Import-Package: javax.jcr,
javax.jcr.nodetype,
javax.jcr.observation,
+ javax.jcr.version,
org.apache.commons.io,
org.apache.commons.logging,
org.argeo,
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";
+++ /dev/null
-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);
- }
- }
-}
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;
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);
}
}
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);
}
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) {
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);
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);
}
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);
}
}
--- /dev/null
+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) {
+ }
+
+}
--- /dev/null
+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);
+ }
+ }
+}
--- /dev/null
+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);
+ }
+}
import org.eclipse.ui.PartInitException;
/**
- *
* Centralizes the management of double click on a NodeTreeViewer
- *
*/
public class GenericNodeDoubleClickListener implements IDoubleClickListener {
package org.argeo.jcr.ui.explorer.utils;
+/** Centralizes some useful methods to build Uis with JCR */
public class JcrUiUtils {
}
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);
## 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.