mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-1635: Recordable Version Store Service Prototype
* integration tests to ensure recorded version retireves the state of the versioned content accurately * various improvements to satisfy tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@81055 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -70,6 +70,10 @@
|
||||
<title>Record Node Reference</title>
|
||||
<type>d:noderef</type>
|
||||
<index enabled="false"/>
|
||||
</property><property name="rmv:frozenOwner">
|
||||
<title>Frozen Owner</title>
|
||||
<type>d:text</type>
|
||||
<index enabled="false"/>
|
||||
</property>
|
||||
</properties>
|
||||
</aspect>
|
||||
|
@@ -18,6 +18,9 @@
|
||||
<property name="namespaceService" ref="NamespaceService"/>
|
||||
</bean>
|
||||
|
||||
<!-- Authentication Helper -->
|
||||
<bean name="rm.authenticationUtil" class="org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil"/>
|
||||
|
||||
<!-- Import extended repository context -->
|
||||
|
||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/extended-repository-context.xml"/>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<bean id="baseService" abstract="true">
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="dictionaryService" ref="DictionaryService"/>
|
||||
<property name="authenticationUtil" ref="rm.authenticationUtil"/>
|
||||
</bean>
|
||||
|
||||
<!-- Records Management Service Registry -->
|
||||
@@ -1086,6 +1087,8 @@
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.disablePropertyEditableCheck=RM_ALLOW
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.enablePropertyEditableCheck=RM_ALLOW
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.getRecordMetaDataAspects=RM_ALLOW
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.isRecordMetadataAspect=RM_ALLOW
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.isRecordMetadataProperty=RM_ALLOW
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.getRecordMetadataAspects=RM.Read.0
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.isRecord=ACL_ALLOW,RM_ALLOW
|
||||
org.alfresco.module.org_alfresco_module_rm.record.RecordService.isDeclared=RM.Read.0
|
||||
|
@@ -16,6 +16,10 @@
|
||||
<bean id="rm.versionService" abstract="true" class="org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl">
|
||||
<property name="filePlanService" ref="FilePlanService" />
|
||||
<property name="fileFolderService" ref="fileFolderService" />
|
||||
<property name="extendedPermissionService" ref="ExtendedPermissionService" />
|
||||
<property name="ownableService" ref="OwnableService" />
|
||||
<property name="extendedSecurityService" ref="ExtendedSecurityService" />
|
||||
<property name="authenticationUtil" ref="rm.authenticationUtil" />
|
||||
</bean>
|
||||
<bean class="org.alfresco.module.org_alfresco_module_rm.util.BeanExtender">
|
||||
<property name="beanName" value="versionService" />
|
||||
@@ -24,6 +28,7 @@
|
||||
|
||||
<!-- extended version node service bean definition -->
|
||||
<bean id="rm.versionNodeService" abstract="true" class="org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionNodeServiceImpl">
|
||||
<property name="recordService" ref="RecordService" />
|
||||
</bean>
|
||||
<bean class="org.alfresco.module.org_alfresco_module_rm.util.BeanExtender">
|
||||
<property name="beanName" value="versionNodeService" />
|
||||
|
@@ -50,6 +50,7 @@ rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildAssocs
|
||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getNodeRef=RM.Read.0
|
||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildAssocsByPropertyValue=RM.Read.0,AFTER_RM.FilterNode
|
||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.countChildAssocs=RM.Read.0
|
||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getNodeAclId=RM.Read.0
|
||||
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.*=RM_DENY
|
||||
|
||||
## File Folder Service
|
||||
|
@@ -195,7 +195,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
};
|
||||
|
||||
// run as system user
|
||||
runAsSystem(work);
|
||||
authenticationUtil.runAsSystem(work);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
if (!getHeld(hold).contains(nodeRef))
|
||||
{
|
||||
// run as system to ensure we have all the appropriate permissions to perform the manipulations we require
|
||||
runAsSystem(new RunAsWork<Void>()
|
||||
authenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork()
|
||||
@@ -684,7 +684,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
// run as system so we don't run into further permission issues
|
||||
// we already know we have to have the correct capability to get here
|
||||
runAsSystem(new RunAsWork<Void>()
|
||||
authenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork()
|
||||
@@ -703,7 +703,7 @@ public class HoldServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
|
||||
// run as system as we can't be sure if have remove aspect rights on node
|
||||
runAsSystem(new RunAsWork<Void>()
|
||||
authenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork()
|
||||
|
@@ -80,6 +80,29 @@ public interface RecordService
|
||||
@Deprecated
|
||||
Set<QName> getRecordMetaDataAspects();
|
||||
|
||||
/**
|
||||
* Indicates whether the provided aspect is a registered record meta-data
|
||||
* aspect.
|
||||
*
|
||||
* @param aspect aspect {@link QName}
|
||||
* @return boolean true if the aspect is a registered record meta-data aspect, false otherwise
|
||||
*
|
||||
* @since 2.3
|
||||
*/
|
||||
boolean isRecordMetadataAspect(QName aspect);
|
||||
|
||||
/**
|
||||
* Indicates whther the provided property is declared on a registered record
|
||||
* meta-data aspect.
|
||||
*
|
||||
* @param property property {@link QName}
|
||||
* @return boolean true if the property is declared on a registered record meta-data aspect,
|
||||
* false otherwise
|
||||
*
|
||||
* @since 2.3
|
||||
*/
|
||||
boolean isRecordMetadataProperty(QName property);
|
||||
|
||||
/**
|
||||
* Gets a list of all the record metadata aspects relevant to the file plan type of the
|
||||
* file plan component provided.
|
||||
|
@@ -47,9 +47,11 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.security.ModelAccessDeniedException;
|
||||
import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper;
|
||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.report.ReportModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.Role;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.ClassPolicyDelegate;
|
||||
@@ -136,10 +138,12 @@ public class RecordServiceImpl extends BaseBehaviourBean
|
||||
};
|
||||
|
||||
/** record model URI's */
|
||||
private static final String[] RECORD_MODEL_URIS = new String[]
|
||||
public static final String[] RECORD_MODEL_URIS = new String[]
|
||||
{
|
||||
RM_URI,
|
||||
RM_CUSTOM_URI,
|
||||
ReportModel.RMR_URI,
|
||||
RecordableVersionModel.RMV_URI,
|
||||
DOD5015Model.DOD_URI
|
||||
};
|
||||
|
||||
@@ -682,6 +686,35 @@ public class RecordServiceImpl extends BaseBehaviourBean
|
||||
return getRecordMetadataAspects(TYPE_FILE_PLAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isRecordMetadataAspect(org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
@Override
|
||||
public boolean isRecordMetadataAspect(QName aspect)
|
||||
{
|
||||
return getRecordMetadataAspectsMap().containsKey(aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isRecordMetadataProperty(org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
@Override
|
||||
public boolean isRecordMetadataProperty(QName property)
|
||||
{
|
||||
boolean result = false;
|
||||
PropertyDefinition propertyDefinition = dictionaryService.getProperty(property);
|
||||
if (propertyDefinition != null)
|
||||
{
|
||||
ClassDefinition classDefinition = propertyDefinition.getContainerClass();
|
||||
if (classDefinition != null &&
|
||||
getRecordMetadataAspectsMap().containsKey(classDefinition.getName()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetaDataAspects(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
|
@@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -31,6 +32,7 @@ import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
@@ -236,18 +238,24 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
||||
// get the reference count
|
||||
Map<String, Integer> referenceCountMap = (Map<String, Integer>)nodeService.getProperty(filePlan, propertyName);
|
||||
|
||||
// set of assigned authorities
|
||||
Set<String> assignedAuthorities = new HashSet<String>(authorities.size());
|
||||
|
||||
for (String authority : authorities)
|
||||
{
|
||||
if ((!authority.equals(PermissionService.ALL_AUTHORITIES) && !authority.equals(PermissionService.OWNER_AUTHORITY)) &&
|
||||
if ((!authority.equals(PermissionService.ALL_AUTHORITIES) &&
|
||||
!authority.equals(PermissionService.OWNER_AUTHORITY)) &&
|
||||
!AuthorityType.ROLE.equals(AuthorityType.getAuthorityType(authority)) &&
|
||||
(referenceCountMap == null || !referenceCountMap.containsKey(authority)))
|
||||
{
|
||||
// add the authority to the role
|
||||
filePlanRoleService.assignRoleToAuthority(filePlan, roleName, authority);
|
||||
assignedAuthorities.add(authority);
|
||||
}
|
||||
}
|
||||
|
||||
// update the reference count
|
||||
nodeService.setProperty(filePlan, propertyName, (Serializable)addToMap(referenceCountMap, authorities));
|
||||
nodeService.setProperty(filePlan, propertyName, (Serializable)addToMap(referenceCountMap, assignedAuthorities));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -225,7 +225,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
|
||||
if (nodeService.exists(parent))
|
||||
{
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
@@ -300,7 +300,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void onAddRecord(final NodeRef record, final QName aspectTypeQName)
|
||||
{
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
@@ -375,7 +375,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
if (nodeService.exists(nodeRef))
|
||||
{
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
@@ -410,7 +410,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
ParameterCheck.mandatory("authority", authority);
|
||||
ParameterCheck.mandatory("permission", permission);
|
||||
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Void doWork()
|
||||
{
|
||||
@@ -557,7 +557,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
|
||||
*/
|
||||
public void deletePermission(final NodeRef nodeRef, final String authority, final String permission)
|
||||
{
|
||||
runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Void doWork()
|
||||
{
|
||||
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.util;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
|
||||
/**
|
||||
* Helper bean to allow injection of AuthenticationUtil methods.
|
||||
* <p>
|
||||
* Useful when testing using mocks.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.3
|
||||
*/
|
||||
public class AuthenticationUtil
|
||||
{
|
||||
/**
|
||||
* Helper method that executed work as system user.
|
||||
* <p>
|
||||
* Useful when testing using mocks.
|
||||
*
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationUtil#runAsSystem(RunAsWork, String)
|
||||
*/
|
||||
public <R> R runAsSystem(RunAsWork<R> runAsWork)
|
||||
{
|
||||
return org.alfresco.repo.security.authentication.AuthenticationUtil.runAsSystem(runAsWork);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that executed work as given user.
|
||||
* <p>
|
||||
* Useful when testing using mocks.
|
||||
*
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationUtil#runAs(RunAsWork, String)
|
||||
*/
|
||||
public <R> R runAs(RunAsWork<R> runAsWork, String uid)
|
||||
{
|
||||
return org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(runAsWork, uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that gets the fully authenticated user.
|
||||
* <p>
|
||||
* Useful when testing using mocks.
|
||||
*
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationUtil#getFullyAuthenticatedUser()
|
||||
*/
|
||||
public String getFullyAuthenticatedUser()
|
||||
{
|
||||
return org.alfresco.repo.security.authentication.AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that gets the admin user name.
|
||||
* <p>
|
||||
* Usefule when testing using mocks.
|
||||
*
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationUtil#getAdminUserName()
|
||||
*/
|
||||
public String getAdminUserName()
|
||||
{
|
||||
return org.alfresco.repo.security.authentication.AuthenticationUtil.getAdminUserName();
|
||||
}
|
||||
|
||||
}
|
@@ -26,8 +26,6 @@ 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.hold.HoldService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.transaction.TransactionalResourceHelper;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
@@ -59,6 +57,9 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
/** internal node service */
|
||||
private NodeService internalNodeService;
|
||||
|
||||
/** authentication helper */
|
||||
protected AuthenticationUtil authenticationUtil;
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
@@ -84,6 +85,14 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authenticationUtil authentication util helper
|
||||
*/
|
||||
public void setAuthenticationUtil(AuthenticationUtil authenticationUtil)
|
||||
{
|
||||
this.authenticationUtil = authenticationUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get internal node service.
|
||||
* <p>
|
||||
@@ -470,30 +479,4 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
|
||||
result.add(nodeService.getType(nodeRef));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that executed work as system user.
|
||||
* <p>
|
||||
* Useful when testing using mocks.
|
||||
*
|
||||
* @param runAsWork work to execute as system user
|
||||
* @return
|
||||
*/
|
||||
public <R> R runAsSystem(RunAsWork<R> runAsWork)
|
||||
{
|
||||
return AuthenticationUtil.runAsSystem(runAsWork);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that executed work as given user.
|
||||
* <p>
|
||||
* Useful when testing using mocks.
|
||||
*
|
||||
* @param runAsWork work to execute as given user
|
||||
* @return
|
||||
*/
|
||||
public <R> R runAs(RunAsWork<R> runAsWork, String uid)
|
||||
{
|
||||
return AuthenticationUtil.runAs(runAsWork, uid);
|
||||
}
|
||||
}
|
||||
|
@@ -40,4 +40,5 @@ public interface RecordableVersionModel
|
||||
/** recorded version aspect */
|
||||
public QName ASPECT_RECORDED_VERSION = QName.createQName(RMV_URI, "recordedVersion");
|
||||
public QName PROP_RECORD_NODE_REF = QName.createQName(RMV_URI, "recordNodeRef");
|
||||
public QName PROP_FROZEN_OWNER = QName.createQName(RMV_URI, "frozenOwner");
|
||||
}
|
||||
|
@@ -19,17 +19,27 @@
|
||||
package org.alfresco.module.org_alfresco_module_rm.version;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
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.record.RecordServiceImpl;
|
||||
import org.alfresco.repo.version.Node2ServiceImpl;
|
||||
import org.alfresco.repo.version.Version2Model;
|
||||
import org.alfresco.repo.version.common.VersionUtil;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
|
||||
/**
|
||||
* Extended version node service implementation that supports the retrieval of
|
||||
* recorded version state.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.3
|
||||
@@ -37,16 +47,31 @@ import org.alfresco.service.namespace.QName;
|
||||
public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl
|
||||
implements RecordableVersionModel
|
||||
{
|
||||
/** record service */
|
||||
private RecordService recordService;
|
||||
|
||||
/**
|
||||
* @param recordService record service
|
||||
*/
|
||||
public void setRecordService(RecordService recordService)
|
||||
{
|
||||
this.recordService = recordService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.version.Node2ServiceImpl#getProperties(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public Map<QName, Serializable> getProperties(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
// TODO only supported for Version2
|
||||
|
||||
NodeRef converted = VersionUtil.convertNodeRef(nodeRef);
|
||||
if (dbNodeService.hasAspect(converted, ASPECT_RECORDED_VERSION))
|
||||
{
|
||||
NodeRef record = (NodeRef)dbNodeService.getProperty(converted, PROP_RECORD_NODE_REF);
|
||||
Map<QName, Serializable> properties = dbNodeService.getProperties(record);
|
||||
return processProperties(properties);
|
||||
return processProperties(converted, properties);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -54,18 +79,153 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<QName, Serializable> processProperties(Map<QName, Serializable> properties)
|
||||
/**
|
||||
* Process properties map before returning as frozen state.
|
||||
*
|
||||
* @param properties properties map
|
||||
* @return {@link Map}<{@link QName}, {@link Serializable}> processed property map
|
||||
*/
|
||||
protected Map<QName, Serializable> processProperties(NodeRef version, Map<QName, Serializable> properties)
|
||||
{
|
||||
Map<QName, Serializable> cloneProperties = new HashMap<QName, Serializable>(properties);
|
||||
|
||||
// revert modified record name
|
||||
properties.put(ContentModel.PROP_NAME, properties.get(RecordsManagementModel.PROP_ORIGIONAL_NAME));
|
||||
|
||||
// remove all rma, rmc, rmr and rmv properties
|
||||
|
||||
// remove any properties relating to custom record-meta data
|
||||
for (QName property : cloneProperties.keySet())
|
||||
{
|
||||
if (!PROP_RECORDABLE_VERSION_POLICY.equals(property) &&
|
||||
!PROP_FILE_PLAN.equals(property) &&
|
||||
(recordService.isRecordMetadataProperty(property) ||
|
||||
ArrayUtils.contains(RecordServiceImpl.RECORD_MODEL_URIS, property.getNamespaceURI())))
|
||||
{
|
||||
properties.remove(property);
|
||||
}
|
||||
}
|
||||
|
||||
// do standard property processing
|
||||
VersionUtil.convertFrozenToOriginalProps(properties);
|
||||
processVersionProperties(version, properties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process version properties.
|
||||
*
|
||||
* @param version version node reference
|
||||
* @param properties properties map
|
||||
*/
|
||||
protected void processVersionProperties(NodeRef version, Map<QName, Serializable> properties) throws InvalidNodeRefException
|
||||
{
|
||||
// get version properties
|
||||
Map<QName, Serializable> versionProperties = dbNodeService.getProperties(version);
|
||||
|
||||
if (versionProperties != null)
|
||||
{
|
||||
String versionLabel = (String)versionProperties.get(Version2Model.PROP_QNAME_VERSION_LABEL);
|
||||
properties.put(ContentModel.PROP_VERSION_LABEL, versionLabel);
|
||||
|
||||
// Convert frozen sys:referenceable properties
|
||||
NodeRef nodeRef = (NodeRef)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF);
|
||||
if (nodeRef != null)
|
||||
{
|
||||
properties.put(ContentModel.PROP_STORE_PROTOCOL, nodeRef.getStoreRef().getProtocol());
|
||||
properties.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier());
|
||||
properties.put(ContentModel.PROP_NODE_UUID, nodeRef.getId());
|
||||
}
|
||||
|
||||
Long dbid = (Long)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_DBID);
|
||||
properties.put(ContentModel.PROP_NODE_DBID, dbid);
|
||||
|
||||
// Convert frozen cm:auditable properties
|
||||
String creator = (String)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_CREATOR);
|
||||
if (creator != null)
|
||||
{
|
||||
properties.put(ContentModel.PROP_CREATOR, creator);
|
||||
}
|
||||
|
||||
Date created = (Date)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_CREATED);
|
||||
if (created != null)
|
||||
{
|
||||
properties.put(ContentModel.PROP_CREATED, created);
|
||||
}
|
||||
|
||||
// TODO - check use-cases for get version, revert, restore ....
|
||||
String modifier = (String)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_MODIFIER);
|
||||
if (modifier != null)
|
||||
{
|
||||
properties.put(ContentModel.PROP_MODIFIER, modifier);
|
||||
}
|
||||
|
||||
Date modified = (Date)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_MODIFIED);
|
||||
if (modified != null)
|
||||
{
|
||||
properties.put(ContentModel.PROP_MODIFIED, modified);
|
||||
}
|
||||
|
||||
Date accessed = (Date)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_ACCESSED);
|
||||
if (accessed != null)
|
||||
{
|
||||
properties.put(ContentModel.PROP_ACCESSED, accessed);
|
||||
}
|
||||
|
||||
String owner = (String)versionProperties.get(PROP_FROZEN_OWNER);
|
||||
if (owner != null)
|
||||
{
|
||||
properties.put(ContentModel.PROP_OWNER, owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.version.Node2ServiceImpl#getAspects(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public Set<QName> getAspects(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
// TODO only supported for Version2
|
||||
|
||||
NodeRef converted = VersionUtil.convertNodeRef(nodeRef);
|
||||
if (dbNodeService.hasAspect(converted, ASPECT_RECORDED_VERSION))
|
||||
{
|
||||
NodeRef record = (NodeRef)dbNodeService.getProperty(converted, PROP_RECORD_NODE_REF);
|
||||
Set<QName> aspects = dbNodeService.getAspects(record);
|
||||
return processAspects(aspects);
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.getAspects(nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process frozen aspects.
|
||||
*
|
||||
* @param aspects aspect set
|
||||
* @return {@link Set}<{@link QName}> processed aspect set
|
||||
*/
|
||||
protected Set<QName> processAspects(Set<QName> aspects)
|
||||
{
|
||||
Set<QName> result = new HashSet<QName>(aspects);
|
||||
|
||||
// remove version aspects
|
||||
result.remove(ASPECT_VERSION);
|
||||
result.remove(ASPECT_RECORDED_VERSION);
|
||||
|
||||
// remove rm aspects
|
||||
for (QName aspect : aspects)
|
||||
{
|
||||
if (!ASPECT_VERSIONABLE.equals(aspect) &&
|
||||
(recordService.isRecordMetadataAspect(aspect) ||
|
||||
ArrayUtils.contains(RecordServiceImpl.RECORD_MODEL_URIS, aspect.getNamespaceURI())))
|
||||
{
|
||||
result.remove(aspect);
|
||||
}
|
||||
}
|
||||
|
||||
// remove custom record meta-data aspects
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -21,20 +21,29 @@ package org.alfresco.module.org_alfresco_module_rm.version;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.security.ExtendedSecurityService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
|
||||
import org.alfresco.repo.policy.PolicyScope;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.security.permissions.impl.ExtendedPermissionService;
|
||||
import org.alfresco.repo.version.Version2Model;
|
||||
import org.alfresco.repo.version.Version2ServiceImpl;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.OwnableService;
|
||||
import org.alfresco.service.cmr.version.ReservedVersionNameException;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
@@ -64,6 +73,18 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
/** file folder service */
|
||||
protected FileFolderService fileFolderService;
|
||||
|
||||
/** extended permission service */
|
||||
protected ExtendedPermissionService extendedPermissionService;
|
||||
|
||||
/** ownable service */
|
||||
protected OwnableService ownableService;
|
||||
|
||||
/** extended security service */
|
||||
protected ExtendedSecurityService extendedSecurityService;
|
||||
|
||||
/** authentication util helper */
|
||||
protected AuthenticationUtil authenticationUtil;
|
||||
|
||||
/**
|
||||
* @param filePlanService file plan service
|
||||
*/
|
||||
@@ -80,6 +101,38 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extendedPermissionService extended permission service
|
||||
*/
|
||||
public void setExtendedPermissionService(ExtendedPermissionService extendedPermissionService)
|
||||
{
|
||||
this.extendedPermissionService = extendedPermissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ownableService ownable service
|
||||
*/
|
||||
public void setOwnableService(OwnableService ownableService)
|
||||
{
|
||||
this.ownableService = ownableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extendedSecurityService extended security service
|
||||
*/
|
||||
public void setExtendedSecurityService(ExtendedSecurityService extendedSecurityService)
|
||||
{
|
||||
this.extendedSecurityService = extendedSecurityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authenticationUtil authentication util helper
|
||||
*/
|
||||
public void setAuthenticationUtil(AuthenticationUtil authenticationUtil)
|
||||
{
|
||||
this.authenticationUtil = authenticationUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.version.Version2ServiceImpl#createVersion(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, int)
|
||||
*/
|
||||
@@ -128,9 +181,8 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nodeRef
|
||||
* @return
|
||||
* @param nodeRef node reference
|
||||
* @return {@link NodeRef} associated file plan, default if none
|
||||
*/
|
||||
private NodeRef getFilePlan(NodeRef nodeRef)
|
||||
{
|
||||
@@ -143,8 +195,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* @return {@link NodeRef} default file plan, exception if none
|
||||
*/
|
||||
private NodeRef getFilePlan()
|
||||
{
|
||||
@@ -212,6 +263,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new recorded version
|
||||
*
|
||||
* @param sourceTypeRef
|
||||
* @param versionHistoryRef
|
||||
@@ -240,35 +292,20 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
try
|
||||
{
|
||||
// get the destination file plan
|
||||
NodeRef filePlan = (NodeRef)versionProperties.get(KEY_FILE_PLAN);
|
||||
final NodeRef filePlan = (NodeRef)versionProperties.get(KEY_FILE_PLAN);
|
||||
if (filePlan == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Can't create a new recorded version, because no file plan has been specified in the version properties.");
|
||||
}
|
||||
|
||||
// get the unfiled record folder
|
||||
final NodeRef unfiledRecordFolder = filePlanService.getUnfiledContainer(filePlan);
|
||||
|
||||
// create a copy of the source node and place in the file plan
|
||||
final NodeRef nodeRef = (NodeRef)standardVersionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF);
|
||||
|
||||
// copy version state and create record
|
||||
NodeRef record = null;
|
||||
try
|
||||
{
|
||||
FileInfo recordInfo = fileFolderService.copy(nodeRef, unfiledRecordFolder, null);
|
||||
record = recordInfo.getNodeRef();
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Can't create recorded version, because copy fails.", e);
|
||||
}
|
||||
|
||||
// set up extended permissions
|
||||
// TODO
|
||||
// create record
|
||||
NodeRef record = createRecord(nodeRef, filePlan);
|
||||
|
||||
// create version nodeRef
|
||||
ChildAssociationRef childAssocRef = this.dbNodeService.createNode(
|
||||
ChildAssociationRef childAssocRef = dbNodeService.createNode(
|
||||
versionHistoryRef,
|
||||
Version2Model.CHILD_QNAME_VERSIONS,
|
||||
QName.createQName(Version2Model.NAMESPACE_URI, Version2Model.CHILD_VERSIONS + "-" + versionNumber), // TODO - testing - note: all children (of a versioned node) will have the same version number, maybe replace with a version sequence of some sort 001-...00n
|
||||
@@ -276,25 +313,14 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
null);
|
||||
versionNodeRef = childAssocRef.getChildRef();
|
||||
|
||||
// NOTE: special ML case - see also MultilingualContentServiceImpl.makeMLContainer
|
||||
// if (sourceTypeRef.equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
// {
|
||||
// // Set the permissions to allow anything by anyone
|
||||
// permissionService.setPermission(
|
||||
// versionNodeRef,
|
||||
// PermissionService.ALL_AUTHORITIES,
|
||||
// PermissionService.ALL_PERMISSIONS, true);
|
||||
// permissionService.setPermission(
|
||||
// versionNodeRef,
|
||||
// AuthenticationUtil.getGuestUserName(),
|
||||
// PermissionService.ALL_PERMISSIONS, true);
|
||||
// }
|
||||
|
||||
// add aspect with the standard version properties to the 'version' node
|
||||
nodeService.addAspect(versionNodeRef, Version2Model.ASPECT_VERSION, standardVersionProperties);
|
||||
|
||||
// add the recordedVersion aspect with link to record
|
||||
nodeService.addAspect(versionNodeRef, ASPECT_RECORDED_VERSION, Collections.singletonMap(PROP_RECORD_NODE_REF, (Serializable)record));
|
||||
|
||||
// freeze auditable aspect information
|
||||
freezeAuditableAspect(nodeRef, versionNodeRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -318,6 +344,118 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||
return versionNodeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create record from current version
|
||||
*
|
||||
* @param nodeRef state to freeze
|
||||
* @param filePlan destination file plan
|
||||
* @return {@link NodeRef} versioned record
|
||||
*/
|
||||
private NodeRef createRecord(final NodeRef nodeRef, final NodeRef filePlan)
|
||||
{
|
||||
return authenticationUtil.runAs(new RunAsWork<NodeRef>()
|
||||
{
|
||||
public NodeRef doWork() throws Exception
|
||||
{
|
||||
// get the unfiled record folder
|
||||
final NodeRef unfiledRecordFolder = filePlanService.getUnfiledContainer(filePlan);
|
||||
|
||||
// get the documents readers
|
||||
Long aclId = dbNodeService.getNodeAclId(nodeRef);
|
||||
Set<String> readers = extendedPermissionService.getReaders(aclId);
|
||||
Set<String> writers = extendedPermissionService.getWriters(aclId);
|
||||
|
||||
// add the current owner to the list of extended writers
|
||||
Set<String> modifiedWrtiers = new HashSet<String>(writers);
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_OWNABLE))
|
||||
{
|
||||
String owner = ownableService.getOwner(nodeRef);
|
||||
if (owner != null && !owner.isEmpty() && !owner.equals(OwnableService.NO_OWNER))
|
||||
{
|
||||
modifiedWrtiers.add(owner);
|
||||
}
|
||||
}
|
||||
|
||||
// add the current user as extended writer
|
||||
modifiedWrtiers.add(authenticationUtil.getFullyAuthenticatedUser());
|
||||
|
||||
// copy version state and create record
|
||||
NodeRef record = null;
|
||||
try
|
||||
{
|
||||
List<AssociationRef> originalAssocs = null;
|
||||
if (dbNodeService.hasAspect(nodeRef, ContentModel.ASPECT_COPIEDFROM))
|
||||
{
|
||||
// take a note of any copyFrom information already on the node
|
||||
originalAssocs = dbNodeService.getTargetAssocs(nodeRef, ContentModel.ASSOC_ORIGINAL);
|
||||
}
|
||||
|
||||
// create a copy of the original state and add it to the unfiled record container
|
||||
FileInfo recordInfo = fileFolderService.copy(nodeRef, unfiledRecordFolder, null);
|
||||
record = recordInfo.getNodeRef();
|
||||
|
||||
// remove added copy assocs
|
||||
List<AssociationRef> recordAssocs = dbNodeService.getTargetAssocs(record, ContentModel.ASSOC_ORIGINAL);
|
||||
for (AssociationRef recordAssoc : recordAssocs)
|
||||
{
|
||||
dbNodeService.removeAssociation(
|
||||
recordAssoc.getSourceRef(),
|
||||
recordAssoc.getTargetRef(),
|
||||
ContentModel.ASSOC_ORIGINAL);
|
||||
}
|
||||
|
||||
// re-add origional assocs or remove aspect
|
||||
if (originalAssocs == null)
|
||||
{
|
||||
dbNodeService.removeAspect(record, ContentModel.ASPECT_COPIEDFROM);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (AssociationRef originalAssoc : originalAssocs)
|
||||
{
|
||||
dbNodeService.createAssociation(originalAssoc.getSourceRef(), originalAssoc.getTargetRef(), ContentModel.ASSOC_ORIGINAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Can't create recorded version, because copy fails.", e);
|
||||
}
|
||||
|
||||
// set extended security on record
|
||||
extendedSecurityService.addExtendedSecurity(record, readers, writers);
|
||||
|
||||
return record;
|
||||
}
|
||||
}, authenticationUtil.getAdminUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Freezes audit aspect properties.
|
||||
*
|
||||
* @param nodeRef
|
||||
* @param versionNodeRef
|
||||
*/
|
||||
private void freezeAuditableAspect(NodeRef nodeRef, NodeRef versionNodeRef)
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE))
|
||||
{
|
||||
Map<QName, Serializable> properties = dbNodeService.getProperties(nodeRef);
|
||||
dbNodeService.setProperty(versionNodeRef, Version2Model.PROP_QNAME_FROZEN_CREATOR, properties.get(ContentModel.PROP_CREATOR));
|
||||
dbNodeService.setProperty(versionNodeRef, Version2Model.PROP_QNAME_FROZEN_CREATED, properties.get(ContentModel.PROP_CREATED));
|
||||
dbNodeService.setProperty(versionNodeRef, Version2Model.PROP_QNAME_FROZEN_MODIFIER, properties.get(ContentModel.PROP_MODIFIER));
|
||||
dbNodeService.setProperty(versionNodeRef, Version2Model.PROP_QNAME_FROZEN_MODIFIED, properties.get(ContentModel.PROP_MODIFIED));
|
||||
dbNodeService.setProperty(versionNodeRef, Version2Model.PROP_QNAME_FROZEN_ACCESSED, properties.get(ContentModel.PROP_ACCESSED));
|
||||
if (properties.get(ContentModel.PROP_OWNER) != null)
|
||||
{
|
||||
dbNodeService.setProperty(versionNodeRef, PROP_FROZEN_OWNER, properties.get(ContentModel.PROP_OWNER));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.version.Version2ServiceImpl#getVersion(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
protected Version getVersion(NodeRef versionRef)
|
||||
{
|
||||
|
@@ -59,7 +59,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase
|
||||
*/
|
||||
public void testMoveRecordFolderBeforeCutOffFolderLevelDisposition() throws Exception
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(false)
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(null, false)
|
||||
{
|
||||
NodeRef recordFolder;
|
||||
NodeRef destinationRecordCategory;
|
||||
@@ -141,7 +141,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase
|
||||
*/
|
||||
public void testMoveRecordFolderBeforeCutOffIntoAFolderWithNoDisposition() throws Exception
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(false)
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(null, false)
|
||||
{
|
||||
NodeRef recordFolder;
|
||||
NodeRef destinationRecordCategory;
|
||||
@@ -217,7 +217,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase
|
||||
*/
|
||||
public void testMoveRecordFolderWithRecordsBeforeCutOffRecordLevelDisposition() throws Exception
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(false)
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(null, false)
|
||||
{
|
||||
NodeRef record;
|
||||
NodeRef recordFolder;
|
||||
|
@@ -22,93 +22,153 @@ import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.TestModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* AdHoc Recordable Versions Integration Test
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.3
|
||||
*/
|
||||
public class AdHocRecordableVersions extends BaseRMTestCase implements RecordableVersionModel
|
||||
public class AdHocRecordableVersions extends RecordableVersionsBaseTest
|
||||
{
|
||||
private static final QName QNAME_PUBLISHER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "publisher");
|
||||
private static final QName QNAME_SUBJECT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "subject");
|
||||
|
||||
private static final String DESCRIPTION = "description";
|
||||
private static final String PUBLISHER = "publisher";
|
||||
private static final String SUBJECT = "subject";
|
||||
|
||||
@Override
|
||||
protected boolean isCollaborationSiteTest()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adhoc recorded version creation, with no policy defined as site collaborator
|
||||
*/
|
||||
public void testRecordAdHocVersionNoPolicy()
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest()
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
|
||||
{
|
||||
private Version version;
|
||||
private Map<String, Serializable> versionProperties;
|
||||
|
||||
public void given() throws Exception
|
||||
{
|
||||
// add Dublin core aspect
|
||||
PropertyMap dublinCoreProperties = new PropertyMap(2);
|
||||
dublinCoreProperties.put(QNAME_PUBLISHER, PUBLISHER);
|
||||
dublinCoreProperties.put(QNAME_SUBJECT, SUBJECT);
|
||||
nodeService.addAspect(documentLibrary, ContentModel.ASPECT_DUBLINCORE, dublinCoreProperties);
|
||||
|
||||
// setup version properties
|
||||
versionProperties = new HashMap<String, Serializable>(4);
|
||||
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan);
|
||||
|
||||
}
|
||||
|
||||
public void when()
|
||||
{
|
||||
// create version
|
||||
version = versionService.createVersion(dmDocument, versionProperties);
|
||||
versionService.createVersion(dmDocument, versionProperties);
|
||||
}
|
||||
|
||||
public void then()
|
||||
{
|
||||
// version has been created
|
||||
assertNotNull(version);
|
||||
|
||||
// check the version properties
|
||||
assertEquals(DESCRIPTION, version.getDescription());
|
||||
assertEquals("0.1", version.getVersionLabel());
|
||||
|
||||
assertEquals(NAME_DM_DOCUMENT, nodeService.getProperty(dmDocument, ContentModel.PROP_NAME));
|
||||
|
||||
NodeRef frozen = version.getFrozenStateNodeRef();
|
||||
assertEquals(NAME_DM_DOCUMENT, nodeService.getProperty(frozen, ContentModel.PROP_NAME));
|
||||
|
||||
// record version node reference is available on version
|
||||
NodeRef record = (NodeRef)version.getVersionProperties().get("RecordVersion");
|
||||
assertNotNull(record);
|
||||
|
||||
// record version is an unfiled record
|
||||
assertTrue(recordService.isRecord(record));
|
||||
assertFalse(recordService.isFiled(record));
|
||||
// check that the record has been recorded
|
||||
checkRecordedVersion(dmDocument, DESCRIPTION, "0.1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adhoc recordable version with recordable set as false
|
||||
*/
|
||||
public void testRecordableVersionFalseNoPolicy()
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
|
||||
{
|
||||
private Map<String, Serializable> versionProperties;
|
||||
|
||||
public void given() throws Exception
|
||||
{
|
||||
// setup version properties
|
||||
versionProperties = new HashMap<String, Serializable>(4);
|
||||
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, false);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan);
|
||||
}
|
||||
|
||||
public void when()
|
||||
{
|
||||
// create version
|
||||
versionService.createVersion(dmDocument, versionProperties);
|
||||
}
|
||||
|
||||
public void then()
|
||||
{
|
||||
// check that the record has been recorded
|
||||
checkNotRecordedAspect(dmDocument, DESCRIPTION, "0.1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test no file plan specified (and no default available)
|
||||
*/
|
||||
public void testNoFilePlan()
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(AlfrescoRuntimeException.class, dmCollaborator)
|
||||
{
|
||||
private Map<String, Serializable> versionProperties;
|
||||
|
||||
public void given() throws Exception
|
||||
{
|
||||
// setup version properties
|
||||
versionProperties = new HashMap<String, Serializable>(4);
|
||||
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||
}
|
||||
|
||||
public void when()
|
||||
{
|
||||
// create version
|
||||
versionService.createVersion(dmDocument, versionProperties);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test recorded version with record metadata aspect (want to ensure additional non-rm URI properties and aspects
|
||||
* don't find their way into the frozen state)
|
||||
*/
|
||||
public void testRecordedVersionWithRecordMetadataAspect()
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
|
||||
{
|
||||
private Map<String, Serializable> versionProperties;
|
||||
|
||||
public void given() throws Exception
|
||||
{
|
||||
// setup version properties
|
||||
versionProperties = new HashMap<String, Serializable>(4);
|
||||
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan);
|
||||
}
|
||||
|
||||
public void when()
|
||||
{
|
||||
// create version
|
||||
Version version = versionService.createVersion(dmDocument, versionProperties);
|
||||
|
||||
// add custom meta-data to record
|
||||
NodeRef record = (NodeRef)version.getVersionProperties().get("RecordVersion");
|
||||
assertNotNull(record);
|
||||
recordService.addRecordType(record, TestModel.ASPECT_RECORD_METADATA);
|
||||
nodeService.setProperty(record, TestModel.PROPERTY_RECORD_METADATA, "Peter Wetherall");
|
||||
}
|
||||
|
||||
public void then()
|
||||
{
|
||||
// check that the record has been recorded
|
||||
checkRecordedVersion(dmDocument, DESCRIPTION, "0.1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.integration.version;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
|
||||
/**
|
||||
* Auto Recordable Versions Integration Test
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.3
|
||||
*/
|
||||
public class AutoRecordableVersions extends RecordableVersionsBaseTest
|
||||
{
|
||||
public final static String MY_NEW_CONTENT = "this is some new content that I have changed to trigger auto version";
|
||||
|
||||
public void testAutoVersionRecordAllRevisions()
|
||||
{
|
||||
doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
|
||||
{
|
||||
public void given() throws Exception
|
||||
{
|
||||
// make the node versionable
|
||||
PropertyMap versionableProperties = new PropertyMap(1);
|
||||
versionableProperties.put(ContentModel.PROP_INITIAL_VERSION, false);
|
||||
nodeService.addAspect(dmDocument, ContentModel.ASPECT_VERSIONABLE, versionableProperties);
|
||||
|
||||
// set the recordable version policy
|
||||
PropertyMap recordableVersionProperties = new PropertyMap(1);
|
||||
recordableVersionProperties.put(PROP_RECORDABLE_VERSION_POLICY, RecordableVersionPolicy.ALL);
|
||||
recordableVersionProperties.put(PROP_FILE_PLAN, filePlan);
|
||||
nodeService.addAspect(dmDocument, RecordableVersionModel.ASPECT_VERSIONABLE, recordableVersionProperties);
|
||||
}
|
||||
|
||||
public void when()
|
||||
{
|
||||
// generate new version by updating content
|
||||
ContentWriter writer = contentService.getWriter(dmDocument, ContentModel.PROP_CONTENT, true);
|
||||
writer.putContent(MY_NEW_CONTENT);
|
||||
}
|
||||
|
||||
public void then()
|
||||
{
|
||||
// check that the record has been recorded
|
||||
checkRecordedVersion(dmDocument, null, "0.2");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.integration.version;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
* @since 2.3
|
||||
*/
|
||||
public abstract class RecordableVersionsBaseTest extends BaseRMTestCase implements RecordableVersionModel
|
||||
{
|
||||
protected static final QName QNAME_PUBLISHER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "publisher");
|
||||
protected static final QName QNAME_SUBJECT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "subject");
|
||||
|
||||
protected static final String DESCRIPTION = "description";
|
||||
protected static final String PUBLISHER = "publisher";
|
||||
protected static final String SUBJECT = "subject";
|
||||
protected static final String OWNER = "Grace Wetherall";
|
||||
|
||||
protected static final String CONTENT =
|
||||
"Simple + Smart. A smarter way to build, a smarter way to deploy. Its simple because we focus on the end "
|
||||
+ "user and smart because we support more open standards than any other ECM platform, while delivering all "
|
||||
+ "the value a traditional platform provides.";
|
||||
|
||||
@Override
|
||||
protected boolean isCollaborationSiteTest()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupCollaborationSiteTestDataImpl()
|
||||
{
|
||||
super.setupCollaborationSiteTestDataImpl();
|
||||
|
||||
// add titled aspect
|
||||
PropertyMap titledProperties = new PropertyMap(2);
|
||||
titledProperties.put(ContentModel.PROP_TITLE, "document title");
|
||||
titledProperties.put(ContentModel.PROP_DESCRIPTION, "document description");
|
||||
nodeService.addAspect(dmDocument, ContentModel.ASPECT_TITLED, titledProperties);
|
||||
|
||||
// add ownable aspect
|
||||
PropertyMap ownableProperties = new PropertyMap(1);
|
||||
ownableProperties.put(ContentModel.PROP_OWNER, OWNER);
|
||||
nodeService.addAspect(dmDocument, ContentModel.ASPECT_OWNABLE, ownableProperties);
|
||||
|
||||
// add Dublin core aspect
|
||||
PropertyMap dublinCoreProperties = new PropertyMap(2);
|
||||
dublinCoreProperties.put(QNAME_PUBLISHER, PUBLISHER);
|
||||
dublinCoreProperties.put(QNAME_SUBJECT, SUBJECT);
|
||||
nodeService.addAspect(dmDocument, ContentModel.ASPECT_DUBLINCORE, dublinCoreProperties);
|
||||
|
||||
// add content
|
||||
ContentWriter writer = contentService.getWriter(dmDocument, ContentModel.PROP_CONTENT, true);
|
||||
writer.setEncoding("UTF-8");
|
||||
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
writer.putContent(CONTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to check that the current version is recorded
|
||||
*/
|
||||
protected void checkRecordedVersion(NodeRef document, String description, String versionLabel)
|
||||
{
|
||||
// double check that the document is not a record
|
||||
assertFalse(recordService.isRecord(document));
|
||||
|
||||
// store document state
|
||||
Map<QName, Serializable> beforeProperties = nodeService.getProperties(document);
|
||||
Set<QName> beforeAspects = nodeService.getAspects(dmDocument);
|
||||
|
||||
// get the current version
|
||||
Version version = versionService.getCurrentVersion(document);
|
||||
|
||||
// version has been created
|
||||
assertNotNull(version);
|
||||
|
||||
// check the version properties
|
||||
assertEquals(description, version.getDescription());
|
||||
assertEquals(versionLabel, version.getVersionLabel());
|
||||
|
||||
// get the frozen state
|
||||
NodeRef frozen = version.getFrozenStateNodeRef();
|
||||
|
||||
// check the properties
|
||||
checkProperties(frozen, beforeProperties);
|
||||
|
||||
// compare aspects
|
||||
checkAspects(frozen, beforeAspects);
|
||||
|
||||
// record version node reference is available on version
|
||||
NodeRef record = (NodeRef)version.getVersionProperties().get("RecordVersion");
|
||||
assertNotNull(record);
|
||||
|
||||
// record version is an unfiled record
|
||||
assertTrue(recordService.isRecord(record));
|
||||
assertFalse(recordService.isFiled(record));
|
||||
|
||||
// check the version history
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(document);
|
||||
assertNotNull(versionHistory);
|
||||
Version headVersion = versionHistory.getHeadVersion();
|
||||
assertNotNull(headVersion);
|
||||
}
|
||||
|
||||
protected void checkNotRecordedAspect(NodeRef document, String description, String versionLabel)
|
||||
{
|
||||
// double check that the document is not a record
|
||||
assertFalse(recordService.isRecord(document));
|
||||
|
||||
// get the current version
|
||||
Version version = versionService.getCurrentVersion(document);
|
||||
|
||||
// version has been created
|
||||
assertNotNull(version);
|
||||
|
||||
// check the version properties
|
||||
assertEquals(description, version.getDescription());
|
||||
assertEquals(versionLabel, version.getVersionLabel());
|
||||
|
||||
// record version node reference is available on version
|
||||
NodeRef record = (NodeRef)version.getVersionProperties().get("RecordVersion");
|
||||
assertNull(record);
|
||||
|
||||
// check the version history
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(document);
|
||||
assertNotNull(versionHistory);
|
||||
Version headVersion = versionHistory.getHeadVersion();
|
||||
assertNotNull(headVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to check the properties of a recorded version
|
||||
*/
|
||||
protected void checkProperties(NodeRef frozen, Map<QName, Serializable> beforeProperies)
|
||||
{
|
||||
Map<QName, Serializable> frozenProperties = nodeService.getProperties(frozen);
|
||||
Map<QName, Serializable> cloneFrozenProperties = new HashMap<QName, Serializable>(frozenProperties);
|
||||
for (Map.Entry<QName, Serializable> entry : beforeProperies.entrySet())
|
||||
{
|
||||
if (frozenProperties.containsKey(entry.getKey()))
|
||||
{
|
||||
Serializable frozenValue = frozenProperties.get(entry.getKey());
|
||||
assertEquals("Frozen property " + entry.getKey().getLocalName() + " value is incorrect.", entry.getValue(), frozenValue);
|
||||
cloneFrozenProperties.remove(entry.getKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
fail("Property missing from frozen state .. " + entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
// frozen properties should be empty
|
||||
assertTrue("Properties in frozen state, but not in origional. " + cloneFrozenProperties.keySet(), cloneFrozenProperties.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to check the aspects of a recorded version
|
||||
*/
|
||||
protected void checkAspects(NodeRef frozen, Set<QName> beforeAspects)
|
||||
{
|
||||
Set<QName> cloneBeforeAspects = new HashSet<QName>(beforeAspects);
|
||||
|
||||
// compare origional and frozen aspects
|
||||
Set<QName> frozenAspects = nodeService.getAspects(frozen);
|
||||
cloneBeforeAspects.removeAll(frozenAspects);
|
||||
if (!cloneBeforeAspects.isEmpty())
|
||||
{
|
||||
fail("Aspects not present in frozen state. " + cloneBeforeAspects.toString());
|
||||
}
|
||||
|
||||
frozenAspects.removeAll(beforeAspects);
|
||||
if (!frozenAspects.isEmpty())
|
||||
{
|
||||
fail("Aspects in the frozen state, but not in origional. " + frozenAspects.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -31,7 +31,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses(
|
||||
{
|
||||
AdHocRecordableVersions.class
|
||||
AdHocRecordableVersions.class,
|
||||
AutoRecordableVersions.class
|
||||
})
|
||||
public class VersionTestSuite
|
||||
{
|
||||
|
@@ -823,10 +823,18 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
||||
*/
|
||||
protected abstract class BehaviourDrivenTest
|
||||
{
|
||||
/** run in transaction */
|
||||
protected boolean runInTransactionTests = true;
|
||||
|
||||
/** run as user */
|
||||
protected String runAsUser = AuthenticationUtil.getAdminUserName();
|
||||
|
||||
/** expected exception */
|
||||
protected Class<?> expectedException;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public BehaviourDrivenTest()
|
||||
{
|
||||
}
|
||||
@@ -836,9 +844,24 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
||||
this.expectedException = expectedException;
|
||||
}
|
||||
|
||||
public BehaviourDrivenTest(boolean runInTransactionTests)
|
||||
public BehaviourDrivenTest(Class<?> expectedException, String runAsUser)
|
||||
{
|
||||
this.expectedException = expectedException;
|
||||
this.runAsUser = runAsUser;
|
||||
}
|
||||
|
||||
public BehaviourDrivenTest(String runAsUser)
|
||||
{
|
||||
this.runAsUser = runAsUser;
|
||||
}
|
||||
|
||||
public BehaviourDrivenTest(String runAsUser, boolean runInTransactionTests)
|
||||
{
|
||||
this.runInTransactionTests = runInTransactionTests;
|
||||
if (runAsUser != null)
|
||||
{
|
||||
this.runAsUser = runAsUser;
|
||||
}
|
||||
}
|
||||
|
||||
public void given() throws Exception { /** empty implementation */ }
|
||||
@@ -862,7 +885,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
||||
{
|
||||
given();
|
||||
}
|
||||
});
|
||||
}, runAsUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -880,7 +903,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
||||
{
|
||||
when();
|
||||
}
|
||||
});
|
||||
}, runAsUser);
|
||||
|
||||
doTestInTransaction(new VoidTest()
|
||||
{
|
||||
@@ -889,7 +912,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
||||
{
|
||||
then();
|
||||
}
|
||||
});
|
||||
}, runAsUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -906,7 +929,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
||||
{
|
||||
when();
|
||||
}
|
||||
});
|
||||
}, runAsUser);
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -920,7 +943,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
||||
{
|
||||
after();
|
||||
}
|
||||
});
|
||||
}, runAsUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.util;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
* @since 2.3
|
||||
*/
|
||||
public interface TestModel
|
||||
{
|
||||
public static final String TEST_URI = "http://www.alfresco.org/model/rmtest/1.0";
|
||||
public static final String TEST_PREFIX = "rmt";
|
||||
|
||||
public static final QName ASPECT_RECORD_METADATA = QName.createQName(TEST_URI, "recordMetaData");
|
||||
public static final QName PROPERTY_RECORD_METADATA = QName.createQName(TEST_URI, "recordMetaDataProperty");
|
||||
}
|
@@ -48,6 +48,11 @@
|
||||
</aspect>
|
||||
|
||||
<aspect name="rmt:recordMetaData">
|
||||
<properties>
|
||||
<property name="rmt:recordMetaDataProperty">
|
||||
<type>d:text</type>
|
||||
</property>
|
||||
</properties>
|
||||
</aspect>
|
||||
|
||||
</aspects>
|
||||
|
@@ -87,9 +87,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
{
|
||||
super.before();
|
||||
|
||||
// mock up run as methods
|
||||
mockRunAsMethods(filePlanPermissionService);
|
||||
|
||||
// initialize node's
|
||||
unfiledRecordContainer = generateContainerNodeRef(TYPE_UNFILED_RECORD_CONTAINER);
|
||||
unfiledRecordFolder = generateContainerNodeRef(TYPE_UNFILED_RECORD_FOLDER);
|
||||
|
@@ -41,10 +41,12 @@ import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.report.ReportService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.security.permissions.impl.ExtendedPermissionService;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
@@ -114,6 +116,9 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
@Mock(name="filePlanRoleService") protected FilePlanRoleService mockedFilePlanRoleService;
|
||||
@Mock(name="recordsManagementAuditService") protected RecordsManagementAuditService mockedRecordsManagementAuditService;
|
||||
@Mock(name="policyBehaviourFilter") protected BehaviourFilter mockedBehaviourFilter;
|
||||
@Mock(name="authenticationUtil") protected AuthenticationUtil mockedAuthenticationUtil;
|
||||
@Mock(name="extendedPermissionService") protected ExtendedPermissionService mockedExtendedPermissionService;
|
||||
@Mock(name="extendedSecurityService") protected ExtendedSecurityService mockedExtendedSecurityService;
|
||||
|
||||
/** application context mock */
|
||||
@Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;
|
||||
@@ -147,6 +152,9 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
};
|
||||
doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).doInTransaction(any(RetryingTransactionCallback.class));
|
||||
|
||||
// setup mocked authentication util
|
||||
setupAuthenticationUtilMock();
|
||||
|
||||
// setup file plan
|
||||
filePlan = generateNodeRef(TYPE_FILE_PLAN);
|
||||
setupAsFilePlanComponent(filePlan);
|
||||
@@ -173,6 +181,43 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup authentication util mock
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void setupAuthenticationUtilMock()
|
||||
{
|
||||
// just do the work
|
||||
doAnswer(new Answer<Object>()
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable
|
||||
{
|
||||
RunAsWork work = (RunAsWork)invocation.getArguments()[0];
|
||||
return work.doWork();
|
||||
}
|
||||
|
||||
}).when(mockedAuthenticationUtil).runAsSystem(any(RunAsWork.class));
|
||||
|
||||
// just do the work
|
||||
doAnswer(new Answer<Object>()
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable
|
||||
{
|
||||
RunAsWork work = (RunAsWork)invocation.getArguments()[0];
|
||||
return work.doWork();
|
||||
}
|
||||
|
||||
}).when(mockedAuthenticationUtil).runAs(any(RunAsWork.class), anyString());
|
||||
|
||||
// assume admin
|
||||
doReturn("admin").when(mockedAuthenticationUtil).getAdminUserName();
|
||||
doReturn("admin").when(mockedAuthenticationUtil).getFullyAuthenticatedUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a qname.
|
||||
*
|
||||
@@ -349,40 +394,6 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
doReturn(assocs).when(mockedNodeService).getChildAssocs(parent, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to mock up calls to 'run as' methods
|
||||
* on base service implementation.
|
||||
*
|
||||
* @param service
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void mockRunAsMethods(ServiceBaseImpl service)
|
||||
{
|
||||
doAnswer(new Answer<Object>()
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable
|
||||
{
|
||||
RunAsWork work = (RunAsWork)invocation.getArguments()[0];
|
||||
return work.doWork();
|
||||
}
|
||||
|
||||
}).when(service).runAsSystem(any(RunAsWork.class));
|
||||
|
||||
doAnswer(new Answer<Object>()
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable
|
||||
{
|
||||
RunAsWork work = (RunAsWork)invocation.getArguments()[0];
|
||||
return work.doWork();
|
||||
}
|
||||
|
||||
}).when(service).runAs(any(RunAsWork.class), anyString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> List<T> buildList(T ... values)
|
||||
{
|
||||
|
Reference in New Issue
Block a user