mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merging from EC-MC: Checkpoint before refactor
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5744 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -50,8 +50,8 @@ import org.alfresco.service.namespace.QName;
|
||||
*/
|
||||
public class EmptyTranslationAspect implements
|
||||
CopyServicePolicies.OnCopyNodePolicy,
|
||||
NodeServicePolicies.BeforeDeleteNodePolicy,
|
||||
NodeServicePolicies.OnRemoveAspectPolicy,
|
||||
// NodeServicePolicies.BeforeDeleteNodePolicy,
|
||||
// NodeServicePolicies.OnRemoveAspectPolicy,
|
||||
ContentServicePolicies.OnContentUpdatePolicy
|
||||
{
|
||||
|
||||
@@ -77,16 +77,16 @@ public class EmptyTranslationAspect implements
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onContentUpdate"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION,
|
||||
new JavaBehaviour(this, "onContentUpdate"));
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION,
|
||||
new JavaBehaviour(this, "beforeDeleteNode"));
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"),
|
||||
ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION,
|
||||
new JavaBehaviour(this, "onRemoveAspect"));
|
||||
//
|
||||
// this.policyComponent.bindClassBehaviour(
|
||||
// QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||
// ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION,
|
||||
// new JavaBehaviour(this, "beforeDeleteNode"));
|
||||
//
|
||||
// this.policyComponent.bindClassBehaviour(
|
||||
// QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"),
|
||||
// ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION,
|
||||
// new JavaBehaviour(this, "onRemoveAspect"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +105,7 @@ public class EmptyTranslationAspect implements
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a <b>cm:mlEmptyTranslation<b> is not permit.
|
||||
*
|
||||
@@ -123,38 +123,38 @@ public class EmptyTranslationAspect implements
|
||||
*/
|
||||
public void onContentUpdate(NodeRef nodeRef, boolean newContent)
|
||||
{
|
||||
if(newContent)
|
||||
if (newContent)
|
||||
{
|
||||
nodeService.removeAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION);
|
||||
nodeService.removeAspect(nodeRef, ContentModel.ASPECT_TEMPORARY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a <b>cm:mlEmptyTranslation<b> is deleted, it can't be archived.
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public void beforeDeleteNode(NodeRef nodeRef)
|
||||
{
|
||||
// add TEMPORARY ASPECT to force the deleteNode
|
||||
nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the aspect <b>cm:mlEmptyTranslation<b> is removed <b>and the content url property is null</b>, the node can't be store much time.
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnRemoveAspectPolicy#onRemoveAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) *
|
||||
*/
|
||||
public void onRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||
{
|
||||
// if the node is updated, the URL will not be null and the rome aspect don't delete
|
||||
// the translation. It will be a simple mlDocument.
|
||||
if(aspectTypeQName.equals(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION)
|
||||
&& ((ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT)).getContentUrl() == null)
|
||||
{
|
||||
// add TEMPORARY ASPECT to force the deleteNode
|
||||
nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null);
|
||||
nodeService.deleteNode(nodeRef);
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * If a <b>cm:mlEmptyTranslation<b> is deleted, it can't be archived.
|
||||
// *
|
||||
// * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
|
||||
// */
|
||||
// public void beforeDeleteNode(NodeRef nodeRef)
|
||||
// {
|
||||
// // add TEMPORARY ASPECT to force the deleteNode
|
||||
// nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * If the aspect <b>cm:mlEmptyTranslation<b> is removed <b>and the content url property is null</b>, the node can be deleted.
|
||||
// * The other time the aspect is removed is when new content is added, in which case the node must be kept.
|
||||
// *
|
||||
// * @see org.alfresco.repo.node.NodeServicePolicies.OnRemoveAspectPolicy#onRemoveAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) *
|
||||
// */
|
||||
// public void onRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||
// {
|
||||
// // Delete the node if the content is empty.
|
||||
// // Keep the node if it has content
|
||||
// ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||
// if(contentData.getContentUrl() == null)
|
||||
// {
|
||||
// nodeService.deleteNode(nodeRef);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@@ -118,7 +118,7 @@ public class MLContainerType implements
|
||||
Map<Locale, NodeRef> translations = multilingualContentService.getTranslations(nodeRef);
|
||||
|
||||
// add the DELETION_RUNNING property
|
||||
nodeService.setProperty(nodeRef, PROP_NAME_DELETION_RUNNING, new Boolean(true));
|
||||
nodeService.setProperty(nodeRef, PROP_NAME_DELETION_RUNNING, Boolean.TRUE);
|
||||
|
||||
for(Map.Entry<Locale, NodeRef> entry : translations.entrySet())
|
||||
{
|
||||
@@ -126,10 +126,7 @@ public class MLContainerType implements
|
||||
}
|
||||
|
||||
// remove the DELETION_RUNNING property
|
||||
Map<QName, Serializable> prop = nodeService.getProperties(nodeRef);
|
||||
prop.remove(PROP_NAME_DELETION_RUNNING);
|
||||
nodeService.setProperties(nodeRef, prop);
|
||||
|
||||
nodeService.removeProperty(nodeRef, PROP_NAME_DELETION_RUNNING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -245,6 +245,42 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
return mlContainerNodeRef;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public boolean isTranslation(NodeRef contentNodeRef)
|
||||
{
|
||||
if (!nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
{
|
||||
// It doesn't have the aspect, so it isn't a translation
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Document is not multilingual: " + contentNodeRef);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Is there a ML container
|
||||
List<ChildAssociationRef> parentAssocRefs = nodeService.getParentAssocs(
|
||||
contentNodeRef,
|
||||
ContentModel.ASSOC_MULTILINGUAL_CHILD,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
if (parentAssocRefs.size() > 0)
|
||||
{
|
||||
// It has the parent required
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Document has ML container parent: " + contentNodeRef);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Document has no ML container parent: " + contentNodeRef);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public NodeRef makeTranslation(NodeRef contentNodeRef, Locale locale)
|
||||
{
|
||||
@@ -505,7 +541,11 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc */
|
||||
* @inheritDoc
|
||||
*
|
||||
* TODO: This logic merely creates a file with a specific aspect and is designed to support
|
||||
* specific use-case in the UI. Examine if the logic should be here or in the UI.
|
||||
*/
|
||||
public NodeRef addEmptyTranslation(NodeRef translationOfNodeRef, String name, Locale locale)
|
||||
{
|
||||
// any node used as reference
|
||||
@@ -542,8 +582,11 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
|
||||
// set it empty
|
||||
nodeService.addAspect(newTranslationNodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION, null);
|
||||
// Initially, the file should be temporary. This will be changed as soon as some content is added.
|
||||
nodeService.addAspect(newTranslationNodeRef, ContentModel.ASPECT_TEMPORARY, null);
|
||||
|
||||
// get the extension and set the ContentData property with an null URL.
|
||||
// TODO: Mimetype must be correct, i.e. taken from the original
|
||||
String extension = "";
|
||||
int dotIdx;
|
||||
if((dotIdx = name.lastIndexOf(".")) > -1 )
|
||||
|
@@ -141,12 +141,18 @@ public class MultilingualContentServiceImplTest extends TestCase
|
||||
public void testMakeTranslation() throws Exception
|
||||
{
|
||||
NodeRef contentNodeRef = createContent();
|
||||
// Check that it is not a translation
|
||||
boolean isTranslation = multilingualContentService.isTranslation(contentNodeRef);
|
||||
assertFalse("New content should not be a translation", isTranslation);
|
||||
// Turn the content into a translation with the appropriate structures
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(contentNodeRef, Locale.CHINESE);
|
||||
// Check it
|
||||
assertNotNull("Container not created", mlContainerNodeRef);
|
||||
// Check the container child count
|
||||
assertEquals("Incorrect number of child nodes", 1, nodeService.getChildAssocs(mlContainerNodeRef).size());
|
||||
// Check that it registers as a translation
|
||||
isTranslation = multilingualContentService.isTranslation(contentNodeRef);
|
||||
assertTrue("Content should be a translation", isTranslation);
|
||||
}
|
||||
|
||||
public void testAddTranslationUsingContainer() throws Exception
|
||||
|
@@ -149,21 +149,16 @@ public class MultilingualDocumentAspect implements
|
||||
*/
|
||||
public void onCopyComplete(QName classRef, NodeRef sourceNodeRef, NodeRef destinationRef, boolean copyToNewNode, Map<NodeRef, NodeRef> copyMap)
|
||||
{
|
||||
Map<QName, Serializable> copiedProp = nodeService.getProperties(destinationRef);
|
||||
copiedProp.remove(ContentModel.PROP_LOCALE);
|
||||
nodeService.setProperties(destinationRef, copiedProp);
|
||||
nodeService.removeProperty(destinationRef, ContentModel.PROP_LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* A <b>cm:mlDocument</b> is pivot translation it is a multilingual document (non empty) if it's language matches the language
|
||||
* of its <b>cm:mlDocument</b>. And a pivot translation can't be removed if it's not the last translation of the <b>cm:mlContainer</b>.
|
||||
*
|
||||
* If a translation is deleted, it's multilingual aspect is lost.
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* If the node is multilingual and it is the pivot translation, then deletion is not allowed unless the
|
||||
*/
|
||||
public void beforeDeleteNode(NodeRef nodeRef)
|
||||
{
|
||||
// checkRemoveParentMLContainer(nodeRef);
|
||||
// Remove the aspect
|
||||
nodeService.removeAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
}
|
||||
|
||||
@@ -178,60 +173,52 @@ public class MultilingualDocumentAspect implements
|
||||
*/
|
||||
public void beforeRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||
{
|
||||
if(aspectTypeQName.equals(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
checkRemoveParentMLContainer(nodeRef);
|
||||
}
|
||||
|
||||
private void checkRemoveParentMLContainer(NodeRef nodeRef)
|
||||
{
|
||||
// Avoid nodes that are no longer translations
|
||||
if (!multilingualContentService.isTranslation(nodeRef))
|
||||
{
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(nodeRef);
|
||||
|
||||
// nothing to do if the mlContainer is in a deletion process
|
||||
Boolean inDeleteProcess = (Boolean) nodeService.getProperty(mlContainer, MLContainerType.PROP_NAME_DELETION_RUNNING);
|
||||
if(inDeleteProcess != null && inDeleteProcess == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Locale mlContainerLocale = (Locale) nodeService.getProperty(mlContainer, ContentModel.PROP_LOCALE);
|
||||
Locale nodeRefLocale = (Locale) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCALE);
|
||||
|
||||
nodeService.removeChild(mlContainer, nodeRef);
|
||||
|
||||
// if last translation or if nodeRef is pivot translation
|
||||
if(multilingualContentService.getTranslations(mlContainer).size() == 0
|
||||
|| mlContainerLocale.equals(nodeRefLocale))
|
||||
{
|
||||
// delete the mlContainer
|
||||
nodeService.deleteNode(mlContainer);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(nodeRef);
|
||||
|
||||
// nothing to do if the mlContainer is in a deletion process
|
||||
Boolean inDeleteProcess = (Boolean) nodeService.getProperty(mlContainer, MLContainerType.PROP_NAME_DELETION_RUNNING);
|
||||
if(inDeleteProcess != null && inDeleteProcess == true)
|
||||
{
|
||||
// TODO: Is this still called? Can we get rid of the DELETION_RUNNING property?
|
||||
return;
|
||||
}
|
||||
|
||||
Locale mlContainerLocale = (Locale) nodeService.getProperty(mlContainer, ContentModel.PROP_LOCALE);
|
||||
Locale nodeRefLocale = (Locale) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCALE);
|
||||
|
||||
nodeService.removeChild(mlContainer, nodeRef);
|
||||
|
||||
// if last translation or if nodeRef is pivot translation
|
||||
if (multilingualContentService.getTranslations(mlContainer).size() == 0
|
||||
|| mlContainerLocale.equals(nodeRefLocale))
|
||||
{
|
||||
// delete the mlContainer
|
||||
nodeService.deleteNode(mlContainer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* After removing the <b>cm:mlDocument</b> aspect :
|
||||
* - the node is removed is it's a <b>cm:mlEmptyTranslation</b>
|
||||
* - if not, only the locale property is removed
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnRemoveAspectPolicy#onRemoveAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
|
||||
* Removes the document's locale and the <b>cm:mlEmptyTranslation</b> aspect,
|
||||
* if present.
|
||||
*/
|
||||
public void onRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||
{
|
||||
if(aspectTypeQName.equals(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
nodeService.removeProperty(nodeRef, ContentModel.PROP_LOCALE);
|
||||
// Remove the empty translation aspect if it is present
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
|
||||
if(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
// note: if the node has the temporary aspect and the mlEmptyTranslation in a same
|
||||
// time, it means that the node is being deleted by another process...
|
||||
if(!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPORARY))
|
||||
{
|
||||
nodeService.deleteNode(nodeRef);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
|
||||
props.remove(ContentModel.PROP_LOCALE);
|
||||
nodeService.setProperties(nodeRef, props);
|
||||
|
||||
}
|
||||
nodeService.removeAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -119,8 +119,6 @@ public class EmptyTranslationAspectTest extends AbstractMultilingualTestCases {
|
||||
|
||||
fileFolderService.getWriter(pivot).putContent(contentString);
|
||||
|
||||
// Ensure that the URL property of the empty translation content is null
|
||||
assertNull("The URL property of an empty translation must be null", ((ContentData) nodeService.getProperty(empty, ContentModel.PROP_CONTENT)).getContentUrl());
|
||||
// Ensure that the content retourned by a get reader of the empty document is the same as the pivot
|
||||
assertEquals("The content retourned of the empty translation must be the same that the content of the pivot",
|
||||
fileFolderService.getReader(pivot).getContentString(),
|
||||
|
@@ -82,15 +82,13 @@ public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCase
|
||||
NodeRef restoredNode = nodeArchiveService.restoreArchivedNode(nodeArchiveService.getArchivedNode(trad3)).getRestoredNodeRef();
|
||||
|
||||
// Ensure that the restored node is restored to it s original space
|
||||
assertEquals("The restaured node must be restaured to the the space", 3, nodeService.getChildAssocs(parent).size());
|
||||
assertEquals("The restored node must be restaured to the the space", 3, nodeService.getChildAssocs(parent).size());
|
||||
// Ensure that the restored node is not linked to the mlContainer
|
||||
assertEquals("The restaured node would not be restaured to the mlContainer", 2, multilingualContentService.getTranslations(mlContainer).size());
|
||||
assertEquals("The restored node would not be restaured to the mlContainer", 2, multilingualContentService.getTranslations(mlContainer).size());
|
||||
// Ensure that the restored node doesn't keep the mlDocument aspect
|
||||
assertFalse("The restaured node can't keep the multilingual aspect", nodeService.hasAspect(restoredNode, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT));
|
||||
assertFalse("The restored node can't keep the multilingual aspect", nodeService.hasAspect(restoredNode, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT));
|
||||
// Ensure that the restored node doesn't keep the locale property
|
||||
assertNull("The restaured node can't keep the locale property", nodeService.getProperty(restoredNode, ContentModel.PROP_LOCALE));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void testDeletePivot() throws Exception
|
||||
|
Reference in New Issue
Block a user