chemistry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From f...@apache.org
Subject svn commit: r1494929 - in /chemistry/opencmis/trunk: chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/ma...
Date Thu, 20 Jun 2013 11:06:06 GMT
Author: fmui
Date: Thu Jun 20 11:06:06 2013
New Revision: 1494929

URL: http://svn.apache.org/r1494929
Log:
CMIS-674: fixed AtomPub change token handling

Added:
    chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/ChangeTokenTest.java
  (with props)
Modified:
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AbstractAtomPubService.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/VersioningServiceImpl.java
    chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/PropertiesImpl.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java
    chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/CRUDTestGroup.java

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AbstractAtomPubService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AbstractAtomPubService.java?rev=1494929&r1=1494928&r2=1494929&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AbstractAtomPubService.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AbstractAtomPubService.java
Thu Jun 20 11:06:06 2013
@@ -85,6 +85,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PolicyIdListImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
 
 /**
  * Base class for all AtomPub client services.
@@ -538,11 +539,18 @@ public abstract class AbstractAtomPubSer
     /**
      * Creates a CMIS object with properties and policy ids.
      */
-    protected ObjectDataImpl createObject(Properties properties, List<String> policies)
{
+    protected ObjectDataImpl createObject(Properties properties, String changeToken, List<String>
policies) {
         ObjectDataImpl object = new ObjectDataImpl();
 
         if (properties == null) {
             properties = new PropertiesImpl();
+            if (changeToken != null) {
+                ((PropertiesImpl) properties)
+                        .addProperty(new PropertyStringImpl(PropertyIds.CHANGE_TOKEN, changeToken));
+            }
+        } else if (changeToken != null && !properties.getProperties().containsKey(PropertyIds.CHANGE_TOKEN))
{
+            properties = new PropertiesImpl(properties);
+            ((PropertiesImpl) properties).addProperty(new PropertyStringImpl(PropertyIds.CHANGE_TOKEN,
changeToken));
         }
         object.setProperties(properties);
 

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java?rev=1494929&r1=1494928&r2=1494929&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
Thu Jun 20 11:06:06 2013
@@ -109,7 +109,7 @@ public class ObjectServiceImpl extends A
         url.addParameter(Constants.PARAM_VERSIONIG_STATE, versioningState);
 
         // set up writer
-        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
policies),
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
null, policies),
                 getCmisVersion(repositoryId), contentStream);
 
         // post the new folder object
@@ -148,7 +148,7 @@ public class ObjectServiceImpl extends A
         UrlBuilder url = new UrlBuilder(link);
 
         // set up writer
-        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
policies),
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
null, policies),
                 getCmisVersion(repositoryId));
 
         // post the new folder object
@@ -195,7 +195,7 @@ public class ObjectServiceImpl extends A
         UrlBuilder url = new UrlBuilder(link);
 
         // set up writer
-        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
policies),
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
null, policies),
                 getCmisVersion(repositoryId));
 
         // post the new folder object
@@ -238,7 +238,7 @@ public class ObjectServiceImpl extends A
         UrlBuilder url = new UrlBuilder(link);
 
         // set up writer
-        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
policies),
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
null, policies),
                 getCmisVersion(repositoryId));
 
         // post the new folder object
@@ -282,7 +282,7 @@ public class ObjectServiceImpl extends A
         UrlBuilder url = new UrlBuilder(link);
 
         // set up writer
-        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
policies),
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
null, policies),
                 getCmisVersion(repositoryId));
 
         // post the new folder object
@@ -317,12 +317,14 @@ public class ObjectServiceImpl extends A
 
         UrlBuilder url = new UrlBuilder(link);
         if (changeToken != null) {
+            // not required by the CMIS specification
+            // -> keep for backwards compatibility with older OpenCMIS servers
             url.addParameter(Constants.PARAM_CHANGE_TOKEN, changeToken.getValue());
         }
 
         // set up writer
-        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
null),
-                getCmisVersion(repositoryId));
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
changeToken == null ? null
+                : changeToken.getValue(), null), getCmisVersion(repositoryId));
 
         // update
         Response resp = put(url, Constants.MEDIATYPE_ENTRY, new Output() {

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/VersioningServiceImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/VersioningServiceImpl.java?rev=1494929&r1=1494928&r2=1494929&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/VersioningServiceImpl.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/VersioningServiceImpl.java
Thu Jun 20 11:06:06 2013
@@ -154,7 +154,7 @@ public class VersioningServiceImpl exten
         url.addParameter(Constants.PARAM_CHECK_IN, "true");
 
         // set up writer
-        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
policies),
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createObject(properties,
null, policies),
                 getCmisVersion(repositoryId), contentStream);
 
         // update

Modified: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/PropertiesImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/PropertiesImpl.java?rev=1494929&r1=1494928&r2=1494929&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/PropertiesImpl.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/PropertiesImpl.java
Thu Jun 20 11:06:06 2013
@@ -52,11 +52,22 @@ public class PropertiesImpl extends Abst
      *            initial collection of properties
      */
     public PropertiesImpl(Collection<PropertyData<?>> properties) {
-        if (properties != null) {
-            for (PropertyData<?> prop : properties) {
-                addProperty(prop);
-            }
+        addProperties(properties);
+    }
+
+    /**
+     * Shallow copy constructor.
+     * 
+     * Creates a new collection of properties but references the original
+     * property and extension objects.
+     */
+    public PropertiesImpl(Properties properties) {
+        if (properties == null) {
+            throw new IllegalArgumentException("Properties not set!");
         }
+
+        addProperties(properties.getPropertyList());
+        setExtensions(properties.getExtensions());
     }
 
     public Map<String, PropertyData<?>> getProperties() {
@@ -67,6 +78,14 @@ public class PropertiesImpl extends Abst
         return Collections.unmodifiableList(propertyList);
     }
 
+    protected void addProperties(Collection<PropertyData<?>> properties) {
+        if (properties != null) {
+            for (PropertyData<?> prop : properties) {
+                addProperty(prop);
+            }
+        }
+    }
+
     /**
      * Adds a property.
      * 

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java?rev=1494929&r1=1494928&r2=1494929&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java
Thu Jun 20 11:06:06 2013
@@ -519,10 +519,24 @@ public class ObjectService {
                     closeContentStream(contentStream);
                 }
             } else {
-                String changeToken = extractChangeToken(parser.getProperties());
+                Properties properties = parser.getProperties();
+                String changeToken = null;
+                if (properties != null) {
+                    changeToken = extractChangeToken(properties);
+                    if (changeToken != null) {
+                        properties = new PropertiesImpl(properties);
+                        ((PropertiesImpl) properties).removeProperty(PropertyIds.CHANGE_TOKEN);
+                    }
+                }
 
+                if(changeToken == null) {
+                    // not required by the CMIS specification
+                    // -> keep for backwards compatibility with older OpenCMIS clients
+                    changeToken = getStringParameter(request, Constants.PARAM_CHANGE_TOKEN);
+                }
+                
                 service.updateProperties(repositoryId, objectIdHolder, changeToken == null
? null : new Holder<String>(
-                        changeToken), parser.getProperties(), null);
+                        changeToken), properties, null);
             }
 
             ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectIdHolder.getValue());
@@ -565,12 +579,12 @@ public class ObjectService {
                 return null;
             }
 
-            PropertyData<?> changeLogProperty = propertiesMap.get(PropertyIds.CHANGE_TOKEN);
-            if (!(changeLogProperty instanceof PropertyString)) {
+            PropertyData<?> changeTokenProperty = propertiesMap.get(PropertyIds.CHANGE_TOKEN);
+            if (!(changeTokenProperty instanceof PropertyString)) {
                 return null;
             }
 
-            return ((PropertyString) changeLogProperty).getFirstValue();
+            return ((PropertyString) changeTokenProperty).getFirstValue();
         }
     }
 

Modified: chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/CRUDTestGroup.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/CRUDTestGroup.java?rev=1494929&r1=1494928&r2=1494929&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/CRUDTestGroup.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/CRUDTestGroup.java
Thu Jun 20 11:06:06 2013
@@ -43,6 +43,7 @@ public class CRUDTestGroup extends Abstr
         addTest(new UpdateSmokeTest());
         addTest(new BulkUpdatePropertiesTest());
         addTest(new SetAndDeleteContentTest());
+        addTest(new ChangeTokenTest());
         addTest(new ContentRangesTest());
         addTest(new CopyTest());
         addTest(new MoveTest());

Added: chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/ChangeTokenTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/ChangeTokenTest.java?rev=1494929&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/ChangeTokenTest.java
(added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/ChangeTokenTest.java
Thu Jun 20 11:06:06 2013
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.tck.tests.crud;
+
+import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.FAILURE;
+import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.SKIPPED;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.chemistry.opencmis.client.api.Document;
+import org.apache.chemistry.opencmis.client.api.Folder;
+import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.enums.Action;
+import org.apache.chemistry.opencmis.commons.enums.CapabilityContentStreamUpdates;
+import org.apache.chemistry.opencmis.commons.enums.Updatability;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
+import org.apache.chemistry.opencmis.tck.impl.AbstractSessionTest;
+
+public class ChangeTokenTest extends AbstractSessionTest {
+
+    @Override
+    public void init(Map<String, String> parameters) {
+        super.init(parameters);
+        setName("Change Token Test");
+        setDescription("Creates a document and updates it with an outdated change token.");
+    }
+
+    @Override
+    public void run(Session session) {
+        // create a test folder
+        Folder testFolder = createTestFolder(session);
+
+        try {
+            // update properties test
+            runUpdateTest(session, testFolder);
+
+            // content update test
+            runContentTest(session, testFolder);
+        } finally {
+            // delete the test folder
+            deleteTestFolder();
+        }
+    }
+
+    private void runUpdateTest(Session session, Folder testFolder) {
+        Document doc = createDocument(session, testFolder, "update1.txt", "Hello World!");
+
+        try {
+            if (doc.getChangeToken() == null) {
+                addResult(createResult(SKIPPED, "Repository does not provide change tokens.
Test skipped!"));
+                return;
+            }
+
+            DocumentTypeDefinition type = (DocumentTypeDefinition) doc.getType();
+            PropertyDefinition<?> namePropDef = type.getPropertyDefinitions().get(PropertyIds.NAME);
+            if (namePropDef.getUpdatability() == Updatability.WHENCHECKEDOUT
+                    || !doc.getAllowableActions().getAllowableActions().contains(Action.CAN_UPDATE_PROPERTIES))
{
+                addResult(createResult(SKIPPED, "Document name can't be changed. Test skipped!"));
+                return;
+            }
+
+            // the first update should succeed
+            Map<String, Object> properties2 = new HashMap<String, Object>();
+            properties2.put(PropertyIds.NAME, "update2.txt");
+            doc.updateProperties(properties2, false);
+
+            try {
+                Map<String, Object> properties3 = new HashMap<String, Object>();
+                properties3.put(PropertyIds.NAME, "update3.txt");
+                doc.updateProperties(properties3, false);
+
+                addResult(createResult(FAILURE, "Updating properties a second time with the
same change token "
+                        + "should result in an UpdateConflict exception!"));
+            } catch (CmisUpdateConflictException e) {
+                // expected exception
+            }
+        } finally {
+            deleteObject(doc);
+        }
+    }
+
+    private void runContentTest(Session session, Folder testFolder) {
+        if (session.getRepositoryInfo().getCapabilities().getContentStreamUpdatesCapability()
!= CapabilityContentStreamUpdates.ANYTIME) {
+            addResult(createResult(SKIPPED, "Repository doesn't allow to replace content.
Test skipped!"));
+            return;
+        }
+
+        Document doc = createDocument(session, testFolder, "content1.txt", "Hello World!");
+
+        try {
+            if (doc.getChangeToken() == null) {
+                addResult(createResult(SKIPPED, "Repository does not provide change tokens.
Test skipped!"));
+                return;
+            }
+
+            if (!doc.getAllowableActions().getAllowableActions().contains(Action.CAN_SET_CONTENT_STREAM))
{
+                addResult(createResult(SKIPPED, "Document content can't be changed. Test
skipped!"));
+                return;
+            }
+
+            byte[] contentBytes = "New content".getBytes();
+            ContentStream contentStream = new ContentStreamImpl("content2.txt",
+                    BigInteger.valueOf(contentBytes.length), "text/plain", new ByteArrayInputStream(contentBytes));
+
+            doc.setContentStream(contentStream, true, false);
+
+            try {
+                doc.setContentStream(contentStream, true, false);
+
+                addResult(createResult(FAILURE, "Updating content a second time with the
same change token "
+                        + "should result in an UpdateConflict exception!"));
+            } catch (CmisUpdateConflictException e) {
+                // expected exception
+            }
+        } finally {
+            deleteObject(doc);
+        }
+    }
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/ChangeTokenTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message