mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Yannick Pignot (European Commission) multilingual services
- EditionService for versioning of groups of translations - Quite a bit of trimming of whitespace that I have no intention of undoing. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5927 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -45,7 +45,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
*
|
||||
* {@link org.alfresco.service.cmr.ml.ContentFilterLanguagesService Content Filter Languages Service}
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class ContentFilterLanguagesMap implements ContentFilterLanguagesService
|
||||
{
|
||||
|
420
source/java/org/alfresco/repo/model/ml/EditionServiceImpl.java
Normal file
420
source/java/org/alfresco/repo/model/ml/EditionServiceImpl.java
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* 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.model.ml;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.node.archive.NodeArchiveService;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.repo.version.common.VersionUtil;
|
||||
import org.alfresco.service.cmr.ml.EditionService;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Edition support implementation
|
||||
*
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class EditionServiceImpl implements EditionService
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(EditionServiceImpl.class);
|
||||
|
||||
private VersionService versionService;
|
||||
private NodeService nodeService;
|
||||
private BehaviourFilter policyBehaviourFilter;
|
||||
private MultilingualContentService multilingualContentService;
|
||||
private NodeArchiveService nodeArchiveService;
|
||||
private NodeService versionNodeService;
|
||||
private FileFolderService fileFolderService;
|
||||
|
||||
/**
|
||||
* List of properties to set persistent when an edition of the mlContainer is created
|
||||
*/
|
||||
public static final QName[] ML_CONTAINER_PROPERTIES_TO_VERSION = {
|
||||
ContentModel.PROP_AUTHOR,
|
||||
ContentModel.PROP_LOCALE
|
||||
};
|
||||
|
||||
/** @inheritDoc */
|
||||
public NodeRef createEdition(NodeRef startingTranslationNodeRef, Map<String, Serializable> versionProperties)
|
||||
{
|
||||
if (nodeService.hasAspect(startingTranslationNodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
{
|
||||
return createEditionImpl(
|
||||
startingTranslationNodeRef,
|
||||
versionProperties
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("The node " + startingTranslationNodeRef + " is not multilingual.");
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef createEditionImpl(NodeRef startingTranslationNodeRef, Map<String, Serializable> versionProperties)
|
||||
{
|
||||
|
||||
// 1. First step: prepare and version the mlContainer
|
||||
|
||||
// Get the ml container to version
|
||||
NodeRef mlContainerToVersion = multilingualContentService.getTranslationContainer(startingTranslationNodeRef);
|
||||
// Get all the container's children
|
||||
List<ChildAssociationRef> childAssocRefs = nodeService.getChildAssocs(
|
||||
mlContainerToVersion, ContentModel.ASSOC_MULTILINGUAL_CHILD,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
// get the last edition and add it the Version Histories property to the version
|
||||
Version currentEdition = versionService.getCurrentVersion(mlContainerToVersion);
|
||||
addVersionHitoryProperty(currentEdition, childAssocRefs);
|
||||
|
||||
if(versionProperties == null)
|
||||
{
|
||||
versionProperties = new HashMap<String, Serializable>();
|
||||
}
|
||||
|
||||
// get the properties to add to the edition history
|
||||
addPropertiesToVersion(versionProperties, mlContainerToVersion);
|
||||
|
||||
// Version the container and its translations
|
||||
versionService.createVersion(mlContainerToVersion, versionProperties, true);
|
||||
|
||||
// 2. Third step: prepare the current edition of the mlContainer
|
||||
|
||||
// Get the new starting point node, it will be returned
|
||||
NodeRef startNode;
|
||||
|
||||
// copy the translation before its deletion and get usefull properties
|
||||
NodeRef space = nodeService.getPrimaryParent(startingTranslationNodeRef).getParentRef();
|
||||
String name = (String) nodeService.getProperty(startingTranslationNodeRef, ContentModel.PROP_NAME);
|
||||
Locale locale = (Locale) nodeService.getProperty(startingTranslationNodeRef, ContentModel.PROP_LOCALE);
|
||||
String author = (String) nodeService.getProperty(startingTranslationNodeRef, ContentModel.PROP_AUTHOR);
|
||||
|
||||
for (int count = 0;; count++)
|
||||
{
|
||||
try
|
||||
{
|
||||
// genererate a temporary name.
|
||||
String tempName = "TEMP_NAME" + System.currentTimeMillis() + "_" + count;
|
||||
|
||||
// try to copy the node
|
||||
startNode = fileFolderService.copy(startingTranslationNodeRef, space, tempName).getNodeRef();
|
||||
|
||||
// copy completed without exception
|
||||
break;
|
||||
|
||||
}
|
||||
catch (FileExistsException e)
|
||||
{
|
||||
// try again with a new name
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// remove the current translations of the mlContainer
|
||||
removeTranslations(childAssocRefs);
|
||||
|
||||
// restore the original name of the node
|
||||
nodeService.setProperty(startNode, ContentModel.PROP_NAME, name);
|
||||
|
||||
|
||||
// add the starting node to the mlContainer, and set the author
|
||||
multilingualContentService.addTranslation(startNode, mlContainerToVersion, locale);
|
||||
nodeService.setProperty(startNode, ContentModel.PROP_AUTHOR, author);
|
||||
|
||||
// set the starting translation become the pivot.
|
||||
nodeService.setProperty(mlContainerToVersion, ContentModel.PROP_LOCALE, locale);
|
||||
nodeService.setProperty(mlContainerToVersion, ContentModel.PROP_AUTHOR, author);
|
||||
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
// Get the version information
|
||||
Version mlContainerVersion = versionService.getCurrentVersion(mlContainerToVersion);
|
||||
String mlContainerVersionLabel = mlContainerVersion.getVersionLabel();
|
||||
|
||||
logger.debug("Versioned multilingual container: \n"
|
||||
+ " Container: " + mlContainerToVersion + "\n"
|
||||
+ " Current Version: " + mlContainerVersionLabel);
|
||||
}
|
||||
|
||||
return startNode;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public VersionHistory getEditions(NodeRef mlContainer)
|
||||
{
|
||||
VersionHistory editionHistory = null;
|
||||
|
||||
// Only the mlContainer can have editions
|
||||
if (nodeService.getType(mlContainer).equals(
|
||||
ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
// get the editions of the mlContainer
|
||||
editionHistory = versionService.getVersionHistory(mlContainer);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("The type of the node must be "
|
||||
+ ContentModel.TYPE_CONTAINER);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Found all editions: \n" + " Node: "
|
||||
+ mlContainer + " (type "
|
||||
+ ContentModel.TYPE_MULTILINGUAL_CONTAINER + ")\n"
|
||||
+ " Editions: " + editionHistory);
|
||||
}
|
||||
|
||||
return editionHistory;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public Map<QName, Serializable> getVersionedMetadatas(Version version)
|
||||
{
|
||||
NodeRef frozenNodeRef = version.getFrozenStateNodeRef();
|
||||
|
||||
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(frozenNodeRef)))
|
||||
{
|
||||
// for the mlContainer, the properties are set as a version properties
|
||||
Map<String, Serializable> properties = version.getVersionProperties();
|
||||
|
||||
// The returned map of this method need a QName type key, not a String.
|
||||
Map<QName, Serializable> convertedProperties = new HashMap<QName, Serializable>(properties.size());
|
||||
|
||||
// perform the convertion
|
||||
for(Map.Entry<String, Serializable> entry : properties.entrySet())
|
||||
{
|
||||
convertedProperties.put(
|
||||
QName.createQName(entry.getKey()),
|
||||
entry.getValue());
|
||||
}
|
||||
|
||||
return convertedProperties;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for any other type of node, the properties are set as versioned metadata
|
||||
return versionNodeService.getProperties(frozenNodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public List<VersionHistory> getVersionedTranslations(Version mlContainerEdition)
|
||||
{
|
||||
// Ensure that the given version is an Edition of an mlContainer
|
||||
if(!ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(mlContainerEdition.getVersionedNodeRef())))
|
||||
{
|
||||
throw new IllegalArgumentException("The type of the node must be " + ContentModel.TYPE_CONTAINER);
|
||||
}
|
||||
|
||||
Map<QName, Serializable> properties = versionNodeService.getProperties(mlContainerEdition.getFrozenStateNodeRef());
|
||||
|
||||
// get the serialisation of the version histories in the version properties
|
||||
List<VersionHistory> versionHistories = (List<VersionHistory>)
|
||||
properties.get(VersionModel.PROP_QNAME_TRANSLATION_VERIONS);
|
||||
|
||||
if (versionHistories == null)
|
||||
{
|
||||
// the initial edition doesn't content translations (at the creation time of the mlContainer).
|
||||
versionHistories = new ArrayList<VersionHistory>();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Found all translations : \n"
|
||||
+ " Versioned mlContainer: " + mlContainerEdition.getVersionedNodeRef() + "\n"
|
||||
+ " Edition: " + mlContainerEdition
|
||||
+ " Translations: " + versionHistories);
|
||||
}
|
||||
|
||||
return versionHistories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Util method to add the version histories of translations as a property of the frozen mlContainer
|
||||
*/
|
||||
private void addVersionHitoryProperty(Version edition, List<ChildAssociationRef> childAssocRefs)
|
||||
{
|
||||
List<VersionHistory> translationVersionHistories = new ArrayList<VersionHistory>(childAssocRefs.size());
|
||||
|
||||
for (ChildAssociationRef ref : childAssocRefs)
|
||||
{
|
||||
NodeRef translation = ref.getChildRef();
|
||||
|
||||
translationVersionHistories.add(versionService.getVersionHistory(translation));
|
||||
|
||||
}
|
||||
|
||||
// properties in which the version histories will be stored
|
||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
|
||||
|
||||
// add the version history of the translation as property of the Edition
|
||||
properties.put(VersionModel.PROP_QNAME_QNAME, VersionModel.PROP_QNAME_TRANSLATION_VERIONS);
|
||||
properties.put(VersionModel.PROP_QNAME_IS_MULTI_VALUE, true);
|
||||
properties.put(VersionModel.PROP_QNAME_MULTI_VALUE, (Serializable) translationVersionHistories);
|
||||
|
||||
// create the versioned property node
|
||||
this.nodeService.createNode(
|
||||
VersionUtil.convertNodeRef(edition.getFrozenStateNodeRef()),
|
||||
VersionModel.CHILD_QNAME_VERSIONED_ATTRIBUTES,
|
||||
VersionModel.CHILD_QNAME_VERSIONED_ATTRIBUTES,
|
||||
VersionModel.TYPE_QNAME_VERSIONED_PROPERTY,
|
||||
properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Util method to add the usefull properties to the existing properties of the given, mlContainer
|
||||
*
|
||||
* @link {@link EditionServiceImpl#ML_CONTAINER_PROPERTIES_TO_VERSION}
|
||||
*/
|
||||
private void addPropertiesToVersion(Map<String, Serializable> versionProperties, NodeRef mlContainerToVersion)
|
||||
{
|
||||
// add useful properties
|
||||
for(QName prop : ML_CONTAINER_PROPERTIES_TO_VERSION)
|
||||
{
|
||||
versionProperties.put(prop.toString(), nodeService.getProperty(mlContainerToVersion, prop));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Util method to remove the given translations after making a new edition
|
||||
*/
|
||||
private void removeTranslations(List<ChildAssociationRef> childAssocRefs)
|
||||
{
|
||||
// Turn off any auto-version policy behaviours. Without that,
|
||||
// the version history of the translations will be deleted.
|
||||
this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
|
||||
|
||||
// Turn off any multilingual document policy behaviours. Without that,
|
||||
// the mlcontainer of the translations will be deleted.
|
||||
this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
|
||||
try
|
||||
{
|
||||
for (ChildAssociationRef childAssoc : childAssocRefs)
|
||||
{
|
||||
NodeRef documentNodeRef = childAssoc.getChildRef();
|
||||
|
||||
// Permanently delete it
|
||||
nodeService.deleteNode(documentNodeRef);
|
||||
if(nodeService.exists(nodeArchiveService.getArchivedNode(documentNodeRef)))
|
||||
{
|
||||
nodeService.deleteNode(nodeArchiveService.getArchivedNode(documentNodeRef));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Turn auto-version and multinlingual document policies back on
|
||||
this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE);
|
||||
this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService
|
||||
* the Node Service to set
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionService
|
||||
* the Version Service to set
|
||||
*/
|
||||
public void setVersionService(VersionService versionService)
|
||||
{
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param multilingualContentService
|
||||
* the Multilingual Content Service to set
|
||||
*/
|
||||
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
|
||||
{
|
||||
this.multilingualContentService = multilingualContentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionNodeService
|
||||
* the Version Store Node Service to set
|
||||
*/
|
||||
public void setVersionNodeService(NodeService versionNodeService)
|
||||
{
|
||||
this.versionNodeService = versionNodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param policyBehaviourFilter the Behaviour Filter to set
|
||||
*/
|
||||
public void setPolicyBehaviourFilter(BehaviourFilter policyBehaviourFilter)
|
||||
{
|
||||
this.policyBehaviourFilter = policyBehaviourFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeArchiveService the node Archive Service to set
|
||||
*/
|
||||
public void setNodeArchiveService(NodeArchiveService nodeArchiveService)
|
||||
{
|
||||
this.nodeArchiveService = nodeArchiveService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileFolderService the fileFolder Service to set
|
||||
*/
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
}
|
@@ -44,7 +44,7 @@ import org.alfresco.service.namespace.QName;
|
||||
*
|
||||
* {@link ContentModel#ASPECT_MULTILINGUAL_EMPTY_TRANSLATION ml empty document aspect}
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class EmptyTranslationAspect implements
|
||||
CopyServicePolicies.OnCopyNodePolicy,
|
||||
|
@@ -45,7 +45,7 @@ import org.alfresco.service.namespace.QName;
|
||||
*
|
||||
* {@link ContentModel#TYPE_MULTILINGUAL_CONTAINER multilingual container type}
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class MLContainerType implements
|
||||
NodeServicePolicies.OnUpdatePropertiesPolicy
|
||||
|
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package org.alfresco.repo.model.ml;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -35,7 +34,6 @@ import java.util.Set;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.service.cmr.ml.ContentFilterLanguagesService;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
@@ -49,8 +47,6 @@ import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
@@ -77,7 +73,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @author Philippe Dubois
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class MultilingualContentServiceImpl implements MultilingualContentService
|
||||
{
|
||||
@@ -85,7 +81,6 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
|
||||
private NodeService nodeService;
|
||||
private SearchService searchService;
|
||||
private VersionService versionService;
|
||||
private PermissionService permissionService;
|
||||
private SearchParameters searchParametersMLRoot;
|
||||
private ContentFilterLanguagesService contentFilterLanguagesService;
|
||||
@@ -136,8 +131,8 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
NodeRef mlContainerRootNodeRef = getMLContainerRoot();
|
||||
// Create the container
|
||||
PropertyMap versionProperties = new PropertyMap();
|
||||
versionProperties.put(ContentModel.PROP_AUTO_VERSION, Boolean.FALSE);
|
||||
versionProperties.put(ContentModel.PROP_INITIAL_VERSION, Boolean.FALSE);
|
||||
//versionProperties.put(ContentModel.PROP_AUTO_VERSION, Boolean.FALSE);
|
||||
//versionProperties.put(ContentModel.PROP_INITIAL_VERSION, Boolean.FALSE);
|
||||
ChildAssociationRef assocRef = nodeService.createNode(
|
||||
mlContainerRootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
@@ -146,8 +141,8 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
versionProperties);
|
||||
NodeRef mlContainerNodeRef = assocRef.getChildRef();
|
||||
// TODO: Examine the usage of versioning - why is autoversioning on and used in the UI?
|
||||
// // The model makes the container versionable by default, but why?
|
||||
// nodeService.addAspect(mlContainerNodeRef, ContentModel.ASPECT_VERSIONABLE, versionProperties);
|
||||
// The model makes the container versionable by default, but why?
|
||||
nodeService.addAspect(mlContainerNodeRef, ContentModel.ASPECT_VERSIONABLE, versionProperties);
|
||||
// Set the permissions to allow anything by anyone
|
||||
permissionService.setPermission(
|
||||
mlContainerNodeRef,
|
||||
@@ -193,7 +188,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
// Done
|
||||
return mlContainerNodeRef;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve or create a <b>cm:mlDocument</b> container for the given node, which must have the
|
||||
* <b>cm:mlDocument</b> already applied.
|
||||
@@ -312,7 +307,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
// done
|
||||
return mlContainerNodeRef;
|
||||
}
|
||||
|
||||
|
||||
private boolean isPivotTranslation(NodeRef contentNodeRef)
|
||||
{
|
||||
Locale locale = (Locale) nodeService.getProperty(contentNodeRef, ContentModel.PROP_LOCALE);
|
||||
@@ -359,7 +354,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @inheritDoc */
|
||||
public void makeTranslation(NodeRef contentNodeRef, Locale locale)
|
||||
{
|
||||
@@ -432,7 +427,17 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
public void addTranslation(NodeRef newTranslationNodeRef, NodeRef translationOfNodeRef, Locale locale)
|
||||
{
|
||||
// Get the container
|
||||
NodeRef mlContainerNodeRef = getOrCreateMLContainer(translationOfNodeRef, false);
|
||||
NodeRef mlContainerNodeRef = null;
|
||||
|
||||
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(translationOfNodeRef)))
|
||||
{
|
||||
mlContainerNodeRef = translationOfNodeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
mlContainerNodeRef = getOrCreateMLContainer(translationOfNodeRef, false);
|
||||
}
|
||||
|
||||
// Use the existing container to make the new content into a translation
|
||||
makeTranslationImpl(mlContainerNodeRef, newTranslationNodeRef, locale);
|
||||
// done
|
||||
@@ -453,72 +458,6 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
return mlContainerNodeRef;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public void createEdition( NodeRef translationNodeRef)
|
||||
{
|
||||
NodeRef mlContainerNodeRef = getOrCreateMLContainer(translationNodeRef, false);
|
||||
// Ensure that the translation given is one of the children
|
||||
getOrCreateMLContainer(translationNodeRef, false);
|
||||
// Get all the container's children
|
||||
List<ChildAssociationRef> childAssocRefs = nodeService.getChildAssocs(
|
||||
mlContainerNodeRef,
|
||||
ContentModel.ASSOC_MULTILINGUAL_CHILD,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
|
||||
// Get and store the translation verions associated to the mlContainer
|
||||
List<Version> versions = new ArrayList<Version>(childAssocRefs.size());
|
||||
|
||||
for (ChildAssociationRef childAssoc : childAssocRefs)
|
||||
{
|
||||
versions.add(versionService.getCurrentVersion(childAssoc.getChildRef()));
|
||||
}
|
||||
|
||||
Map<String, Serializable> editionProperties = new HashMap<String, Serializable>();
|
||||
editionProperties.put(
|
||||
VersionModel.PROP_QNAME_TRANSLATION_VERIONS.toString(),
|
||||
(Serializable) versions
|
||||
);
|
||||
|
||||
// Version the container and all its children
|
||||
versionService.createVersion(mlContainerNodeRef, editionProperties, true);
|
||||
|
||||
// Remove all the child documents apart from the given node
|
||||
boolean found = false;
|
||||
for (ChildAssociationRef childAssoc : childAssocRefs)
|
||||
{
|
||||
NodeRef documentNodeRef = childAssoc.getChildRef();
|
||||
// Is this the node to keep?
|
||||
if (documentNodeRef.equals(translationNodeRef))
|
||||
{
|
||||
// It is, so keep it
|
||||
found = true;
|
||||
continue;
|
||||
}
|
||||
// Delete it
|
||||
nodeService.deleteNode(documentNodeRef);
|
||||
}
|
||||
// Check that we left a document
|
||||
if (!found)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"The translation provided is not a child of the multilingual container: \n" +
|
||||
" Container: " + mlContainerNodeRef + "\n" +
|
||||
" Translation: " + translationNodeRef);
|
||||
}
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
// Get the version information
|
||||
Version mlContainerVersion = versionService.getCurrentVersion(mlContainerNodeRef);
|
||||
String mlContainerVersionLabel = mlContainerVersion.getVersionLabel();
|
||||
logger.debug(
|
||||
"Versioned multilingual container: \n" +
|
||||
" Container: " + mlContainerNodeRef + "\n" +
|
||||
" Current Version: " + mlContainerVersionLabel);
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public Map<Locale, NodeRef> getTranslations(NodeRef translationOfNodeRef)
|
||||
{
|
||||
@@ -676,7 +615,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
return nodeRefsByLocale.get(nearestLocale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -704,7 +643,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
" Translation: " + translationOfNodeRef + "\n" +
|
||||
" Locale: " + locale);
|
||||
}
|
||||
|
||||
|
||||
FileInfo translationOfFileInfo = fileFolderService.getFileInfo(translationOfNodeRef);
|
||||
String translationOfName = translationOfFileInfo.getName();
|
||||
// If name is null, supply one
|
||||
@@ -713,7 +652,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
name = translationOfName;
|
||||
}
|
||||
// If there is a name clash, add the locale to the main portion of the filename
|
||||
if (name.equals(translationOfName))
|
||||
if (name.equalsIgnoreCase(translationOfName))
|
||||
{
|
||||
String localeStr = locale.toString();
|
||||
if (localeStr.endsWith("_"))
|
||||
@@ -744,7 +683,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
parentNodeRef,
|
||||
name,
|
||||
ContentModel.TYPE_CONTENT).getNodeRef();
|
||||
|
||||
|
||||
// add the translation to the container
|
||||
addTranslation(newTranslationNodeRef, translationOfNodeRef, locale);
|
||||
|
||||
@@ -788,15 +727,10 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
public void setVersionService(VersionService versionService)
|
||||
{
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
public void setPermissionService(PermissionService permissionService)
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
public void setContentFilterLanguagesService(ContentFilterLanguagesService contentFilterLanguagesService)
|
||||
{
|
||||
@@ -807,4 +741,14 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public NodeRef copyTranslationContainer(NodeRef translationNodeRef, NodeRef newParentRef)
|
||||
{
|
||||
throw new UnsupportedOperationException("This operation is not yet supported");
|
||||
}
|
||||
|
||||
public void moveTranslationContainer(NodeRef translationNodeRef, NodeRef newParentRef)
|
||||
{
|
||||
throw new UnsupportedOperationException("This operation is not yet supported");
|
||||
}
|
||||
}
|
@@ -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.model.ml;
|
||||
@@ -35,6 +35,7 @@ import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.policy.PolicyScope;
|
||||
import org.alfresco.repo.version.VersionServicePolicies;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
@@ -46,54 +47,69 @@ import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
|
||||
/**
|
||||
* Class containing behaviour for the multilingual document aspect.
|
||||
*
|
||||
*
|
||||
* {@link ContentModel#ASPECT_MULTILINGUAL_DOCUMENT ml document aspect}
|
||||
*
|
||||
* @author yanipig
|
||||
*/
|
||||
public class MultilingualDocumentAspect implements
|
||||
public class MultilingualDocumentAspect implements
|
||||
CopyServicePolicies.OnCopyNodePolicy,
|
||||
CopyServicePolicies.OnCopyCompletePolicy,
|
||||
NodeServicePolicies.BeforeDeleteNodePolicy,
|
||||
NodeServicePolicies.OnUpdatePropertiesPolicy
|
||||
NodeServicePolicies.OnUpdatePropertiesPolicy,
|
||||
VersionServicePolicies.OnCreateVersionPolicy
|
||||
{
|
||||
|
||||
/**
|
||||
* List of properties to set persistent when a version of the mlDocument is created
|
||||
*/
|
||||
public static final QName[] PROPERTIES_TO_VERSION = {
|
||||
ContentModel.PROP_AUTHOR,
|
||||
ContentModel.PROP_LOCALE,
|
||||
ContentModel.PROP_TITLE,
|
||||
ContentModel.PROP_DESCRIPTION,
|
||||
};
|
||||
|
||||
// Dependencies
|
||||
private PolicyComponent policyComponent;
|
||||
|
||||
private MultilingualContentService multilingualContentService;
|
||||
|
||||
private NodeService nodeService;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the Multilingual Aspect
|
||||
*
|
||||
*
|
||||
* Ensures that the {@link ContentModel#ASPECT_MULTILINGUAL_DOCUMENT ml document aspect}
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyNode"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_DOCUMENT,
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyNode"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_DOCUMENT,
|
||||
new JavaBehaviour(this, "onCopyNode"));
|
||||
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyComplete"),
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyComplete"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_DOCUMENT,
|
||||
new JavaBehaviour(this, "onCopyComplete"));
|
||||
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_DOCUMENT,
|
||||
new JavaBehaviour(this, "beforeDeleteNode"));
|
||||
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_DOCUMENT,
|
||||
new JavaBehaviour(this, "beforeDeleteNode"));
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_DOCUMENT,
|
||||
new JavaBehaviour(this, "onUpdateProperties"));
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateVersion"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_DOCUMENT,
|
||||
new JavaBehaviour(this, "onCreateVersion"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param policyComponent the policy component to register behaviour with
|
||||
*/
|
||||
@@ -101,12 +117,12 @@ public class MultilingualDocumentAspect implements
|
||||
{
|
||||
this.policyComponent = policyComponent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param multilingualContentService the Multilingual Content Service to set
|
||||
*/
|
||||
public void setMultilingualContentService(
|
||||
MultilingualContentService multilingualContentService)
|
||||
MultilingualContentService multilingualContentService)
|
||||
{
|
||||
this.multilingualContentService = multilingualContentService;
|
||||
}
|
||||
@@ -114,36 +130,36 @@ public class MultilingualDocumentAspect implements
|
||||
/**
|
||||
* @param nodeService the Node Service to set
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The copy of a <b>cm:mlDocument</b> can't keep the Multilingual aspect.
|
||||
*
|
||||
*
|
||||
* @see org.alfresco.repo.copy.CopyServicePolicies.OnCopyNodePolicy#onCopyNode(org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.StoreRef, boolean, org.alfresco.repo.policy.PolicyScope)
|
||||
*/
|
||||
public void onCopyNode(QName classRef, NodeRef sourceNodeRef, StoreRef destinationStoreRef, boolean copyToNewNode, PolicyScope copyDetails)
|
||||
public void onCopyNode(QName classRef, NodeRef sourceNodeRef, StoreRef destinationStoreRef, boolean copyToNewNode, PolicyScope copyDetails)
|
||||
{
|
||||
copyDetails.removeAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
copyDetails.removeAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The copy of <b>mlDocument</b> don't keep the 'locale' property.
|
||||
*
|
||||
* The copy of <b>mlDocument</b> don't keep the 'locale' property.
|
||||
*
|
||||
* @see org.alfresco.repo.copy.CopyServicePolicies.OnCopyCompletePolicy#onCopyComplete(org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, boolean, java.util.Map)
|
||||
*/
|
||||
public void onCopyComplete(QName classRef, NodeRef sourceNodeRef, NodeRef destinationRef, boolean copyToNewNode, Map<NodeRef, NodeRef> copyMap)
|
||||
public void onCopyComplete(QName classRef, NodeRef sourceNodeRef, NodeRef destinationRef, boolean copyToNewNode, Map<NodeRef, NodeRef> copyMap)
|
||||
{
|
||||
nodeService.removeProperty(destinationRef, ContentModel.PROP_LOCALE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If this is not an empty translation, then ensure that the node is properly
|
||||
* unhooked from the translation mechanism first.
|
||||
*/
|
||||
public void beforeDeleteNode(NodeRef nodeRef)
|
||||
public void beforeDeleteNode(NodeRef nodeRef)
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
@@ -155,63 +171,63 @@ public class MultilingualDocumentAspect implements
|
||||
multilingualContentService.unmakeTranslation(nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensure that the locale is unique inside the <b>mlContainer</b>.
|
||||
*
|
||||
*
|
||||
* If the locale of a pivot translation is modified, the pivot locale reference of the mlContainer
|
||||
* must be modified too.
|
||||
*
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy#onUpdateProperties(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, java.util.Map)
|
||||
*/
|
||||
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
|
||||
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
|
||||
{
|
||||
/*
|
||||
* TODO: Move this into MultilingualContentService#setTranslationLocale
|
||||
*/
|
||||
|
||||
|
||||
Locale localeBefore = (Locale) before.get(ContentModel.PROP_LOCALE);
|
||||
Locale localeAfter;
|
||||
|
||||
// the after local property type can be either Locale or String
|
||||
|
||||
// the after local property type can be either Locale or String
|
||||
Serializable objLocaleAfter = after.get(ContentModel.PROP_LOCALE);
|
||||
if (objLocaleAfter instanceof Locale )
|
||||
if (objLocaleAfter instanceof Locale )
|
||||
{
|
||||
localeAfter = (Locale) objLocaleAfter;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
localeAfter = I18NUtil.parseLocale(objLocaleAfter.toString());
|
||||
}
|
||||
|
||||
|
||||
// if the local has been modified
|
||||
if(!localeBefore.equals(localeAfter))
|
||||
{
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(nodeRef);
|
||||
|
||||
// Since the map returned by the getTranslations doesn't duplicate keys, the size of this map will be
|
||||
|
||||
// Since the map returned by the getTranslations doesn't duplicate keys, the size of this map will be
|
||||
// different of the size of the number of children of the mlContainer if a duplicate locale is found.
|
||||
int transSize = multilingualContentService.getTranslations(mlContainer).size();
|
||||
int childSize = nodeService.getChildAssocs(mlContainer, ContentModel.ASSOC_MULTILINGUAL_CHILD, RegexQNamePattern.MATCH_ALL).size();
|
||||
|
||||
|
||||
// if duplicate locale found
|
||||
if(transSize != childSize)
|
||||
{
|
||||
// throw an exception and the current transaction will be rolled back. The properties will not be
|
||||
// throw an exception and the current transaction will be rolled back. The properties will not be
|
||||
// longer in an illegal state.
|
||||
throw new IllegalArgumentException("The locale " + localeAfter +
|
||||
" can't be changed for the node " + nodeRef +
|
||||
throw new IllegalArgumentException("The locale " + localeAfter +
|
||||
" can't be changed for the node " + nodeRef +
|
||||
" because this locale is already in use in an other translation of the same " +
|
||||
ContentModel.TYPE_MULTILINGUAL_CONTAINER + ".");
|
||||
}
|
||||
|
||||
|
||||
// get the locale of ML Container
|
||||
Locale localMlContainer = (Locale) nodeService.getProperty(
|
||||
mlContainer,
|
||||
ContentModel.PROP_LOCALE);
|
||||
|
||||
// if locale of the container is equals to the locale of
|
||||
|
||||
// if locale of the container is equals to the locale of
|
||||
// the node (before update). The nodeRef is the pivot language
|
||||
// and the locale of the mlContainer must be modified
|
||||
if(localeBefore.equals(localMlContainer))
|
||||
@@ -219,12 +235,26 @@ public class MultilingualDocumentAspect implements
|
||||
nodeService.setProperty(
|
||||
mlContainer,
|
||||
ContentModel.PROP_LOCALE,
|
||||
localeAfter);
|
||||
localeAfter);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// else no action to perform
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist some specific properties in the version store
|
||||
*
|
||||
* @see org.alfresco.repo.model.ml.MultilingualDocumentAspect.PROPERTIES_TO_VERSION
|
||||
* @see org.alfresco.repo.version.VersionServicePolicies.OnCreateVersionPolicy#onCreateVersion(org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef, java.util.Map, org.alfresco.repo.policy.PolicyScope)
|
||||
*/
|
||||
public void onCreateVersion(QName classRef, NodeRef versionableNode, Map<String, Serializable> versionProperties, PolicyScope nodeDetails)
|
||||
{
|
||||
for(QName prop : PROPERTIES_TO_VERSION)
|
||||
{
|
||||
nodeDetails.addProperty(prop, nodeService.getProperty(versionableNode, prop));
|
||||
}
|
||||
|
||||
// else no action to perform
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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.model.ml;
|
||||
@@ -28,6 +28,7 @@ import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.alfresco.repo.model.ml.tools.ContentFilterLanguagesMapTest;
|
||||
import org.alfresco.repo.model.ml.tools.EditionServiceImplTest;
|
||||
import org.alfresco.repo.model.ml.tools.EmptyTranslationAspectTest;
|
||||
import org.alfresco.repo.model.ml.tools.MLContainerTypeTest;
|
||||
import org.alfresco.repo.model.ml.tools.MultilingualContentServiceImplTest;
|
||||
@@ -35,26 +36,27 @@ import org.alfresco.repo.model.ml.tools.MultilingualDocumentAspectTest;
|
||||
|
||||
/**
|
||||
* Multilingual test suite
|
||||
*
|
||||
*
|
||||
* @author yanipig
|
||||
*/
|
||||
public class MultilingualTestSuite extends TestSuite
|
||||
{
|
||||
/**
|
||||
* Creates the test suite
|
||||
*
|
||||
*
|
||||
* @return the test suite
|
||||
*/
|
||||
public static Test suite()
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite();
|
||||
|
||||
|
||||
suite.addTestSuite(EmptyTranslationAspectTest.class);
|
||||
suite.addTestSuite(ContentFilterLanguagesMapTest.class);
|
||||
suite.addTestSuite(MultilingualContentServiceImplTest.class);
|
||||
suite.addTestSuite(MultilingualDocumentAspectTest.class);
|
||||
suite.addTestSuite(MLContainerTypeTest.class);
|
||||
|
||||
suite.addTestSuite(EditionServiceImplTest.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
@@ -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.model.ml.tools;
|
||||
@@ -33,6 +33,7 @@ import org.alfresco.repo.transaction.TransactionUtil;
|
||||
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.ml.ContentFilterLanguagesService;
|
||||
import org.alfresco.service.cmr.ml.EditionService;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
@@ -48,12 +49,12 @@ import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Base multilingual test cases
|
||||
*
|
||||
*
|
||||
* @author yanipig
|
||||
*/
|
||||
public abstract class AbstractMultilingualTestCases extends TestCase
|
||||
public abstract class AbstractMultilingualTestCases extends TestCase
|
||||
{
|
||||
|
||||
|
||||
protected static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
|
||||
protected ServiceRegistry serviceRegistry;
|
||||
@@ -66,6 +67,8 @@ public abstract class AbstractMultilingualTestCases extends TestCase
|
||||
protected NodeRef folderNodeRef;
|
||||
protected ContentFilterLanguagesService contentFilterLanguagesService;
|
||||
protected NodeArchiveService nodeArchiveService;
|
||||
protected EditionService editionService;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
@@ -78,10 +81,11 @@ public abstract class AbstractMultilingualTestCases extends TestCase
|
||||
versionService = serviceRegistry.getVersionService();
|
||||
multilingualContentService = (MultilingualContentService) ctx.getBean("MultilingualContentService");
|
||||
contentFilterLanguagesService = (ContentFilterLanguagesService) ctx.getBean("ContentFilterLanguagesService");
|
||||
|
||||
editionService = (EditionService) ctx.getBean("EditionService");
|
||||
|
||||
// Run as admin
|
||||
authenticationComponent.setCurrentUser("admin");
|
||||
|
||||
|
||||
// Create a folder to work in
|
||||
TransactionWork<NodeRef> createFolderWork = new TransactionWork<NodeRef>()
|
||||
{
|
||||
@@ -101,7 +105,7 @@ public abstract class AbstractMultilingualTestCases extends TestCase
|
||||
};
|
||||
folderNodeRef = TransactionUtil.executeInUserTransaction(transactionService, createFolderWork);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
@@ -115,13 +119,13 @@ public abstract class AbstractMultilingualTestCases extends TestCase
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected NodeRef createContent()
|
||||
{
|
||||
String name = "" + System.currentTimeMillis();
|
||||
return createContent(name);
|
||||
}
|
||||
|
||||
|
||||
protected NodeRef createContent(String name)
|
||||
{
|
||||
NodeRef contentNodeRef = fileFolderService.create(
|
||||
@@ -134,7 +138,7 @@ public abstract class AbstractMultilingualTestCases extends TestCase
|
||||
// done
|
||||
return contentNodeRef;
|
||||
}
|
||||
|
||||
|
||||
public void testSetup() throws Exception
|
||||
{
|
||||
// Ensure that content can be created
|
||||
|
@@ -35,7 +35,7 @@ import java.util.Locale;
|
||||
* @see org.alfresco.service.cmr.ml.ContentFilterLanguagesService
|
||||
* @see org.alfresco.repo.model.ml.ContentFilterLanguagesMap
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class ContentFilterLanguagesMapTest extends AbstractMultilingualTestCases
|
||||
{
|
||||
|
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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.model.ml.tools;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
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.VersionType;
|
||||
|
||||
/**
|
||||
* Edition Service test cases
|
||||
*
|
||||
* @since 2.1
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class EditionServiceImplTest extends AbstractMultilingualTestCases
|
||||
{
|
||||
private static String FRENCH_CONTENT = "FRENCH_CONTENT";
|
||||
private static String CHINESE_CONTENT = "CHINESE_CONTENT";
|
||||
private static String JAPANESE_CONTENT = "JAPANESE_CONTENT";
|
||||
|
||||
public void testAutoEdition() throws Exception
|
||||
{
|
||||
// create a mlContainer with some content
|
||||
checkFirstVersion(this.createMLContainerWithContent());
|
||||
}
|
||||
|
||||
public void testEditionLabels()
|
||||
{
|
||||
// create a mlContainer with some content
|
||||
NodeRef mlContainerNodeRef = createMLContainerWithContent();
|
||||
Map<String, Serializable> versionProperties = null;
|
||||
List<Version> editions = null;
|
||||
NodeRef pivot = multilingualContentService.getPivotTranslation(mlContainerNodeRef);
|
||||
|
||||
checkFirstVersion(mlContainerNodeRef);
|
||||
|
||||
/*
|
||||
* at the creation (1.0)
|
||||
*/
|
||||
|
||||
Version rootEdition = editionService.getEditions(mlContainerNodeRef).getAllVersions().iterator().next();
|
||||
// Ensure that the version label is 1.0
|
||||
assertTrue("The edition label would be 1.0 and not " + rootEdition.getVersionLabel(), rootEdition.getVersionLabel().equals("1.0"));
|
||||
|
||||
/*
|
||||
* default (1.1)
|
||||
*/
|
||||
|
||||
pivot = editionService.createEdition(pivot, versionProperties);
|
||||
editions = orderVersions(editionService.getEditions(mlContainerNodeRef).getAllVersions());
|
||||
Version firstEdition = editions.get(0);
|
||||
// Ensure that the version label is 1.1
|
||||
assertTrue("The edition label would be 1.1 and not " + firstEdition.getVersionLabel(), firstEdition.getVersionLabel().equals("1.1"));
|
||||
|
||||
/*
|
||||
* major (2.0)
|
||||
*/
|
||||
|
||||
versionProperties = new HashMap<String, Serializable>();
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||
pivot = editionService.createEdition(pivot, versionProperties);
|
||||
editions = orderVersions(editionService.getEditions(mlContainerNodeRef).getAllVersions());
|
||||
Version secondEdition = editions.get(0);
|
||||
// Ensure that the version label is 2.0
|
||||
assertTrue("The edition label would be 2.0 and not " + secondEdition.getVersionLabel(), secondEdition.getVersionLabel().equals("2.0"));
|
||||
|
||||
/*
|
||||
* minor (2.1)
|
||||
*/
|
||||
|
||||
versionProperties = new HashMap<String, Serializable>();
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
pivot = editionService.createEdition(pivot, versionProperties);
|
||||
editions = orderVersions(editionService.getEditions(mlContainerNodeRef).getAllVersions());
|
||||
Version thirdEdition = editions.get(0);
|
||||
// Ensure that the version label is 2.1
|
||||
assertTrue("The edition label would be 2.1 and not " + thirdEdition.getVersionLabel(), thirdEdition.getVersionLabel().equals("2.1"));
|
||||
}
|
||||
|
||||
public void testCreateEdition() throws Exception
|
||||
{
|
||||
// create a mlContainer with some content
|
||||
NodeRef mlContainerNodeRef = createMLContainerWithContent();
|
||||
// get the french translation
|
||||
NodeRef frenchContentNodeRef = multilingualContentService.getTranslationForLocale(mlContainerNodeRef, Locale.FRENCH);
|
||||
|
||||
checkFirstVersion(mlContainerNodeRef);
|
||||
|
||||
// create a new edition form the french translation
|
||||
NodeRef newStartingPoint = editionService.createEdition(frenchContentNodeRef, null);
|
||||
// get the edition history
|
||||
VersionHistory editionHistory = editionService.getEditions(mlContainerNodeRef);
|
||||
|
||||
// Ensure that the edition history contains two versions
|
||||
assertTrue("The edition history must contain two versions", editionHistory.getAllVersions().size() == 2);
|
||||
|
||||
// Ensure that the locale of the container is changer
|
||||
assertTrue("The locale of the conatiner should be changed", nodeService.getProperty(mlContainerNodeRef, ContentModel.PROP_LOCALE).equals(Locale.FRENCH));
|
||||
|
||||
// get the two editions
|
||||
Version rootEdition = editionHistory.getVersion("1.0");
|
||||
Version actualEdition = editionHistory.getVersion("1.1");
|
||||
|
||||
// get the translations of the root versions
|
||||
List<VersionHistory> rootVersionTranslations = editionService.getVersionedTranslations(rootEdition);
|
||||
|
||||
// Ensure that the editions are not null
|
||||
assertNotNull("The root edition can't be null", rootEdition);
|
||||
assertNotNull("The actual edition can't be null", actualEdition);
|
||||
assertNotNull("The translations list of the root edition can't be null", rootVersionTranslations);
|
||||
|
||||
// Ensure that the new starting document noderef is different that the initial one
|
||||
assertFalse("The created starting document must be different that the starting document of the edition", frenchContentNodeRef.equals(newStartingPoint));
|
||||
// Ensure that the new starting document is the pivot of the current translation
|
||||
assertTrue("The new pivot must be equal to the created starting document", newStartingPoint.equals(multilingualContentService.getPivotTranslation(mlContainerNodeRef)));
|
||||
|
||||
int numberOfTranslations;
|
||||
|
||||
// Ensure that the current translations size is 1
|
||||
numberOfTranslations = multilingualContentService.getTranslations(mlContainerNodeRef).size();
|
||||
assertEquals("The number of translations must be 1 and not " + numberOfTranslations, 1, numberOfTranslations);
|
||||
// Ensure that the number of translations of the current edition is 0
|
||||
numberOfTranslations = editionService.getVersionedTranslations(actualEdition).size();
|
||||
assertEquals("The number of translations must be 0 and not " + numberOfTranslations, 0, numberOfTranslations);
|
||||
// Ensure that the number of translations of the root verions is 3
|
||||
numberOfTranslations = rootVersionTranslations.size();
|
||||
assertEquals("The number of translations must be 3 and not " + numberOfTranslations, 3, numberOfTranslations);
|
||||
}
|
||||
|
||||
public void testReadVersionedContent() throws Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void testReadVersionedProperties() throws Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void checkFirstVersion(NodeRef mlContainerNodeRef)
|
||||
{
|
||||
// get the edition list of edition
|
||||
VersionHistory editionHistory = editionService.getEditions(mlContainerNodeRef);
|
||||
|
||||
// Ensure that the first edition of the mlContainer is created
|
||||
assertNotNull("The edition history can't be null", editionHistory);
|
||||
// Ensure that it contains only one version
|
||||
assertTrue("The edition history must contain only one edition", editionHistory.getAllVersions().size() == 1);
|
||||
|
||||
// get the edition
|
||||
Version currentEdition = editionHistory.getAllVersions().iterator().next();
|
||||
|
||||
// Ensure that this version is the edition of the mlContainer
|
||||
assertTrue("The versioned mlContainer noderef of the editon must be the noderef of the created mlContainer", currentEdition.getVersionedNodeRef().equals(mlContainerNodeRef));
|
||||
|
||||
// get the list of translations
|
||||
List<VersionHistory> translations = editionService.getVersionedTranslations(currentEdition);
|
||||
|
||||
// Ensure that the get versioned translations is empty
|
||||
assertNotNull("The translations list of the current edition can't be null", translations);
|
||||
// Ensure that the list is empty
|
||||
assertTrue("The translations list of the current edition would be empty", translations.size() == 0);
|
||||
}
|
||||
|
||||
private NodeRef createMLContainerWithContent()
|
||||
{
|
||||
NodeRef chineseContentNodeRef = createContent(CHINESE_CONTENT + "_1.0");
|
||||
NodeRef frenchContentNodeRef = createContent(FRENCH_CONTENT + "_1.0");
|
||||
NodeRef japaneseContentNodeRef = createContent(JAPANESE_CONTENT + "_1.0");
|
||||
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.addTranslation(frenchContentNodeRef, chineseContentNodeRef, Locale.FRENCH);
|
||||
multilingualContentService.addTranslation(japaneseContentNodeRef, chineseContentNodeRef, Locale.JAPANESE);
|
||||
|
||||
return multilingualContentService.getTranslationContainer(chineseContentNodeRef);
|
||||
}
|
||||
|
||||
private Comparator versionComparator = new Comparator()
|
||||
{
|
||||
public int compare(Object o1, Object o2)
|
||||
{
|
||||
String label01 = ((Version) o1).getVersionLabel();
|
||||
String label02 = ((Version) o2).getVersionLabel();
|
||||
|
||||
// sort the list ascending
|
||||
return label02.compareTo(label01);
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Version> orderVersions(Collection<Version> allVersions)
|
||||
{
|
||||
List<Version> versionsAsList = new ArrayList<Version>(allVersions.size());
|
||||
versionsAsList.addAll(allVersions);
|
||||
Collections.sort(versionsAsList, versionComparator);
|
||||
return versionsAsList;
|
||||
}
|
||||
}
|
@@ -40,7 +40,7 @@ import org.alfresco.service.namespace.QName;
|
||||
*
|
||||
* @see org.alfresco.service.cmr.ml.EmptyTranslationAspect
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class EmptyTranslationAspectTest extends AbstractMultilingualTestCases {
|
||||
|
||||
|
@@ -37,7 +37,7 @@ import org.alfresco.service.namespace.QName;
|
||||
*
|
||||
* @see org.alfresco.service.cmr.ml.MLContainerType
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class MLContainerTypeTest extends AbstractMultilingualTestCases
|
||||
{
|
||||
|
@@ -24,11 +24,8 @@
|
||||
*/
|
||||
package org.alfresco.repo.model.ml.tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
@@ -39,8 +36,6 @@ import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.ml.MultilingualContentServiceImpl
|
||||
@@ -231,58 +226,6 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
assertEquals("Empty translation name not generated correctly.", "Document2.txt", differentName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void testCreateEdition() throws Exception
|
||||
{
|
||||
// Make some content
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
NodeRef frenchContentNodeRef = createContent();
|
||||
NodeRef japaneseContentNodeRef = createContent();
|
||||
// Add to container
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.addTranslation(frenchContentNodeRef, chineseContentNodeRef, Locale.FRENCH);
|
||||
multilingualContentService.addTranslation(japaneseContentNodeRef, chineseContentNodeRef, Locale.JAPANESE);
|
||||
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.getTranslationContainer(chineseContentNodeRef);
|
||||
// Check the container child count
|
||||
assertEquals("Incorrect number of child nodes", 3, nodeService.getChildAssocs(mlContainerNodeRef).size());
|
||||
|
||||
// Version each of the documents
|
||||
List<NodeRef> nodeRefs = new ArrayList<NodeRef>(3);
|
||||
nodeRefs.add(chineseContentNodeRef);
|
||||
nodeRefs.add(frenchContentNodeRef);
|
||||
nodeRefs.add(japaneseContentNodeRef);
|
||||
versionService.createVersion(nodeRefs, null);
|
||||
// Get the current versions of each of the documents
|
||||
Version chineseVersionPreEdition = versionService.getCurrentVersion(chineseContentNodeRef);
|
||||
Version frenchVersionPreEdition = versionService.getCurrentVersion(frenchContentNodeRef);
|
||||
Version japaneseVersionPreEdition = versionService.getCurrentVersion(japaneseContentNodeRef);
|
||||
|
||||
// Create the edition, keeping the Chinese translation as the basis
|
||||
multilingualContentService.createEdition(chineseContentNodeRef);
|
||||
// Check the container child count
|
||||
assertEquals("Incorrect number of child nodes", 1, nodeService.getChildAssocs(mlContainerNodeRef).size());
|
||||
|
||||
// Get the document versions now
|
||||
Version chineseVersionPostEdition = versionService.getCurrentVersion(chineseContentNodeRef);
|
||||
assertFalse("Expected document to be gone", nodeService.exists(frenchContentNodeRef));
|
||||
assertFalse("Expected document to be gone", nodeService.exists(japaneseContentNodeRef));
|
||||
|
||||
// Now be sure that we can get the required information using the version service
|
||||
VersionHistory mlContainerVersionHistory = versionService.getVersionHistory(mlContainerNodeRef);
|
||||
Collection<Version> mlContainerVersions = mlContainerVersionHistory.getAllVersions();
|
||||
// Loop through and get all the children of each version
|
||||
for (Version mlContainerVersion : mlContainerVersions)
|
||||
{
|
||||
NodeRef versionedMLContainerNodeRef = mlContainerVersion.getFrozenStateNodeRef();
|
||||
// Get all the children
|
||||
Map<Locale, NodeRef> translationsByLocale = multilingualContentService.getTranslations(
|
||||
versionedMLContainerNodeRef);
|
||||
// Count the children
|
||||
int count = translationsByLocale.size();
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetTranslationContainerPermissions() throws Exception
|
||||
{
|
||||
// Grant the guest user rights to our working folder
|
||||
@@ -335,7 +278,6 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.addTranslation(frenchContentNodeRef, chineseContentNodeRef, Locale.FRENCH);
|
||||
multilingualContentService.addEmptyTranslation(chineseContentNodeRef, null, Locale.JAPANESE);
|
||||
multilingualContentService.createEdition(chineseContentNodeRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -37,7 +37,7 @@ import org.alfresco.service.namespace.QName;
|
||||
*
|
||||
* @see org.alfresco.service.cmr.ml.MultilingualDocumentAspect
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCases
|
||||
{
|
||||
|
@@ -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;
|
||||
@@ -35,6 +35,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.version.common.VersionUtil;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
@@ -57,22 +58,22 @@ import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
|
||||
/**
|
||||
* The light weight version store node service implementation.
|
||||
*
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class NodeServiceImpl implements NodeService, VersionModel
|
||||
public class NodeServiceImpl implements NodeService, VersionModel
|
||||
{
|
||||
/**
|
||||
* Error messages
|
||||
*/
|
||||
private final static String MSG_UNSUPPORTED =
|
||||
private final static String MSG_UNSUPPORTED =
|
||||
"This operation is not supported by a version store implementation of the node service.";
|
||||
|
||||
|
||||
/**
|
||||
* The name of the spoofed root association
|
||||
*/
|
||||
private static final QName rootAssocName = QName.createQName(VersionModel.NAMESPACE_URI, "versionedState");
|
||||
|
||||
|
||||
/**
|
||||
* The db node service, used as the version store implementation
|
||||
*/
|
||||
@@ -83,16 +84,16 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private SearchService searcher;
|
||||
|
||||
|
||||
/**
|
||||
* The dictionary service
|
||||
*/
|
||||
protected DictionaryService dicitionaryService;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets the db node service, used as the version store implementation
|
||||
*
|
||||
*
|
||||
* @param nodeService the node service
|
||||
*/
|
||||
public void setDbNodeService(NodeService nodeService)
|
||||
@@ -102,24 +103,24 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
|
||||
/**
|
||||
* Sets the searcher
|
||||
*
|
||||
*
|
||||
* @param searcher the searcher
|
||||
*/
|
||||
public void setSearcher(SearchService searcher)
|
||||
{
|
||||
this.searcher = searcher;
|
||||
this.searcher = searcher;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the dictionary service
|
||||
*
|
||||
*
|
||||
* @param dictionaryService the dictionary service
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dicitionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delegates to the <code>NodeService</code> used as the version store implementation
|
||||
*/
|
||||
@@ -127,7 +128,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
{
|
||||
return dbNodeService.getStores();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delegates to the <code>NodeService</code> used as the version store implementation
|
||||
*/
|
||||
@@ -149,9 +150,9 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
*/
|
||||
public boolean exists(NodeRef nodeRef)
|
||||
{
|
||||
return dbNodeService.exists(convertNodeRef(nodeRef));
|
||||
return dbNodeService.exists(VersionUtil.convertNodeRef(nodeRef));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delegates to the <code>NodeService</code> used as the version store implementation
|
||||
*/
|
||||
@@ -160,18 +161,6 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
return dbNodeService.getNodeStatus(nodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private NodeRef convertNodeRef(NodeRef nodeRef)
|
||||
{
|
||||
return new NodeRef(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, STORE_ID), nodeRef.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the <code>NodeService</code> used as the version store implementation
|
||||
*/
|
||||
@@ -184,7 +173,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
public ChildAssociationRef createNode(
|
||||
NodeRef parentRef,
|
||||
NodeRef parentRef,
|
||||
QName assocTypeQName,
|
||||
QName assocQName,
|
||||
QName nodeTypeQName) throws InvalidNodeRefException
|
||||
@@ -192,12 +181,12 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
public ChildAssociationRef createNode(
|
||||
NodeRef parentRef,
|
||||
NodeRef parentRef,
|
||||
QName assocTypeQName,
|
||||
QName assocQName,
|
||||
QName nodeTypeQName,
|
||||
@@ -206,7 +195,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -215,7 +204,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -227,7 +216,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -274,9 +263,9 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
*/
|
||||
public QName getType(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
return (QName)this.dbNodeService.getProperty(convertNodeRef(nodeRef), PROP_QNAME_FROZEN_NODE_TYPE);
|
||||
return (QName)this.dbNodeService.getProperty(VersionUtil.convertNodeRef(nodeRef), PROP_QNAME_FROZEN_NODE_TYPE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.NodeService#setType(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
@@ -285,7 +274,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -318,7 +307,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
public Set<QName> getAspects(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
return new HashSet<QName>(
|
||||
(ArrayList<QName>)this.dbNodeService.getProperty(convertNodeRef(nodeRef), PROP_QNAME_FROZEN_ASPECTS));
|
||||
(ArrayList<QName>)this.dbNodeService.getProperty(VersionUtil.convertNodeRef(nodeRef), PROP_QNAME_FROZEN_ASPECTS));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,9 +315,9 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
*/
|
||||
public Map<QName, Serializable> getProperties(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
Map<QName, Serializable> result = new HashMap<QName, Serializable>();
|
||||
|
||||
Collection<ChildAssociationRef> children = this.dbNodeService.getChildAssocs(convertNodeRef(nodeRef), CHILD_QNAME_VERSIONED_ATTRIBUTES, RegexQNamePattern.MATCH_ALL);
|
||||
Map<QName, Serializable> result = new HashMap<QName, Serializable>();
|
||||
|
||||
Collection<ChildAssociationRef> children = this.dbNodeService.getChildAssocs(VersionUtil.convertNodeRef(nodeRef), CHILD_QNAME_VERSIONED_ATTRIBUTES, RegexQNamePattern.MATCH_ALL);
|
||||
for (ChildAssociationRef child : children)
|
||||
{
|
||||
NodeRef versionedAttribute = child.getChildRef();
|
||||
@@ -337,35 +326,35 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
Serializable value = null;
|
||||
QName qName = (QName)this.dbNodeService.getProperty(versionedAttribute, PROP_QNAME_QNAME);
|
||||
PropertyDefinition propDef = this.dicitionaryService.getProperty(qName);
|
||||
|
||||
|
||||
Boolean isMultiValue = (Boolean)this.dbNodeService.getProperty(versionedAttribute, PROP_QNAME_IS_MULTI_VALUE);
|
||||
if (isMultiValue.booleanValue() == false)
|
||||
{
|
||||
value = this.dbNodeService.getProperty(versionedAttribute, PROP_QNAME_VALUE);
|
||||
value = (Serializable)DefaultTypeConverter.INSTANCE.convert(propDef.getDataType(), value);
|
||||
value = this.dbNodeService.getProperty(versionedAttribute, PROP_QNAME_VALUE);
|
||||
value = (Serializable)DefaultTypeConverter.INSTANCE.convert(propDef.getDataType(), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = this.dbNodeService.getProperty(versionedAttribute, PROP_QNAME_MULTI_VALUE);
|
||||
}
|
||||
|
||||
|
||||
result.put(qName, value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Property translation for version store
|
||||
*/
|
||||
public Serializable getProperty(NodeRef nodeRef, QName qname) throws InvalidNodeRefException
|
||||
{
|
||||
{
|
||||
// TODO should be doing this with a search ...
|
||||
|
||||
Map<QName, Serializable> properties = getProperties(convertNodeRef(nodeRef));
|
||||
return properties.get(qname);
|
||||
|
||||
Map<QName, Serializable> properties = getProperties(VersionUtil.convertNodeRef(nodeRef));
|
||||
return properties.get(qname);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -374,7 +363,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -383,7 +372,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -395,17 +384,17 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
|
||||
/**
|
||||
* The node will appear to be attached to the root of the version store
|
||||
*
|
||||
*
|
||||
* @see NodeService#getParentAssocs(NodeRef)
|
||||
*/
|
||||
public List<ChildAssociationRef> getParentAssocs(NodeRef nodeRef)
|
||||
{
|
||||
return getParentAssocs(nodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The node will apprear to be attached to the root of the version store
|
||||
*
|
||||
*
|
||||
* @see NodeService#getParentAssocs(NodeRef, QNamePattern, QNamePattern)
|
||||
*/
|
||||
public List<ChildAssociationRef> getParentAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern)
|
||||
@@ -428,7 +417,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
*/
|
||||
public List<ChildAssociationRef> getChildAssocs(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
return getChildAssocs(convertNodeRef(nodeRef), RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL);
|
||||
return getChildAssocs(VersionUtil.convertNodeRef(nodeRef), RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,46 +427,46 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
{
|
||||
// Get the child assocs from the version store
|
||||
List<ChildAssociationRef> childAssocRefs = this.dbNodeService.getChildAssocs(
|
||||
convertNodeRef(nodeRef),
|
||||
VersionUtil.convertNodeRef(nodeRef),
|
||||
RegexQNamePattern.MATCH_ALL, CHILD_QNAME_VERSIONED_CHILD_ASSOCS);
|
||||
List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>(childAssocRefs.size());
|
||||
for (ChildAssociationRef childAssocRef : childAssocRefs)
|
||||
{
|
||||
// Get the child reference
|
||||
NodeRef childRef = childAssocRef.getChildRef();
|
||||
NodeRef referencedNode = (NodeRef)this.dbNodeService.getProperty(childRef, ContentModel.PROP_REFERENCE);
|
||||
|
||||
NodeRef referencedNode = (NodeRef)this.dbNodeService.getProperty(childRef, ContentModel.PROP_REFERENCE);
|
||||
|
||||
if (this.dbNodeService.exists(referencedNode) == true)
|
||||
{
|
||||
// get the qualified name of the frozen child association and filter out unwanted names
|
||||
QName qName = (QName)this.dbNodeService.getProperty(childRef, PROP_QNAME_ASSOC_QNAME);
|
||||
|
||||
|
||||
if (qnamePattern.isMatch(qName) == true)
|
||||
{
|
||||
{
|
||||
// Retrieve the isPrimary and nthSibling values of the forzen child association
|
||||
QName assocType = (QName)this.dbNodeService.getProperty(childRef, PROP_QNAME_ASSOC_TYPE_QNAME);
|
||||
boolean isPrimary = ((Boolean)this.dbNodeService.getProperty(childRef, PROP_QNAME_IS_PRIMARY)).booleanValue();
|
||||
int nthSibling = ((Integer)this.dbNodeService.getProperty(childRef, PROP_QNAME_NTH_SIBLING)).intValue();
|
||||
|
||||
|
||||
// Build a child assoc ref to add to the returned list
|
||||
ChildAssociationRef newChildAssocRef = new ChildAssociationRef(
|
||||
assocType,
|
||||
nodeRef,
|
||||
qName,
|
||||
referencedNode,
|
||||
isPrimary,
|
||||
nodeRef,
|
||||
qName,
|
||||
referencedNode,
|
||||
isPrimary,
|
||||
nthSibling);
|
||||
result.add(newChildAssocRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sort the results so that the order appears to be exactly as it was originally
|
||||
Collections.sort(result);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -488,7 +477,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the node begin attached ot the root node of the version store.
|
||||
* Simulates the node begin attached ot the root node of the version store.
|
||||
*/
|
||||
public ChildAssociationRef getPrimaryParent(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
@@ -498,7 +487,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
rootAssocName,
|
||||
nodeRef);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -508,7 +497,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -517,7 +506,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -525,31 +514,31 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
{
|
||||
// Get the child assocs from the version store
|
||||
List<ChildAssociationRef> childAssocRefs = this.dbNodeService.getChildAssocs(
|
||||
convertNodeRef(sourceRef),
|
||||
VersionUtil.convertNodeRef(sourceRef),
|
||||
RegexQNamePattern.MATCH_ALL, CHILD_QNAME_VERSIONED_ASSOCS);
|
||||
List<AssociationRef> result = new ArrayList<AssociationRef>(childAssocRefs.size());
|
||||
for (ChildAssociationRef childAssocRef : childAssocRefs)
|
||||
{
|
||||
// Get the assoc reference
|
||||
NodeRef childRef = childAssocRef.getChildRef();
|
||||
NodeRef referencedNode = (NodeRef)this.dbNodeService.getProperty(childRef, ContentModel.PROP_REFERENCE);
|
||||
|
||||
NodeRef referencedNode = (NodeRef)this.dbNodeService.getProperty(childRef, ContentModel.PROP_REFERENCE);
|
||||
|
||||
if (this.dbNodeService.exists(referencedNode) == true)
|
||||
{
|
||||
// get the qualified type name of the frozen child association and filter out unwanted names
|
||||
QName qName = (QName)this.dbNodeService.getProperty(childRef, PROP_QNAME_ASSOC_TYPE_QNAME);
|
||||
|
||||
|
||||
if (qnamePattern.isMatch(qName) == true)
|
||||
{
|
||||
{
|
||||
AssociationRef newAssocRef = new AssociationRef(sourceRef, qName, referencedNode);
|
||||
result.add(newAssocRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -558,7 +547,7 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
// This operation is not supported for a version store
|
||||
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@@ -567,9 +556,9 @@ public class NodeServiceImpl implements NodeService, VersionModel
|
||||
ChildAssociationRef childAssocRef = getPrimaryParent(nodeRef);
|
||||
Path path = new Path();
|
||||
path.append(new Path.ChildAssocElement(childAssocRef));
|
||||
return path;
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ import org.alfresco.service.PublicService;
|
||||
/**
|
||||
* This service interface provides support for content filter languages .
|
||||
*
|
||||
* @author yanipig
|
||||
* @author Yannick Pignot
|
||||
*
|
||||
*/
|
||||
@PublicService
|
||||
|
95
source/java/org/alfresco/service/cmr/ml/EditionService.java
Normal file
95
source/java/org/alfresco/service/cmr/ml/EditionService.java
Normal file
@@ -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 <b>mlContainer</b>
|
||||
*
|
||||
* @since 2.1
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
@PublicService
|
||||
public interface EditionService
|
||||
{
|
||||
/**
|
||||
* Create a new edition of an existing <b>cm:mlContainer</b> using any one of the
|
||||
* associated <b>cm:mlDocument</b> transalations.
|
||||
*
|
||||
* If startingTranslationNodeRef is multilingual, it will be copied. The copy will become the pivot translation
|
||||
* of the new Edition of the <b>cm:mlContainer</b>. The reference of the copy will be returned.
|
||||
*
|
||||
* @param translationNodeRef The specific <b>cm:mlDocument</b> 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<String, Serializable> versionProperties);
|
||||
|
||||
/**
|
||||
* Get editions of an existing <b>cm:mlContainer</b>.
|
||||
*
|
||||
* @param mlContainer An existing <b>cm:mlContainer</b>
|
||||
* @return The Version History of the mlContainer
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"mlContainer"})
|
||||
VersionHistory getEditions(NodeRef mlContainer);
|
||||
|
||||
/**
|
||||
* Get the different <b>cm:mlDocument</b> transalation version histories of a specific edition of a <b>cm:mlContainer</b>
|
||||
*
|
||||
* @param mlContainerEdition An existing version of a mlContainer
|
||||
* @return The list of <b>cm:mlDocument</b> transalation versions of the edition
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"mlContainerEdition"})
|
||||
List<VersionHistory> getVersionedTranslations(Version mlContainerEdition);
|
||||
|
||||
/**
|
||||
* Get the the versioned metadata of a specific <b>cm:mlDocument</b> transalation version or a specific
|
||||
* <b>cm:mlContainer</b> version
|
||||
*
|
||||
* @see org.alfresco.repo.model.ml.MultilingualDocumentAspect.PROPERTIES_TO_VERSION the versioned metadata
|
||||
* of a <b>cm:mlDocument</b> 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 <b>cm:mlContainer</b> added to the usual metadata versioned for a normal node.
|
||||
*
|
||||
* @param version An existing version of a <b>cm:mlDocument</b> translation version or
|
||||
* an existing version of a <b>cm:mlContainer</b> version.
|
||||
* @return The versioned metadata
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"version"})
|
||||
Map<QName, Serializable> getVersionedMetadatas(Version version);
|
||||
|
||||
}
|
@@ -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 <b>cm:content</b>
|
||||
* @return Returns <tt>true</tt> if the document has a <b>cm:mlContainer</b> parent
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"contentNodeRef"})
|
||||
boolean isTranslation(NodeRef contentNodeRef);
|
||||
|
||||
|
||||
/**
|
||||
* Make an existing document into a translation by adding the <b>cm:mlDocument</b> aspect and
|
||||
* creating a <b>cm:mlContainer</b> parent. If it is already a translation, then nothing is done.
|
||||
*
|
||||
* @param contentNodeRef An existing <b>cm:content</b>
|
||||
*
|
||||
*
|
||||
* @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 <b>cm:mlDocument</b>
|
||||
*/
|
||||
@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 <b>cm:mlContainer</b> using any one of the
|
||||
* associated <b>cm:mlDocument</b> transalations.
|
||||
*
|
||||
* @param translationNodeRef The specific <b>cm:mlDocument</b> 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 <b>cm:mlDocument</b> or
|
||||
* <b>cm:mlContainer</b>.
|
||||
*
|
||||
*
|
||||
* @param translationOfNodeRef An existing <b>cm:mlDocument</b> or <b>cm:mlContainer</b>
|
||||
* @return Returns a map of translation nodes keyed by locale
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationOfNodeRef"})
|
||||
Map<Locale, NodeRef> getTranslations(NodeRef translationOfNodeRef);
|
||||
|
||||
|
||||
/**
|
||||
* Given a <b>cm:mlDocument</b>, 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 <b>cm:mlDocument</b>
|
||||
* @param locale the target locale
|
||||
* @return Returns the best match for the locale (never <tt>null</tt>)
|
||||
*
|
||||
*
|
||||
* @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 <b>cm:mlDocument</b> or <b>cm:mlContainer</b> this node returns each locale for
|
||||
* which there isn't a translation.
|
||||
*
|
||||
* which there isn't a translation.
|
||||
*
|
||||
* @param localizedNodeRef the <b>cm:mlDocument</b> or <b>cm:mlContainer</b>
|
||||
* @param addThisNodeLocale if true, add the locale of the given <b>cm:mlDocument</b> in the list.
|
||||
* @param addThisNodeLocale if true, add the locale of the given <b>cm:mlDocument</b> in the list.
|
||||
* @return Returns a list of missng locales
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"localizedNodeRef", "addThisNodeLocale"})
|
||||
List<Locale> 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 <b>cm:mlContainer</b>. 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 <b>cm:mlDocument</b> translation or <b>cm:mlContainer</b> translation
|
||||
* container
|
||||
* @return Returns a corresponding <b>cm:mlDocument</b> 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
|
||||
* </pre>
|
||||
* <p/>
|
||||
* The necessary translation structures will be created as necessary.
|
||||
*
|
||||
*
|
||||
* @param translationOfNodeRef An existing <b>cm:mlDocument</b>
|
||||
* @param name The name of the file to create, or <tt>null</tt> to use
|
||||
* the default naming convention.
|
||||
* @return Returns the new created <b>cm:mlEmptyTranslation</b>
|
||||
* @return Returns the new created <b>cm:mlEmptyTranslation</b>
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationOfNodeRef", "name", "locale"})
|
||||
NodeRef addEmptyTranslation(NodeRef translationOfNodeRef, String name, Locale locale);
|
||||
|
||||
/**
|
||||
* Copies the given <b>cm:mlContainer</b>.
|
||||
* <p>
|
||||
* This involves the copy of the <b>cm:mlContainer</b> node and the copy of its <b>cm:mlDocument</b>.
|
||||
* <p>
|
||||
*
|
||||
* @param translationNodeRef The <b>cm:mlContainer</b> to copy
|
||||
* @param newParentRef The new parent of the copied <b>cm:mlDocument</b>
|
||||
* @return The copied <b>cm:mlContainer</b>
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef", "newParentRef"})
|
||||
NodeRef copyTranslationContainer(NodeRef translationNodeRef, NodeRef newParentRef);
|
||||
|
||||
/**
|
||||
* Moves the location of the given <b>cm:mlContainer</b>.
|
||||
* <p>
|
||||
* This not involves changing the <b>cm:mlContainer</b> node but moves its <b>cm:mlDocument</b>.
|
||||
* <p>
|
||||
*
|
||||
* @param translationNodeRef The <b>cm:mlContainer</b> to move
|
||||
* @param newParentRef The new parent of the moved <b>cm:mlDocument</b>
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef", "newParentRef"})
|
||||
void moveTranslationContainer(NodeRef translationNodeRef, NodeRef newParentRef);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user