You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by dc...@apache.org on 2010/02/11 12:44:29 UTC
svn commit: r908938 - in
/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry:
abdera/ext/ tck/atompub/client/ tck/atompub/fixture/ tck/atompub/test/
tck/atompub/test/spec/
Author: dcaruana
Date: Thu Feb 11 11:44:23 2010
New Revision: 908938
URL: http://svn.apache.org/viewvc?rev=908938&view=rev
Log:
CMIS-115: Add Change Log tests to TCK
- update TCK Abdera extension to allow for query of change log related information
Added:
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISChangeEventInfo.java (with props)
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertChangeTypeInChangeLogVisitor.java (with props)
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/ManageAccessControlListVisitor.java (with props)
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/UpdateDocumentsVisitor.java (with props)
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/ChangeLogTest.java (with props)
Modified:
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISAccessControlList.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISCapabilities.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISConstants.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISExtensionFactory.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISObject.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISRepositoryInfo.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISTypeDefinition.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/TCKTestSuite.java
incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/AccessControlListTest.java
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISAccessControlList.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISAccessControlList.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISAccessControlList.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISAccessControlList.java Thu Feb 11 11:44:23 2010
@@ -17,7 +17,9 @@
package org.apache.chemistry.abdera.ext;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.abdera.factory.Factory;
import org.apache.abdera.model.Element;
@@ -63,4 +65,31 @@
}
return entries;
}
+
+ /**
+ * Flattens an access control list into a structure that is easy to compare:
+ * a set of triples containing the principal ID, the direct flag and the
+ * permission name.
+ *
+ * @param accessControlList
+ * the access control list
+ *
+ * @return the set of triples
+ */
+ public Set<List<Object>> getHashedEntries() {
+ List<CMISAccessControlEntry> entries = getEntries();
+ Set<List<Object>> hashSet = new HashSet<List<Object>>(entries.size() * 2);
+ for (CMISAccessControlEntry accessControlEntry : entries) {
+ String principalId = accessControlEntry.getPrincipalId();
+ Boolean direct = accessControlEntry.isDirect();
+ for (String permission : accessControlEntry.getPermissions()) {
+ List<Object> comparable = new ArrayList<Object>(3);
+ comparable.add(principalId);
+ comparable.add(direct);
+ comparable.add(permission);
+ hashSet.add(comparable);
+ }
+ }
+ return hashSet;
+ }
}
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISCapabilities.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISCapabilities.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISCapabilities.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISCapabilities.java Thu Feb 11 11:44:23 2010
@@ -87,4 +87,9 @@
Element child = getFirstChild(CMISConstants.CAPABILITY_ACL);
return child.getText();
}
+
+ public String getChanges() {
+ Element child = getFirstChild(CMISConstants.CAPABILITY_CHANGES);
+ return child.getText();
+ }
}
Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISChangeEventInfo.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISChangeEventInfo.java?rev=908938&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISChangeEventInfo.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISChangeEventInfo.java Thu Feb 11 11:44:23 2010
@@ -0,0 +1,39 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ * David Ward, Alfresco
+ */
+package org.apache.chemistry.abdera.ext;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ExtensibleElementWrapper;
+
+/**
+ * CMIS Change Event Info for the Abdera ATOM library.
+ */
+public class CMISChangeEventInfo extends ExtensibleElementWrapper {
+
+ public CMISChangeEventInfo(Element internal) {
+ super(internal);
+ }
+
+ public CMISChangeEventInfo(Factory factory) {
+ super(factory, CMISConstants.CHANGE_EVENT_INFO);
+ }
+
+ public String getChangeType() {
+ return getFirstChild(CMISConstants.CHANGE_TYPE).getText();
+ }
+}
Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISChangeEventInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISConstants.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISConstants.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISConstants.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISConstants.java Thu Feb 11 11:44:23 2010
@@ -62,6 +62,8 @@
public static final QName VERSION_SUPPORTED = new QName(CMIS_NS, "cmisVersionSupported");
public static final QName PRINCIPAL_ANONYMOUS = new QName(CMIS_NS, "principalAnonymous");
public static final QName PRINCIPAL_ANYONE = new QName(CMIS_NS, "principalAnyone");
+ public static final QName LATEST_CHANGE_LOG_TOKEN = new QName(CMIS_NS, "latestChangeLogToken");
+ public static final QName CHANGES_ON_TYPE = new QName(CMIS_NS, "changesOnType");
// CMIS URI Templates
public static final QName URI_TEMPLATE = new QName(CMISRA_NS, "uritemplate");
@@ -86,6 +88,7 @@
public static final QName CAPABILITY_JOIN = new QName(CMIS_NS, "capabilityJoin");
public static final QName CAPABILITY_RENDITIONS = new QName(CMIS_NS, "capabilityRenditions");
public static final QName CAPABILITY_ACL = new QName(CMIS_NS, "capabilityACL");
+ public static final QName CAPABILITY_CHANGES = new QName(CMIS_NS, "capabilityChanges");
// ACL Capabilities
public static final QName ACL_CAPABILITY = new QName(CMIS_NS, "aclCapability");
@@ -179,6 +182,7 @@
public static final String REL_SERVICE = "service";
public static final String REL_UP = "up";
public static final String REL_DOWN = "down";
+ public static final String REL_NEXT = "next";
public static final String REL_DESCRIBED_BY = "describedby";
public static final String REL_VERSION_HISTORY = "version-history";
public static final String REL_CURRENT_VERSION = "current-version";
@@ -191,6 +195,7 @@
public static final String REL_POLICIES = CMISLINK_NS + "policies";
public static final String REL_RELATIONSHIPS = CMISLINK_NS + "relationships";
public static final String REL_ACL = CMISLINK_NS + "acl";
+ public static final String REL_CHANGES = CMISLINK_NS + "changes";
public static final String REL_ASSOC_SOURCE = CMISLINK_NS + "source";
public static final String REL_ASSOC_TARGET = CMISLINK_NS + "target";
@@ -246,6 +251,16 @@
public static final QName PERMISSION = new QName(CMIS_NS, "permission");
public static final QName DIRECT = new QName(CMIS_NS, "direct");
+ // CMIS Change Event Info
+ public static final QName CHANGE_EVENT_INFO = new QName(CMIS_NS, "changeEventInfo");
+ public static final QName CHANGE_TYPE = new QName(CMIS_NS, "changeType");
+
+ // CMIS Change Types
+ public static final String CHANGE_TYPE_CREATED = "created";
+ public static final String CHANGE_TYPE_UPDATED = "updated";
+ public static final String CHANGE_TYPE_DELETED = "deleted";
+ public static final String CHANGE_TYPE_SECURITY = "security";
+
// CMIS Type Names
public static final String TYPE_DOCUMENT = "cmis:document";
public static final String TYPE_FOLDER = "cmis:folder";
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISExtensionFactory.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISExtensionFactory.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISExtensionFactory.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISExtensionFactory.java Thu Feb 11 11:44:23 2010
@@ -60,6 +60,7 @@
addImpl(HTML_PROPERTY, CMISPropertyHtml.class);
addImpl(PROPERTY_VALUE, CMISValue.class);
addImpl(ALLOWABLE_ACTIONS, CMISAllowableActions.class);
+ addImpl(CHANGE_EVENT_INFO, CMISChangeEventInfo.class);
addImpl(ACCESS_CONTROL_LIST, CMISAccessControlList.class);
addImpl(PERMISSION, CMISAccessControlEntry.class);
addImpl(TYPE_DEFINITION, CMISTypeDefinition.class);
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISObject.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISObject.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISObject.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISObject.java Thu Feb 11 11:44:23 2010
@@ -67,6 +67,28 @@
}
/**
+ * Gets the change event information for this CMIS Object if it is in a
+ * change log.
+ *
+ * @return change event information for this CMIS Object
+ */
+ public CMISChangeEventInfo getChangeEventInfo() {
+ Element child = getFirstChild(CMISConstants.CHANGE_EVENT_INFO);
+ return (CMISChangeEventInfo) child;
+ }
+
+ /**
+ * Gets the access control list for this CMIS Object if it is in a change
+ * log.
+ *
+ * @return access control list for this CMIS Object
+ */
+ public CMISAccessControlList getAccessControlList() {
+ Element child = getFirstChild(CMISConstants.ACCESS_CONTROL_LIST);
+ return (CMISAccessControlList) child;
+ }
+
+ /**
* Gets name
*
* @return name property
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISRepositoryInfo.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISRepositoryInfo.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISRepositoryInfo.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISRepositoryInfo.java Thu Feb 11 11:44:23 2010
@@ -16,6 +16,9 @@
*/
package org.apache.chemistry.abdera.ext;
+import java.util.HashSet;
+import java.util.Set;
+
import org.apache.abdera.factory.Factory;
import org.apache.abdera.model.Element;
import org.apache.abdera.model.ElementWrapper;
@@ -140,4 +143,21 @@
}
return null;
}
+
+ public String getLatestChangeLogToken() {
+ Element child = getFirstChild(CMISConstants.LATEST_CHANGE_LOG_TOKEN);
+ if (child != null) {
+ return child.getText();
+ }
+ return null;
+ }
+
+ public Set<String> getChangesOnType() {
+ Set<String> changesOnType = new HashSet<String>(5);
+ for (Element type = getFirstChild(CMISConstants.CHANGES_ON_TYPE); type != null; type = type
+ .getNextSibling(CMISConstants.CHANGES_ON_TYPE)) {
+ changesOnType.add(type.getText());
+ }
+ return changesOnType;
+ }
}
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISTypeDefinition.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISTypeDefinition.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISTypeDefinition.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISTypeDefinition.java Thu Feb 11 11:44:23 2010
@@ -54,6 +54,17 @@
}
/**
+ * Gets a value that indicates whether the base type for this Object-Type is
+ * the Document, Folder, Relationship, or Policy base type.
+ *
+ * @return "cmis:document", "cmis:folder", "cmis:relationship" or
+ * "cmis:policy"
+ */
+ public String getBaseId() {
+ return getFirstChild(CMISConstants.TYPE_BASE_ID).getText();
+ }
+
+ /**
* Gets all Property Definitions for this CMIS Type
*
* @return property definitions
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java Thu Feb 11 11:44:23 2010
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -39,6 +40,7 @@
import org.apache.abdera.model.Link;
import org.apache.abdera.model.Service;
import org.apache.abdera.model.Workspace;
+import org.apache.abdera.util.Constants;
import org.apache.chemistry.abdera.ext.CMISACLCapability;
import org.apache.chemistry.abdera.ext.CMISCapabilities;
import org.apache.chemistry.abdera.ext.CMISConstants;
@@ -109,7 +111,11 @@
}
public Service getRepository() throws Exception {
- if (cmisService == null) {
+ return getRepository(false);
+ }
+
+ public Service getRepository(boolean refresh) throws Exception {
+ if (refresh || cmisService == null) {
Request req = new GetRequest(serviceUrl);
Response res = executeRequest(req, 200);
String xml = res.getContentAsString();
@@ -121,10 +127,14 @@
return cmisService;
}
+
public CMISRepositoryInfo getRepositoryInfo() throws Exception {
- if (cmisRepositoryInfo == null) {
- // TODO: latestChangeLogToken can't be cached
- Service repo = getRepository();
+ return getRepositoryInfo(false);
+ }
+
+ public CMISRepositoryInfo getRepositoryInfo(boolean refresh) throws Exception {
+ if (refresh || cmisRepositoryInfo == null) {
+ Service repo = getRepository(refresh);
Workspace workspace = getWorkspace(repo);
cmisRepositoryInfo = workspace.getExtension(CMISConstants.REPOSITORY_INFO);
Assert.assertNotNull(cmisRepositoryInfo);
@@ -141,7 +151,7 @@
}
public Workspace getWorkspace() throws Exception {
- return getRepository().getWorkspaces().get(0);
+ return getRepository(false).getWorkspaces().get(0);
}
public Workspace getWorkspace(Service service) {
@@ -217,9 +227,22 @@
public CMISUriTemplate getTypeByIdUriTemplate(Workspace workspace) {
return getUriTemplate(workspace, CMISConstants.URI_TYPE_BY_ID);
}
+
+ public Link getLink(Workspace workspace, String rel, String... matchesMimetypes)
+ {
+ List<Link> links = workspace.getExtensions(Constants.LINK);
+ List<Link> filteredLinks = new ArrayList<Link>(links.size());
+ for (Link link : links)
+ {
+ if (link.getRel().equals(rel))
+ {
+ filteredLinks.add(link);
+ }
+ }
+ return getLink(filteredLinks, matchesMimetypes);
+ }
- public Link getLink(Entry entry, String rel, String... matchesMimetypes) {
- List<Link> links = entry.getLinks(rel);
+ private Link getLink(List<Link> links, String... matchesMimetypes) {
if (links != null) {
for (Link link : links) {
MimeType mimetype = link.getMimeType();
@@ -257,6 +280,10 @@
}
return null;
}
+
+ public Link getLink(Entry entry, String rel, String... matchesMimetypes) {
+ return getLink(entry.getLinks(rel), matchesMimetypes);
+ }
public Link getChildrenLink(Entry entry) {
return getLink(entry, CMISConstants.REL_DOWN, CMISConstants.MIMETYPE_FEED);
@@ -281,6 +308,10 @@
public List<Link> getRenditionLinks(Entry entry) {
return entry.getLinks(CMISConstants.REL_ALTERNATE);
}
+
+ public Link getChangesLink(Workspace workspace) {
+ return getLink(workspace, CMISConstants.REL_CHANGES, CMISConstants.MIMETYPE_FEED);
+ }
public Entry getEntry(IRI href) throws Exception {
return getEntry(href, null);
Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertChangeTypeInChangeLogVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertChangeTypeInChangeLogVisitor.java?rev=908938&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertChangeTypeInChangeLogVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertChangeTypeInChangeLogVisitor.java Thu Feb 11 11:44:23 2010
@@ -0,0 +1,147 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ * David Ward, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Link;
+import org.apache.chemistry.abdera.ext.CMISAccessControlList;
+import org.apache.chemistry.abdera.ext.CMISChangeEventInfo;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.abdera.ext.CMISObject;
+import org.apache.chemistry.tck.atompub.client.CMISAppModel;
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.apache.chemistry.tck.atompub.http.GetRequest;
+import org.apache.chemistry.tck.atompub.http.Request;
+import org.apache.chemistry.tck.atompub.http.Response;
+import org.junit.Assert;
+
+/**
+ * Visitor that asserts that an entry of the given type exists for the given
+ * object types in the change log feed after the given change log token.
+ * Optionally follows paging links and checks included ACLs and properties.
+ */
+public class AssertChangeTypeInChangeLogVisitor implements TreeVisitor {
+
+ private String changeType;
+ private Set<String> changesOnType;
+ private Map<String, Entry> entriesByObjectId;
+
+ public AssertChangeTypeInChangeLogVisitor(CMISClient client, CMISAppModel model, String changeLogToken,
+ Integer maxItems, boolean includeACL, boolean includeProperties, String changeType,
+ Set<String> changesOnType) throws Exception {
+ this.changeType = changeType;
+ this.changesOnType = changesOnType;
+ Feed feed = getChangeLog(client, changeLogToken, maxItems, includeACL, includeProperties);
+ List<Entry> entries = feed.getEntries();
+ this.entriesByObjectId = new HashMap<String, Entry>(entries.size() * 2);
+ // Keep looping until we have no more "next" links
+ for (;;) {
+ if (maxItems != null) {
+ Assert.assertFalse("maxItems exceeded", entries.size() > maxItems);
+ }
+ for (Entry entry : entries) {
+ CMISObject object = entry.getExtension(CMISConstants.OBJECT);
+ Assert.assertNotNull(object);
+ String objectId = object.getObjectId().getStringValue();
+ Assert.assertNotNull(objectId);
+ CMISChangeEventInfo changeEventInfo = object.getChangeEventInfo();
+ Assert.assertNotNull(changeEventInfo);
+ if (changeEventInfo.getChangeType().equals(changeType)) {
+ entriesByObjectId.put(objectId, entry);
+
+ // Ensure the change log entry contains the expected ACL
+ if (includeACL) {
+ CMISAccessControlList accessControlList = object.getAccessControlList();
+ Assert.assertNotNull("Expected ACL", accessControlList);
+ Link accessControlListLink = entry.getLink(CMISConstants.REL_ACL);
+ Assert.assertNotNull("Expected ACL Link", accessControlListLink);
+ Request req = new GetRequest(accessControlListLink.getHref().toString());
+ Response accessControlListRes = client.executeRequest(req, 200);
+ Assert.assertNotNull(accessControlListRes);
+ Element fetchedAccessControlList = model.parse(new StringReader(accessControlListRes
+ .getContentAsString()), null);
+ Assert.assertNotNull(fetchedAccessControlList);
+ Assert.assertTrue(fetchedAccessControlList instanceof CMISAccessControlList);
+ Assert.assertEquals(accessControlList.getHashedEntries(),
+ ((CMISAccessControlList) fetchedAccessControlList).getHashedEntries());
+ }
+
+ // Ensure we have the expected properties
+ Set<String> properties = new HashSet<String>(object.getProperties().getIds());
+ Assert.assertTrue(properties.contains(CMISConstants.PROP_OBJECT_ID));
+
+ // Object ID MUST be the only property if we didn't include
+ // properties
+ if (!includeProperties) {
+ Assert.assertTrue("Unexpected properties in change log", properties.size() == 1);
+ }
+ }
+ }
+ // Keep looping while we have a next page link
+ Link nextPageLink = feed.getLink(CMISConstants.REL_NEXT);
+ if (nextPageLink == null) {
+ break;
+ }
+ feed = client.getFeed(nextPageLink.getHref());
+ entries = feed.getEntries();
+ }
+ }
+
+ public void visit(EntryTree entry) throws Exception {
+ if (this.changesOnType.contains(entry.type)) {
+ CMISObject object = entry.entry.getExtension(CMISConstants.OBJECT);
+ Assert.assertNotNull(object);
+ String objectId = object.getObjectId().getStringValue();
+ Assert.assertNotNull(objectId);
+ Assert.assertTrue(this.changeType + " change log entry should exist for " + objectId, entriesByObjectId
+ .containsKey(objectId));
+ }
+ }
+
+ private Feed getChangeLog(CMISClient client, String changeLogToken, Integer maxItems, boolean includeACL,
+ boolean includeProperties) throws Exception {
+ Link changesLink = client.getChangesLink(client.getWorkspace());
+ Assert.assertNotNull(changesLink);
+ Map<String, String> args = new HashMap<String, String>(5);
+ if (changeLogToken != null) {
+ args.put("changeLogToken", changeLogToken);
+ }
+ if (maxItems != null) {
+ args.put("maxItems", maxItems.toString());
+ }
+ if (includeACL) {
+ args.put("includeACL", "true");
+ }
+ if (includeProperties) {
+ args.put("includeProperties", "true");
+ args.put("filter", "*");
+ }
+ Feed changes = client.getFeed(changesLink.getHref(), args);
+ Assert.assertNotNull(changes);
+ return changes;
+ }
+}
Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertChangeTypeInChangeLogVisitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/ManageAccessControlListVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/ManageAccessControlListVisitor.java?rev=908938&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/ManageAccessControlListVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/ManageAccessControlListVisitor.java Thu Feb 11 11:44:23 2010
@@ -0,0 +1,259 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ * David Ward, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Link;
+import org.apache.chemistry.abdera.ext.CMISACLCapability;
+import org.apache.chemistry.abdera.ext.CMISAccessControlList;
+import org.apache.chemistry.abdera.ext.CMISAllowableActions;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.abdera.ext.CMISObject;
+import org.apache.chemistry.abdera.ext.CMISRepositoryInfo;
+import org.apache.chemistry.abdera.ext.CMISTypeDefinition;
+import org.apache.chemistry.tck.atompub.client.CMISAppModel;
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.apache.chemistry.tck.atompub.http.GetRequest;
+import org.apache.chemistry.tck.atompub.http.PutRequest;
+import org.apache.chemistry.tck.atompub.http.Request;
+import org.apache.chemistry.tck.atompub.http.Response;
+import org.junit.Assert;
+
+/**
+ * Visitor that manages ACLs on all objects in a tree.
+ */
+public class ManageAccessControlListVisitor implements TreeVisitor {
+
+ private CMISClient client;
+ private CMISAppModel model;
+ private Set<String> rejectedTypes = new HashSet<String>(5);
+
+ public ManageAccessControlListVisitor(CMISClient client, CMISAppModel model) {
+ this.client = client;
+ this.model = model;
+ }
+
+ public void visit(EntryTree entry) throws Exception {
+ Link accessControlListLink = entry.entry.getLink(CMISConstants.REL_ACL);
+ Request req = new GetRequest(accessControlListLink.getHref().toString());
+ Response accessControlListRes = client.executeRequest(req, 200);
+ Assert.assertNotNull(accessControlListRes);
+ Element accessControlList = model.parse(new StringReader(accessControlListRes.getContentAsString()), null);
+ Assert.assertNotNull(accessControlList);
+ Assert.assertTrue(accessControlList instanceof CMISAccessControlList);
+ CMISObject childObject = entry.entry.getExtension(CMISConstants.OBJECT);
+ Assert.assertNotNull(childObject);
+ String objectId = childObject.getObjectId().getStringValue();
+ Assert.assertNotNull(objectId);
+
+ // Check whether apply ACL is an allowable action
+ CMISAllowableActions objectAllowableActions = childObject.getExtension(CMISConstants.ALLOWABLE_ACTIONS);
+ Assert.assertNotNull(objectAllowableActions);
+ boolean canApplyACL = objectAllowableActions.isAllowed("canApplyACL");
+
+ // Check whether the typedef allows ACL management
+ Link typeLink = entry.entry.getLink(CMISConstants.REL_DESCRIBED_BY);
+ Assert.assertNotNull(typeLink);
+ Entry type = client.getEntry(typeLink.getHref());
+ Assert.assertNotNull(type);
+ CMISTypeDefinition docType = type.getExtension(CMISConstants.TYPE_DEFINITION);
+ Assert.assertNotNull(docType);
+ boolean controllableACL = docType.getControllableACL();
+ if (!controllableACL) {
+ Assert.assertFalse(canApplyACL);
+ }
+ // If we are not allowed to apply the ACL, we should expect an error
+ // status code
+ int expectedStatusMin = 200, expectedStatusMax = 200;
+ if (!canApplyACL) {
+ expectedStatusMin = 400;
+ expectedStatusMax = 499;
+ // Remember the set of rejected types to help with change log
+ // validation
+ rejectedTypes.add(docType.getBaseId());
+ }
+
+ // Convert the ACL to an easy to use form
+ Set<List<Object>> hashedACL = ((CMISAccessControlList) accessControlList).getHashedEntries();
+
+ // Take a back up for future reference
+ Set<List<Object>> originalACL = new HashSet<List<Object>>(hashedACL);
+
+ // Choose some permissions to add in to the ACL
+ CMISACLCapability aclCapability = client.getACLCapability();
+ Assert.assertNotNull(aclCapability);
+ Set<String> repositoryPermissions = new HashSet<String>(aclCapability.getRepositoryPermissions());
+ String supportedPermissions = aclCapability.getSupportedPermissions();
+ CMISRepositoryInfo info = client.getRepositoryInfo();
+
+ // Add some ACES with repository permissions if supported
+ if (!supportedPermissions.equals("basic")) {
+ chooseRepositoryPermission(repositoryPermissions, client.getUserId(), hashedACL);
+ chooseRepositoryPermission(repositoryPermissions, info.getPrincipalAnonymous(), hashedACL);
+ chooseRepositoryPermission(repositoryPermissions, info.getPrincipalAnyone(), hashedACL);
+ }
+
+ // Add some ACES with CMIS permissions if supported
+ if (!supportedPermissions.equals("repository")) {
+ addAce(client.getUserId(), hashedACL, "cmis:write");
+ addAce(info.getPrincipalAnonymous(), hashedACL, "cmis:read");
+ addAce(info.getPrincipalAnyone(), hashedACL, "cmis:read");
+ }
+
+ // Apply the ACL with the additions
+ accessControlList = applyACL(accessControlListLink, hashedACL, expectedStatusMin, expectedStatusMax);
+
+ // If change logging supported + changesOnType includes document, ensure
+ // an entry shows up in the change log and ensure ACL is identical when
+ // includeACL=true
+
+ // If we expected success, try removing the ACEs we added and restoring
+ // the ACL to its original state
+ if (accessControlList != null) {
+ applyACL(accessControlListLink, originalACL, expectedStatusMin, expectedStatusMax);
+ }
+ }
+
+ /**
+ * Gets the set of base types that we have not been able to handle, and thus
+ * do not expect to show in the change log.
+ *
+ * @return the rejected types
+ */
+ public Set<String> getRejectedTypes() {
+ return rejectedTypes;
+ }
+
+ /**
+ * Chooses a repository permission to add to an ACL for a given principal.
+ * Tries to find one that would result in a new entry.
+ *
+ * @param repositoryPermissions
+ * the repository permissions. Permissions are removed as they
+ * are used
+ * @param principalId
+ * the principal id. If <code>null</code> the method returns
+ * immediately.
+ * @param hashedACL
+ * the current state of the ACL. Tries to avoid creating an ACE
+ * that is already present. The ace with the chosen permission is
+ * added to this set
+ *
+ * @return an ACE with the chosen permission or <code>null</code> if it was
+ * not possible to choose one< object>
+ */
+ private static List<Object> chooseRepositoryPermission(Set<String> repositoryPermissions, String principalId,
+ Set<List<Object>> hashedACL) {
+ if (principalId == null) {
+ return null;
+ }
+ List<Object> potential = new ArrayList<Object>(3);
+ potential.add(principalId);
+ potential.add(Boolean.TRUE);
+ for (String permission : repositoryPermissions) {
+ potential.add(permission);
+ if (hashedACL.add(potential)) {
+ repositoryPermissions.remove(permission);
+ return potential;
+ }
+ potential.remove(2);
+ }
+ return null;
+ }
+
+ /**
+ * Adds an ACE for the given principal and permission to the given ACL if it
+ * does not already exist.
+ *
+ * @param principalId
+ * the principal id. If <code>null</code> the method returns
+ * immediately.
+ * @param hashedACL
+ * the current state of the ACL. The ace with the chosen given is
+ * added to this set
+ * @param permission
+ * the permission
+ *
+ * @return an ACE with the permission if it did not already exist in the ACL
+ * or <code>null</code> otherwise
+ */
+ private static List<Object> addAce(String principalId, Set<List<Object>> hashedACL, String permission) {
+ if (principalId == null) {
+ return null;
+ }
+ List<Object> potential = new ArrayList<Object>(3);
+ potential.add(principalId);
+ potential.add(Boolean.TRUE);
+ potential.add(permission);
+ if (hashedACL.add(potential)) {
+ return potential;
+ }
+ return null;
+ }
+
+ /**
+ * Applies the given ACL using the CMIS API.
+ *
+ * @param accessControlListLink
+ * the access control list link
+ * @param hashedACL
+ * the hashed ACL
+ * @param expectedStatusMin
+ * Minimum expected result status code
+ * @param expectedStatusMax
+ * Maximum expected result status code
+ *
+ * @return the resulting access control list
+ *
+ * @throws Exception
+ * on error
+ */
+ private CMISAccessControlList applyACL(Link accessControlListLink, Set<List<Object>> hashedACL,
+ int expectedStatusMin, int expectedStatusMax) throws Exception {
+ StringBuilder buff = new StringBuilder(1024);
+ buff.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append(
+ "<cmis:acl xmlns:cmis=\"http://docs.oasis-open.org/ns/cmis/core/200908/\">");
+ for (List<Object> ace : hashedACL) {
+ buff.append("<cmis:permission><cmis:principal><cmis:principalId>").append(ace.get(0)).append(
+ "</cmis:principalId></cmis:principal><cmis:permission>").append(ace.get(2)).append(
+ "</cmis:permission><cmis:direct>").append(ace.get(1)).append("</cmis:direct></cmis:permission>");
+ }
+ buff.append("</cmis:acl>");
+ String req = buff.toString();
+ client.getAppValidator().validate(new StreamSource(new StringReader(req)));
+ Request putReq = new PutRequest(accessControlListLink.getHref().toString(), req, CMISConstants.MIMETYPE_CMISACL);
+ Response aclRes = client.executeRequest(putReq, expectedStatusMin, expectedStatusMax);
+ Assert.assertNotNull(aclRes);
+ if (aclRes.getStatus() == 200) {
+ Element accessControlList = model.parse(new StringReader(aclRes.getContentAsString()), null);
+ Assert.assertNotNull(accessControlList);
+ Assert.assertTrue(accessControlList instanceof CMISAccessControlList);
+ return (CMISAccessControlList) accessControlList;
+ }
+ return null;
+ }
+}
Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/ManageAccessControlListVisitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/UpdateDocumentsVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/UpdateDocumentsVisitor.java?rev=908938&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/UpdateDocumentsVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/UpdateDocumentsVisitor.java Thu Feb 11 11:44:23 2010
@@ -0,0 +1,53 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ * David Ward, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.apache.chemistry.tck.atompub.http.PutRequest;
+import org.apache.chemistry.tck.atompub.http.Request;
+import org.apache.chemistry.tck.atompub.utils.ResourceLoader;
+import org.apache.commons.codec.binary.Base64;
+
+/**
+ * Visitor that updates all documents in a tree.
+ */
+public class UpdateDocumentsVisitor implements TreeVisitor {
+
+ private CMISClient client;
+ private ResourceLoader templates;
+
+ public UpdateDocumentsVisitor(CMISClient client, ResourceLoader templates) {
+ this.client = client;
+ this.templates = templates;
+ }
+
+ public void visit(EntryTree entry) throws Exception {
+ if (entry.type.equals(CMISConstants.TYPE_DOCUMENT)) {
+ String updateFile = templates.load("updatedocument.cmisatomentry.xml");
+ updateFile = updateFile.replace("${ID}", entry.entry.getId().toString());
+ String guid = String.valueOf(System.currentTimeMillis());
+ updateFile = updateFile.replace("${NAME}", guid);
+ updateFile = updateFile.replace("${CMISCONTENT}", new String(Base64
+ .encodeBase64(("updated content " + guid).getBytes())));
+ Request putReq = new PutRequest(entry.entry.getSelfLink().getHref().toString(), updateFile,
+ CMISConstants.MIMETYPE_ENTRY);
+ client.executeRequest(putReq, 200);
+ }
+ }
+}
Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/UpdateDocumentsVisitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/TCKTestSuite.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/TCKTestSuite.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/TCKTestSuite.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/TCKTestSuite.java Thu Feb 11 11:44:23 2010
@@ -22,6 +22,7 @@
import org.apache.chemistry.tck.atompub.test.spec.AccessControlListTest;
import org.apache.chemistry.tck.atompub.test.spec.AllowableActionsTest;
+import org.apache.chemistry.tck.atompub.test.spec.ChangeLogTest;
import org.apache.chemistry.tck.atompub.test.spec.ContentStreamTest;
import org.apache.chemistry.tck.atompub.test.spec.CreateTest;
import org.apache.chemistry.tck.atompub.test.spec.DeleteTest;
@@ -61,6 +62,7 @@
suite.addTestSuite(AllowableActionsTest.class);
suite.addTestSuite(VersionsTest.class);
suite.addTestSuite(AccessControlListTest.class);
+ suite.addTestSuite(ChangeLogTest.class);
// custom type tests
// TODO: when mechanism for registering custom types is done
Modified: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/AccessControlListTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/AccessControlListTest.java?rev=908938&r1=908937&r2=908938&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/AccessControlListTest.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/AccessControlListTest.java Thu Feb 11 11:44:23 2010
@@ -17,32 +17,22 @@
package org.apache.chemistry.tck.atompub.test.spec;
import java.io.StringReader;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
-
-import javax.xml.transform.stream.StreamSource;
import org.apache.abdera.i18n.iri.IRI;
import org.apache.abdera.model.Element;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Link;
-import org.apache.chemistry.abdera.ext.CMISACLCapability;
-import org.apache.chemistry.abdera.ext.CMISAccessControlEntry;
import org.apache.chemistry.abdera.ext.CMISAccessControlList;
-import org.apache.chemistry.abdera.ext.CMISAllowableActions;
import org.apache.chemistry.abdera.ext.CMISConstants;
import org.apache.chemistry.abdera.ext.CMISObject;
-import org.apache.chemistry.abdera.ext.CMISRepositoryInfo;
-import org.apache.chemistry.abdera.ext.CMISTypeDefinition;
import org.apache.chemistry.abdera.ext.CMISUriTemplate;
import org.apache.chemistry.tck.atompub.TCKSkipCapabilityException;
import org.apache.chemistry.tck.atompub.TCKTest;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree;
+import org.apache.chemistry.tck.atompub.fixture.ManageAccessControlListVisitor;
import org.apache.chemistry.tck.atompub.http.GetRequest;
-import org.apache.chemistry.tck.atompub.http.PutRequest;
import org.apache.chemistry.tck.atompub.http.Request;
import org.apache.chemistry.tck.atompub.http.Response;
import org.junit.Assert;
@@ -87,8 +77,8 @@
Assert.assertNotNull(childObject);
CMISAccessControlList objectAccessControlList = childObject.getExtension(CMISConstants.ACCESS_CONTROL_LIST);
Assert.assertNotNull(objectAccessControlList);
- Assert.assertEquals(hashAccessControlList((CMISAccessControlList) accessControlList),
- hashAccessControlList(objectAccessControlList));
+ Assert.assertEquals(((CMISAccessControlList) accessControlList).getHashedEntries(), objectAccessControlList
+ .getHashedEntries());
}
/**
@@ -126,90 +116,20 @@
Assert.assertNotNull(childObject);
CMISAccessControlList objectAccessControlList = childObject.getExtension(CMISConstants.ACCESS_CONTROL_LIST);
Assert.assertNotNull(objectAccessControlList);
- Assert.assertEquals(hashAccessControlList((CMISAccessControlList) accessControlList),
- hashAccessControlList(objectAccessControlList));
+ Assert.assertEquals(((CMISAccessControlList) accessControlList).getHashedEntries(), objectAccessControlList
+ .getHashedEntries());
}
/**
- * Test manage access control list.
+ * Tests managing the access control lists of a folder and a document
*
* @throws Exception
* on error
*/
public void testManageAccessControlList() throws Exception {
checkACLCapability(true);
- Entry document = fixture.createTestDocument("testManageAccessControlList");
-
- Link accessControlListLink = document.getLink(CMISConstants.REL_ACL);
- Request req = new GetRequest(accessControlListLink.getHref().toString());
- Response accessControlListRes = client.executeRequest(req, 200);
- Assert.assertNotNull(accessControlListRes);
- Element accessControlList = model.parse(new StringReader(accessControlListRes.getContentAsString()), null);
- Assert.assertNotNull(accessControlList);
- Assert.assertTrue(accessControlList instanceof CMISAccessControlList);
- CMISObject childObject = document.getExtension(CMISConstants.OBJECT);
- Assert.assertNotNull(childObject);
- String objectId = childObject.getObjectId().getStringValue();
- Assert.assertNotNull(objectId);
-
- // Check whether apply ACL is an allowable action
- CMISAllowableActions objectAllowableActions = childObject.getExtension(CMISConstants.ALLOWABLE_ACTIONS);
- Assert.assertNotNull(objectAllowableActions);
- boolean canApplyACL = objectAllowableActions.isAllowed("canApplyACL");
-
- // Check whether the typedef allows ACL management
- Link typeLink = document.getLink(CMISConstants.REL_DESCRIBED_BY);
- Assert.assertNotNull(typeLink);
- Entry type = client.getEntry(typeLink.getHref());
- Assert.assertNotNull(type);
- CMISTypeDefinition docType = type.getExtension(CMISConstants.TYPE_DEFINITION);
- Assert.assertNotNull(docType);
- boolean controllableACL = docType.getControllableACL();
- if (!controllableACL) {
- Assert.assertFalse(canApplyACL);
- }
- // If we are not allowed to apply the ACL, we should expect an error
- // status code
- int expectedStatusMin = 200, expectedStatusMax = 200;
- if (!canApplyACL) {
- expectedStatusMin = 400;
- expectedStatusMax = 499;
- }
-
- // Convert the ACL to an easy to use form
- Set<List<Object>> hashedACL = hashAccessControlList((CMISAccessControlList) accessControlList);
-
- // Take a back up for future reference
- Set<List<Object>> originalACL = new HashSet<List<Object>>(hashedACL);
-
- // Choose some permissions to add in to the ACL
- CMISACLCapability aclCapability = client.getACLCapability();
- Assert.assertNotNull(aclCapability);
- Set<String> repositoryPermissions = new HashSet<String>(aclCapability.getRepositoryPermissions());
- String supportedPermissions = aclCapability.getSupportedPermissions();
- CMISRepositoryInfo info = client.getRepositoryInfo();
-
- // Add some ACES with repository permissions if supported
- if (!supportedPermissions.equals("basic")) {
- chooseRepositoryPermission(repositoryPermissions, client.getUserId(), hashedACL);
- chooseRepositoryPermission(repositoryPermissions, info.getPrincipalAnonymous(), hashedACL);
- chooseRepositoryPermission(repositoryPermissions, info.getPrincipalAnyone(), hashedACL);
- }
-
- // Add some ACES with CMIS permissions if supported
- if (!supportedPermissions.equals("repository")) {
- addAce(client.getUserId(), hashedACL, "cmis:write");
- addAce(info.getPrincipalAnonymous(), hashedACL, "cmis:read");
- addAce(info.getPrincipalAnyone(), hashedACL, "cmis:read");
- }
-
- // Apply the ACL with the additions
- accessControlList = applyACL(accessControlListLink, hashedACL, expectedStatusMin, expectedStatusMax);
-
- // If we expected success, try removing the ACEs we added and restoring the ACL to its original state
- if (accessControlList != null) {
- applyACL(accessControlListLink, originalACL, expectedStatusMin, expectedStatusMax);
- }
+ EntryTree folderTree = fixture.createTestTree("testManageAccessControlList", 1, 1, null, null);
+ folderTree.walkTree(new ManageAccessControlListVisitor(client, model));
}
/**
@@ -238,140 +158,4 @@
// Ensure the ACL capability info has been supplied as required
assertNotNull(client.getACLCapability());
}
-
- /**
- * Flattens an access control list into a structure that is easy to compare:
- * a set of triples containing the principal ID, the direct flag and the
- * permission name.
- *
- * @param accessControlList
- * the access control list
- *
- * @return the set of triples
- */
- private static Set<List<Object>> hashAccessControlList(CMISAccessControlList accessControlList) {
- List<CMISAccessControlEntry> entries = accessControlList.getEntries();
- Set<List<Object>> hashSet = new HashSet<List<Object>>(entries.size() * 2);
- for (CMISAccessControlEntry accessControlEntry : entries) {
- String principalId = accessControlEntry.getPrincipalId();
- Boolean direct = accessControlEntry.isDirect();
- for (String permission : accessControlEntry.getPermissions()) {
- List<Object> comparable = new ArrayList<Object>(3);
- comparable.add(principalId);
- comparable.add(direct);
- comparable.add(permission);
- hashSet.add(comparable);
- }
- }
- return hashSet;
- }
-
- /**
- * Chooses a repository permission to add to an ACL for a given principal.
- * Tries to find one that would result in a new entry.
- *
- * @param repositoryPermissions
- * the repository permissions. Permissions are removed as they
- * are used
- * @param principalId
- * the principal id. If <code>null</code> the method returns
- * immediately.
- * @param hashedACL
- * the current state of the ACL. Tries to avoid creating an ACE
- * that is already present. The ace with the chosen permission is
- * added to this set
- *
- * @return an ACE with the chosen permission or <code>null</code> if it was
- * not possible to choose one< object>
- */
- private static List<Object> chooseRepositoryPermission(Set<String> repositoryPermissions, String principalId,
- Set<List<Object>> hashedACL) {
- if (principalId == null) {
- return null;
- }
- List<Object> potential = new ArrayList<Object>(3);
- potential.add(principalId);
- potential.add(Boolean.TRUE);
- for (String permission : repositoryPermissions) {
- potential.add(permission);
- if (hashedACL.add(potential)) {
- repositoryPermissions.remove(permission);
- return potential;
- }
- potential.remove(2);
- }
- return null;
- }
-
- /**
- * Adds an ACE for the given principal and permission to the given ACL if it
- * does not already exist.
- *
- * @param principalId
- * the principal id. If <code>null</code> the method returns
- * immediately.
- * @param hashedACL
- * the current state of the ACL. The ace with the chosen given is
- * added to this set
- * @param permission
- * the permission
- *
- * @return an ACE with the permission if it did not already exist in the ACL
- * or <code>null</code> otherwise
- */
- private static List<Object> addAce(String principalId, Set<List<Object>> hashedACL, String permission) {
- if (principalId == null) {
- return null;
- }
- List<Object> potential = new ArrayList<Object>(3);
- potential.add(principalId);
- potential.add(Boolean.TRUE);
- potential.add(permission);
- if (hashedACL.add(potential)) {
- return potential;
- }
- return null;
- }
-
- /**
- * Applies the given ACL using the CMIS API.
- *
- * @param accessControlListLink
- * the access control list link
- * @param hashedACL
- * the hashed ACL
- * @param expectedStatusMin
- * Minimum expected result status code
- * @param expectedStatusMax
- * Maximum expected result status code
- *
- * @return the resulting access control list
- *
- * @throws Exception
- * on error
- */
- private CMISAccessControlList applyACL(Link accessControlListLink, Set<List<Object>> hashedACL,
- int expectedStatusMin, int expectedStatusMax) throws Exception {
- StringBuilder buff = new StringBuilder(1024);
- buff.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append(
- "<cmis:acl xmlns:cmis=\"http://docs.oasis-open.org/ns/cmis/core/200908/\">");
- for (List<Object> ace : hashedACL) {
- buff.append("<cmis:permission><cmis:principal><cmis:principalId>").append(ace.get(0)).append(
- "</cmis:principalId></cmis:principal><cmis:permission>").append(ace.get(2)).append(
- "</cmis:permission><cmis:direct>").append(ace.get(1)).append("</cmis:direct></cmis:permission>");
- }
- buff.append("</cmis:acl>");
- String req = buff.toString();
- client.getAppValidator().validate(new StreamSource(new StringReader(req)));
- Request putReq = new PutRequest(accessControlListLink.getHref().toString(), req, CMISConstants.MIMETYPE_CMISACL);
- Response aclRes = client.executeRequest(putReq, expectedStatusMin, expectedStatusMax);
- Assert.assertNotNull(aclRes);
- if (aclRes.getStatus() == 200) {
- Element accessControlList = model.parse(new StringReader(aclRes.getContentAsString()), null);
- Assert.assertNotNull(accessControlList);
- Assert.assertTrue(accessControlList instanceof CMISAccessControlList);
- return (CMISAccessControlList) accessControlList;
- }
- return null;
- }
}
Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/ChangeLogTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/ChangeLogTest.java?rev=908938&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/ChangeLogTest.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/ChangeLogTest.java Thu Feb 11 11:44:23 2010
@@ -0,0 +1,165 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ * David Ward, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.test.spec;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.tck.atompub.TCKSkipCapabilityException;
+import org.apache.chemistry.tck.atompub.TCKTest;
+import org.apache.chemistry.tck.atompub.fixture.AssertChangeTypeInChangeLogVisitor;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree;
+import org.apache.chemistry.tck.atompub.fixture.ManageAccessControlListVisitor;
+import org.apache.chemistry.tck.atompub.fixture.UpdateDocumentsVisitor;
+import org.junit.Assert;
+
+/**
+ * CMIS Change Log Tests.
+ */
+public class ChangeLogTest extends TCKTest {
+
+ /**
+ * Tests all change types on documents and folders.
+ *
+ * @throws Exception
+ * on error
+ */
+ public void testDocumentsAndFolders() throws Exception {
+ testDocumentsAndFolders(null);
+ }
+
+ /**
+ * Run the same tests, but with paged change logs.
+ *
+ * @throws Exception
+ * on error
+ */
+ public void testPaging() throws Exception {
+ testDocumentsAndFolders(1);
+ }
+
+ /**
+ * Tests all change types on documents and folders.
+ *
+ * @param maxItems
+ * the maximum number of items per page or <code>null</code> if
+ * unlimited
+ *
+ * @throws Exception
+ * on error
+ */
+ private void testDocumentsAndFolders(Integer maxItems) throws Exception {
+ // Validate the capability
+ checkChangeLogCapability(false);
+
+ // Get the change log token
+ String changeLogToken = client.getRepositoryInfo(true).getLatestChangeLogToken();
+
+ // Create a folder tree
+ EntryTree folderTree = fixture.createTestTree("changeLog", 4, 3, null, null);
+
+ // Fetch changesOnType
+ Set<String> changesOnType = client.getRepositoryInfo().getChangesOnType();
+ assertTrue(changesOnType.size() > 0);
+
+ // Check created entries exist for the objects of applicable types
+ folderTree.walkTree(new AssertChangeTypeInChangeLogVisitor(client, model, changeLogToken, maxItems, false,
+ false, CMISConstants.CHANGE_TYPE_CREATED, changesOnType));
+
+ // Get the new change log token
+ changeLogToken = client.getRepositoryInfo(true).getLatestChangeLogToken();
+ assertNotNull(changeLogToken);
+
+ // Walk the tree and update all the documents
+
+ // TODO: Work out a reliable way of updating folders!
+ // 2.1.11.1: "A Repository MAY record events such as
+ // filing/unfiling/moving of Documents as change events on the
+ // Documents, their parent Folder(s), or both the Documents and the
+ // parent Folders."
+ if (changesOnType.contains(CMISConstants.TYPE_DOCUMENT)) {
+ folderTree.walkTree(new UpdateDocumentsVisitor(client, templates));
+
+ // Check updated entries exist for the document objects
+ folderTree.walkTree(new AssertChangeTypeInChangeLogVisitor(client, model, changeLogToken, maxItems, false,
+ true, CMISConstants.CHANGE_TYPE_UPDATED, Collections.singleton(CMISConstants.TYPE_DOCUMENT)));
+
+ // Get the new change log token
+ changeLogToken = client.getRepositoryInfo(true).getLatestChangeLogToken();
+ assertNotNull(changeLogToken);
+ }
+
+ // Skip security tests if we don't have ACL manage capability
+ String aclCapability = client.getCapabilities().getACL();
+ if (aclCapability.equals("manage")) {
+ // Walk the tree and update all ACLs
+ ManageAccessControlListVisitor visitor = new ManageAccessControlListVisitor(client, model);
+ folderTree.walkTree(visitor);
+
+ // Create a filtered set of change types that we know we should be
+ // able to manage
+ Set<String> filteredChangesOnType = new HashSet<String>(changesOnType);
+ filteredChangesOnType.removeAll(visitor.getRejectedTypes());
+
+ // Check security entries exist for the objects of applicable types
+ // and include the ACL
+ folderTree.walkTree(new AssertChangeTypeInChangeLogVisitor(client, model, changeLogToken, maxItems, true,
+ true, CMISConstants.CHANGE_TYPE_SECURITY, changesOnType));
+
+ // Get the new change log token
+ changeLogToken = client.getRepositoryInfo(true).getLatestChangeLogToken();
+ assertNotNull(changeLogToken);
+ }
+
+ // Delete the tree
+ fixture.delete();
+
+ // Check deleted entries exist for the objects of applicable types
+ folderTree.walkTree(new AssertChangeTypeInChangeLogVisitor(client, model, changeLogToken, maxItems, false,
+ false, CMISConstants.CHANGE_TYPE_DELETED, changesOnType));
+ }
+
+ /**
+ * Check whether we have sufficient capability to read change logs and
+ * optionally their properties.
+ *
+ * @param properties
+ * <code>true</code> if we require properties capability or
+ * <code>false</code> if objectidsonly capability is sufficient.
+ *
+ * @throws TCKSkipCapabilityException
+ * if we don't have sufficient capability
+ * @throws Exception
+ * on error
+ */
+ private void checkChangeLogCapability(boolean properties) throws TCKSkipCapabilityException, Exception {
+ String changesCapability = client.getCapabilities().getChanges();
+ if (properties) {
+ if (!changesCapability.equals("properties") && !changesCapability.equals("all")) {
+ throw new TCKSkipCapabilityException("Changes", "properties", changesCapability);
+ }
+ } else {
+ if (changesCapability.equals("none")) {
+ throw new TCKSkipCapabilityException("Changes", "objectidsonly", changesCapability);
+ }
+ }
+ // Ensure we have some types that will show up in the change log!
+ Assert.assertFalse(client.getRepositoryInfo().getChangesOnType().isEmpty());
+ }
+}
Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/test/spec/ChangeLogTest.java
------------------------------------------------------------------------------
svn:eol-style = native