mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge branch 'release/V3.2' into merge/RM-7060_FixSearchAspect
This commit is contained in:
@@ -732,6 +732,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>
|
||||
|
@@ -16,5 +16,5 @@
|
||||
<property name="filePlanService" ref="filePlanService"/>
|
||||
<property name="nodeService" ref="nodeService"/>
|
||||
</bean>
|
||||
|
||||
|
||||
</beans>
|
@@ -3,16 +3,30 @@
|
||||
|
||||
<mapper namespace="alfresco.query.rm">
|
||||
|
||||
<parameterMap id="parameter_CountRMIndentifier" type="map">
|
||||
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="idValue" jdbcType="BIGINT" javaType="java.lang.String"/>
|
||||
</parameterMap>
|
||||
<parameterMap id="parameter_CountRMIndentifier" type="map">
|
||||
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="idValue" jdbcType="BIGINT" javaType="java.lang.String"/>
|
||||
</parameterMap>
|
||||
|
||||
<resultMap id="result_NodeIds" type="java.lang.Long">
|
||||
<result property="node.id" column="node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
</resultMap>
|
||||
|
||||
<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>
|
||||
|
||||
<resultMap id="result_NodeIds" type="java.lang.Long">
|
||||
<result property="node.id" column="node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="select_CountRMIndentifier" parameterMap="parameter_CountRMIndentifier" resultType="java.lang.Integer">
|
||||
select
|
||||
count(*)
|
||||
from
|
||||
@@ -21,7 +35,7 @@
|
||||
where
|
||||
prop.qname_id = ? and
|
||||
prop.string_value = ?
|
||||
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Get distinct property values of children for a given property qname -->
|
||||
@@ -39,10 +53,10 @@
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Get list of node ids which reference given content url -->
|
||||
<select id="select_NodeIdsWhichReferenceContentUrl"
|
||||
parameterType="ContentUrl"
|
||||
resultMap="result_NodeIds">
|
||||
<!-- Get list of node ids which reference given content url -->
|
||||
<select id="select_NodeIdsWhichReferenceContentUrl"
|
||||
parameterType="ContentUrl"
|
||||
resultMap="result_NodeIds">
|
||||
select
|
||||
p.node_id
|
||||
from
|
||||
@@ -55,5 +69,19 @@
|
||||
|
||||
</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>
|
||||
|
||||
</mapper>
|
||||
|
@@ -680,4 +680,21 @@
|
||||
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" />
|
||||
<property name="frozenAspect" ref="rma.freeze"/>
|
||||
<property name="recordsManagementSearchBehaviour" ref="recordsManagementSearchBehaviour"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
@@ -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.
|
||||
*
|
||||
|
@@ -977,8 +977,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;
|
||||
@@ -997,7 +1025,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;
|
||||
|
||||
@@ -1013,14 +1041,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
|
||||
|
@@ -288,9 +288,9 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
||||
QName PROP_COUNT = QName.createQName(RM_URI, "count");
|
||||
|
||||
QName ASPECT_SAVED_SEARCH = QName.createQName(RM_URI, "savedSearch");
|
||||
|
||||
//Workaround for RM-6788
|
||||
String GL_URI = "http://www.alfresco.org/model/glacier/1.0";
|
||||
QName ASPECT_ARCHIVED = QName.createQName(GL_URI, "archived");
|
||||
|
||||
QName ASPECT_DISPOSITION_PROCESSED = QName.createQName(RM_URI, "dispositionProcessed");
|
||||
}
|
||||
|
@@ -50,9 +50,12 @@ import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordDefinition;
|
||||
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.transaction.TransactionalResourceHelper;
|
||||
@@ -74,7 +77,8 @@ import org.apache.commons.logging.LogFactory;
|
||||
* @author Roy Wetherall
|
||||
* @since 1.0
|
||||
*/
|
||||
public class RecordsManagementSearchBehaviour implements RecordsManagementModel
|
||||
public class RecordsManagementSearchBehaviour implements RecordsManagementModel,
|
||||
NodeServicePolicies.OnMoveNodePolicy
|
||||
{
|
||||
/** logger */
|
||||
private static Log logger = LogFactory.getLog(RecordsManagementSearchBehaviour.class);
|
||||
@@ -187,6 +191,9 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
|
||||
private JavaBehaviour jbEventExecutionUpdate = new JavaBehaviour(this, "eventExecutionUpdate", NotificationFrequency.TRANSACTION_COMMIT);
|
||||
private JavaBehaviour jbEventExecutionDelete = new JavaBehaviour(this, "eventExecutionDelete", NotificationFrequency.TRANSACTION_COMMIT);
|
||||
|
||||
/** on move record or record folder behavior */
|
||||
private JavaBehaviour jbMoveNode = new JavaBehaviour(this, "onMoveNode", NotificationFrequency.TRANSACTION_COMMIT);
|
||||
|
||||
/** Array of behaviours related to disposition schedule artifacts */
|
||||
private JavaBehaviour[] jbDispositionBehaviours =
|
||||
{
|
||||
@@ -263,6 +270,11 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
ASPECT_VITAL_RECORD_DEFINITION,
|
||||
new JavaBehaviour(this, "vitalRecordDefintionUpdateProperties", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"),
|
||||
ASPECT_FILE_PLAN_COMPONENT,
|
||||
jbMoveNode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -976,4 +988,37 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record and record folder move behavior
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy#onMoveNode(org.alfresco.service.cmr.repository.ChildAssociationRef, org.alfresco.service.cmr.repository.ChildAssociationRef)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef)
|
||||
{
|
||||
// check the parent has actually changed
|
||||
if (!oldChildAssocRef.getParentRef().equals(newChildAssocRef.getParentRef()))
|
||||
{
|
||||
final NodeRef recordOrFolder = newChildAssocRef.getChildRef();
|
||||
final boolean isRecordOrFolder = recordService.isRecord(recordOrFolder) || recordFolderService.isRecordFolder(recordOrFolder);
|
||||
AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork()
|
||||
{
|
||||
if (nodeService.exists(recordOrFolder) && isRecordOrFolder)
|
||||
{
|
||||
applySearchAspect(recordOrFolder);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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,9 +27,11 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.query;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import java.util.Collection;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
@@ -54,6 +56,17 @@ public interface RecordsManagementQueryDAO
|
||||
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);
|
||||
|
||||
/**
|
||||
* Returns whether a given node contains children with one of the given values for the given property
|
||||
* Returns distinct property values from children for the given property
|
||||
*
|
||||
* @param parent the parent to evaluate
|
||||
@@ -63,7 +76,7 @@ public interface RecordsManagementQueryDAO
|
||||
public Set<String> getChildrenStringPropertyValues(NodeRef parent, QName property);
|
||||
|
||||
/**
|
||||
* @param contentUrl the URL of the content url entity
|
||||
* @param contentUrl the URL of the content url entity
|
||||
* @return Set<NodeRef> a set of nodes that reference the given content url
|
||||
*/
|
||||
Set<NodeRef> getNodeRefsWhichReferenceContentUrl(String contentUrl);
|
||||
|
@@ -27,8 +27,11 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.query;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -56,33 +59,43 @@ import org.mybatis.spring.SqlSessionTemplate;
|
||||
*/
|
||||
public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO, RecordsManagementModel
|
||||
{
|
||||
/** logger */
|
||||
@SuppressWarnings ("unused")
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static final Log logger = LogFactory.getLog(RecordsManagementQueryDAOImpl.class);
|
||||
|
||||
/** query names */
|
||||
/**
|
||||
* query names
|
||||
*/
|
||||
private static final String COUNT_IDENTIFIER = "alfresco.query.rm.select_CountRMIndentifier";
|
||||
private static final String GET_CHILDREN_PROPERTY_VALUES = "select_GetStringPropertyValuesOfChildren";
|
||||
private static final String SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL = "select_NodeIdsWhichReferenceContentUrl";
|
||||
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 */
|
||||
/**
|
||||
* SQL session template
|
||||
*/
|
||||
protected SqlSessionTemplate template;
|
||||
|
||||
/** QName DAO */
|
||||
|
||||
/**
|
||||
* QName DAO
|
||||
*/
|
||||
protected QNameDAO qnameDAO;
|
||||
protected NodeDAO nodeDAO;
|
||||
protected TenantService tenantService;
|
||||
|
||||
|
||||
/**
|
||||
* @param sqlSessionTemplate SQL session template
|
||||
* @param sqlSessionTemplate SQL session template
|
||||
*/
|
||||
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
|
||||
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
|
||||
{
|
||||
this.template = sqlSessionTemplate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param qnameDAO qname DAO
|
||||
* @param qnameDAO qname DAO
|
||||
*/
|
||||
public final void setQnameDAO(QNameDAO qnameDAO)
|
||||
{
|
||||
@@ -106,25 +119,25 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
|
||||
public int getCountRmaIdentifier(String identifierValue)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
|
||||
// lookup the id of the identifier property qname
|
||||
Pair<Long, QName> pair = qnameDAO.getQName(PROP_IDENTIFIER);
|
||||
if (pair != null)
|
||||
{
|
||||
{
|
||||
// create query params
|
||||
Map<String, Object> params = new HashMap<>(2);
|
||||
params.put("qnameId", pair.getFirst());
|
||||
params.put("idValue", identifierValue);
|
||||
|
||||
|
||||
// return the number of rma identifiers found that match the passed value
|
||||
Integer count = (Integer)template.selectOne(COUNT_IDENTIFIER, params);
|
||||
|
||||
Integer count = (Integer) template.selectOne(COUNT_IDENTIFIER, params);
|
||||
|
||||
if (count != null)
|
||||
{
|
||||
result = count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -158,8 +171,8 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
|
||||
/**
|
||||
* Get a set of node reference which reference the provided content URL
|
||||
*
|
||||
* @param String contentUrl content URL
|
||||
* @return Set<NodeRef> set of nodes that reference the provided content URL
|
||||
* @param String contentUrl content URL
|
||||
*/
|
||||
@Override
|
||||
public Set<NodeRef> getNodeRefsWhichReferenceContentUrl(String contentUrl)
|
||||
@@ -208,14 +221,16 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logMessage.append(nodeRefToAdd).append(" (from version)");
|
||||
logMessage.append(nodeRefToAdd)
|
||||
.append(" (from version)");
|
||||
}
|
||||
}
|
||||
|
||||
// add the node ref of the referencing node
|
||||
else
|
||||
{
|
||||
nodeRefToAdd = nodeDAO.getNodeIdStatus(nodeId).getNodeRef();
|
||||
nodeRefToAdd = nodeDAO.getNodeIdStatus(nodeId)
|
||||
.getNodeRef();
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logMessage.append(nodeRefToAdd);
|
||||
@@ -240,4 +255,33 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
|
||||
|
||||
return nodesReferencingContentUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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,443 @@
|
||||
/*
|
||||
* #%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.model.behaviour.RecordsManagementSearchBehaviour;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.rma.aspect.FrozenAspect;
|
||||
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;
|
||||
private FrozenAspect frozenAspect;
|
||||
private RecordsManagementSearchBehaviour recordsManagementSearchBehaviour;
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public void setFrozenAspect(FrozenAspect frozenAspect)
|
||||
{
|
||||
this.frozenAspect = frozenAspect;
|
||||
}
|
||||
|
||||
public void setRecordsManagementSearchBehaviour(RecordsManagementSearchBehaviour recordsManagementSearchBehaviour)
|
||||
{
|
||||
this.recordsManagementSearchBehaviour = recordsManagementSearchBehaviour;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
frozenAspect.disableOnPropUpdateFrozenAspect();
|
||||
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);
|
||||
recordsManagementSearchBehaviour.onAddDispositionLifecycleAspect(record,null);
|
||||
innerRecordCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return innerRecordCount;
|
||||
}
|
||||
});
|
||||
nodeService.addAspect(recordFolder, ASPECT_DISPOSITION_PROCESSED, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
frozenAspect.enableOnPropUpdateFrozenAspect();
|
||||
}
|
||||
return recordCount;
|
||||
}
|
||||
}, false, true);
|
||||
}
|
||||
}
|
@@ -120,7 +120,7 @@ public class MoveRecordTest extends BaseRMTestCase
|
||||
assertNull(dispositionService.getNextDispositionAction(record));
|
||||
|
||||
// check the search aspect properties
|
||||
assertFalse(nodeService.hasAspect(record, ASPECT_RM_SEARCH));
|
||||
assertTrue(nodeService.hasAspect(record, ASPECT_RM_SEARCH));
|
||||
|
||||
}
|
||||
});
|
||||
|
@@ -218,7 +218,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase
|
||||
assertNull(dispositionService.getNextDispositionAction(recordFolder));
|
||||
|
||||
// check the search aspect properties
|
||||
assertFalse(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH));
|
||||
assertTrue(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user