--- /dev/null
+package org.argeo.slc.akb.ui.commands;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.akb.AkbException;
+import org.argeo.slc.akb.AkbTypes;
+import org.argeo.slc.akb.ui.AkbUiPlugin;
+import org.argeo.slc.akb.ui.editors.AkbConnectorAliasEditor;
+import org.argeo.slc.akb.ui.editors.AkbEnvTemplateEditor;
+import org.argeo.slc.akb.ui.editors.AkbNodeEditorInput;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Opens or show an AKB specific node in a single repository / single workspace
+ * environment given some parameters, namely :
+ * <ul>
+ * <li>PARAM_NODE_JCR_ID: the corresponding JCR ID might be null to create a new
+ * one</li>
+ * <li>PARAM_NODE_TYPE: jcr type of the node to create</li>
+ * <li>PARAM_PARENT_NODE_JCR_ID: Only used in the case of the creation of a new
+ * node.</li>
+ * </ul>
+ */
+public class OpenAkbNodeEditor extends AbstractHandler {
+ public final static String ID = AkbUiPlugin.PLUGIN_ID
+ + ".openAkbNodeEditor";
+
+ /* DEPENDENCY INJECTION */
+ private Repository repository;
+
+ public final static String PARAM_NODE_JCR_ID = "param.nodeJcrId";
+ public final static String PARAM_NODE_TYPE = "param.nodeType";
+ public final static String PARAM_PARENT_NODE_JCR_ID = "param.parentNodeJcrId";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ String nodeType = event.getParameter(PARAM_NODE_TYPE);
+ String nodeJcrId = event.getParameter(PARAM_NODE_JCR_ID);
+ String parentNodeJcrId = event.getParameter(PARAM_PARENT_NODE_JCR_ID);
+
+ Session session = null;
+ try {
+ session = repository.login();
+ Node node = null;
+
+ if (nodeJcrId == null)
+ if (parentNodeJcrId == null)
+ throw new AkbException(
+ "Define a parent node to create a new node");
+ else
+ node = createNewNode(session, nodeType, parentNodeJcrId);
+ else
+ node = session.getNodeByIdentifier(nodeJcrId);
+
+ String editorId = getEditorForNode(node);
+
+ AkbNodeEditorInput eei = new AkbNodeEditorInput(
+ node.getIdentifier());
+
+ HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
+ .openEditor(eei, editorId);
+ } catch (PartInitException pie) {
+ throw new AkbException(
+ "Unexpected PartInitException while opening akb node editor",
+ pie);
+ } catch (RepositoryException e) {
+ throw new AkbException("unexpected JCR error while opening "
+ + nodeType + " editor", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ return null;
+ }
+
+ private Node createNewNode(Session session, String nodeType,
+ String parentNodeJcrId) throws RepositoryException {
+ Node parentNode = session.getNodeByIdentifier(parentNodeJcrId);
+ Node node = parentNode.addNode("new", nodeType);
+ // corresponding node is saved but not checked in, in order to ease
+ // cancel actions.
+ session.save();
+ return node;
+ }
+
+ private String getEditorForNode(Node node) throws RepositoryException {
+ String editorId = null;
+
+ if (node.isNodeType(AkbTypes.AKB_CONNECTOR_ALIAS))
+ editorId = AkbConnectorAliasEditor.ID;
+ else if (node.isNodeType(AkbTypes.AKB_ENV_TEMPLATE))
+ editorId = AkbEnvTemplateEditor.ID;
+ else
+ throw new AkbException("Editor is undefined for node " + node);
+ return editorId;
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.akb.ui.views;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import javax.jcr.Node;\r
+import javax.jcr.Repository;\r
+import javax.jcr.RepositoryException;\r
+import javax.jcr.Session;\r
+\r
+import org.argeo.eclipse.ui.utils.CommandUtils;\r
+import org.argeo.slc.akb.AkbException;\r
+import org.argeo.slc.akb.AkbNames;\r
+import org.argeo.slc.akb.AkbTypes;\r
+import org.argeo.slc.akb.ui.AkbUiPlugin;\r
+import org.argeo.slc.akb.ui.commands.OpenAkbNodeEditor;\r
+import org.argeo.slc.akb.ui.providers.AkbTreeLabelProvider;\r
+import org.argeo.slc.akb.ui.providers.TemplatesTreeContentProvider;\r
+import org.eclipse.jface.action.IMenuListener;\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.action.MenuManager;\r
+import org.eclipse.jface.viewers.DoubleClickEvent;\r
+import org.eclipse.jface.viewers.IDoubleClickListener;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.TreeViewer;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Menu;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.part.ViewPart;\r
+\r
+/** SLC generic JCR Result tree view. */\r
+public class AkbTemplatesTreeView extends ViewPart {\r
+ // private final static Log log =\r
+ // LogFactory.getLog(JcrResultTreeView.class);\r
+\r
+ public final static String ID = AkbUiPlugin.PLUGIN_ID\r
+ + ".akbTemplatesTreeView";\r
+\r
+ /* DEPENDENCY INJECTION */\r
+ private Session session;\r
+\r
+ // This page widgets\r
+ private TreeViewer resultTreeViewer;\r
+\r
+ // Usefull business objects\r
+ private Node templatesParentNode;\r
+\r
+ // private EventListener myResultsObserver = null;\r
+ // private EventListener allResultsObserver = null;\r
+ //\r
+ // // under My Results\r
+ // private final static String[] observedNodeTypesUnderMyResult = {\r
+ // SlcTypes.SLC_TEST_RESULT, SlcTypes.SLC_RESULT_FOLDER,\r
+ // SlcTypes.SLC_MY_RESULT_ROOT_FOLDER };\r
+ //\r
+ // private final static String[] observedNodeTypesUnderAllResults = {\r
+ // SlcTypes.SLC_TEST_RESULT, NodeType.NT_UNSTRUCTURED };\r
+ //\r
+ // private boolean isResultFolder = false;\r
+\r
+ // /**\r
+ // * To be overridden to adapt size of form and result frames.\r
+ // */\r
+ // protected int[] getWeights() {\r
+ // return new int[] { 70, 30 };\r
+ // }\r
+\r
+ private void initialize() {\r
+ try {\r
+ templatesParentNode = session\r
+ .getNode(AkbNames.AKB_TEMPLATES_BASE_PATH);\r
+ } catch (RepositoryException e) {\r
+ throw new AkbException("unable to initialize AKB Browser view", e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void createPartControl(Composite parent) {\r
+ initialize();\r
+\r
+ createResultsTreeViewer(parent);\r
+\r
+ // parent.setLayout(new FillLayout());\r
+ // // Main layout\r
+ // SashForm sashForm = new SashForm(parent, SWT.VERTICAL);\r
+ // sashForm.setSashWidth(4);\r
+ // sashForm.setLayout(new FillLayout());\r
+\r
+ // Create the tree on top of the view\r
+ // Composite top = new Composite(sashForm, SWT.NONE);\r
+ // GridLayout gl = new GridLayout(1, false);\r
+ // top.setLayout(gl);\r
+ // resultTreeViewer = createResultsTreeViewer(top);\r
+\r
+ // // Create the property viewer on the bottom\r
+ // Composite bottom = new Composite(sashForm, SWT.NONE);\r
+ // bottom.setLayout(new GridLayout(1, false));\r
+ // propertiesViewer = createPropertiesViewer(bottom);\r
+ //\r
+ // sashForm.setWeights(getWeights());\r
+\r
+ // setOrderedInput(resultTreeViewer);\r
+\r
+ // Initialize observer\r
+ // try {\r
+ // ObservationManager observationManager = session.getWorkspace()\r
+ // .getObservationManager();\r
+ // myResultsObserver = new MyResultsObserver(resultTreeViewer\r
+ // .getTree().getDisplay());\r
+ // allResultsObserver = new AllResultsObserver(resultTreeViewer\r
+ // .getTree().getDisplay());\r
+ //\r
+ // // observe tree changes under MyResults\r
+ // observationManager.addEventListener(myResultsObserver,\r
+ // Event.NODE_ADDED | Event.NODE_REMOVED,\r
+ // SlcJcrResultUtils.getMyResultsBasePath(session), true,\r
+ // null, observedNodeTypesUnderMyResult, false);\r
+ // // observe tree changes under All results\r
+ // observationManager.addEventListener(allResultsObserver,\r
+ // Event.NODE_ADDED | Event.NODE_REMOVED,\r
+ // SlcJcrResultUtils.getSlcResultsBasePath(session), true,\r
+ // null, observedNodeTypesUnderAllResults, false);\r
+ // } catch (RepositoryException e) {\r
+ // throw new SlcException("Cannot register listeners", e);\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * Override default behaviour so that default defined order remains\r
+ * unchanged on first level of the tree\r
+ */\r
+ // private void setOrderedInput(TreeViewer viewer) {\r
+ // // Add specific ordering\r
+ // viewer.setInput(null);\r
+ // viewer.setComparator(null);\r
+ // viewer.setInput(initializeResultTree());\r
+ // viewer.setComparator(new ResultItemsComparator());\r
+ // }\r
+\r
+ // The main tree viewer\r
+ protected TreeViewer createResultsTreeViewer(Composite parent) {\r
+ int style = SWT.BORDER | SWT.MULTI;\r
+\r
+ TreeViewer viewer = new TreeViewer(parent, style);\r
+ viewer.getTree().setLayoutData(\r
+ new GridData(SWT.FILL, SWT.FILL, true, true));\r
+\r
+ viewer.setContentProvider(new TemplatesTreeContentProvider());\r
+ viewer.setLabelProvider(new AkbTreeLabelProvider());\r
+ viewer.addDoubleClickListener(new ViewDoubleClickListener());\r
+\r
+ // Add label provider with label decorator\r
+ // ResultTreeLabelProvider rtLblProvider = new\r
+ // ResultTreeLabelProvider();\r
+ // ILabelDecorator decorator = AkbUiPlugin.getDefault().getWorkbench()\r
+ // .getDecoratorManager().getLabelDecorator();\r
+ // viewer.setLabelProvider(new DecoratingLabelProvider(rtLblProvider,\r
+ // decorator));\r
+ // viewer.addDoubleClickListener(new ViewDoubleClickListener());\r
+\r
+ // Override default behaviour to insure that 2 distincts results that\r
+ // have the same name will be correctly and distincly returned by\r
+ // corresponding TreeViewer.getSelection() method.\r
+ // viewer.setComparer(new ResultItemsComparer());\r
+\r
+ getSite().setSelectionProvider(viewer);\r
+\r
+ // // add drag & drop support\r
+ // int operations = DND.DROP_COPY | DND.DROP_MOVE;\r
+ // Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };\r
+ // viewer.addDragSupport(operations, tt, new ViewDragListener());\r
+ // viewer.addDropSupport(operations, tt, new ViewDropListener(viewer));\r
+\r
+ // add context menu\r
+ MenuManager menuManager = new MenuManager();\r
+ Menu menu = menuManager.createContextMenu(viewer.getTree());\r
+ menuManager.addMenuListener(new IMenuListener() {\r
+ public void menuAboutToShow(IMenuManager manager) {\r
+ contextMenuAboutToShow(manager);\r
+ }\r
+ });\r
+ viewer.getTree().setMenu(menu);\r
+ menuManager.setRemoveAllWhenShown(true);\r
+\r
+ getSite().registerContextMenu(menuManager, viewer);\r
+\r
+ // add change listener to display TestResult information in the property\r
+ // viewer\r
+ // viewer.addSelectionChangedListener(new MySelectionChangedListener());\r
+ return viewer;\r
+ }\r
+\r
+ // Detailed property viewer\r
+ // protected TableViewer createPropertiesViewer(Composite parent) {\r
+ // }\r
+\r
+ @Override\r
+ public void setFocus() {\r
+ }\r
+\r
+ // private ResultParent[] initializeResultTree() {\r
+ // try {\r
+ // // Force initialization of the tree structure if needed\r
+ // SlcJcrResultUtils.getSlcResultsParentNode(session);\r
+ // SlcJcrResultUtils.getMyResultParentNode(session);\r
+ // // Remove yesterday and last 7 days virtual folders\r
+ // // ResultParent[] roots = new ResultParent[5];\r
+ // ResultParent[] roots = new ResultParent[3];\r
+ //\r
+ // // My results\r
+ // roots[0] = new ParentNodeFolder(null,\r
+ // SlcJcrResultUtils.getMyResultParentNode(session),\r
+ // SlcUiConstants.DEFAULT_MY_RESULTS_FOLDER_LABEL);\r
+ //\r
+ // // today\r
+ // Calendar cal = Calendar.getInstance();\r
+ // String relPath = JcrUtils.dateAsPath(cal);\r
+ // List<String> datePathes = new ArrayList<String>();\r
+ // datePathes.add(relPath);\r
+ // roots[1] = new VirtualFolder(null,\r
+ // ResultParentUtils.getResultsForDates(session, datePathes),\r
+ // "Today");\r
+ //\r
+ // // // Yesterday\r
+ // // cal = Calendar.getInstance();\r
+ // // cal.add(Calendar.DAY_OF_YEAR, -1);\r
+ // // relPath = JcrUtils.dateAsPath(cal);\r
+ // // datePathes = new ArrayList<String>();\r
+ // // datePathes.add(relPath);\r
+ // // roots[2] = new VirtualFolder(null,\r
+ // // ResultParentUtils.getResultsForDates(session, datePathes),\r
+ // // "Yesterday");\r
+ // // // Last 7 days\r
+ // //\r
+ // // cal = Calendar.getInstance();\r
+ // // datePathes = new ArrayList<String>();\r
+ // //\r
+ // // for (int i = 0; i < 7; i++) {\r
+ // // cal.add(Calendar.DAY_OF_YEAR, -i);\r
+ // // relPath = JcrUtils.dateAsPath(cal);\r
+ // // datePathes.add(relPath);\r
+ // // }\r
+ // // roots[3] = new VirtualFolder(null,\r
+ // // ResultParentUtils.getResultsForDates(session, datePathes),\r
+ // // "Last 7 days");\r
+ //\r
+ // // All results\r
+ // Node otherResultsPar = session.getNode(SlcJcrResultUtils\r
+ // .getSlcResultsBasePath(session));\r
+ // // roots[4] = new ParentNodeFolder(null, otherResultsPar,\r
+ // // "All results");\r
+ // roots[2] = new ParentNodeFolder(null, otherResultsPar,\r
+ // "All results");\r
+ // return roots;\r
+ // } catch (RepositoryException re) {\r
+ // throw new ArgeoException(\r
+ // "Unexpected error while initializing ResultTree.", re);\r
+ // }\r
+ // }\r
+\r
+ // Manage context menu\r
+ /**\r
+ * Defines the commands that will pop up in the context menu.\r
+ **/\r
+ protected void contextMenuAboutToShow(IMenuManager menuManager) {\r
+ IWorkbenchWindow window = AkbUiPlugin.getDefault().getWorkbench()\r
+ .getActiveWorkbenchWindow();\r
+ try {\r
+ // IStructuredSelection selection = (IStructuredSelection)\r
+ // resultTreeViewer\r
+ // .getSelection();\r
+ // boolean canAddSubfolder = false;\r
+ // boolean canRenamefolder = false;\r
+ // boolean isSingleResultNode = false;\r
+ // boolean isUnderMyResult = false;\r
+ // boolean validMultipleDelete = false;\r
+ //\r
+ // // Building conditions\r
+ // if (selection.size() == 1) {\r
+ // Object obj = selection.getFirstElement();\r
+ // if (obj instanceof SingleResultNode)\r
+ // isSingleResultNode = true;\r
+ // else if (obj instanceof ParentNodeFolder) {\r
+ // Node cNode = ((ParentNodeFolder) obj).getNode();\r
+ // if (cNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {\r
+ // canAddSubfolder = true;\r
+ // canRenamefolder = true;\r
+ // isUnderMyResult = true;\r
+ // } else if (cNode\r
+ // .isNodeType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER)) {\r
+ // canAddSubfolder = true;\r
+ // }\r
+ // }\r
+ // } else {\r
+ // @SuppressWarnings("rawtypes")\r
+ // Iterator it = selection.iterator();\r
+ // multicheck: while (it.hasNext()) {\r
+ // validMultipleDelete = true;\r
+ // Object obj = it.next();\r
+ // if (obj instanceof SingleResultNode)\r
+ // continue multicheck;\r
+ // else if (obj instanceof ParentNodeFolder) {\r
+ // Node cNode = ((ParentNodeFolder) obj).getNode();\r
+ // if (cNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER))\r
+ // continue multicheck;\r
+ // else {\r
+ // validMultipleDelete = false;\r
+ // break multicheck;\r
+ // }\r
+ // } else {\r
+ // validMultipleDelete = false;\r
+ // break multicheck;\r
+ // }\r
+ // }\r
+ // }\r
+\r
+ Map<String, String> params = new HashMap<String, String>();\r
+ params.put(OpenAkbNodeEditor.PARAM_PARENT_NODE_JCR_ID,\r
+ templatesParentNode.getIdentifier());\r
+ params.put(OpenAkbNodeEditor.PARAM_NODE_TYPE,\r
+ AkbTypes.AKB_ENV_TEMPLATE);\r
+\r
+ // Effective Refresh\r
+ CommandUtils.refreshParametrizedCommand(menuManager, window,\r
+ OpenAkbNodeEditor.ID, "Create new template...", null, true,\r
+ params);\r
+\r
+ //\r
+ // CommandUtils.refreshCommand(menuManager, window, DeleteItems.ID,\r
+ // DeleteItems.DEFAULT_LABEL, DeleteItems.DEFAULT_IMG_DESCRIPTOR,\r
+ // isUnderMyResult || isSingleResultNode || validMultipleDelete);\r
+ //\r
+ // CommandUtils.refreshCommand(menuManager, window,\r
+ // AddResultFolder.ID,\r
+ // AddResultFolder.DEFAULT_LABEL,\r
+ // ClientUiPlugin.getDefault().getWorkbench().getSharedImages()\r
+ // .getImageDescriptor(ISharedImages.IMG_OBJ_ADD),\r
+ // canAddSubfolder);\r
+ //\r
+ // CommandUtils.refreshCommand(menuManager, window,\r
+ // RenameResultFolder.ID,\r
+ // RenameResultFolder.DEFAULT_LABEL,\r
+ // RenameResultFolder.DEFAULT_IMG_DESCRIPTOR, canRenamefolder);\r
+ //\r
+ // // Command removed for the time being.\r
+ // CommandUtils.refreshCommand(menuManager, window,\r
+ // RenameResultNode.ID,\r
+ // RenameResultNode.DEFAULT_LABEL,\r
+ // RenameResultNode.DEFAULT_IMG_DESCRIPTOR, false);\r
+ //\r
+ // // Test to be removed\r
+ // // If you use this pattern, do not forget to call\r
+ // // menuManager.setRemoveAllWhenShown(true);\r
+ // // when creating the menuManager\r
+ //\r
+ // // menuManager.add(new Action("Test") {\r
+ // // public void run() {\r
+ // // log.debug("do something");\r
+ // // }\r
+ // // });\r
+ } catch (RepositoryException re) {\r
+ throw new AkbException("Error while refreshing context menu", re);\r
+ }\r
+ }\r
+\r
+ /* INNER CLASSES */\r
+ class ViewDoubleClickListener implements IDoubleClickListener {\r
+ public void doubleClick(DoubleClickEvent evt) {\r
+ Object obj = ((IStructuredSelection) evt.getSelection())\r
+ .getFirstElement();\r
+ try {\r
+ if (obj instanceof Node) {\r
+ Node node = (Node) obj;\r
+ CommandUtils.callCommand(OpenAkbNodeEditor.ID,\r
+ OpenAkbNodeEditor.PARAM_NODE_JCR_ID,\r
+ node.getIdentifier());\r
+ }\r
+ } catch (RepositoryException e) {\r
+ throw new AkbException("Cannot open " + obj, e);\r
+ }\r
+ }\r
+ }\r
+\r
+ // class MyResultsObserver extends AsyncUiEventListener {\r
+ //\r
+ // public MyResultsObserver(Display display) {\r
+ // super(display);\r
+ // }\r
+ //\r
+ // @Override\r
+ // protected Boolean willProcessInUiThread(List<Event> events)\r
+ // throws RepositoryException {\r
+ // // unfiltered for the time being\r
+ // return true;\r
+ // }\r
+ //\r
+ // protected void onEventInUiThread(List<Event> events)\r
+ // throws RepositoryException {\r
+ // List<Node> nodesToRefresh = new ArrayList<Node>();\r
+ //\r
+ // for (Event event : events) {\r
+ // String parPath = JcrUtils.parentPath(event.getPath());\r
+ // if (session.nodeExists(parPath)) {\r
+ // Node node = session.getNode(parPath);\r
+ // if (!nodesToRefresh.contains(node)) {\r
+ // nodesToRefresh.add(node);\r
+ // }\r
+ // }\r
+ // }\r
+ //\r
+ // // Update check nodes\r
+ // for (Node node : nodesToRefresh)\r
+ // jcrRefresh(node);\r
+ // refresh(null);\r
+ // }\r
+ // }\r
+\r
+ // class AllResultsObserver extends AsyncUiEventListener {\r
+ //\r
+ // public AllResultsObserver(Display display) {\r
+ // super(display);\r
+ // }\r
+ //\r
+ // @Override\r
+ // protected Boolean willProcessInUiThread(List<Event> events)\r
+ // throws RepositoryException {\r
+ // // unfiltered for the time being\r
+ // return true;\r
+ // }\r
+ //\r
+ // protected void onEventInUiThread(List<Event> events)\r
+ // throws RepositoryException {\r
+ // refresh(null);\r
+ // // if (lastSelectedSourceElementParent != null)\r
+ // // refresh(lastSelectedSourceElementParent);\r
+ // }\r
+ // }\r
+\r
+ /* DEPENDENCY INJECTION */\r
+ public void setRepository(Repository repository) {\r
+ try {\r
+ session = repository.login();\r
+ } catch (RepositoryException e) {\r
+ throw new AkbException("unable to log in for " + ID + " view");\r
+ }\r
+ }\r
+}
\ No newline at end of file