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
.AkbTypes
;
38 import org
.argeo
.slc
.akb
.ui
.AkbUiPlugin
;
39 import org
.argeo
.slc
.akb
.ui
.AkbUiUtils
;
40 import org
.argeo
.slc
.akb
.ui
.commands
.DeleteAkbNodes
;
41 import org
.argeo
.slc
.akb
.ui
.commands
.OpenAkbNodeEditor
;
42 import org
.argeo
.slc
.akb
.ui
.providers
.AkbTreeLabelProvider
;
43 import org
.argeo
.slc
.akb
.ui
.providers
.TemplatesTreeContentProvider
;
44 import org
.eclipse
.jface
.action
.IContributionItem
;
45 import org
.eclipse
.jface
.action
.IMenuListener
;
46 import org
.eclipse
.jface
.action
.IMenuManager
;
47 import org
.eclipse
.jface
.action
.MenuManager
;
48 import org
.eclipse
.jface
.resource
.ImageDescriptor
;
49 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
50 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
51 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
52 import org
.eclipse
.jface
.viewers
.TreeViewer
;
53 import org
.eclipse
.swt
.SWT
;
54 import org
.eclipse
.swt
.layout
.GridData
;
55 import org
.eclipse
.swt
.widgets
.Composite
;
56 import org
.eclipse
.swt
.widgets
.Display
;
57 import org
.eclipse
.swt
.widgets
.Menu
;
58 import org
.eclipse
.ui
.IWorkbenchWindow
;
59 import org
.eclipse
.ui
.menus
.CommandContributionItem
;
60 import org
.eclipse
.ui
.menus
.CommandContributionItemParameter
;
61 import org
.eclipse
.ui
.part
.ViewPart
;
62 import org
.eclipse
.ui
.services
.IServiceLocator
;
64 /** SLC generic JCR Result tree view. */
65 public class AkbTemplatesTreeView
extends ViewPart
{
66 // private final static Log log =
67 // LogFactory.getLog(JcrResultTreeView.class);
69 public final static String ID
= AkbUiPlugin
.PLUGIN_ID
70 + ".akbTemplatesTreeView";
72 /* DEPENDENCY INJECTION */
73 private Session session
;
76 private TreeViewer resultTreeViewer
;
78 // Usefull business objects
79 private Node templatesParentNode
;
82 private EventListener allResultsObserver
= null;
83 private final static String
[] observedNodeTypesUnderAllResults
= {
84 AkbTypes
.AKB_ENV_TEMPLATE
, AkbTypes
.AKB_CONNECTOR_ALIAS
,
85 AkbTypes
.AKB_ITEM
, AkbTypes
.AKB_ITEM_FOLDER
,
86 AkbTypes
.AKB_CONNECTOR_FOLDER
};
88 // private EventListener myResultsObserver = null;
89 // private EventListener allResultsObserver = null;
91 // // under My Results
92 // private final static String[] observedNodeTypesUnderMyResult = {
93 // SlcTypes.SLC_TEST_RESULT, SlcTypes.SLC_RESULT_FOLDER,
94 // SlcTypes.SLC_MY_RESULT_ROOT_FOLDER };
96 // private final static String[] observedNodeTypesUnderAllResults = {
97 // SlcTypes.SLC_TEST_RESULT, NodeType.NT_UNSTRUCTURED };
99 // private boolean isResultFolder = false;
102 // * To be overridden to adapt size of form and result frames.
104 // protected int[] getWeights() {
105 // return new int[] { 70, 30 };
108 private void initialize() {
110 templatesParentNode
= session
111 .getNode(AkbNames
.AKB_TEMPLATES_BASE_PATH
);
112 } catch (RepositoryException e
) {
113 throw new AkbException("unable to initialize AKB Browser view", e
);
118 public void createPartControl(Composite parent
) {
121 resultTreeViewer
= createResultsTreeViewer(parent
);
122 resultTreeViewer
.setInput(initializeResultTree());
124 // parent.setLayout(new FillLayout());
126 // SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
127 // sashForm.setSashWidth(4);
128 // sashForm.setLayout(new FillLayout());
130 // Create the tree on top of the view
131 // Composite top = new Composite(sashForm, SWT.NONE);
132 // GridLayout gl = new GridLayout(1, false);
133 // top.setLayout(gl);
134 // resultTreeViewer = createResultsTreeViewer(top);
136 // // Create the property viewer on the bottom
137 // Composite bottom = new Composite(sashForm, SWT.NONE);
138 // bottom.setLayout(new GridLayout(1, false));
139 // propertiesViewer = createPropertiesViewer(bottom);
141 // sashForm.setWeights(getWeights());
143 // setOrderedInput(resultTreeViewer);
147 * Override default behaviour so that default defined order remains
148 * unchanged on first level of the tree
150 // private void setOrderedInput(TreeViewer viewer) {
151 // // Add specific ordering
152 // viewer.setInput(null);
153 // viewer.setComparator(null);
154 // viewer.setInput(initializeResultTree());
155 // viewer.setComparator(new ResultItemsComparator());
158 // The main tree viewer
159 protected TreeViewer
createResultsTreeViewer(Composite parent
) {
160 parent
.setLayout(AkbUiUtils
.gridLayoutNoBorder());
161 int style
= SWT
.BORDER
| SWT
.MULTI
;
163 TreeViewer viewer
= new TreeViewer(parent
, style
);
164 viewer
.getTree().setLayoutData(
165 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
167 viewer
.setContentProvider(new TemplatesTreeContentProvider());
168 viewer
.setLabelProvider(new AkbTreeLabelProvider());
169 viewer
.addDoubleClickListener(new ViewDoubleClickListener());
171 // Add label provider with label decorator
172 // ResultTreeLabelProvider rtLblProvider = new
173 // ResultTreeLabelProvider();
174 // ILabelDecorator decorator = AkbUiPlugin.getDefault().getWorkbench()
175 // .getDecoratorManager().getLabelDecorator();
176 // viewer.setLabelProvider(new DecoratingLabelProvider(rtLblProvider,
179 getSite().setSelectionProvider(viewer
);
181 // // add drag & drop support
182 // int operations = DND.DROP_COPY | DND.DROP_MOVE;
183 // Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
184 // viewer.addDragSupport(operations, tt, new ViewDragListener());
185 // viewer.addDropSupport(operations, tt, new ViewDropListener(viewer));
188 MenuManager menuManager
= new MenuManager();
189 Menu menu
= menuManager
.createContextMenu(viewer
.getTree());
190 menuManager
.addMenuListener(new IMenuListener() {
191 public void menuAboutToShow(IMenuManager manager
) {
192 contextMenuAboutToShow(manager
);
195 viewer
.getTree().setMenu(menu
);
196 menuManager
.setRemoveAllWhenShown(true);
198 getSite().registerContextMenu(menuManager
, viewer
);
200 // Initialize observer
202 ObservationManager observationManager
= session
.getWorkspace()
203 .getObservationManager();
205 allResultsObserver
= new AllResultsObserver(viewer
.getTree()
208 // observe tree changes under All results
209 observationManager
.addEventListener(allResultsObserver
,
210 Event
.NODE_ADDED
| Event
.NODE_REMOVED
,
211 templatesParentNode
.getPath(), true, null,
212 observedNodeTypesUnderAllResults
, false);
213 } catch (RepositoryException e
) {
214 throw new AkbException("Cannot register listeners", e
);
217 // add change listener to display TestResult information in the property
219 // viewer.addSelectionChangedListener(new MySelectionChangedListener());
223 class AllResultsObserver
extends AsyncUiEventListener
{
225 public AllResultsObserver(Display display
) {
230 protected Boolean
willProcessInUiThread(List
<Event
> events
)
231 throws RepositoryException
{
232 // unfiltered for the time being
236 protected void onEventInUiThread(List
<Event
> events
)
237 throws RepositoryException
{
238 boolean fullRefresh
= false;
240 eventLoop
: for (Event event
: events
) {
241 String currPath
= event
.getPath();
242 if (session
.nodeExists(currPath
)) {
243 Node node
= session
.getNode(currPath
);
244 if (node
.isNodeType(AkbTypes
.AKB_ENV_TEMPLATE
)) {
251 Object
[] visibles
= resultTreeViewer
.getExpandedElements();
253 resultTreeViewer
.setInput(initializeResultTree());
255 resultTreeViewer
.refresh();
257 resultTreeViewer
.setExpandedElements(visibles
);
261 // Detailed property viewer
262 // protected TableViewer createPropertiesViewer(Composite parent) {
266 public void setFocus() {
269 private Node
[] initializeResultTree() {
271 NodeIterator ni
= templatesParentNode
.getNodes();
272 List
<Node
> templates
= new ArrayList
<Node
>();
274 while (ni
.hasNext()) {
275 Node currNode
= ni
.nextNode();
276 if (currNode
.isNodeType(AkbTypes
.AKB_ENV_TEMPLATE
))
277 templates
.add(currNode
);
280 Node
[] templateArr
= templates
.toArray(new Node
[templates
.size()]);
282 } catch (RepositoryException re
) {
283 throw new AkbException("Error while initializing templates Tree.",
288 // Manage context menu
290 * Defines the commands that will pop up in the context menu.
292 protected void contextMenuAboutToShow(IMenuManager menuManager
) {
293 IWorkbenchWindow window
= AkbUiPlugin
.getDefault().getWorkbench()
294 .getActiveWorkbenchWindow();
298 Node selected
= (Node
) ((IStructuredSelection
) resultTreeViewer
299 .getSelection()).getFirstElement();
301 boolean hasSelection
= selected
!= null;
302 boolean isParentItemsFolder
= hasSelection ? selected
303 .isNodeType(AkbTypes
.AKB_ITEM_FOLDER
) : false;
304 boolean isParentConnectorsFolder
= hasSelection ? selected
305 .isNodeType(AkbTypes
.AKB_CONNECTOR_FOLDER
) : false;
306 boolean isDeletable
= hasSelection ?
!(selected
.getParent()
307 .isNodeType(AkbTypes
.AKB_ENV_TEMPLATE
)) : false;
309 // Add Connector Alias
310 Map
<String
, String
> params
= new HashMap
<String
, String
>();
312 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
313 selected
.getIdentifier());
314 params
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
315 AkbTypes
.AKB_CONNECTOR_ALIAS
);
316 refreshParameterizedCommand(menuManager
, window
,
317 "cmd.addConnector", OpenAkbNodeEditor
.ID
,
318 "Add connector Alias", null, isParentConnectorsFolder
,
322 params
= new HashMap
<String
, String
>();
324 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
325 selected
.getIdentifier());
326 params
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
, AkbTypes
.AKB_ITEM
);
327 refreshParameterizedCommand(menuManager
, window
, "cmd.addItem",
328 OpenAkbNodeEditor
.ID
, "Add item", null,
329 isParentItemsFolder
, params
);
332 params
= new HashMap
<String
, String
>();
334 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
335 selected
.getIdentifier());
336 params
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
337 AkbTypes
.AKB_ITEM_FOLDER
);
338 refreshParameterizedCommand(menuManager
, window
,
339 "cmd.addItemFolder", OpenAkbNodeEditor
.ID
,
340 "Add item folder", null, isParentItemsFolder
, params
);
343 params
= new HashMap
<String
, String
>();
345 params
.put(DeleteAkbNodes
.PARAM_NODE_JCR_ID
,
346 selected
.getIdentifier());
347 refreshParameterizedCommand(menuManager
, window
, "cmd.deleteItem",
348 DeleteAkbNodes
.ID
, "Delete selected item(s)", null,
349 isDeletable
, params
);
352 params
= new HashMap
<String
, String
>();
353 params
.put(OpenAkbNodeEditor
.PARAM_PARENT_NODE_JCR_ID
,
354 templatesParentNode
.getIdentifier());
355 params
.put(OpenAkbNodeEditor
.PARAM_NODE_TYPE
,
356 AkbTypes
.AKB_ENV_TEMPLATE
);
357 refreshParameterizedCommand(menuManager
, window
,
358 "cmd.createTemplate", OpenAkbNodeEditor
.ID
,
359 "Create new template...", null, true, params
);
361 } catch (RepositoryException re
) {
362 throw new AkbException("Error while refreshing context menu", re
);
367 * Commodities the refresh of a single command with a map of parameters in a
368 * Menu.aboutToShow method to simplify further development
377 private void refreshParameterizedCommand(IMenuManager menuManager
,
378 IServiceLocator locator
, String itemId
, String cmdId
, String label
,
379 ImageDescriptor icon
, boolean showCommand
,
380 Map
<String
, String
> params
) {
381 IContributionItem ici
= menuManager
.find(itemId
);
383 menuManager
.remove(ici
);
384 CommandContributionItemParameter contributionItemParameter
= new CommandContributionItemParameter(
385 locator
, itemId
, cmdId
, SWT
.PUSH
);
389 contributionItemParameter
.label
= label
;
390 contributionItemParameter
.icon
= icon
;
393 contributionItemParameter
.parameters
= params
;
395 CommandContributionItem cci
= new CommandContributionItem(
396 contributionItemParameter
);
397 menuManager
.add(cci
);
402 class ViewDoubleClickListener
implements IDoubleClickListener
{
403 public void doubleClick(DoubleClickEvent evt
) {
404 Object obj
= ((IStructuredSelection
) evt
.getSelection())
407 if (obj
instanceof Node
) {
408 Node node
= (Node
) obj
;
409 CommandUtils
.callCommand(OpenAkbNodeEditor
.ID
,
410 OpenAkbNodeEditor
.PARAM_NODE_JCR_ID
,
411 node
.getIdentifier());
413 } catch (RepositoryException e
) {
414 throw new AkbException("Cannot open " + obj
, e
);
420 public void dispose() {
421 JcrUtils
.logoutQuietly(session
);
425 /* DEPENDENCY INJECTION */
426 public void setRepository(Repository repository
) {
428 session
= repository
.login();
429 } catch (RepositoryException e
) {
430 throw new AkbException("unable to log in for " + ID
+ " view");