mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-4689 (Can delete all RM site content through Repository browser)
Manually backported following changes: RM-4293734c1b2a82
RM-4326a4aac053a8
c6ca74ab26
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -38,3 +38,6 @@ test-output
|
||||
/rm-enterprise/rm-automation-enterprise/root
|
||||
|
||||
rm-automation/src/test/resources/webdriver.properties
|
||||
|
||||
/rm-community/rm-community-rest-api-explorer/overlays
|
||||
/rm-enterprise/rm-enterprise-rest-api-explorer/overlays
|
@@ -94,4 +94,35 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="rmDeleteTransferContainerCapability"
|
||||
parent="declarativeCapability">
|
||||
<property name="name" value="DeleteTransferContainer"/>
|
||||
<property name="kinds">
|
||||
<list>
|
||||
<value>TRANSFER_CONTAINER</value>
|
||||
</list>
|
||||
</property>
|
||||
<property name="conditions">
|
||||
<map>
|
||||
<entry key="capabilityCondition.filling" value="true"/>
|
||||
</map>
|
||||
</property>
|
||||
<property name="private" value="true"/>
|
||||
</bean>
|
||||
|
||||
<bean id="rmDeleteHoldContainerCapability"
|
||||
parent="declarativeCapability">
|
||||
<property name="name" value="DeleteHoldContainer"/>
|
||||
<property name="kinds">
|
||||
<list>
|
||||
<value>HOLD_CONTAINER</value>
|
||||
</list>
|
||||
</property>
|
||||
<property name="conditions">
|
||||
<map>
|
||||
<entry key="capabilityCondition.filling" value="true"/>
|
||||
</map>
|
||||
</property>
|
||||
<property name="private" value="true"/>
|
||||
</bean>
|
||||
</beans>
|
@@ -25,6 +25,8 @@
|
||||
<ref bean="rmDeleteUnfiledRecordsContainerFolderCapability"/>
|
||||
<ref bean="rmDeleteHoldCapability"/>
|
||||
<ref bean="rmUnlinkFromRecordFolderCapability"/>
|
||||
<ref bean="rmDeleteTransferContainerCapability"/>
|
||||
<ref bean="rmDeleteHoldContainerCapability"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
@@ -76,6 +76,9 @@
|
||||
<property name="filePlanService" ref="FilePlanService" />
|
||||
<property name="recordFolderService" ref="RecordFolderService" />
|
||||
<property name="filePlanRoleService" ref="FilePlanRoleService" />
|
||||
<property name="unfilerRecordContainerType" ref="rma.unfiledRecordsContainer"/>
|
||||
<property name="transferContainerType" ref="rma.transferContainer"/>
|
||||
<property name="holdContainerType" ref="rma.holdContainer"/>
|
||||
</bean>
|
||||
|
||||
<bean id="rma.holdContainer" class="org.alfresco.module.org_alfresco_module_rm.model.rma.type.HoldContainerType" parent="rm.baseBehaviour">
|
||||
@@ -84,6 +87,14 @@
|
||||
<bean id="rma.transferContainer" class="org.alfresco.module.org_alfresco_module_rm.model.rma.type.TransferContainerType" parent="rm.baseBehaviour">
|
||||
</bean>
|
||||
|
||||
<bean id="rma.transfer" class="org.alfresco.module.org_alfresco_module_rm.model.rma.type.TransferType"
|
||||
parent="rm.baseBehaviour"/>
|
||||
|
||||
<bean id="rma.unfiledRecordsContainer" class="org.alfresco.module.org_alfresco_module_rm.model.rma.type.UnfiledRecordContainerType" parent="rm.baseBehaviour">
|
||||
</bean>
|
||||
|
||||
<bean id="rma.unfiledRecordFolder" class="org.alfresco.module.org_alfresco_module_rm.model.rma.type.UnfiledRecordFolderType" parent="rm.baseBehaviour"/>
|
||||
|
||||
<bean id="rma.recordCategory" class="org.alfresco.module.org_alfresco_module_rm.model.rma.type.RecordCategoryType" parent="rm.baseBehaviour">
|
||||
<property name="vitalRecordService" ref="VitalRecordService" />
|
||||
<property name="filePlanPermissionService" ref="FilePlanPermissionService" />
|
||||
@@ -105,6 +116,7 @@
|
||||
<property name="recordsManagementSearchService" ref="RecordsManagementSearchService" />
|
||||
<property name="capabilityService" ref="CapabilityService" />
|
||||
<property name="authorityService" ref="AuthorityService" />
|
||||
<property name="filePlanType" ref="rma.filePlan"/>
|
||||
</bean>
|
||||
|
||||
<!-- rma model aspects -->
|
||||
|
@@ -173,6 +173,8 @@
|
||||
<property name="recordFolderService" ref="RecordFolderService" />
|
||||
<property name="nodeService" ref="nodeService"/>
|
||||
<property name="freezeService" ref="FreezeService"/>
|
||||
<property name="transferContainerType" ref="rma.transferContainer"/>
|
||||
<property name="transferType" ref="rma.transfer"/>
|
||||
</bean>
|
||||
|
||||
<bean id="RmTransferService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
|
@@ -27,15 +27,20 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.model;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
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.util.ServiceBaseImpl;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Convenient base class for behaviour beans.
|
||||
@@ -50,6 +55,12 @@ public abstract class BaseBehaviourBean extends ServiceBaseImpl
|
||||
/** Logger */
|
||||
protected static final Log LOGGER = LogFactory.getLog(BaseBehaviourBean.class);
|
||||
|
||||
/**
|
||||
* I18N
|
||||
*/
|
||||
protected static final String UNIQUE_CHILD_TYPE_ERROR = "rm.action.unique.child.type-error-message";
|
||||
protected static final String MULTIPLE_CHILDREN_TYPE_ERROR = "rm.action.multiple.children.type-error-message";
|
||||
|
||||
/** behaviour filter */
|
||||
protected BehaviourFilter behaviourFilter;
|
||||
|
||||
@@ -87,4 +98,52 @@ public abstract class BaseBehaviourBean extends ServiceBaseImpl
|
||||
return behaviours.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that checks if the newly created child association complies with the RM rules
|
||||
*
|
||||
* @param parent the parent node
|
||||
* @param childType the child node
|
||||
* @param acceptedUniqueChildType a list of node types that are accepted as children of the provided parent only once
|
||||
* @param acceptedMultipleChildType a list of node types that are accepted as children of the provided parent multiple times
|
||||
* @throws IntegrityException if the child association doesn't comply with the RM rules
|
||||
*/
|
||||
protected void validateNewChildAssociation(NodeRef parent, NodeRef child, List<QName> acceptedUniqueChildType, List<QName> acceptedMultipleChildType) throws IntegrityException
|
||||
{
|
||||
QName childType = getInternalNodeService().getType(child);
|
||||
if (acceptedUniqueChildType.contains(childType))
|
||||
{
|
||||
// check the user is not trying to create multiple children of a type that is only accepted once
|
||||
if (nodeService.getChildAssocs(parent, Sets.newHashSet(childType))
|
||||
.size() > 1)
|
||||
{
|
||||
throw new IntegrityException(I18NUtil.getMessage(UNIQUE_CHILD_TYPE_ERROR), null);
|
||||
}
|
||||
}
|
||||
else if (!acceptedMultipleChildType.contains(childType))
|
||||
{
|
||||
throw new IntegrityException(I18NUtil.getMessage(MULTIPLE_CHILDREN_TYPE_ERROR, childType), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that checks if the newly created child association is between the sub-types of accepted types.
|
||||
*
|
||||
* @param child the child node
|
||||
* @param acceptedMultipleChildType a list of node types that are accepted as children of the provided parent multiple times
|
||||
* @throws IntegrityException if the child association isn't between the sub-types of accepted types
|
||||
*/
|
||||
protected void validateNewChildAssociationSubTypesIncluded(NodeRef child, List<QName> acceptedMultipleChildType)
|
||||
throws IntegrityException
|
||||
{
|
||||
QName childType = getInternalNodeService().getType(child);
|
||||
for (QName type : acceptedMultipleChildType)
|
||||
{
|
||||
if (instanceOf(childType, type))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
//no match was found in sub-types of permitted types list
|
||||
throw new IntegrityException(I18NUtil.getMessage(MULTIPLE_CHILDREN_TYPE_ERROR, childType), null);
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,8 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.model.rma.type;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService;
|
||||
@@ -36,6 +37,7 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
@@ -45,6 +47,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* rma:filePlan behaviour bean
|
||||
@@ -59,8 +62,13 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
public class FilePlanType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||
NodeServicePolicies.OnCreateNodePolicy,
|
||||
NodeServicePolicies.OnDeleteNodePolicy
|
||||
NodeServicePolicies.OnDeleteNodePolicy,
|
||||
NodeServicePolicies.BeforeDeleteNodePolicy
|
||||
{
|
||||
private final static List<QName> ACCEPTED_UNIQUE_CHILD_TYPES = Arrays.asList(TYPE_HOLD_CONTAINER, TYPE_TRANSFER_CONTAINER, TYPE_UNFILED_RECORD_CONTAINER);
|
||||
private final static List<QName> ACCEPTED_NON_UNIQUE_CHILD_TYPES = Arrays.asList(TYPE_RECORD_CATEGORY);
|
||||
private static final String BEHAVIOUR_NAME = "onDeleteFilePlan";
|
||||
|
||||
/** file plan service */
|
||||
private FilePlanService filePlanService;
|
||||
|
||||
@@ -73,6 +81,21 @@ public class FilePlanType extends BaseBehaviourBean
|
||||
/** file plan role service */
|
||||
private FilePlanRoleService filePlanRoleService;
|
||||
|
||||
/**
|
||||
* Unfiled Record Container Type behaviour bean
|
||||
*/
|
||||
private UnfiledRecordContainerType unfilerRecordContainerType;
|
||||
|
||||
/**
|
||||
* Transfer Container Type behaviour bean
|
||||
*/
|
||||
private TransferContainerType transferContainerType;
|
||||
|
||||
/**
|
||||
* Hold Container Type behaviour bean
|
||||
*/
|
||||
private HoldContainerType holdContainerType;
|
||||
|
||||
/**
|
||||
* @return File plan service
|
||||
*/
|
||||
@@ -137,6 +160,46 @@ public class FilePlanType extends BaseBehaviourBean
|
||||
this.filePlanRoleService = filePlanRoleService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param unfilerRecordContainerType - unfiled record container type behaviour bean
|
||||
*/
|
||||
public void setUnfilerRecordContainerType(UnfiledRecordContainerType unfilerRecordContainerType)
|
||||
{
|
||||
this.unfilerRecordContainerType = unfilerRecordContainerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param transferContainerType - transfer container type behaviour bean
|
||||
*/
|
||||
public void setTransferContainerType(TransferContainerType transferContainerType)
|
||||
{
|
||||
this.transferContainerType = transferContainerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param holdContainerType - hold container type behaviour bean
|
||||
*/
|
||||
public void setHoldContainerType(HoldContainerType holdContainerType)
|
||||
{
|
||||
this.holdContainerType = holdContainerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the behaviours for this transaction
|
||||
*/
|
||||
public void disable()
|
||||
{
|
||||
getBehaviour(BEHAVIOUR_NAME).disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable behaviours for this transaction
|
||||
*/
|
||||
public void enable()
|
||||
{
|
||||
getBehaviour(BEHAVIOUR_NAME).enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@@ -147,20 +210,17 @@ public class FilePlanType extends BaseBehaviourBean
|
||||
@Override
|
||||
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean bNew)
|
||||
{
|
||||
// ensure we are not trying to put content in the file plan root node
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT))
|
||||
// We need to automatically cast the created folder to category if it is a plain folder
|
||||
// This occurs if the RM folder has been created via IMap, WebDav, etc. Don't check subtypes.
|
||||
// Some modules use hidden files to store information (see RM-3283)
|
||||
if (nodeService.getType(childAssocRef.getChildRef())
|
||||
.equals(ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Operation failed, because you can't place content in the root of the file plan.");
|
||||
}
|
||||
|
||||
// ensure we are not trying to put a record folder in the root of the file plan
|
||||
NodeRef parent = childAssocRef.getParentRef();
|
||||
if (getFilePlanService().isFilePlan(parent) && getRecordFolderService().isRecordFolder(nodeRef))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Operation failed, because you can not place a record folder in the root of the file plan.");
|
||||
nodeService.setType(childAssocRef.getChildRef(), TYPE_RECORD_CATEGORY);
|
||||
}
|
||||
|
||||
// check the created child is of an accepted type
|
||||
validateNewChildAssociation(childAssocRef.getParentRef(), childAssocRef.getChildRef(), ACCEPTED_UNIQUE_CHILD_TYPES, ACCEPTED_NON_UNIQUE_CHILD_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,15 +261,40 @@ public class FilePlanType extends BaseBehaviourBean
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnDeleteNodePolicy#onDeleteNode(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.FIRST_EVENT,
|
||||
name = BEHAVIOUR_NAME)
|
||||
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean archived)
|
||||
{
|
||||
unfilerRecordContainerType.enable();
|
||||
transferContainerType.enable();
|
||||
holdContainerType.enable();
|
||||
throw new IntegrityException("Operation failed. Deletion of File Plan is not allowed.", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.FIRST_EVENT)
|
||||
public void beforeDeleteNode(NodeRef nodeRef)
|
||||
{
|
||||
unfilerRecordContainerType.disable();
|
||||
transferContainerType.disable();
|
||||
holdContainerType.disable();
|
||||
}
|
||||
|
||||
@Behaviour(kind = BehaviourKind.CLASS,
|
||||
policy = "alf:onDeleteNode",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT)
|
||||
public void onDeleteNodeOnCommit(ChildAssociationRef childAssocRef, boolean archived)
|
||||
{
|
||||
// tear down the file plan roles
|
||||
getFilePlanRoleService().tearDownFilePlanRoles(childAssocRef.getChildRef());
|
||||
unfilerRecordContainerType.enable();
|
||||
transferContainerType.enable();
|
||||
holdContainerType.enable();
|
||||
}
|
||||
}
|
||||
|
@@ -26,15 +26,19 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.model.rma.type;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
@@ -45,9 +49,29 @@ import org.springframework.extensions.surf.util.I18NUtil;
|
||||
*/
|
||||
@BehaviourBean(defaultType = "rma:holdContainer")
|
||||
public class HoldContainerType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy, NodeServicePolicies.OnCreateNodePolicy
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||
NodeServicePolicies.OnCreateNodePolicy,
|
||||
NodeServicePolicies.OnDeleteNodePolicy
|
||||
{
|
||||
private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container";
|
||||
private final static List<QName> ACCEPTED_NON_UNIQUE_CHILD_TYPES = Arrays.asList(TYPE_HOLD);
|
||||
private static final String DELETE_BEHAVIOUR_NAME = "onDeleteHoldContainer";
|
||||
|
||||
/**
|
||||
* Disable the behaviours for this transaction
|
||||
*/
|
||||
public void disable()
|
||||
{
|
||||
getBehaviour(DELETE_BEHAVIOUR_NAME).disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable behaviours for this transaction
|
||||
*/
|
||||
public void enable()
|
||||
{
|
||||
getBehaviour(DELETE_BEHAVIOUR_NAME).enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* On every event
|
||||
@@ -59,11 +83,8 @@ public class HoldContainerType extends BaseBehaviourBean
|
||||
@Behaviour(kind = BehaviourKind.ASSOCIATION)
|
||||
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean bNew)
|
||||
{
|
||||
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true) { throw new AlfrescoRuntimeException(
|
||||
I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
|
||||
|
||||
// check the created child is of an accepted type
|
||||
validateNewChildAssociationSubTypesIncluded(childAssocRef.getChildRef(), ACCEPTED_NON_UNIQUE_CHILD_TYPES);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,4 +95,12 @@ public class HoldContainerType extends BaseBehaviourBean
|
||||
I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.CLASS,
|
||||
name = DELETE_BEHAVIOUR_NAME)
|
||||
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isNodeArchived)
|
||||
{
|
||||
throw new IntegrityException("Operation failed. Deletion of Hold Container is not allowed.", null);
|
||||
}
|
||||
}
|
||||
|
@@ -27,6 +27,9 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.model.rma.type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
|
||||
@@ -62,6 +65,9 @@ public class RecordCategoryType extends BaseBehaviourBean
|
||||
NodeServicePolicies.OnCreateNodePolicy,
|
||||
NodeServicePolicies.OnMoveNodePolicy
|
||||
{
|
||||
private final static List<QName> ACCEPTED_UNIQUE_CHILD_TYPES = new ArrayList<QName>();
|
||||
private final static List<QName> ACCEPTED_NON_UNIQUE_CHILD_TYPES = Arrays.asList(TYPE_RECORD_CATEGORY, TYPE_RECORD_FOLDER);
|
||||
|
||||
/** vital record service */
|
||||
protected VitalRecordService vitalRecordService;
|
||||
|
||||
@@ -107,17 +113,22 @@ public class RecordCategoryType extends BaseBehaviourBean
|
||||
)
|
||||
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean bNew)
|
||||
{
|
||||
// ensure content is not placed directly into a record category
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT))
|
||||
QName childType = nodeService.getType(childAssocRef.getChildRef());
|
||||
|
||||
// We need to automatically cast the created folder to record folder if it is a plain folder
|
||||
// This occurs if the RM folder has been created via IMap, WebDav, etc. Don't check subtypes.
|
||||
// Some modules use hidden folders to store information (see RM-3283).
|
||||
if (childType.equals(ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Operation failed, because you can't place content directly into a record category.");
|
||||
nodeService.setType(childAssocRef.getChildRef(), TYPE_RECORD_FOLDER);
|
||||
}
|
||||
|
||||
validateNewChildAssociation(childAssocRef.getParentRef(), childAssocRef.getChildRef(), ACCEPTED_UNIQUE_CHILD_TYPES, ACCEPTED_NON_UNIQUE_CHILD_TYPES);
|
||||
|
||||
if (bNew)
|
||||
{
|
||||
// setup the record folder
|
||||
recordFolderService.setupRecordFolder(nodeRef);
|
||||
recordFolderService.setupRecordFolder(childAssocRef.getChildRef());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -27,15 +27,20 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.model.rma.type;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
|
||||
import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
@@ -54,6 +59,7 @@ import org.alfresco.service.cmr.site.SiteVisibility;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Behaviour associated with the RM Site type
|
||||
@@ -68,12 +74,14 @@ import org.alfresco.util.PropertyMap;
|
||||
public class RmSiteType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateNodePolicy,
|
||||
NodeServicePolicies.OnUpdatePropertiesPolicy,
|
||||
NodeServicePolicies.BeforeDeleteNodePolicy
|
||||
NodeServicePolicies.BeforeDeleteNodePolicy,
|
||||
NodeServicePolicies.OnCreateChildAssociationPolicy
|
||||
{
|
||||
/** Constant values */
|
||||
public static final String COMPONENT_DOCUMENT_LIBRARY = "documentLibrary";
|
||||
public static final String DEFAULT_SITE_NAME = "rm";
|
||||
public static final QName DEFAULT_FILE_PLAN_TYPE = TYPE_FILE_PLAN;
|
||||
private final static List<QName> ACCEPTED_NON_UNIQUE_CHILD_TYPES = Arrays.asList(ContentModel.TYPE_FOLDER);
|
||||
|
||||
/** Site service */
|
||||
protected SiteService siteService;
|
||||
@@ -87,6 +95,8 @@ public class RmSiteType extends BaseBehaviourBean
|
||||
/** Authority service */
|
||||
private AuthorityService authorityService;
|
||||
|
||||
private FilePlanType filePlanType;
|
||||
|
||||
/** Map of file plan type's key'ed by corresponding site types */
|
||||
protected Map<QName, QName> mapFilePlanType = new HashMap<QName, QName>(3);
|
||||
|
||||
@@ -123,6 +133,11 @@ public class RmSiteType extends BaseBehaviourBean
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
public void setFilePlanType(FilePlanType filePlanType)
|
||||
{
|
||||
this.filePlanType = filePlanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a file plan type for a specific site type.
|
||||
*
|
||||
@@ -292,7 +307,63 @@ public class RmSiteType extends BaseBehaviourBean
|
||||
return null;
|
||||
}
|
||||
});
|
||||
filePlanType.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the limitation of creating only one rma:filePlan or one dod:filePlan depending on the type of rm site.
|
||||
* Also added the limitation of crating two cm:folder type under rm site.
|
||||
* Other than this nothing can be created under rm site nodeRef
|
||||
*
|
||||
* @author Silviu Dinuta
|
||||
* @since 2.6
|
||||
*/
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.ASSOCIATION)
|
||||
public void onCreateChildAssociation(final ChildAssociationRef childAssocRef, boolean isNewNode)
|
||||
{
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork()
|
||||
{
|
||||
final NodeRef child = childAssocRef.getChildRef();
|
||||
final NodeRef parent = childAssocRef.getParentRef();
|
||||
List<QName> acceptedUniqueChildTypes = new ArrayList<QName>();
|
||||
SiteInfo siteInfo = siteService.getSite(parent);
|
||||
acceptedUniqueChildTypes.add(getFilePlanType(siteInfo));
|
||||
// check the created child is of an accepted type
|
||||
validateNewChildAssociation(parent, child, acceptedUniqueChildTypes, ACCEPTED_NON_UNIQUE_CHILD_TYPES);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden this because in this case we need to have multiple cm:folder types but not more than two of them.
|
||||
* The two mentioned folders are created when rm site is created and one of them is Saved Searches and the other surf-config folder.
|
||||
* After that creation of cm:folder should not be allowed under rm site node
|
||||
*/
|
||||
@Override
|
||||
protected void validateNewChildAssociation(NodeRef parent, NodeRef child, List<QName> acceptedUniqueChildType,
|
||||
List<QName> acceptedMultipleChildType) throws IntegrityException
|
||||
{
|
||||
super.validateNewChildAssociation(parent, child, acceptedUniqueChildType, acceptedMultipleChildType);
|
||||
|
||||
// check the user is not trying to create more than 2 folders that are created by default.
|
||||
if (nodeService.getChildAssocs(parent, Sets.newHashSet(ContentModel.TYPE_FOLDER)).size() > 2)
|
||||
{
|
||||
throw new IntegrityException(I18NUtil.getMessage(MULTIPLE_CHILDREN_TYPE_ERROR, ContentModel.TYPE_FOLDER), null);
|
||||
}
|
||||
}
|
||||
|
||||
@Behaviour(kind = BehaviourKind.CLASS,
|
||||
policy = "alf:onDeleteNode",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT)
|
||||
public void onDeleteNodeOnCommit(ChildAssociationRef childAssocRef, boolean isNodeArchived)
|
||||
{
|
||||
filePlanType.enable();
|
||||
}
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
@@ -45,31 +46,61 @@ import org.springframework.extensions.surf.util.I18NUtil;
|
||||
*/
|
||||
@BehaviourBean(defaultType = "rma:transferContainer")
|
||||
public class TransferContainerType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy, NodeServicePolicies.OnCreateNodePolicy
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||
NodeServicePolicies.OnCreateNodePolicy,
|
||||
NodeServicePolicies.OnDeleteNodePolicy
|
||||
{
|
||||
private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container";
|
||||
private final static String MSG_ERROR_ADD_CHILD_TO_TRANSFER_CONTAINER = "rm.action.create.transfer.container.child-error-message";
|
||||
private static final String BEHAVIOUR_NAME = "onCreateChildAssocsForTransferContainer";
|
||||
private static final String DELETE_BEHAVIOUR_NAME = "onDeleteTransferContainer";
|
||||
|
||||
/**
|
||||
* On every event
|
||||
* Disable the behaviours for this transaction
|
||||
*/
|
||||
public void disable()
|
||||
{
|
||||
getBehaviour(BEHAVIOUR_NAME).disable();
|
||||
getBehaviour(DELETE_BEHAVIOUR_NAME).disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable behaviours for this transaction
|
||||
*/
|
||||
public void enable()
|
||||
{
|
||||
getBehaviour(BEHAVIOUR_NAME).enable();
|
||||
getBehaviour(DELETE_BEHAVIOUR_NAME).enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent creating a node inside transfer container, this will be possible only through internal services in a controlled manner.
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef,
|
||||
* boolean)
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, * boolean)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.ASSOCIATION)
|
||||
@Behaviour(kind = BehaviourKind.ASSOCIATION,
|
||||
name = BEHAVIOUR_NAME)
|
||||
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean bNew)
|
||||
{
|
||||
// ensure not content to be added in Holdsfolder
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true) { throw new AlfrescoRuntimeException(
|
||||
I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
|
||||
throw new IntegrityException(I18NUtil.getMessage(MSG_ERROR_ADD_CHILD_TO_TRANSFER_CONTAINER), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateNode(ChildAssociationRef childAssocRef)
|
||||
{
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true) { throw new AlfrescoRuntimeException(
|
||||
I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
|
||||
if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.CLASS,
|
||||
name = DELETE_BEHAVIOUR_NAME)
|
||||
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isNodeArchived)
|
||||
{
|
||||
throw new IntegrityException("Operation failed. Deletion of Transfer Container is not allowed.", null);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 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.model.rma.type;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* rma:transfer behaviour bean
|
||||
*
|
||||
* @author Silviu Dinuta
|
||||
* @since 2.6
|
||||
*/
|
||||
@BehaviourBean(defaultType = "rma:transfer")
|
||||
public class TransferType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy
|
||||
{
|
||||
private final static String MSG_ERROR_ADD_CHILD_TO_TRANSFER = "rm.action.create.transfer.child-error-message";
|
||||
|
||||
private static final String CREATE_CHILD_BEHAVIOUR_NAME = "onCreateChildAssocsForTransferType";
|
||||
|
||||
/**
|
||||
* Disable the behaviours for this transaction
|
||||
*/
|
||||
public void disable()
|
||||
{
|
||||
getBehaviour(CREATE_CHILD_BEHAVIOUR_NAME).disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable behaviours for this transaction
|
||||
*/
|
||||
public void enable()
|
||||
{
|
||||
getBehaviour(CREATE_CHILD_BEHAVIOUR_NAME).enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent creating a node inside transfer folder, this will be possible only through internal services in a controlled manner.
|
||||
*/
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.ASSOCIATION,
|
||||
name = CREATE_CHILD_BEHAVIOUR_NAME)
|
||||
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode)
|
||||
{
|
||||
throw new IntegrityException(I18NUtil.getMessage(MSG_ERROR_ADD_CHILD_TO_TRANSFER), null);
|
||||
}
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 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.model.rma.type;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* rma:unfiledRecordContainer behaviour bean
|
||||
*
|
||||
* @author Silviu Dinuta
|
||||
* @since 2.6
|
||||
*/
|
||||
@BehaviourBean(defaultType = "rma:unfiledRecordContainer")
|
||||
public class UnfiledRecordContainerType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||
NodeServicePolicies.OnDeleteNodePolicy
|
||||
{
|
||||
private static final String BEHAVIOUR_NAME = "onDeleteUnfiledRecordContainer";
|
||||
private final static List<QName> ACCEPTED_NON_UNIQUE_CHILD_TYPES = Arrays.asList(TYPE_UNFILED_RECORD_FOLDER, ContentModel.TYPE_CONTENT, TYPE_NON_ELECTRONIC_DOCUMENT);
|
||||
|
||||
/**
|
||||
* Disable the behaviours for this transaction
|
||||
*/
|
||||
public void disable()
|
||||
{
|
||||
getBehaviour(BEHAVIOUR_NAME).disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable behaviours for this transaction
|
||||
*/
|
||||
public void enable()
|
||||
{
|
||||
getBehaviour(BEHAVIOUR_NAME).enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.ASSOCIATION)
|
||||
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode)
|
||||
{
|
||||
// We need to automatically cast the created folder to record folder if it is a plain folder
|
||||
// This occurs if the RM folder has been created via IMap, WebDav, etc. Don't check subtypes.
|
||||
// Some modules use hidden folder subtypes to store information (see RM-3283).
|
||||
QName childType = nodeService.getType(childAssocRef.getChildRef());
|
||||
if (childType.equals(ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
nodeService.setType(childAssocRef.getChildRef(), TYPE_UNFILED_RECORD_FOLDER);
|
||||
}
|
||||
|
||||
// check the created child is of an accepted type
|
||||
validateNewChildAssociationSubTypesIncluded(childAssocRef.getChildRef(), ACCEPTED_NON_UNIQUE_CHILD_TYPES);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.CLASS,
|
||||
name = BEHAVIOUR_NAME)
|
||||
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isNodeArchived)
|
||||
{
|
||||
throw new IntegrityException("Operation failed. Deletion of Unfiled Record Container is not allowed.", null);
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 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.model.rma.type;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* rma:unfiledRecordFolder behaviour bean
|
||||
*
|
||||
* @author Silviu Dinuta
|
||||
* @since 2.6
|
||||
*/
|
||||
@BehaviourBean(defaultType = "rma:unfiledRecordFolder")
|
||||
public class UnfiledRecordFolderType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy
|
||||
{
|
||||
private final static List<QName> ACCEPTED_NON_UNIQUE_CHILD_TYPES = Arrays.asList(TYPE_UNFILED_RECORD_FOLDER, ContentModel.TYPE_CONTENT, TYPE_NON_ELECTRONIC_DOCUMENT);
|
||||
|
||||
@Override
|
||||
@Behaviour(kind = BehaviourKind.ASSOCIATION)
|
||||
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode)
|
||||
{
|
||||
// We need to automatically cast the created folder to record folder if it is a plain folder
|
||||
// This occurs if the RM folder has been created via IMap, WebDav, etc. Don't check subtypes.
|
||||
// Some modules use hidden folder subtypes to store information (see RM-3283).
|
||||
QName childType = nodeService.getType(childAssocRef.getChildRef());
|
||||
if (childType.equals(ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
nodeService.setType(childAssocRef.getChildRef(), TYPE_UNFILED_RECORD_FOLDER);
|
||||
}
|
||||
|
||||
// check the created child is of an accepted type
|
||||
validateNewChildAssociationSubTypesIncluded(childAssocRef.getChildRef(), ACCEPTED_NON_UNIQUE_CHILD_TYPES);
|
||||
}
|
||||
}
|
@@ -32,7 +32,6 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction;
|
||||
@@ -41,6 +40,8 @@ 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.freeze.FreezeService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.rma.type.TransferContainerType;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.rma.type.TransferType;
|
||||
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.util.ServiceBaseImpl;
|
||||
@@ -87,6 +88,10 @@ public class TransferServiceImpl extends ServiceBaseImpl
|
||||
/** Freeze Service */
|
||||
protected FreezeService freezeService;
|
||||
|
||||
protected TransferContainerType transferContainerType;
|
||||
|
||||
protected TransferType transferType;
|
||||
|
||||
/**
|
||||
* @param filePlanService file plan service
|
||||
*/
|
||||
@@ -127,6 +132,16 @@ public class TransferServiceImpl extends ServiceBaseImpl
|
||||
this.freezeService = freezeService;
|
||||
}
|
||||
|
||||
public void setTransferContainerType(TransferContainerType transferContainerType)
|
||||
{
|
||||
this.transferContainerType = transferContainerType;
|
||||
}
|
||||
|
||||
public void setTransferType(TransferType transferType)
|
||||
{
|
||||
this.transferType = transferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.transfer.TransferService#transfer(NodeRef, boolean)
|
||||
*/
|
||||
@@ -164,11 +179,19 @@ public class TransferServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
|
||||
NodeRef transferContainer = filePlanService.getTransferContainer(root);
|
||||
transferNodeRef = nodeService.createNode(transferContainer,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(RM_URI, transferName),
|
||||
TYPE_TRANSFER,
|
||||
transferProps).getChildRef();
|
||||
|
||||
transferContainerType.disable();
|
||||
try
|
||||
{
|
||||
transferNodeRef = nodeService.createNode(transferContainer, ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(RM_URI, transferName), TYPE_TRANSFER, transferProps)
|
||||
.getChildRef();
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
transferContainerType.enable();
|
||||
}
|
||||
|
||||
// Bind the hold node reference to the transaction
|
||||
AlfrescoTransactionSupport.bindResource(KEY_TRANSFER_NODEREF, transferNodeRef);
|
||||
@@ -188,13 +211,17 @@ public class TransferServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
|
||||
// Link the record to the trasnfer object
|
||||
nodeService.addChild(transferNodeRef,
|
||||
nodeRef,
|
||||
ASSOC_TRANSFERRED,
|
||||
ASSOC_TRANSFERRED);
|
||||
|
||||
transferType.disable();
|
||||
try
|
||||
{
|
||||
nodeService.addChild(transferNodeRef, nodeRef, ASSOC_TRANSFERRED, ASSOC_TRANSFERRED);
|
||||
// Set PDF indicator flag
|
||||
setPDFIndicationFlag(transferNodeRef, nodeRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
transferType.enable();
|
||||
}
|
||||
|
||||
// Set the transferring indicator aspect
|
||||
nodeService.addAspect(nodeRef, ASPECT_TRANSFERRING, null);
|
||||
|
@@ -25,16 +25,15 @@
|
||||
* #L%
|
||||
*
|
||||
*/
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.integration.issue;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Unit test for RM-3341 .. can copy to hold and transfer folder
|
||||
@@ -43,9 +42,6 @@ import org.springframework.extensions.surf.util.I18NUtil;
|
||||
*/
|
||||
public class RM3341Test extends BaseRMTestCase
|
||||
{
|
||||
|
||||
private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container";
|
||||
|
||||
public void testCopyingContentsInHoldandTransfer() throws Exception
|
||||
{
|
||||
doTestInTransaction(new Test<Void>()
|
||||
@@ -79,13 +75,12 @@ public class RM3341Test extends BaseRMTestCase
|
||||
|
||||
try
|
||||
{
|
||||
FileInfo copyInfo = fileFolderService.create(holdContainer, "test file", ContentModel.TYPE_CONTENT);
|
||||
fileFolderService.create(holdContainer, "test file", ContentModel.TYPE_CONTENT);
|
||||
fail("This should have thrown an exception");
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
catch (IntegrityException e)
|
||||
{
|
||||
// ("Content can't be added to a record container. Use record folders to file content.")
|
||||
assertEquals(I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER), e.getMsgId());
|
||||
// ("Content can't be added to a hold container. Use record folders to file content.")
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -109,10 +104,9 @@ public class RM3341Test extends BaseRMTestCase
|
||||
fail("This should have thrown an exception");
|
||||
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
catch (IntegrityException e)
|
||||
{
|
||||
// ("Content can't be added to a record container. Use record folders to file content.")
|
||||
assertEquals(I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER), e.getMsgId());
|
||||
// ("Content can't be added to a transfer container. Use record folders to file content.")
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 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.test.integration.issue;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* Test for RM-4293
|
||||
*
|
||||
* @author Silviu Dinuta
|
||||
* @since 2.6
|
||||
*/
|
||||
public class RM4293Test extends BaseRMTestCase
|
||||
{
|
||||
public void testDeleteSpecialContainers() throws Exception
|
||||
{
|
||||
doTestInTransaction(new Test<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void run()
|
||||
{
|
||||
NodeRef holdContainer = filePlanService.getHoldContainer(filePlan);
|
||||
assertNotNull(holdContainer);
|
||||
|
||||
try
|
||||
{
|
||||
fileFolderService.delete(holdContainer);
|
||||
fail("This should have thrown an exception");
|
||||
}
|
||||
catch (IntegrityException e)
|
||||
{
|
||||
// ("Hold Container can't be deleted.")
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
doTestInTransaction(new Test<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void run()
|
||||
{
|
||||
NodeRef transferContainer = filePlanService.getTransferContainer(filePlan);
|
||||
assertNotNull(transferContainer);
|
||||
try
|
||||
{
|
||||
fileFolderService.delete(transferContainer);
|
||||
fail("This should have thrown an exception");
|
||||
}
|
||||
catch (IntegrityException e)
|
||||
{
|
||||
// ("Transfer Container can't be deleted.")
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
doTestInTransaction(new Test<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void run()
|
||||
{
|
||||
NodeRef unfiledRecordContainer = filePlanService.getUnfiledContainer(filePlan);
|
||||
assertNotNull(unfiledRecordContainer);
|
||||
|
||||
try
|
||||
{
|
||||
fileFolderService.delete(unfiledRecordContainer);
|
||||
fail("This should have thrown an exception");
|
||||
}
|
||||
catch (IntegrityException e)
|
||||
{
|
||||
// ("Unfiled Record Container can't be deleted.")
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
doTestInTransaction(new Test<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
fileFolderService.delete(filePlan);
|
||||
fail("This should have thrown an exception");
|
||||
}
|
||||
catch (IntegrityException e)
|
||||
{
|
||||
// ("FilePlan can't be deleted.")
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -26,11 +26,16 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.model.rma.type;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
|
||||
@@ -42,40 +47,27 @@ import org.mockito.InjectMocks;
|
||||
*/
|
||||
public class TransferContainerTypeUnitTest extends BaseUnitTest
|
||||
{
|
||||
/** test object */
|
||||
private @InjectMocks TransferContainerType transferContainerType;
|
||||
/**
|
||||
* test object
|
||||
*/
|
||||
private @InjectMocks
|
||||
TransferContainerType transferContainerType;
|
||||
|
||||
/**
|
||||
* Having the Unfilled Record container and a folder having the aspect ASPECT_HIDDEN When adding a child association
|
||||
* between the folder and the container Then the folder type shouldn't be renamed
|
||||
* Given that we try to add to transfer container,
|
||||
* Then IntegrityException is thrown.
|
||||
*/
|
||||
@Test(expected = AlfrescoRuntimeException.class)
|
||||
public void testAddContentToTransferContainerTest()
|
||||
@Test(expected = IntegrityException.class)
|
||||
public void testAddToTransferContainerTest()
|
||||
{
|
||||
NodeRef transferContainer = generateNodeRef(TYPE_TRANSFER_CONTAINER, true);
|
||||
|
||||
NodeRef transferContainer = createTransferContainer();
|
||||
|
||||
/*
|
||||
* When adding a child association between the folder and the container
|
||||
*/
|
||||
NodeRef record = generateNodeRef(ContentModel.TYPE_CONTENT);
|
||||
ChildAssociationRef childAssoc = new ChildAssociationRef(ContentModel.TYPE_CONTENT, transferContainer,
|
||||
ContentModel.TYPE_CONTENT, record);
|
||||
|
||||
transferContainerType.onCreateChildAssociation(childAssoc, true);
|
||||
QName type = AlfMock.generateQName();
|
||||
NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type);
|
||||
|
||||
ChildAssociationRef mockedChildAssoc = mock(ChildAssociationRef.class);
|
||||
when(mockedChildAssoc.getChildRef()).thenReturn(nodeRef);
|
||||
when(mockedChildAssoc.getParentRef()).thenReturn(transferContainer);
|
||||
transferContainerType.onCreateChildAssociation(mockedChildAssoc, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a record management container
|
||||
*
|
||||
* @return reference to the generated container
|
||||
*/
|
||||
private NodeRef createTransferContainer()
|
||||
{
|
||||
NodeRef holdContainer = generateNodeRef(TYPE_TRANSFER, true);
|
||||
|
||||
return holdContainer;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user