getRelationshipsFrom(NodeRef nodeRef);
-
+
/**
- * Gets all the relationships that go in to the given node reference
+ * Gets all the relationships that come out from the given node reference
+ * that match the a given name filter.
+ *
+ * Exact match only.
*
* @param nodeRef The node reference
- * @return All relationships that go in to the given node reference
+ * @param nameFilter Name filter for results
+ * @return All relationships that come out from the given node reference
+ *
+ * @since 2.3.1
+ */
+ Set getRelationshipsFrom(NodeRef nodeRef, String nameFilter);
+
+ /**
+ * Gets all the relationships that go into the given node reference
+ *
+ * @param nodeRef The node reference
+ * @return All relationships that go into the given node reference
*/
Set getRelationshipsTo(NodeRef nodeRef);
+
+ /**
+ * Gets all the relationships that go into the given node reference
+ * that match the a given name filter.
+ *
+ * Exact match only.
+ *
+ * @param nodeRef The node reference
+ * @param nameFilter Name filter for results
+ * @return All relationships that go into the given node reference
+ *
+ * @since 2.3.1
+ */
+ Set getRelationshipsTo(NodeRef nodeRef, String nameFilter);
/**
* Adds a relationship from the given node source
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java
index 92b4fa7be4..df7487e6ad 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java
@@ -376,16 +376,25 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen
*/
@Override
public Set getRelationshipsFrom(NodeRef nodeRef)
+ {
+ return getRelationshipsFrom(nodeRef, null);
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService#getRelationshipsFrom(org.alfresco.service.cmr.repository.NodeRef, String)
+ */
+ @Override
+ public Set getRelationshipsFrom(NodeRef nodeRef, String nameFilter)
{
mandatory("nodeRef", nodeRef);
Set relationships = new HashSet();
List customReferencesFrom = getNodeService().getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
- relationships.addAll(generateRelationshipFromAssociationRef(customReferencesFrom));
+ relationships.addAll(generateRelationshipFromAssociationRef(customReferencesFrom, nameFilter));
List customChildReferences = getNodeService().getChildAssocs(nodeRef);
- relationships.addAll(generateRelationshipFromParentChildAssociationRef(customChildReferences));
+ relationships.addAll(generateRelationshipFromParentChildAssociationRef(customChildReferences, nameFilter));
return relationships;
}
@@ -395,20 +404,29 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen
*/
@Override
public Set getRelationshipsTo(NodeRef nodeRef)
+ {
+ return getRelationshipsTo(nodeRef, null);
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService#getRelationshipsTo(org.alfresco.service.cmr.repository.NodeRef, String)
+ */
+ @Override
+ public Set getRelationshipsTo(NodeRef nodeRef, String nameFilter)
{
mandatory("nodeRef", nodeRef);
Set relationships = new HashSet();
List customReferencesTo = getNodeService().getSourceAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
- relationships.addAll(generateRelationshipFromAssociationRef(customReferencesTo));
+ relationships.addAll(generateRelationshipFromAssociationRef(customReferencesTo, nameFilter));
List customParentReferences = getNodeService().getParentAssocs(nodeRef);
- relationships.addAll(generateRelationshipFromParentChildAssociationRef(customParentReferences));
+ relationships.addAll(generateRelationshipFromParentChildAssociationRef(customParentReferences, nameFilter));
return relationships;
}
-
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService#addRelationship(java.lang.String, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -418,7 +436,19 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen
mandatoryString("uniqueName", uniqueName);
mandatory("source", source);
mandatory("target", target);
-
+
+ // check the source node exists
+ if (!getNodeService().exists(source))
+ {
+ throw new AlfrescoRuntimeException("Can't create relationship '" + uniqueName + "', because source node doesn't exist.");
+ }
+
+ // check the target node exists
+ if (!getNodeService().exists(target))
+ {
+ throw new AlfrescoRuntimeException("Can't create relationship " + uniqueName + ", because target node doesn't exist.");
+ }
+
if (getNodeService().hasAspect(target, ASPECT_FROZEN))
{
StringBuilder sb = new StringBuilder();
@@ -622,14 +652,15 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen
* @param associationRefs Association references
* @return Relationships generated from the given association references
*/
- private Set generateRelationshipFromAssociationRef(List associationRefs)
+ private Set generateRelationshipFromAssociationRef(List associationRefs, String nameFilter)
{
Set relationships = new HashSet();
for (AssociationRef associationRef : associationRefs)
{
String uniqueName = associationRef.getTypeQName().getLocalName();
- if (existsRelationshipDefinition(uniqueName))
+ if (existsRelationshipDefinition(uniqueName) &&
+ (nameFilter == null || uniqueName.equals(nameFilter)))
{
NodeRef from = associationRef.getSourceRef();
NodeRef to = associationRef.getTargetRef();
@@ -646,14 +677,15 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen
* @param childAssociationRefs Child association references
* @return Relationships generated from the given child association references
*/
- private Set generateRelationshipFromParentChildAssociationRef(List childAssociationRefs)
+ private Set generateRelationshipFromParentChildAssociationRef(List childAssociationRefs, String nameFilter)
{
Set relationships = new HashSet();
for (ChildAssociationRef childAssociationRef : childAssociationRefs)
{
String uniqueName = childAssociationRef.getQName().getLocalName();
- if (existsRelationshipDefinition(uniqueName))
+ if (existsRelationshipDefinition(uniqueName)&&
+ (nameFilter == null || uniqueName.equals(nameFilter)))
{
NodeRef from = childAssociationRef.getParentRef();
NodeRef to = childAssociationRef.getChildRef();
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionModel.java
index f21b28043d..180b191bfd 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionModel.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionModel.java
@@ -41,6 +41,7 @@ public interface RecordableVersionModel
QName ASPECT_RECORDED_VERSION = QName.createQName(RMV_URI, "recordedVersion");
QName PROP_RECORD_NODE_REF = QName.createQName(RMV_URI, "recordNodeRef");
QName PROP_FROZEN_OWNER = QName.createQName(RMV_URI, "frozenOwner");
+ QName PROP_DESTROYED = QName.createQName(RMV_URI, "destroyed");
/** version record aspect */
QName ASPECT_VERSION_RECORD = QName.createQName(RMV_URI, "versionRecord");
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java
index c90dc17da9..78759b8713 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java
@@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.version;
import static org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImpl.RECORD_MODEL_URIS;
import java.io.Serializable;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -181,6 +182,7 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl
/**
* @see org.alfresco.repo.version.Node2ServiceImpl#getAspects(org.alfresco.service.cmr.repository.NodeRef)
*/
+ @SuppressWarnings("unchecked")
@Override
public Set getAspects(NodeRef nodeRef) throws InvalidNodeRefException
{
@@ -190,8 +192,15 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl
if (dbNodeService.hasAspect(converted, ASPECT_RECORDED_VERSION))
{
NodeRef record = (NodeRef)dbNodeService.getProperty(converted, PROP_RECORD_NODE_REF);
- Set aspects = dbNodeService.getAspects(record);
- return processAspects(aspects);
+ if (dbNodeService.exists(record))
+ {
+ Set aspects = dbNodeService.getAspects(record);
+ return processAspects(aspects);
+ }
+ else
+ {
+ return (Set)Collections.EMPTY_SET;
+ }
}
else
{
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 e5b0c8c6f2..6687da6580 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
@@ -47,6 +47,15 @@ public interface RecordableVersionService
*/
boolean isRecordedVersion(Version version);
+ /**
+ * If the version is a recorded version, gets the related version
+ * record.
+ *
+ * @param version version
+ * @return NodeRef node reference of version record
+ */
+ NodeRef getVersionRecord(Version version);
+
/**
* Creates a record from the latest version, marking it as recorded.
*
@@ -54,8 +63,26 @@ public interface RecordableVersionService
* version is already recorded.
*
* @param nodeRef node reference
- * @return NodeRef node reference to the crated record.
+ * @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
+ */
+ 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.
+ *
+ * @param version version
+ */
+ void destroyRecordedVersion(Version version);
}
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 a148fd3016..c5d2a14408 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
@@ -76,7 +76,8 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
public static final String KEY_FILE_PLAN = "file-plan";
/** version record property */
- public static final String PROP_VERSION_RECORD = "RecordVersion";
+ protected static final String PROP_VERSION_RECORD = "RecordVersion";
+ protected static final String PROP_RECORDED_VERSION_DESTROYED = "RecordedVersionDestroyed";
/** version aspect property names */
private static final String[] VERSION_PROPERTY_NAMES = new String[]
@@ -491,7 +492,8 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
{
// look for the associated record
final NodeRef previousRecord = (NodeRef)previousVersion.getVersionProperties().get(PROP_VERSION_RECORD);
- if (previousRecord != null)
+ if (previousRecord != null &&
+ nodeService.exists(previousRecord))
{
versionRecord = previousRecord;
break;
@@ -502,6 +504,66 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
return versionRecord;
}
+ @Override
+ protected VersionHistory buildVersionHistory(NodeRef versionHistoryRef, NodeRef nodeRef)
+ {
+ VersionHistory versionHistory = super.buildVersionHistory(versionHistoryRef, nodeRef);
+
+ // create an empty version history if appropriate
+ if (versionHistoryRef != null &&
+ nodeRef != null &&
+ versionHistory == null &&
+ getAllVersions(versionHistoryRef).isEmpty() == true)
+ {
+ versionHistory = new EmptyVersionHistory();
+ }
+
+ return versionHistory;
+ }
+
+ public class EmptyVersionHistory implements VersionHistory
+ {
+ private static final long serialVersionUID = 3449832161314670033L;
+
+ @Override
+ public Version getRootVersion()
+ {
+ return null;
+ }
+
+ @Override
+ public Version getHeadVersion()
+ {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection getAllVersions()
+ {
+ return (Collection)Collections.EMPTY_LIST;
+ }
+
+ @Override
+ public Version getPredecessor(Version version)
+ {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection getSuccessors(Version version)
+ {
+ return (Collection)Collections.EMPTY_LIST;
+ }
+
+ @Override
+ public Version getVersion(String versionLabel)
+ {
+ return null;
+ }
+ }
+
/**
* Freezes audit aspect properties.
*
@@ -533,12 +595,18 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
{
Version version = super.getVersion(versionRef);
+ // place the version record reference in the version properties
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);
+ if (destroyed == null) { destroyed = Boolean.FALSE; }
+ version.getVersionProperties().put(PROP_RECORDED_VERSION_DESTROYED, destroyed);
+
return version;
}
@@ -579,10 +647,31 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
@Override
public boolean isRecordedVersion(Version version)
{
- boolean result = true;
- if (version.getVersionProperties().get(PROP_VERSION_RECORD) == null)
+ 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)
+ */
+ @Override
+ public NodeRef getVersionRecord(Version version)
+ {
+ NodeRef result = null;
+ NodeRef versionNodeRef = getVersionNodeRef(version);
+ if (dbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
{
- result = false;
+ // get the version record
+ result = (NodeRef)dbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF);
+
+ // check that the version record exists
+ if (result != null &&
+ !dbNodeService.exists(result))
+ {
+ throw new AlfrescoRuntimeException("Version record node doesn't exist. Indicates version has not been updated "
+ + "when associated version record was deleted. "
+ + "(nodeRef=" + result.toString() + ")");
+ }
}
return result;
}
@@ -737,6 +826,47 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl
return record;
}
+ /**
+ * @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);
+
+ // get the destroyed property value
+ 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)
+ */
+ @Override
+ public void destroyRecordedVersion(Version version)
+ {
+ // 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);
+ }
+ }
+
/**
* Helper method to get the version number of a given version by inspecting the
* name of the parent association.
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersionsTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersionsTest.java
index c7b1e08f4c..b8a2ed6e94 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersionsTest.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersionsTest.java
@@ -169,7 +169,7 @@ public class AdHocRecordableVersionsTest extends RecordableVersionsBaseTest
public Void doWork() throws Exception
{
// add custom meta-data to record
- NodeRef record = (NodeRef)version.getVersionProperties().get(RecordableVersionServiceImpl.PROP_VERSION_RECORD);
+ NodeRef record = recordableVersionService.getVersionRecord(version);
assertNotNull(record);
recordService.addRecordType(record, TestModel.ASPECT_RECORD_METADATA);
nodeService.setProperty(record, TestModel.PROPERTY_RECORD_METADATA, "Peter Wetherall");
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AutoRecordableVersionsTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AutoRecordableVersionsTest.java
index a9e4d678a3..81a49f3652 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AutoRecordableVersionsTest.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AutoRecordableVersionsTest.java
@@ -24,7 +24,6 @@ import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.relationship.Relationship;
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy;
-import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.version.Version;
@@ -131,7 +130,7 @@ public class AutoRecordableVersionsTest extends RecordableVersionsBaseTest
checkRecordedVersion(dmDocument, null, "0.3");
Version version = versionService.getCurrentVersion(dmDocument);
- NodeRef record = (NodeRef)version.getVersionProperties().get(RecordableVersionServiceImpl.PROP_VERSION_RECORD);
+ NodeRef record = recordableVersionService.getVersionRecord(version);
boolean foundPrevious = false;
Set relationships = relationshipService.getRelationshipsFrom(record);
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeleteRecordVersionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeleteRecordVersionTest.java
new file mode 100644
index 0000000000..9a7e62a22a
--- /dev/null
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/DeleteRecordVersionTest.java
@@ -0,0 +1,400 @@
+/*
+ * 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.module.org_alfresco_module_rm.test.integration.version;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.relationship.Relationship;
+import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService;
+import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
+import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy;
+import org.alfresco.repo.content.MimetypeMap;
+import org.alfresco.service.cmr.repository.ContentWriter;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.version.Version;
+import org.alfresco.service.cmr.version.VersionHistory;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.GUID;
+
+
+/**
+ * Recordable version history integration tests.
+ *
+ * @author Roy Wetherall
+ * @since 2.3.1
+ */
+public class DeleteRecordVersionTest extends RecordableVersionsBaseTest
+{
+ /**
+ * Given that a document is created
+ * And the initial version is record
+ * When I delete the version record
+ * Then the version is deleted
+ * And the version history is not deleted
+ *
+ * @see https://issues.alfresco.com/jira/browse/RM-2562
+ */
+ public void testDeleteFirstRecordedVersion()
+ {
+ doBehaviourDrivenTest(new BehaviourDrivenTest()
+ {
+ private NodeRef myDocument;
+
+ public void given() throws Exception
+ {
+ // create a document
+ myDocument = fileFolderService.create(dmFolder, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
+
+ // make versionable
+ Map props = new HashMap(2);
+ props.put(RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY, RecordableVersionPolicy.ALL);
+ props.put(RecordableVersionModel.PROP_FILE_PLAN, filePlan);
+ nodeService.addAspect(myDocument, RecordableVersionModel.ASPECT_VERSIONABLE, props);
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_VERSIONABLE, null);
+ }
+
+ public void when()
+ {
+ // check the initial version label
+ assertEquals("1.0", nodeService.getProperty(myDocument, ContentModel.PROP_VERSION_LABEL));
+
+ // check that the version history contains a single version that is recorded
+ VersionHistory versionHistory = versionService.getVersionHistory(myDocument);
+ assertNotNull(versionHistory);
+ assertEquals(1, versionHistory.getAllVersions().size());
+
+ // check the recorded version is not marked as destroyed
+ Version version = versionHistory.getHeadVersion();
+ assertNotNull(version);
+ assertFalse(recordableVersionService.isRecordedVersionDestroyed(version));
+
+ Version head = versionHistory.getHeadVersion();
+ NodeRef record = recordableVersionService.getVersionRecord(head);
+ assertTrue(recordService.isRecord(record));
+
+ // record should not have a version history because it is immutable
+ assertFalse(nodeService.hasAspect(record, ContentModel.ASPECT_VERSIONABLE));
+ VersionHistory recordVersionHistory = versionService.getVersionHistory(record);
+ assertNull(recordVersionHistory);
+
+ // destroy record
+ nodeService.deleteNode(record);
+ }
+
+ public void then()
+ {
+ // document is still versionable
+ assertTrue(nodeService.hasAspect(myDocument, ContentModel.ASPECT_VERSIONABLE));
+
+ // check the initial version label
+ assertEquals("1.0", nodeService.getProperty(myDocument, ContentModel.PROP_VERSION_LABEL));
+
+ // still has a version history, but the version is marked as destroyed
+ VersionHistory versionHistory = versionService.getVersionHistory(myDocument);
+ assertNotNull(versionHistory);
+ assertEquals(1, versionHistory.getAllVersions().size());
+
+ // check the recorded version is marked as destroyed and the record version is not longer available
+ Version version = versionHistory.getHeadVersion();
+ assertNotNull(version);
+ assertTrue(recordableVersionService.isRecordedVersionDestroyed(version));
+ assertNull(recordableVersionService.getVersionRecord(version));
+ }
+ });
+ }
+
+ /**
+ * Given that a document is created
+ * And the initial version is record
+ * And the associated version record is deleted
+ * When a new version is created
+ * Then a new associated version record is created
+ * And the version is 1.1 (not 1.0 since this was deleted, but the version history maintained)
+ *
+ * @see https://issues.alfresco.com/jira/browse/RM-2562
+ */
+ public void testDeleteFirstRecordedVersionAndCreateNewVersion()
+ {
+ doBehaviourDrivenTest(new BehaviourDrivenTest()
+ {
+ private NodeRef myDocument;
+
+ public void given() throws Exception
+ {
+ // create a document
+ myDocument = fileFolderService.create(dmFolder, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
+ ContentWriter writer = fileFolderService.getWriter(myDocument);
+ writer.setEncoding("UTF-8");
+ writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+ writer.putContent(GUID.generate());
+
+ // make versionable
+ Map props = new HashMap(2);
+ props.put(RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY, RecordableVersionPolicy.ALL);
+ props.put(RecordableVersionModel.PROP_FILE_PLAN, filePlan);
+ nodeService.addAspect(myDocument, RecordableVersionModel.ASPECT_VERSIONABLE, props);
+ nodeService.addAspect(myDocument, ContentModel.ASPECT_VERSIONABLE, null);
+ }
+
+ public void when()
+ {
+ // get the created version record
+ VersionHistory versionHistory = versionService.getVersionHistory(myDocument);
+ Version head = versionHistory.getHeadVersion();
+ NodeRef record = recordableVersionService.getVersionRecord(head);
+
+ // destroy record
+ nodeService.deleteNode(record);
+
+ // update the content to create a new version (and version record)
+ ContentWriter writer = fileFolderService.getWriter(myDocument);
+ writer.putContent(GUID.generate());
+ }
+
+ public void then()
+ {
+ // document is still versionable
+ assertTrue(nodeService.hasAspect(myDocument, ContentModel.ASPECT_VERSIONABLE));
+
+ // check the version number has been incremented
+ assertEquals("1.1", nodeService.getProperty(myDocument, ContentModel.PROP_VERSION_LABEL));
+
+ // still has a version history, with 2 enties
+ VersionHistory versionHistory = versionService.getVersionHistory(myDocument);
+ assertNotNull(versionHistory);
+ assertEquals(2, versionHistory.getAllVersions().size());
+
+ // latest version is current
+ Version head = versionHistory.getHeadVersion();
+ assertFalse(recordableVersionService.isRecordedVersionDestroyed(head));
+ assertNotNull(recordableVersionService.getVersionRecord(head));
+
+ // first version is destroyed
+ Version destroyed = versionHistory.getPredecessor(head);
+ assertTrue(recordableVersionService.isRecordedVersionDestroyed(destroyed));
+ assertNull(recordableVersionService.getVersionRecord(destroyed));
+
+ // get the version record for the current version
+ NodeRef versionRecord = recordableVersionService.getVersionRecord(head);
+ assertNotNull(versionRecord);
+ assertTrue(nodeService.exists(versionRecord));
+
+ Set from = relationshipService.getRelationshipsFrom(versionRecord);
+ assertTrue(from.isEmpty());
+
+ Set to = relationshipService.getRelationshipsTo(versionRecord);
+ assertTrue(to.isEmpty());
+ }
+ });
+ }
+
+ /**
+ * Given a chain of version records (1.0, 1.1, 1.2) which are all related
+ * When I delete version record 1.0
+ * Then 1.1 is the oldest version
+ */
+ public void testDeleteOldestVersion()
+ {
+ final NodeRef myDocument = createDocumentWithRecordVersions();
+
+ doBehaviourDrivenTest(new BehaviourDrivenTest()
+ {
+ private VersionHistory versionHistory;
+
+ public void given() throws Exception
+ {
+ // get version history
+ versionHistory = versionService.getVersionHistory(myDocument);
+ }
+
+ public void when()
+ {
+ Version version10 = versionHistory.getVersion("1.0");
+ NodeRef recordVersion10 = recordableVersionService.getVersionRecord(version10);
+
+ // delete record version 1.0
+ nodeService.deleteNode(recordVersion10);
+ }
+
+ public void then()
+ {
+ // check the deleted version
+ Version version10 = versionHistory.getVersion("1.0");
+ assertNotNull(version10);
+ assertTrue(recordableVersionService.isRecordedVersionDestroyed(version10));
+ NodeRef recordVersion10 = recordableVersionService.getVersionRecord(version10);
+ assertNull(recordVersion10);
+
+ // verify 1.2 setup as expected
+ Version version12 = versionHistory.getHeadVersion();
+ assertEquals("1.2", version12.getVersionLabel());
+ NodeRef recordVersion12 = recordableVersionService.getVersionRecord(version12);
+ assertNotNull(recordVersion12);
+
+ assertTrue(relationshipService.getRelationshipsTo(recordVersion12, RelationshipService.RELATIONSHIP_VERSIONS).isEmpty());
+
+ Set from12 = relationshipService.getRelationshipsFrom(recordVersion12, RelationshipService.RELATIONSHIP_VERSIONS);
+ assertEquals(1, from12.size());
+
+ // verify 1.1 setup as expected
+ Version version11 = versionHistory.getPredecessor(version12);
+ assertEquals("1.1", version11.getVersionLabel());
+ NodeRef recordVersion11 = recordableVersionService.getVersionRecord(version11);
+ assertNotNull(recordVersion11);
+
+ Set to11 = relationshipService.getRelationshipsTo(recordVersion11, RelationshipService.RELATIONSHIP_VERSIONS);
+ assertEquals(1, to11.size());
+ assertEquals(recordVersion12, to11.iterator().next().getSource());
+
+ assertTrue(relationshipService.getRelationshipsFrom(recordVersion11, RelationshipService.RELATIONSHIP_VERSIONS).isEmpty());
+ }
+ });
+ }
+
+ /**
+ * Given a chain of version records (1.0, 1.1, 1.2) which are all related
+ * When I delete version record 1.1
+ * Then 1.2 now 'versions' 1.0
+ */
+ public void testDeleteMiddleVersion()
+ {
+ final NodeRef myDocument = createDocumentWithRecordVersions();
+
+ doBehaviourDrivenTest(new BehaviourDrivenTest()
+ {
+ private VersionHistory versionHistory;
+
+ public void given() throws Exception
+ {
+ // get version history
+ versionHistory = versionService.getVersionHistory(myDocument);
+ }
+
+ public void when()
+ {
+ Version version11 = versionHistory.getVersion("1.1");
+ NodeRef recordVersion11 = recordableVersionService.getVersionRecord(version11);
+
+ // delete record version 1.1
+ nodeService.deleteNode(recordVersion11);
+ }
+
+ public void then()
+ {
+ // check the deleted version
+ Version version11 = versionHistory.getVersion("1.1");
+ assertNotNull(version11);
+ assertTrue(recordableVersionService.isRecordedVersionDestroyed(version11));
+ NodeRef recordVersion11 = recordableVersionService.getVersionRecord(version11);
+ assertNull(recordVersion11);
+
+ // verify 1.2 setup as expected
+ Version version12 = versionHistory.getHeadVersion();
+ assertEquals("1.2", version12.getVersionLabel());
+ NodeRef recordVersion12 = recordableVersionService.getVersionRecord(version12);
+ assertNotNull(recordVersion12);
+
+ assertTrue(relationshipService.getRelationshipsTo(recordVersion12, RelationshipService.RELATIONSHIP_VERSIONS).isEmpty());
+
+ Set from12 = relationshipService.getRelationshipsFrom(recordVersion12, RelationshipService.RELATIONSHIP_VERSIONS);
+ assertEquals(1, from12.size());
+
+ // verify 1.0 setup as expected
+ Version version10 = versionHistory.getVersion("1.0");
+ assertEquals("1.0", version10.getVersionLabel());
+ NodeRef recordVersion10 = recordableVersionService.getVersionRecord(version10);
+ assertNotNull(recordVersion10);
+
+ Set to10 = relationshipService.getRelationshipsTo(recordVersion10, RelationshipService.RELATIONSHIP_VERSIONS);
+ assertEquals(1, to10.size());
+ assertEquals(recordVersion12, to10.iterator().next().getSource());
+
+ assertTrue(relationshipService.getRelationshipsFrom(recordVersion10, RelationshipService.RELATIONSHIP_VERSIONS).isEmpty());
+
+ }
+ });
+ }
+
+ /**
+ * Given a chain of version records (1.0, 1.1, 1.2) which are all related
+ * When I delete version record 1.2
+ * Then 1.1 is the most recent version
+ */
+ public void testDeleteLatestVersion()
+ {
+ final NodeRef myDocument = createDocumentWithRecordVersions();
+
+ doBehaviourDrivenTest(new BehaviourDrivenTest()
+ {
+ private VersionHistory versionHistory;
+
+ public void given() throws Exception
+ {
+ // get version history
+ versionHistory = versionService.getVersionHistory(myDocument);
+ }
+
+ public void when()
+ {
+ Version version10 = versionHistory.getVersion("1.0");
+ NodeRef recordVersion10 = recordableVersionService.getVersionRecord(version10);
+
+ // delete record version 1.0
+ nodeService.deleteNode(recordVersion10);
+ }
+
+ public void then()
+ {
+ // check the deleted version
+ Version version10 = versionHistory.getVersion("1.0");
+ assertNotNull(version10);
+ assertTrue(recordableVersionService.isRecordedVersionDestroyed(version10));
+ NodeRef recordVersion10 = recordableVersionService.getVersionRecord(version10);
+ assertNull(recordVersion10);
+
+ // verify 1.2 setup as expected
+ Version version12 = versionHistory.getHeadVersion();
+ assertEquals("1.2", version12.getVersionLabel());
+ NodeRef recordVersion12 = recordableVersionService.getVersionRecord(version12);
+ assertNotNull(recordVersion12);
+
+ assertTrue(relationshipService.getRelationshipsTo(recordVersion12, RelationshipService.RELATIONSHIP_VERSIONS).isEmpty());
+
+ Set from12 = relationshipService.getRelationshipsFrom(recordVersion12, RelationshipService.RELATIONSHIP_VERSIONS);
+ assertEquals(1, from12.size());
+
+ // verify 1.1 setup as expected
+ Version version11 = versionHistory.getPredecessor(version12);
+ assertEquals("1.1", version11.getVersionLabel());
+ NodeRef recordVersion11 = recordableVersionService.getVersionRecord(version11);
+ assertNotNull(recordVersion11);
+
+ Set to11 = relationshipService.getRelationshipsTo(recordVersion11, RelationshipService.RELATIONSHIP_VERSIONS);
+ assertEquals(1, to11.size());
+ assertEquals(recordVersion12, to11.iterator().next().getSource());
+
+ assertTrue(relationshipService.getRelationshipsFrom(recordVersion11, RelationshipService.RELATIONSHIP_VERSIONS).isEmpty());
+ }
+ });
+ }
+}
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/RecordableVersionsBaseTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/RecordableVersionsBaseTest.java
index 2e2679884c..32f1269bf3 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/RecordableVersionsBaseTest.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/RecordableVersionsBaseTest.java
@@ -19,15 +19,18 @@
package org.alfresco.module.org_alfresco_module_rm.test.integration.version;
import java.io.Serializable;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.relationship.Relationship;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
-import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl;
+import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy;
+import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -35,9 +38,12 @@ import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionHistory;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
+import org.alfresco.util.GUID;
import org.alfresco.util.PropertyMap;
/**
+ * Recordable versions base integration test
+ *
* @author Roy Wetherall
* @since 2.3
*/
@@ -54,7 +60,16 @@ public abstract class RecordableVersionsBaseTest extends BaseRMTestCase implemen
protected static final String CONTENT =
"Simple + Smart. A smarter way to build, a smarter way to deploy. Its simple because we focus on the end "
+ "user and smart because we support more open standards than any other ECM platform, while delivering all "
- + "the value a traditional platform provides.";
+ + "the value a traditional platform provides.";
+
+ protected RecordableVersionService recordableVersionService;
+
+ @Override
+ protected void initServices()
+ {
+ super.initServices();
+ recordableVersionService = (RecordableVersionService)applicationContext.getBean("RecordableVersionService");
+ }
/**
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isCollaborationSiteTest()
@@ -150,7 +165,7 @@ public abstract class RecordableVersionsBaseTest extends BaseRMTestCase implemen
checkAspects(frozen, beforeAspects);
// record version node reference is available on version
- NodeRef record = (NodeRef)version.getVersionProperties().get(RecordableVersionServiceImpl.PROP_VERSION_RECORD);
+ NodeRef record = recordableVersionService.getVersionRecord(version);
assertNotNull(record);
// check that the version record information has been added
@@ -191,7 +206,7 @@ public abstract class RecordableVersionsBaseTest extends BaseRMTestCase implemen
assertEquals(versionLabel, version.getVersionLabel());
// record version node reference is available on version
- NodeRef record = (NodeRef)version.getVersionProperties().get(RecordableVersionServiceImpl.PROP_VERSION_RECORD);
+ NodeRef record = recordableVersionService.getVersionRecord(version);
assertNull(record);
// check the version history
@@ -267,5 +282,121 @@ public abstract class RecordableVersionsBaseTest extends BaseRMTestCase implemen
fail("Aspects in the frozen state, but not in origional. " + frozenAspects.toString());
}
}
+
+ /**
+ * Creates a document with three versions (1.0, 1.1, 1.2) all of which
+ * are recorded.
+ *
+ * @return NodeRef node reference
+ */
+ protected NodeRef createDocumentWithRecordVersions()
+ {
+ // create document and initial version (1.0)
+ final NodeRef myDocument = doTestInTransaction(new Test()
+ {
+ @Override
+ public NodeRef run() throws Exception
+ {
+ // create a document
+ NodeRef testDoc = fileFolderService.create(dmFolder, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
+ ContentWriter writer = fileFolderService.getWriter(testDoc);
+ writer.setEncoding("UTF-8");
+ writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+ writer.putContent(GUID.generate());
+
+ // make versionable
+ Map props = new HashMap(2);
+ props.put(RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY, RecordableVersionPolicy.ALL);
+ props.put(RecordableVersionModel.PROP_FILE_PLAN, filePlan);
+ nodeService.addAspect(testDoc, RecordableVersionModel.ASPECT_VERSIONABLE, props);
+ nodeService.addAspect(testDoc, ContentModel.ASPECT_VERSIONABLE, null);
+
+ return testDoc;
+ }
+ });
+
+ // create 1.1
+ doTestInTransaction(new Test()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ // update content
+ ContentWriter writer = fileFolderService.getWriter(myDocument);
+ writer.putContent(GUID.generate());
+
+ return null;
+ }
+ });
+
+ // create 1.2
+ doTestInTransaction(new Test()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ // update content
+ ContentWriter writer = fileFolderService.getWriter(myDocument);
+ writer.putContent(GUID.generate());
+
+ return null;
+ }
+ });
+
+ // we do these checks to ensure that the test data is in the correct state before we
+ // start to manipulate the versions and execute tests
+ doTestInTransaction(new Test()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ // verify that the version history looks as expected
+ VersionHistory versionHistory = versionService.getVersionHistory(myDocument);
+ assertNotNull(versionHistory);
+ Collection versions = versionHistory.getAllVersions();
+ assertEquals(3, versions.size());
+
+ // verify 1.2 setup as expected
+ Version version12 = versionHistory.getHeadVersion();
+ assertEquals("1.2", version12.getVersionLabel());
+ NodeRef recordVersion12 = recordableVersionService.getVersionRecord(version12);
+ assertNotNull(recordVersion12);
+
+ assertTrue(relationshipService.getRelationshipsTo(recordVersion12, "versions").isEmpty());
+
+ Set from12 = relationshipService.getRelationshipsFrom(recordVersion12, "versions");
+ assertEquals(1, from12.size());
+
+ // verify 1.1 setup as expected
+ Version version11 = versionHistory.getPredecessor(version12);
+ assertEquals("1.1", version11.getVersionLabel());
+ NodeRef recordVersion11 = recordableVersionService.getVersionRecord(version11);
+ assertNotNull(recordVersion11);
+
+ Set to11 = relationshipService.getRelationshipsTo(recordVersion11, "versions");
+ assertEquals(1, to11.size());
+ assertEquals(recordVersion12, to11.iterator().next().getSource());
+
+ Set from11 = relationshipService.getRelationshipsFrom(recordVersion11, "versions");
+ assertEquals(1, from11.size());
+
+ // verify 1.0 setup as expected
+ Version version10 = versionHistory.getPredecessor(version11);
+ assertEquals("1.0", version10.getVersionLabel());
+ NodeRef recordVersion10 = recordableVersionService.getVersionRecord(version10);
+ assertNotNull(recordVersion10);
+
+ Set to10 = relationshipService.getRelationshipsTo(recordVersion10, "versions");
+ assertEquals(1, to10.size());
+ assertEquals(recordVersion11, to10.iterator().next().getSource());
+
+ assertTrue(relationshipService.getRelationshipsFrom(recordVersion10, "versions").isEmpty());
+
+ return null;
+ }
+ });
+
+ return myDocument;
+ }
}
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/VersionTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/VersionTestSuite.java
index 1b970e0134..4cf00fec8a 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/VersionTestSuite.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/VersionTestSuite.java
@@ -34,7 +34,8 @@ import org.junit.runners.Suite.SuiteClasses;
AdHocRecordableVersionsTest.class,
AutoRecordableVersionsTest.class,
DeclareAsRecordVersionTest.class,
- AutoVersionTest.class
+ AutoVersionTest.class,
+ DeleteRecordVersionTest.class
})
public class VersionTestSuite
{
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/VersionRecordAspectUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/VersionRecordAspectUnitTest.java
new file mode 100644
index 0000000000..02011c9d9a
--- /dev/null
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/VersionRecordAspectUnitTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2005-2015 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.module.org_alfresco_module_rm.model.rma.aspect;
+
+import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel.PROP_VERSIONED_NODEREF;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService;
+import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
+import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.version.Version;
+import org.alfresco.service.cmr.version.VersionHistory;
+import org.alfresco.service.cmr.version.VersionService;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+/**
+ * Version record aspect unit tests
+ *
+ * @author Roy Wetherall
+ * @since 2.3.1
+ */
+public class VersionRecordAspectUnitTest extends BaseUnitTest
+{
+ /** service mocks */
+ private @Mock VersionHistory mockedVersionHistory;
+ private @Mock Version mockedVersion;
+ private @Mock VersionService mockedVersionService;
+ private @Mock RelationshipService mockedRelationshipService;
+
+ /** test object */
+ private @InjectMocks VersionRecordAspect versionRecordAspect;
+
+ /**
+ * given that version node ref is null
+ * before delete of record
+ * then nothing happens
+ */
+ @Test
+ public void beforeDeleteNoVersionNodeRef()
+ {
+ NodeRef nodeRef = generateNodeRef();
+
+ when(mockedNodeService.getProperty(nodeRef, PROP_VERSIONED_NODEREF))
+ .thenReturn(null);
+
+ versionRecordAspect.beforeDeleteNode(nodeRef);
+
+ verify(mockedNodeService, never()).getProperty(nodeRef, RecordableVersionModel.PROP_VERSION_LABEL);
+ verify(mockedRecordableVersionService, never()).destroyRecordedVersion(any(Version.class));
+ }
+
+ /**
+ * given that version node ref is not null
+ * and version label is null
+ * before delete of record
+ * then nothing happens
+ */
+ @Test
+ public void beforeDeleteNoVersionLabel()
+ {
+ NodeRef nodeRef = generateNodeRef();
+ NodeRef versionedNodeRef = generateNodeRef();
+
+ when(mockedNodeService.getProperty(nodeRef, PROP_VERSIONED_NODEREF))
+ .thenReturn(versionedNodeRef);
+ when(mockedNodeService.getProperty(nodeRef, RecordableVersionModel.PROP_VERSION_LABEL))
+ .thenReturn(null);
+
+ versionRecordAspect.beforeDeleteNode(nodeRef);
+
+ verify(mockedVersionService, never()).getVersionHistory(versionedNodeRef);
+ verify(mockedRecordableVersionService, never()).destroyRecordedVersion(any(Version.class));
+ }
+
+ /**
+ * given that version node ref is not null
+ * and version label is not null
+ * and version history is null
+ * before delete of record
+ * then nothing happens
+ */
+ @Test
+ public void beforeDeleteNoVersionHistory()
+ {
+ NodeRef nodeRef = generateNodeRef();
+ NodeRef versionedNodeRef = generateNodeRef();
+
+ when(mockedNodeService.getProperty(nodeRef, PROP_VERSIONED_NODEREF))
+ .thenReturn(versionedNodeRef);
+ when(mockedNodeService.getProperty(nodeRef, RecordableVersionModel.PROP_VERSION_LABEL))
+ .thenReturn(generateText());
+ when(mockedVersionService.getVersionHistory(versionedNodeRef))
+ .thenReturn(null);
+
+ versionRecordAspect.beforeDeleteNode(nodeRef);
+
+ verify(mockedRecordableVersionService, never()).destroyRecordedVersion(any(Version.class));
+ }
+
+ /**
+ * given that version node ref is not null
+ * and version label is not null
+ * and version history is not null
+ * and the version relating to the version label is null
+ * before delete of record
+ * then nothing happens
+ */
+ @Test
+ public void beforeDeleteNoVersionForLabel()
+ {
+ NodeRef nodeRef = generateNodeRef();
+ NodeRef versionedNodeRef = generateNodeRef();
+ String versionLabel = generateText();
+
+ when(mockedNodeService.getProperty(nodeRef, PROP_VERSIONED_NODEREF))
+ .thenReturn(versionedNodeRef);
+ when(mockedNodeService.getProperty(nodeRef, RecordableVersionModel.PROP_VERSION_LABEL))
+ .thenReturn(versionLabel);
+ when(mockedVersionService.getVersionHistory(versionedNodeRef))
+ .thenReturn(mockedVersionHistory);
+ when(mockedVersionHistory.getVersion(versionLabel))
+ .thenReturn(null);
+
+ versionRecordAspect.beforeDeleteNode(nodeRef);
+
+ verify(mockedRecordableVersionService, never()).destroyRecordedVersion(any(Version.class));
+ }
+
+ /**
+ * given that version node ref is not null
+ * and version label is not null
+ * and version history is not null
+ * and the version relating to the version label is not null
+ * before delete of record
+ * then the version is marked as destroyed
+ */
+ @Test
+ public void beforeDeleteMarkVersionDestroyed()
+ {
+ NodeRef nodeRef = generateNodeRef();
+ NodeRef versionedNodeRef = generateNodeRef();
+ String versionLabel = generateText();
+
+ when(mockedNodeService.getProperty(nodeRef, PROP_VERSIONED_NODEREF))
+ .thenReturn(versionedNodeRef);
+ when(mockedNodeService.getProperty(nodeRef, RecordableVersionModel.PROP_VERSION_LABEL))
+ .thenReturn(versionLabel);
+ when(mockedVersionService.getVersionHistory(versionedNodeRef))
+ .thenReturn(mockedVersionHistory);
+ when(mockedVersionHistory.getVersion(versionLabel))
+ .thenReturn(mockedVersion);
+
+ versionRecordAspect.beforeDeleteNode(nodeRef);
+
+ verify(mockedRecordableVersionService).destroyRecordedVersion(mockedVersion);
+ }
+}
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java
index bd622f09f3..ff73cacd40 100644
--- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java
@@ -18,33 +18,9 @@
*/
package org.alfresco.module.org_alfresco_module_rm.test;
-import org.alfresco.module.org_alfresco_module_rm.action.dm.DeclareAsVersionRecordActionUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.action.impl.FileReportActionUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.action.impl.UnlinkFromActionUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.bootstrap.BootstrapImporterModuleComponentUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.bootstrap.RecordContributorsGroupBootstrapComponentUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoterUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.CapabilityDeclarativeConditionSuite;
-import org.alfresco.module.org_alfresco_module_rm.capability.impl.EditNonRecordsMetadataCapabilityUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.forms.RecordsManagementTypeFormFilterUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImplUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.job.DispositionLifecycleJobExecuterUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.jscript.app.evaluator.FrozenEvaluatorUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.jscript.app.evaluator.TransferEvaluatorUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.model.compatibility.DictionaryBootstrapPostProcessorUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.patch.v22.PatchV22Suite;
-import org.alfresco.module.org_alfresco_module_rm.record.RecordMetadataBootstrapUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImplUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.recorded.version.config.RecordedVersionConfigGetTest;
-import org.alfresco.module.org_alfresco_module_rm.recorded.version.config.RecordedVersionConfigPostTest;
-import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPostUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPutUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldsGetUnitTest;
-import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImplUnitTest;
-import org.alfresco.repo.action.parameter.DateParameterProcessorUnitTest;
+import org.junit.extensions.cpsuite.ClasspathSuite;
+import org.junit.extensions.cpsuite.ClasspathSuite.ClassnameFilters;
import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
/**
* All unit test suite.
@@ -52,51 +28,12 @@ import org.junit.runners.Suite.SuiteClasses;
* @author Roy Wetherall
* @since 2.2
*/
-@RunWith(Suite.class)
-@SuiteClasses(
-{
- RecordMetadataBootstrapUnitTest.class,
- RecordsManagementTypeFormFilterUnitTest.class,
- DispositionLifecycleJobExecuterUnitTest.class,
- DictionaryBootstrapPostProcessorUnitTest.class,
- DateParameterProcessorUnitTest.class,
- RMEntryVoterUnitTest.class,
-
- // services
- RecordServiceImplUnitTest.class,
- HoldServiceImplUnitTest.class,
- // FilePlanPermissionServiceImplUnitTest.class, // removed because test unreliable on Bamboo
- RecordableVersionServiceImplUnitTest.class,
-
- // evaluators
- TransferEvaluatorUnitTest.class,
- FrozenEvaluatorUnitTest.class,
-
- // capabilities
- EditNonRecordsMetadataCapabilityUnitTest.class,
-
- // web scripts
- HoldsGetUnitTest.class,
- HoldPostUnitTest.class,
- HoldPutUnitTest.class,
-
- // action implementations
- FileReportActionUnitTest.class,
- UnlinkFromActionUnitTest.class,
- DeclareAsVersionRecordActionUnitTest.class,
-
- // recorded version config
- RecordedVersionConfigGetTest.class,
- RecordedVersionConfigPostTest.class,
-
- // bootstrap
- BootstrapImporterModuleComponentUnitTest.class,
- RecordContributorsGroupBootstrapComponentUnitTest.class,
-
- // suites by package
- CapabilityDeclarativeConditionSuite.class,
- PatchV22Suite.class
-
+@RunWith(ClasspathSuite.class)
+@ClassnameFilters({
+ // Execute all test classes ending with "UnitTest"
+ ".*UnitTest",
+ // Put the test classes you want to exclude here
+ "!.*FilePlanPermissionServiceImplUnitTest"
})
public class AllUnitTestSuite
{
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java
index 21d590dd27..19dd235cae 100644
--- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2014 Alfresco Software Limited.
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,8 @@
*/
package org.alfresco.module.org_alfresco_module_rm.version;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.anyString;
@@ -27,6 +29,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import java.io.Serializable;
import java.util.Collections;
@@ -419,9 +422,16 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
{
// latest version is already recorded
Version mockedVersion = mock(VersionImpl.class);
- doReturn(Collections.singletonMap(RecordableVersionServiceImpl.PROP_VERSION_RECORD, generateNodeRef())).when(mockedVersion).getVersionProperties();
- doReturn(true).when(mockedNodeService).hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE);
- doReturn(mockedVersion).when(recordableVersionService).getCurrentVersion(nodeRef);
+ NodeRef versionNodeRef = generateNodeRef();
+ when(mockedVersion.getFrozenStateNodeRef())
+ .thenReturn(versionNodeRef);
+
+ when(mockedNodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
+ .thenReturn(true);
+ when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
+ .thenReturn(true);
+ doReturn(mockedVersion)
+ .when(recordableVersionService).getCurrentVersion(nodeRef);
// create record from version
recordableVersionService.createRecordFromLatestVersion(filePlan, nodeRef);
@@ -495,4 +505,157 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
RecordableVersionModel.ASPECT_RECORDED_VERSION,
Collections.singletonMap(RecordableVersionModel.PROP_RECORD_NODE_REF, (Serializable)newRecordNodeRef));
}
+
+
+ /**
+ * given the destroyed prop isn't set
+ * when I ask if the version is destroyed
+ * then the result is false
+ */
+ @Test
+ public void propNotSetVersionNotDestroyed()
+ {
+ // set up version
+ Version mockedVersion = mock(VersionImpl.class);
+ NodeRef versionNodeRef = generateNodeRef();
+ when(mockedVersion.getFrozenStateNodeRef())
+ .thenReturn(versionNodeRef);
+
+ // set prop not set
+ when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_DESTROYED))
+ .thenReturn(null);
+
+ // is version destroyed
+ assertFalse(recordableVersionService.isRecordedVersionDestroyed(mockedVersion));
+ }
+
+ /**
+ * given the destroyed prop is set
+ * when I ask if the version is destroyed
+ * then the result matches the value set in the destroy property
+ */
+ @Test
+ public void propSetVersionDestroyed()
+ {
+ // set up version
+ Version mockedVersion = mock(VersionImpl.class);
+ NodeRef versionNodeRef = generateNodeRef();
+ when(mockedVersion.getFrozenStateNodeRef())
+ .thenReturn(versionNodeRef);
+
+ // set prop
+ when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_DESTROYED))
+ .thenReturn(Boolean.TRUE);
+
+ // is version destroyed
+ assertTrue(recordableVersionService.isRecordedVersionDestroyed(mockedVersion));
+
+ // set prop
+ when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_DESTROYED))
+ .thenReturn(Boolean.FALSE);
+
+ // is version destroyed
+ assertFalse(recordableVersionService.isRecordedVersionDestroyed(mockedVersion));
+ }
+
+ /**
+ * given that the version node doesn't have the recorded version aspect applied
+ * when I mark the version as destroyed
+ * then nothing happens
+ */
+ @Test
+ public void noAspectMarkAsDestroyed()
+ {
+ // set up version
+ Version mockedVersion = mock(VersionImpl.class);
+ NodeRef versionNodeRef = generateNodeRef();
+ when(mockedVersion.getFrozenStateNodeRef())
+ .thenReturn(versionNodeRef);
+
+ // indicate that the version doesn't have the aspect
+ when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
+ .thenReturn(false);
+
+ // mark as destroyed
+ recordableVersionService.destroyRecordedVersion(mockedVersion);
+
+ // verify nothing happened
+ verify(mockedDbNodeService, never())
+ .setProperty(versionNodeRef, RecordableVersionModel.PROP_DESTROYED, Boolean.TRUE);
+ }
+
+ /**
+ * given that the version node ref has the recorded version aspect applied
+ * and the record version reference exists
+ * when I mark the version as destroyed
+ * then the version is marked as destroyed
+ */
+ @Test
+ public void markAsDestroyed()
+ {
+ // set up version
+ Version mockedVersion = mock(VersionImpl.class);
+ NodeRef versionNodeRef = generateNodeRef();
+ NodeRef versionRecordNodeRef = generateNodeRef();
+ when(mockedVersion.getFrozenStateNodeRef())
+ .thenReturn(versionNodeRef);
+ when(mockedDbNodeService.exists(versionRecordNodeRef))
+ .thenReturn(true);
+
+ // indicate that the version doesn't have the aspect
+ when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
+ .thenReturn(true);
+
+ // indicate that the associated version record exists
+ when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF))
+ .thenReturn(versionRecordNodeRef);
+
+ // mark as destroyed
+ recordableVersionService.destroyRecordedVersion(mockedVersion);
+
+ // verify that the version was marked as destroyed
+ verify(mockedDbNodeService)
+ .setProperty(versionNodeRef, RecordableVersionModel.PROP_DESTROYED, Boolean.TRUE);
+ // and the reference to the version record was cleared
+ verify(mockedDbNodeService)
+ .setProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF, null);
+ }
+
+ /**
+ * given that the version node ref has the recorded version aspect applied
+ * and the associated version record has been deleted
+ * when I mark the version as destroyed
+ * then the version is marked as destroyed
+ * and the reference to the deleted version record is removed
+ */
+ @Test
+ public void markAsDestroyedClearNodeRef()
+ {
+ // set up version
+ Version mockedVersion = mock(VersionImpl.class);
+ NodeRef versionNodeRef = generateNodeRef();
+ NodeRef versionRecordNodeRef = generateNodeRef();
+ when(mockedVersion.getFrozenStateNodeRef())
+ .thenReturn(versionNodeRef);
+ when(mockedDbNodeService.exists(versionRecordNodeRef))
+ .thenReturn(false);
+
+ // indicate that the version doesn't have the aspect
+ when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
+ .thenReturn(true);
+
+ // indicate that the associated version record exists
+ when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF))
+ .thenReturn(versionRecordNodeRef);
+
+ // mark as destroyed
+ recordableVersionService.destroyRecordedVersion(mockedVersion);
+
+ // verify that the version was marked as destroyed
+ verify(mockedDbNodeService)
+ .setProperty(versionNodeRef, RecordableVersionModel.PROP_DESTROYED, Boolean.TRUE);
+ // and the reference to the version record was cleared
+ verify(mockedDbNodeService)
+ .setProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF, null);
+ }
}
\ No newline at end of file