X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=plugins%2Forg.argeo.slc.client.ui%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fclient%2Fui%2Fviews%2FJcrResultTreeView.java;h=bef8f208260e15f48333ff02c5753e6f919df4c4;hb=9aa71322cd6bc61cd7da179ed21e3bcbefb21cff;hp=a00548a2c3d069aa1bd585775c92cc18a29881e2;hpb=844bc386a1854a29d282a23ffda820ed7a52b74e;p=gpl%2Fargeo-slc.git diff --git a/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java b/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java index a00548a2c..bef8f2082 100644 --- a/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java +++ b/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java @@ -1,6 +1,7 @@ package org.argeo.slc.client.ui.views; import java.util.ArrayList; +import java.util.Calendar; import java.util.List; import javax.jcr.Node; @@ -11,12 +12,11 @@ import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; +import javax.jcr.nodetype.NodeType; import javax.jcr.observation.Event; import javax.jcr.observation.EventListener; import javax.jcr.observation.ObservationManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.argeo.eclipse.ui.jcr.AsyncUiEventListener; import org.argeo.eclipse.ui.utils.CommandUtils; @@ -24,11 +24,16 @@ import org.argeo.jcr.JcrUtils; import org.argeo.jcr.UserJcrUtils; import org.argeo.slc.SlcException; import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.SlcUiConstants; import org.argeo.slc.client.ui.commands.AddResultFolder; +import org.argeo.slc.client.ui.editors.ProcessEditor; +import org.argeo.slc.client.ui.editors.ProcessEditorInput; +import org.argeo.slc.client.ui.model.ParentNodeFolder; import org.argeo.slc.client.ui.model.ResultFolder; import org.argeo.slc.client.ui.model.ResultParent; -import org.argeo.slc.client.ui.model.SimpleNodeFolder; +import org.argeo.slc.client.ui.model.ResultParentUtils; import org.argeo.slc.client.ui.model.SingleResultNode; +import org.argeo.slc.client.ui.model.VirtualFolder; import org.argeo.slc.client.ui.providers.ResultTreeContentProvider; import org.argeo.slc.client.ui.providers.ResultTreeLabelProvider; import org.argeo.slc.jcr.SlcJcrResultUtils; @@ -39,6 +44,8 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.DecoratingLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; @@ -64,14 +71,17 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; /** SLC generic JCR Result tree view. */ public class JcrResultTreeView extends ViewPart { public final static String ID = ClientUiPlugin.ID + ".jcrResultTreeView"; - private final static Log log = LogFactory.getLog(JcrResultTreeView.class); + // private final static Log log = + // LogFactory.getLog(JcrResultTreeView.class); /* DEPENDENCY INJECTION */ private Session session; @@ -82,7 +92,14 @@ public class JcrResultTreeView extends ViewPart { private EventListener resultsObserver = null; - private final static String[] observedNodeTypes = { SlcTypes.SLC_TEST_RESULT }; + private final static String[] observedNodeTypes = { + SlcTypes.SLC_TEST_RESULT, SlcTypes.SLC_RESULT_FOLDER, + NodeType.NT_UNSTRUCTURED }; + + // FIXME cache to ease refresh after D&D + private ResultParent lastSelectedTargetElement; + private ResultParent lastSelectedTargetElementParent; + private ResultParent lastSelectedSourceElementParent; /** * To be overridden to adapt size of form and result frames. @@ -114,23 +131,6 @@ public class JcrResultTreeView extends ViewPart { // Refresh the view to initialize it refresh(null); - - try { - ObservationManager observationManager = session.getWorkspace() - .getObservationManager(); - // FIXME Will not be notified if empty result is deleted - if (UserJcrUtils.getUserHome(session) != null) { - resultsObserver = new ResultObserver(resultTreeViewer.getTree() - .getDisplay()); - observationManager.addEventListener(resultsObserver, - Event.PROPERTY_ADDED | Event.NODE_REMOVED, UserJcrUtils - .getUserHome(session).getPath(), true, null, - observedNodeTypes, false); - } - } catch (RepositoryException e) { - throw new SlcException("Cannot register listeners", e); - } - } // The main tree viewer @@ -149,6 +149,8 @@ public class JcrResultTreeView extends ViewPart { .getDecoratorManager().getLabelDecorator(); viewer.setLabelProvider(new DecoratingLabelProvider(rtLblProvider, decorator)); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + // viewer.setLabelProvider(rtLblProvider); getSite().setSelectionProvider(viewer); @@ -183,10 +185,12 @@ public class JcrResultTreeView extends ViewPart { .getNode()); else propertiesViewer.setInput(null); + lastSelectedTargetElement = (ResultParent) firstItem; + lastSelectedTargetElementParent = (ResultParent) ((ResultParent) firstItem) + .getParent(); } } }); - return viewer; } @@ -256,6 +260,33 @@ public class JcrResultTreeView extends ViewPart { return propertiesViewer; } + /** + * Override to provide specific behaviour. Typically to enable the display + * of a result file. + * + * @param evt + */ + protected void processDoubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + try { + if (obj instanceof SingleResultNode) { + SingleResultNode srNode = (SingleResultNode) obj; + Node node = srNode.getNode(); + // FIXME: open a default result editor + if (node.isNodeType(SlcTypes.SLC_PROCESS)) { + IWorkbenchPage activePage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + activePage.openEditor( + new ProcessEditorInput(node.getPath()), + ProcessEditor.ID); + } + } + } catch (Exception e) { + throw new SlcException("Cannot open " + obj, e); + } + } + @Override public void setFocus() { } @@ -308,16 +339,13 @@ public class JcrResultTreeView extends ViewPart { if (resultParent == null) { resultTreeViewer.setInput(initializeResultTree()); if (resultsObserver == null) { - // force initialization of the resultsObserver, only useful - // if the current view has been displayed before a single - // test has been run try { ObservationManager observationManager = session .getWorkspace().getObservationManager(); resultsObserver = new ResultObserver(resultTreeViewer .getTree().getDisplay()); observationManager.addEventListener(resultsObserver, - Event.PROPERTY_ADDED | Event.NODE_REMOVED, UserJcrUtils + Event.NODE_ADDED | Event.NODE_REMOVED, UserJcrUtils .getUserHome(session).getPath(), true, null, observedNodeTypes, false); } catch (RepositoryException e) { @@ -331,21 +359,63 @@ public class JcrResultTreeView extends ViewPart { ResultFolder currFolder = (ResultFolder) resultParent; jcrRefresh(currFolder.getNode()); currFolder.forceFullRefresh(); + resultTreeViewer.refresh(lastSelectedTargetElement); } } } private ResultParent[] initializeResultTree() { - ResultParent[] roots = new ResultParent[2]; try { - roots[0] = new ResultFolder(null, - SlcJcrResultUtils.getMyResultParentNode(session), - "My results"); - Node otherResultsPar = session.getNode(SlcJcrResultUtils - .getSlcResultsBasePath(session)); - roots[1] = new SimpleNodeFolder(null, otherResultsPar, - "All results"); - return roots; + if (session.nodeExists(SlcJcrResultUtils + .getSlcResultsBasePath(session))) { + ResultParent[] roots = new ResultParent[5]; + + // My results + roots[0] = new ParentNodeFolder(null, + SlcJcrResultUtils.getMyResultParentNode(session), + SlcUiConstants.DEFAULT_MY_RESULTS_FOLDER_LABEL); + + // today + Calendar cal = Calendar.getInstance(); + String relPath = JcrUtils.dateAsPath(cal); + List datePathes = new ArrayList(); + datePathes.add(relPath); + roots[1] = new VirtualFolder(null, + ResultParentUtils.getResultsForDates(session, + datePathes), "Today"); + + // Yesterday + cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_YEAR, -1); + relPath = JcrUtils.dateAsPath(cal); + datePathes = new ArrayList(); + datePathes.add(relPath); + roots[2] = new VirtualFolder(null, + ResultParentUtils.getResultsForDates(session, + datePathes), "Yesterday"); + // Last 7 days + + cal = Calendar.getInstance(); + datePathes = new ArrayList(); + + for (int i = 0; i < 7; i++) { + cal.add(Calendar.DAY_OF_YEAR, -i); + relPath = JcrUtils.dateAsPath(cal); + datePathes.add(relPath); + } + roots[3] = new VirtualFolder(null, + ResultParentUtils.getResultsForDates(session, + datePathes), "Last 7 days"); + + // All results + Node otherResultsPar = session.getNode(SlcJcrResultUtils + .getSlcResultsBasePath(session)); + roots[4] = new ParentNodeFolder(null, otherResultsPar, + "All results"); + return roots; + } else + // no test has yet been processed, we leave the viewer blank + return null; } catch (RepositoryException re) { throw new ArgeoException( "Unexpected error while initializing ResultTree.", re); @@ -367,13 +437,15 @@ public class JcrResultTreeView extends ViewPart { if (selection.size() == 1) { Object obj = selection.getFirstElement(); try { - Node targetParentNode = null; - if (obj instanceof ResultFolder) { - targetParentNode = ((ResultFolder) obj).getNode(); - - if (targetParentNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER)) - isMyResultFolder = true; - } + if (obj instanceof ResultFolder + && (((ResultFolder) obj).getNode()) + .isNodeType(SlcTypes.SLC_RESULT_FOLDER)) + isMyResultFolder = true; + else if (obj instanceof ParentNodeFolder + && (((ParentNodeFolder) obj).getNode().getPath() + .startsWith(SlcJcrResultUtils + .getMyResultsBasePath(session)))) + isMyResultFolder = true; } catch (RepositoryException re) { throw new SlcException( "unexpected error while building condition for context menu", @@ -393,7 +465,6 @@ public class JcrResultTreeView extends ViewPart { public void dragStart(DragSourceEvent event) { // Check if the drag action should start. - IStructuredSelection selection = (IStructuredSelection) resultTreeViewer .getSelection(); boolean doIt = false; @@ -403,12 +474,16 @@ public class JcrResultTreeView extends ViewPart { if (obj instanceof SingleResultNode) { Node tNode = ((SingleResultNode) obj).getNode(); try { + // if (tNode.getPrimaryNodeType().isNodeType( + // SlcTypes.SLC_TEST_RESULT) + // && (tNode.getPath() + // .startsWith(SlcJcrResultUtils + // .getSlcResultsBasePath(session)))) if (tNode.getPrimaryNodeType().isNodeType( - SlcTypes.SLC_TEST_RESULT) - && (tNode.getPath() - .startsWith(SlcJcrResultUtils - .getSlcResultsBasePath(session)))) + SlcTypes.SLC_TEST_RESULT)) doIt = true; + lastSelectedSourceElementParent = (ResultParent) ((SingleResultNode) obj) + .getParent(); } catch (RepositoryException re) { throw new SlcException( "unexpected error while validating drag source", @@ -427,6 +502,7 @@ public class JcrResultTreeView extends ViewPart { Node first = ((SingleResultNode) obj).getNode(); try { event.data = first.getIdentifier(); + } catch (RepositoryException re) { throw new SlcException( "unexpected error while setting data", re); @@ -443,6 +519,7 @@ public class JcrResultTreeView extends ViewPart { protected class ViewDropListener extends ViewerDropAdapter { private Node currParentNode = null; + private boolean copyNode = true; public ViewDropListener(Viewer viewer) { super(viewer); @@ -456,20 +533,40 @@ public class JcrResultTreeView extends ViewPart { // We can only drop under myResults Node targetParentNode = null; if (target instanceof ResultFolder) { - Node currNode = ((ResultFolder) target).getNode(); - - if (currNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER)) { - targetParentNode = currNode; - } + targetParentNode = ((ResultFolder) target).getNode(); + } else if (target instanceof ParentNodeFolder) { + if ((((ParentNodeFolder) target).getNode().getPath() + .startsWith(SlcJcrResultUtils + .getMyResultsBasePath(session)))) + targetParentNode = ((ParentNodeFolder) target) + .getNode(); } else if (target instanceof SingleResultNode) { Node currNode = ((SingleResultNode) target).getNode(); - if (currNode.getParent().isNodeType( - SlcTypes.SLC_RESULT_FOLDER)) + if (currNode + .getParent() + .getPath() + .startsWith( + SlcJcrResultUtils + .getMyResultsBasePath(session))) targetParentNode = currNode.getParent(); } if (targetParentNode != null) { currParentNode = targetParentNode; validDrop = true; + // FIXME + lastSelectedTargetElement = (ResultParent) target; + lastSelectedTargetElementParent = (ResultParent) ((ResultParent) target) + .getParent(); + } + // Check if it's a move or a copy + if (validDrop) { + String pPath = ""; + if (lastSelectedSourceElementParent instanceof ResultFolder) + pPath = ((ResultFolder) lastSelectedSourceElementParent) + .getNode().getPath(); + if ((pPath.startsWith(SlcJcrResultUtils + .getMyResultsBasePath(session)))) + copyNode = false; } } catch (RepositoryException re) { throw new SlcException( @@ -483,71 +580,37 @@ public class JcrResultTreeView extends ViewPart { try { Node source = session.getNodeByIdentifier((String) data); - Node target = currParentNode.addNode(source.getName(), source - .getPrimaryNodeType().getName()); - JcrUtils.copy(source, target); - updatePassedStatus(target, target.getNode(SlcNames.SLC_STATUS) - .getProperty(SlcNames.SLC_SUCCESS).getBoolean()); - target.getSession().save(); + if (copyNode) { + Node target = currParentNode.addNode(source.getName(), + source.getPrimaryNodeType().getName()); + JcrUtils.copy(source, target); + ResultParentUtils.updatePassedStatus( + target, + target.getNode(SlcNames.SLC_STATUS) + .getProperty(SlcNames.SLC_SUCCESS) + .getBoolean()); + target.getSession().save(); + } else // move only + { + String sourcePath = source.getPath(); + String destPath = currParentNode.getPath() + "/" + + source.getName(); + session.move(sourcePath, destPath); + session.save(); + Node target = session.getNode(destPath); + ResultParentUtils.updatePassedStatus( + target, + target.getNode(SlcNames.SLC_STATUS) + .getProperty(SlcNames.SLC_SUCCESS) + .getBoolean()); + session.save(); + } } catch (RepositoryException re) { throw new SlcException( "unexpected error while copying dropped node", re); } return true; } - - /** - * recursively update passed status of the parent ResultFolder and its - * parent if needed - * - * @param node - * cannot be null - * - */ - private void updatePassedStatus(Node node, boolean passed) { - try { - Node pNode = node.getParent(); - boolean pStatus = pNode.getNode(SlcNames.SLC_STATUS) - .getProperty(SlcNames.SLC_SUCCESS).getBoolean(); - if (pStatus == passed) - // nothing to update - return; - else if (!passed) { - // error we only update status of the result folder and its - // parent if needed - pNode.getNode(SlcNames.SLC_STATUS).setProperty( - SlcNames.SLC_SUCCESS, passed); - updatePassedStatus(pNode, passed); - } else { - // success we must first check if all siblings have also - // successfully completed - boolean success = true; - NodeIterator ni = pNode.getNodes(); - children: while (ni.hasNext()) { - Node currNode = ni.nextNode(); - if ((currNode.isNodeType(SlcTypes.SLC_DIFF_RESULT) || currNode - .isNodeType(SlcTypes.SLC_RESULT_FOLDER)) - && !currNode.getNode(SlcNames.SLC_STATUS) - .getProperty(SlcNames.SLC_SUCCESS) - .getBoolean()) { - success = false; - break children; - } - } - if (success) { - pNode.getNode(SlcNames.SLC_STATUS).setProperty( - SlcNames.SLC_SUCCESS, passed); - updatePassedStatus(pNode, passed); - } else - // one of the siblings had also the failed status so - // above tree remains unchanged. - return; - } - - } catch (RepositoryException e) { - throw new SlcException("Cannot register listeners", e); - } - } } class ResultObserver extends AsyncUiEventListener { @@ -559,35 +622,63 @@ public class JcrResultTreeView extends ViewPart { @Override protected Boolean willProcessInUiThread(List events) throws RepositoryException { - for (Event event : events) { - // getLog().debug("Received event " + event); - int eventType = event.getType(); - if (eventType == Event.NODE_REMOVED) - return true; - String path = event.getPath(); - int index = path.lastIndexOf('/'); - String propertyName = path.substring(index + 1); - if (propertyName.equals(SlcNames.SLC_COMPLETED) - || propertyName.equals(SlcNames.SLC_UUID)) { - return true; - } - } - return false; + // unfiltered for the time being + return true; + // for (Event event : events) { + // getLog().debug("Received event " + event); + // int eventType = event.getType(); + // if (eventType == Event.NODE_REMOVED) + // ;//return true; + // String path = event.getPath(); + // int index = path.lastIndexOf('/'); + // String propertyName = path.substring(index + 1); + // if (propertyName.equals(SlcNames.SLC_COMPLETED) + // || propertyName.equals(SlcNames.SLC_UUID)) { + // ;//return true; + // } + // } + // return false; } protected void onEventInUiThread(List events) throws RepositoryException { - // FIXME implement correct behaviour. treeViewer selection is - // disposed by the drag & drop. - // resultTreeViewer.refresh(); - // refresh(null); - // log.warn("Implement refresh."); - } + for (Event event : events) { + getLog().debug("Received event " + event); + int eventType = event.getType(); + if (eventType == Event.NODE_REMOVED) { + String path = event.getPath(); + int index = path.lastIndexOf('/'); + String parPath = path.substring(0, index + 1); + if (session.nodeExists(parPath)) { + Node currNode = session.getNode(parPath); + if (currNode.isNodeType(NodeType.NT_UNSTRUCTURED)) { + refresh(null); + jcrRefresh(currNode); + resultTreeViewer.refresh(true); + resultTreeViewer.expandToLevel( + lastSelectedTargetElementParent, 1); + + } + } + } else if (eventType == Event.NODE_ADDED) { + String path = event.getPath(); + if (session.nodeExists(path)) { + Node currNode = session.getNode(path); + if (currNode.isNodeType(SlcTypes.SLC_DIFF_RESULT) + || currNode + .isNodeType(SlcTypes.SLC_RESULT_FOLDER)) { + refresh(null); + resultTreeViewer.expandToLevel( + lastSelectedTargetElement, 1); + } + } + } + } + } } class PropertiesContentProvider implements IStructuredContentProvider { - // private JcrItemsComparator itemComparator = new JcrItemsComparator(); public void dispose() { } @@ -613,6 +704,13 @@ public class JcrResultTreeView extends ViewPart { } } + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + processDoubleClick(evt); + } + + } + /* DEPENDENCY INJECTION */ public void setSession(Session session) { this.session = session;