diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java index 5208c71f3b..1e98e18920 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptNode.java +++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java @@ -29,6 +29,7 @@ import java.io.Serializable; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -71,6 +72,7 @@ import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.version.Version; +import org.alfresco.service.cmr.version.VersionHistory; import org.alfresco.service.cmr.version.VersionType; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; @@ -142,7 +144,10 @@ public class ScriptNode implements Serializable, Scopeable /** The properties of this node */ private ScriptableQNameMap properties = null; - + + /** The versions of this node */ + private Scriptable versions = null; + protected ServiceRegistry services = null; private NodeService nodeService = null; private Boolean isDocument = null; @@ -1522,6 +1527,78 @@ public class ScriptNode implements Serializable, Scopeable // ------------------------------------------------------------------------------ // Checkout/Checkin Services + + /** + * Create a version of this document. Note: this will add the cm:versionable aspect. + * + * @param history Version history note + * @param majorVersion True to save as a major version increment, false for minor version. + */ + public ScriptVersion createVersion(String history, boolean majorVersion) + { + Map props = new HashMap(2, 1.0f); + props.put(Version.PROP_DESCRIPTION, history); + props.put(VersionModel.PROP_VERSION_TYPE, majorVersion ? VersionType.MAJOR : VersionType.MINOR); + ScriptVersion version = new ScriptVersion(this.services.getVersionService().createVersion(this.nodeRef, props), this.services, this.scope); + this.versions = null; + return version; + } + + /** + * Determines if this node is versioned + * + * @return true => is versioned + */ + public boolean getIsVersioned() + { + return this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_VERSIONABLE); + } + + /** + * Gets the version history + * + * @return version history + */ + public Scriptable getVersionHistory() + { + if (this.versions == null && getIsVersioned()) + { + VersionHistory history = this.services.getVersionService().getVersionHistory(this.nodeRef); + if (history != null) + { + Collection allVersions = history.getAllVersions(); + Object[] versions = new Object[allVersions.size()]; + int i = 0; + for (Version version : allVersions) + { + versions[i++] = new ScriptVersion(version, this.services, this.scope); + } + this.versions = Context.getCurrentContext().newArray(this.scope, versions); + } + } + return this.versions; + } + + /** + * Gets the version of this node specified by version label + * + * @param versionLabel version label + * @return version of node, or null if node is not versioned, or label does not exist + */ + public ScriptVersion getVersion(String versionLabel) + { + if (!getIsVersioned()) + { + return null; + } + VersionHistory history = this.services.getVersionService().getVersionHistory(this.nodeRef); + Version version = history.getVersion(versionLabel); + if (version == null) + { + return null; + } + return new ScriptVersion(version, this.services, this.scope); + } /** * Perform a check-out of this document into the current parent space. @@ -1605,6 +1682,7 @@ public class ScriptNode implements Serializable, Scopeable props.put(Version.PROP_DESCRIPTION, history); props.put(VersionModel.PROP_VERSION_TYPE, majorVersion ? VersionType.MAJOR : VersionType.MINOR); NodeRef original = this.services.getCheckOutCheckInService().checkin(this.nodeRef, props); + this.versions = null; return newInstance(original, this.services, this.scope); } @@ -1620,8 +1698,7 @@ public class ScriptNode implements Serializable, Scopeable NodeRef original = this.services.getCheckOutCheckInService().cancelCheckout(this.nodeRef); return newInstance(original, this.services, this.scope); } - - + // ------------------------------------------------------------------------------ // Transformation and Rendering API diff --git a/source/java/org/alfresco/repo/jscript/ScriptVersion.java b/source/java/org/alfresco/repo/jscript/ScriptVersion.java new file mode 100644 index 0000000000..43d7e4d006 --- /dev/null +++ b/source/java/org/alfresco/repo/jscript/ScriptVersion.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.jscript; + +import java.io.Serializable; + +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.version.Version; +import org.mozilla.javascript.Scriptable; + +/** + * Scriptable Version + * + * @author davidc + */ +public final class ScriptVersion implements Serializable +{ + private static final long serialVersionUID = 3896177303419746778L; + + /** Root scope for this object */ + private Scriptable scope; + private ServiceRegistry services; + private Version version; + private static ValueConverter converter = new ValueConverter(); + + + /** + * Construct + */ + public ScriptVersion(Version version, ServiceRegistry services, Scriptable scope) + { + this.version = version; + this.services = services; + this.scope = scope; + } + + /** + * Gets the date the version was created + * + * @return the date the version was created + */ + public Object getCreatedDate() + { + return converter.convertValueForScript(services, scope, null, version.getCreatedDate()); + } + + /** + * Gets the creator of the version + * + * @return the creator of the version + */ + public String getCreator() + { + return version.getCreator(); + } + + /** + * Gets the version label + * + * @return the version label + */ + public String getLabel() + { + return version.getVersionLabel(); + } + + /** + * Gets the version type + * + * @return "MAJOR", "MINOR" + */ + public String getType() + { + return version.getVersionType().name(); + } + + /** + * Gets the version description (or checkin comment) + * + * @return the version description + */ + public String getDescription() + { + String desc = version.getDescription(); + return (desc == null) ? "" : desc; + } + + /** + * Gets the node ref represented by this version + * + * @return node ref + */ + public NodeRef getNodeRef() + { + return version.getVersionedNodeRef(); + } + + /** + * Gets the node represented by this version + * + * @return node + */ + public ScriptNode getNode() + { + return new ScriptNode(version.getFrozenStateNodeRef(), services, scope); + } + +} diff --git a/source/java/org/alfresco/repo/version/NodeServiceImpl.java b/source/java/org/alfresco/repo/version/NodeServiceImpl.java index 9795d388e0..c9750547b0 100644 --- a/source/java/org/alfresco/repo/version/NodeServiceImpl.java +++ b/source/java/org/alfresco/repo/version/NodeServiceImpl.java @@ -142,7 +142,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public boolean exists(StoreRef storeRef) { - return dbNodeService.exists(storeRef); + return dbNodeService.exists(VersionUtil.convertStoreRef(storeRef)); } /** diff --git a/source/java/org/alfresco/repo/version/common/VersionHistoryImpl.java b/source/java/org/alfresco/repo/version/common/VersionHistoryImpl.java index 8c8b69fb15..1105143a8d 100644 --- a/source/java/org/alfresco/repo/version/common/VersionHistoryImpl.java +++ b/source/java/org/alfresco/repo/version/common/VersionHistoryImpl.java @@ -26,7 +26,11 @@ package org.alfresco.repo.version.common; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; +import java.util.Date; import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; import org.alfresco.service.cmr.version.Version; import org.alfresco.service.cmr.version.VersionDoesNotExistException; @@ -63,8 +67,16 @@ public class VersionHistoryImpl implements VersionHistory /* * Label to version object map */ - private HashMap versions = null; + private HashMap versionsByLabel = null; + /* + * Versions ordered by creation date (descending) + */ + private Map versions = new TreeMap(new VersionComparator()); + + /** + * Root version + */ private Version rootVersion; /** @@ -82,7 +94,7 @@ public class VersionHistoryImpl implements VersionHistory } this.versionHistory = new HashMap(); - this.versions = new HashMap(); + this.versionsByLabel = new HashMap(); this.rootVersion = rootVersion; this.rootVersionLabel = rootVersion.getVersionLabel(); @@ -103,7 +115,7 @@ public class VersionHistoryImpl implements VersionHistory * Gets a collection containing all the versions within the * version history. *

- * The order of the versions is not guarenteed. + * Versions are returned in descending create date order. * * @return collection containing all the versions */ @@ -170,7 +182,7 @@ public class VersionHistoryImpl implements VersionHistory Version result = null; if (versionLabel != null) { - result = this.versions.get(versionLabel); + result = this.versionsByLabel.get(versionLabel); if (result == null) { @@ -193,11 +205,26 @@ public class VersionHistoryImpl implements VersionHistory { // TODO cope with exception case where duplicate version labels have been specified - this.versions.put(version.getVersionLabel(), version); + this.versionsByLabel.put(version.getVersionLabel(), version); + this.versions.put(version.getCreatedDate(), version); if (predecessor != null) { this.versionHistory.put(version.getVersionLabel(), predecessor.getVersionLabel()); } } + + /** + * Version Comparator + * + * Note: Descending create date order + */ + public class VersionComparator implements Comparator + { + public int compare(Date o1, Date o2) + { + return o2.compareTo(o1); + } + } + } diff --git a/source/java/org/alfresco/repo/version/common/VersionUtil.java b/source/java/org/alfresco/repo/version/common/VersionUtil.java index 2d9fdaf58b..33a806f525 100644 --- a/source/java/org/alfresco/repo/version/common/VersionUtil.java +++ b/source/java/org/alfresco/repo/version/common/VersionUtil.java @@ -71,6 +71,17 @@ public class VersionUtil } } + /** + * Create Version Store Ref + * + * @param store ref + * @return store ref for version store + */ + public static StoreRef convertStoreRef(StoreRef storeRef) + { + return new StoreRef(StoreRef.PROTOCOL_WORKSPACE, storeRef.getIdentifier()); + } + /** * Convert the incomming node ref (with the version store protocol specified) * to the internal representation with the workspace protocol. @@ -80,6 +91,6 @@ public class VersionUtil */ public static NodeRef convertNodeRef(NodeRef nodeRef) { - return new NodeRef(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionModel.STORE_ID), nodeRef.getId()); + return new NodeRef(convertStoreRef(nodeRef.getStoreRef()), nodeRef.getId()); } }