diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml
index f8a9094c6a..196149832c 100644
--- a/config/alfresco/core-services-context.xml
+++ b/config/alfresco/core-services-context.xml
@@ -552,6 +552,7 @@
fm:commentCount
cm:storeName
+ cm:content
diff --git a/source/java/org/alfresco/opencmis/CMISConnector.java b/source/java/org/alfresco/opencmis/CMISConnector.java
index 1393bbf93a..433dfe42ec 100644
--- a/source/java/org/alfresco/opencmis/CMISConnector.java
+++ b/source/java/org/alfresco/opencmis/CMISConnector.java
@@ -1413,6 +1413,7 @@ public class CMISConnector implements ApplicationContextAware, ApplicationListen
Map props = new HashMap();
props.put(ContentModel.PROP_INITIAL_VERSION, false);
props.put(ContentModel.PROP_AUTO_VERSION, false);
+ props.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, props);
}
@@ -1429,6 +1430,7 @@ public class CMISConnector implements ApplicationContextAware, ApplicationListen
Map props = new HashMap();
props.put(ContentModel.PROP_INITIAL_VERSION, false);
props.put(ContentModel.PROP_AUTO_VERSION, false);
+ props.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, props);
}
diff --git a/source/java/org/alfresco/repo/version/VersionableAspect.java b/source/java/org/alfresco/repo/version/VersionableAspect.java
index d6fa5d7150..89def120b4 100644
--- a/source/java/org/alfresco/repo/version/VersionableAspect.java
+++ b/source/java/org/alfresco/repo/version/VersionableAspect.java
@@ -432,6 +432,7 @@ public class VersionableAspect implements ContentServicePolicies.OnContentUpdate
// Create the auto-version
Map versionProperties = new HashMap(1);
versionProperties.put(Version.PROP_DESCRIPTION, I18NUtil.getMessage(MSG_AUTO_VERSION));
+ versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
createVersionImpl(nodeRef, versionProperties);
}
@@ -463,24 +464,15 @@ public class VersionableAspect implements ContentServicePolicies.OnContentUpdate
Map versionedNodeRefs = (Map)AlfrescoTransactionSupport.getResource(KEY_VERSIONED_NODEREFS);
if (versionedNodeRefs == null || versionedNodeRefs.containsKey(nodeRef) == false)
{
- // Determine whether the node is auto versionable (for property only updates) or not
- boolean autoVersion = false;
- Boolean value = (Boolean)this.nodeService.getProperty(nodeRef, ContentModel.PROP_AUTO_VERSION);
- if (value != null)
- {
- // If the value is not null then
- autoVersion = value.booleanValue();
- }
-
boolean autoVersionProps = false;
- value = (Boolean)this.nodeService.getProperty(nodeRef, ContentModel.PROP_AUTO_VERSION_PROPS);
+ Boolean value = (Boolean)this.nodeService.getProperty(nodeRef, ContentModel.PROP_AUTO_VERSION_PROPS);
if (value != null)
{
// If the value is not null then
autoVersionProps = value.booleanValue();
}
- if ((autoVersion == true) && (autoVersionProps == true))
+ if (autoVersionProps == true)
{
// Check for explicitly excluded props - if one or more excluded props changes then do not auto-version on this event (even if other props changed)
if (excludedOnUpdatePropQNames.size() > 0)
diff --git a/source/test-java/org/alfresco/opencmis/CMISTest.java b/source/test-java/org/alfresco/opencmis/CMISTest.java
index 5835621bc7..107c2244a3 100644
--- a/source/test-java/org/alfresco/opencmis/CMISTest.java
+++ b/source/test-java/org/alfresco/opencmis/CMISTest.java
@@ -82,7 +82,9 @@ import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.tagging.TaggingService;
+import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionService;
+import org.alfresco.service.cmr.version.VersionType;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
@@ -2753,4 +2755,249 @@ public class CMISTest
withCmisService(callback, CmisVersion.CMIS_1_1);
}
+
+ /**
+ * Test to ensure auto version behavior for update properties, set and delete content using both Alfresco and CMIS perspectives.
+ * Testing different combinations of cm:initialVersion, cm:autoVersion and cm:autoVersionOnUpdateProps properties
+ *
+ * OnUpdateProperties MINOR version should be created if cm:initialVersion and cm:autoVersionOnUpdateProps are both TRUE
+ *
+ * OnContentUpdate MINOR version should be created if cm:initialVersion and cm:autoVersion are both TRUE
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdatePropertiesSetDeleteContentVersioning() throws Exception
+ {
+ AuthenticationUtil.pushAuthentication();
+ AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
+
+ final String FOLDER = "testUpdatePropertiesSetDeleteContentVersioning-" + GUID.generate();
+ final String DOC1 = "documentProperties1-" + GUID.generate();
+ final String DOC2 = "documentProperties2-" + GUID.generate();
+ final String DOC3 = "documentProperties3-" + GUID.generate();
+ final String DOC4 = "documentProperties4-" + GUID.generate();
+
+ try
+ {
+ final List docs = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback>()
+ {
+ @Override
+ public List execute() throws Throwable
+ {
+ // create folder
+ FileInfo folderInfo = fileFolderService.create(repositoryHelper.getCompanyHome(), FOLDER, ContentModel.TYPE_FOLDER);
+ nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, FOLDER);
+ assertNotNull(folderInfo);
+
+ FileInfo document;
+ List docs = new ArrayList();
+ // create documents
+ document = fileFolderService.create(folderInfo.getNodeRef(), DOC1, ContentModel.TYPE_CONTENT);
+ nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC1);
+ docs.add(document);
+ document = fileFolderService.create(folderInfo.getNodeRef(), DOC2, ContentModel.TYPE_CONTENT);
+ nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC2);
+ docs.add(document);
+ document = fileFolderService.create(folderInfo.getNodeRef(), DOC3, ContentModel.TYPE_CONTENT);
+ nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC3);
+ docs.add(document);
+ document = fileFolderService.create(folderInfo.getNodeRef(), DOC4, ContentModel.TYPE_CONTENT);
+ nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC4);
+ docs.add(document);
+
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_TITLE, "Initial Title");
+ props.put(ContentModel.PROP_DESCRIPTION, "Initial Description");
+
+ for (FileInfo fileInfo : docs)
+ {
+ nodeService.addAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_TITLED, props);
+ }
+
+ // apply versionable aspect with properties
+ props = new HashMap();
+ // ContentModel.PROP_INITIAL_VERSION always true
+ props.put(ContentModel.PROP_INITIAL_VERSION, true);
+
+ props.put(ContentModel.PROP_AUTO_VERSION, false);
+ props.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
+ versionService.ensureVersioningEnabled(docs.get(0).getNodeRef(), props);
+
+ props.put(ContentModel.PROP_AUTO_VERSION, false);
+ props.put(ContentModel.PROP_AUTO_VERSION_PROPS, true);
+ versionService.ensureVersioningEnabled(docs.get(1).getNodeRef(), props);
+
+ props.put(ContentModel.PROP_AUTO_VERSION, true);
+ props.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
+ versionService.ensureVersioningEnabled(docs.get(2).getNodeRef(), props);
+
+ props.put(ContentModel.PROP_AUTO_VERSION, true);
+ props.put(ContentModel.PROP_AUTO_VERSION_PROPS, true);
+ versionService.ensureVersioningEnabled(docs.get(3).getNodeRef(), props);
+
+ return docs;
+ }
+ });
+
+ assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(1).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(2).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(3).getNodeRef(), "1.0", VersionType.MAJOR);
+
+ // update node properties using Alfresco
+ transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback>()
+ {
+ @Override
+ public List execute() throws Throwable
+ {
+ for (FileInfo fileInfo : docs)
+ {
+ Map props = nodeService.getProperties(fileInfo.getNodeRef());
+
+ props.put(ContentModel.PROP_DESCRIPTION, "description-" + GUID.generate());
+ props.put(ContentModel.PROP_TITLE, "title-" + GUID.generate());
+
+ nodeService.setProperties(fileInfo.getNodeRef(), props);
+ }
+ return null;
+ }
+ });
+
+ assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(1).getNodeRef(), "1.1", VersionType.MINOR);
+ assertVersions(docs.get(2).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(3).getNodeRef(), "1.1", VersionType.MINOR);
+
+ // update properties using CMIS perspective
+ final String repositoryId = withCmisService(new CmisServiceCallback()
+ {
+ @Override
+ public String execute(CmisService cmisService)
+ {
+ String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
+
+ for (FileInfo fileInfo : docs)
+ {
+ PropertiesImpl properties = new PropertiesImpl();
+ properties.addProperty(new PropertyStringImpl(PropertyIds.DESCRIPTION, "description-" + GUID.generate()));
+
+ cmisService.updateProperties(repositoryId, new Holder(fileInfo.getNodeRef().toString()), null, properties, null);
+ }
+
+ return repositoryId;
+ }
+ }, CmisVersion.CMIS_1_1);
+
+ assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
+ assertVersions(docs.get(2).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(3).getNodeRef(), "1.2", VersionType.MINOR);
+
+ // CMIS setContentStream
+ withCmisService(new CmisServiceCallback()
+ {
+ @Override
+ public Void execute(CmisService cmisService)
+ {
+ for (FileInfo fileInfo : docs)
+ {
+ ContentStreamImpl contentStream = new ContentStreamImpl(null, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Content " + GUID.generate());
+
+ cmisService.setContentStream(repositoryId, new Holder(fileInfo.getNodeRef().toString()), true, null, contentStream, null);
+ }
+ return null;
+ }
+ }, CmisVersion.CMIS_1_1);
+
+ assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
+ assertVersions(docs.get(2).getNodeRef(), "1.1", VersionType.MINOR);
+ assertVersions(docs.get(3).getNodeRef(), "1.3", VersionType.MINOR);
+
+ // update content using Alfresco
+ transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback>()
+ {
+ @Override
+ public List execute() throws Throwable
+ {
+ for (FileInfo fileInfo : docs)
+ {
+ ContentWriter writer = contentService.getWriter(fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
+ writer.putContent("Content " + GUID.generate());
+ }
+ return null;
+ }
+ });
+
+ assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
+ assertVersions(docs.get(2).getNodeRef(), "1.2", VersionType.MINOR);
+ assertVersions(docs.get(3).getNodeRef(), "1.4", VersionType.MINOR);
+
+ // CMIS deleteContentStream
+ withCmisService(new CmisServiceCallback()
+ {
+ @Override
+ public Void execute(CmisService cmisService)
+ {
+ for (FileInfo fileInfo : docs)
+ {
+ cmisService.deleteContentStream(repositoryId, new Holder(fileInfo.getNodeRef().toString()), null, null);
+ }
+ return null;
+ }
+ }, CmisVersion.CMIS_1_1);
+
+ assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
+ assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
+ assertVersions(docs.get(2).getNodeRef(), "1.3", VersionType.MINOR);
+ assertVersions(docs.get(3).getNodeRef(), "1.5", VersionType.MINOR);
+ }
+ finally
+ {
+ AuthenticationUtil.popAuthentication();
+ }
+ }
+
+ private void assertVersions(final NodeRef nodeRef, final String expectedVersionLabel, final VersionType expectedVersionType)
+ {
+ transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback>()
+ {
+ @Override
+ public List execute() throws Throwable
+ {
+ assertTrue("Node should be versionable", nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE));
+
+ Version version = versionService.getCurrentVersion(nodeRef);
+
+ assertNotNull(version);
+ assertEquals(expectedVersionLabel, version.getVersionLabel());
+ assertEquals(expectedVersionType, version.getVersionType());
+
+ return null;
+ }
+ });
+
+ withCmisService(new CmisServiceCallback()
+ {
+ @Override
+ public Void execute(CmisService cmisService)
+ {
+ String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
+
+ ObjectData data =
+ cmisService.getObjectOfLatestVersion(repositoryId, nodeRef.toString(), null, Boolean.FALSE, null, null, null, null, null, null, null);
+
+ assertNotNull(data);
+
+ PropertyData> prop = data.getProperties().getProperties().get(PropertyIds.VERSION_LABEL);
+ Object versionLabelCmisValue = prop.getValues().get(0);
+
+ assertEquals(expectedVersionLabel, versionLabelCmisValue);
+
+ return null;
+ }
+ }, CmisVersion.CMIS_1_1);
+ }
}