mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-1098: Refactor RM model behavior into a more maintainable structure
* added behaviour bean and method annotations .. allows the simple defintion of methods as behaviours, simplifies code and provides a way to report on the registered behaviours in the future * moved and consolidated some of the behaviours into classes based on the RM object model .. with behaviours in one logical place it should reduce issues with unpredictable behaviours and help maintenance * TODO more consolidate still needed git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@58120 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -28,12 +28,10 @@ import java.util.Set;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.RenditionModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind;
|
||||
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.RecordsManagementCustomModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||
@@ -45,7 +43,6 @@ import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
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.cmr.repository.ScriptService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
@@ -61,12 +58,11 @@ import org.springframework.extensions.surf.util.I18NUtil;
|
||||
*/
|
||||
public class RecordsManagementServiceImpl extends ServiceBaseImpl
|
||||
implements RecordsManagementService,
|
||||
RecordsManagementModel,
|
||||
RecordsManagementPolicies.OnCreateReference,
|
||||
RecordsManagementPolicies.OnRemoveReference
|
||||
RecordsManagementModel //,
|
||||
//RecordsManagementPolicies.OnCreateReference,
|
||||
//RecordsManagementPolicies.OnRemoveReference
|
||||
{
|
||||
/** I18N */
|
||||
private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container";
|
||||
private final static String MSG_UPDATE_DISP_ACT_DEF = "rm.service.update-disposition-action-def";
|
||||
private final static String MSG_SET_ID = "rm.service.set-id";
|
||||
|
||||
@@ -81,7 +77,7 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl
|
||||
/** Policy component */
|
||||
private PolicyComponent policyComponent;
|
||||
|
||||
/** Well-known location of the scripts folder. */
|
||||
///** Well-known location of the scripts folder. */
|
||||
private NodeRef scriptsFolderNodeRef = new NodeRef("workspace", "SpacesStore", "rm_behavior_scripts");
|
||||
|
||||
/** Java behaviour */
|
||||
@@ -196,26 +192,6 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
// Register the association behaviours
|
||||
policyComponent.bindAssociationBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"),
|
||||
TYPE_FILE_PLAN,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
new JavaBehaviour(this, "onAddContentToContainer", NotificationFrequency.EVERY_EVENT));
|
||||
policyComponent.bindAssociationBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"),
|
||||
TYPE_RECORD_CATEGORY,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
new JavaBehaviour(this, "onAddContentToContainer", NotificationFrequency.EVERY_EVENT));
|
||||
|
||||
// TODO move this into the record service
|
||||
policyComponent.bindAssociationBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"),
|
||||
ASPECT_RECORD,
|
||||
RenditionModel.ASSOC_RENDITION,
|
||||
new JavaBehaviour(this, "onAddRecordThumbnail", NotificationFrequency.TRANSACTION_COMMIT)
|
||||
);
|
||||
|
||||
// Register script execution behaviour on RM property update.
|
||||
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
ASPECT_FILE_PLAN_COMPONENT,
|
||||
@@ -227,81 +203,12 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl
|
||||
TYPE_DISPOSITION_ACTION_DEFINITION,
|
||||
onChangeToDispositionActionDefinition);
|
||||
|
||||
// Reference behaviours
|
||||
policyComponent.bindClassBehaviour(RecordsManagementPolicies.ON_CREATE_REFERENCE,
|
||||
ASPECT_RECORD,
|
||||
new JavaBehaviour(this, "onCreateReference", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
|
||||
policyComponent.bindClassBehaviour(RecordsManagementPolicies.ON_REMOVE_REFERENCE,
|
||||
ASPECT_RECORD,
|
||||
new JavaBehaviour(this, "onRemoveReference", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
|
||||
// Identifier behaviours
|
||||
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
ASPECT_RECORD_COMPONENT_ID,
|
||||
new JavaBehaviour(this, "onIdentifierUpdate", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
}
|
||||
|
||||
/**
|
||||
* On add content to container
|
||||
*
|
||||
* Prevents content nodes being added to record series and record category folders
|
||||
* by imap, cifs etc.
|
||||
*
|
||||
* @param childAssocRef
|
||||
* @param bNew
|
||||
*/
|
||||
public void onAddContentToContainer(ChildAssociationRef childAssocRef, boolean bNew)
|
||||
{
|
||||
NodeRef parent = childAssocRef.getParentRef();
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER));
|
||||
}
|
||||
if (isFilePlan(parent) == true && isRecordFolder(nodeRef) == true)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Operation failed, because you can not place a record folder in the root of the file plan.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the thumbnails of records are marked as file plan components as are therefore subject to the same
|
||||
* permission restrictions.
|
||||
*
|
||||
* @param childAssocRef
|
||||
* @param bNew
|
||||
*/
|
||||
public void onAddRecordThumbnail(final ChildAssociationRef childAssocRef, final boolean bNew)
|
||||
{
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
NodeRef thumbnail = childAssocRef.getChildRef();
|
||||
|
||||
if (nodeService.exists(thumbnail) == true)
|
||||
{
|
||||
// apply file plan component aspect to thumbnail
|
||||
nodeService.addAspect(thumbnail, ASPECT_FILE_PLAN_COMPONENT, null);
|
||||
|
||||
// manage any extended readers
|
||||
NodeRef parent = childAssocRef.getParentRef();
|
||||
ExtendedSecurityService extendedSecurityService = getExtendedSecurityService();
|
||||
Set<String> readers = extendedSecurityService.getExtendedReaders(parent);
|
||||
Set<String> writers = extendedSecurityService.getExtendedWriters(parent);
|
||||
if (readers != null && readers.size() != 0)
|
||||
{
|
||||
extendedSecurityService.addExtendedSecurity(thumbnail, readers, writers, false);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after a DispositionActionDefinition property has been updated.
|
||||
*/
|
||||
@@ -483,67 +390,6 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnCreateReference#onCreateReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public void onCreateReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference)
|
||||
{
|
||||
// Deal with versioned records
|
||||
if (reference.equals(QName.createQName(RecordsManagementCustomModel.RM_CUSTOM_URI, "versions")) == true)
|
||||
{
|
||||
// Apply the versioned aspect to the from node
|
||||
this.nodeService.addAspect(fromNodeRef, ASPECT_VERSIONED_RECORD, null);
|
||||
}
|
||||
|
||||
// Execute script if for the reference event
|
||||
executeReferenceScript("onCreate", reference, fromNodeRef, toNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a reference script if present
|
||||
*
|
||||
* @param policy
|
||||
* @param reference
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
private void executeReferenceScript(String policy, QName reference, NodeRef from, NodeRef to)
|
||||
{
|
||||
String referenceId = reference.getLocalName();
|
||||
|
||||
// This is the filename pattern which is assumed.
|
||||
// e.g. a script file onCreate_superceded.js for the creation of a superseded reference
|
||||
String expectedScriptName = policy + "_" + referenceId + ".js";
|
||||
|
||||
NodeRef scriptNodeRef = nodeService.getChildByName(scriptsFolderNodeRef, ContentModel.ASSOC_CONTAINS, expectedScriptName);
|
||||
if (scriptNodeRef != null)
|
||||
{
|
||||
Map<String, Object> objectModel = new HashMap<String, Object>(1);
|
||||
objectModel.put("node", from);
|
||||
objectModel.put("toNode", to);
|
||||
objectModel.put("policy", policy);
|
||||
objectModel.put("reference", referenceId);
|
||||
|
||||
getScriptService().executeScript(scriptNodeRef, null, objectModel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnRemoveReference#onRemoveReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public void onRemoveReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference)
|
||||
{
|
||||
// Deal with versioned records
|
||||
if (reference.equals(QName.createQName(RecordsManagementCustomModel.RM_CUSTOM_URI, "versions")) == true)
|
||||
{
|
||||
// Apply the versioned aspect to the from node
|
||||
this.nodeService.removeAspect(fromNodeRef, ASPECT_VERSIONED_RECORD);
|
||||
}
|
||||
|
||||
// Execute script if for the reference event
|
||||
executeReferenceScript("onRemove", reference, fromNodeRef, toNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of 2.1, see {@link FilePlanService#isFilePlanComponent(NodeRef)}
|
||||
*/
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -26,8 +26,10 @@ import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Bootstrap bean that indicates that the specified types or aspects are
|
||||
* customizable.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.0
|
||||
*/
|
||||
public class CustomisableTypesBootstrap
|
||||
{
|
||||
|
@@ -143,10 +143,6 @@ public class RecordCopyBehaviours implements RecordsManagementModel
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "getCopyCallback"),
|
||||
RecordsManagementModel.TYPE_RECORD_FOLDER,
|
||||
new JavaBehaviour(this, "onCopyRecordFolderNode"));
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "getCopyCallback"),
|
||||
RecordsManagementModel.TYPE_RECORD_CATEGORY,
|
||||
new JavaBehaviour(this, "onCopyRecordCategoryNode"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -330,36 +326,6 @@ public class RecordCopyBehaviours implements RecordsManagementModel
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Record Category Copy Behaviour
|
||||
*
|
||||
* <li> Do not allow copy of record category into a record folder</li>
|
||||
*
|
||||
* @param classRef
|
||||
* @param copyDetails
|
||||
* @return
|
||||
*/
|
||||
public CopyBehaviourCallback onCopyRecordCategoryNode(final QName classRef, final CopyDetails copyDetails)
|
||||
{
|
||||
return new DefaultCopyBehaviourCallback()
|
||||
{
|
||||
final NodeService nodeService = rmServiceRegistry.getNodeService();
|
||||
|
||||
/**
|
||||
* If the targets parent is a Record Folder -- Do Not Allow Copy
|
||||
*
|
||||
* @param classQName
|
||||
* @param copyDetails
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean getMustCopy(QName classQName, CopyDetails copyDetails)
|
||||
{
|
||||
return nodeService.getType(copyDetails.getTargetParentNodeRef()).equals(TYPE_RECORD_FOLDER) ? false : true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes unwanted aspects
|
||||
*
|
||||
|
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.model.rma;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Convenient base class for behaviour beans.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
public abstract class BaseBehaviourBean implements RecordsManagementModel
|
||||
{
|
||||
/** Logger */
|
||||
protected static Log logger = LogFactory.getLog(BaseBehaviourBean.class);
|
||||
|
||||
/** node service */
|
||||
protected NodeService nodeService;
|
||||
|
||||
/** dictionary service */
|
||||
protected DictionaryService dictionaryService;
|
||||
|
||||
/** behaviour filter */
|
||||
protected BehaviourFilter behaviourFilter;
|
||||
|
||||
/**
|
||||
* @param nodeService node service
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dictionaryService dictionary service
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param behaviourFilter behaviour filter
|
||||
*/
|
||||
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
|
||||
{
|
||||
this.behaviourFilter = behaviourFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to safely and quickly determine if a node is a type (or sub-type) of the one specified.
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param ofClassName class name to check
|
||||
*/
|
||||
protected boolean instanceOf(NodeRef nodeRef, QName ofClassName)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
ParameterCheck.mandatory("ofClassName", ofClassName);
|
||||
boolean result = false;
|
||||
if (nodeService.exists(nodeRef) == true &&
|
||||
(ofClassName.equals(nodeService.getType(nodeRef)) == true ||
|
||||
dictionaryService.isSubClass(nodeService.getType(nodeRef), ofClassName) == true))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 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.module.org_alfresco_module_rm.model.rma;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
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;
|
||||
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.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
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.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* rma:filePlan behaviour bean
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
@BehaviourBean
|
||||
(
|
||||
defaultType = "rma:filePlan"
|
||||
)
|
||||
public class FilePlanType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||
NodeServicePolicies.OnCreateNodePolicy,
|
||||
NodeServicePolicies.OnDeleteNodePolicy
|
||||
{
|
||||
/** file plan service */
|
||||
protected FilePlanService filePlanService;
|
||||
|
||||
/** record folder service */
|
||||
protected RecordFolderService recordFolderService;
|
||||
|
||||
/** identifier service */
|
||||
protected IdentifierService identifierService;
|
||||
|
||||
/** file plan role service */
|
||||
protected FilePlanRoleService filePlanRoleService;
|
||||
|
||||
/**
|
||||
* @param filePlanService file plan service
|
||||
*/
|
||||
public void setFilePlanService(FilePlanService filePlanService)
|
||||
{
|
||||
this.filePlanService = filePlanService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param recordFolderService record folder service
|
||||
*/
|
||||
public void setRecordFolderService(RecordFolderService recordFolderService)
|
||||
{
|
||||
this.recordFolderService = recordFolderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param identifierService identifier service
|
||||
*/
|
||||
public void setIdentifierService(IdentifierService identifierService)
|
||||
{
|
||||
this.identifierService = identifierService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePlanRoleService file plan role service
|
||||
*/
|
||||
public void setFilePlanRoleService(FilePlanRoleService filePlanRoleService)
|
||||
{
|
||||
this.filePlanRoleService = filePlanRoleService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.ASSOCIATION
|
||||
)
|
||||
@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) == true)
|
||||
{
|
||||
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 (filePlanService.isFilePlan(parent) == true && recordFolderService.isRecordFolder(nodeRef) == true)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Operation failed, because you can not place a record folder in the root of the file plan.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef)
|
||||
*/
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
@Override
|
||||
public void onCreateNode(final ChildAssociationRef childAssocRef)
|
||||
{
|
||||
final NodeRef filePlan = childAssocRef.getChildRef();
|
||||
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
if (nodeService.hasAspect(filePlan, ASPECT_FILE_PLAN_COMPONENT) == true &&
|
||||
nodeService.getProperty(filePlan, PROP_IDENTIFIER) == null)
|
||||
{
|
||||
String id = identifierService.generateIdentifier(filePlan);
|
||||
nodeService.setProperty(filePlan, RecordsManagementModel.PROP_IDENTIFIER, id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// setup the file plan roles
|
||||
filePlanRoleService.setupFilePlanRoles(filePlan);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnDeleteNodePolicy#onDeleteNode(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
@Override
|
||||
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean archived)
|
||||
{
|
||||
// tear down the file plan roles
|
||||
filePlanRoleService.tearDownFilePlanRoles(childAssocRef.getChildRef());
|
||||
}
|
||||
}
|
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 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.module.org_alfresco_module_rm.model.rma;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
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.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.ScriptService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* rma:record behaviour bean
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
@BehaviourBean
|
||||
(
|
||||
defaultType = "rma:record"
|
||||
)
|
||||
public class RecordAspect extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||
RecordsManagementPolicies.OnCreateReference,
|
||||
RecordsManagementPolicies.OnRemoveReference
|
||||
{
|
||||
/** Well-known location of the scripts folder. */
|
||||
// TODO make configurable
|
||||
private NodeRef scriptsFolderNodeRef = new NodeRef("workspace", "SpacesStore", "rm_behavior_scripts");
|
||||
|
||||
/** extended security service */
|
||||
protected ExtendedSecurityService extendedSecurityService;
|
||||
|
||||
/** script service */
|
||||
protected ScriptService scriptService;
|
||||
|
||||
/**
|
||||
* @param extendedSecurityService extended security service
|
||||
*/
|
||||
public void setExtendedSecurityService(ExtendedSecurityService extendedSecurityService)
|
||||
{
|
||||
this.extendedSecurityService = extendedSecurityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scriptService script service
|
||||
*/
|
||||
public void setScriptService(ScriptService scriptService)
|
||||
{
|
||||
this.scriptService = scriptService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Behaviour to ensure renditions have the appropriate extended security.
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.ASSOCIATION,
|
||||
assocType = "rn:rendition",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateChildAssociation(final ChildAssociationRef childAssocRef, boolean bNew)
|
||||
{
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
NodeRef thumbnail = childAssocRef.getChildRef();
|
||||
|
||||
if (nodeService.exists(thumbnail) == true)
|
||||
{
|
||||
// apply file plan component aspect to thumbnail
|
||||
nodeService.addAspect(thumbnail, ASPECT_FILE_PLAN_COMPONENT, null);
|
||||
|
||||
// manage any extended readers
|
||||
NodeRef parent = childAssocRef.getParentRef();
|
||||
Set<String> readers = extendedSecurityService.getExtendedReaders(parent);
|
||||
Set<String> writers = extendedSecurityService.getExtendedWriters(parent);
|
||||
if (readers != null && readers.size() != 0)
|
||||
{
|
||||
extendedSecurityService.addExtendedSecurity(thumbnail, readers, writers, false);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnCreateReference#onCreateReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference)
|
||||
{
|
||||
// Deal with versioned records
|
||||
if (reference.equals(QName.createQName(RecordsManagementCustomModel.RM_CUSTOM_URI, "versions")) == true)
|
||||
{
|
||||
// Apply the versioned aspect to the from node
|
||||
nodeService.addAspect(fromNodeRef, ASPECT_VERSIONED_RECORD, null);
|
||||
}
|
||||
|
||||
// Execute script if for the reference event
|
||||
executeReferenceScript("onCreate", reference, fromNodeRef, toNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnRemoveReference#onRemoveReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onRemoveReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference)
|
||||
{
|
||||
// Deal with versioned records
|
||||
if (reference.equals(QName.createQName(RecordsManagementCustomModel.RM_CUSTOM_URI, "versions")) == true)
|
||||
{
|
||||
// Apply the versioned aspect to the from node
|
||||
nodeService.removeAspect(fromNodeRef, ASPECT_VERSIONED_RECORD);
|
||||
}
|
||||
|
||||
// Execute script if for the reference event
|
||||
executeReferenceScript("onRemove", reference, fromNodeRef, toNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a reference script if present
|
||||
*
|
||||
* @param policy
|
||||
* @param reference
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
private void executeReferenceScript(String policy, QName reference, NodeRef from, NodeRef to)
|
||||
{
|
||||
String referenceId = reference.getLocalName();
|
||||
|
||||
// This is the filename pattern which is assumed.
|
||||
// e.g. a script file onCreate_superceded.js for the creation of a superseded reference
|
||||
String expectedScriptName = policy + "_" + referenceId + ".js";
|
||||
|
||||
NodeRef scriptNodeRef = nodeService.getChildByName(scriptsFolderNodeRef, ContentModel.ASSOC_CONTAINS, expectedScriptName);
|
||||
if (scriptNodeRef != null)
|
||||
{
|
||||
Map<String, Object> objectModel = new HashMap<String, Object>(1);
|
||||
objectModel.put("node", from);
|
||||
objectModel.put("toNode", to);
|
||||
objectModel.put("policy", policy);
|
||||
objectModel.put("reference", referenceId);
|
||||
|
||||
scriptService.executeScript(scriptNodeRef, null, objectModel);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 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.module.org_alfresco_module_rm.model.rma;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService;
|
||||
import org.alfresco.repo.copy.CopyBehaviourCallback;
|
||||
import org.alfresco.repo.copy.CopyDetails;
|
||||
import org.alfresco.repo.copy.DefaultCopyBehaviourCallback;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
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.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* rma:recordCategory behaviour bean
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
@BehaviourBean
|
||||
(
|
||||
defaultType = "rma:recordCategory"
|
||||
)
|
||||
public class RecordCategoryType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||
NodeServicePolicies.OnCreateNodePolicy
|
||||
{
|
||||
/** vital record service */
|
||||
protected VitalRecordService vitalRecordService;
|
||||
|
||||
/** file plan permission service */
|
||||
protected FilePlanPermissionService filePlanPermissionService;
|
||||
|
||||
/**
|
||||
* @param vitalRecordService vital record service
|
||||
*/
|
||||
public void setVitalRecordService(VitalRecordService vitalRecordService)
|
||||
{
|
||||
this.vitalRecordService = vitalRecordService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePlanPermissionService file plan permission service
|
||||
*/
|
||||
public void setFilePlanPermissionService(FilePlanPermissionService filePlanPermissionService)
|
||||
{
|
||||
this.filePlanPermissionService = filePlanPermissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* On every event
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.ASSOCIATION
|
||||
)
|
||||
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) == true)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Operation failed, because you can't place content directly into a record category.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On transaction commit
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.ASSOCIATION,
|
||||
policy = "alf:onCreateChildAssociation",
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateChildAssociationOnCommit(ChildAssociationRef childAssocRef, boolean bNew)
|
||||
{
|
||||
final NodeRef recordCategory = childAssocRef.getChildRef();
|
||||
|
||||
behaviourFilter.disableBehaviour();
|
||||
try
|
||||
{
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
// setup vital record definition
|
||||
vitalRecordService.setupVitalRecordDefinition(recordCategory);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
behaviourFilter.enableBehaviour();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateNode(ChildAssociationRef childAssocRef)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("rma:recordCategory|alf:onCreateNode|this.onCreateNode()|TRANSATION_COMMIT");
|
||||
}
|
||||
|
||||
// setup record category permissions
|
||||
filePlanPermissionService.setupRecordCategoryPermissions(childAssocRef.getChildRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy callback for record category
|
||||
*/
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
policy = "alf:getCopyCallback"
|
||||
)
|
||||
public CopyBehaviourCallback onCopyRecordCategory(final QName classRef, final CopyDetails copyDetails)
|
||||
{
|
||||
return new DefaultCopyBehaviourCallback()
|
||||
{
|
||||
/**
|
||||
* If the targets parent is a Record Folder -- Do Not Allow Copy
|
||||
*
|
||||
* @param classQName
|
||||
* @param copyDetails
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean getMustCopy(QName classQName, CopyDetails copyDetails)
|
||||
{
|
||||
return nodeService.getType(copyDetails.getTargetParentNodeRef()).equals(TYPE_RECORD_FOLDER) ? false : true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 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.module.org_alfresco_module_rm.model.rma;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
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.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* rma:recordsManagementContainer behaviour bean.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
@BehaviourBean
|
||||
(
|
||||
defaultType = "rma:recordsManagementContainer"
|
||||
)
|
||||
public class RecordsManagementContainerType extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnCreateChildAssociationPolicy
|
||||
{
|
||||
/** identifier service */
|
||||
protected IdentifierService identifierService;
|
||||
|
||||
/**
|
||||
* @param identifierService identifier service
|
||||
*/
|
||||
public void setIdentifierService(IdentifierService identifierService)
|
||||
{
|
||||
this.identifierService = identifierService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.model.BaseTypeBehaviour#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
|
||||
*/
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.ASSOCIATION,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onCreateChildAssociation(final ChildAssociationRef childAssocRef, boolean isNewNode)
|
||||
{
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
// Get the elements of the created association
|
||||
final NodeRef child = childAssocRef.getChildRef();
|
||||
if (nodeService.exists(child) == true)
|
||||
{
|
||||
QName childType = nodeService.getType(child);
|
||||
|
||||
// We only care about "folder" or sub-types
|
||||
if (dictionaryService.isSubClass(childType, ContentModel.TYPE_FOLDER) == true)
|
||||
{
|
||||
if (dictionaryService.isSubClass(childType, ContentModel.TYPE_SYSTEM_FOLDER) == true)
|
||||
{
|
||||
// this is a rule container, make sure it is an file plan component
|
||||
nodeService.addAspect(child, ASPECT_FILE_PLAN_COMPONENT, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to automatically cast the created folder to RM type if it is a plain folder
|
||||
// This occurs if the RM folder has been created via IMap, WebDav, etc
|
||||
if (nodeService.hasAspect(child, ASPECT_FILE_PLAN_COMPONENT) == false)
|
||||
{
|
||||
// TODO it may not always be a record folder ... perhaps if the current user is a admin it would be a record category??
|
||||
|
||||
// Assume any created folder is a rma:recordFolder
|
||||
nodeService.setType(child, TYPE_RECORD_FOLDER);
|
||||
}
|
||||
|
||||
// Catch all to generate the rm id (assuming it doesn't already have one!)
|
||||
setIdenifierProperty(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nodeRef
|
||||
*/
|
||||
protected void setIdenifierProperty(final NodeRef nodeRef)
|
||||
{
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT) == true &&
|
||||
nodeService.getProperty(nodeRef, PROP_IDENTIFIER) == null)
|
||||
{
|
||||
String id = identifierService.generateIdentifier(nodeRef);
|
||||
nodeService.setProperty(nodeRef, RecordsManagementModel.PROP_IDENTIFIER, id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -84,6 +84,7 @@ public class RecordFolderServiceImpl extends ServiceBaseImpl
|
||||
= new JavaBehaviour(this,
|
||||
"onCreateChildAssociation",
|
||||
NotificationFrequency.FIRST_EVENT);
|
||||
|
||||
private JavaBehaviour onCreateChildAssociationInRecordFolderFolder
|
||||
= new JavaBehaviour(this,
|
||||
"onCreateChildAssociationInRecordFolder",
|
||||
@@ -126,6 +127,7 @@ public class RecordFolderServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
|
||||
policyComponent.bindAssociationBehaviour(
|
||||
NodeServicePolicies.OnCreateChildAssociationPolicy.QNAME,
|
||||
TYPE_RECORD_CATEGORY,
|
||||
|
@@ -47,7 +47,21 @@ public interface FilePlanRoleService
|
||||
ROLE_EXTENDED_READERS,
|
||||
ROLE_EXTENDED_WRITERS
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets up the roles on a new file plan.
|
||||
*
|
||||
* @param filePlan file plan
|
||||
*/
|
||||
void setupFilePlanRoles(NodeRef filePlan);
|
||||
|
||||
/**
|
||||
* Tears down the roles on a file plan.
|
||||
*
|
||||
* @param filePlan file plan
|
||||
*/
|
||||
void tearDownFilePlanRoles(NodeRef filePlan);
|
||||
|
||||
/**
|
||||
* Returns the name of the container group for all roles of a specified file
|
||||
* plan.
|
||||
|
@@ -42,13 +42,8 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationService;
|
||||
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.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authority.RMAuthority;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
@@ -95,9 +90,6 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
|
||||
/** Permission service */
|
||||
private PermissionService permissionService;
|
||||
|
||||
/** Policy component */
|
||||
private PolicyComponent policyComponent;
|
||||
|
||||
/** File plan service */
|
||||
private FilePlanService filePlanService;
|
||||
|
||||
@@ -150,14 +142,6 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param policyComponent policy component
|
||||
*/
|
||||
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||
{
|
||||
this.policyComponent = policyComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService node service
|
||||
*/
|
||||
@@ -208,39 +192,21 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisation method
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService#initialiseFilePlan(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public void init()
|
||||
@Override
|
||||
public void setupFilePlanRoles(final NodeRef filePlan)
|
||||
{
|
||||
policyComponent.bindClassBehaviour(
|
||||
NodeServicePolicies.OnCreateNodePolicy.QNAME,
|
||||
TYPE_FILE_PLAN,
|
||||
new JavaBehaviour(this, "onCreateRootNode", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
policyComponent.bindClassBehaviour(
|
||||
NodeServicePolicies.OnDeleteNodePolicy.QNAME,
|
||||
TYPE_FILE_PLAN,
|
||||
new JavaBehaviour(this, "onDeleteRootNode", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create root node behaviour
|
||||
*
|
||||
* @param childAssocRef
|
||||
*/
|
||||
public void onCreateRootNode(ChildAssociationRef childAssocRef)
|
||||
{
|
||||
final NodeRef rmRootNode = childAssocRef.getChildRef();
|
||||
|
||||
// Do not execute behaviour if this has been created in the archive store
|
||||
if(rmRootNode.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE) == true)
|
||||
if(filePlan.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE) == true)
|
||||
{
|
||||
// This is not the spaces store - probably the archive store
|
||||
return;
|
||||
}
|
||||
|
||||
if (nodeService.exists(rmRootNode) == true)
|
||||
if (nodeService.exists(filePlan) == true)
|
||||
{
|
||||
List<NodeRef> systemContainers = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<List<NodeRef>>()
|
||||
List<NodeRef> systemContainers = AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<List<NodeRef>>()
|
||||
{
|
||||
public List<NodeRef> doWork()
|
||||
{
|
||||
@@ -256,50 +222,44 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
|
||||
// Create "all" role group for root node
|
||||
String allRoles = authorityService.createAuthority(
|
||||
AuthorityType.GROUP,
|
||||
getAllRolesGroupShortName(rmRootNode),
|
||||
getAllRolesGroupShortName(filePlan),
|
||||
I18NUtil.getMessage(MSG_ALL_ROLES),
|
||||
new HashSet<String>(Arrays.asList(RMAuthority.ZONE_APP_RM)));
|
||||
|
||||
// Set the permissions
|
||||
permissionService.setInheritParentPermissions(rmRootNode, false);
|
||||
permissionService.setPermission(rmRootNode, allRoles, RMPermissionModel.READ_RECORDS, true);
|
||||
permissionService.setPermission(rmRootNode, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||
permissionService.setPermission(rmRootNode, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true);
|
||||
permissionService.setInheritParentPermissions(filePlan, false);
|
||||
permissionService.setPermission(filePlan, allRoles, RMPermissionModel.READ_RECORDS, true);
|
||||
permissionService.setPermission(filePlan, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||
permissionService.setPermission(filePlan, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true);
|
||||
|
||||
// Create the transfer and hold containers
|
||||
systemContainers.add(filePlanService.createHoldContainer(rmRootNode));
|
||||
systemContainers.add(filePlanService.createTransferContainer(rmRootNode));
|
||||
systemContainers.add(filePlanService.createHoldContainer(filePlan));
|
||||
systemContainers.add(filePlanService.createTransferContainer(filePlan));
|
||||
|
||||
// Create the unfiled record container
|
||||
systemContainers.add(filePlanService.createUnfiledContainer(rmRootNode));
|
||||
systemContainers.add(filePlanService.createUnfiledContainer(filePlan));
|
||||
|
||||
return systemContainers;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
});
|
||||
|
||||
// Bootstrap in the default set of roles for the newly created root node
|
||||
bootstrapDefaultRoles(rmRootNode, systemContainers);
|
||||
bootstrapDefaultRoles(filePlan, systemContainers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete root node behaviour
|
||||
*
|
||||
* @param childAssocRef
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService#tearDownFilePlanRoles(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public void onDeleteRootNode(ChildAssociationRef childAssocRef, boolean isNodeArchived)
|
||||
@Override
|
||||
public void tearDownFilePlanRoles(final NodeRef filePlan)
|
||||
{
|
||||
logger.debug("onDeleteRootNode called");
|
||||
|
||||
// get the deleted node
|
||||
final NodeRef rmRootNode = childAssocRef.getChildRef();
|
||||
|
||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||
AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
// cascade delete the 'all' roles group for the site
|
||||
String allRolesGroup = authorityService.getName(AuthorityType.GROUP, getAllRolesGroupShortName(rmRootNode));
|
||||
String allRolesGroup = authorityService.getName(AuthorityType.GROUP, getAllRolesGroupShortName(filePlan));
|
||||
Set<String> groups = authorityService.getContainedAuthorities(AuthorityType.GROUP, allRolesGroup, true);
|
||||
for (String group : groups)
|
||||
{
|
||||
@@ -310,7 +270,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
|
||||
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -28,6 +28,12 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
*/
|
||||
public interface FilePlanPermissionService
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param nodeRef
|
||||
*/
|
||||
void setupRecordCategoryPermissions(NodeRef recordCategory);
|
||||
|
||||
/**
|
||||
* Sets a permission on a file plan object. Assumes allow is true. Cascades permission down to record folder.
|
||||
* Cascades ReadRecord up to file plan.
|
||||
|
@@ -22,6 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
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.fileplan.FilePlanService;
|
||||
@@ -79,10 +80,6 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
policyComponent.bindClassBehaviour(
|
||||
NodeServicePolicies.OnCreateNodePolicy.QNAME,
|
||||
TYPE_RECORD_CATEGORY,
|
||||
new JavaBehaviour(this, "onCreateRMContainer", NotificationFrequency.TRANSACTION_COMMIT));
|
||||
policyComponent.bindClassBehaviour(
|
||||
NodeServicePolicies.OnCreateNodePolicy.QNAME,
|
||||
TYPE_RECORD_FOLDER,
|
||||
@@ -152,28 +149,33 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
this.recordFolderService = recordFolderService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param childAssocRef
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService#setupRecordCategoryPermissions(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public void onCreateRMContainer(ChildAssociationRef childAssocRef)
|
||||
@Override
|
||||
public void setupRecordCategoryPermissions(final NodeRef recordCategory)
|
||||
{
|
||||
final NodeRef recordCategory = childAssocRef.getChildRef();
|
||||
setUpPermissions(recordCategory);
|
||||
ParameterCheck.mandatory("recordCategory", recordCategory);
|
||||
|
||||
// assert that we have a record category in our hands
|
||||
if (instanceOf(recordCategory, TYPE_RECORD_CATEGORY) == false)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to setup record category permissions, because node is not a record category.");
|
||||
}
|
||||
|
||||
// init permissions
|
||||
initPermissions(recordCategory);
|
||||
|
||||
// Pull any permissions found on the parent (ie the record category)
|
||||
final NodeRef parentNodeRef = childAssocRef.getParentRef();
|
||||
final NodeRef parentNodeRef = nodeService.getPrimaryParent(recordCategory).getParentRef();
|
||||
if (parentNodeRef != null && nodeService.exists(parentNodeRef) == true)
|
||||
{
|
||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||
AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
boolean fillingOnly = false;
|
||||
if (filePlanService.isFilePlan(parentNodeRef) == true)
|
||||
{
|
||||
fillingOnly = true;
|
||||
}
|
||||
boolean fillingOnly = filePlanService.isFilePlan(parentNodeRef);
|
||||
|
||||
// since this is not a root category, inherit from parent
|
||||
Set<AccessPermission> perms = permissionService.getAllSetPermissions(parentNodeRef);
|
||||
@@ -198,7 +200,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +212,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
final NodeRef folderNodeRef = childAssocRef.getChildRef();
|
||||
|
||||
// initialise the permissions
|
||||
setUpPermissions(folderNodeRef);
|
||||
initPermissions(folderNodeRef);
|
||||
|
||||
// Pull any permissions found on the parent (ie the record category)
|
||||
final NodeRef catNodeRef = childAssocRef.getParentRef();
|
||||
@@ -285,7 +287,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
if (nodeService.exists(nodeRef) == true)
|
||||
{
|
||||
setUpPermissions(nodeRef);
|
||||
initPermissions(nodeRef);
|
||||
|
||||
NodeRef parent = childAssocRef.getParentRef();
|
||||
Set<AccessPermission> perms = permissionService.getAllSetPermissions(parent);
|
||||
@@ -324,7 +326,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void initialiseRecordPermissions(NodeRef record, NodeRef parent)
|
||||
{
|
||||
setUpPermissions(record);
|
||||
initPermissions(record);
|
||||
|
||||
Set<AccessPermission> perms = permissionService.getAllSetPermissions(parent);
|
||||
for (AccessPermission perm : perms)
|
||||
@@ -402,10 +404,11 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nodeRef
|
||||
* Initiliase the permissions for the given node.
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
*/
|
||||
public void setUpPermissions(final NodeRef nodeRef)
|
||||
private void initPermissions(final NodeRef nodeRef)
|
||||
{
|
||||
if (nodeService.exists(nodeRef) == true)
|
||||
{
|
||||
|
@@ -33,8 +33,15 @@ public interface VitalRecordService
|
||||
static final Period PERIOD_NONE = new Period("none|0");
|
||||
|
||||
/**
|
||||
* Gets the vital record definition details for the node.
|
||||
*
|
||||
* Setup the vital record definition for the given node.
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
*/
|
||||
void setupVitalRecordDefinition(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Gets the vital record definition details for the node.
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @return VitalRecordDefinition vital record definition details
|
||||
*/
|
||||
|
@@ -129,11 +129,6 @@ public class VitalRecordServiceImpl implements VitalRecordService,
|
||||
TYPE_RECORD_FOLDER,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
onCreateChildAssociation);
|
||||
policyComponent.bindAssociationBehaviour(
|
||||
NodeServicePolicies.OnCreateChildAssociationPolicy.QNAME,
|
||||
TYPE_RECORD_CATEGORY,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
onCreateChildAssociation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +180,7 @@ public class VitalRecordServiceImpl implements VitalRecordService,
|
||||
if (filePlanService.isRecordCategory(nodeRef) == true ||
|
||||
recordFolderService.isRecordFolder(nodeRef) == true)
|
||||
{
|
||||
inheritVitalRecordDefinition(nodeRef);
|
||||
setupVitalRecordDefinition(nodeRef);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -202,11 +197,10 @@ public class VitalRecordServiceImpl implements VitalRecordService,
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the inherited vital record definition details.
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService#setupVitalRecordDefinition(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
private void inheritVitalRecordDefinition(NodeRef nodeRef)
|
||||
@Override
|
||||
public void setupVitalRecordDefinition(NodeRef nodeRef)
|
||||
{
|
||||
// get the current review period value
|
||||
Period currentReviewPeriod = (Period)nodeService.getProperty(nodeRef, PROP_REVIEW_PERIOD);
|
||||
|
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 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.policy.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
||||
/**
|
||||
* Annotated behaviour bean post processor.
|
||||
* <p>
|
||||
* Registers the annotated methods on behaviour beans with the policy component.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class AnnotatedBehaviourPostProcessor implements BeanPostProcessor
|
||||
{
|
||||
/** logger */
|
||||
private static Log logger = LogFactory.getLog(AnnotatedBehaviourPostProcessor.class);
|
||||
|
||||
/** policy component */
|
||||
private PolicyComponent policyComponent;
|
||||
|
||||
/** namespace service */
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
/**
|
||||
* @param policyComponent policy component
|
||||
*/
|
||||
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||
{
|
||||
this.policyComponent = policyComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param namespaceService namespace service
|
||||
*/
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
|
||||
{
|
||||
// register annotated behavior methods
|
||||
registerBehaviours(bean, beanName);
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
|
||||
{
|
||||
// do nothing
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bean
|
||||
* @param beanName
|
||||
*/
|
||||
private void registerBehaviours(Object bean, String beanName)
|
||||
{
|
||||
if (bean.getClass().isAnnotationPresent(BehaviourBean.class) == true)
|
||||
{
|
||||
BehaviourBean behaviourBean = bean.getClass().getAnnotation(BehaviourBean.class);
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Annotated behaviour post processing for " + beanName);
|
||||
}
|
||||
|
||||
Method[] methods = bean.getClass().getMethods();
|
||||
for (Method method : methods)
|
||||
{
|
||||
if (method.isAnnotationPresent(Behaviour.class) == true)
|
||||
{
|
||||
registerBehaviour(behaviourBean, bean, beanName, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bean
|
||||
* @param beanName
|
||||
* @param method
|
||||
* @param classBehaviour
|
||||
*/
|
||||
private void registerBehaviour(BehaviourBean behaviourBean, Object bean, String beanName, Method method)
|
||||
{
|
||||
Behaviour behaviour = method.getAnnotation(Behaviour.class);
|
||||
QName policy = resolvePolicy(behaviour.policy(), method);
|
||||
QName type = resolveType(behaviourBean, behaviour.type());
|
||||
|
||||
// assert that the policy and type have been set!!
|
||||
ParameterCheck.mandatory("policy", policy);
|
||||
ParameterCheck.mandatory("type", type);
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug(" ... registering " + behaviour.kind() + " behaviour for " + beanName + "." + method.getName() +
|
||||
" for policy " + policy.toString() +
|
||||
" and type " + type.toString());
|
||||
}
|
||||
|
||||
JavaBehaviour javaBehaviour = new JavaBehaviour(bean, method.getName(), behaviour.notificationFrequency());
|
||||
|
||||
if (BehaviourKind.CLASS.equals(behaviour.kind()) == true)
|
||||
{
|
||||
policyComponent.bindClassBehaviour(policy,
|
||||
type,
|
||||
javaBehaviour);
|
||||
}
|
||||
else if (BehaviourKind.ASSOCIATION.equals(behaviour.kind()) == true)
|
||||
{
|
||||
policyComponent.bindAssociationBehaviour(policy,
|
||||
type,
|
||||
toQName(behaviour.assocType()),
|
||||
javaBehaviour);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param policyName
|
||||
* @param method
|
||||
* @return
|
||||
*/
|
||||
private QName resolvePolicy(String policyName, Method method)
|
||||
{
|
||||
QName policy = null;
|
||||
if (policyName.isEmpty() == true)
|
||||
{
|
||||
policy = QName.createQName(NamespaceService.ALFRESCO_URI, method.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
policy = toQName(policyName);
|
||||
}
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param behaviourBean
|
||||
* @param typeName
|
||||
* @return
|
||||
*/
|
||||
private QName resolveType(BehaviourBean behaviourBean, String typeName)
|
||||
{
|
||||
QName type = null;
|
||||
if (typeName.isEmpty() == true)
|
||||
{
|
||||
// get default
|
||||
type = toQName(behaviourBean.defaultType());
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert set
|
||||
type = toQName(typeName);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private QName toQName(String name)
|
||||
{
|
||||
return QName.createQName(name, namespaceService);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 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.policy.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
|
||||
/**
|
||||
* Behaviour method annotation.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
@Target(value = ElementType.METHOD)
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
public @interface Behaviour
|
||||
{
|
||||
/** kind of behaviour */
|
||||
BehaviourKind kind();
|
||||
|
||||
/** qualified name of policy */
|
||||
String policy() default "";
|
||||
|
||||
/** qualified name of type/aspect */
|
||||
String type() default "";
|
||||
|
||||
/** qualified name of association */
|
||||
String assocType() default "cm:contains";
|
||||
|
||||
/** notification frequency */
|
||||
NotificationFrequency notificationFrequency() default NotificationFrequency.EVERY_EVENT;
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 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.policy.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
@Target(value = ElementType.TYPE)
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
public @interface BehaviourBean
|
||||
{
|
||||
/** qualified name of type/aspect */
|
||||
String defaultType() default "";
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 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.policy.annotation;
|
||||
|
||||
/**
|
||||
* Enumeration describing the different kinds of behaviour.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
public enum BehaviourKind
|
||||
{
|
||||
CLASS,
|
||||
ASSOCIATION
|
||||
}
|
Reference in New Issue
Block a user