/* * #%L * Alfresco Records Management Module * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * - * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * - * 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 <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.module.org_alfresco_module_rm.patch.v22; import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch; 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.RegexQNamePattern; /** * Sets the ghost on destroy property for existing destroy disposition actions * to the value specified in the global properties file * * @author Mark Hibbins * @since 2.2 */ public class RMv22GhostOnDestroyDispositionActionPatch extends AbstractModulePatch { /** Disposition service */ private DispositionService dispositionService; /** File plan service */ private FilePlanService filePlanService; /** Node service */ private NodeService nodeService; /** Ghost on destroy setting */ private boolean ghostingEnabled; /** * @param dispositionService disposition service */ public void setDispositionService(DispositionService dispositionService) { this.dispositionService = dispositionService; } /** * @param filePlanService file plan service */ public void setFilePlanService(FilePlanService filePlanService) { this.filePlanService = filePlanService; } /** * @param nodeService file plan service */ public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } /** * @param ghostingEnabled Ghost on destroy setting from * alfresco-global.properties */ public void setGhostingEnabled(boolean ghostingEnabled) { this.ghostingEnabled = ghostingEnabled; } /** * @see org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch#applyInternal() */ @Override public void applyInternal() { Set<NodeRef> filePlans = filePlanService.getFilePlans(); for (NodeRef filePlan : filePlans) { processFilePlan(filePlan); } } /** * Apply the patch to each file plan * * @param filePlan */ private void processFilePlan(NodeRef filePlan) { Set<DispositionSchedule> dispositionSchedules = new HashSet<DispositionSchedule>(); getDispositionSchedules(filePlan, dispositionSchedules); for (DispositionSchedule dispositionSchedule : dispositionSchedules) { processDispositionSchedule(dispositionSchedule); } } /** * Add the disposition schedule associated with the node ref to the passed * set of disposition schedule then call this method recursively for this * node's children * * @param nodeRef * @param dispositionSchedules */ private void getDispositionSchedules(NodeRef nodeRef, Set<DispositionSchedule> dispositionSchedules) { if (filePlanService.isRecordCategory(nodeRef)) { DispositionSchedule dispositionSchedule = this.dispositionService.getDispositionSchedule(nodeRef); if (dispositionSchedule != null) { dispositionSchedules.add(dispositionSchedule); } List<ChildAssociationRef> children = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); for (ChildAssociationRef childAssoc : children) { getDispositionSchedules(childAssoc.getChildRef(), dispositionSchedules); } } } /** * Patch the specified disposition schedule. To do this add the host on * destroy to any action definition that doesn't already have it defined and * set the value to the value set in the global properties file. Leave any * action definitions that have this property already defined untouched. * * @param dispositionSchedule */ private void processDispositionSchedule(DispositionSchedule dispositionSchedule) { List<DispositionActionDefinition> actionDefinitions = dispositionSchedule.getDispositionActionDefinitions(); for(DispositionActionDefinition actionDefinition : actionDefinitions) { String actionName = (String) nodeService.getProperty(actionDefinition.getNodeRef(), RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME); if ("destroy".equals(actionName)) { // we only want to add the ghost on destroy property to action // definitions that do not already have it defined String ghostOnDestroyValue = (String) nodeService.getProperty(actionDefinition.getNodeRef(), RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY); if (ghostOnDestroyValue == null) { Map<QName, Serializable> props = new HashMap<QName, Serializable>(1); props.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, this.ghostingEnabled ? "ghost" : "destroy"); this.dispositionService.updateDispositionActionDefinition(actionDefinition, props); } } } } }