]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/views/AkbTemplatesTreeView.java
Edit connector wizard
[gpl/argeo-slc.git] / plugins / org.argeo.slc.akb.ui / src / main / java / org / argeo / slc / akb / ui / views / AkbTemplatesTreeView.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16 package org.argeo.slc.akb.ui.views;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
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;
31
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;
63
64 /** AKB template tree view. */
65 public class AkbTemplatesTreeView extends ViewPart implements Refreshable {
66 // private final static Log log =
67 // LogFactory.getLog(AkbTemplatesTreeView.class);
68
69 public final static String ID = AkbUiPlugin.PLUGIN_ID
70 + ".akbTemplatesTreeView";
71
72 /* DEPENDENCY INJECTION */
73 private Session session;
74 private AkbService akbService;
75
76 // This page widgets
77 private TreeViewer envTreeViewer;
78
79 // Usefull business objects
80 private Node templatesParentNode;
81
82 // Observer
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 };
88
89 private void initialize() {
90 try {
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);
95 }
96 }
97
98 @Override
99 public void createPartControl(Composite parent) {
100 initialize();
101
102 envTreeViewer = createTreeViewer(parent);
103 envTreeViewer.setInput(initializeTree());
104
105 // parent.setLayout(new FillLayout());
106 // // Main layout
107 // SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
108 // sashForm.setSashWidth(4);
109 // sashForm.setLayout(new FillLayout());
110
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);
116
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);
121 //
122 // sashForm.setWeights(getWeights());
123
124 // setOrderedInput(resultTreeViewer);
125 }
126
127 /**
128 * Override default behaviour so that default defined order remains
129 * unchanged on first level of the tree
130 */
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());
137 // }
138
139 // The main tree viewer
140 protected TreeViewer createTreeViewer(Composite parent) {
141 parent.setLayout(AkbUiUtils.gridLayoutNoBorder());
142 int style = SWT.BORDER | SWT.MULTI;
143
144 TreeViewer viewer = new TreeViewer(parent, style);
145 viewer.getTree().setLayoutData(
146 new GridData(SWT.FILL, SWT.FILL, true, true));
147
148 viewer.setContentProvider(new TemplatesTreeContentProvider());
149 viewer.setLabelProvider(new AkbTreeLabelProvider());
150 viewer.addDoubleClickListener(new ViewDoubleClickListener());
151
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,
158 // decorator));
159
160 getSite().setSelectionProvider(viewer);
161
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));
167
168 // add context menu
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);
174 }
175 });
176 viewer.getTree().setMenu(menu);
177 menuManager.setRemoveAllWhenShown(true);
178
179 getSite().registerContextMenu(menuManager, viewer);
180
181 // Initialize observer
182 try {
183 ObservationManager observationManager = session.getWorkspace()
184 .getObservationManager();
185
186 akbNodesObserver = new AkbNodesObserver(viewer.getTree()
187 .getDisplay());
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);
194 }
195 return viewer;
196 }
197
198 @Override
199 public void setFocus() {
200 }
201
202 private Node[] initializeTree() {
203 try {
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);
210 }
211 Node[] templateArr = templates.toArray(new Node[templates.size()]);
212 return templateArr;
213 } catch (RepositoryException re) {
214 throw new AkbException("Error while initializing templates Tree.",
215 re);
216 }
217 }
218
219 @Override
220 public void forceRefresh(Object object) {
221 envTreeViewer.setInput(initializeTree());
222 }
223
224 // ///////////////////////////
225 // CONTEXT MENU MANAGEMENT
226
227 /**
228 * Defines the commands that will pop up in the context menu.
229 **/
230 protected void contextMenuAboutToShow(IMenuManager menuManager) {
231 IWorkbenchWindow window = AkbUiPlugin.getDefault().getWorkbench()
232 .getActiveWorkbenchWindow();
233 try {
234
235 // Build conditions
236 IStructuredSelection selection = (IStructuredSelection) envTreeViewer
237 .getSelection();
238
239 Node selected = (Node) selection.getFirstElement();
240 Node currEnv = null;
241
242 boolean hasSelection = selected != null;
243
244 if (hasSelection)
245 currEnv = AkbJcrUtils.getCurrentTemplate(selected);
246
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;
254
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());
262 }
263 params.put(OpenAkbNodeEditor.PARAM_NODE_TYPE,
264 AkbTypes.AKB_CONNECTOR_ALIAS);
265
266 // Connector Alias submenu
267 refreshAliasesSubmenu(menuManager, window, "menu.aliasesSubmenu",
268 "Add Connector Alias", isTemplate, params);
269
270 // Item Submenu
271 params = new HashMap<String, String>();
272 if (hasSelection) {
273 params.put(OpenAkbNodeEditor.PARAM_PARENT_NODE_JCR_ID,
274 selected.getIdentifier());
275 params.put(OpenAkbNodeEditor.PARAM_CURR_ENV_JCR_ID,
276 currEnv.getIdentifier());
277 }
278 refreshItemsSubmenu(menuManager, window, "menu.itemsSubmenu",
279 "Add Item", isParentItemsFolder || isTemplate, params);
280
281 // Add Item Folder
282 params = new HashMap<String, String>();
283 if (hasSelection) {
284 params.put(OpenAkbNodeEditor.PARAM_PARENT_NODE_JCR_ID,
285 selected.getIdentifier());
286 params.put(OpenAkbNodeEditor.PARAM_CURR_ENV_JCR_ID,
287 currEnv.getIdentifier());
288 }
289 params.put(OpenAkbNodeEditor.PARAM_NODE_TYPE,
290 AkbTypes.AKB_ITEM_FOLDER);
291
292 AkbUiUtils.refreshParameterizedCommand(menuManager, window,
293 "cmd.addItemFolder", OpenAkbNodeEditor.ID,
294 "Add item folder", null, isParentItemsFolder || isTemplate,
295 params);
296
297 // Delete Item
298 params = new HashMap<String, String>();
299 if (hasSelection)
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);
305
306 // create template
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);
316
317 } catch (RepositoryException re) {
318 throw new AkbException("Error while refreshing context menu", re);
319 }
320 }
321
322 /**
323 *
324 * refreshes submenu with various connector types
325 *
326 * @param menuManager
327 * @param locator
328 * @param itemId
329 * @param label
330 * @param isVisible
331 * @param params
332 */
333 private void refreshItemsSubmenu(IMenuManager menuManager,
334 IServiceLocator locator, String itemId, String label,
335 boolean isVisible, Map<String, String> params) {
336
337 // clean
338 IContributionItem ici = menuManager.find(itemId);
339 if (ici != null)
340 menuManager.remove(ici);
341
342 MenuManager subMenu = new MenuManager(label, itemId);
343
344 // JDBC Query
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));
355
356 // SSH COMMAND
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,
367 tmpParams));
368
369 // SSH FILE
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));
379
380 // refresh
381 menuManager.add(subMenu);
382 subMenu.setVisible(isVisible);
383 }
384
385 /**
386 *
387 * refreshes submenu with various connector types
388 *
389 * @param menuManager
390 * @param locator
391 * @param itemId
392 * @param label
393 * @param isVisible
394 * @param params
395 */
396 private void refreshAliasesSubmenu(IMenuManager menuManager,
397 IServiceLocator locator, String itemId, String label,
398 boolean isVisible, Map<String, String> params) {
399
400 // clean
401 IContributionItem ici = menuManager.find(itemId);
402 if (ici != null)
403 menuManager.remove(ici);
404
405 // TODO use dynamic contribution to dynamically retrieve specific
406 // connector types
407 // CompoundContributionItem comConI = new MyCompoundCI(menuManager,
408 // locator, itemId);
409 MenuManager subMenu = new MenuManager(label, itemId);
410
411 // JDBC
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));
422
423 // SSH
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));
434
435 // refresh
436 menuManager.add(subMenu);
437 subMenu.setVisible(isVisible);
438 }
439
440 // private class MyCompoundCI extends CompoundContributionItem {
441 // private IMenuManager menuManager;
442 // private IServiceLocator locator;
443 //
444 // public MyCompoundCI(IMenuManager menuManager, IServiceLocator locator,
445 // String itemId) {
446 // super(itemId);
447 // this.menuManager = menuManager;
448 // this.locator = locator;
449 // }
450 //
451 // @Override
452 // protected IContributionItem[] getContributionItems() {
453 //
454 // CommandContributionItem[] submenu = new CommandContributionItem[2];
455 // submenu[0] = createContributionItem(menuManager, locator, "uid.1",
456 // OpenAkbNodeEditor.ID, "test1" + System.currentTimeMillis(),
457 // null, null);
458 // submenu[1] = createContributionItem(menuManager, locator, "uid.2",
459 // OpenAkbNodeEditor.ID, "test2", null, null);
460 // return submenu;
461 // }
462 // }
463
464 /* INNER CLASSES */
465 private class AkbNodesObserver extends AsyncUiEventListener {
466
467 public AkbNodesObserver(Display display) {
468 super(display);
469 }
470
471 @Override
472 protected Boolean willProcessInUiThread(List<Event> events)
473 throws RepositoryException {
474 // unfiltered for the time being
475 return true;
476 }
477
478 protected void onEventInUiThread(List<Event> events)
479 throws RepositoryException {
480 boolean fullRefresh = false;
481
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)) {
487 fullRefresh = true;
488 break eventLoop;
489 }
490 }
491 }
492
493 Object[] visibles = envTreeViewer.getExpandedElements();
494 if (fullRefresh)
495 envTreeViewer.setInput(initializeTree());
496 else
497 envTreeViewer.refresh();
498
499 envTreeViewer.setExpandedElements(visibles);
500 }
501 }
502
503 class ViewDoubleClickListener implements IDoubleClickListener {
504 public void doubleClick(DoubleClickEvent evt) {
505 Object obj = ((IStructuredSelection) evt.getSelection())
506 .getFirstElement();
507 try {
508 if (obj instanceof Node) {
509 Node node = (Node) obj;
510 Node currEnv = AkbJcrUtils.getCurrentTemplate(node);
511
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());
518
519 CommandUtils.callCommand(OpenAkbNodeEditor.ID, params);
520 }
521 } catch (RepositoryException e) {
522 throw new AkbException("Cannot open " + obj, e);
523 }
524 }
525 }
526
527 @Override
528 public void dispose() {
529 JcrUtils.logoutQuietly(session);
530 super.dispose();
531 }
532
533 /* DEPENDENCY INJECTION */
534 public void setRepository(Repository repository) {
535 try {
536 session = repository.login();
537 } catch (RepositoryException e) {
538 throw new AkbException("unable to log in for " + ID + " view");
539 }
540 }
541
542 public void setAkbService(AkbService akbService) {
543 this.akbService = akbService;
544
545 }
546 }