Merged DEV/INPLACE to HEAD :

41707: RM: Transparent records management prototype WIP
       * Create Record service and refactor
       * Add 'createRecord' method that preserves origional location(s) of the content
       * Add content readers information to record on extended security aspect
       * Experimental dynamic authority
       * DM action to 'create' record
       * Behaviour and methods to create and get new record container
   41708: RM: In-place filing prototype WIP
   42063: RM: Inplace filing prototype
       * extension of seciruty service to allow management of extended readers
       * extended reader maintained within file plan hierarchy
       * support ready for removal (ie move) and overlapping of readers in hirearchy (maintained in reference counting map)
       * general rename to "Unfiled Records" rather than "New Records"
       * File plan unfiled records filter
       * Unit tests
       * Correct permissions on created unfiled container (file for admin as per file plan root)
       * record readers dynamic authority applied to file plan components on bootstrap and creation
   42374: RM InPlace Prototype:

       * permission mapping improvements ... allows filling and declaration of unfiled records
       * actions of 'records' in doc lib are shown as restricted rm list
       * "Record" banner is shown in doc lib if content is a record (this differs from the normal record view where the undeclared status is shown, this isn't relevant for a content user)
       * linked to many record folders indicator not shown unless it really is linked to many record folders

   42700: RM Prototype:
       * stoppped hidden RM actions from appearing in UI
       * added file record action (TODO run-as RecordsManager and make applicable via aspect)
       * added hook points to allow customisation of Rule UI and customised for file record action
   43030: RM: In-place prototype
   43238: Rule editing fixed
   43332: 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.
   43348: DeclareRecordAction: The actioned upon node should be a record no need to create a record from the actioned node. If it is not a record an error should be thrown. If a user wants to create and declare a file as record a composite rule can be used.



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@43934 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2012-11-26 05:45:48 +00:00
65 changed files with 1790 additions and 6321 deletions

View File

@@ -71,15 +71,14 @@ public class RecordsManagementServiceRegistryImpl extends ServiceDescriptorRegis
{
return (RecordsManagementService)getService(RECORDS_MANAGEMENT_SERVICE);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry#getRecordService()
*/
@Override
public RecordService getRecordService()
{
return (RecordService)getService(RECORD_SERVICE);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry#getRecordService()
*/
public RecordService getRecordService()
{
return (RecordService)getService(RECORD_SERVICE);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry#getRecordsManagementSecurityService()

View File

@@ -101,6 +101,9 @@ public abstract class RMActionExecuterAbstractBase extends ActionExecuterAbstra
/** Records management service */
protected RecordsManagementService recordsManagementService;
/** Record service */
protected RecordService recordService;
/** Disposition service */
protected DispositionService dispositionService;
@@ -119,9 +122,6 @@ public abstract class RMActionExecuterAbstractBase extends ActionExecuterAbstra
/** Freeze Service */
protected FreezeService freezeService;
/** Record Service */
protected RecordService recordService;
protected LinkedList<AbstractCapability> capabilities = new LinkedList<AbstractCapability>();;
/** Default constructor */
@@ -301,12 +301,23 @@ public abstract class RMActionExecuterAbstractBase extends ActionExecuterAbstra
PropertyCheck.mandatory(this, "recordsManagementService", recordsManagementService);
PropertyCheck.mandatory(this, "recordsManagementAdminService", recordsManagementAdminService);
PropertyCheck.mandatory(this, "recordsManagementEventService", recordsManagementEventService);
for(AbstractCapability capability : capabilities)
{
capability.registerAction(this);
}
}
/**
* Indicates whether this records management action is public or not
*
* @return boolean true if public, false otherwise
*/
public boolean isPublicAction()
{
return publicAction;
}
/**
* @see org.alfresco.repo.action.CommonResourceAbstractBase#setBeanName(java.lang.String)
*/

View File

@@ -100,7 +100,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
if (this.recordsManagementService.isRecord(actionedUponNodeRef) == true)
{
// Can only execute disposition action on record if declared
if (this.recordsManagementService.isRecordDeclared(actionedUponNodeRef) == true)
if (recordService.isDeclared(actionedUponNodeRef) == true)
{
// Indicate that the disposition action is underway
this.nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_AT, new Date());
@@ -315,7 +315,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
if (this.recordsManagementService.isRecord(filePlanComponent) == true)
{
// Can only execute disposition action on record if declared
if (this.recordsManagementService.isRecordDeclared(filePlanComponent) == true)
if (recordService.isDeclared(filePlanComponent) == true)
{
return true;
}

View File

@@ -0,0 +1,128 @@
/*
* 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.action.dm;
import java.util.List;
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.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
/**
* Creates a new record from an existing content object.
*
* Note: This is a 'normal' dm action, rather than a records management action.
*
* @author Roy Wetherall
*/
public class CreateRecordAction extends ActionExecuterAbstractBase
implements RecordsManagementModel
{
/** Action name */
public static final String NAME = "create-record";
/** Records management service */
private RecordsManagementService recordsManagementService;
/** Record service */
private RecordService recordService;
/** Node service */
private NodeService nodeService;
/**
* @param recordsManagementService records management service
*/
public void setRecordsManagementService(RecordsManagementService recordsManagementService)
{
this.recordsManagementService = recordsManagementService;
}
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* @param nodeService node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@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;
}
});
}
else
{
throw new AlfrescoRuntimeException("Unable to find file plan.");
}
}
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefinitions(List<ParameterDefinition> params)
{
// TODO eventually we will need to pass in the file plan as a parameter
// TODO .. or the RM site
}
}

View File

@@ -0,0 +1,219 @@
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.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_UNDECLARED_ONLY_RECORDS = "rm.action.undeclared-only-records";
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)
{
if (recordService.isRecord(actionedUponNodeRef) == true)
{
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(I18NUtil.getMessage(MSG_UNDECLARED_ONLY_RECORDS, actionedUponNodeRef.toString()));
}
}
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)
{
// No parameters
}
}

View File

@@ -0,0 +1,70 @@
package org.alfresco.module.org_alfresco_module_rm.action.dm;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.action.ParameterDefinitionImpl;
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.DataTypeDefinition;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
public class FileRecordAction extends ActionExecuterAbstractBase
{
public static final String NAME = "file-record";
public static final String PARAM_DESTINATION_RECORD_FOLDER = "destination-record-folder";
/**
* FileFolder service
*/
private FileFolderService fileFolderService;
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(
PARAM_DESTINATION_RECORD_FOLDER,
DataTypeDefinition.NODE_REF,
true,
getParamDisplayLabel(PARAM_DESTINATION_RECORD_FOLDER)));
}
/**
* @see org.alfresco.repo.action.executer.ActionExecuter#execute(org.alfresco.repo.ref.NodeRef, org.alfresco.repo.ref.NodeRef)
*/
public void executeImpl(final Action ruleAction, final NodeRef actionedUponNodeRef)
{
final NodeRef destinationParent = (NodeRef)ruleAction.getParameterValue(PARAM_DESTINATION_RECORD_FOLDER);
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
try
{
fileFolderService.move(actionedUponNodeRef, destinationParent, null);
}
catch (FileNotFoundException e)
{
throw new AlfrescoRuntimeException("Could not file record.", e);
}
return null;
}
});
}
}

View File

@@ -114,7 +114,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase
if (recordsManagementService.isRecord(actionedUponNodeRef) == true)
{
if (recordsManagementService.isRecordDeclared(actionedUponNodeRef) == false)
if (recordService.isDeclared(actionedUponNodeRef) == false)
{
ChildAssociationRef parent = nodeService.getPrimaryParent(actionedUponNodeRef);
@@ -175,7 +175,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase
{
if (recordsManagementService.isRecord(filePlanComponent) == true)
{
if (recordsManagementService.isRecordDeclared(filePlanComponent))
if (recordService.isDeclared(filePlanComponent))
{
if (throwException)
{

View File

@@ -48,7 +48,7 @@ public class UndeclareRecordAction extends RMActionExecuterAbstractBase
{
if (recordsManagementService.isRecord(actionedUponNodeRef) == true)
{
if (recordsManagementService.isRecordDeclared(actionedUponNodeRef) == true)
if (recordService.isDeclared(actionedUponNodeRef) == true)
{
// Remove the declared aspect
this.nodeService.removeAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD);
@@ -73,7 +73,7 @@ public class UndeclareRecordAction extends RMActionExecuterAbstractBase
{
if (recordsManagementService.isRecord(filePlanComponent) == true)
{
if (recordsManagementService.isRecordDeclared(filePlanComponent) == true)
if (recordService.isDeclared(filePlanComponent) == true)
{
return true;
}

View File

@@ -18,6 +18,7 @@
*/
package org.alfresco.module.org_alfresco_module_rm.capability;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
import org.alfresco.repo.action.RuntimeActionService;
@@ -59,7 +60,10 @@ public class RMActionProxyFactoryBean extends ProxyFactoryBean
{
public Void doWork() throws Exception
{
runtimeActionService.registerActionExecuter((ActionExecuter) getObject());
if (((RMActionExecuterAbstractBase)getTargetSource().getTarget()).isPublicAction() == true)
{
runtimeActionService.registerActionExecuter((ActionExecuter) getObject());
}
recordsManagementActionService.register((RecordsManagementAction) getObject());
return null;
}

View File

@@ -61,6 +61,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
* RM After Invocation Provider
*/
public class RMAfterInvocationProvider extends RMSecurityCommon
implements AfterInvocationProvider, InitializingBean
{

View File

@@ -22,7 +22,7 @@ import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigComponent;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -31,6 +31,9 @@ import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @author Roy Wetherall
@@ -42,6 +45,8 @@ public class RMSecurityCommon
private static Log logger = LogFactory.getLog(RMSecurityCommon.class);
private ApplicationContext applicationContext;
protected NodeService nodeService;
protected PermissionService permissionService;
protected RecordsManagementService rmService;

View File

@@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.capability.declarative;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
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.record.RecordService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
import org.springframework.beans.factory.BeanNameAware;
@@ -39,6 +40,7 @@ public abstract class AbstractCapabilityCondition implements CapabilityCondition
/** Services */
protected RecordsManagementService rmService;
protected RecordService recordService;
protected PermissionService permissionService;
protected NodeService nodeService;
protected FreezeService freezeService;
@@ -51,6 +53,14 @@ public abstract class AbstractCapabilityCondition implements CapabilityCondition
this.rmService = rmService;
}
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* @param permissionService permission service
*/

View File

@@ -128,6 +128,9 @@ public class DeclarativeCapability extends AbstractCapability
this.isUndetermined = isUndetermined;
}
/**
* @return
*/
public boolean isUndetermined()
{
return isUndetermined;

View File

@@ -33,7 +33,7 @@ public class DeclaredCapabilityCondition extends AbstractCapabilityCondition
boolean result = false;
if (FilePlanComponentKind.RECORD.equals(rmService.getFilePlanComponentKind(nodeRef)) == true)
{
result = rmService.isRecordDeclared(nodeRef);
result = recordService.isDeclared(nodeRef);
}
return result;
}

View File

@@ -26,6 +26,7 @@ import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.capability.declarative.DeclarativeCapability;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
@@ -37,6 +38,13 @@ import org.alfresco.service.namespace.QName;
*/
public class CreateCapability extends DeclarativeCapability
{
private RecordService recordService;
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.capability.Capability#evaluate(org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -70,7 +78,7 @@ public class CreateCapability extends DeclarativeCapability
{
if(linkee == null)
{
if(rmService.isRecord(destination) && rmService.isRecordDeclared(destination) == false)
if(rmService.isRecord(destination) && recordService.isDeclared(destination) == false)
{
if (permissionService.hasPermission(destination, RMPermissionModel.FILE_RECORDS) == AccessStatus.ALLOWED)
{
@@ -80,7 +88,7 @@ public class CreateCapability extends DeclarativeCapability
}
else
{
if(rmService.isRecord(linkee) && rmService.isRecord(destination) && rmService.isRecordDeclared(destination) == false)
if(rmService.isRecord(linkee) && rmService.isRecord(destination) && recordService.isDeclared(destination) == false)
{
if (permissionService.hasPermission(destination, RMPermissionModel.FILE_RECORDS) == AccessStatus.ALLOWED)
{

View File

@@ -9,8 +9,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Map.Entry;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
@@ -20,7 +20,7 @@ import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService;
import org.alfresco.module.org_alfresco_module_rm.security.Role;
import org.alfresco.repo.security.authentication.AuthenticationUtil;

View File

@@ -25,6 +25,7 @@ import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementAdminService;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.repo.forms.Field;
import org.alfresco.repo.forms.FieldGroup;
import org.alfresco.repo.forms.Form;
@@ -58,6 +59,7 @@ public abstract class RecordsManagementFormFilter<ItemType> extends AbstractFilt
protected RecordsManagementServiceRegistry rmServiceRegistry;
protected RecordsManagementService rmService;
protected RecordsManagementAdminService rmAdminService;
protected RecordService recordService;
/**
* Sets the NamespaceService instance
@@ -109,6 +111,14 @@ public abstract class RecordsManagementFormFilter<ItemType> extends AbstractFilt
this.rmAdminService = rmAdminService;
}
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* Add property fields to group
*

View File

@@ -167,7 +167,7 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter
protected void addRecordMetadataPropertyFieldsToGroup(Form form, NodeRef nodeRef)
{
Set<QName> aspects = rmService.getRecordMetaDataAspects();
Set<QName> aspects = recordService.getRecordMetaDataAspects();
for (QName aspect : aspects)
{
@@ -215,7 +215,7 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter
{
if (rmService.isRecord(nodeRef) == true)
{
addTransientPropertyField(form, TRANSIENT_DECLARED, DataTypeDefinition.BOOLEAN, rmService.isRecordDeclared(nodeRef));
addTransientPropertyField(form, TRANSIENT_DECLARED, DataTypeDefinition.BOOLEAN, recordService.isDeclared(nodeRef));
}
DispositionSchedule ds = dispositionService.getDispositionSchedule(nodeRef);

View File

@@ -120,7 +120,7 @@ public class IdentifierServiceImpl implements IdentifierService
}
/**
* Generate an identifier for a given type of object with the acompanying context.
* Generate an identifier for a given type of object with the accompanying context.
*
* @param type content type
* @param context context

View File

@@ -29,6 +29,7 @@ import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
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.record.RecordService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
@@ -50,6 +51,9 @@ public abstract class BaseEvaluator implements RecordsManagementModel
/** Records management service */
protected RecordsManagementService recordsManagementService;
/** Record service */
protected RecordService recordService;
/** Node service */
protected NodeService nodeService;
@@ -84,6 +88,14 @@ public abstract class BaseEvaluator implements RecordsManagementModel
this.recordsManagementService = recordsManagementService;
}
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* @param nodeService node service
*/

View File

@@ -25,6 +25,7 @@ import org.alfresco.module.org_alfresco_module_rm.FilePlanComponentKind;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
@@ -41,6 +42,9 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
/** Records management service */
private RecordsManagementService recordsManagementService;
/** Record service */
private RecordService recordService;
/** Capability service */
private CapabilityService capabilityService;
@@ -56,7 +60,15 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
public void setRecordsManagementService(RecordsManagementService recordsManagementService)
{
this.recordsManagementService = recordsManagementService;
}
}
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* @param capabilityService capability service
@@ -128,7 +140,11 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
rmNodeValues.put("kind", kind.toString());
// File plan node reference
rmNodeValues.put("filePlan", recordsManagementService.getFilePlan(nodeRef).toString());
NodeRef filePlan = recordsManagementService.getFilePlan(nodeRef);
rmNodeValues.put("filePlan", filePlan.toString());
// Unfiled container node reference
rmNodeValues.put("unfiledRecordContainer", recordService.getUnfiledRecordContainer(filePlan).toString());
// Set the indicators array
setIndicators(rmNodeValues, nodeRef);
@@ -219,7 +235,7 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
}
else
{
if (recordsManagementService.isRecordDeclared(nodeRef) == true)
if (recordService.isDeclared(nodeRef) == true)
{
result = "record";
}

View File

@@ -22,19 +22,39 @@ import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.jscript.app.BaseEvaluator;
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.RegexQNamePattern;
/**
* Determines whether a node has multiple parents within a file plan
*
* @author Roy Wetherall
*/
public class MultiParentEvaluator extends BaseEvaluator
{
@Override
protected boolean evaluateImpl(NodeRef nodeRef)
{
List<ChildAssociationRef> parents = nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
return (parents.size() > 1);
protected boolean evaluateImpl(final NodeRef nodeRef)
{
return AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
{
@Override
public Boolean doWork() throws Exception
{
List<ChildAssociationRef> parents = nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
int count = 0;
for (ChildAssociationRef parent : parents)
{
if (nodeService.hasAspect(parent.getParentRef(), ASPECT_FILE_PLAN_COMPONENT) == true)
{
count++;
}
}
return (count > 1);
}
});
}
}

View File

@@ -35,7 +35,7 @@ public class SplitEmailActionEvaluator extends BaseEvaluator
protected boolean evaluateImpl(NodeRef nodeRef)
{
boolean result = false;
if (recordsManagementService.isRecordDeclared(nodeRef) == false)
if (recordService.isDeclared(nodeRef) == false)
{
ContentData contentData = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
if (contentData != null)

View File

@@ -231,4 +231,5 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
// Extended readers aspect
public static final QName ASPECT_EXTENDED_READERS = QName.createQName(RM_URI, "extendedReaders");
public static final QName PROP_READERS = QName.createQName(RM_URI, "readers");
}

View File

@@ -16,12 +16,13 @@
* 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;
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.copy.AbstractCopyBehaviourCallback;
import org.alfresco.repo.copy.CopyBehaviourCallback;
import org.alfresco.repo.copy.CopyDetails;

View File

@@ -0,0 +1,90 @@
/*
* 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.behaviour;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
/**
* Behaviour associated with the file plan type
*
* @author Roy Wetherall
*/
public class FilePlanType implements RecordsManagementModel,
NodeServicePolicies.OnCreateNodePolicy
{
/** Policy component */
private PolicyComponent policyComponent;
/** Node service */
private NodeService nodeService;
/** Permission service */
private PermissionService permissionService;
/** New record container name */
private static final String NAME_NR_CONTAINER = "New Records";
/**
* Set the policy component
* @param policyComponent policy component
*/
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
/**
* Set node service
* @param nodeService node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
/**
* Bean initialisation method
*/
public void init()
{
// policyComponent.bindClassBehaviour(
// NodeServicePolicies.OnCreateNodePolicy.QNAME,
// TYPE_FILE_PLAN,
// new JavaBehaviour(this, "onCreateNode", NotificationFrequency.TRANSACTION_COMMIT));
}
/**
* @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef)
*/
@Override
public void onCreateNode(ChildAssociationRef assoc)
{
// TODO refactor the file plan behaviours from the service code
}
}

View File

@@ -16,11 +16,12 @@
* 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;
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;

View File

@@ -16,11 +16,12 @@
* 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;
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
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.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;

View File

@@ -16,7 +16,7 @@
* 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;
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
import java.io.Serializable;
import java.util.ArrayList;
@@ -26,6 +26,7 @@ import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.copy.AbstractCopyBehaviourCallback;
import org.alfresco.repo.copy.CopyBehaviourCallback;
import org.alfresco.repo.copy.CopyDetails;

View File

@@ -16,7 +16,7 @@
* 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;
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
import java.io.Serializable;
import java.util.ArrayList;
@@ -36,6 +36,7 @@ import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedul
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionScheduleImpl;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.event.EventCompletionDetails;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordDefinition;
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService;
import org.alfresco.repo.policy.JavaBehaviour;
@@ -315,13 +316,22 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
}
}
public void onAddRecordAspect(NodeRef nodeRef, QName aspectTypeQName)
public void onAddRecordAspect(final NodeRef nodeRef, final QName aspectTypeQName)
{
if (nodeService.exists(nodeRef) == true)
AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Void>()
{
applySearchAspect(nodeRef);
setupDispositionScheduleProperties(nodeRef);
}
@Override
public Void doWork() throws Exception
{
if (nodeService.exists(nodeRef) == true)
{
applySearchAspect(nodeRef);
setupDispositionScheduleProperties(nodeRef);
}
return null;
}
});
}
public void recordFolderCreate(ChildAssociationRef childAssocRef)
@@ -494,20 +504,28 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
}
}
public void rmSearchAspectAdd(NodeRef nodeRef, QName aspectTypeQName)
{
if (nodeService.exists(nodeRef) == true)
public void rmSearchAspectAdd(final NodeRef nodeRef, final QName aspectTypeQName)
{
AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Void>()
{
// Initialise the search parameters as required
setVitalRecordDefintionDetails(nodeRef);
}
@Override
public Void doWork() throws Exception
{
if (nodeService.exists(nodeRef) == true)
{
// Initialise the search parameteres as required
setVitalRecordDefintionDetails(nodeRef);
}
return null;
}
});
}
public void vitalRecordDefintionAddAspect(NodeRef nodeRef, QName aspectTypeQName)
{
// Only care about record folders or record categories
if (recordsManagementService.isRecordFolder(nodeRef) == true ||
recordsManagementService.isRecordCategory(nodeRef) == true)
// Only care about record folders
if (recordsManagementService.isRecordFolder(nodeRef) == true)
{
updateVitalRecordDefinitionValues(nodeRef);
}
@@ -515,9 +533,8 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
public void vitalRecordDefintionUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
{
// Only care about record folders or record categories
if (recordsManagementService.isRecordFolder(nodeRef) == true ||
recordsManagementService.isRecordCategory(nodeRef) == true)
// Only care about record folders
if (recordsManagementService.isRecordFolder(nodeRef) == true)
{
Set<QName> props = new HashSet<QName>(1);
props.add(PROP_REVIEW_PERIOD);
@@ -537,17 +554,14 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
applySearchAspect(nodeRef);
setVitalRecordDefintionDetails(nodeRef);
if (recordsManagementService.isRecordFolder(nodeRef) == true)
{
List<NodeRef> records = recordsManagementService.getRecords(nodeRef);
for (NodeRef record : records)
{
// Apply the search aspect
applySearchAspect(record);
// Set the vital record definition details
setVitalRecordDefintionDetails(record);
}
List<NodeRef> records = recordsManagementService.getRecords(nodeRef);
for (NodeRef record : records)
{
// Apply the search aspect
applySearchAspect(record);
// Set the vital record definition details
setVitalRecordDefintionDetails(record);
}
}

View File

@@ -16,8 +16,9 @@
* 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;
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
@@ -55,6 +56,9 @@ public class RmSiteType implements RecordsManagementModel,
/** Record Management Search Service */
private RecordsManagementSearchService recordsManagementSearchService;
/** Behaviour */
JavaBehaviour behaviour = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.FIRST_EVENT);
/**
* Set the policy component
* @param policyComponent policy component
@@ -98,7 +102,7 @@ public class RmSiteType implements RecordsManagementModel,
policyComponent.bindClassBehaviour(
NodeServicePolicies.OnCreateNodePolicy.QNAME,
TYPE_RM_SITE,
new JavaBehaviour(this, "onCreateNode", NotificationFrequency.FIRST_EVENT));
behaviour);
}
/**
@@ -107,33 +111,41 @@ public class RmSiteType implements RecordsManagementModel,
@Override
public void onCreateNode(ChildAssociationRef childAssocRef)
{
final NodeRef rmSite = childAssocRef.getChildRef();
// Do not execute behaviour if this has been created in the archive store
if(rmSite.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE) == true)
{
// This is not the spaces store - probably the archive store
return;
}
if (nodeService.exists(rmSite) == true)
{
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
behaviour.disable();
try
{
final NodeRef rmSite = childAssocRef.getChildRef();
// Do not execute behaviour if this has been created in the archive store
if(rmSite.getStoreRef().equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE) == true)
{
public Object doWork()
// This is not the spaces store - probably the archive store
return;
}
if (nodeService.exists(rmSite) == true)
{
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
{
SiteInfo siteInfo = siteService.getSite(rmSite);
if (siteInfo != null)
{
// Create the file plan component
siteService.createContainer(siteInfo.getShortName(), COMPONENT_DOCUMENT_LIBRARY, TYPE_FILE_PLAN, null);
// Add the reports
recordsManagementSearchService.addReports(siteInfo.getShortName());
}
return null;
}
}, AuthenticationUtil.getAdminUserName());
}
public Object doWork()
{
SiteInfo siteInfo = siteService.getSite(rmSite);
if (siteInfo != null)
{
// Create the file plan component
siteService.createContainer(siteInfo.getShortName(), COMPONENT_DOCUMENT_LIBRARY, TYPE_FILE_PLAN, null);
// Add the reports
recordsManagementSearchService.addReports(siteInfo.getShortName());
}
return null;
}
}, AuthenticationUtil.getAdminUserName());
}
}
finally
{
behaviour.enable();
}
}
}

View File

@@ -16,9 +16,10 @@
* 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;
package org.alfresco.module.org_alfresco_module_rm.model.behaviour;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;

View File

@@ -1,370 +0,0 @@
package org.alfresco.module.org_alfresco_module_rm.permission;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.domain.permissions.AclDAO;
import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessControlList;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.ModelDAO;
import org.alfresco.repo.security.permissions.impl.PermissionServiceImpl;
import org.alfresco.repo.security.permissions.impl.RequiredPermission;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
public class OtherImpl extends PermissionServiceImpl
{
static SimplePermissionReference RM_OLD_ALL_PERMISSIONS_REFERENCE = SimplePermissionReference.getPermissionReference(
QName.createQName("", PermissionService.ALL_PERMISSIONS),
PermissionService.ALL_PERMISSIONS);
private SimpleCache<Serializable, Set<String>> rmReadersCache;
private AclDAO rmAclDaoComponent;
private ModelDAO rmModelDao;
public void setRmReadersCache(SimpleCache<Serializable, Set<String>> rmReadersCache)
{
this.rmReadersCache = rmReadersCache;
}
public void setRmAclDAO(AclDAO rmAclDaoComponent)
{
this.rmAclDaoComponent = rmAclDaoComponent;
}
public void setRmModelDAO(ModelDAO rmModelDao)
{
this.rmModelDao = rmModelDao;
}
@Override
public void setAnyDenyDenies(boolean anyDenyDenies)
{
super.setAnyDenyDenies(anyDenyDenies);
rmReadersCache.clear();
}
@Override
public Set<String> getReaders(Long aclId)
{
Set<String> dmReaders = super.getReaders(aclId);
Set<String> rmReaders = rmReadersCache.get(aclId);
if (rmReaders == null)
{
rmReaders = buildRMReaders(aclId);
rmReadersCache.put(aclId, rmReaders);
}
Set<String> result = new HashSet<String>();
result.addAll(dmReaders);
result.addAll(rmReaders);
return result;
}
private Set<String> buildRMReaders(Long aclId)
{
AccessControlList acl = rmAclDaoComponent.getAccessControlList(aclId);
if (acl == null)
{
return Collections.emptySet();
}
HashSet<String> assigned = new HashSet<String>();
HashSet<String> readers = new HashSet<String>();
for (AccessControlEntry ace : acl.getEntries())
{
assigned.add(ace.getAuthority());
}
PermissionReference permissionRef = getPermissionReference(RMPermissionModel.READ_RECORDS);
for (String authority : assigned)
{
RMUnconditionalAclTest rmTest = new RMUnconditionalAclTest(permissionRef);
if (rmTest.evaluate(authority, aclId))
{
readers.add(authority);
}
}
return Collections.unmodifiableSet(readers);
}
/**
* Ignores type and aspect requirements on the node
*
*/
private class RMUnconditionalAclTest
{
/*
* The required permission.
*/
PermissionReference required;
/*
* Granters of the permission
*/
Set<PermissionReference> granters;
/*
* The additional permissions required at the node level.
*/
Set<PermissionReference> nodeRequirements = new HashSet<PermissionReference>();
/*
* Constructor just gets the additional requirements
*/
RMUnconditionalAclTest(PermissionReference required)
{
this.required = required;
// Set the required node permissions
if (required.equals(getPermissionReference(ALL_PERMISSIONS)))
{
nodeRequirements = rmModelDao.getUnconditionalRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), RequiredPermission.On.NODE);
}
else
{
nodeRequirements = rmModelDao.getUnconditionalRequiredPermissions(required, RequiredPermission.On.NODE);
}
if (rmModelDao.getUnconditionalRequiredPermissions(required, RequiredPermission.On.PARENT).size() > 0)
{
throw new IllegalStateException("Parent permissions can not be checked for an acl");
}
if (rmModelDao.getUnconditionalRequiredPermissions(required, RequiredPermission.On.CHILDREN).size() > 0)
{
throw new IllegalStateException("Child permissions can not be checked for an acl");
}
// Find all the permissions that grant the allowed permission
// All permissions are treated specially.
granters = new LinkedHashSet<PermissionReference>(128, 1.0f);
granters.addAll(rmModelDao.getGrantingPermissions(required));
granters.add(getAllPermissionReference());
granters.add(RM_OLD_ALL_PERMISSIONS_REFERENCE);
}
/**
* Internal hook point for recursion
*
* @param authorisations
* @param nodeRef
* @param denied
* @param recursiveIn
* @return true if granted
*/
boolean evaluate(String authority, Long aclId)
{
// Start out true and "and" all other results
boolean success = true;
// Check the required permissions but not for sets they rely on
// their underlying permissions
//if (modelDAO.checkPermission(required))
//{
// We have to do the test as no parent will help us out
success &= hasSinglePermission(authority, aclId);
if (!success)
{
return false;
}
//}
// Check the other permissions required on the node
for (PermissionReference pr : nodeRequirements)
{
// Build a new test
RMUnconditionalAclTest nt = new RMUnconditionalAclTest(pr);
success &= nt.evaluate(authority, aclId);
if (!success)
{
return false;
}
}
return success;
}
boolean hasSinglePermission(String authority, Long aclId)
{
// Check global permission
if (checkGlobalPermissions(authority))
{
return true;
}
if(aclId == null)
{
return false;
}
else
{
return checkRequired(authority, aclId);
}
}
/**
* Check if we have a global permission
*
* @param authorisations
* @return true if granted
*/
private boolean checkGlobalPermissions(String authority)
{
for (PermissionEntry pe : rmModelDao.getGlobalPermissionEntries())
{
if (isGranted(pe, authority))
{
return true;
}
}
return false;
}
/**
* Check that a given authentication is available on a node
*
* @param authorisations
* @param nodeRef
* @param denied
* @return true if a check is required
*/
boolean checkRequired(String authority, Long aclId)
{
AccessControlList acl = rmAclDaoComponent.getAccessControlList(aclId);
if (acl == null)
{
return false;
}
Set<Pair<String, PermissionReference>> denied = new HashSet<Pair<String, PermissionReference>>();
// Check if each permission allows - the first wins.
// We could have other voting style mechanisms here
for (AccessControlEntry ace : acl.getEntries())
{
if (isGranted(ace, authority, denied))
{
return true;
}
}
return false;
}
/**
* Is a permission granted
*
* @param pe -
* the permissions entry to consider
* @param granters -
* the set of granters
* @param authorisations -
* the set of authorities
* @param denied -
* the set of denied permissions/authority pais
* @return true if granted
*/
private boolean isGranted(AccessControlEntry ace, String authority, Set<Pair<String, PermissionReference>> denied)
{
// If the permission entry denies then we just deny
if (ace.getAccessStatus() == AccessStatus.DENIED)
{
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), ace.getPermission()));
Set<PermissionReference> granters = rmModelDao.getGrantingPermissions(ace.getPermission());
for (PermissionReference granter : granters)
{
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), granter));
}
// All the things granted by this permission must be
// denied
Set<PermissionReference> grantees = rmModelDao.getGranteePermissions(ace.getPermission());
for (PermissionReference grantee : grantees)
{
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), grantee));
}
// All permission excludes all permissions available for
// the node.
if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(RM_OLD_ALL_PERMISSIONS_REFERENCE))
{
for (PermissionReference deny : rmModelDao.getAllPermissions())
{
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), deny));
}
}
return false;
}
// The permission is allowed but we deny it as it is in the denied
// set
if (denied != null)
{
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(ace.getAuthority(), required);
if (denied.contains(specific))
{
return false;
}
}
// If the permission has a match in both the authorities and
// granters list it is allowed
// It applies to the current user and it is granted
if (authority.equals(ace.getAuthority()) && granters.contains(ace.getPermission()))
{
{
return true;
}
}
// Default deny
return false;
}
private boolean isGranted(PermissionEntry pe, String authority)
{
// If the permission entry denies then we just deny
if (pe.isDenied())
{
return false;
}
// If the permission has a match in both the authorities and
// granters list it is allowed
// It applies to the current user and it is granted
if (granters.contains(pe.getPermissionReference()) && authority.equals(pe.getAuthority()))
{
{
return true;
}
}
// Default deny
return false;
}
}
}

View File

@@ -33,8 +33,8 @@ import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.model.RmSiteType;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RmSiteType;
import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService;
import org.alfresco.module.org_alfresco_module_rm.security.Role;
import org.alfresco.repo.security.authentication.AuthenticationUtil;

View File

@@ -5,7 +5,7 @@ import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.dataset.DataSetService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.model.RmSiteType;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RmSiteType;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteService;
import org.apache.commons.lang.StringUtils;

View File

@@ -7,7 +7,7 @@ import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.dataset.DataSet;
import org.alfresco.module.org_alfresco_module_rm.dataset.DataSetService;
import org.alfresco.module.org_alfresco_module_rm.model.RmSiteType;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RmSiteType;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteService;
import org.apache.commons.lang.StringUtils;

View File

@@ -20,28 +20,28 @@ package org.alfresco.module.org_alfresco_module_rm.script;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RecordsManagementSearchBehaviour;
import org.alfresco.repo.exporter.ACPExportPackageHandler;
import org.alfresco.repo.web.scripts.content.StreamACP;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.view.ExporterCrawlerParameters;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.QName;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Creates an RM specific ACP file of nodes to export then streams it back

View File

@@ -24,7 +24,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.namespace.NamespaceService;
@@ -41,7 +41,7 @@ public class RecordMetaDataAspectsGet extends DeclarativeWebScript
{
protected DictionaryService dictionaryService;
protected NamespaceService namespaceService;
protected RecordsManagementService recordsManagementService;
protected RecordService recordService;
/**
* Set the dictionary service instance
@@ -62,10 +62,13 @@ public class RecordMetaDataAspectsGet extends DeclarativeWebScript
{
this.namespaceService = namespaceService;
}
public void setRecordsManagementService(RecordsManagementService recordsManagementService)
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordsManagementService = recordsManagementService;
this.recordService = recordService;
}
/*
@@ -75,7 +78,7 @@ public class RecordMetaDataAspectsGet extends DeclarativeWebScript
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
// Get the details of all the aspects
Set<QName> aspectQNames = recordsManagementService.getRecordMetaDataAspects();
Set<QName> aspectQNames = recordService.getRecordMetaDataAspects();
List<Map<String, Object>> aspects = new ArrayList<Map<String,Object>>(aspectQNames.size()+1);
for (QName aspectQName : aspectQNames)
{

View File

@@ -24,17 +24,17 @@ import java.io.IOException;
import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RecordsManagementSearchBehaviour;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.view.ExporterCrawlerParameters;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Streams the nodes of a transfer object to the client in the form of an

View File

@@ -25,7 +25,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementAdminService;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
@@ -43,35 +43,45 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
*/
public class RMSearchPropertiesGet extends DeclarativeWebScript
{
private RecordsManagementAdminService adminService;
private RecordsManagementService recordsManagementService;
private DictionaryService dictionaryService;
/** Services */
private RecordsManagementAdminService adminService;
private RecordService recordService;
private DictionaryService dictionaryService;
private NamespaceService namespaceService;
/**
* @param adminService records management admin service
*/
public void setAdminService(RecordsManagementAdminService adminService)
{
this.adminService = adminService;
}
public void setRecordsManagementService(RecordsManagementService recordsManagementService)
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordsManagementService = recordsManagementService;
this.recordService = recordService;
}
/**
* @param dictionaryService dictionary service
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* @param namespaceService namespace service
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/*
/**
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status, org.alfresco.web.scripts.Cache)
*/
@Override
@@ -81,7 +91,7 @@ public class RMSearchPropertiesGet extends DeclarativeWebScript
List<Group> groups = new ArrayList<Group>(5);
Set<QName> aspects = recordsManagementService.getRecordMetaDataAspects();
Set<QName> aspects = recordService.getRecordMetaDataAspects();
for (QName aspect : aspects)
{
Map<QName, PropertyDefinition> properties = dictionaryService.getPropertyDefs(aspect);

View File

@@ -392,25 +392,25 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
{
public Object doWork()
{
Set<AccessPermission> perms = permissionService.getAllSetPermissions(catNodeRef);
for (AccessPermission perm : perms)
{
if (ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) == false)
{
AccessStatus accessStatus = perm.getAccessStatus();
boolean allow = false;
if (AccessStatus.ALLOWED.equals(accessStatus) == true)
{
allow = true;
}
permissionService.setPermission(
folderNodeRef,
perm.getAuthority(),
perm.getPermission(),
allow);
}
}
Set<AccessPermission> perms = permissionService.getAllSetPermissions(catNodeRef);
for (AccessPermission perm : perms)
{
if (ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) == false)
{
AccessStatus accessStatus = perm.getAccessStatus();
boolean allow = false;
if (AccessStatus.ALLOWED.equals(accessStatus) == true)
{
allow = true;
}
permissionService.setPermission(
folderNodeRef,
perm.getAuthority(),
perm.getPermission(),
allow);
}
}
return null;
}
}, AuthenticationUtil.getSystemUserName());