/*
* #%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.job;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.action.RMDispositionActionExecuterAbstractBase;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
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.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.PersonService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* The Disposition Lifecycle Job Finds all disposition action nodes which are for disposition actions specified Where
* asOf > now OR dispositionEventsEligible = true; Runs the cut off or retain action for eligible records.
*
* @author mrogers
* @author Roy Wetherall
*/
public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecuter
{
/** logger */
private static Log logger = LogFactory.getLog(DispositionLifecycleJobExecuter.class);
/** list of disposition actions to automatically execute */
private List<String> dispositionActions;
/** query string */
private String query;
/** records management action service */
private RecordsManagementActionService recordsManagementActionService;
/** node service */
private NodeService nodeService;
/** search service */
private SearchService searchService;
/** person service */
private PersonService personService;
/**
* List of disposition actions to automatically execute when eligible.
*
* @param dispositionActions disposition actions
*/
public void setDispositionActions(List<String> dispositionActions)
{
this.dispositionActions = dispositionActions;
}
/**
* @param recordsManagementActionService records management action service
*/
public void setRecordsManagementActionService(RecordsManagementActionService recordsManagementActionService)
{
this.recordsManagementActionService = recordsManagementActionService;
}
/**
* @param nodeService node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param searchService search service
*/
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
/**
* Get the search query string.
*
* @return job query string
*/
protected String getQuery()
{
if (query == null)
{
StringBuilder sb = new StringBuilder();
sb.append("TYPE:\"rma:dispositionAction\" + ");
sb.append("(@rma\\:dispositionAction:(");
boolean bFirst = true;
for (String dispositionAction : dispositionActions)
{
if (bFirst)
{
bFirst = false;
}
else
{
sb.append(" OR ");
}
sb.append("\"").append(dispositionAction).append("\"");
}
sb.append("))");
sb.append(" AND ISUNSET:\"rma:dispositionActionCompletedAt\" ");
sb.append(" AND ( ");
sb.append("@rma\\:dispositionEventsEligible:true ");
sb.append("OR @rma\\:dispositionAsOf:[MIN TO NOW] ");
sb.append(") ");
query = sb.toString();
}
return query;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJobExecuter#execute()
*/
public void executeImpl()
{
try
{
logger.debug("Job Starting");
if (dispositionActions != null && !dispositionActions.isEmpty())
{
// execute search
ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,
SearchService.LANGUAGE_FTS_ALFRESCO, getQuery());
List<NodeRef> resultNodes = results.getNodeRefs();
results.close();
if (logger.isDebugEnabled())
{
logger.debug("Processing " + resultNodes.size() + " nodes");
}
// process search results
for (NodeRef node : resultNodes)
{
final NodeRef currentNode = node;
RetryingTransactionCallback<Boolean> processTranCB = new RetryingTransactionCallback<Boolean>()
{
public Boolean execute()
{
final String dispAction = (String) nodeService.getProperty(currentNode,
RecordsManagementModel.PROP_DISPOSITION_ACTION);
// Run disposition action
if (dispAction != null && dispositionActions.contains(dispAction))
{
ChildAssociationRef parent = nodeService.getPrimaryParent(currentNode);
if (parent.getTypeQName().equals(RecordsManagementModel.ASSOC_NEXT_DISPOSITION_ACTION))
{
Map<String, Serializable> props = new HashMap<String, Serializable>(1);
props.put(RMDispositionActionExecuterAbstractBase.PARAM_NO_ERROR_CHECK,
Boolean.FALSE);
try
{
// execute disposition action
recordsManagementActionService.executeRecordsManagementAction(
parent.getParentRef(), dispAction, props);
if (logger.isDebugEnabled())
{
logger.debug("Processed action: " + dispAction + "on" + parent);
}
}
catch (AlfrescoRuntimeException exception)
{
if (logger.isDebugEnabled())
{
logger.debug(exception);
}
}
}
}
return Boolean.TRUE;
}
};
// if exists
if (nodeService.exists(currentNode))
{
retryingTransactionHelper.doInTransaction(processTranCB);
}
}
}
logger.debug("Job Finished");
}
catch (AlfrescoRuntimeException exception)
{
if (logger.isDebugEnabled())
{
logger.debug(exception);
}
}
}
public PersonService getPersonService()
{
return personService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
}