Implemented a DeclareRecordAction so that a rule can be setup for a folder and a user can declare a record just uploading a file (in a collaboration site) into the folder.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/DEV/INPLACE@43332 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2012-11-02 10:37:51 +00:00
parent 691865e574
commit 75443d6ad5
3 changed files with 281 additions and 1 deletions

View File

@@ -34,4 +34,12 @@
</property> -->
</bean>
<!-- Declare record action -->
<bean id="declare-record" parent="action-executer" class="org.alfresco.module.org_alfresco_module_rm.action.dm.DeclareRecordAction">
<property name="recordsManagementService" ref="RecordsManagementService" />
<property name="recordService" ref="RecordService" />
<property name="nodeService" ref="NodeService" />
<property name="ownableService" ref="OwnableService" />
<property name="dictionaryService" ref="DictionaryService" />
</bean>
</beans>

View File

@@ -34,4 +34,20 @@ rm.action.node-already-transfer=Node is already being transfered.
rm.action.node-not-transfer=Node is not a transfer object.
rm.action.undo-not-last=Can not undo cut off, because last disposition action was not cut off.
rm.action.records_only_undeclared=Only records can be undeclared.
rm.action.event-not-undone=The event {0} can not be undone, because it is not defined on the disposition lifecycle.
rm.action.event-not-undone=The event {0} can not be undone, because it is not defined on the disposition lifecycle.
#
# i18n for Rule Actions
#
# File record
file-record.title=File record
# FIXME!!!
#file-record.description=The rule is applied to all items that...
#file-record.destination-record-folder.display-label=File record
# Create record
create-record.title=Create record
# FIXME!!!
#create-record.description=The rule is applied to all items that...
# Declare record
declare-record.title=Declare record
# FIXME!!!
#declare-record.description=The rule is applied to all items that...

View File

@@ -0,0 +1,256 @@
package org.alfresco.module.org_alfresco_module_rm.action.dm;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.OwnableService;
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;
public class DeclareRecordAction extends ActionExecuterAbstractBase implements RecordsManagementModel
{
/** I18N */
private static final String MSG_NO_DECLARE_MAND_PROP = "rm.action.no-declare-mand-prop";
/** Logger */
private static Log logger = LogFactory.getLog(DeclareRecordAction.class);
/** Record service */
private RecordService recordService;
/** Record management service */
private RecordsManagementService recordsManagementService;
/** Node service */
private NodeService nodeService;
/** Ownable service **/
private OwnableService ownableService;
/** Dictionary service */
private DictionaryService dictionaryService;
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* @param recordsManagementService records management service
*/
public void setRecordsManagementService(
RecordsManagementService recordsManagementService)
{
this.recordsManagementService = recordsManagementService;
}
/**
* @param nodeService node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param ownableSerice ownable serice
*/
public void setOwnableService(OwnableService ownableService)
{
this.ownableService = ownableService;
}
/**
* @param dictionaryService dictionary service
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
@Override
protected void executeImpl(Action action, final NodeRef actionedUponNodeRef)
{
// skip everything if the actioned upon node reference is already a record
if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_RECORD) == false)
{
// TODO we should use the file plan passed as a parameter
// grab the file plan
List<NodeRef> filePlans = recordsManagementService.getFilePlans();
if (filePlans.size() == 1)
{
// TODO parameterise the action with the file plan
final NodeRef filePlan = filePlans.get(0);
// run record creation as system
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
// create record from existing document
recordService.createRecordFromDocument(filePlan, actionedUponNodeRef);
return null;
}
});
// DEMO CODE
if (nodeService.getProperty(actionedUponNodeRef, PROP_ORIGINATOR) == null)
{
nodeService.setProperty(actionedUponNodeRef, PROP_ORIGINATOR, "Michelle Smith");
}
if (nodeService.getProperty(actionedUponNodeRef, PROP_ORIGINATING_ORGANIZATION) == null)
{
nodeService.setProperty(actionedUponNodeRef, PROP_ORIGINATING_ORGANIZATION, "Customer Service");
}
if (nodeService.getProperty(actionedUponNodeRef, PROP_PUBLICATION_DATE) == null)
{
nodeService.setProperty(actionedUponNodeRef, PROP_PUBLICATION_DATE, new Date());
}
if (recordService.isDeclared(actionedUponNodeRef) == false)
{
List<String> missingProperties = new ArrayList<String>(5);
// Aspect not already defined - check mandatory properties then add
if (mandatoryPropertiesSet(actionedUponNodeRef, missingProperties) == true)
{
// Add the declared aspect
Map<QName, Serializable> declaredProps = new HashMap<QName, Serializable>(2);
declaredProps.put(PROP_DECLARED_AT, new Date());
declaredProps.put(PROP_DECLARED_BY, AuthenticationUtil.getRunAsUser());
nodeService.addAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD, declaredProps);
// remove all owner related rights
ownableService.setOwner(actionedUponNodeRef, OwnableService.NO_OWNER);
}
else
{
throw new AlfrescoRuntimeException(buildMissingPropertiesErrorString(missingProperties));
}
}
}
else
{
throw new AlfrescoRuntimeException("Unable to find file plan.");
}
}
}
private String buildMissingPropertiesErrorString(List<String> missingProperties)
{
StringBuilder builder = new StringBuilder(255);
builder.append(I18NUtil.getMessage(MSG_NO_DECLARE_MAND_PROP));
builder.append(" ");
for (String missingProperty : missingProperties)
{
builder.append(missingProperty)
.append(", ");
}
return builder.toString();
}
/**
* Helper method to check whether all the mandatory properties of the node have been set
*
* @param nodeRef
* node reference
* @return boolean true if all mandatory properties are set, false otherwise
*/
private boolean mandatoryPropertiesSet(NodeRef nodeRef, List<String> missingProperties)
{
boolean result = true;
Map<QName, Serializable> nodeRefProps = nodeService.getProperties(nodeRef);
QName nodeRefType = nodeService.getType(nodeRef);
TypeDefinition typeDef = dictionaryService.getType(nodeRefType);
for (PropertyDefinition propDef : typeDef.getProperties().values())
{
if (propDef.isMandatory() == true)
{
if (nodeRefProps.get(propDef.getName()) == null)
{
logMissingProperty(propDef, missingProperties);
result = false;
break;
}
}
}
if (result != false)
{
Set<QName> aspects = this.nodeService.getAspects(nodeRef);
for (QName aspect : aspects)
{
AspectDefinition aspectDef = dictionaryService.getAspect(aspect);
for (PropertyDefinition propDef : aspectDef.getProperties().values())
{
if (propDef.isMandatory() == true)
{
if (nodeRefProps.get(propDef.getName()) == null)
{
logMissingProperty(propDef, missingProperties);
result = false;
break;
}
}
}
}
}
return result;
}
/**
* Log information about missing properties.
*
* @param propDef property definition
* @param missingProperties missing properties
*/
private void logMissingProperty(PropertyDefinition propDef, List<String> missingProperties)
{
if (logger.isWarnEnabled())
{
StringBuilder msg = new StringBuilder();
msg.append("Mandatory property missing: ").append(propDef.getName());
logger.warn(msg.toString());
}
missingProperties.add(propDef.getName().toString());
}
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
// TODO eventually we will need to pass in the file plan as a parameter
// TODO .. or the RM site
}
}