mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge branch 'merge-2.5/RM-7051_mergeUp' into 'release/V2.5'
Resolve RM-7051 "Merge 2.5/ mergeup" See merge request records-management/records-management!1305
This commit is contained in:
@@ -700,6 +700,10 @@
|
||||
<title>Saved search</title>
|
||||
</aspect>
|
||||
|
||||
<aspect name="rma:dispositionProcessed">
|
||||
<title>Disposition processed</title>
|
||||
</aspect>
|
||||
|
||||
<aspect name="rma:vitalRecordDefinition">
|
||||
<title>Vital Record Definition</title>
|
||||
<properties>
|
||||
|
@@ -14,5 +14,5 @@
|
||||
<property name="filePlanService" ref="filePlanService"/>
|
||||
<property name="nodeService" ref="nodeService"/>
|
||||
</bean>
|
||||
|
||||
|
||||
</beans>
|
@@ -7,8 +7,23 @@
|
||||
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="idValue" jdbcType="BIGINT" javaType="java.lang.String"/>
|
||||
</parameterMap>
|
||||
|
||||
<select id="select_CountRMIndentifier" parameterMap="parameter_CountRMIndentifier" resultType="java.lang.Integer">
|
||||
|
||||
<parameterMap id="parameter_folderPatchPaging" type="map">
|
||||
<parameter property="processed" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="folderQnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="start" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="end" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
</parameterMap>
|
||||
|
||||
<resultMap id="result_NodeRefEntity" type="org.alfresco.module.org_alfresco_module_rm.query.NodeRefEntity">
|
||||
<result property="row" column="row" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<result property="protocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String" />
|
||||
<result property="identifier" column="identifier" jdbcType="VARCHAR" javaType="java.lang.String" />
|
||||
<result property="uuid" column="uuid" jdbcType="VARCHAR" javaType="java.lang.String" />
|
||||
</resultMap>
|
||||
|
||||
|
||||
<select id="select_CountRMIndentifier" parameterMap="parameter_CountRMIndentifier" resultType="java.lang.Integer">
|
||||
select
|
||||
count(*)
|
||||
from
|
||||
@@ -19,5 +34,19 @@
|
||||
prop.string_value = ?
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
<select id="select_RecordFoldersWithSchedules"
|
||||
parameterMap="parameter_folderPatchPaging"
|
||||
resultMap="result_NodeRefEntity">
|
||||
select alfn.id , alfs.protocol, alfs.identifier, alfn.uuid
|
||||
from alf_node alfn, alf_store alfs
|
||||
where alfn.id not in (
|
||||
select node_id
|
||||
from alf_node_aspects
|
||||
where qname_id = ? )
|
||||
and type_qname_id = ?
|
||||
and alfn.store_id = alfs.id
|
||||
and alfn.id between ? and ?
|
||||
</select>
|
||||
|
||||
</mapper>
|
@@ -665,4 +665,19 @@
|
||||
parent="rmBaseWebscript">
|
||||
<property name="relationshipService" ref="RelationshipService" />
|
||||
</bean>
|
||||
|
||||
<!-- Update record schedule GET webscript -->
|
||||
<bean id="webscript.org.alfresco.repository.schedules.rm-updaterecordschedule.get"
|
||||
class="org.alfresco.repo.web.scripts.schedule.UpdateRecordScheduleGet"
|
||||
parent="webscript">
|
||||
<property name="nodeDAO" ref="nodeDAO"/>
|
||||
<property name="qnameDAO" ref="qnameDAO"/>
|
||||
<property name="nodeService" ref="nodeService"/>
|
||||
<property name="transactionService" ref="transactionService"/>
|
||||
<property name="dispositionService" ref="dispositionService"/>
|
||||
<property name="recordService" ref="recordService"/>
|
||||
<property name="recordsManagementQueryDAO" ref="recordsManagementQueryDAO"/>
|
||||
<property name="behaviourFilter" ref="policyBehaviourFilter" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
@@ -1,3 +1,3 @@
|
||||
# RM Schema number
|
||||
|
||||
version.rm.schema=2501
|
||||
version.rm.schema=2502
|
||||
|
@@ -0,0 +1,13 @@
|
||||
<webscript>
|
||||
<shortname>Updates Record Schedules based on Hierarchical Retention Instructions</shortname>
|
||||
<description><![CDATA[
|
||||
Updates records schedules by reviewing retention instructions defined within the principle hierarchy.<br/>
|
||||
URL parameter maxRecordFolders is optional, and represents the maximum number of record folders that should be processed. If not specified maxRecordFolders will be set to the max value for an integer.<br/>
|
||||
URL parameter recordFolder is optional, and represents the nodeRef of a record folder whose records should be processed. If specified then maxRecordFolders will be ignored.<br/>
|
||||
]]>
|
||||
</description>
|
||||
<url>/api/rm/rm-updateRecordSchedule?maxRecordFolders={maxRecordFolders?}&recordFolder={recordFolder?}</url>
|
||||
<format default="json">argument</format>
|
||||
<authentication>admin</authentication>
|
||||
<transaction allow="readonly">required</transaction>
|
||||
</webscript>
|
@@ -0,0 +1,30 @@
|
||||
<#--
|
||||
#%L
|
||||
Alfresco Records Management Module
|
||||
%%
|
||||
Copyright (C) 2005 - 2019 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%
|
||||
-->
|
||||
{
|
||||
"responsestatus" : "${responsestatus?json_string}",
|
||||
"message" : "${message?json_string}"
|
||||
}
|
@@ -237,6 +237,14 @@ public interface DispositionService
|
||||
*/
|
||||
void updateNextDispositionAction(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Updates the next disposition action
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param dispositionSchedule the schedule to be applied
|
||||
*/
|
||||
void updateNextDispositionAction(NodeRef nodeRef, DispositionSchedule dispositionSchedule);
|
||||
|
||||
/**
|
||||
* Refreshes the disposition action details of the given node.
|
||||
*
|
||||
|
@@ -953,8 +953,36 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
||||
public Void doWork()
|
||||
{
|
||||
// Get this disposition instructions for the node
|
||||
DispositionSchedule di = getDispositionSchedule(nodeRef);
|
||||
if (di != null)
|
||||
DispositionSchedule dispositionSchedule = getDispositionSchedule(nodeRef);
|
||||
|
||||
updateNextDispositionAction(nodeRef, dispositionSchedule);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
AuthenticationUtil.runAsSystem(runAsWork);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public void updateNextDispositionAction(final NodeRef nodeRef, final DispositionSchedule dispositionSchedule)
|
||||
{
|
||||
|
||||
|
||||
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
|
||||
{
|
||||
/**
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork()
|
||||
*/
|
||||
@Override
|
||||
public Void doWork()
|
||||
{
|
||||
|
||||
if (dispositionSchedule != null)
|
||||
{
|
||||
// Get the current action node
|
||||
NodeRef currentDispositionAction = null;
|
||||
@@ -973,7 +1001,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
||||
nodeService.moveNode(currentDispositionAction, nodeRef, ASSOC_DISPOSITION_ACTION_HISTORY, ASSOC_DISPOSITION_ACTION_HISTORY);
|
||||
}
|
||||
|
||||
List<DispositionActionDefinition> dispositionActionDefinitions = di.getDispositionActionDefinitions();
|
||||
List<DispositionActionDefinition> dispositionActionDefinitions = dispositionSchedule.getDispositionActionDefinitions();
|
||||
DispositionActionDefinition currentDispositionActionDefinition = null;
|
||||
DispositionActionDefinition nextDispositionActionDefinition = null;
|
||||
|
||||
@@ -989,14 +1017,14 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
// Get the current action
|
||||
String currentADId = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION_ID);
|
||||
currentDispositionActionDefinition = di.getDispositionActionDefinition(currentADId);
|
||||
currentDispositionActionDefinition = dispositionSchedule.getDispositionActionDefinition(currentADId);
|
||||
|
||||
// When the record has multiple disposition schedules the current disposition action may not be found by id
|
||||
// In this case it will be searched by name
|
||||
if(currentDispositionActionDefinition == null)
|
||||
{
|
||||
String currentADName = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION);
|
||||
currentDispositionActionDefinition = di.getDispositionActionDefinitionByName(currentADName);
|
||||
currentDispositionActionDefinition = dispositionSchedule.getDispositionActionDefinitionByName(currentADName);
|
||||
}
|
||||
|
||||
// Get the next disposition action
|
||||
|
@@ -281,4 +281,5 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
||||
QName PROP_COUNT = QName.createQName(RM_URI, "count");
|
||||
|
||||
QName ASPECT_SAVED_SEARCH = QName.createQName(RM_URI, "savedSearch");
|
||||
QName ASPECT_DISPOSITION_PROCESSED = QName.createQName(RM_URI, "dispositionProcessed");
|
||||
}
|
||||
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2019 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.query;
|
||||
|
||||
/**
|
||||
* NodeRef Entity - used by {@link RecordsManagementQueryDAOImpl}.
|
||||
*
|
||||
* @author Tom Page
|
||||
* @since 2.5.0.4
|
||||
*/
|
||||
public class NodeRefEntity
|
||||
{
|
||||
private Long num;
|
||||
private String protocol;
|
||||
private String identifier;
|
||||
private String uuid;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public NodeRefEntity()
|
||||
{
|
||||
}
|
||||
|
||||
public Long getNum()
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
public void setNum(Long num)
|
||||
{
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public String getProtocol()
|
||||
{
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol)
|
||||
{
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public String getIdentifier()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier)
|
||||
{
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public String getUuid()
|
||||
{
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid)
|
||||
{
|
||||
this.uuid = uuid;
|
||||
}
|
||||
}
|
@@ -27,6 +27,10 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* Records management query DAO
|
||||
*
|
||||
@@ -46,4 +50,15 @@ public interface RecordsManagementQueryDAO
|
||||
* @return int count
|
||||
*/
|
||||
int getCountRmaIdentifier(String identifierValue);
|
||||
|
||||
/**
|
||||
* Returns a number of nodeRefs for record folders in the system
|
||||
* that have the property recordSearchHasDispositionSchedule:true
|
||||
* (used for MNT-20864)
|
||||
* @param start long - the first result row to return
|
||||
* @param end long - the last result row to return
|
||||
* @return list of node refs
|
||||
*/
|
||||
List<NodeRef> getRecordFoldersWithSchedules(Long start, Long end);
|
||||
|
||||
}
|
||||
|
@@ -27,11 +27,14 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
@@ -45,7 +48,9 @@ import org.mybatis.spring.SqlSessionTemplate;
|
||||
public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO, RecordsManagementModel
|
||||
{
|
||||
private static final String COUNT_IDENTIFIER = "alfresco.query.rm.select_CountRMIndentifier";
|
||||
|
||||
private static final String SCHEDULED_FOLDERS = "alfresco.query.rm.select_RecordFoldersWithSchedules";
|
||||
private static final String SCHEDULED_FOLDERS_COUNT = "alfresco.query.rm.select_RecordFoldersWithSchedulesCount";
|
||||
|
||||
/** SQL session template */
|
||||
protected SqlSessionTemplate template;
|
||||
|
||||
@@ -97,4 +102,32 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.query.RecordsManagementQueryDAO#getRecordFoldersWithSchedules(Long, Long)
|
||||
*/
|
||||
@Override
|
||||
public List<NodeRef> getRecordFoldersWithSchedules(Long start, Long end)
|
||||
{
|
||||
Map<String, Object> params = new HashMap<>(2);
|
||||
params.put("processed", qnameDAO.getQName(ASPECT_DISPOSITION_PROCESSED)
|
||||
.getFirst());
|
||||
params.put("folderQnameId", qnameDAO.getQName(TYPE_RECORD_FOLDER)
|
||||
.getFirst());
|
||||
params.put("start", start);
|
||||
params.put("end", end);
|
||||
|
||||
List<NodeRefEntity> entities = template.selectList(SCHEDULED_FOLDERS, params);
|
||||
|
||||
List<NodeRef> results = new ArrayList<>();
|
||||
|
||||
// convert the entities to NodeRefs
|
||||
for (NodeRefEntity nodeRefEntity : entities)
|
||||
{
|
||||
results.add(
|
||||
new NodeRef(nodeRefEntity.getProtocol(), nodeRefEntity.getIdentifier(), nodeRefEntity.getUuid()));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,430 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2019 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%
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2005-2014 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.web.scripts.schedule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.query.RecordsManagementQueryDAO;
|
||||
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.webscripts.AbstractWebScript;
|
||||
import org.springframework.extensions.webscripts.Cache;
|
||||
import org.springframework.extensions.webscripts.Format;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||
|
||||
/**
|
||||
* Webscript used to update records that are missing their schedule information
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class UpdateRecordScheduleGet extends AbstractWebScript implements RecordsManagementModel
|
||||
{
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
private static Log logger = LogFactory.getLog(UpdateRecordScheduleGet.class);
|
||||
|
||||
/**
|
||||
* parameters
|
||||
*/
|
||||
private static final String PARAM_MAX_RECORD_FOLDERS = "maxRecordFolders";
|
||||
private static final String PARAM_RECORD_FOLDER = "recordFolder";
|
||||
|
||||
private static final String SUCCESS_STATUS = "success";
|
||||
private static final String MODEL_STATUS = "responsestatus";
|
||||
private static final String MODEL_MESSAGE = "message";
|
||||
private static final String MESSAGE_ALL_TEMPLATE = "Updated {0} records from {1} folders with updated disposition instructions.";
|
||||
private static final String MESSAGE_FOLDER_TEMPLATE = "Updated records in folder {0} with updated disposition instructions.";
|
||||
|
||||
/**
|
||||
* services
|
||||
*/
|
||||
private NodeService nodeService;
|
||||
private DispositionService dispositionService;
|
||||
private RecordService recordService;
|
||||
private TransactionService transactionService;
|
||||
private RecordsManagementQueryDAO recordsManagementQueryDAO;
|
||||
private BehaviourFilter behaviourFilter;
|
||||
private NodeDAO nodeDAO;
|
||||
private QNameDAO qnameDAO;
|
||||
|
||||
/**
|
||||
* service setters
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setRecordsManagementQueryDAO(RecordsManagementQueryDAO recordsManagementQueryDAO)
|
||||
{
|
||||
this.recordsManagementQueryDAO = recordsManagementQueryDAO;
|
||||
}
|
||||
|
||||
public void setRecordService(RecordService recordService)
|
||||
{
|
||||
this.recordService = recordService;
|
||||
}
|
||||
|
||||
public void setDispositionService(DispositionService dispositionService)
|
||||
{
|
||||
this.dispositionService = dispositionService;
|
||||
}
|
||||
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
|
||||
{
|
||||
this.behaviourFilter = behaviourFilter;
|
||||
}
|
||||
|
||||
public void setNodeDAO(NodeDAO nodeDAO)
|
||||
{
|
||||
this.nodeDAO = nodeDAO;
|
||||
}
|
||||
|
||||
public void setQnameDAO(QNameDAO qnameDAO)
|
||||
{
|
||||
this.qnameDAO = qnameDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build web script model
|
||||
*/
|
||||
protected Map<String, Object> buildModel(WebScriptRequest req, WebScriptResponse res) throws IOException
|
||||
{
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
transactionService.getRetryingTransactionHelper()
|
||||
.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<String>()
|
||||
{
|
||||
public String execute() throws Throwable
|
||||
{
|
||||
qnameDAO.getOrCreateQName(ASPECT_DISPOSITION_PROCESSED);
|
||||
return null;
|
||||
}
|
||||
|
||||
}, false, true);
|
||||
|
||||
int maxRecordFolders = getMaxRecordFolders(req);
|
||||
NodeRef recordFolder = getRecordFolder(req);
|
||||
|
||||
int processedRecords = 0;
|
||||
String message;
|
||||
if (recordFolder != null)
|
||||
{
|
||||
// Process the specified record folder
|
||||
updateRecordFolder(recordFolder);
|
||||
message = MessageFormat.format(MESSAGE_FOLDER_TEMPLATE, recordFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
int processedRecordFolders = 0;
|
||||
int queryBatchSize = 10000;
|
||||
Long maxNodeId = nodeDAO.getMaxNodeId();
|
||||
for (Long i = 0L; i < maxNodeId; i += queryBatchSize)
|
||||
{
|
||||
List<NodeRef> folders = recordsManagementQueryDAO.getRecordFoldersWithSchedules(i, i + queryBatchSize);
|
||||
for (NodeRef folder : folders)
|
||||
{
|
||||
processedRecords = processedRecords + updateRecordFolder(folder);
|
||||
processedRecordFolders++;
|
||||
|
||||
if (processedRecordFolders >= maxRecordFolders)
|
||||
{
|
||||
// stop processing since we have meet our limit
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (processedRecordFolders >= maxRecordFolders)
|
||||
{
|
||||
// stop processing since we have meet our limit
|
||||
break;
|
||||
}
|
||||
}
|
||||
message = MessageFormat.format(MESSAGE_ALL_TEMPLATE, processedRecords, processedRecordFolders);
|
||||
}
|
||||
|
||||
model.put(MODEL_STATUS, SUCCESS_STATUS);
|
||||
model.put(MODEL_MESSAGE, message);
|
||||
logger.info(message);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.scripts.content.StreamContent#execute(org.springframework.extensions.webscripts.
|
||||
* WebScriptRequest, org.springframework.extensions.webscripts.WebScriptResponse)
|
||||
*/
|
||||
@Override
|
||||
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
|
||||
{
|
||||
// retrieve requested format
|
||||
String format = req.getFormat();
|
||||
|
||||
try
|
||||
{
|
||||
String mimetype = getContainer().getFormatRegistry()
|
||||
.getMimeType(req.getAgent(), format);
|
||||
if (mimetype == null)
|
||||
{
|
||||
throw new WebScriptException("Web Script format '" + format + "' is not registered");
|
||||
}
|
||||
|
||||
// construct model for script / template
|
||||
Status status = new Status();
|
||||
Cache cache = new Cache(getDescription().getRequiredCache());
|
||||
|
||||
Map<String, Object> model = buildModel(req, res);
|
||||
|
||||
if (model == null) { return; }
|
||||
model.put("status", status);
|
||||
model.put("cache", cache);
|
||||
|
||||
Map<String, Object> templateModel = createTemplateParameters(req, res, model);
|
||||
|
||||
// render output
|
||||
int statusCode = status.getCode();
|
||||
if (statusCode != HttpServletResponse.SC_OK && !req.forceSuccessStatus())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Force success status header in response: " + req.forceSuccessStatus());
|
||||
logger.debug("Setting status " + statusCode);
|
||||
}
|
||||
res.setStatus(statusCode);
|
||||
}
|
||||
|
||||
// apply location
|
||||
String location = status.getLocation();
|
||||
if (location != null && location.length() > 0)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Setting location to " + location);
|
||||
res.setHeader(WebScriptResponse.HEADER_LOCATION, location);
|
||||
}
|
||||
|
||||
// apply cache
|
||||
res.setCache(cache);
|
||||
|
||||
String callback = null;
|
||||
if (getContainer().allowCallbacks())
|
||||
{
|
||||
callback = req.getJSONCallback();
|
||||
}
|
||||
if (format.equals(WebScriptResponse.JSON_FORMAT) && callback != null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug(
|
||||
"Rendering JSON callback response: content type=" + Format.JAVASCRIPT.mimetype() + ", status="
|
||||
+ statusCode + ", callback=" + callback);
|
||||
|
||||
// NOTE: special case for wrapping JSON results in a javascript function callback
|
||||
res.setContentType(Format.JAVASCRIPT.mimetype() + ";charset=UTF-8");
|
||||
res.getWriter()
|
||||
.write((callback + "("));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Rendering response: content type=" + mimetype + ", status=" + statusCode);
|
||||
|
||||
res.setContentType(mimetype + ";charset=UTF-8");
|
||||
}
|
||||
|
||||
// render response according to requested format
|
||||
renderFormatTemplate(format, templateModel, res.getWriter());
|
||||
|
||||
if (format.equals(WebScriptResponse.JSON_FORMAT) && callback != null)
|
||||
{
|
||||
// NOTE: special case for wrapping JSON results in a javascript function callback
|
||||
res.getWriter()
|
||||
.write(")");
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
StringWriter stack = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(stack));
|
||||
logger.debug("Caught exception; decorating with appropriate status template : " + stack.toString());
|
||||
}
|
||||
|
||||
throw createStatusException(e, req, res);
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderFormatTemplate(String format, Map<String, Object> model, Writer writer)
|
||||
{
|
||||
format = (format == null) ? "" : format;
|
||||
|
||||
String templatePath = getDescription().getId() + "." + format;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Rendering template '" + templatePath + "'");
|
||||
|
||||
renderTemplate(templatePath, model, writer);
|
||||
}
|
||||
|
||||
protected int getMaxRecordFolders(WebScriptRequest req)
|
||||
{
|
||||
String valueStr = req.getParameter(PARAM_MAX_RECORD_FOLDERS);
|
||||
int value = Integer.MAX_VALUE;
|
||||
if (StringUtils.isNotBlank(valueStr))
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Integer.parseInt(valueStr);
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
//do nothing here, the value will remain 0L in this case
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected NodeRef getRecordFolder(WebScriptRequest req)
|
||||
{
|
||||
String valueStr = req.getParameter(PARAM_RECORD_FOLDER);
|
||||
NodeRef value = null;
|
||||
if (StringUtils.isNotBlank(valueStr))
|
||||
{
|
||||
value = new NodeRef(valueStr);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private int updateRecordFolder(final NodeRef recordFolder)
|
||||
{
|
||||
return transactionService.getRetryingTransactionHelper()
|
||||
.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Integer>()
|
||||
{
|
||||
public Integer execute() throws Throwable
|
||||
{
|
||||
int recordCount = 0;
|
||||
|
||||
behaviourFilter.disableBehaviour(ASPECT_FILE_PLAN_COMPONENT);
|
||||
try
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.info("Checking folder: " + recordFolder);
|
||||
}
|
||||
recordCount = AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Integer>()
|
||||
{
|
||||
@Override
|
||||
public Integer doWork() throws Exception
|
||||
{
|
||||
DispositionSchedule schedule = dispositionService.getDispositionSchedule(recordFolder);
|
||||
int innerRecordCount = 0;
|
||||
if (schedule != null && schedule.isRecordLevelDisposition())
|
||||
{
|
||||
|
||||
List<NodeRef> records = recordService.getRecords(recordFolder);
|
||||
for (NodeRef record : records)
|
||||
{
|
||||
if (!nodeService.hasAspect(record, ASPECT_DISPOSITION_LIFECYCLE))
|
||||
{
|
||||
if (recordFolder.equals(nodeService.getPrimaryParent(record).getParentRef()))
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.info("updating record: " + record);
|
||||
}
|
||||
|
||||
// update record disposition information
|
||||
dispositionService.updateNextDispositionAction(record, schedule);
|
||||
innerRecordCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return innerRecordCount;
|
||||
}
|
||||
});
|
||||
nodeService.addAspect(recordFolder, ASPECT_DISPOSITION_PROCESSED, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
behaviourFilter.enableBehaviour(ASPECT_FILE_PLAN_COMPONENT);
|
||||
}
|
||||
return recordCount;
|
||||
}
|
||||
}, false, true);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user