events = nextDispositionActionDefinition.getEvents();
- for (RecordsManagementEvent event : events)
- {
- // For every event create an entry on the action
- da.addEventCompletionDetails(event);
- }
+ initialiseDispositionAction(nodeRef, nextDispositionActionDefinition, false);
}
}
@@ -1025,7 +987,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
recordFolderService.closeRecordFolder(nodeRef);
return null;
}
- });
+ });
}
}
else
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
index 79e4311596..134811f0f2 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
@@ -1058,7 +1058,9 @@ public class RecordServiceImpl extends BaseBehaviourBean
private NodeRef getLatestVersionRecord(NodeRef nodeRef)
{
NodeRef versionRecord = null;
-
+
+
+ recordableVersionService.createSnapshotVersion(nodeRef);
// wire record up to previous record
VersionHistory versionHistory = versionService.getVersionHistory(nodeRef);
if (versionHistory != null)
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java
index 4a2e9ce666..a9c78f6ffc 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java
@@ -59,8 +59,7 @@ public interface RecordableVersionService
boolean isRecordedVersion(Version version);
/**
- * If the version is a recorded version, gets the related version
- * record.
+ * If the version is a recorded version, gets the related version record.
*
* @param version version
* @return NodeRef node reference of version record
@@ -76,16 +75,27 @@ public interface RecordableVersionService
Version getRecordedVersion(NodeRef record);
/**
- * Creates a record from the latest version, marking it as recorded.
+ * Creates a record from the latest frozen version, marking it as recorded.
*
- * Does not create a record if the node is not versionable or the latest
- * version is already recorded.
+ * Does not create a record if the node is not versionable or the latest version is already recorded.
*
- * @param nodeRef node reference
- * @return NodeRef node reference to the created record.
+ * @param nodeRef node reference
+ * @return NodeRef node reference to the created record.
*/
NodeRef createRecordFromLatestVersion(NodeRef filePlan, NodeRef nodeRef);
+ /**
+ * Creates a record from the latest version, marking it as recorded.
+ *
+ * Does not create a record if the node is not versionable or the latest version is already recorded.
+ *
+ * @param nodeRef parent node reference
+ * @param nodeRef node reference
+ * @param autoVersion true, create new record version from latest version, false creates a record from the latest frozen version
+ * @return NodeRef node reference to the created record.
+ */
+ NodeRef createRecordFromLatestVersion(NodeRef filePlan, NodeRef nodeRef, boolean autoVersion);
+
/**
* Indicates whether a record version is destroyed or not.
*
@@ -97,11 +107,23 @@ public interface RecordableVersionService
/**
* Marks a recorded version as destroyed.
*
- * Note this method does not destroy the associated record, instead it marks the
- * version as destroyed.
+ * Note this method does not destroy the associated record, instead it marks the version as destroyed.
*
* @param version version
*/
void destroyRecordedVersion(Version version);
+ /**
+ * Flag that indicate to create new version on record creation if current node is modified
+ *
+ * @return boolean true to auto-version on record creation, false to use latest versioned version
+ */
+ boolean isEnableAutoVersionOnRecordCreation();
+
+ /**
+ * Create a snapshot version of current node
+ *
+ * @param nodeRef node reference
+ */
+ void createSnapshotVersion(NodeRef nodeRef);
}
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java
index 005b6415c5..4c6fafee1d 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java
@@ -33,6 +33,7 @@ import static org.codehaus.plexus.util.StringUtils.isNotBlank;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -66,6 +67,7 @@ import org.alfresco.util.PropertyMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.extensions.surf.util.I18NUtil;
/**
* Recordable version service implementation
@@ -88,6 +90,12 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
protected static final String PROP_VERSION_RECORD = "RecordVersion";
protected static final String PROP_RECORDED_VERSION_DESTROYED = "RecordedVersionDestroyed";
+ /** I18N */
+ private static final String AUTO_VERSION_ON_RECORD_CREATION = "rm.service.enable-autoversion-on-record-creation";
+
+ /** flag that enable auto-version on record creation */
+ private boolean isEnableAutoVersionOnRecordCreation = false;
+
/** version aspect property names */
private static final String[] VERSION_PROPERTY_NAMES = new String[]
{
@@ -122,15 +130,15 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
/** cm object type */
private CmObjectType cmObjectType;
-
+
/** extended permission service */
private ExtendedPermissionService extendedPermissionService;
-
+
/** extended security service */
private ExtendedSecurityService extendedSecurityService;
/**
- * @param filePlanService file plan service
+ * @param filePlanService file plan service
*/
public void setFilePlanService(FilePlanService filePlanService)
{
@@ -138,7 +146,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
/**
- * @param authenticationUtil authentication util helper
+ * @param authenticationUtil authentication util helper
*/
public void setAuthenticationUtil(AuthenticationUtil authenticationUtil)
{
@@ -146,7 +154,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
/**
- * @param relationshipService relationship service
+ * @param relationshipService relationship service
*/
public void setRelationshipService(RelationshipService relationshipService)
{
@@ -162,7 +170,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
/**
- * @param modelSecurityService model security service
+ * @param modelSecurityService model security service
*/
public void setModelSecurityService(ModelSecurityService modelSecurityService)
{
@@ -176,7 +184,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
{
this.cmObjectType = cmObjectType;
}
-
+
/**
* @param extendedPermissionService extended permission service
*/
@@ -184,9 +192,9 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
{
this.extendedPermissionService = extendedPermissionService;
}
-
+
/**
- * @param extendedSecurityService extended security service
+ * @param extendedSecurityService extended security service
*/
public void setExtendedSecurityService(ExtendedSecurityService extendedSecurityService)
{
@@ -194,7 +202,21 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
/**
- * @see org.alfresco.repo.version.Version2ServiceImpl#createVersion(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, int)
+ * @param isEnableAutoVersionOnRecordCreation
+ */
+ public void setEnableAutoVersionOnRecordCreation(boolean isEnableAutoVersionOnRecordCreation)
+ {
+ this.isEnableAutoVersionOnRecordCreation = isEnableAutoVersionOnRecordCreation;
+ }
+
+ public boolean isEnableAutoVersionOnRecordCreation()
+ {
+ return isEnableAutoVersionOnRecordCreation;
+ }
+
+ /**
+ * @see org.alfresco.repo.version.Version2ServiceImpl#createVersion(org.alfresco.service.cmr.repository.NodeRef,
+ * java.util.Map, int)
*/
@Override
protected Version createVersion(NodeRef nodeRef, Map origVersionProperties, int versionNumber) throws ReservedVersionNameException
@@ -214,7 +236,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
VersionType versionType = null;
if (origVersionProperties != null)
{
- versionType = (VersionType)origVersionProperties.get(VersionModel.PROP_VERSION_TYPE);
+ versionType = (VersionType) origVersionProperties.get(VersionModel.PROP_VERSION_TYPE);
}
// determine whether this is a recorded version or not
@@ -241,12 +263,12 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
/**
- * @param nodeRef node reference
- * @return {@link NodeRef} associated file plan, default if none
+ * @param nodeRef node reference
+ * @return {@link NodeRef} associated file plan, default if none
*/
private NodeRef getFilePlan(NodeRef nodeRef)
{
- NodeRef filePlan = (NodeRef)nodeService.getProperty(nodeRef, PROP_FILE_PLAN);
+ NodeRef filePlan = (NodeRef) nodeService.getProperty(nodeRef, PROP_FILE_PLAN);
if (filePlan == null)
{
filePlan = getFilePlan();
@@ -255,7 +277,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
/**
- * @return {@link NodeRef} default file plan, exception if none
+ * @return {@link NodeRef} default file plan, exception if none
*/
private NodeRef getFilePlan()
{
@@ -285,7 +307,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
boolean result = false;
if (nodeService.hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE))
{
- String policyString = (String)nodeService.getProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY);
+ String policyString = (String) nodeService.getProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY);
if (policyString != null)
{
RecordableVersionPolicy policy = RecordableVersionPolicy.valueOf(policyString.toUpperCase());
@@ -315,7 +337,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
NodeRef version = null;
if (versionProperties.containsKey(KEY_RECORDABLE_VERSION) &&
- ((Boolean)versionProperties.get(KEY_RECORDABLE_VERSION)).booleanValue())
+ ((Boolean)versionProperties.get(KEY_RECORDABLE_VERSION)).booleanValue())
{
// create a recorded version
version = createNewRecordedVersion(sourceTypeRef, versionHistoryRef, standardVersionProperties, versionProperties, versionNumber, nodeDetails);
@@ -332,13 +354,13 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
/**
* Creates a new recorded version
*
- * @param sourceTypeRef source type name
- * @param versionHistoryRef version history reference
- * @param standardVersionProperties standard version properties
- * @param versionProperties version properties
- * @param versionNumber version number
- * @param nodeDetails policy scope
- * @return {@link NodeRef} record version
+ * @param sourceTypeRef source type name
+ * @param versionHistoryRef version history reference
+ * @param standardVersionProperties standard version properties
+ * @param versionProperties version properties
+ * @param versionNumber version number
+ * @param nodeDetails policy scope
+ * @return {@link NodeRef} record version
*/
protected NodeRef createNewRecordedVersion(QName sourceTypeRef,
NodeRef versionHistoryRef,
@@ -365,14 +387,14 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
try
{
// get the destination file plan
- final 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.");
}
// 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);
+ final NodeRef nodeRef = (NodeRef) standardVersionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF);
cmObjectType.disableCopy();
try
@@ -418,7 +440,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
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));
+ nodeService.addAspect(versionNodeRef, ASPECT_RECORDED_VERSION, Collections.singletonMap(PROP_RECORD_NODE_REF, (Serializable) record));
// freeze auditable aspect information
freezeAuditableAspect(nodeRef, versionNodeRef);
@@ -459,8 +481,8 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
/**
* Helper method to link the record to the previous version record
*
- * @param nodeRef noderef source node reference
- * @param record record record node reference
+ * @param nodeRef noderef source node reference
+ * @param record record record node reference
*/
private void linkToPreviousVersionRecord(final NodeRef nodeRef, final NodeRef record)
{
@@ -483,8 +505,8 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
/**
* Helper to get the latest version record for a given document (ie non-record)
*
- * @param nodeRef node reference
- * @return NodeRef latest version record, null otherwise
+ * @param nodeRef node reference
+ * @return NodeRef latest version record, null otherwise
*/
private NodeRef getLatestVersionRecord(NodeRef nodeRef)
{
@@ -498,7 +520,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
for (Version previousVersion : previousVersions)
{
// look for the associated record
- final NodeRef previousRecord = (NodeRef)previousVersion.getVersionProperties().get(PROP_VERSION_RECORD);
+ final NodeRef previousRecord = (NodeRef) previousVersion.getVersionProperties().get(PROP_VERSION_RECORD);
if (previousRecord != null &&
nodeService.exists(previousRecord))
{
@@ -510,7 +532,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
return versionRecord;
}
-
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#getRecordedVersion(org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -563,20 +585,21 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
@Override
protected Version getVersion(NodeRef versionRef)
{
+
Version version = super.getVersion(versionRef);
// place the version record reference in the version properties
- NodeRef record = (NodeRef)dbNodeService.getProperty(versionRef, PROP_RECORD_NODE_REF);
+ NodeRef record = (NodeRef) dbNodeService.getProperty(versionRef, PROP_RECORD_NODE_REF);
if (record != null)
- {
+ {
version.getVersionProperties().put(PROP_VERSION_RECORD, record);
}
// place information about the destruction of the version record in the properties
- Boolean destroyed = (Boolean)dbNodeService.getProperty(versionRef, PROP_DESTROYED);
+ Boolean destroyed = (Boolean) dbNodeService.getProperty(versionRef, PROP_DESTROYED);
if (destroyed == null) { destroyed = Boolean.FALSE; }
version.getVersionProperties().put(PROP_RECORDED_VERSION_DESTROYED, destroyed);
-
+
return version;
}
@@ -595,22 +618,22 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
dbNodeService.setProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY, versionPolicy);
}
}
-
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#isLatestVersionRecorded(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public boolean isCurrentVersionRecorded(NodeRef nodeRef)
{
- boolean result = false;
+ boolean result = false;
Version version = getCurrentVersion(nodeRef);
if (version != null)
{
result = isRecordedVersion(version);
- }
+ }
return result;
}
-
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#isRecordedVersion(org.alfresco.service.cmr.version.Version)
*/
@@ -620,7 +643,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
NodeRef versionNodeRef = getVersionNodeRef(version);
return dbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION);
}
-
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#getVersionRecord(org.alfresco.service.cmr.version.Version)
*/
@@ -632,8 +655,8 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
if (dbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
{
// get the version record
- result = (NodeRef)dbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF);
-
+ result = (NodeRef) dbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF);
+
// check that the version record exists
if (result != null &&
!dbNodeService.exists(result))
@@ -645,47 +668,59 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
return result;
}
-
+
/**
* Create Version Store Ref
*
- * @param store ref
- * @return store ref for version store
+ * @param store ref
+ * @return store ref for version store
*/
public StoreRef convertStoreRef(StoreRef storeRef)
{
return new StoreRef(StoreRef.PROTOCOL_WORKSPACE, storeRef.getIdentifier());
}
-
+
/**
* Convert the incomming node ref (with the version store protocol specified)
* to the internal representation with the workspace protocol.
*
- * @param nodeRef the incomming verison protocol node reference
- * @return the internal version node reference
+ * @param nodeRef the incomming verison protocol node reference
+ * @return the internal version node reference
*/
public NodeRef convertNodeRef(NodeRef nodeRef)
{
return new NodeRef(convertStoreRef(nodeRef.getStoreRef()), nodeRef.getId());
}
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#createRecordFromLatestVersion(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, autoVersion)
+ */
+ @Override
+ public NodeRef createRecordFromLatestVersion(final NodeRef filePlan, final NodeRef nodeRef, final boolean isEnableAutoVersionOnRecordCreation)
+ {
+ setEnableAutoVersionOnRecordCreation(isEnableAutoVersionOnRecordCreation);
+
+ return createRecordFromLatestVersion(filePlan, nodeRef);
+ }
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#createRecordFromLatestVersion(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public NodeRef createRecordFromLatestVersion(final NodeRef filePlan, final NodeRef nodeRef)
- {
+ {
ParameterCheck.mandatory("filePlan", filePlan);
ParameterCheck.mandatory("nodeRef", nodeRef);
-
+
NodeRef record = null;
-
+
// check for versionable aspect
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
{
+ createSnapshotVersion(nodeRef);
// get the latest version
final Version currentVersion = getCurrentVersion(nodeRef);
-
+
if (currentVersion != null &&
!isRecordedVersion(currentVersion))
{
@@ -696,19 +731,19 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
{
// get the documents readers and writers
Pair, Set> readersAndWriters = extendedPermissionService.getReadersAndWriters(nodeRef);
-
+
// grab the frozen state
NodeRef currentFrozenState = currentVersion.getFrozenStateNodeRef();
-
+
// determine the type of the object
QName type = nodeService.getType(currentFrozenState);
-
+
// grab all the properties
Map properties = nodeService.getProperties(currentFrozenState);
-
+
// grab all the aspects
Set aspects = nodeService.getAspects(currentFrozenState);
-
+
// create the record
NodeRef record = recordService.createRecordFromContent(
filePlan,
@@ -716,14 +751,14 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
type,
properties,
null);
-
+
// apply aspects to record
for (QName aspect : aspects)
{
// add the aspect, properties have already been set
nodeService.addAspect(record, aspect, null);
}
-
+
// apply version record aspect to record
PropertyMap versionRecordProps = new PropertyMap(3);
versionRecordProps.put(PROP_VERSIONED_NODEREF, nodeRef);
@@ -734,38 +769,38 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
// wire record up to previous record
linkToPreviousVersionRecord(nodeRef, record);
-
+
// set the extended security
extendedSecurityService.set(record, readersAndWriters);
-
+
return record;
}
});
-
+
// get the version history
NodeRef versionHistoryRef = getVersionHistoryNodeRef(nodeRef);
-
+
// get details from the version before we remove it
int versionNumber = getVersionNumber(currentVersion);
Map versionProperties = getVersionAspectProperties(currentVersion);
QName sourceTypeRef = getVersionType(currentVersion);
-
+
// patch-up owner information, which needs to be frozen for recorded versions
- String owner = (String)nodeService.getProperty(currentVersion.getFrozenStateNodeRef(), ContentModel.PROP_OWNER);
+ String owner = (String) nodeService.getProperty(currentVersion.getFrozenStateNodeRef(), ContentModel.PROP_OWNER);
if (owner != null)
{
versionProperties.put(PROP_FROZEN_OWNER, owner);
}
-
+
// delete the current version
this.dbNodeService.deleteNode(convertNodeRef(currentVersion.getFrozenStateNodeRef()));
-
+
// create a new version history if we need to
if (!nodeService.exists(versionHistoryRef))
{
versionHistoryRef = createVersionHistory(nodeRef);
}
-
+
// create recorded version nodeRef
ChildAssociationRef childAssocRef = dbNodeService.createNode(
versionHistoryRef,
@@ -779,34 +814,34 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
nodeService.addAspect(versionNodeRef, Version2Model.ASPECT_VERSION, versionProperties);
// add the recordedVersion aspect with link to record
- nodeService.addAspect(versionNodeRef, ASPECT_RECORDED_VERSION, Collections.singletonMap(PROP_RECORD_NODE_REF, (Serializable)record));
+ nodeService.addAspect(versionNodeRef, ASPECT_RECORDED_VERSION, Collections.singletonMap(PROP_RECORD_NODE_REF, (Serializable) record));
}
}
-
+
return record;
}
-
+
/**
- * @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#isRecordedVersionDestroyed(org.alfresco.service.cmr.version.Version)
+ * @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#isRecordedVersionDestroyed(org.alfresco.service.cmr.version.Version)
*/
@Override
public boolean isRecordedVersionDestroyed(Version version)
{
boolean result = false;
-
+
// get the version node reference
- NodeRef versionNodeRef = getVersionNodeRef(version);
+ NodeRef versionNodeRef = getVersionNodeRef(version);
// get the destroyed property value
- Boolean isDestroyed = (Boolean)dbNodeService.getProperty(versionNodeRef, PROP_DESTROYED);
+ Boolean isDestroyed = (Boolean) dbNodeService.getProperty(versionNodeRef, PROP_DESTROYED);
if (isDestroyed != null)
{
result = isDestroyed.booleanValue();
}
-
+
return result;
}
-
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService#destroyRecordedVersion(org.alfresco.service.cmr.version.Version)
*/
@@ -815,24 +850,24 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
{
// get the version node reference
NodeRef versionNodeRef = getVersionNodeRef(version);
-
+
// if it's a recorded version
if (dbNodeService.hasAspect(versionNodeRef, ASPECT_RECORDED_VERSION))
{
// mark it as destroyed
dbNodeService.setProperty(versionNodeRef, PROP_DESTROYED, true);
-
+
// clear the record node reference property
- dbNodeService.setProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF, null);
- }
+ dbNodeService.setProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF, null);
+ }
}
-
+
/**
* Helper method to get the version number of a given version by inspecting the
* name of the parent association.
*
- * @param version version
- * @return int version number
+ * @param version version
+ * @return int version number
*/
private int getVersionNumber(Version version)
{
@@ -842,11 +877,11 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
String versionNumber = fullVersionNumber.substring(fullVersionNumber.indexOf("-") + 1);
return Integer.parseInt(versionNumber);
}
-
+
/**
* Helper method to get all the version aspect properties from an existing version
*
- * @param version version
+ * @param version version
* @return Map property values
*/
private Map getVersionAspectProperties(Version version)
@@ -858,7 +893,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
{
QName propertyQName = QName.createQName(Version2Model.NAMESPACE_URI, propertyName);
result.put(propertyQName, versionProps.get(propertyQName));
-
+
if (propertyName.equals(Version2Model.PROP_FROZEN_NODE_DBID))
{
System.out.println(versionProps.get(propertyQName));
@@ -866,7 +901,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
}
return result;
}
-
+
/**
* Helper method to get the type of a versions frozen state
*
@@ -876,16 +911,57 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
private QName getVersionType(Version version)
{
return nodeService.getType(getVersionNodeRef(version));
- }
-
+ }
+
/**
* Helper method to get the internal node reference of a version
*
- * @param version version
- * @return NodeRef internal node reference to version
+ * @param version version
+ * @return NodeRef internal node reference to version
*/
private NodeRef getVersionNodeRef(Version version)
{
- return convertNodeRef(version.getFrozenStateNodeRef());
+ return convertNodeRef(version.getFrozenStateNodeRef());
+ }
+
+ /**
+ * Check if current version of the node is modified compared with versioned version
+ *
+ * @param nodeRef internal node reference
+ * @return boolean true if nodeRef is modified, otherwise false
+ */
+ public boolean isCurrentVersionDirty(NodeRef nodeRef)
+ {
+ if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE)) { return false; }
+
+ // get the latest version
+ Version currentVersion = getCurrentVersion(nodeRef);
+ Date modificationDate = (Date) nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
+
+ if (currentVersion == null) { return true; }
+
+ // grab the frozen state
+ NodeRef currentFrozenState = currentVersion.getFrozenStateNodeRef();
+ Date frozenModificationDate = (Date) nodeService.getProperty(currentFrozenState, ContentModel.PROP_MODIFIED);
+
+ boolean versionStoreOutdated = ((frozenModificationDate != null) && (modificationDate.getTime() > frozenModificationDate.getTime()));
+ return versionStoreOutdated;
+ }
+
+ /**
+ * @see RecordableVersionService#createSnapshotVersion(NodeRef)
+ */
+ public void createSnapshotVersion(NodeRef nodeRef)
+ {
+ boolean autoVersion = isEnableAutoVersionOnRecordCreation();
+ // if the flag autoversion on record creation set, create new version on dirty nodes
+ if (autoVersion && isCurrentVersionDirty(nodeRef))
+ {
+ Map autoVersionProperties = new HashMap(2);
+ autoVersionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
+ autoVersionProperties.put(VersionModel.PROP_DESCRIPTION, I18NUtil.getMessage(AUTO_VERSION_ON_RECORD_CREATION));
+ createVersion(nodeRef, autoVersionProperties);
+ }
+
}
}
diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateDispositionScheduleTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateDispositionScheduleTest.java
new file mode 100644
index 0000000000..7bcd0d47da
--- /dev/null
+++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateDispositionScheduleTest.java
@@ -0,0 +1,172 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.module.org_alfresco_module_rm.test.integration.disposition;
+
+import static org.alfresco.module.org_alfresco_module_rm.test.util.bdt.BehaviourTest.test;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction;
+import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction;
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
+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.job.publish.DispositionActionDefinitionPublishExecutor;
+import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
+import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils;
+import org.alfresco.module.org_alfresco_module_rm.test.util.bdt.BehaviourTest;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.ApplicationContextHelper;
+import org.springframework.extensions.webscripts.GUID;
+
+/**
+ * Integration tests for updating the disposition schedule.
+ *
+ * @author Tom Page
+ * @since 2.3.1
+ */
+public class UpdateDispositionScheduleTest extends BaseRMTestCase
+{
+ /** A unique prefix for the constants in this test. */
+ protected static final String TEST_PREFIX = UpdateDispositionScheduleTest.class.getName() + GUID.generate() + "_";
+ /** The name to use for the category. */
+ protected static final String CATEGORY_NAME = TEST_PREFIX + "Category";
+ /** The name to use for the folder. */
+ protected static final String FOLDER_NAME = TEST_PREFIX + "Folder";
+ /** The name to use for the record. */
+ protected static final String RECORD_NAME = TEST_PREFIX + "Record";
+
+ /** The executor for the disposition update job. */
+ private DispositionActionDefinitionPublishExecutor dispositionActionDefinitionPublishExecutor;
+ /** The internal disposition service is used to avoid permissions issues when updating the record. */
+ private DispositionService internalDispositionService;
+
+ /** The category node. */
+ private NodeRef category;
+ /** The folder node. */
+ private NodeRef folder;
+ /** The record node. */
+ private NodeRef record;
+ /** The 'disposition as of' date from before the 'when' step. */
+ private Date originalAsOfDate;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ BehaviourTest.initBehaviourTests(retryingTransactionHelper);
+
+ // Get the application context
+ applicationContext = ApplicationContextHelper.getApplicationContext(getConfigLocations());
+ dispositionActionDefinitionPublishExecutor = applicationContext.getBean(DispositionActionDefinitionPublishExecutor.class);
+ internalDispositionService = (DispositionService) applicationContext.getBean("dispositionService");
+ }
+
+ /**
+ * RM-3386
+ *
+ * Given a record subject to a disposition schedule
+ * And the next step is due to run at some period after the date the content was created
+ * When I update the period of the next step (and wait for this to be processed)
+ * Then the "as of" date is updated to be at the new period after the creation date.
+ *
+ */
+ public void testUpdatePeriod()
+ {
+ test()
+ .given(() -> {
+ // Create a category.
+ category = filePlanService.createRecordCategory(filePlan, CATEGORY_NAME);
+ // Create a disposition schedule for the category (Cut off immediately, then Destroy 1 year after the creation date).
+ DispositionSchedule dispSched = utils.createBasicDispositionSchedule(category, "instructions", "authority", true, false);
+ Map cutOffParams = ImmutableMap.of(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME,
+ PROP_DISPOSITION_DESCRIPTION, "description",
+ PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY);
+ dispositionService.addDispositionActionDefinition(dispSched, cutOffParams);
+ Map destroyParams = ImmutableMap.of(PROP_DISPOSITION_ACTION_NAME, DestroyAction.NAME,
+ PROP_DISPOSITION_DESCRIPTION, "description",
+ PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_ONE_YEAR,
+ PROP_DISPOSITION_PERIOD_PROPERTY, ContentModel.PROP_CREATED);
+ dispositionService.addDispositionActionDefinition(dispSched, destroyParams);
+ // Create a folder containing a record within the category.
+ folder = recordFolderService.createRecordFolder(category, FOLDER_NAME);
+ record = fileFolderService.create(folder, RECORD_NAME, ContentModel.TYPE_CONTENT).getNodeRef();
+
+ dispositionService.cutoffDisposableItem(record);
+ // Ensure the update has been applied to the record.
+ internalDispositionService.updateNextDispositionAction(record);
+
+ originalAsOfDate = dispositionService.getNextDispositionAction(record).getAsOfDate();
+ })
+ .when(() -> {
+ // Update the Destroy step to be 3 years after the creation date.
+ DispositionSchedule dispSched = dispositionService.getDispositionSchedule(category);
+ DispositionActionDefinition destroy = dispSched.getDispositionActionDefinitionByName(DestroyAction.NAME);
+ Map destroyParams = ImmutableMap.of(PROP_DISPOSITION_ACTION_NAME, DestroyAction.NAME,
+ PROP_DISPOSITION_DESCRIPTION, "description",
+ PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_THREE_YEARS,
+ PROP_DISPOSITION_PERIOD_PROPERTY, ContentModel.PROP_CREATED);
+ dispositionService.updateDispositionActionDefinition(destroy, destroyParams);
+
+ // Make the disposition action definition update job run.
+ dispositionActionDefinitionPublishExecutor.publish(destroy.getNodeRef());
+ })
+ .then()
+ .expect(true)
+ .from(() -> aboutTwoYearsApart(originalAsOfDate, dispositionService.getNextDispositionAction(record).getAsOfDate()))
+ .because("Increasing the destroy period by two years should increase the 'as of' date by two years.");
+ }
+
+ /**
+ * Check that the two given dates are approximately two years apart.
+ *
+ * This actually just checks that they're more than one and less than three years apart, because leap years make
+ * things hard to calculate.
+ *
+ * @return true if the two dates are about two years apart.
+ */
+ private boolean aboutTwoYearsApart(Date start, Date end)
+ {
+ long days = daysBetween(start, end);
+ long yearInDays = 365;
+ return (yearInDays < days) && (days < 3 * yearInDays);
+ }
+
+ /** Find the number of days between the two dates. */
+ private long daysBetween(Date start, Date end)
+ {
+ return TimeUnit.MILLISECONDS.toDays(end.getTime() - start.getTime());
+ }
+}
diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1727Test.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1727Test.java
index 293a948e8a..d74556cc22 100644
--- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1727Test.java
+++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1727Test.java
@@ -90,7 +90,7 @@ public class RM1727Test extends BaseRMTestCase
return null;
}
});
-
+
doTestInTransaction(new Test()
{
@Override
diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java
index 596d569525..1b370b73f4 100644
--- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java
+++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java
@@ -28,20 +28,23 @@
package org.alfresco.module.org_alfresco_module_rm.test.integration.version;
import java.io.Serializable;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService;
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.QName;
import org.alfresco.util.GUID;
/**
* Declare as record version integration tests
- *
+ *
* @author Roy Wetherall
* @since 2.3
*/
@@ -49,7 +52,7 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest
{
/** recordable version service */
private RecordableVersionService recordableVersionService;
-
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#initServices()
*/
@@ -57,56 +60,56 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest
protected void initServices()
{
super.initServices();
- recordableVersionService = (RecordableVersionService)applicationContext.getBean("RecordableVersionService");
+ recordableVersionService = (RecordableVersionService) applicationContext.getBean("RecordableVersionService");
}
-
+
/**
- * Given versionable content with a non-recorded latest version
- * When I declare a version record
+ * Given versionable content with a non-recorded latest version
+ * When I declare a version record
* Then the latest version is recorded and a record is created
*/
public void testDeclareLatestVersionAsRecord()
{
doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
- {
+ {
private NodeRef versionRecord;
- private Map versionProperties;
-
+ private Map versionProperties;
+
public void given() throws Exception
{
// setup version properties
versionProperties = new HashMap(4);
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
-
+
// create version
versionService.createVersion(dmDocument, versionProperties);
-
+
// assert that the latest version is not recorded
assertFalse(recordableVersionService.isCurrentVersionRecorded(dmDocument));
}
-
+
public void when()
- {
+ {
// create version record from latest version
versionRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, dmDocument);
- }
-
+ }
+
public void then()
{
// check the created record
assertNotNull(versionRecord);
assertTrue(recordService.isRecord(versionRecord));
-
+
// assert the current version is recorded
assertTrue(recordableVersionService.isCurrentVersionRecorded(dmDocument));
-
+
// check the recorded version
checkRecordedVersion(dmDocument, DESCRIPTION, "0.1");
}
- });
- }
-
+ });
+ }
+
/**
* Given versionable content with a recorded latest version
* When I declare a version record
@@ -116,10 +119,10 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest
public void testDeclareLatestVersionAsRecordButAlreadyRecorded()
{
doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
- {
+ {
private NodeRef versionRecord;
- private Map versionProperties;
-
+ private Map versionProperties;
+
public void given() throws Exception
{
// setup version properties
@@ -128,90 +131,270 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan);
-
+
// create version
versionService.createVersion(dmDocument, versionProperties);
-
+
// assert that the latest version is not recorded
assertTrue(recordableVersionService.isCurrentVersionRecorded(dmDocument));
}
-
+
public void when()
- {
+ {
// create version record from latest version
versionRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, dmDocument);
- }
-
+ }
+
public void then()
{
// check that a record was not created
assertNull(versionRecord);
-
- // assert the current version is recorded
+
+ // assert the current version is recorded
assertTrue(recordableVersionService.isCurrentVersionRecorded(dmDocument));
-
+
// check the recorded version
checkRecordedVersion(dmDocument, DESCRIPTION, "0.1");
}
- });
+ });
}
/**
- * Given that a document is a specialized type
- * When version is declared as a record
- * Then the record is the same type as the source document
+ * Given that a document is a specialized type
+ * When version is declared as a record
+ * Then the record is the same type as the source document
*
* @see https://issues.alfresco.com/jira/browse/RM-2194
*/
public void testSpecializedContentType()
{
doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
- {
+ {
private NodeRef customDocument;
private NodeRef versionRecord;
- private Map versionProperties;
-
+ private Map versionProperties;
+
public void given() throws Exception
{
- // create content
+ // create content
customDocument = fileFolderService.create(dmFolder, GUID.generate(), TYPE_CUSTOM_TYPE).getNodeRef();
prepareContent(customDocument);
-
+
// setup version properties
versionProperties = new HashMap(2);
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
-
+
// create version
versionService.createVersion(customDocument, versionProperties);
-
+
// assert that the latest version is not recorded
assertFalse(recordableVersionService.isCurrentVersionRecorded(customDocument));
}
-
+
public void when()
- {
+ {
// create version record from latest version
versionRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, customDocument);
- }
-
+ }
+
public void then()
{
// check the created record
assertNotNull(versionRecord);
assertTrue(recordService.isRecord(versionRecord));
-
+
// check the record type is correct
assertEquals(TYPE_CUSTOM_TYPE, nodeService.getType(versionRecord));
-
+
// assert the current version is recorded
assertTrue(recordableVersionService.isCurrentVersionRecorded(customDocument));
-
+
// check the recorded version
checkRecordedVersion(customDocument, DESCRIPTION, "0.1");
}
- });
-
+ });
+
+ }
+
+ /**
+ * Given versionable content with a recorded latest version and autoversion is true
+ * When I declare this version record and contains local modifications
+ * Then a new minor version is created for document
+ *
+ * @see https://issues.alfresco.com/jira/browse/RM-2368
+ */
+ public void testCreateRecordFromLatestVersionAutoTrue()
+ {
+ doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
+ {
+ private NodeRef myDocument;
+ private NodeRef versionedRecord;
+ private Map versionProperties;
+ private Date createdDate;
+ private Date modificationDate;
+ private String record_name = "initial_name";
+ private String AUTO_VERSION_DESCRIPTION = "Auto Version on Record Creation";
+ private boolean autoVersion = true;
+
+ public void given() throws Exception
+ {
+ // create a document
+ myDocument = fileFolderService.create(dmFolder, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
+ createdDate = (Date) nodeService.getProperty(myDocument, ContentModel.PROP_CREATED);
+ modificationDate = (Date) nodeService.getProperty(myDocument, ContentModel.PROP_MODIFIED);
+ assertTrue("Modified date must be after or on creation date", createdDate.getTime() == modificationDate.getTime());
+
+ // Set initial set of properties
+ Map properties = new HashMap(3);
+ // Ensure default behaviour autoversion on change properties is set to false
+ properties.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
+ // Set initial name
+ properties.put(ContentModel.PROP_NAME, "initial_name");
+ nodeService.setProperties(myDocument, properties);
+ nodeService.setProperty(myDocument, ContentModel.PROP_DESCRIPTION, DESCRIPTION);
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_OWNABLE, null);
+ // make sure document is versionable
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_VERSIONABLE, null);
+ // Change Type to a custom document
+ nodeService.setType(myDocument, TYPE_CUSTOM_TYPE);
+
+ // setup version properties
+ versionProperties = new HashMap(2);
+ versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
+ versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
+
+ // create initial version
+ versionService.createVersion(myDocument, versionProperties);
+ }
+
+ public void when()
+ {
+ // Apply a custom aspect
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_TITLED, null);
+ // Update properties
+ nodeService.setProperty(myDocument, ContentModel.PROP_NAME, "updated_name");
+ nodeService.setProperty(myDocument, ContentModel.PROP_DESCRIPTION, DESCRIPTION);
+ // test RM-2368
+ versionedRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, myDocument, autoVersion);
+ }
+
+ public void then()
+ {
+ // Properties updated / flag as modified
+ // check the created record
+ assertNotNull(versionedRecord);
+ assertTrue(recordService.isRecord(versionedRecord));
+
+ // check the record type is correct
+ assertEquals(TYPE_CUSTOM_TYPE, nodeService.getType(versionedRecord));
+
+ // assert the current version is recorded
+ assertTrue(recordableVersionService.isCurrentVersionRecorded(myDocument));
+
+ // get name of record
+ record_name = (String) nodeService.getProperty(versionedRecord, ContentModel.PROP_NAME);
+
+ // new version is create, current node was modified
+ assertTrue("Name was updated:", record_name.contains("updated_name"));
+ // check record
+ checkRecordedVersion(myDocument, AUTO_VERSION_DESCRIPTION, "1.1");
+
+ }
+
+ });
+
}
+
+ /**
+ *
+ * Given versionable content with a recorded latest version and autoversion is false
+ * When I declare this version record and contains local modifications
+ * Then a record is created from latest version
+ *
+ * @see https://issues.alfresco.com/jira/browse/RM-2368
+ */
+ public void testCreateRecordFromLatestVersion()
+ {
+ doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator)
+ {
+ private NodeRef myDocument;
+ private NodeRef versionedRecord;
+ private Map versionProperties;
+ private Date createdDate;
+ private Date modificationDate;
+ private String record_name = "initial_name";
+ private boolean autoVersion = false;
+
+ public void given() throws Exception
+ {
+ // create a document
+ myDocument = fileFolderService.create(dmFolder, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
+ createdDate = (Date) nodeService.getProperty(myDocument, ContentModel.PROP_CREATED);
+ modificationDate = (Date) nodeService.getProperty(myDocument, ContentModel.PROP_MODIFIED);
+ assertTrue("Modified date must be after or on creation date", createdDate.getTime() == modificationDate.getTime());
+
+ // Set initial set of properties
+ Map properties = new HashMap(3);
+ // Ensure default behaviour autoversion on change properties is set to false
+ properties.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
+ // Set initial name
+ properties.put(ContentModel.PROP_NAME, "initial_name");
+ nodeService.setProperties(myDocument, properties);
+ nodeService.setProperty(myDocument, ContentModel.PROP_DESCRIPTION, DESCRIPTION);
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_OWNABLE, null);
+ // make sure document is versionable
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_VERSIONABLE, null);
+ // Change Type to a custom document
+ nodeService.setType(myDocument, TYPE_CUSTOM_TYPE);
+
+ // setup version properties
+ versionProperties = new HashMap(2);
+ versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
+ versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
+
+ // create initial version
+ versionService.createVersion(myDocument, versionProperties);
+ }
+
+ public void when()
+ {
+ // Apply a custom aspect
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_TITLED, null);
+ // Update properties
+ nodeService.setProperty(myDocument, ContentModel.PROP_NAME, "initial_name");
+ nodeService.setProperty(myDocument, ContentModel.PROP_DESCRIPTION, DESCRIPTION);
+ // test RM-2368
+ versionedRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, myDocument, autoVersion);
+ }
+
+ public void then()
+ {
+ // Properties updated / flag as modified
+ // check the created record
+ assertNotNull(versionedRecord);
+ assertTrue(recordService.isRecord(versionedRecord));
+
+ // check the record type is correct
+ assertEquals(TYPE_CUSTOM_TYPE, nodeService.getType(versionedRecord));
+
+ // assert the current version is recorded
+ assertTrue(recordableVersionService.isCurrentVersionRecorded(myDocument));
+
+ // get name of record
+ record_name = (String) nodeService.getProperty(versionedRecord, ContentModel.PROP_NAME);
+
+ // record is created based on existing frozen, which does not contain any modification of node
+ assertTrue("Name is not modified: ", record_name.contains("initial_name"));
+ checkRecordedVersion(myDocument, DESCRIPTION, "1.0");
+
+ }
+
+
+ });
+
+ }
+
+
}
diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java
index 53e4bb898d..df5266be21 100644
--- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java
+++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java
@@ -66,7 +66,7 @@ import org.springframework.context.ApplicationContext;
/**
* Common RM test utility methods.
- *
+ *
* @author Roy Wetherall
*/
public class CommonRMTestUtils implements RecordsManagementModel
@@ -87,10 +87,12 @@ public class CommonRMTestUtils implements RecordsManagementModel
public static final String PERIOD_NONE = "none|0";
public static final String PERIOD_IMMEDIATELY = "immediately|0";
public static final String PERIOD_ONE_WEEK = "week|1";
+ public static final String PERIOD_ONE_YEAR = "year|1";
+ public static final String PERIOD_THREE_YEARS = "year|3";
/**
* Constructor
- *
+ *
* @param applicationContext application context
*/
public CommonRMTestUtils(ApplicationContext applicationContext)
@@ -106,7 +108,7 @@ public class CommonRMTestUtils implements RecordsManagementModel
/**
* Create a disposition schedule
- *
+ *
* @param container record category
* @return {@link DispositionSchedule} created disposition schedule node reference
*/
@@ -140,15 +142,15 @@ public class CommonRMTestUtils implements RecordsManagementModel
boolean extendedDispositionSchedule)
{
return createDispositionSchedule(
- container,
- dispositionInstructions,
- dispositionAuthority,
- isRecordLevel,
- defaultDispositionActions,
- extendedDispositionSchedule,
+ container,
+ dispositionInstructions,
+ dispositionAuthority,
+ isRecordLevel,
+ defaultDispositionActions,
+ extendedDispositionSchedule,
DEFAULT_EVENT_NAME);
}
-
+
/**
* Create test disposition schedule
*/
@@ -203,7 +205,7 @@ public class CommonRMTestUtils implements RecordsManagementModel
/**
* Helper method to create a record in a record folder.
- *
+ *
* @param recordFolder record folder
* @param name name of record
* @return {@link NodeRef} record node reference
@@ -215,7 +217,7 @@ public class CommonRMTestUtils implements RecordsManagementModel
/**
* Helper method to create a record in a record folder.
- *
+ *
* @param recordFolder record folder
* @param name name of the record
* @param title title of the record
@@ -230,7 +232,7 @@ public class CommonRMTestUtils implements RecordsManagementModel
/**
* Helper method to create a record in a record folder.
- *
+ *
* @param recordFolder record folder
* @param name name of record
* @param properties properties of the record
@@ -250,10 +252,10 @@ public class CommonRMTestUtils implements RecordsManagementModel
return record;
}
-
+
/**
* Helper method to create a record in a record folder.
- *
+ *
* @param recordFolder record folder
* @param name name of record
* @param properties properties of the record
@@ -273,7 +275,7 @@ public class CommonRMTestUtils implements RecordsManagementModel
return record;
}
-
+
/**
* Helper to consolidate creation of contentless record
*/
@@ -292,10 +294,10 @@ public class CommonRMTestUtils implements RecordsManagementModel
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
ContentModel.TYPE_CONTENT,
- properties).getChildRef();
- return record;
+ properties).getChildRef();
+ return record;
}
-
+
/**
* Helper method to complete record.
*/
@@ -309,8 +311,8 @@ public class CommonRMTestUtils implements RecordsManagementModel
modelSecurityService.setEnabled(false);
try
{
- nodeService.setProperty(record, RecordsManagementModel.PROP_DATE_FILED, new Date());
- nodeService.setProperty(record, ContentModel.PROP_TITLE, "titleValue");
+ nodeService.setProperty(record, RecordsManagementModel.PROP_DATE_FILED, new Date());
+ nodeService.setProperty(record, ContentModel.PROP_TITLE, "titleValue");
actionService.executeRecordsManagementAction(record, "declareRecord");
}
finally
@@ -323,7 +325,7 @@ public class CommonRMTestUtils implements RecordsManagementModel
}, AuthenticationUtil.getAdminUserName());
- }
+ }
public void closeFolder(final NodeRef recordFolder)
{
@@ -361,10 +363,10 @@ public class CommonRMTestUtils implements RecordsManagementModel
return filePlanRoleService.createRole(filePlan, roleName, roleName, capabilities);
}
-
+
/**
* Helper method to complete event on disposable item
- *
+ *
* @param disposableItem disposable item (record or record folder)
* @param eventName event name
*/
@@ -373,8 +375,8 @@ public class CommonRMTestUtils implements RecordsManagementModel
// build action properties
Map params = new HashMap(1);
params.put(CompleteEventAction.PARAM_EVENT_NAME, eventName);
-
+
// complete event
- actionService.executeRecordsManagementAction(disposableItem, CompleteEventAction.NAME, params);
+ actionService.executeRecordsManagementAction(disposableItem, CompleteEventAction.NAME, params);
}
-}
+}
\ No newline at end of file
diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateActionUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateActionUnitTest.java
new file mode 100644
index 0000000000..f83249dc51
--- /dev/null
+++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateActionUnitTest.java
@@ -0,0 +1,103 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.module.org_alfresco_module_rm.action.impl;
+
+import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_DISPOSITION_AS_OF;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Date;
+
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction;
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
+import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link BroadcastDispositionActionDefinitionUpdateAction}.
+ *
+ * @author Tom Page
+ * @since 2.3.1
+ */
+public class BroadcastDispositionActionDefinitionUpdateActionUnitTest
+{
+ /** The node under the category containing information about the definition of the action. */
+ private static final NodeRef DISPOSITION_ACTION_DEF_NODE = new NodeRef("disposition://Action/Def");
+ /** The node containing the details of the next disposition step for the content. */
+ private static final NodeRef NEXT_ACTION_NODE_REF = new NodeRef("next://Step/");
+ /** The node being subject to the disposition step. */
+ private static final NodeRef CONTENT_NODE_REF = new NodeRef("content://Node/Ref");
+
+ /** The class under test. */
+ private BroadcastDispositionActionDefinitionUpdateAction action = new BroadcastDispositionActionDefinitionUpdateAction();
+
+ private NodeService mockNodeService = mock(NodeService.class);
+ private DispositionService mockDispositionService = mock(DispositionService.class);
+
+ /** Inject the mock services into the class under test and link the content and next action nodes. */
+ @Before
+ public void setUp()
+ {
+ action.setNodeService(mockNodeService);
+ action.setDispositionService(mockDispositionService);
+
+ ChildAssociationRef mockAssocRef = mock(ChildAssociationRef.class);
+ when(mockNodeService.getPrimaryParent(NEXT_ACTION_NODE_REF)).thenReturn(mockAssocRef);
+ when(mockAssocRef.getParentRef()).thenReturn(CONTENT_NODE_REF);
+ }
+
+ /**
+ * Check that the disposition service is used to determine the "disposition as of" date when changes are made to the
+ * disposition period.
+ */
+ @Test
+ public void testPersistPeriodChanges()
+ {
+ // Set up the data associated with the next disposition action.
+ DispositionAction mockAction = mock(DispositionAction.class);
+ when(mockAction.getNodeRef()).thenReturn(NEXT_ACTION_NODE_REF);
+ DispositionActionDefinition mockDispositionActionDefinition = mock(DispositionActionDefinition.class);
+ when(mockAction.getDispositionActionDefinition()).thenReturn(mockDispositionActionDefinition);
+ when(mockAction.getName()).thenReturn("mockAction");
+ // Set up the disposition service to return a known "disposition as of" date.
+ Date asOfDate = new Date();
+ when(mockDispositionService.calculateAsOfDate(CONTENT_NODE_REF, mockDispositionActionDefinition, false))
+ .thenReturn(asOfDate);
+
+ // Call the method under test.
+ action.persistPeriodChanges(DISPOSITION_ACTION_DEF_NODE, mockAction);
+
+ // Check that the "disposition as of" date has been set on the next action.
+ verify(mockNodeService).setProperty(NEXT_ACTION_NODE_REF, PROP_DISPOSITION_AS_OF, asOfDate);
+ }
+}
diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImplUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImplUnitTest.java
new file mode 100644
index 0000000000..0e9a44d001
--- /dev/null
+++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImplUnitTest.java
@@ -0,0 +1,102 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.module.org_alfresco_module_rm.disposition;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Date;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.Period;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link DispositionServiceImpl}.
+ *
+ * @author Tom Page
+ * @since 2.3.1
+ */
+public class DispositionServiceImplUnitTest
+{
+ /** The node being subject to the disposition step. */
+ NodeRef CONTENT_NODE_REF = new NodeRef("content://node/");
+
+ /** The class under test. */
+ private DispositionServiceImpl dispositionService = new DispositionServiceImpl();
+
+ private NodeService mockNodeService = mock(NodeService.class);
+
+ @Before
+ public void setUp()
+ {
+ dispositionService.setNodeService(mockNodeService);
+ }
+
+ /**
+ * Check that the relevant information is retrieved from the DispositionActionDefinition in order to determine the
+ * "disposition as of" date.
+ */
+ @Test
+ public void testCalculateAsOfDate()
+ {
+ // Set up a mock for the disposition action definition.
+ DispositionActionDefinition mockDispositionActionDefinition = mock(DispositionActionDefinition.class);
+ Period mockPeriod = mock(Period.class);
+ when(mockDispositionActionDefinition.getPeriod()).thenReturn(mockPeriod);
+ when(mockDispositionActionDefinition.getPeriodProperty()).thenReturn(ContentModel.PROP_CREATED);
+ // Set up a created date and another date that is some Period later.
+ Date createdDate = new Date(1234567890);
+ when(mockNodeService.getProperty(CONTENT_NODE_REF, ContentModel.PROP_CREATED)).thenReturn(createdDate);
+ Date nextDate = new Date(1240000000);
+ when(mockPeriod.getNextDate(createdDate)).thenReturn(nextDate);
+
+ // Call the method under test.
+ Date asOfDate = dispositionService.calculateAsOfDate(CONTENT_NODE_REF, mockDispositionActionDefinition, true);
+
+ assertEquals("Unexpected calculation for 'as of' date", nextDate, asOfDate);
+ }
+
+ /** Check that the calculated "disposition as of" date is null if a null period is given. */
+ @Test
+ public void testCalculateAsOfDate_nullPeriod()
+ {
+ DispositionActionDefinition mockDispositionActionDefinition = mock(DispositionActionDefinition.class);
+ when(mockDispositionActionDefinition.getPeriod()).thenReturn(null);
+
+ // Call the method under test.
+ Date asOfDate = dispositionService.calculateAsOfDate(CONTENT_NODE_REF, mockDispositionActionDefinition, true);
+
+ assertNull("It should not be possible to determine the 'as of' date.", asOfDate);
+ }
+}
diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/repo/web/scripts/roles/DynamicAuthoritiesGetUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/repo/web/scripts/roles/DynamicAuthoritiesGetUnitTest.java
index 38d3da056b..3c9043e096 100644
--- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/repo/web/scripts/roles/DynamicAuthoritiesGetUnitTest.java
+++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/repo/web/scripts/roles/DynamicAuthoritiesGetUnitTest.java
@@ -24,24 +24,6 @@
* along with Alfresco. If not, see .
* #L%
*/
-/*
- * 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 .
- */
package org.alfresco.repo.web.scripts.roles;