diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml
index 9519b9f065..97f0de875b 100644
--- a/config/alfresco/public-rest-context.xml
+++ b/config/alfresco/public-rest-context.xml
@@ -783,6 +783,11 @@
+
+
+
+
+
diff --git a/source/java/org/alfresco/rest/api/model/Node.java b/source/java/org/alfresco/rest/api/model/Node.java
index ce999eaf8a..a9c15652fb 100644
--- a/source/java/org/alfresco/rest/api/model/Node.java
+++ b/source/java/org/alfresco/rest/api/model/Node.java
@@ -63,9 +63,12 @@ public class Node implements Comparable
protected UserInfo createdByUser;
protected UserInfo modifiedByUser;
- //Archived info, explicitly setting to NULL because NULLS don't get shown in the JSON.
- protected Date archivedAt = null;
- protected UserInfo archivedByUser = null;
+ // Archived info - specifically for archive (deleted) node - see Trashcan API
+ protected Date archivedAt;
+ protected UserInfo archivedByUser;
+
+ // Version info - specifically for version node - see Version History API
+ protected String versionComment;
protected Boolean isFolder;
protected Boolean isFile;
@@ -211,6 +214,11 @@ public class Node implements Comparable
return createdByUser;
}
+ public void setCreatedByUser(UserInfo createdByUser)
+ {
+ this.createdByUser = createdByUser;
+ }
+
public String getName()
{
return this.name;
@@ -337,6 +345,16 @@ public class Node implements Comparable
this.archivedByUser = archivedByUser;
}
+ public String getVersionComment()
+ {
+ return versionComment;
+ }
+
+ public void setVersionComment(String versionComment)
+ {
+ this.versionComment = versionComment;
+ }
+
public boolean equals(Object other)
{
if(this == other)
diff --git a/source/java/org/alfresco/rest/api/nodes/NodeVersionsRelation.java b/source/java/org/alfresco/rest/api/nodes/NodeVersionsRelation.java
new file mode 100644
index 0000000000..965f60d9b4
--- /dev/null
+++ b/source/java/org/alfresco/rest/api/nodes/NodeVersionsRelation.java
@@ -0,0 +1,184 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.api.nodes;
+
+import org.alfresco.rest.api.Nodes;
+import org.alfresco.rest.api.model.Node;
+import org.alfresco.rest.api.model.UserInfo;
+import org.alfresco.rest.framework.BinaryProperties;
+import org.alfresco.rest.framework.WebApiDescription;
+import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
+import org.alfresco.rest.framework.resource.RelationshipResource;
+import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
+import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
+import org.alfresco.rest.framework.resource.content.BinaryResource;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Paging;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.service.ServiceRegistry;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.version.Version;
+import org.alfresco.service.cmr.version.VersionHistory;
+import org.alfresco.service.cmr.version.VersionService;
+import org.alfresco.util.ParameterCheck;
+import org.alfresco.util.PropertyCheck;
+import org.springframework.beans.factory.InitializingBean;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Node Versions - version history
+ *
+ * @author janv
+ */
+@RelationshipResource(name = "versions", entityResource = NodesEntityResource.class, title = "Node Versions")
+public class NodeVersionsRelation implements
+ RelationshipResourceAction.Read,
+ RelationshipResourceAction.ReadById,
+ RelationshipResourceBinaryAction.Read,
+ InitializingBean
+{
+ protected ServiceRegistry sr;
+ protected Nodes nodes;
+ protected VersionService versionService;
+
+ public void setNodes(Nodes nodes)
+ {
+ this.nodes = nodes;
+ }
+
+ public void setServiceRegistry(ServiceRegistry sr)
+ {
+ this.sr = sr;
+ }
+
+ @Override
+ public void afterPropertiesSet()
+ {
+ PropertyCheck.mandatory(this, "serviceRegistry", sr);
+ ParameterCheck.mandatory("nodes", this.nodes);
+
+ this.versionService = sr.getVersionService();
+ }
+ /**
+ * List version history
+ *
+ * @param nodeId String id of (live) node
+ */
+ @Override
+ @WebApiDescription(title = "Return version history as a paged list of version node infos")
+ public CollectionWithPagingInfo readAll(String nodeId, Parameters parameters)
+ {
+ NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null);
+
+ VersionHistory vh = versionService.getVersionHistory(nodeRef);
+
+ Map mapUserInfo = new HashMap<>(10);
+ List includeParam = parameters.getInclude();
+
+ // TODO fixme - add paging etc
+ List collection = null;
+ if (vh != null)
+ {
+ collection = new ArrayList<>(vh.getAllVersions().size());
+ for (Version v : vh.getAllVersions())
+ {
+ Node node = nodes.getFolderOrDocument(v.getFrozenStateNodeRef(), null, null, includeParam, mapUserInfo);
+ mapVersionInfo(v, node);
+ collection.add(node);
+ }
+ }
+
+ Paging paging = parameters.getPaging();
+ return CollectionWithPagingInfo.asPaged(paging, collection, false, (collection != null ? collection.size() : 0));
+ }
+
+ private void mapVersionInfo(Version v, Node aNode)
+ {
+ aNode.setNodeRef(new NodeRef("", "", v.getVersionLabel()));
+
+ aNode.setVersionComment(v.getDescription());
+
+ //Don't show parentId, createdAt, createdByUser
+ aNode.setParentId(null);
+ aNode.setCreated(null);
+ aNode.setCreatedByUser(null);
+ }
+
+ @Override
+ @WebApiDescription(title="Get version node info", description = "Return metadata for a specific version node")
+ public Node readById(String nodeId, String versionId, Parameters parameters)
+ {
+ Version v = findVersion(nodeId, versionId);
+
+ if (v != null)
+ {
+ List includeParam = parameters.getInclude();
+ Node node = nodes.getFolderOrDocument(v.getFrozenStateNodeRef(), null, null, includeParam, null);
+ mapVersionInfo(v, node);
+ return node;
+ }
+
+ throw new EntityNotFoundException(nodeId+"-"+versionId);
+ }
+
+ @WebApiDescription(title = "Download version content", description = "Download version content")
+ @BinaryProperties({ "content" })
+ @Override
+ public BinaryResource readProperty(String nodeId, String versionId, Parameters parameters)
+ {
+ Version v = findVersion(nodeId, versionId);
+
+ if (v != null)
+ {
+ NodeRef versionNodeRef = v.getFrozenStateNodeRef();
+ return nodes.getContent(versionNodeRef, parameters, true); // TODO should we record version downloads ?
+ }
+
+ throw new EntityNotFoundException(nodeId+"-"+versionId);
+ }
+
+ private Version findVersion(String nodeId, String versionLabelId)
+ {
+ // note: sub-optimal
+ NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null);
+ VersionHistory vh = versionService.getVersionHistory(nodeRef);
+ if (vh != null)
+ {
+ for (Version v : vh.getAllVersions())
+ {
+ if (v.getVersionLabel().equals(versionLabelId))
+ {
+ return v;
+ }
+ }
+ }
+ return null;
+ }
+}