();
- props.put(PROP_QNAME_QNAME, entry.getKey());
-
+ props.put(PROP_QNAME_QNAME, entry.getKey());
+
if (entry.getValue() instanceof Collection)
{
props.put(PROP_QNAME_MULTI_VALUE, entry.getValue());
@@ -648,34 +654,34 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
props.put(PROP_QNAME_VALUE, entry.getValue());
props.put(PROP_QNAME_IS_MULTI_VALUE, false);
}
-
+
// Create the node storing the frozen attribute details
this.dbNodeService.createNode(
- versionNodeRef,
- CHILD_QNAME_VERSIONED_ATTRIBUTES,
+ versionNodeRef,
+ CHILD_QNAME_VERSIONED_ATTRIBUTES,
CHILD_QNAME_VERSIONED_ATTRIBUTES,
TYPE_QNAME_VERSIONED_PROPERTY,
- props);
+ props);
}
- }
-
- /**
- * Gets the version stores root node
- *
- * @return the node ref to the root node of the version store
- */
- private NodeRef getRootNode()
- {
- // Get the version store root node reference
+ }
+
+ /**
+ * Gets the version stores root node
+ *
+ * @return the node ref to the root node of the version store
+ */
+ private NodeRef getRootNode()
+ {
+ // Get the version store root node reference
return this.dbNodeService.getRootNode(getVersionStoreReference());
- }
-
- /**
+ }
+
+ /**
* Builds a version history object from the version history reference.
*
* The node ref is passed to enable the version history to be scoped to the
* appropriate branch in the version history.
- *
+ *
* @param versionHistoryRef the node ref for the version history
* @param nodeRef the node reference
* @return a constructed version history object
@@ -683,42 +689,42 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
private VersionHistory buildVersionHistory(NodeRef versionHistoryRef, NodeRef nodeRef)
{
VersionHistory versionHistory = null;
-
+
ArrayList versionHistoryNodeRefs = new ArrayList();
NodeRef currentVersion = getCurrentVersionNodeRef(versionHistoryRef, nodeRef);
-
+
while (currentVersion != null)
{
AssociationRef preceedingVersion = null;
-
+
versionHistoryNodeRefs.add(0, currentVersion);
-
+
List preceedingVersions = this.dbNodeService.getSourceAssocs(
- currentVersion,
- VersionModel.ASSOC_SUCCESSOR);
+ currentVersion,
+ VersionModel.ASSOC_SUCCESSOR);
if (preceedingVersions.size() == 1)
{
preceedingVersion = (AssociationRef)preceedingVersions.toArray()[0];
- currentVersion = preceedingVersion.getSourceRef();
+ currentVersion = preceedingVersion.getSourceRef();
}
else if (preceedingVersions.size() > 1)
{
// Error since we only currently support one preceeding version
throw new VersionServiceException(MSGID_ERR_ONE_PRECEEDING);
- }
+ }
else
{
currentVersion = null;
}
}
-
+
// Build the version history object
boolean isRoot = true;
Version preceeding = null;
for (NodeRef versionRef : versionHistoryNodeRefs)
{
Version version = getVersion(versionRef);
-
+
if (isRoot == true)
{
versionHistory = new VersionHistoryImpl(version);
@@ -730,13 +736,13 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
}
preceeding = version;
}
-
+
return versionHistory;
- }
-
+ }
+
/**
* Constructs the a version object to contain the version information from the version node ref.
- *
+ *
* @param versionRef the version reference
* @return object containing verison data
*/
@@ -747,15 +753,15 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
return null;
}
Map versionProperties = new HashMap();
-
+
// Get the standard node details
Map nodeProperties = this.dbNodeService.getProperties(versionRef);
for (QName key : nodeProperties.keySet())
- {
+ {
Serializable value = nodeProperties.get(key);
versionProperties.put(key.getLocalName(), value);
}
-
+
// Get the meta data
List metaData = this.dbNodeService.getChildAssocs(
versionRef,
@@ -768,17 +774,17 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
Serializable value = this.dbNodeService.getProperty(metaDataValue, PROP_QNAME_META_DATA_VALUE);
versionProperties.put(name, value);
}
-
+
// Create and return the version object
NodeRef newNodeRef = new NodeRef(new StoreRef(STORE_PROTOCOL, STORE_ID), versionRef.getId());
Version result = new VersionImpl(versionProperties, newNodeRef);
- // done
- return result;
+ // done
+ return result;
}
-
+
/**
* Gets a reference to the version history node for a given 'real' node.
- *
+ *
* @param nodeRef a node reference
* @return a reference to the version history node, null of none
*/
@@ -786,13 +792,13 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
{
return this.dbNodeService.getChildByName(getRootNode(), CHILD_QNAME_VERSION_HISTORIES, nodeRef.getId());
}
-
+
/**
* Gets a reference to the node for the current version of the passed node ref.
- *
+ *
* This uses the version label as a mechanism for looking up the version node in
* the version history.
- *
+ *
* @param nodeRef a node reference
* @return a reference to a version reference
*/
@@ -800,41 +806,41 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
{
NodeRef result = null;
String versionLabel = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL);
-
+
Collection versions = this.dbNodeService.getChildAssocs(versionHistory);
for (ChildAssociationRef version : versions)
{
String tempLabel = (String)this.dbNodeService.getProperty(version.getChildRef(), VersionModel.PROP_QNAME_VERSION_LABEL);
if (tempLabel != null && tempLabel.equals(versionLabel) == true)
{
- result = version.getChildRef();
+ result = version.getChildRef();
break;
}
}
-
+
return result;
- }
-
+ }
+
/**
* @see org.alfresco.cms.version.VersionService#revert(NodeRef)
*/
- public void revert(NodeRef nodeRef)
+ public void revert(NodeRef nodeRef)
{
- revert(nodeRef, getCurrentVersion(nodeRef), true);
- }
-
+ revert(nodeRef, getCurrentVersion(nodeRef), true);
+ }
+
/**
* @see org.alfresco.service.cmr.version.VersionService#revert(org.alfresco.service.cmr.repository.NodeRef, boolean)
*/
- public void revert(NodeRef nodeRef, boolean deep)
+ public void revert(NodeRef nodeRef, boolean deep)
{
revert(nodeRef, getCurrentVersion(nodeRef), deep);
}
-
+
/**
* @see org.alfresco.service.cmr.version.VersionService#revert(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.version.Version)
*/
- public void revert(NodeRef nodeRef, Version version)
+ public void revert(NodeRef nodeRef, Version version)
{
revert(nodeRef, version, true);
}
@@ -842,75 +848,75 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
/**
* @see org.alfresco.service.cmr.version.VersionService#revert(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.version.Version, boolean)
*/
- public void revert(NodeRef nodeRef, Version version, boolean deep)
- {
- // Check the mandatory parameters
- ParameterCheck.mandatory("nodeRef", nodeRef);
- ParameterCheck.mandatory("version", version);
-
+ public void revert(NodeRef nodeRef, Version version, boolean deep)
+ {
+ // Check the mandatory parameters
+ ParameterCheck.mandatory("nodeRef", nodeRef);
+ ParameterCheck.mandatory("version", version);
+
// Cross check that the version provided relates to the node reference provided
if (nodeRef.getId().equals(version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_ID)) == false)
{
// Error since the version provided does not correspond to the node reference provided
throw new VersionServiceException(MSGID_ERR_REVERT_MISMATCH);
}
-
+
// Turn off any auto-version policy behaviours
this.policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE);
try
{
// Store the current version label
String currentVersionLabel = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL);
-
+
// Get the node that represents the frozen state
- NodeRef versionNodeRef = version.getFrozenStateNodeRef();
-
- // Revert the property values
- this.nodeService.setProperties(nodeRef, this.nodeService.getProperties(versionNodeRef));
-
- // Apply/remove the aspects as required
- Set aspects = new HashSet(this.nodeService.getAspects(nodeRef));
- for (QName versionAspect : this.nodeService.getAspects(versionNodeRef))
- {
- if (aspects.contains(versionAspect) == false)
- {
- this.nodeService.addAspect(nodeRef, versionAspect, null);
- }
- else
- {
- aspects.remove(versionAspect);
- }
- }
- for (QName aspect : aspects)
- {
- this.nodeService.removeAspect(nodeRef, aspect);
- }
-
- // Re-add the versionable aspect to the reverted node
+ NodeRef versionNodeRef = version.getFrozenStateNodeRef();
+
+ // Revert the property values
+ this.nodeService.setProperties(nodeRef, this.nodeService.getProperties(versionNodeRef));
+
+ // Apply/remove the aspects as required
+ Set aspects = new HashSet(this.nodeService.getAspects(nodeRef));
+ for (QName versionAspect : this.nodeService.getAspects(versionNodeRef))
+ {
+ if (aspects.contains(versionAspect) == false)
+ {
+ this.nodeService.addAspect(nodeRef, versionAspect, null);
+ }
+ else
+ {
+ aspects.remove(versionAspect);
+ }
+ }
+ for (QName aspect : aspects)
+ {
+ this.nodeService.removeAspect(nodeRef, aspect);
+ }
+
+ // Re-add the versionable aspect to the reverted node
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false)
{
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null);
}
-
+
// Re-set the version label property (since it should not be modified from the origional)
this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, currentVersionLabel);
-
- // Add/remove the child nodes
- List children = new ArrayList(this.nodeService.getChildAssocs(nodeRef));
- for (ChildAssociationRef versionedChild : this.nodeService.getChildAssocs(versionNodeRef))
- {
- if (children.contains(versionedChild) == false)
- {
- if (this.nodeService.exists(versionedChild.getChildRef()) == true)
- {
- // The node was a primary child of the parent, but that is no longer the case. Dispite this
- // the node still exits so this means it has been moved.
- // The best thing to do in this situation will be to re-add the node as a child, but it will not
- // be a primary child.
- this.nodeService.addChild(nodeRef, versionedChild.getChildRef(), versionedChild.getTypeQName(), versionedChild.getQName());
- }
- else
- {
+
+ // Add/remove the child nodes
+ List children = new ArrayList(this.nodeService.getChildAssocs(nodeRef));
+ for (ChildAssociationRef versionedChild : this.nodeService.getChildAssocs(versionNodeRef))
+ {
+ if (children.contains(versionedChild) == false)
+ {
+ if (this.nodeService.exists(versionedChild.getChildRef()) == true)
+ {
+ // The node was a primary child of the parent, but that is no longer the case. Dispite this
+ // the node still exits so this means it has been moved.
+ // The best thing to do in this situation will be to re-add the node as a child, but it will not
+ // be a primary child.
+ this.nodeService.addChild(nodeRef, versionedChild.getChildRef(), versionedChild.getTypeQName(), versionedChild.getQName());
+ }
+ else
+ {
if (versionedChild.isPrimary() == true)
{
// Only try to resotre missing children if we are doing a deep revert
@@ -921,82 +927,82 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
restore(
versionedChild.getChildRef(),
nodeRef,
- versionedChild.getTypeQName(),
+ versionedChild.getTypeQName(),
versionedChild.getQName());
}
// else the deleted child did not have a version history so we can't restore the child
// and so we can't revert the association
}
-
+
// else
// Since this was never a primary assoc and the child has been deleted we won't recreate
// the missing node as it was never owned by the node and we wouldn't know where to put it.
- }
- }
- else
- {
- children.remove(versionedChild);
- }
- }
- for (ChildAssociationRef ref : children)
- {
- this.nodeService.removeChild(nodeRef, ref.getChildRef());
- }
-
- // Add/remove the target associations
- for (AssociationRef assocRef : this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL))
- {
- this.nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName());
- }
- for (AssociationRef versionedAssoc : this.nodeService.getTargetAssocs(versionNodeRef, RegexQNamePattern.MATCH_ALL))
- {
- if (this.nodeService.exists(versionedAssoc.getTargetRef()) == true)
- {
- this.nodeService.createAssociation(nodeRef, versionedAssoc.getTargetRef(), versionedAssoc.getTypeQName());
- }
-
- // else
+ }
+ }
+ else
+ {
+ children.remove(versionedChild);
+ }
+ }
+ for (ChildAssociationRef ref : children)
+ {
+ this.nodeService.removeChild(nodeRef, ref.getChildRef());
+ }
+
+ // Add/remove the target associations
+ for (AssociationRef assocRef : this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL))
+ {
+ this.nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName());
+ }
+ for (AssociationRef versionedAssoc : this.nodeService.getTargetAssocs(versionNodeRef, RegexQNamePattern.MATCH_ALL))
+ {
+ if (this.nodeService.exists(versionedAssoc.getTargetRef()) == true)
+ {
+ this.nodeService.createAssociation(nodeRef, versionedAssoc.getTargetRef(), versionedAssoc.getTypeQName());
+ }
+
+ // else
// Since the tareget of the assoc no longer exists we can't recreate the assoc
- }
+ }
}
finally
{
// Turn auto-version policies back on
this.policyBehaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE);
}
- }
-
+ }
+
/**
* @see org.alfresco.service.cmr.version.VersionService#restore(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName)
*/
public NodeRef restore(
NodeRef nodeRef,
- NodeRef parentNodeRef,
+ NodeRef parentNodeRef,
QName assocTypeQName,
QName assocQName)
{
return restore(nodeRef, parentNodeRef, assocTypeQName, assocQName, true);
}
-
+
/**
* @see org.alfresco.service.cmr.version.VersionService#restore(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName, boolean)
*/
public NodeRef restore(
NodeRef nodeRef,
- NodeRef parentNodeRef,
+ NodeRef parentNodeRef,
QName assocTypeQName,
QName assocQName,
boolean deep)
{
NodeRef restoredNodeRef = null;
-
- // Check that the node does not exist
+
+ // Check that the node does not exist
if (this.nodeService.exists(nodeRef) == true)
{
// Error since you can not restore a node that already exists
throw new VersionServiceException(MSGID_ERR_RESTORE_EXISTS, new Object[]{nodeRef.toString()});
}
-
+
// Try and get the version details that we want to restore to
Version version = getHeadVersion(nodeRef);
if (version == null)
@@ -1004,14 +1010,14 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
// Error since there is no version information available to restore the node from
throw new VersionServiceException(MSGID_ERR_RESTORE_NO_VERSION, new Object[]{nodeRef.toString()});
}
-
+
// Set the uuid of the new node
Map props = new HashMap(1);
props.put(ContentModel.PROP_NODE_UUID, version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_ID));
-
+
// Get the type of the node node
QName type = (QName)version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_TYPE);
-
+
// Disable auto-version behaviour
this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
try
@@ -1029,16 +1035,16 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
// Enable auto-version behaviour
this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE);
}
-
+
// Now we need to revert the newly restored node
revert(restoredNodeRef, version, deep);
-
+
return restoredNodeRef;
}
-
+
/**
* Get the head version given a node reference
- *
+ *
* @param nodeRef the node reference
* @return the 'head' version
*/
@@ -1046,7 +1052,7 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
{
Version version = null;
StoreRef storeRef = nodeRef.getStoreRef();
-
+
NodeRef versionHistoryNodeRef = getVersionHistoryNodeRef(nodeRef);
if (versionHistoryNodeRef != null)
{
@@ -1067,33 +1073,33 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl
if (storeRef.equals(versionStoreRef) == true)
{
version = getVersion(versionNodeRef);
- }
+ }
}
}
}
-
+
return version;
}
- /**
- * @see org.alfresco.cms.version.VersionService#deleteVersionHistory(NodeRef)
- */
- public void deleteVersionHistory(NodeRef nodeRef)
- throws AspectMissingException
- {
- // Get the version history node for the node is question and delete it
- NodeRef versionHistoryNodeRef = getVersionHistoryNodeRef(nodeRef);
-
- if (versionHistoryNodeRef != null)
- {
- // Delete the version history node
- this.dbNodeService.deleteNode(versionHistoryNodeRef);
-
- if (this.nodeService.exists(nodeRef) == true && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true)
- {
- // Reset the version label property on the versionable node
- this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, null);
- }
- }
- }
+ /**
+ * @see org.alfresco.cms.version.VersionService#deleteVersionHistory(NodeRef)
+ */
+ public void deleteVersionHistory(NodeRef nodeRef)
+ throws AspectMissingException
+ {
+ // Get the version history node for the node is question and delete it
+ NodeRef versionHistoryNodeRef = getVersionHistoryNodeRef(nodeRef);
+
+ if (versionHistoryNodeRef != null)
+ {
+ // Delete the version history node
+ this.dbNodeService.deleteNode(versionHistoryNodeRef);
+
+ if (this.nodeService.exists(nodeRef) == true && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true)
+ {
+ // Reset the version label property on the versionable node
+ this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, null);
+ }
+ }
+ }
}
diff --git a/source/java/org/alfresco/repo/version/common/VersionUtil.java b/source/java/org/alfresco/repo/version/common/VersionUtil.java
index 35cd5d5e27..2d9fdaf58b 100644
--- a/source/java/org/alfresco/repo/version/common/VersionUtil.java
+++ b/source/java/org/alfresco/repo/version/common/VersionUtil.java
@@ -15,11 +15,11 @@
* 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:
+ * 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.version.common;
@@ -27,11 +27,13 @@ package org.alfresco.repo.version.common;
import java.util.Collection;
import org.alfresco.repo.version.VersionModel;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.version.ReservedVersionNameException;
/**
* Helper class containing helper methods for the versioning services.
- *
+ *
* @author Roy Wetherall
*/
public class VersionUtil
@@ -40,20 +42,20 @@ public class VersionUtil
* Reserved property names
*/
public static final String[] RESERVED_PROPERTY_NAMES = new String[]{
- VersionModel.PROP_CREATED_DATE,
- VersionModel.PROP_FROZEN_NODE_ID,
- VersionModel.PROP_FROZEN_NODE_STORE_ID,
+ VersionModel.PROP_CREATED_DATE,
+ VersionModel.PROP_FROZEN_NODE_ID,
+ VersionModel.PROP_FROZEN_NODE_STORE_ID,
VersionModel.PROP_FROZEN_NODE_STORE_PROTOCOL,
VersionModel.PROP_FROZEN_NODE_TYPE,
VersionModel.PROP_FROZEN_ASPECTS,
VersionModel.PROP_VERSION_LABEL,
VersionModel.PROP_VERSION_NUMBER};
-
+
/**
* Checks that the names of the additional version properties are valid and that they do not clash
* with the reserved properties.
- *
- * @param versionProperties the property names
+ *
+ * @param versionProperties the property names
* @return true is the names are considered valid, false otherwise
* @throws ReservedVersionNameException
*/
@@ -68,4 +70,16 @@ public class VersionUtil
}
}
}
+
+ /**
+ * Convert the incomming node ref (with the version store protocol specified)
+ * to the internal representation with the workspace protocol.
+ *
+ * @param nodeRef the incomming verison protocol node reference
+ * @return the internal version node reference
+ */
+ public static NodeRef convertNodeRef(NodeRef nodeRef)
+ {
+ return new NodeRef(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionModel.STORE_ID), nodeRef.getId());
+ }
}
diff --git a/source/java/org/alfresco/service/cmr/ml/ContentFilterLanguagesService.java b/source/java/org/alfresco/service/cmr/ml/ContentFilterLanguagesService.java
index f7c76bc102..45399e5d35 100644
--- a/source/java/org/alfresco/service/cmr/ml/ContentFilterLanguagesService.java
+++ b/source/java/org/alfresco/service/cmr/ml/ContentFilterLanguagesService.java
@@ -35,7 +35,7 @@ import org.alfresco.service.PublicService;
/**
* This service interface provides support for content filter languages .
*
- * @author yanipig
+ * @author Yannick Pignot
*
*/
@PublicService
diff --git a/source/java/org/alfresco/service/cmr/ml/EditionService.java b/source/java/org/alfresco/service/cmr/ml/EditionService.java
new file mode 100644
index 0000000000..6378631488
--- /dev/null
+++ b/source/java/org/alfresco/service/cmr/ml/EditionService.java
@@ -0,0 +1,95 @@
+/*
+ * 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.service.cmr.ml;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
+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.namespace.QName;
+
+/**
+ * The API to manage editions of a mlContainer. An edition is a version of a mlContainer
+ *
+ * @since 2.1
+ * @author Yannick Pignot
+ */
+@PublicService
+public interface EditionService
+{
+ /**
+ * Create a new edition of an existing cm:mlContainer using any one of the
+ * associated cm:mlDocument transalations.
+ *
+ * If startingTranslationNodeRef is multilingual, it will be copied. The copy will become the pivot translation
+ * of the new Edition of the cm:mlContainer. The reference of the copy will be returned.
+ *
+ * @param translationNodeRef The specific cm:mlDocument to use as the starting point
+ * of the new edition. All other translations will be removed.
+ */
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef", "versionProperties"})
+ NodeRef createEdition(NodeRef translationNodeRef, Map versionProperties);
+
+ /**
+ * Get editions of an existing cm:mlContainer.
+ *
+ * @param mlContainer An existing cm:mlContainer
+ * @return The Version History of the mlContainer
+ */
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"mlContainer"})
+ VersionHistory getEditions(NodeRef mlContainer);
+
+ /**
+ * Get the different cm:mlDocument transalation version histories of a specific edition of a cm:mlContainer
+ *
+ * @param mlContainerEdition An existing version of a mlContainer
+ * @return The list of cm:mlDocument transalation versions of the edition
+ */
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"mlContainerEdition"})
+ List getVersionedTranslations(Version mlContainerEdition);
+
+ /**
+ * Get the the versioned metadata of a specific cm:mlDocument transalation version or a specific
+ * cm:mlContainer version
+ *
+ * @see org.alfresco.repo.model.ml.MultilingualDocumentAspect.PROPERTIES_TO_VERSION the versioned metadata
+ * of a cm:mlDocument transalation added to the usual metadata versioned for a normal node.
+ *
+ * @see org.alfresco.repo.model.ml.MLContainerType.PROPERTIES_TO_VERSION the versioned metadata
+ * of a cm:mlContainer added to the usual metadata versioned for a normal node.
+ *
+ * @param version An existing version of a cm:mlDocument translation version or
+ * an existing version of a cm:mlContainer version.
+ * @return The versioned metadata
+ */
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"version"})
+ Map getVersionedMetadatas(Version version);
+
+ }
diff --git a/source/java/org/alfresco/service/cmr/ml/MultilingualContentService.java b/source/java/org/alfresco/service/cmr/ml/MultilingualContentService.java
index 68be4dcee3..6a20407d7d 100644
--- a/source/java/org/alfresco/service/cmr/ml/MultilingualContentService.java
+++ b/source/java/org/alfresco/service/cmr/ml/MultilingualContentService.java
@@ -15,11 +15,11 @@
* 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:
+ * 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.service.cmr.ml;
@@ -35,7 +35,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
/**
* The API to manage multilingual content and related structures.
- *
+ *
* @author Derek Hulley
* @author Philippe Dubois
*/
@@ -44,19 +44,19 @@ public interface MultilingualContentService
{
/**
* Checks whether an existing document is part of a translation group.
- *
+ *
* @param contentNodeRef An existing cm:content
* @return Returns true if the document has a cm:mlContainer parent
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"contentNodeRef"})
boolean isTranslation(NodeRef contentNodeRef);
-
+
/**
* Make an existing document into a translation by adding the cm:mlDocument aspect and
* creating a cm:mlContainer parent. If it is already a translation, then nothing is done.
*
* @param contentNodeRef An existing cm:content
- *
+ *
* @see org.alfresco.model.ContentModel#ASPECT_MULTILINGUAL_DOCUMENT
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"contentNodeRef", "locale"})
@@ -65,12 +65,12 @@ public interface MultilingualContentService
/**
* Removes the node from any associated translations. If the translation is the
* pivot translation, then the entire set of translations will be unhooked.
- *
+ *
* @param translationNodeRef an existing cm:mlDocument
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef"})
void unmakeTranslation(NodeRef translationNodeRef);
-
+
/**
* Make a translation out of an existing document. The necessary translation structures will be created
* as necessary.
@@ -90,61 +90,51 @@ public interface MultilingualContentService
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef"})
NodeRef getTranslationContainer(NodeRef translationNodeRef);
- /**
- * Create a new edition of an existing cm:mlContainer using any one of the
- * associated cm:mlDocument transalations.
- *
- * @param translationNodeRef The specific cm:mlDocument to use as the starting point
- * of the new edition. All other translations will be removed.
- */
- @Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef"})
- void createEdition(NodeRef translationNodeRef);
-
/**
* Gets the set of sibling translations associated with the given cm:mlDocument or
* cm:mlContainer.
- *
+ *
* @param translationOfNodeRef An existing cm:mlDocument or cm:mlContainer
* @return Returns a map of translation nodes keyed by locale
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationOfNodeRef"})
Map getTranslations(NodeRef translationOfNodeRef);
-
+
/**
* Given a cm:mlDocument, this method attempts to find the best translation for the given
* locale. If there is not even a
* {@link org.alfresco.i18n.I18NUtil#getNearestLocale(Locale, Set) partial match}, then the
* {@link #getPivotTranslation(NodeRef) pivot translation} is used. If that also gives no results
* then the translation itself is returned.
- *
+ *
* @param translationNodeRef the cm:mlDocument
* @param locale the target locale
* @return Returns the best match for the locale (never null)
- *
+ *
* @see #getTranslations(NodeRef)
* @see org.alfresco.i18n.I18NUtil#getNearestLocale(Locale, Set)
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef", "locale"})
NodeRef getTranslationForLocale(NodeRef translationNodeRef, Locale locale);
-
-
+
+
/**
* Given a cm:mlDocument or cm:mlContainer this node returns each locale for
- * which there isn't a translation.
- *
+ * which there isn't a translation.
+ *
* @param localizedNodeRef the cm:mlDocument or cm:mlContainer
- * @param addThisNodeLocale if true, add the locale of the given cm:mlDocument in the list.
+ * @param addThisNodeLocale if true, add the locale of the given cm:mlDocument in the list.
* @return Returns a list of missng locales
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"localizedNodeRef", "addThisNodeLocale"})
List getMissingTranslations(NodeRef localizedNodeRef, boolean addThisNodeLocale);
-
+
/**
* Given any node, this returns the pivot translation. All multilingual documents belong to
* a group linked by a hidden parent node of type cm:mlContainer. The pivot language
* for the translations is stored on the parent, and the child that has the same locale is the
* pivot translation.
- *
+ *
* @param nodeRef a cm:mlDocument translation or cm:mlContainer translation
* container
* @return Returns a corresponding cm:mlDocument that matches the locale of
@@ -153,7 +143,7 @@ public interface MultilingualContentService
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"nodeRef"})
NodeRef getPivotTranslation(NodeRef nodeRef);
-
+
/**
* Make a empty translation out of an existing pivot translation. The given translation or
* container will be used to find the pivot translation. Failing this, the given translation
@@ -164,12 +154,40 @@ public interface MultilingualContentService
*
*
* The necessary translation structures will be created as necessary.
- *
+ *
* @param translationOfNodeRef An existing cm:mlDocument
* @param name The name of the file to create, or null to use
* the default naming convention.
- * @return Returns the new created cm:mlEmptyTranslation
+ * @return Returns the new created cm:mlEmptyTranslation
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationOfNodeRef", "name", "locale"})
NodeRef addEmptyTranslation(NodeRef translationOfNodeRef, String name, Locale locale);
+
+ /**
+ * Copies the given cm:mlContainer.
+ *
+ * This involves the copy of the cm:mlContainer node and the copy of its cm:mlDocument.
+ *
+ *
+ * @param translationNodeRef The cm:mlContainer to copy
+ * @param newParentRef The new parent of the copied cm:mlDocument
+ * @return The copied cm:mlContainer
+ */
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef", "newParentRef"})
+ NodeRef copyTranslationContainer(NodeRef translationNodeRef, NodeRef newParentRef);
+
+ /**
+ * Moves the location of the given cm:mlContainer.
+ *
+ * This not involves changing the cm:mlContainer node but moves its cm:mlDocument.
+ *
+ *
+ * @param translationNodeRef The cm:mlContainer to move
+ * @param newParentRef The new parent of the moved cm:mlDocument
+ */
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef", "newParentRef"})
+ void moveTranslationContainer(NodeRef translationNodeRef, NodeRef newParentRef);
+
+
+
}