First implementation of the version page of the generic node editor
authorBruno Sinou <bsinou@argeo.org>
Wed, 7 Sep 2011 20:15:38 +0000 (20:15 +0000)
committerBruno Sinou <bsinou@argeo.org>
Wed, 7 Sep 2011 20:15:38 +0000 (20:15 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4735 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

14 files changed:
server/plugins/org.argeo.jcr.ui.explorer/META-INF/MANIFEST.MF
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/JcrExplorerPerspective.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/SingleNodeAsTreeContentProvider.java [deleted file]
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/ChildNodesPage.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/GenericNodePage.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/NodeRightsManagementPage.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/editors/NodeVersionHistoryPage.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/FullVersioningTreeContentProvider.java [new file with mode: 0644]
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/SingleNodeAsTreeContentProvider.java [new file with mode: 0644]
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/VersionLabelProvider.java [new file with mode: 0644]
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/GenericNodeDoubleClickListener.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrUiUtils.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/views/GenericJcrBrowser.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/resources/org/argeo/jcr/ui/explorer/messages.properties

index 896f7fa3691fef33d6292db1a6865cc89d66e0c9..869e0a2aa7e151dc7f3d0f9fb54b7a7d9b46abf3 100644 (file)
@@ -14,6 +14,7 @@ Bundle-ActivationPolicy: lazy
 Import-Package: javax.jcr,
  javax.jcr.nodetype,
  javax.jcr.observation,
+ javax.jcr.version,
  org.apache.commons.io,
  org.apache.commons.logging,
  org.argeo,
index 487784d4ecb6e357b6d62cf2ef9c9418e4382402..9698a1933c5eea36a80b3a356ebcdf6fcd7eab75 100644 (file)
@@ -4,6 +4,7 @@ import org.eclipse.ui.IFolderLayout;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveFactory;
 
+/** Base perspective for JcrExplorer browser */
 public class JcrExplorerPerspective implements IPerspectiveFactory {
        public static String BROWSER_VIEW_ID = JcrExplorerPlugin.ID
                        + ".browserView";
diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/SingleNodeAsTreeContentProvider.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/SingleNodeAsTreeContentProvider.java
deleted file mode 100644 (file)
index 7666589..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.argeo.jcr.ui.explorer.browser;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Implementation of the {@code ITreeContentProvider} in order to display a
- * single JCR node and its children in a tree like structure
- * 
- */
-public class SingleNodeAsTreeContentProvider implements ITreeContentProvider {
-       // private Node rootNode;
-       private ItemComparator itemComparator = new ItemComparator();
-
-       /**
-        * Sends back the first level of the Tree. input element must be a single
-        * node object
-        */
-       public Object[] getElements(Object inputElement) {
-               try {
-                       Node rootNode = (Node) inputElement;
-                       List<Node> result = new ArrayList<Node>();
-                       NodeIterator ni = rootNode.getNodes();
-                       while (ni.hasNext()) {
-                               result.add(ni.nextNode());
-                       }
-
-                       return result.toArray();
-               } catch (RepositoryException re) {
-                       throw new ArgeoException(
-                                       "Unexpected error while getting child nodes for children editor page ",
-                                       re);
-               }
-       }
-
-       public Object[] getChildren(Object parentElement) {
-               return childrenNodes((Node) parentElement);
-       }
-
-       public Object getParent(Object element) {
-               try {
-                       Node node = (Node) element;
-                       if (!node.getPath().equals("/"))
-                               return node.getParent();
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       return null;
-               }
-       }
-
-       public boolean hasChildren(Object element) {
-               try {
-                       return ((Node) element).hasNodes();
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot check children of " + element, e);
-               }
-       }
-
-       public void dispose() {
-       }
-
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-       }
-
-       protected Object[] childrenNodes(Node parentNode) {
-               try {
-                       List<Node> children = new ArrayList<Node>();
-                       NodeIterator nit = parentNode.getNodes();
-                       while (nit.hasNext()) {
-                               Node node = nit.nextNode();
-                               children.add(node);
-                       }
-                       Node[] arr = children.toArray(new Node[children.size()]);
-                       Arrays.sort(arr, itemComparator);
-                       return arr;
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot list children of " + parentNode, e);
-               }
-       }
-}
index 58f4166e3734bb253960f7ca54c5219e2cf46e89..175c06dba0cd3c882f0cb6748138ae8040b74f7a 100644 (file)
@@ -4,8 +4,10 @@ import javax.jcr.Node;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
 import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider;
-import org.argeo.jcr.ui.explorer.browser.SingleNodeAsTreeContentProvider;
+import org.argeo.jcr.ui.explorer.providers.SingleNodeAsTreeContentProvider;
 import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.TreeViewer;
@@ -44,12 +46,18 @@ public class ChildNodesPage extends FormPage {
                        GridLayout twt = new GridLayout(1, false);
                        twt.marginWidth = twt.marginHeight = 0;
                        body.setLayout(twt);
+                       if (!currentNode.hasNodes()) {
+                               managedForm.getToolkit().createLabel(body,
+                                               JcrExplorerPlugin.getMessage("warningNoChildNode"));
+                       } else {
 
-                       nodeContentProvider = new SingleNodeAsTreeContentProvider();
-                       nodesViewer = createNodeViewer(body, nodeContentProvider);
-                       nodesViewer.setInput(currentNode);
+                               nodeContentProvider = new SingleNodeAsTreeContentProvider();
+                               nodesViewer = createNodeViewer(body, nodeContentProvider);
+                               nodesViewer.setInput(currentNode);
+                       }
                } catch (Exception e) {
-                       e.printStackTrace();
+                       throw new ArgeoException(
+                                       "Unexpected error while creating child node page", e);
                }
        }
 
index da01f3d49da4c0683564fea9237ed958d0ace15d..ca9d969925efc9219ab8c5f8f5ad922bd5d66aa9 100644 (file)
@@ -33,6 +33,11 @@ import org.eclipse.ui.forms.editor.FormPage;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.eclipse.ui.forms.widgets.ScrolledForm;
 
+/**
+ * Main node editor page. Lists all properties of the current node and enable
+ * access and editing for some of them.
+ */
+
 public class GenericNodePage extends FormPage implements JcrExplorerConstants {
        private final static Log log = LogFactory.getLog(GenericNodePage.class);
 
@@ -55,18 +60,13 @@ public class GenericNodePage extends FormPage implements JcrExplorerConstants {
        }
 
        protected void createFormContent(IManagedForm managedForm) {
-               try {
-                       tk = managedForm.getToolkit();
-                       ScrolledForm form = managedForm.getForm();
-                       GridLayout twt = new GridLayout(3, false);
-                       twt.marginWidth = twt.marginHeight = 5;
+               tk = managedForm.getToolkit();
+               ScrolledForm form = managedForm.getForm();
+               GridLayout twt = new GridLayout(3, false);
+               twt.marginWidth = twt.marginHeight = 5;
 
-                       form.getBody().setLayout(twt);
-
-                       createPropertiesPart(form.getBody());
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
+               form.getBody().setLayout(twt);
+               createPropertiesPart(form.getBody());
        }
 
        private void createPropertiesPart(Composite parent) {
index 04bbaaa18cc53aa36d2c5a3d7c25e042b11ed181..485264b138b76a9f882826e384bee1a581ca1685 100644 (file)
@@ -13,8 +13,7 @@ import org.eclipse.ui.forms.editor.FormPage;
 import org.eclipse.ui.forms.widgets.ScrolledForm;
 
 /**
- * This page is only used at editor's creation time when current node has not
- * yet been set
+ * This comments will be nicely fill by mbaudier in. 
  */
 public class NodeRightsManagementPage extends FormPage {
        private final static Log log = LogFactory.getLog(NodeRightsManagementPage.class);
index dd888d12b0bcb448547e547415f4901c20a491a4..bd8265ce9d40b71d79e559fa21ef3dffb878aeb5 100644 (file)
@@ -1,27 +1,72 @@
 package org.argeo.jcr.ui.explorer.editors;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+
 import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+import javax.jcr.version.VersionManager;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.PropertyDiff;
+import org.argeo.jcr.VersionDiff;
+import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.providers.FullVersioningTreeContentProvider;
+import org.argeo.jcr.ui.explorer.providers.VersionLabelProvider;
+import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.AbstractFormPart;
 import org.eclipse.ui.forms.IManagedForm;
 import org.eclipse.ui.forms.editor.FormEditor;
 import org.eclipse.ui.forms.editor.FormPage;
+import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
 /**
- * This page is only used at editor's creation time when current node has not
- * yet been set
- */
-public class NodeVersionHistoryPage extends FormPage {
+ * Offers two main sections : one to display a text area with a summary of all
+ * variations between a version and its predecessor and one tree view that
+ * enable browsing
+ * */
+public class NodeVersionHistoryPage extends FormPage implements
+               JcrExplorerConstants {
        private final static Log log = LogFactory
                        .getLog(NodeVersionHistoryPage.class);
 
+       // Utils
+       protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
+
+       // business objects
        private Node currentNode;
 
+       // this page UI components
+       private FullVersioningTreeContentProvider nodeContentProvider;
+       private TreeViewer nodesViewer;
+       private FormToolkit tk;
+
        public NodeVersionHistoryPage(FormEditor editor, String title,
                        Node currentNode) {
                super(editor, "NodeVersionHistoryPage", title);
@@ -29,15 +74,231 @@ public class NodeVersionHistoryPage extends FormPage {
        }
 
        protected void createFormContent(IManagedForm managedForm) {
+               ScrolledForm form = managedForm.getForm();
+               tk = managedForm.getToolkit();
+               GridLayout twt = new GridLayout(1, false);
+               twt.marginWidth = twt.marginHeight = 5;
+               Composite body = form.getBody();
+               body.setLayout(twt);
+
+               try {
+                       if (!currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) {
+                               tk.createLabel(body, JcrExplorerPlugin
+                                               .getMessage("warningUnversionableNode"));
+                       } else {
+                               createHistorySection(form.getBody());
+                               createTreeSection(form.getBody());
+                       }
+               } catch (RepositoryException e) {
+                       throw new ArgeoException(
+                                       "Unexpected error while checking if node is versionable", e);
+               }
+       }
+
+       protected void createTreeSection(Composite parent) {
+               // Section Layout & MetaData
+               Section section = tk.createSection(parent, Section.TWISTIE);
+               section.setLayoutData(new GridData(GridData.FILL_BOTH));
+               section.setText(JcrExplorerPlugin.getMessage("versionTreeSectionTitle"));
+
+               // Section Body
+               Composite body = tk.createComposite(section, SWT.FILL);
+               // WARNING : 2 following lines are compulsory or body won't be
+               // displayed.
+               body.setLayout(new GridLayout());
+               section.setClient(body);
+
+               body.setLayoutData(new GridData(GridData.FILL_BOTH));
+               section.setExpanded(true);
+
+               nodeContentProvider = new FullVersioningTreeContentProvider();
+               nodesViewer = createNodeViewer(body, nodeContentProvider);
+               nodesViewer.setInput(currentNode);
+       }
+
+       protected TreeViewer createNodeViewer(Composite parent,
+                       final ITreeContentProvider nodeContentProvider) {
+
+               final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
+
+               tmpNodeViewer.getTree().setLayoutData(
+                               new GridData(SWT.FILL, SWT.FILL, true, true));
+
+               tmpNodeViewer.setContentProvider(nodeContentProvider);
+               tmpNodeViewer.setLabelProvider(new VersionLabelProvider());
+               tmpNodeViewer
+                               .addDoubleClickListener(new GenericNodeDoubleClickListener(
+                                               tmpNodeViewer));
+               return tmpNodeViewer;
+       }
+
+       protected void createHistorySection(Composite parent) {
+
+               // Section Layout
+               Section section = tk.createSection(parent, Section.TWISTIE);
+               section.setLayoutData(new GridData(TableWrapData.FILL_GRAB));
+               TableWrapLayout twt = new TableWrapLayout();
+               section.setLayout(twt);
+
+               // Set title of the section
+               section.setText(JcrExplorerPlugin
+                               .getMessage("versionHistorySectionTitle"));
+
+               final Text styledText = tk.createText(section, "", SWT.FULL_SELECTION
+                               | SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
+               styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               section.setClient(styledText);
+               refreshHistory(styledText);
+               styledText.setEditable(false);
+               section.setExpanded(false);
+
+               AbstractFormPart part = new AbstractFormPart() {
+                       public void commit(boolean onSave) {
+                       }
+
+                       public void refresh() {
+                               super.refresh();
+                               refreshHistory(styledText);
+                       }
+               };
+               getManagedForm().addPart(part);
+       }
+
+       protected void refreshHistory(Text styledText) {
                try {
-                       ScrolledForm form = managedForm.getForm();
-                       GridLayout twt = new GridLayout(1, false);
-                       twt.marginWidth = twt.marginHeight = 0;
-                       form.getBody().setLayout(twt);
-                       Label lbl = new Label(form.getBody(), SWT.NONE);
-                       lbl.setText("Implement this");
-               } catch (Exception e) {
-                       e.printStackTrace();
+                       List<VersionDiff> lst = listHistoryDiff();
+                       StringBuffer main = new StringBuffer("");
+
+                       for (int i = lst.size() - 1; i >= 0; i--) {
+                               if (i == 0)
+                                       main.append("Creation (");
+                               else
+                                       main.append("Update " + i + " (");
+
+                               if (lst.get(i).getUserId() != null)
+                                       main.append("UserId : " + lst.get(i).getUserId());
+
+                               if (lst.get(i).getUserId() != null
+                                               && lst.get(i).getUpdateTime() != null)
+                                       main.append(", ");
+
+                               if (lst.get(i).getUpdateTime() != null)
+                                       main.append("Date : "
+                                                       + timeFormatter.format(lst.get(i).getUpdateTime()
+                                                                       .getTime()) + ")\n");
+
+                               StringBuffer buf = new StringBuffer("");
+                               Map<String, PropertyDiff> diffs = lst.get(i).getDiffs();
+                               props: for (String prop : diffs.keySet()) {
+                                       PropertyDiff pd = diffs.get(prop);
+                                       String propName = pd.getRelPath();
+                                       Value refValue = pd.getReferenceValue();
+                                       Value newValue = pd.getNewValue();
+                                       String refValueStr = "";
+                                       String newValueStr = "";
+
+                                       if (refValue != null) {
+                                               if (refValue.getType() == PropertyType.DATE) {
+                                                       refValueStr = timeFormatter.format(refValue
+                                                                       .getDate().getTime());
+                                               } else
+                                                       refValueStr = refValue.getString();
+                                       }
+                                       if (newValue != null) {
+                                               if (newValue.getType() == PropertyType.DATE) {
+                                                       newValueStr = timeFormatter.format(newValue
+                                                                       .getDate().getTime());
+                                               } else
+                                                       newValueStr = newValue.getString();
+                                       }
+
+                                       if (pd.getType() == PropertyDiff.MODIFIED) {
+                                               buf.append(prop).append(": ");
+                                               buf.append(refValueStr);
+                                               buf.append(" > ");
+                                               buf.append(newValueStr);
+                                               buf.append("\n");
+                                       } else if (pd.getType() == PropertyDiff.ADDED
+                                                       && !"".equals(newValueStr)) {
+                                               // we don't list property that have been added with an
+                                               // empty string as value
+                                               buf.append(prop).append(": ");
+                                               buf.append(" + ");
+                                               buf.append(newValueStr);
+                                               buf.append("\n");
+                                       } else if (pd.getType() == PropertyDiff.REMOVED) {
+                                               buf.append(prop).append(": ");
+                                               buf.append(" - ");
+                                               buf.append(refValueStr);
+                                               buf.append("\n");
+                                       }
+                               }
+                               buf.append("\n");
+                               main.append(buf);
+                       }
+                       styledText.setText(main.toString());
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot generate history for node", e);
                }
+
+       }
+
+       public List<VersionDiff> listHistoryDiff() {
+               try {
+                       List<VersionDiff> res = new ArrayList<VersionDiff>();
+                       VersionManager versionManager = currentNode.getSession()
+                                       .getWorkspace().getVersionManager();
+                       VersionHistory versionHistory = versionManager
+                                       .getVersionHistory(currentNode.getPath());
+
+                       VersionIterator vit = versionHistory.getAllLinearVersions();
+                       while (vit.hasNext()) {
+                               Version version = vit.nextVersion();
+                               Node node = version.getFrozenNode();
+                               Version predecessor = null;
+                               try {
+                                       predecessor = version.getLinearPredecessor();
+                               } catch (Exception e) {
+                                       // no predecessor seems to throw an exception even if it
+                                       // shouldn't...
+                               }
+                               if (predecessor == null) {// original
+                               } else {
+                                       Map<String, PropertyDiff> diffs = JcrUtils.diffProperties(
+                                                       predecessor.getFrozenNode(), node);
+                                       if (!diffs.isEmpty()) {
+                                               String lastUserName = null;
+                                               Calendar lastUpdate = null;
+                                               try {
+                                                       if (currentNode
+                                                                       .isNodeType(NodeType.MIX_LAST_MODIFIED)) {
+                                                               lastUserName = node.getProperty(
+                                                                               Property.JCR_LAST_MODIFIED_BY)
+                                                                               .getString();
+                                                               lastUpdate = node.getProperty(
+                                                                               Property.JCR_LAST_MODIFIED).getDate();
+                                                       } else
+                                                               lastUpdate = version.getProperty(
+                                                                               Property.JCR_CREATED).getDate();
+
+                                               } catch (Exception e) {
+                                                       // Silent that info is optionnal
+                                               }
+                                               VersionDiff vd = new VersionDiff(lastUserName,
+                                                               lastUpdate, diffs);
+                                               res.add(vd);
+                                       }
+                               }
+                       }
+                       return res;
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot generate history for node ");
+               }
+
+       }
+
+       @Override
+       public void setActive(boolean active) {
+               super.setActive(active);
        }
 }
diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/FullVersioningTreeContentProvider.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/FullVersioningTreeContentProvider.java
new file mode 100644 (file)
index 0000000..e89f16e
--- /dev/null
@@ -0,0 +1,103 @@
+package org.argeo.jcr.ui.explorer.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+import javax.jcr.version.VersionManager;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ui.explorer.browser.ItemComparator;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Implementation of the {@code ITreeContentProvider} in order to display some
+ * version informations of a JCR full versionable node in a tree like structure
+ * 
+ */
+public class FullVersioningTreeContentProvider implements ITreeContentProvider {
+       // private Node rootNode;
+       private ItemComparator itemComparator = new ItemComparator();
+
+       /**
+        * Sends back the first level of the Tree. input element must be a single
+        * node object
+        */
+       public Object[] getElements(Object inputElement) {
+               try {
+                       Node rootNode = (Node) inputElement;
+                       String curPath = rootNode.getPath();
+                       VersionManager vm = rootNode.getSession().getWorkspace()
+                                       .getVersionManager();
+
+                       VersionHistory vh = vm.getVersionHistory(curPath);
+                       List<Version> result = new ArrayList<Version>();
+                       VersionIterator vi = vh.getAllLinearVersions();
+
+                       while (vi.hasNext()) {
+                               result.add(vi.nextVersion());
+                       }
+                       return result.toArray();
+               } catch (RepositoryException re) {
+                       throw new ArgeoException(
+                                       "Unexpected error while getting version elements", re);
+               }
+       }
+
+       public Object[] getChildren(Object parentElement) {
+               try {
+                       if (parentElement instanceof Version) {
+                               List<Node> tmp = new ArrayList<Node>();
+                               tmp.add(((Version) parentElement).getFrozenNode());
+                               return tmp.toArray();
+                               // Node node = ((Version) parentElement).getFrozenNode();
+                               // return new Object[] { node };
+                       }
+               } catch (RepositoryException re) {
+                       throw new ArgeoException("Unexpected error while getting child "
+                                       + "node for version element", re);
+               }
+               return null;
+       }
+
+       public Object getParent(Object element) {
+               try {
+                       // this will not work in a simpleVersionning environment, parent is
+                       // not a node.
+                       if (element instanceof Node
+                                       && ((Node) element).isNodeType(NodeType.NT_FROZEN_NODE)) {
+                               Node node = (Node) element;
+                               return node.getParent();
+                       } else
+                               return null;
+               } catch (RepositoryException e) {
+                       return null;
+               }
+       }
+
+       public boolean hasChildren(Object element) {
+               try {
+                       if (element instanceof Version)
+                               return true;
+                       else if (element instanceof Node)
+                               return ((Node) element).hasNodes();
+                       else
+                               return false;
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot check children of " + element, e);
+               }
+       }
+
+       public void dispose() {
+       }
+
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+       }
+
+}
diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/SingleNodeAsTreeContentProvider.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/SingleNodeAsTreeContentProvider.java
new file mode 100644 (file)
index 0000000..d329427
--- /dev/null
@@ -0,0 +1,91 @@
+package org.argeo.jcr.ui.explorer.providers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ui.explorer.browser.ItemComparator;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Implementation of the {@code ITreeContentProvider} in order to display a
+ * single JCR node and its children in a tree like structure
+ * 
+ */
+public class SingleNodeAsTreeContentProvider implements ITreeContentProvider {
+       // private Node rootNode;
+       private ItemComparator itemComparator = new ItemComparator();
+
+       /**
+        * Sends back the first level of the Tree. input element must be a single
+        * node object
+        */
+       public Object[] getElements(Object inputElement) {
+               try {
+                       Node rootNode = (Node) inputElement;
+                       List<Node> result = new ArrayList<Node>();
+                       NodeIterator ni = rootNode.getNodes();
+                       while (ni.hasNext()) {
+                               result.add(ni.nextNode());
+                       }
+
+                       return result.toArray();
+               } catch (RepositoryException re) {
+                       throw new ArgeoException(
+                                       "Unexpected error while getting child nodes for children editor page ",
+                                       re);
+               }
+       }
+
+       public Object[] getChildren(Object parentElement) {
+               return childrenNodes((Node) parentElement);
+       }
+
+       public Object getParent(Object element) {
+               try {
+                       Node node = (Node) element;
+                       if (!node.getPath().equals("/"))
+                               return node.getParent();
+                       else
+                               return null;
+               } catch (RepositoryException e) {
+                       return null;
+               }
+       }
+
+       public boolean hasChildren(Object element) {
+               try {
+                       return ((Node) element).hasNodes();
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot check children of " + element, e);
+               }
+       }
+
+       public void dispose() {
+       }
+
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+       }
+
+       protected Object[] childrenNodes(Node parentNode) {
+               try {
+                       List<Node> children = new ArrayList<Node>();
+                       NodeIterator nit = parentNode.getNodes();
+                       while (nit.hasNext()) {
+                               Node node = nit.nextNode();
+                               children.add(node);
+                       }
+                       Node[] arr = children.toArray(new Node[children.size()]);
+                       Arrays.sort(arr, itemComparator);
+                       return arr;
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot list children of " + parentNode, e);
+               }
+       }
+}
diff --git a/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/VersionLabelProvider.java b/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/providers/VersionLabelProvider.java
new file mode 100644 (file)
index 0000000..cc6093e
--- /dev/null
@@ -0,0 +1,32 @@
+package org.argeo.jcr.ui.explorer.providers;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.Version;
+
+import org.argeo.ArgeoException;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+
+/**
+ * simple wrapping of the ColumnLabelProvider class to provide text display in
+ * order to build a tree for version. The Get text method does not assume that
+ * Version extends Node class to respect JCR 2.0 specification
+ * 
+ */
+public class VersionLabelProvider extends ColumnLabelProvider {
+
+       public String getText(Object element) {
+               try {
+                       if (element instanceof Version) {
+                               Version version = (Version) element;
+                               return version.getName();
+                       } else if (element instanceof Node) {
+                               return ((Node) element).getName();
+                       }
+               } catch (RepositoryException re) {
+                       throw new ArgeoException(
+                                       "Unexpected error while getting element name", re);
+               }
+               return super.getText(element);
+       }
+}
index 5308015f5245b3b5185b46088de274757004e9de..4418c09d7689c2133962f26520625944cb3364ab 100644 (file)
@@ -22,9 +22,7 @@ import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.ui.PartInitException;
 
 /**
- * 
  * Centralizes the management of double click on a NodeTreeViewer
- * 
  */
 public class GenericNodeDoubleClickListener implements IDoubleClickListener {
 
index 72bd9ab117a0ee53f690e39c0f6e396dc1cab734..b859ffdeabaf0609dda129862e17b522fc744757 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.jcr.ui.explorer.utils;
 
+/** Centralizes some useful methods to build Uis with JCR */
 public class JcrUiUtils {
 
 }
index 2fd97ae97172ad9bf88eae527faa94e4200ed29e..4a2562fd0377d9db00e9b289bc4999181a0643bd 100644 (file)
@@ -45,6 +45,11 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Menu;
 
+/**
+ * Basic View to display a sash form to browse a JCR compliant multirepository
+ * environment
+ */
+
 public class GenericJcrBrowser extends AbstractJcrBrowser {
        private final static Log log = LogFactory.getLog(GenericJcrBrowser.class);
 
index f212a192dc1e87b02eec226a97ec82ad8133f772..b6bcd07b2bcd226a773b5ff7263ede93726988f0 100644 (file)
@@ -1,11 +1,19 @@
 ## English labels for Agreo JCR UI application 
 
 ## Generic labels 
+warningUnversionableNode= Warning: Current node is not versionable.
+warningNoChildNode= Warning: current node has no children.
+
+## GenericNodeEditor 
 nodeEditorLbl=Generic node editor
-genericNodePageTitle=Edit Node properties
+genericNodePageTitle=Properties
 childNodesPageTitle=Children
 nodeRightsManagementPageTitle=Permissions
-nodeVersionHistoryPageTitle=Node history
+nodeVersionHistoryPageTitle=History
 
+# History 
+versionTreeSectionTitle=Version list
+versionHistorySectionTitle=History
 ## Dummy ones 
 testLbl=Internationalizations of messages seems to work properly.