/* * Copyright (C) 2005-2011 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.executer; import java.io.Serializable; import java.util.List; import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.executer.ActionExecuter; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.repo.rendition.RenditionedAspect; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.thumbnail.AddFailedThumbnailActionExecuter; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.rendition.RenditionService; 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.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This {@link ActionExecuter} implementation is used internally to delete rendition nodes when a rendition update has failed. * The scenario is as follows: a content node exists in the repository and has a number of rendition nodes associated with it. * When the content node is given new content, each of the rendition nodes must be updated to reflect the new source content. * But if one or more of those re-renditions fail, then the old rendition nodes now refer to out of date content and should be deleted. *

* This class executes the deletion of the specified rendition node. * * @author Neil Mc Erlean * @since 3.4.2 * * @see RenditionedAspect * @see AddFailedThumbnailActionExecuter */ public class DeleteRenditionActionExecuter extends ActionExecuterAbstractBase { private static Log log = LogFactory.getLog(DeleteRenditionActionExecuter.class); /** * The action bean name. */ public static final String NAME = "delete-rendition"; /** * The name of the rendition definition to delete e.g. cm:doclib. */ public static final String PARAM_RENDITION_DEFINITION_NAME = "rendition-definition-name"; private NodeService nodeService; private RenditionService renditionService; private BehaviourFilter behaviourFilter; public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } public void setRenditionService(RenditionService renditionService) { this.renditionService = renditionService; } public void setBehaviourFilter(BehaviourFilter behaviourFilter) { this.behaviourFilter = behaviourFilter; } /** * @see org.alfresco.repo.action.executer.ActionExecuter#execute(org.alfresco.service.cmr.repository.NodeRef, NodeRef) */ public void executeImpl(final Action action, final NodeRef actionedUponNodeRef) { // It is possible that the user who triggered the thumbnail update does not have delete permissions on the node // but does have write permissions. e.g. if a SiteCollaborator updates a node which they do not own, any failure // to update renditions would trigger this DeleteRendition action and they would not have permissions to delete. // // For that reason this action is run as the system user. final NodeService finalNodeService = nodeService; AuthenticationUtil.runAsSystem(new RunAsWork() { @Override public Void doWork() throws Exception { final boolean nodeExists = finalNodeService.exists(actionedUponNodeRef); if (nodeExists) { Map paramValues = action.getParameterValues(); final QName renditionDefName = (QName)paramValues.get(PARAM_RENDITION_DEFINITION_NAME); ChildAssociationRef existingRendition = renditionService.getRenditionByName(actionedUponNodeRef, renditionDefName); if (existingRendition != null) { if (log.isDebugEnabled()) { StringBuilder msg = new StringBuilder(); msg.append("Deleting rendition node: ").append(existingRendition); log.debug(msg.toString()); } behaviourFilter.disableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE); try { nodeService.deleteNode(existingRendition.getChildRef()); } finally { behaviourFilter.enableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE); } } } return null; } }); } /** * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List) */ @Override protected void addParameterDefinitions(List paramList) { paramList.add(new ParameterDefinitionImpl(PARAM_RENDITION_DEFINITION_NAME, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_RENDITION_DEFINITION_NAME), false)); } }