From 17099d1731aca3186aa832c3fc9d905ea58ac5fb Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Mon, 3 Oct 2016 18:02:20 +0300 Subject: [PATCH 1/7] RM-2368 Initial version record does not inherit document type and aspects from original document --- .../alfresco-global.properties | 7 + .../records-management-service.properties | 3 +- .../rm-version-context.xml | 3 + .../record/RecordServiceImpl.java | 4 +- .../version/RecordableVersionService.java | 61 ++-- .../version/RecordableVersionServiceImpl.java | 267 +++++++++++------- .../version/DeclareAsRecordVersionTest.java | 256 +++++++++++++---- 7 files changed, 420 insertions(+), 181 deletions(-) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties index 4c3a2f3d64..8116b69d78 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties @@ -77,3 +77,10 @@ rm.patch.v22.convertToStandardFilePlan=false # a document will be auto-versioned when its type is changed. # version.store.enableAutoVersionOnTypeChange=false + +# +# Enable auto-version to be created when there is a difference between the document and latest record state +# to ensure that the created version record matches the current document state, +# otherwise create the version record from the version history +# +rm.enableAutoVersionOnRecordCreation=false diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties index f53f066f9d..20a0cf4c62 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties @@ -18,4 +18,5 @@ rm.service.vital-def-missing=Vital record definition aspect is not present on no rm.service.close-record-folder-not-folder=The record folder couldn't be closed because it's not defined as a record folder.(nodeRef={0}) rm.service.node-has-aspect=The node {0} has already the aspect {1}. rm.service.final-version=Final -rm.service.final-version-description=The final archived record version \ No newline at end of file +rm.service.final-version-description=The final archived record version +rm.service.enable-autoversion-on-record-creation=Auto Version on Record Creation \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml index 1f755ca57f..4088679ca1 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml @@ -21,6 +21,7 @@ + @@ -28,6 +29,7 @@ + @@ -77,6 +79,7 @@ * Returns false if not versionable or no version. * - * @param nodeRef node reference - * @return boolean true if latest version recorded, false otherwise + * @param nodeRef node reference + * @return boolean true if latest version recorded, false otherwise */ boolean isCurrentVersionRecorded(NodeRef nodeRef); - + /** * Indicates whether a version is recorded or not. * - * @param version version - * @return boolean true if recorded version, false otherwise + * @param version version + * @return boolean true if recorded version, false otherwise */ 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 + * @param version version + * @return NodeRef node reference of version record */ NodeRef getVersionRecord(Version version); - + /** * Gets the version that relates to the version record * * @param versionRecord version record node reference - * @return Version version or null if not found + * @return Version version or null if not found */ Version getRecordedVersion(NodeRef record); - + /** * 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. + * 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); - + /** * Indicates whether a record version is destroyed or not. * - * @param version version - * @return boolean true if destroyed, false otherwise + * @param version version + * @return boolean true if destroyed, false otherwise */ boolean isRecordedVersionDestroyed(Version version); - + /** * 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 + * @param version version */ void destroyRecordedVersion(Version version); + /** + * Flag that indicate to create new version on record creation if current state of node is modified + * + * @return boolean + */ + public boolean isEnableAutoVersionOnRecordCreation(); + + /** + * Create a snapshot - 'freeze' version of current node + * + * @param nodeRef node reference + * @return version version or null + */ + Version createFreezeVersion(NodeRef nodeRef); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java index e63d5b696b..b2508898fb 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java @@ -24,6 +24,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; @@ -57,6 +58,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 @@ -79,6 +81,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[] { @@ -113,15 +121,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) { @@ -129,7 +137,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl } /** - * @param authenticationUtil authentication util helper + * @param authenticationUtil authentication util helper */ public void setAuthenticationUtil(AuthenticationUtil authenticationUtil) { @@ -137,7 +145,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl } /** - * @param relationshipService relationship service + * @param relationshipService relationship service */ public void setRelationshipService(RelationshipService relationshipService) { @@ -153,7 +161,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl } /** - * @param modelSecurityService model security service + * @param modelSecurityService model security service */ public void setModelSecurityService(ModelSecurityService modelSecurityService) { @@ -167,7 +175,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl { this.cmObjectType = cmObjectType; } - + /** * @param extendedPermissionService extended permission service */ @@ -175,9 +183,9 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl { this.extendedPermissionService = extendedPermissionService; } - + /** - * @param extendedSecurityService extended security service + * @param extendedSecurityService extended security service */ public void setExtendedSecurityService(ExtendedSecurityService extendedSecurityService) { @@ -185,7 +193,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 @@ -205,7 +227,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 @@ -232,12 +254,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(); @@ -246,7 +268,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() { @@ -276,7 +298,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()); @@ -306,7 +328,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); @@ -323,13 +345,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, @@ -356,14 +378,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 @@ -400,7 +422,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); @@ -441,8 +463,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) { @@ -465,8 +487,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) { @@ -480,7 +502,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)) { @@ -492,7 +514,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) */ @@ -545,20 +567,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; } @@ -577,22 +600,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) */ @@ -602,7 +625,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) */ @@ -614,8 +637,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)) @@ -627,47 +650,48 @@ 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) */ @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)) { + createFreezeVersion(nodeRef); // get the latest version final Version currentVersion = getCurrentVersion(nodeRef); - + if (currentVersion != null && !isRecordedVersion(currentVersion)) { @@ -678,19 +702,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, @@ -698,14 +722,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); @@ -715,38 +739,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, @@ -760,34 +784,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) */ @@ -796,24 +820,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) { @@ -823,11 +847,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) @@ -839,7 +863,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)); @@ -847,7 +871,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl } return result; } - + /** * Helper method to get the type of a versions frozen state * @@ -857,16 +881,67 @@ 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) == true) + { + // get the latest version + Version currentVersion = getCurrentVersion(nodeRef); + Date modificationDate = (Date) nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED); + if (currentVersion != null) + { + // grab the frozen state + NodeRef currentFrozenState = currentVersion.getFrozenStateNodeRef(); + Date frozenModificationDate = (Date) nodeService.getProperty(currentFrozenState, ContentModel.PROP_MODIFIED); + if (frozenModificationDate != null) + { + if (modificationDate.getTime() > frozenModificationDate.getTime()) { return true; } + } + } + else + { + return true; + } + + } + return false; + } + + /** + * @see RecordableVersionService#createFreezeVersion(NodeRef) + */ + public Version createFreezeVersion(NodeRef nodeRef) + { + Version newVersion = null; + 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)); + newVersion = createVersion(nodeRef, autoVersionProperties); + } + return newVersion; } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java index b305a1801c..69bbb27879 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java @@ -19,20 +19,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 */ @@ -40,7 +43,7 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest { /** recordable version service */ private RecordableVersionService recordableVersionService; - + /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#initServices() */ @@ -48,69 +51,66 @@ 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 - * Then the latest version is recorded and a record is created + * 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 - * Then nothing happens since the latest version is already recorded - * And a warning is logged + * Given versionable content with a recorded latest version When I declare a version record Then nothing happens + * since the latest version is already recorded And a warning is logged */ public void testDeclareLatestVersionAsRecordButAlreadyRecorded() { doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator) - { + { private NodeRef versionRecord; - private Map versionProperties; - + private Map versionProperties; + public void given() throws Exception { // setup version properties @@ -119,90 +119,230 @@ 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"); } - }); - + }); + } - + + /** + * @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 frozenModifDate; + private Date modificationDate; + private String record_name = "initial_name"; + private String AUTO_VERSION_DESCRIPTION = "Auto Version on Record Creation"; + 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); + + Date modificationDate1 = (Date) nodeService.getProperty(myDocument, ContentModel.PROP_MODIFIED); + assertTrue("Frozen modification date", modificationDate.getTime() == modificationDate1.getTime()); + // 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); + Version version = versionService.getCurrentVersion(myDocument); + frozenModifDate = version.getFrozenModifiedDate(); + + // get autoversion flag from cofiguratie + autoVersion = recordableVersionService.isEnableAutoVersionOnRecordCreation(); + } + + public void when() + { + // check1 + assertTrue("Frozen modification date is the same with initial document ", modificationDate.getTime() == frozenModifDate.getTime()); + // current node is not dirty + assertFalse(isCurrentVersionDirty(myDocument)); + + if (autoVersion) + { + // 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); + // node should be modified + assertTrue(isCurrentVersionDirty(myDocument)); + } + else + { + assertFalse(isCurrentVersionDirty(myDocument)); + } + + assertFalse(recordableVersionService.isCurrentVersionRecorded(myDocument)); + // test RM-2368 + versionedRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, myDocument); + + } + + 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); + + if (autoVersion) + { + // 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"); + } + else + { + // 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"); + } + + } + + public boolean isCurrentVersionDirty(NodeRef nodeRef) + { + if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) + { + // get the latest version + Version currentVersion = versionService.getCurrentVersion(nodeRef); + Date modificationDate = (Date) nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED); + if (currentVersion != null) + { + // grab the frozen state + NodeRef currentFrozenState = currentVersion.getFrozenStateNodeRef(); + Date frozenModificationDate = (Date) nodeService.getProperty(currentFrozenState, ContentModel.PROP_MODIFIED); + if (modificationDate.getTime() > frozenModificationDate.getTime()) { return true; } + } + else + { + return true; + } + } + return false; + } + + }); + + } + } From db0f5a2b4525483f23730d15ca67435ab2eca6b9 Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Tue, 4 Oct 2016 14:22:59 +0300 Subject: [PATCH 2/7] Re-format acceptance criteria comments --- .../version/DeclareAsRecordVersionTest.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) mode change 100755 => 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java old mode 100755 new mode 100644 index 69bbb27879..db99d11803 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java @@ -55,8 +55,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** - * 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 + * 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() { @@ -101,8 +102,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** - * Given versionable content with a recorded latest version When I declare a version record Then nothing happens - * since the latest version is already recorded And a warning is logged + * Given versionable content with a recorded latest version + * When I declare a version record + * Then nothing happens since the latest version is already recorded And a warning is logged */ public void testDeclareLatestVersionAsRecordButAlreadyRecorded() { @@ -148,8 +150,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** - * 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 */ @@ -205,6 +208,11 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** + * + * Given versionable content with a recorded latest version with auto-version set on true + * When I declare this version record + * Then a new minor version is created for document + * * @see https://issues.alfresco.com/jira/browse/RM-2368 */ public void testCreateRecordFromLatestVersion() @@ -261,8 +269,6 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest public void when() { - // check1 - assertTrue("Frozen modification date is the same with initial document ", modificationDate.getTime() == frozenModifDate.getTime()); // current node is not dirty assertFalse(isCurrentVersionDirty(myDocument)); @@ -280,8 +286,6 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest { assertFalse(isCurrentVersionDirty(myDocument)); } - - assertFalse(recordableVersionService.isCurrentVersionRecorded(myDocument)); // test RM-2368 versionedRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, myDocument); From cf602aa9e18bf5b416e8fff20bac9ee11de6bccc Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Tue, 4 Oct 2016 14:27:03 +0300 Subject: [PATCH 3/7] Re-format acceptance criteria comments --- .../test/integration/version/DeclareAsRecordVersionTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java index db99d11803..3e2d83f0f6 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java @@ -320,7 +320,6 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest assertTrue("Name is not modified: ", record_name.contains("initial_name")); checkRecordedVersion(myDocument, DESCRIPTION, "1.0"); } - } public boolean isCurrentVersionDirty(NodeRef nodeRef) From b46709d75a304048b22ab21831bdfcb10bb71ace Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Tue, 4 Oct 2016 14:34:07 +0300 Subject: [PATCH 4/7] Re-format acceptance criteria comments --- .../version/DeclareAsRecordVersionTest.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java index 69bbb27879..d735a2b31c 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java @@ -101,8 +101,10 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** - * Given versionable content with a recorded latest version When I declare a version record Then nothing happens - * since the latest version is already recorded And a warning is logged + * Given versionable content with a recorded latest version + * When I declare a version record + * Then nothing happens since the latest version is already recorded And a warning is logged + * */ public void testDeclareLatestVersionAsRecordButAlreadyRecorded() { @@ -148,8 +150,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** - * 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 */ @@ -205,6 +208,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** + * Given versionable content with a non recorded latest version, with auto-version flag true , and properties are changed for current version + * When I declare this version as a record + * Then a new minor version is created * @see https://issues.alfresco.com/jira/browse/RM-2368 */ public void testCreateRecordFromLatestVersion() From 98ca0abe19af3c8d59c37f0e06a0a277f5620aca Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Thu, 6 Oct 2016 13:03:40 +0300 Subject: [PATCH 5/7] RM-2368 Initial version record does not inherit document type and aspects from original document --- .../record/RecordServiceImpl.java | 2 +- .../version/RecordableVersionService.java | 26 ++- .../version/RecordableVersionServiceImpl.java | 55 +++--- .../version/DeclareAsRecordVersionTest.java | 174 +++++++++++------- 4 files changed, 156 insertions(+), 101 deletions(-) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index 6e54dbcf03..f4fa00e1d0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -1039,7 +1039,7 @@ public class RecordServiceImpl extends BaseBehaviourBean NodeRef versionRecord = null; - recordableVersionService.createFreezeVersion(nodeRef); + recordableVersionService.createSnapshotVersion(nodeRef); // wire record up to previous record VersionHistory versionHistory = versionService.getVersionHistory(nodeRef); if (versionHistory != null) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java index 63aad9852f..d33e5ac532 100755 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionService.java @@ -64,7 +64,7 @@ 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. * @@ -72,6 +72,19 @@ public interface RecordableVersionService * @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. @@ -91,17 +104,16 @@ public interface RecordableVersionService void destroyRecordedVersion(Version version); /** - * Flag that indicate to create new version on record creation if current state of node is modified + * Flag that indicate to create new version on record creation if current node is modified * - * @return boolean + * @return boolean true to auto-version on record creation, false to use latest versioned version */ - public boolean isEnableAutoVersionOnRecordCreation(); + boolean isEnableAutoVersionOnRecordCreation(); /** - * Create a snapshot - 'freeze' version of current node + * Create a snapshot version of current node * * @param nodeRef node reference - * @return version version or null */ - Version createFreezeVersion(NodeRef nodeRef); + void createSnapshotVersion(NodeRef nodeRef); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java index b2508898fb..8463159849 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java @@ -673,6 +673,17 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl { 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) @@ -688,7 +699,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl // check for versionable aspect if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE)) { - createFreezeVersion(nodeRef); + createSnapshotVersion(nodeRef); // get the latest version final Version currentVersion = getCurrentVersion(nodeRef); @@ -902,37 +913,27 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl */ public boolean isCurrentVersionDirty(NodeRef nodeRef) { + if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE)) { return false; } - if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) - { - // get the latest version - Version currentVersion = getCurrentVersion(nodeRef); - Date modificationDate = (Date) nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED); - if (currentVersion != null) - { - // grab the frozen state - NodeRef currentFrozenState = currentVersion.getFrozenStateNodeRef(); - Date frozenModificationDate = (Date) nodeService.getProperty(currentFrozenState, ContentModel.PROP_MODIFIED); - if (frozenModificationDate != null) - { - if (modificationDate.getTime() > frozenModificationDate.getTime()) { return true; } - } - } - else - { - return true; - } + // get the latest version + Version currentVersion = getCurrentVersion(nodeRef); + Date modificationDate = (Date) nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED); - } - return false; + 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#createFreezeVersion(NodeRef) + * @see RecordableVersionService#createSnapshotVersion(NodeRef) */ - public Version createFreezeVersion(NodeRef nodeRef) + public void createSnapshotVersion(NodeRef nodeRef) { - Version newVersion = null; boolean autoVersion = isEnableAutoVersionOnRecordCreation(); // if the flag autoversion on record creation set, create new version on dirty nodes if (autoVersion && isCurrentVersionDirty(nodeRef)) @@ -940,8 +941,8 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl 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)); - newVersion = createVersion(nodeRef, autoVersionProperties); + createVersion(nodeRef, autoVersionProperties); } - return newVersion; + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java index 3e2d83f0f6..6010515860 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java @@ -102,9 +102,10 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** - * Given versionable content with a recorded latest version - * When I declare a version record - * Then nothing happens since the latest version is already recorded And a warning is logged + * Given versionable content with a recorded latest version + * When I declare a version record + * Then nothing happens since the latest version is already recorded + * And a warning is logged */ public void testDeclareLatestVersionAsRecordButAlreadyRecorded() { @@ -215,6 +216,98 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest * * @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 + * When I declare this version record + * Then a new minor version is created for document + * + * @see https://issues.alfresco.com/jira/browse/RM-2368 + */ public void testCreateRecordFromLatestVersion() { doBehaviourDrivenTest(new BehaviourDrivenTest(dmCollaborator) @@ -223,10 +316,8 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest private NodeRef versionedRecord; private Map versionProperties; private Date createdDate; - private Date frozenModifDate; private Date modificationDate; private String record_name = "initial_name"; - private String AUTO_VERSION_DESCRIPTION = "Auto Version on Record Creation"; private boolean autoVersion = false; public void given() throws Exception @@ -251,8 +342,6 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest // Change Type to a custom document nodeService.setType(myDocument, TYPE_CUSTOM_TYPE); - Date modificationDate1 = (Date) nodeService.getProperty(myDocument, ContentModel.PROP_MODIFIED); - assertTrue("Frozen modification date", modificationDate.getTime() == modificationDate1.getTime()); // setup version properties versionProperties = new HashMap(2); versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION); @@ -260,35 +349,17 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest // create initial version versionService.createVersion(myDocument, versionProperties); - Version version = versionService.getCurrentVersion(myDocument); - frozenModifDate = version.getFrozenModifiedDate(); - - // get autoversion flag from cofiguratie - autoVersion = recordableVersionService.isEnableAutoVersionOnRecordCreation(); } public void when() { - // current node is not dirty - assertFalse(isCurrentVersionDirty(myDocument)); - - if (autoVersion) - { - // 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); - // node should be modified - assertTrue(isCurrentVersionDirty(myDocument)); - } - else - { - assertFalse(isCurrentVersionDirty(myDocument)); - } + // 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); - + versionedRecord = recordableVersionService.createRecordFromLatestVersion(filePlan, myDocument, autoVersion); } public void then() @@ -307,45 +378,16 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest // get name of record record_name = (String) nodeService.getProperty(versionedRecord, ContentModel.PROP_NAME); - if (autoVersion) - { - // 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"); - } - else - { - // 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"); - } - } - - public boolean isCurrentVersionDirty(NodeRef nodeRef) - { - if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) - { - // get the latest version - Version currentVersion = versionService.getCurrentVersion(nodeRef); - Date modificationDate = (Date) nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED); - if (currentVersion != null) - { - // grab the frozen state - NodeRef currentFrozenState = currentVersion.getFrozenStateNodeRef(); - Date frozenModificationDate = (Date) nodeService.getProperty(currentFrozenState, ContentModel.PROP_MODIFIED); - if (modificationDate.getTime() > frozenModificationDate.getTime()) { return true; } - } - else - { - return true; - } - } - return false; + // 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"); + } + }); } + } From 3a74bc28f52e9278fa1e22de8ca49dd8139850bc Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Thu, 6 Oct 2016 13:17:48 +0300 Subject: [PATCH 6/7] fix ' And a warning is logged' --- .../test/integration/version/DeclareAsRecordVersionTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java index 3b51e4af56..6c1e212dba 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java @@ -104,7 +104,8 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest /** * Given versionable content with a recorded latest version When I declare a version record Then nothing happens * When I declare a version record - * since the latest version is already recorded And a warning is logged + * since the latest version is already recorded + * And a warning is logged */ public void testDeclareLatestVersionAsRecordButAlreadyRecorded() { From 6155c71e249fb4a99580900e70f40465d36b8bf0 Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Thu, 6 Oct 2016 13:42:10 +0300 Subject: [PATCH 7/7] Add comments to the method --- .../version/DeclareAsRecordVersionTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java index 6c1e212dba..9e0fe9ddae 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeclareAsRecordVersionTest.java @@ -102,9 +102,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** - * Given versionable content with a recorded latest version When I declare a version record Then nothing happens + * Given versionable content with a recorded latest version * When I declare a version record - * since the latest version is already recorded + * Then nothing happens since the latest version is already recorded * And a warning is logged */ public void testDeclareLatestVersionAsRecordButAlreadyRecorded() @@ -209,11 +209,12 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest } /** + * 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) @@ -299,9 +300,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest /** * - * Given versionable content with a recorded latest version - * When I declare this version record - * Then a new minor version is created for document + * 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 */