2 * Copyright (C) 2007-2012 Argeo GmbH
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.slc
.akb
.ui
.views
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
23 import javax
.jcr
.Node
;
24 import javax
.jcr
.NodeIterator
;
25 import javax
.jcr
.Repository
;
26 import javax
.jcr
.RepositoryException
;
27 import javax
.jcr
.Session
;
28 import javax
.jcr
.observation
.Event
;
29 import javax
.jcr
.observation
.EventListener
;
30 import javax
.jcr
.observation
.ObservationManager
;
32 import org
.argeo
.eclipse
.ui
.jcr
.AsyncUiEventListener
;
33 import org
.argeo
.eclipse
.ui
.utils
.CommandUtils
;
34 import org
.argeo
.jcr
.JcrUtils
;
35 import org
.argeo
.slc
.akb
.AkbException
;
36 import org
.argeo
.slc
.akb
.AkbNames
;
37 import org
.argeo
.slc
.akb
.AkbService
;
38 import org
.argeo
.slc
.akb
.AkbTypes
;
39 import org
.argeo
.slc
.akb
.ui
.AkbUiPlugin
;
40 import org
.argeo
.slc
.akb
.ui
.AkbUiUtils
;
41 import org
.argeo
.slc
.akb
.ui
.commands
.DeleteAkbNodes
;
42 import org
.argeo
.slc
.akb
.ui
.commands
.OpenAkbNodeEditor
;
43 import org
.argeo
.slc
.akb
.ui
.providers
.AkbTreeLabelProvider
;
44 import org
.argeo
.slc
.akb
.ui
.providers
.TemplatesTreeContentProvider
;
45 import org
.argeo
.slc
.akb
.ui
.utils
.Refreshable
;
46 import org
.argeo
.slc
.akb
.utils
.AkbJcrUtils
;
47 import org
.eclipse
.jface
.action
.IContributionItem
;
48 import org
.eclipse
.jface
.action
.IMenuListener
;
49 import org
.eclipse
.jface
.action
.IMenuManager
;
50 import org
.eclipse
.jface
.action
.MenuManager
;
51 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
52 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
53 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
54 import org
.eclipse
.jface
.viewers
.TreeViewer
;
55 import org
.eclipse
.swt
.SWT
;
56 import org
.eclipse
.swt
.layout
.GridData
;
57 import org
.eclipse
.swt
.widgets
.Composite
;
58 import org
.eclipse
.swt
.widgets
.Display
;
59 import org
.eclipse
.swt
.widgets
.Menu
;
60 import org
.eclipse
.ui
.IWorkbenchWindow
;
61 import org
.eclipse
.ui
.part
.ViewPart
;
62 import org
.eclipse
.ui
.services
.IServiceLocator
;
64 /** AKB template tree view. */
65 public class AkbTemplatesTreeView
extends ViewPart
implements Refreshable
{
66 // private final static Log log =
67 // LogFactory.getLog(AkbTemplatesTreeView.class);
69 public final static String ID
= AkbUiPlugin
.PLUGIN_ID
70 + ".akbTemplatesTreeView";
72 /* DEPENDENCY INJECTION */
73 private Session session
;
74 private AkbService akbService
;
77 private TreeViewer envTreeViewer
;
79 // Usefull business objects
80 private Node templatesParentNode
;
83 private EventListener akbNodesObserver
= null;
84 private final static String
[] observedNodeTypes
= {
85 AkbTypes
.AKB_ENV_TEMPLATE
, AkbTypes
.AKB_CONNECTOR_ALIAS
,
86 AkbTypes
.AKB_ITEM
, AkbTypes
.AKB_ITEM_FOLDER
,
87 AkbTypes
.AKB_CONNECTOR_FOLDER
};
89 private void initialize() {
91 templatesParentNode
= session
92 .getNode(AkbNames
.AKB_TEMPLATES_BASE_PATH
);
93 } catch (RepositoryException e
) {
94 throw new AkbException("unable to initialize AKB Browser view", e
);
99 public void createPartControl(Composite parent
) {
102 envTreeViewer
= createTreeViewer(parent
);
103 envTreeViewer
.setInput(initializeTree());
105 // parent.setLayout(new FillLayout());
107 // SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
108 // sashForm.setSashWidth(4);
109 // sashForm.setLayout(new FillLayout());
111 // Create the tree on top of the view
112 // Composite top = new Composite(sashForm, SWT.NONE);
113 // GridLayout gl = new GridLayout(1, false);
114 // top.setLayout(gl);
115 // resultTreeViewer = createResultsTreeViewer(top);
117 // // Create the property viewer on the bottom
118 // Composite bottom = new Composite(sashForm, SWT.NONE);
119 // bottom.setLayout(new GridLayout(1, false));
120 // propertiesViewer = createPropertiesViewer(bottom);
122 // sashForm.setWeights(getWeights());
124 // setOrderedInput(resultTreeViewer);
128 * Override default behaviour so that default defined order remains
129 * unchanged on first level of the tree
131 // private void setOrderedInput(TreeViewer viewer) {
132 // // Add specific ordering
133 // viewer.setInput(null);
134 // viewer.setComparator(null);
135 // viewer.setInput(initializeResultTree());
136 // viewer.setComparator(new ResultItemsComparator());
139 // The main tree viewer
140 protected TreeViewer
createTreeViewer(Composite parent
) {
141 parent
.setLayout(AkbUiUtils
.gridLayoutNoBorder());
142 int style
= SWT
.BORDER
| SWT
.MULTI
;
144 TreeViewer viewer
= new TreeViewer(parent
, style
);
145 viewer
.getTree().setLayoutData(
146 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
148 viewer
.setContentProvider(new TemplatesTreeContentProvider());
149 viewer
.setLabelProvider(new AkbTreeLabelProvider());
150 viewer
.addDoubleClickListener(new ViewDoubleClickListener());
152 // Add label provider with label decorator
153 // ResultTreeLabelProvider rtLblProvider = new
154 // ResultTreeLabelProvider();
155 // ILabelDecorator decorator = AkbUiPlugin.getDefault().getWorkbench()
156 // .getDecoratorManager().getLabelDecorator();
157 // viewer.setLabelProvider(new DecoratingLabelProvider(rtLblProvider,
160 getSite().setSelectionProvider(viewer
);
162 // // add drag & drop support
163 // int operations = DND.DROP_COPY | DND.DROP_MOVE;
164 // Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
165 // viewer.addDragSupport(operations, tt, new ViewDragListener());
166 // viewer.addDropSupport(operations, tt, new ViewDropListener(viewer));
169 MenuManager menuManager
= new MenuManager();
170 Menu menu
= menuManager
.createContextMenu(viewer
.getTree());
171 menuManager
.addMenuListener(new IMenuListener() {
172 public void menuAboutToShow(IMenuManager manager
) {
173 contextMenuAboutToShow(manager
);
176 viewer
.getTree().setMenu(menu
);
177 menuManager
.setRemoveAllWhenShown(true);
179 getSite().registerContextMenu(menuManager
, viewer
);
181 // Initialize observer
183 ObservationManager observationManager
= session
.getWorkspace()
184 .getObservationManager();
186 akbNodesObserver
= new AkbNodesObserver(viewer
.getTree()
188 observationManager
.addEventListener(akbNodesObserver
,
189 Event
.NODE_ADDED
| Event
.NODE_REMOVED
,
190 templatesParentNode
.getPath(), true, null,
191 observedNodeTypes
, false);
192 } catch (RepositoryException e
) {
193 throw new AkbException("Cannot register listeners", e
);
199 public void setFocus() {
202 private Node
[] initializeTree() {
204 NodeIterator ni
= templatesParentNode
.getNodes();
205 List
<Node
> templates
= new ArrayList
<Node
>();
206 while (ni
.hasNext()) {
207 Node currNode
= ni
.nextNode();
208 if (currNode
.isNodeType(AkbTypes
.AKB_ENV_TEMPLATE
))
209 templates
.add(currNode
);
211 Node
[] templateArr
= templates
.toArray(new Node
[templates
.size()]);
213 } catch (RepositoryException re
) {
214 throw new AkbException("Error while initializing templates Tree.",
220 public void forceRefresh(Object object
) {
221 envTreeViewer
.setInput(initializeTree());
224 // ///////////////////////////
225 // CONTEXT MENU MANAGEMENT
228 * Defines the commands that will pop up in the context menu.
230 protected void contextMenuAboutToShow(IMenuManager menuManager
) {
231 IWorkbenchWindow window
= AkbUiPlugin
.getDefault().getWorkbench()
232 .getActiveWorkbenchWindow();
236 IStructuredSelection selection
= (IStructuredSelection
) envTreeViewer
239 Node selected
= (Node
) selection
.getFirstElement();
242 boolean hasSelection
= selected
!= null;
245 currEnv
= AkbJcrUtils
.getCurrentTemplate(selected
);
247 boolean isTemplate
= hasSelection ? selected
248 .isNodeType(AkbTypes
.AKB_ENV_TEMPLATE
) : false;
249 boolean isParentItemsFolder
= hasSelection ? selected
250 .isNodeType(AkbTypes
.AKB_ITEM_FOLDER
) : false;
251 // boolean isParentConnectorsFolder = hasSelection ? selected
252 // .isNodeType(AkbTypes.AKB_CONNECTOR_FOLDER) : false;
253 boolean isDeletable
= hasSelection ?
true : false;
255 // Add Connector Alias
256 Map
<String
, String
> params
= new HashMap
<String
, String
>();
257 if (hasSelection
&& isTemplate
) {
258 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
259 selected
.getIdentifier());
260 params
.put(OpenAkbNodeEditor
.PARAM_CURR_ENV_JCR_ID
,
261 currEnv
.getIdentifier());
263 params
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
264 AkbTypes
.AKB_CONNECTOR_ALIAS
);
266 // Connector Alias submenu
267 refreshAliasesSubmenu(menuManager
, window
, "menu.aliasesSubmenu",
268 "Add Connector Alias", isTemplate
, params
);
271 params
= new HashMap
<String
, String
>();
273 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
274 selected
.getIdentifier());
275 params
.put(OpenAkbNodeEditor
.PARAM_CURR_ENV_JCR_ID
,
276 currEnv
.getIdentifier());
278 refreshItemsSubmenu(menuManager
, window
, "menu.itemsSubmenu",
279 "Add Item", isParentItemsFolder
|| isTemplate
, params
);
282 params
= new HashMap
<String
, String
>();
284 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
285 selected
.getIdentifier());
286 params
.put(OpenAkbNodeEditor
.PARAM_CURR_ENV_JCR_ID
,
287 currEnv
.getIdentifier());
289 params
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
290 AkbTypes
.AKB_ITEM_FOLDER
);
292 AkbUiUtils
.refreshParameterizedCommand(menuManager
, window
,
293 "cmd.addItemFolder", OpenAkbNodeEditor
.ID
,
294 "Add item folder", null, isParentItemsFolder
|| isTemplate
,
298 params
= new HashMap
<String
, String
>();
300 params
.put(DeleteAkbNodes
.PARAM_NODE_JCR_ID
,
301 selected
.getIdentifier());
302 AkbUiUtils
.refreshParameterizedCommand(menuManager
, window
,
303 "cmd.deleteItem", DeleteAkbNodes
.ID
,
304 "Delete selected item(s)", null, isDeletable
, params
);
307 params
= new HashMap
<String
, String
>();
308 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
309 templatesParentNode
.getIdentifier());
310 params
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
311 AkbTypes
.AKB_ENV_TEMPLATE
);
312 AkbUiUtils
.refreshParameterizedCommand(menuManager
, window
,
313 "cmd.createTemplate", OpenAkbNodeEditor
.ID
,
314 "Create new template...", null,
315 !hasSelection
|| isTemplate
, params
);
317 } catch (RepositoryException re
) {
318 throw new AkbException("Error while refreshing context menu", re
);
324 * refreshes submenu with various connector types
333 private void refreshItemsSubmenu(IMenuManager menuManager
,
334 IServiceLocator locator
, String itemId
, String label
,
335 boolean isVisible
, Map
<String
, String
> params
) {
338 IContributionItem ici
= menuManager
.find(itemId
);
340 menuManager
.remove(ici
);
342 MenuManager subMenu
= new MenuManager(label
, itemId
);
345 Map
<String
, String
> tmpParams
= new HashMap
<String
, String
>();
346 tmpParams
.putAll(params
);
347 tmpParams
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
348 AkbTypes
.AKB_JDBC_QUERY
);
349 String currItemId
= "cmd.createJDBCQuery";
350 IContributionItem currItem
= subMenu
.find(currItemId
);
351 if (currItem
!= null)
352 subMenu
.remove(currItem
);
353 subMenu
.add(AkbUiUtils
.createContributionItem(menuManager
, locator
,
354 currItemId
, OpenAkbNodeEditor
.ID
, "JDBC", null, tmpParams
));
357 tmpParams
= new HashMap
<String
, String
>();
358 tmpParams
.putAll(params
);
359 tmpParams
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
360 AkbTypes
.AKB_SSH_COMMAND
);
361 currItemId
= "cmd.createSSHCommand";
362 currItem
= subMenu
.find(currItemId
);
363 if (currItem
!= null)
364 subMenu
.remove(currItem
);
365 subMenu
.add(AkbUiUtils
.createContributionItem(menuManager
, locator
,
366 currItemId
, OpenAkbNodeEditor
.ID
, "SSH Command", null,
370 tmpParams
= new HashMap
<String
, String
>();
371 tmpParams
.putAll(params
);
372 tmpParams
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
, AkbTypes
.AKB_SSH_FILE
);
373 currItemId
= "cmd.createSSHFile";
374 currItem
= subMenu
.find(currItemId
);
375 if (currItem
!= null)
376 subMenu
.remove(currItem
);
377 subMenu
.add(AkbUiUtils
.createContributionItem(menuManager
, locator
,
378 currItemId
, OpenAkbNodeEditor
.ID
, "SSH File", null, tmpParams
));
381 menuManager
.add(subMenu
);
382 subMenu
.setVisible(isVisible
);
387 * refreshes submenu with various connector types
396 private void refreshAliasesSubmenu(IMenuManager menuManager
,
397 IServiceLocator locator
, String itemId
, String label
,
398 boolean isVisible
, Map
<String
, String
> params
) {
401 IContributionItem ici
= menuManager
.find(itemId
);
403 menuManager
.remove(ici
);
405 // TODO use dynamic contribution to dynamically retrieve specific
407 // CompoundContributionItem comConI = new MyCompoundCI(menuManager,
409 MenuManager subMenu
= new MenuManager(label
, itemId
);
412 Map
<String
, String
> tmpParams
= new HashMap
<String
, String
>();
413 tmpParams
.putAll(params
);
414 tmpParams
.put(OpenAkbNodeEditor
.PARAM_NODE_SUBTYPE
,
415 AkbTypes
.AKB_JDBC_CONNECTOR
);
416 String currItemId
= "cmd.createJDBCAlias";
417 IContributionItem currItem
= subMenu
.find(currItemId
);
418 if (currItem
!= null)
419 subMenu
.remove(currItem
);
420 subMenu
.add(AkbUiUtils
.createContributionItem(menuManager
, locator
,
421 currItemId
, OpenAkbNodeEditor
.ID
, "JDBC", null, tmpParams
));
424 tmpParams
= new HashMap
<String
, String
>();
425 tmpParams
.putAll(params
);
426 tmpParams
.put(OpenAkbNodeEditor
.PARAM_NODE_SUBTYPE
,
427 AkbTypes
.AKB_SSH_CONNECTOR
);
428 currItemId
= "cmd.createSSHAlias";
429 currItem
= subMenu
.find(currItemId
);
430 if (currItem
!= null)
431 subMenu
.remove(currItem
);
432 subMenu
.add(AkbUiUtils
.createContributionItem(menuManager
, locator
,
433 currItemId
, OpenAkbNodeEditor
.ID
, "SSH", null, tmpParams
));
436 menuManager
.add(subMenu
);
437 subMenu
.setVisible(isVisible
);
440 // private class MyCompoundCI extends CompoundContributionItem {
441 // private IMenuManager menuManager;
442 // private IServiceLocator locator;
444 // public MyCompoundCI(IMenuManager menuManager, IServiceLocator locator,
447 // this.menuManager = menuManager;
448 // this.locator = locator;
452 // protected IContributionItem[] getContributionItems() {
454 // CommandContributionItem[] submenu = new CommandContributionItem[2];
455 // submenu[0] = createContributionItem(menuManager, locator, "uid.1",
456 // OpenAkbNodeEditor.ID, "test1" + System.currentTimeMillis(),
458 // submenu[1] = createContributionItem(menuManager, locator, "uid.2",
459 // OpenAkbNodeEditor.ID, "test2", null, null);
465 private class AkbNodesObserver
extends AsyncUiEventListener
{
467 public AkbNodesObserver(Display display
) {
472 protected Boolean
willProcessInUiThread(List
<Event
> events
)
473 throws RepositoryException
{
474 // unfiltered for the time being
478 protected void onEventInUiThread(List
<Event
> events
)
479 throws RepositoryException
{
480 boolean fullRefresh
= false;
482 eventLoop
: for (Event event
: events
) {
483 String currPath
= event
.getPath();
484 if (session
.nodeExists(currPath
)) {
485 Node node
= session
.getNode(currPath
);
486 if (node
.isNodeType(AkbTypes
.AKB_ENV_TEMPLATE
)) {
493 Object
[] visibles
= envTreeViewer
.getExpandedElements();
495 envTreeViewer
.setInput(initializeTree());
497 envTreeViewer
.refresh();
499 envTreeViewer
.setExpandedElements(visibles
);
503 class ViewDoubleClickListener
implements IDoubleClickListener
{
504 public void doubleClick(DoubleClickEvent evt
) {
505 Object obj
= ((IStructuredSelection
) evt
.getSelection())
508 if (obj
instanceof Node
) {
509 Node node
= (Node
) obj
;
510 Node currEnv
= AkbJcrUtils
.getCurrentTemplate(node
);
512 // Add Connector Alias
513 Map
<String
, String
> params
= new HashMap
<String
, String
>();
514 params
.put(OpenAkbNodeEditor
.PARAM_NODE_JCR_ID
,
515 node
.getIdentifier());
516 params
.put(OpenAkbNodeEditor
.PARAM_CURR_ENV_JCR_ID
,
517 currEnv
.getIdentifier());
519 CommandUtils
.callCommand(OpenAkbNodeEditor
.ID
, params
);
521 } catch (RepositoryException e
) {
522 throw new AkbException("Cannot open " + obj
, e
);
528 public void dispose() {
529 JcrUtils
.logoutQuietly(session
);
533 /* DEPENDENCY INJECTION */
534 public void setRepository(Repository repository
) {
536 session
= repository
.login();
537 } catch (RepositoryException e
) {
538 throw new AkbException("unable to log in for " + ID
+ " view");
542 public void setAkbService(AkbService akbService
) {
543 this.akbService
= akbService
;