diff --git a/source/java/org/alfresco/repo/rendition/PerformRenditionActionExecuter.java b/source/java/org/alfresco/repo/rendition/PerformRenditionActionExecuter.java index 71714bb9be..f4d47679b6 100644 --- a/source/java/org/alfresco/repo/rendition/PerformRenditionActionExecuter.java +++ b/source/java/org/alfresco/repo/rendition/PerformRenditionActionExecuter.java @@ -298,8 +298,9 @@ public class PerformRenditionActionExecuter extends ActionExecuterAbstractBase " renditionDefinition.name: ").append(renditionQName); log.debug(msg.toString()); } - ChildAssociationRef primaryAssoc = findOrCreatePrimaryRenditionAssociation(sourceNode, renditionDefinition, - location); + NodeRef oldRendition=getOldRenditionIfExists(sourceNode, renditionDefinition); + RenditionNodeManager renditionNodeManager = new RenditionNodeManager(sourceNode, oldRendition, location, renditionDefinition, nodeService); + ChildAssociationRef primaryAssoc = renditionNodeManager.findOrCreateRenditionNode(); // Copy relevant properties from the temporary node to the new rendition // node. @@ -326,6 +327,16 @@ public class PerformRenditionActionExecuter extends ActionExecuterAbstractBase return renditionAssoc; } + private NodeRef getOldRenditionIfExists(NodeRef sourceNode, RenditionDefinition renditionDefinition) + { + QName renditionName=renditionDefinition.getRenditionName(); + ChildAssociationRef renditionAssoc = renditionService.getRenditionByName(sourceNode, renditionName); + if(renditionAssoc ==null) + return null; + else + return renditionAssoc.getChildRef(); + } + private void manageRenditionAspects(NodeRef sourceNode, ChildAssociationRef renditionParentAssoc) { NodeRef renditionNode = renditionParentAssoc.getChildRef(); @@ -368,121 +379,6 @@ public class PerformRenditionActionExecuter extends ActionExecuterAbstractBase return renditionDefinition.getRenditionName().getLocalName(); } - private ChildAssociationRef findOrCreatePrimaryRenditionAssociation(NodeRef sourceNode, - RenditionDefinition renditionDefinition, RenditionLocation location) - { - // Get old Rendition if exists. - QName renditionName = renditionDefinition.getRenditionName(); - ChildAssociationRef oldRenditionAssoc = renditionService.getRenditionByName(sourceNode, renditionName); - // If no rendition already exists create anew rendition node and - // association. - if (oldRenditionAssoc == null) - { - return getSpecifiedRenditionOrCreateNewRendition(sourceNode, location, renditionName); - } - // If a rendition exists and is already in the correct location then - // return that renditions primary parent association - NodeRef oldRendition = oldRenditionAssoc.getChildRef(); - if (renditionLocationMatches(oldRendition, location)) - { - return nodeService.getPrimaryParent(oldRendition); - } - // If the old rendition is in the wrong location and the 'orphan - // existing rendition' param is set to true or the RenditionLocation - // specifies a destination NodeRef then ldelete the old - // rendition association and create a new rendition node. - if (orphanExistingRendition(renditionDefinition, location)) - { - orphanRendition(oldRenditionAssoc); - return getSpecifiedRenditionOrCreateNewRendition(sourceNode, location, renditionName); - } - // If the old rendition is in the wrong place and the 'orphan existing - // rendition' param is not set to true then move the existing rendition - // to the correct location. - return moveRendition(oldRendition, location, renditionName); - } - - private ChildAssociationRef moveRendition(NodeRef renditionNode, RenditionLocation location, QName associationName) - { - ChildAssociationRef assoc = nodeService.moveNode(renditionNode, location.getParentRef(), - ContentModel.ASSOC_CONTAINS, associationName); - return assoc; - } - - private void orphanRendition(ChildAssociationRef oldRenditionAssoc) - { - NodeRef oldRendition = oldRenditionAssoc.getChildRef(); - nodeService.removeAspect(oldRendition, RenditionModel.ASPECT_HIDDEN_RENDITION); - nodeService.removeAspect(oldRendition, RenditionModel.ASPECT_VISIBLE_RENDITION); - nodeService.removeChildAssociation(oldRenditionAssoc); - } - - private boolean orphanExistingRendition(RenditionDefinition renditionDefinition, RenditionLocation location) - { - if (location.getChildRef() != null) - return true; - else - return AbstractRenderingEngine.getParamWithDefault(RenditionService.PARAM_ORPHAN_EXISTING_RENDITION, - Boolean.FALSE, renditionDefinition); - } - - private boolean renditionLocationMatches(NodeRef oldRendition, RenditionLocation location) - { - NodeRef destination = location.getChildRef(); - if (destination != null) - { - return destination.equals(oldRendition); - } - ChildAssociationRef oldParentAssoc = nodeService.getPrimaryParent(oldRendition); - NodeRef oldParent = oldParentAssoc.getParentRef(); - if (oldParent.equals(location.getParentRef())) - { - String childName = location.getChildName(); - if (childName == null) - return true; - else - { - Serializable oldName = nodeService.getProperty(oldRendition, ContentModel.PROP_NAME); - return childName.equals(oldName); - } - } - return false; - } - - private ChildAssociationRef getSpecifiedRenditionOrCreateNewRendition(NodeRef sourceNode, - RenditionLocation location, QName renditionName) - { - NodeRef destination = location.getChildRef(); - if (destination != null) - return nodeService.getPrimaryParent(destination); - else - return createNewRendition(sourceNode, location, renditionName); - } - - private ChildAssociationRef createNewRendition(NodeRef sourceNode, RenditionLocation location, QName renditionName) - { - NodeRef parentRef = location.getParentRef(); - boolean parentIsSource = parentRef.equals(sourceNode); - QName renditionType = RenditionModel.ASSOC_RENDITION; - QName assocTypeQName = parentIsSource ? renditionType : ContentModel.ASSOC_CONTAINS; - QName nodeTypeQName = ContentModel.TYPE_CONTENT; - ChildAssociationRef primaryAssoc = nodeService.createNode(parentRef, assocTypeQName, renditionName, - nodeTypeQName); - - // If the new rendition is not directly under the source node then add - // the rendition association. - if (parentIsSource == false) - { - NodeRef rendition = primaryAssoc.getChildRef(); - nodeService.addChild(sourceNode, rendition, renditionType, renditionName); - } - return primaryAssoc; - } - - /** - * @param sourceNode - * @param targetNode - */ private void transferNodeProperties(NodeRef sourceNode, NodeRef targetNode) { if (log.isDebugEnabled()) diff --git a/source/java/org/alfresco/repo/rendition/RenditionNodeManager.java b/source/java/org/alfresco/repo/rendition/RenditionNodeManager.java new file mode 100644 index 0000000000..d1981f2f03 --- /dev/null +++ b/source/java/org/alfresco/repo/rendition/RenditionNodeManager.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +package org.alfresco.repo.rendition; + +import java.io.Serializable; +import java.util.List; + +import org.alfresco.model.ContentModel; +import org.alfresco.model.RenditionModel; +import org.alfresco.repo.rendition.executer.AbstractRenderingEngine; +import org.alfresco.service.cmr.rendition.RenditionDefinition; +import org.alfresco.service.cmr.rendition.RenditionService; +import org.alfresco.service.cmr.rendition.RenditionServiceException; +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.namespace.QName; +import org.alfresco.service.namespace.QNamePattern; + +/** + * This class is responsible for placing a rendition node in the correct + * location given a temporary rendition, a source node, a rendition location and + * optionally an old rendition. This manages the complex logic of deciding + * whether to move and old rendition or orphan it and create a new one amongst + * other things. + * + * @author Nick Smith + * + */ +public class RenditionNodeManager +{ + private final NodeRef sourceNode; + private final NodeRef oldRendition; + private final RenditionDefinition renditionDefinition; + private final RenditionLocation location; + private final NodeService nodeService; + + public RenditionNodeManager(NodeRef sourceNode, NodeRef oldRendition, RenditionLocation location, + RenditionDefinition renditionDefinition, NodeService nodeService) + { + this.sourceNode = sourceNode; + this.oldRendition = oldRendition; + this.location = location; + this.renditionDefinition = renditionDefinition; + this.nodeService = nodeService; + } + + public ChildAssociationRef findOrCreateRenditionNode() + { + QName renditionName = renditionDefinition.getRenditionName(); + // If no rendition already exists create anew rendition node and + // association. + if (oldRendition == null) + { + return getSpecifiedRenditionOrCreateNewRendition(renditionName); + } + // If a rendition exists and is already in the correct location then + // return that renditions primary parent association + if (renditionLocationMatches()) + { + return nodeService.getPrimaryParent(oldRendition); + } + // If the old rendition is in the wrong location and the 'orphan + // existing rendition' param is set to true or the RenditionLocation + // specifies a destination NodeRef then ldelete the old + // rendition association and create a new rendition node. + if (orphanExistingRendition()) + { + orphanRendition( renditionName); + return getSpecifiedRenditionOrCreateNewRendition(renditionName); + } + // If the old rendition is in the wrong place and the 'orphan existing + // rendition' param is not set to true then move the existing rendition + // to the correct location. + return moveRendition(renditionName); + } + + private ChildAssociationRef moveRendition(QName associationName) + { + return nodeService.moveNode(oldRendition, location.getParentRef(), ContentModel.ASSOC_CONTAINS, associationName); + } + + private void orphanRendition(QNamePattern renditionName) + { + List parents = nodeService.getParentAssocs(oldRendition, RenditionModel.ASSOC_RENDITION, renditionName); + if(parents.size() ==1) + { + ChildAssociationRef parentAssoc = parents.get(0); + if(parentAssoc.getParentRef().equals(sourceNode)) + { + nodeService.removeAspect(oldRendition, RenditionModel.ASPECT_HIDDEN_RENDITION); + nodeService.removeAspect(oldRendition, RenditionModel.ASPECT_VISIBLE_RENDITION); + nodeService.removeChildAssociation(parentAssoc); + return; + } + } + String msg = "Node: " + oldRendition + + " is not a rendition of type: " + renditionName + + " for source node: " + sourceNode; + throw new RenditionServiceException(msg); + } + + private boolean orphanExistingRendition() + { + if (location.getChildRef() != null) + return true; + else + return AbstractRenderingEngine.getParamWithDefault(RenditionService.PARAM_ORPHAN_EXISTING_RENDITION, + Boolean.FALSE, renditionDefinition); + } + + private boolean renditionLocationMatches() + { + NodeRef destination = location.getChildRef(); + if (destination != null) + { + return destination.equals(oldRendition); + } + ChildAssociationRef oldParentAssoc = nodeService.getPrimaryParent(oldRendition); + NodeRef oldParent = oldParentAssoc.getParentRef(); + if (oldParent.equals(location.getParentRef())) + { + String childName = location.getChildName(); + if (childName == null) + return true; + else + { + Serializable oldName = nodeService.getProperty(oldRendition, ContentModel.PROP_NAME); + return childName.equals(oldName); + } + } + return false; + } + + private ChildAssociationRef getSpecifiedRenditionOrCreateNewRendition(QName renditionName) + { + NodeRef destination = location.getChildRef(); + if (destination != null) + return nodeService.getPrimaryParent(destination); + else + return createNewRendition(renditionName); + } + + private ChildAssociationRef createNewRendition(QName renditionName) + { + NodeRef parentRef = location.getParentRef(); + boolean parentIsSource = parentRef.equals(sourceNode); + QName renditionType = RenditionModel.ASSOC_RENDITION; + QName assocTypeQName = parentIsSource ? renditionType : ContentModel.ASSOC_CONTAINS; + QName nodeTypeQName = ContentModel.TYPE_CONTENT; + ChildAssociationRef primaryAssoc = nodeService.createNode(parentRef, assocTypeQName, renditionName, + nodeTypeQName); + + // If the new rendition is not directly under the source node then add + // the rendition association. + if (parentIsSource == false) + { + NodeRef rendition = primaryAssoc.getChildRef(); + nodeService.addChild(sourceNode, rendition, renditionType, renditionName); + } + return primaryAssoc; + } + +}