/*
* #%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.freeze;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
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.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Freeze Service Implementation
*
* @author Roy Wetherall
* @author Tuna Aksoy
* @since 2.1
*/
public class FreezeServiceImpl extends ServiceBaseImpl
implements FreezeService,
RecordsManagementModel
{
/** I18N */
private static final String MSG_HOLD_NAME = "rm.hold.name";
/** File Plan Service */
private FilePlanService filePlanService;
/** Hold service */
private HoldService holdService;
/**
* @return File plan service
*/
protected FilePlanService getFilePlanService()
{
return this.filePlanService;
}
/**
* @return Hold service
*/
protected HoldService getHoldService()
{
return this.holdService;
}
/**
* @param filePlanService file plan service
*/
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
/**
* @param holdService hold service
*/
public void setHoldService(HoldService holdService)
{
this.holdService = holdService;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#isFrozen(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public boolean isFrozen(NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
return nodeService.hasAspect(nodeRef, ASPECT_FROZEN);
}
/**
* Deprecated Method Implementations
*/
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFrozen(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Deprecated
public Set<NodeRef> getFrozen(NodeRef hold)
{
return new HashSet<NodeRef>(getHoldService().getHeld(hold));
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(java.lang.String,
* org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Deprecated
public NodeRef freeze(String reason, NodeRef nodeRef)
{
NodeRef hold = createHold(nodeRef, reason);
getHoldService().addToHold(hold, nodeRef);
return hold;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(org.alfresco.service.cmr.repository.NodeRef,
* org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Deprecated
public void freeze(NodeRef hold, NodeRef nodeRef)
{
ParameterCheck.mandatory("hold", hold);
ParameterCheck.mandatory("nodeRef", nodeRef);
getHoldService().addToHold(hold, nodeRef);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(java.lang.String,
* java.util.Set)
*/
@Override
@Deprecated
public NodeRef freeze(String reason, Set<NodeRef> nodeRefs)
{
NodeRef hold = null;
if (!nodeRefs.isEmpty())
{
List<NodeRef> list = new ArrayList<NodeRef>(nodeRefs);
hold = createHold(list.get(0), reason);
getHoldService().addToHold(hold, list);
}
return hold;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(org.alfresco.service.cmr.repository.NodeRef,
* java.util.Set)
*/
@Override
@Deprecated
public void freeze(NodeRef hold, Set<NodeRef> nodeRefs)
{
ParameterCheck.mandatory("hold", hold);
ParameterCheck.mandatoryCollection("nodeRefs", nodeRefs);
for (NodeRef nodeRef : nodeRefs)
{
freeze(hold, nodeRef);
}
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#unFreeze(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Deprecated
public void unFreeze(NodeRef nodeRef)
{
List<NodeRef> holds = getHoldService().heldBy(nodeRef, true);
for (NodeRef hold : holds)
{
getHoldService().removeFromHold(hold, nodeRef);
}
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#unFreeze(java.util.Set)
*/
@Override
@Deprecated
public void unFreeze(Set<NodeRef> nodeRefs)
{
ParameterCheck.mandatoryCollection("nodeRefs", nodeRefs);
for (NodeRef nodeRef : nodeRefs)
{
unFreeze(nodeRef);
}
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#relinquish(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Deprecated
public void relinquish(NodeRef hold)
{
getHoldService().deleteHold(hold);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getReason(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Deprecated
public String getReason(NodeRef hold)
{
return getHoldService().getHoldReason(hold);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#updateReason(org.alfresco.service.cmr.repository.NodeRef,
* java.lang.String)
*/
@Override
@Deprecated
public void updateReason(NodeRef hold, String reason)
{
getHoldService().setHoldReason(hold, reason);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getHold(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public Set<NodeRef> getHolds(NodeRef filePlan)
{
ParameterCheck.mandatory("filePlan", filePlan);
return new HashSet<NodeRef>(getHoldService().getHolds(filePlan));
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public boolean hasFrozenChildren(final NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
boolean result = false;
// check that we are dealing with a record folder
if (isRecordFolder(nodeRef))
{
int heldCount = 0;
if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN))
{
heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT);
}
else
{
final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService");
heldCount = AuthenticationUtil.runAsSystem(new RunAsWork<Integer>()
{
@Override
public Integer doWork()
{
return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Integer>()
{
public Integer execute() throws Throwable
{
int heldCount = 0;
// NOTE: this process remains to 'patch' older systems to improve performance next time around
List<ChildAssociationRef> childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, null);
if (childAssocs != null && !childAssocs.isEmpty())
{
for (ChildAssociationRef childAssociationRef : childAssocs)
{
NodeRef record = childAssociationRef.getChildRef();
if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record))
{
heldCount ++;
}
}
}
// add aspect and set count
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(PROP_HELD_CHILDREN_COUNT, heldCount);
getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props);
return heldCount;
}
},
false, true);
}
});
}
// true if more than one child held
result = (heldCount > 0);
}
return result;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public Date getFreezeDate(NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
if (isFrozen(nodeRef))
{
Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_AT);
if (property != null) { return (Date) property; }
}
return null;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeInitiator(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public String getFreezeInitiator(NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
if (isFrozen(nodeRef))
{
Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_BY);
if (property != null) { return (String) property; }
}
return null;
}
/**
* Helper Methods
*/
/**
* Creates a hold using the given nodeRef and reason
*
* @param nodeRef the nodeRef which will be frozen
* @param reason the reason why the record will be frozen
* @return NodeRef of the created hold
*/
private NodeRef createHold(NodeRef nodeRef, String reason)
{
// get the hold container
final NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef);
NodeRef holdContainer = getFilePlanService().getHoldContainer(filePlan);
// calculate the hold name
int nextCount = getNextCount(holdContainer);
String holdName = I18NUtil.getMessage(MSG_HOLD_NAME) + " " + StringUtils.leftPad(Integer.toString(nextCount), 10, "0");
// create hold
return getHoldService().createHold(filePlan, holdName, reason, null);
}
}