You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by je...@apache.org on 2011/08/04 08:03:42 UTC

svn commit: r1153760 - in /chemistry/opencmis/trunk: chemistry-opencmis-samples/chemistry-opencmis-hello/src/main/java/org/apache/chemistry/opencmis/doc/ chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/op...

Author: jens
Date: Thu Aug  4 06:03:39 2011
New Revision: 1153760

URL: http://svn.apache.org/viewvc?rev=1153760&view=rev
Log:
Some first step towards ACL support in InMemory [CMIS-414]

Added:
    chemistry/opencmis/trunk/chemistry-opencmis-samples/chemistry-opencmis-hello/src/main/java/org/apache/chemistry/opencmis/doc/QueryTest.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAce.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAcl.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/Permission.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/AclTest.java
Modified:
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryVersioningServiceImpl.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/types/PropertyCreationHelper.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/VersioningTest.java

Added: chemistry/opencmis/trunk/chemistry-opencmis-samples/chemistry-opencmis-hello/src/main/java/org/apache/chemistry/opencmis/doc/QueryTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-samples/chemistry-opencmis-hello/src/main/java/org/apache/chemistry/opencmis/doc/QueryTest.java?rev=1153760&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-samples/chemistry-opencmis-hello/src/main/java/org/apache/chemistry/opencmis/doc/QueryTest.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-samples/chemistry-opencmis-hello/src/main/java/org/apache/chemistry/opencmis/doc/QueryTest.java Thu Aug  4 06:03:39 2011
@@ -0,0 +1,149 @@
+/*
+ * 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.doc;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+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.ItemIterable;
+import org.apache.chemistry.opencmis.client.api.QueryResult;
+import org.apache.chemistry.opencmis.client.api.Repository;
+import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.client.api.SessionFactory;
+import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.SessionParameter;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.enums.BindingType;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
+
+public class QueryTest {
+    private static final String CMIS_ENDPOINT_TEST_SERVER = "http://localhost:8080/inmemory/atom";
+    private Session session;
+    
+    private void getCmisClientSession(){
+        // default factory implementation
+        SessionFactory factory = SessionFactoryImpl.newInstance();
+        Map<String, String> parameters = new HashMap<String, String>();
+        // user credentials
+        parameters.put(SessionParameter.USER, "dummyuser");
+        parameters.put(SessionParameter.PASSWORD, "dummysecret");
+        // connection settings
+        parameters.put(SessionParameter.ATOMPUB_URL, 
+                CMIS_ENDPOINT_TEST_SERVER );
+        parameters.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB 
+                .value());
+        // create session
+        session =  factory.getRepositories(parameters).get(0).createSession();
+    }
+
+    public void createTestArea()
+            throws Exception
+            {
+
+        //creating a new folder
+        Folder root = session.getRootFolder();
+        Map<String, Object> folderProperties = new HashMap<String, Object>();
+        folderProperties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
+        folderProperties.put(PropertyIds.NAME, "testdata");
+
+        Folder newFolder = root.createFolder(folderProperties);
+        //create a new content in the folder
+        String name = "testdata1.txt";
+        // properties
+        // (minimal set: name and object type id)
+        Map<String, Object> contentProperties = new HashMap<String, Object>();
+        contentProperties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
+        contentProperties.put(PropertyIds.NAME, name);
+
+        // content
+        byte[] content = "CMIS Testdata One".getBytes();
+        InputStream stream = new ByteArrayInputStream(content);
+        ContentStream contentStream = new ContentStreamImpl(name, new BigInteger(content), "text/plain", stream);
+
+        // create a major version
+        Document newContent1 =  newFolder.createDocument(contentProperties, contentStream, null);
+        System.out.println("Document created: " + newContent1.getId());
+    }
+
+    private void doQuery() {
+        ItemIterable<QueryResult> results = session.query("SELECT * FROM cmis:folder WHERE cmis:name='testdata'", false);
+        for (QueryResult result : results) {
+            String id = result.getPropertyValueById(PropertyIds.OBJECT_ID);
+            System.out.println("doQuery() found id: " + id);
+        }
+    }
+    
+    public static void main(String args[]) {
+        QueryTest o = new QueryTest();
+        try {
+            o.getCmisClientSession();
+            o.createTestArea();
+            o.doQuery();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    
+    public static void xmain(String args[]) {
+        
+        System.out.println(Hello.class.getName() + " started");
+
+        // Create a SessionFactory and set up the SessionParameter map
+        SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
+        Map<String, String> parameter = new HashMap<String, String>();
+
+        // connection settings - we're connecting to a public cmis repo,
+        // using the AtomPUB binding
+        parameter.put(SessionParameter.ATOMPUB_URL, "http://localhost:8080/inmemory/atom/");
+        parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
+
+        // find all the repositories at this URL - there should only be one.
+        List<Repository> repositories = new ArrayList<Repository>();
+        repositories = sessionFactory.getRepositories(parameter);
+        for (Repository r : repositories) {
+            System.out.println("Found repository: " + r.getName());
+        }
+
+        // create session with the first (and only) repository
+        Repository repository = repositories.get(0);
+        parameter.put(SessionParameter.REPOSITORY_ID, repository.getId());
+        Session session = sessionFactory.createSession(parameter);
+
+        System.out.println("Got a connection to repository: " + repository.getName() + ", with id: "
+                + repository.getId());
+
+//        // Get everything in the root folder and print the names of the objects
+//        Folder root = session.getRootFolder();
+//        ItemIterable<CmisObject> children = root.getChildren();
+//        System.out.println("Found the following objects in the root folder:-");
+//        for (CmisObject o : children) {
+//            System.out.println(o.getName());
+//        }
+//        
+        System.out.println(QueryTest.class.getName() + " ended");
+    }
+}

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java?rev=1153760&r1=1153759&r2=1153760&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java Thu Aug  4 06:03:39 2011
@@ -390,7 +390,7 @@ public class InMemoryNavigationServiceIm
                     ObjectParentDataImpl parentData = new ObjectParentDataImpl();
                     TypeDefinition typeDef = fStoreManager.getTypeById(repositoryId, parent.getTypeId()).getTypeDefinition();
                     ObjectData objData = PropertyCreationHelper.getObjectData(typeDef, parent, filter, user, includeAllowableActions, 
-                            IncludeRelationships.NONE, "", false, true, null);
+                            includeRelationships, "", false, true, null);
 
                     parentData.setObject(objData);
                     parentData.setRelativePathSegment(multiParentObj.getPathSegment());

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryVersioningServiceImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryVersioningServiceImpl.java?rev=1153760&r1=1153759&r2=1153760&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryVersioningServiceImpl.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryVersioningServiceImpl.java Thu Aug  4 06:03:39 2011
@@ -151,7 +151,7 @@ public class InMemoryVersioningServiceIm
             if (!(so instanceof VersionedDocument)) {
               so = validator.getObject(context, repositoryId, objectId, extension);  
               ObjectData objData = getObject(context, repositoryId, objectId, filter, includeAllowableActions,
-                      extension, objectInfos);
+                      IncludeRelationships.NONE,extension, objectInfos);
               res.add(objData);
             }
     
@@ -160,7 +160,7 @@ public class InMemoryVersioningServiceIm
             List<DocumentVersion> versions = verDoc.getAllVersions();
             for (DocumentVersion version : versions) {
                 ObjectData objData = getObject(context, repositoryId, version.getId(), filter, includeAllowableActions,
-                        extension, objectInfos);
+                        IncludeRelationships.NONE,extension, objectInfos);
                 res.add(objData);
             }
 
@@ -188,10 +188,10 @@ public class InMemoryVersioningServiceIm
             VersionedDocument verDoc = (VersionedDocument) so;
             DocumentVersion latestVersion = verDoc.getLatestVersion(major);
             objData = getObject(context, repositoryId, latestVersion.getId(), filter, includeAllowableActions,
-                    extension, objectInfos);
+                    includeRelationships, extension, objectInfos);
         } else if (so instanceof Document) {
-            objData = getObject(context, repositoryId, so.getId(), filter, includeAllowableActions, extension,
-                    objectInfos);
+            objData = getObject(context, repositoryId, so.getId(), filter, includeAllowableActions,
+                    includeRelationships, extension, objectInfos);
         } else {
             throw new CmisInvalidArgumentException("Object is not instance of a document (version series)");
         }
@@ -232,9 +232,10 @@ public class InMemoryVersioningServiceIm
     }
 
     private ObjectData getObject(CallContext context, String repositoryId, String objectId, String filter,
-            Boolean includeAllowableActions, ExtensionsData extension, ObjectInfoHandler objectInfos) {
+            Boolean includeAllowableActions, IncludeRelationships includeRelationships, ExtensionsData extension,
+            ObjectInfoHandler objectInfos) {
 
         return fObjectService.getObject(context, repositoryId, objectId, filter, includeAllowableActions,
-                IncludeRelationships.NONE, null, false, includeAllowableActions, extension, objectInfos);
+                includeRelationships, null, false, includeAllowableActions, extension, objectInfos);
     }
 }

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAce.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAce.java?rev=1153760&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAce.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAce.java Thu Aug  4 06:03:39 2011
@@ -0,0 +1,101 @@
+/*
+ * 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.inmemory.storedobj.impl;
+
+import java.util.List;
+
+import org.apache.chemistry.opencmis.commons.data.Ace;
+
+
+public class InMemoryAce {
+
+    private final String principalId;
+    
+    private Permission permission;
+    
+    public InMemoryAce(Ace commonsAce) {
+        if (null == commonsAce || null == commonsAce.getPrincipalId() || null == commonsAce.getPermissions())
+            throw new IllegalArgumentException("Cannot create InMemoryAce with null value");
+        List<String> perms = commonsAce.getPermissions();
+        if (perms.size() != 1)
+            throw new IllegalArgumentException("InMemory only supports ACEs with a single permission.");
+        String perm = perms.get(0);
+        this.principalId = commonsAce.getPrincipalId();
+        this.permission = Permission.fromCmisString(perm);        
+    }
+
+    public InMemoryAce(String prinicpalId, Permission permission) {
+        if (null == prinicpalId || null == permission)
+            throw new IllegalArgumentException("Cannot create InMemoryAce with null value");
+        
+        this.principalId = prinicpalId;
+        this.permission = permission;        
+    }
+    
+    public String getPrincipalId() {
+        return principalId;
+    }
+    
+    public Permission getPermission() {
+        return permission;
+    }
+    
+    public void setPermission(Permission newPermission) {
+        permission = newPermission;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((permission == null) ? 0 : permission.hashCode());
+        result = prime * result + ((principalId == null) ? 0 : principalId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        InMemoryAce other = (InMemoryAce) obj;
+        if (permission != other.permission)
+            return false;
+        if (principalId == null) {
+            if (other.principalId != null)
+                return false;
+        } else if (!principalId.equals(other.principalId))
+            return false;
+        return true;
+    }
+
+    public boolean hasPermission(Permission permission2) {
+        return this.permission.compareTo(permission2) >= 0;
+    }
+
+    @Override
+    public String toString() {
+        return "InMemoryAce [principalId=" + principalId + ", permission=" + permission + "]";
+    }
+
+    
+}

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAcl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAcl.java?rev=1153760&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAcl.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/InMemoryAcl.java Thu Aug  4 06:03:39 2011
@@ -0,0 +1,171 @@
+/*
+ * 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.inmemory.storedobj.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.chemistry.opencmis.commons.data.Ace;
+import org.apache.chemistry.opencmis.commons.data.Acl;
+
+public class InMemoryAcl {
+    
+    private List<InMemoryAce> acl;
+    
+    private static class AceComparator<T extends InMemoryAce> implements Comparator<T> {
+
+        public int compare(T o1, T o2) {            
+            int res = o1.getPrincipalId().compareTo(o2.getPrincipalId());
+            return res;
+        }
+        
+    };
+    
+    private static Comparator<? super InMemoryAce> COMP = new AceComparator<InMemoryAce>();
+    
+    public static InMemoryAcl createFromCommonsAcl(Acl commonsAcl) {
+        InMemoryAcl acl = new InMemoryAcl();
+        for (Ace cace : commonsAcl.getAces()) {
+            if (acl.hasPrincipal(cace.getPrincipalId())) {
+                Permission perm = acl.getPermission(cace.getPrincipalId());
+                Permission newPerm = Permission.fromCmisString(cace.getPermissions().get(0));
+                if (perm.ordinal() > newPerm.ordinal())
+                    acl.setPermission(cace.getPrincipalId(), newPerm);
+            } else {
+                acl.addAce(new InMemoryAce(cace));
+            }
+            
+        }
+        return acl;
+    }
+
+
+    public InMemoryAcl() {
+        acl = new ArrayList<InMemoryAce>(3);
+    }
+
+    public InMemoryAcl(final List<InMemoryAce> arg ) {        
+        this.acl = new ArrayList<InMemoryAce>(arg);
+        Collections.sort(this.acl, COMP);
+        for (int i=0 ; i<acl.size(); i++) {
+            InMemoryAce ace = acl.get(i);
+            if (ace == null)
+                throw new IllegalArgumentException("Cannot create ACLs with a null principal id or permission.");        
+        }
+        for (int i=0 ; i<acl.size()-1; i++) {
+            if (acl.get(i).equals(acl.get(i+1)))
+                throw new IllegalArgumentException("Cannot create ACLs with same principal id in more than one ACE.");
+        }
+    }
+    
+    public final List<InMemoryAce> getAces() {
+        return acl;
+    }
+    
+    public boolean addAce(InMemoryAce ace) {
+        if (ace == null)
+            return false;
+        for (InMemoryAce ace2: acl) {
+            if (ace2.getPrincipalId().equals(ace.getPrincipalId()))
+                return false;
+        }
+        acl.add(ace);
+        Collections.sort(acl, COMP);
+        return true;
+    }
+    
+    public boolean removeAce(InMemoryAce ace) {
+        return acl.remove(ace);
+    }
+    
+    public Permission getPermission(String principalId) {
+        if (null == principalId)
+            return null;
+        
+        for (InMemoryAce ace : acl) {
+            if (ace.getPrincipalId().equals(principalId))
+                return ace.getPermission();
+        }
+        return Permission.NONE;
+    }
+
+    public boolean hasPermission(String principalId, Permission permission) {
+        if (null == principalId || null == permission)
+            return false;
+        
+        for (InMemoryAce ace : acl) {
+            if (ace.getPrincipalId().equals(principalId))
+                return ace.hasPermission(permission);
+        }
+        return false;
+    }
+
+    public void setPermission(String principalId, Permission permission) {        
+        for (InMemoryAce ace : acl) {
+            if (ace.getPrincipalId().equals(principalId))
+                ace.setPermission(permission);
+        }
+        throw new IllegalArgumentException("Unknown principalId in setPermission: " + principalId);
+    }
+   
+    public int size() {
+        return acl.size();
+    }
+     
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((acl == null) ? 0 : acl.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        InMemoryAcl other = (InMemoryAcl) obj;
+        if (acl == null) {
+            if (other.acl != null)
+                return false;
+        } else if (!acl.equals(other.acl))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "InMemoryAcl [acl=" + acl + "]";
+    }
+            
+    private boolean hasPrincipal(String principalId) {
+        for (InMemoryAce ace: acl) {
+            if (ace.getPrincipalId().equals(principalId))
+                return true;
+        }
+        return false;
+    }
+
+}

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/Permission.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/Permission.java?rev=1153760&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/Permission.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/Permission.java Thu Aug  4 06:03:39 2011
@@ -0,0 +1,60 @@
+/*
+ * 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.inmemory.storedobj.impl;
+
+
+public enum Permission {
+    NONE("none"),
+    READ("read"),
+    WRITE("write"),
+    ALL("all");
+    
+    private final String value;
+    
+    Permission(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static Permission fromValue(String v) {
+        for (Permission c : Permission.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+    
+    public static Permission fromCmisString(String strPerm) {
+        Permission permission;
+        if (strPerm.equals("cmis:read")) 
+            permission = Permission.READ;
+        else if (strPerm.equals("cmis:write")) 
+            permission = Permission.WRITE;
+        else if (strPerm.equals("cmis:all")) 
+            permission = Permission.ALL;
+        else
+            throw new IllegalArgumentException("InMemory only supports CMIS basic permissions read, write, all.");
+        return permission;
+     }
+
+}

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/types/PropertyCreationHelper.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/types/PropertyCreationHelper.java?rev=1153760&r1=1153759&r2=1153760&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/types/PropertyCreationHelper.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/types/PropertyCreationHelper.java Thu Aug  4 06:03:39 2011
@@ -334,6 +334,9 @@ public class PropertyCreationHelper {
             od.setAllowableActions(allowableActions);
         }
 
+        od.setAcl(so.getAcl());
+        od.setIsExactAcl(true);
+        
         if (null != includeRelationships && includeRelationships != IncludeRelationships.NONE) {
             od.setRelationships(DataObjectCreator.fillRelationships(includeRelationships, so, user));
         }

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/AclTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/AclTest.java?rev=1153760&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/AclTest.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/AclTest.java Thu Aug  4 06:03:39 2011
@@ -0,0 +1,232 @@
+/*
+ * 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.inmemory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.chemistry.opencmis.commons.data.Ace;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
+import org.apache.chemistry.opencmis.inmemory.storedobj.impl.InMemoryAce;
+import org.apache.chemistry.opencmis.inmemory.storedobj.impl.InMemoryAcl;
+import org.apache.chemistry.opencmis.inmemory.storedobj.impl.Permission;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Test;
+
+public class AclTest {
+
+    private static final Log LOG = LogFactory.getLog(AclTest.class);
+
+    final static String ANDREAS = "andreas";
+    final static String BERTA = "berta";
+    final static String CHRISTIAN = "christian";
+    final static String DOROTHEE = "dorothee";
+    
+    final InMemoryAce aceN = new InMemoryAce(ANDREAS, Permission.NONE);
+    final InMemoryAce aceR = new InMemoryAce(BERTA, Permission.READ);
+    final InMemoryAce aceW = new InMemoryAce(CHRISTIAN, Permission.WRITE);
+    final InMemoryAce aceA = new InMemoryAce(DOROTHEE, Permission.ALL);
+
+    @Test
+    public void testCreateAce() {
+        InMemoryAce ace;
+        try {
+            ace = new InMemoryAce(null, Permission.NONE);
+            fail("create an ACE with null principalId should fail.");
+        } catch (RuntimeException e) {            
+        }
+
+        try {
+            ace = new InMemoryAce("xxx", null);
+            fail("create an ACE with null permission should fail.");
+        } catch (RuntimeException e) {            
+        }
+
+    }
+    
+    @Test
+    public void testCreate() {
+    
+        InMemoryAcl acl = new InMemoryAcl();
+        acl.addAce(aceA);
+        assertEquals(1, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceA);
+    
+        acl = new InMemoryAcl(createAceList());
+        LOG.debug(acl);
+        
+        assertEquals(2, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceR);
+        assertTrue(acl.getAces().get(1) == aceA);
+    
+        acl = createDefaultAcl();
+        checkDefaultAcl(acl);
+        
+        try {
+            List<InMemoryAce> aces = createAceList();
+            aces.add(null);
+            acl = new InMemoryAcl(aces);
+            fail("create an ACL with a null ACE should fail.");
+        } catch (RuntimeException e) {            
+        }
+    }
+    
+    @Test
+    public void testAdd() {
+        InMemoryAcl acl = new InMemoryAcl();
+        acl.addAce(aceR);
+        assertEquals(1, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceR);
+        acl.addAce(aceW);
+        assertEquals(2, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceR);
+        assertTrue(acl.getAces().get(1) == aceW);
+        acl.addAce(aceN);
+        assertEquals(3, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceN);
+        assertTrue(acl.getAces().get(1) == aceR);
+        assertTrue(acl.getAces().get(2) == aceW);
+        acl.addAce(aceA);
+        assertEquals(4, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceN);
+        assertTrue(acl.getAces().get(1) == aceR);
+        assertTrue(acl.getAces().get(2) == aceW);
+        assertTrue(acl.getAces().get(3) == aceA);    
+
+        assertFalse("Adding an existing ACE to an ACL should fail.", acl.addAce(aceN));
+        assertFalse("Adding null to an ACL should fail.", acl.addAce(null));
+    }
+    
+    @Test
+    public void testRemove() {
+        InMemoryAcl acl = createDefaultAcl();
+        checkDefaultAcl(acl);
+
+        acl.removeAce(aceR);
+        assertEquals(3, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceN);
+        assertTrue(acl.getAces().get(1) == aceW);
+        assertTrue(acl.getAces().get(2) == aceA);
+        acl.removeAce(aceW);
+        assertEquals(2, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceN);
+        assertTrue(acl.getAces().get(1) == aceA);
+        acl.removeAce(aceN);
+        assertEquals(1, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceA);
+        acl.removeAce(aceA);
+        assertEquals(0, acl.getAces().size());
+        
+        acl = createDefaultAcl();
+        final InMemoryAce ace = new InMemoryAce("xyu", Permission.ALL);
+        assertFalse("Removing an unknown ACE from an ACL should fail.", acl.removeAce(ace));
+        assertFalse("Removing null from an ACL should fail.", acl.removeAce(null));
+    }
+
+    @Test
+    public void testAclEquality() {
+        final InMemoryAce aceNew = new InMemoryAce("Hugo", Permission.WRITE);
+        final InMemoryAce aceRCopy = new InMemoryAce(BERTA, Permission.READ);
+
+        InMemoryAcl acl1 = createDefaultAcl();
+        InMemoryAcl acl2 = new InMemoryAcl(new ArrayList<InMemoryAce>() {{ add(aceRCopy); add(aceA);  add(aceW);  add(aceN); }});
+        InMemoryAcl acl3 = new InMemoryAcl(new ArrayList<InMemoryAce>() {{ add(aceR); add(aceNew);  add(aceW);  add(aceN); }});
+        assertEquals(acl1, acl2);
+        assertFalse(acl1.equals(acl3));      
+    }
+    
+    
+    @Test
+    public void testCheckPermissions() {
+        InMemoryAcl acl = createDefaultAcl();
+
+        assertTrue(acl.hasPermission(ANDREAS, Permission.NONE));
+        assertFalse(acl.hasPermission(ANDREAS, Permission.READ));
+        assertFalse(acl.hasPermission(ANDREAS, Permission.WRITE));
+        assertFalse(acl.hasPermission(ANDREAS, Permission.ALL));
+
+        assertTrue(acl.hasPermission(BERTA, Permission.NONE));
+        assertTrue(acl.hasPermission(BERTA, Permission.READ));
+        assertFalse(acl.hasPermission(BERTA, Permission.WRITE));
+        assertFalse(acl.hasPermission(BERTA, Permission.ALL));
+    
+        assertTrue(acl.hasPermission(CHRISTIAN, Permission.NONE));
+        assertTrue(acl.hasPermission(CHRISTIAN, Permission.READ));
+        assertTrue(acl.hasPermission(CHRISTIAN, Permission.WRITE));
+        assertFalse(acl.hasPermission(CHRISTIAN, Permission.ALL));
+
+        assertTrue(acl.hasPermission(DOROTHEE, Permission.NONE));
+        assertTrue(acl.hasPermission(DOROTHEE, Permission.READ));
+        assertTrue(acl.hasPermission(DOROTHEE, Permission.WRITE));
+        assertTrue(acl.hasPermission(DOROTHEE, Permission.ALL));
+    }
+
+    @Test
+    public void testConvertFomCmisAcl() {
+        List<Ace> aces = Arrays.asList(new Ace[] { createAce(ANDREAS, "cmis:read"), createAce(DOROTHEE, "cmis:write") });
+        AccessControlListImpl cAcl = new AccessControlListImpl(aces);
+        InMemoryAcl acl = InMemoryAcl.createFromCommonsAcl(cAcl);        
+        assertEquals(2, acl.size());
+        assertEquals(Permission.READ, acl.getPermission(ANDREAS));
+        assertEquals(Permission.WRITE, acl.getPermission(DOROTHEE));
+        
+        try {
+            List<Ace> aces2 = Arrays.asList(new Ace[] { new AccessControlEntryImpl(null,  Arrays.asList(new String[] { "cmis:read"}))});
+            acl = InMemoryAcl.createFromCommonsAcl(new AccessControlListImpl(aces2));
+            fail("create Ace will null principal should raise exception.");
+        } catch (RuntimeException e) { }
+        try {
+            List<Ace> aces2 = Arrays.asList(new Ace[] { new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(ANDREAS),  null)});
+            acl = InMemoryAcl.createFromCommonsAcl(new AccessControlListImpl(aces2));
+            fail("create Ace will null permission should raise exception.");
+        } catch (RuntimeException e) { }
+    }
+    
+    private InMemoryAcl createDefaultAcl() {
+        return  new InMemoryAcl(new ArrayList<InMemoryAce>() {{ add(aceA); add(aceR);  add(aceN);  add(aceW); }});
+    }
+    
+    private void checkDefaultAcl(InMemoryAcl acl) {
+        assertEquals(4, acl.getAces().size());
+        assertTrue(acl.getAces().get(0) == aceN);
+        assertTrue(acl.getAces().get(1) == aceR);
+        assertTrue(acl.getAces().get(2) == aceW);
+        assertTrue(acl.getAces().get(3) == aceA);        
+    }
+
+    private List<InMemoryAce> createAceList() {
+        return new ArrayList<InMemoryAce>() {{ add(aceA); add(aceR); }};
+    }
+    
+    private Ace createAce(String principalId, String permission) {
+        AccessControlEntryImpl ace = new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(principalId),
+                Arrays.asList(new String[] { permission }));
+        return ace;
+    }
+
+}

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/VersioningTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/VersioningTest.java?rev=1153760&r1=1153759&r2=1153760&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/VersioningTest.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/VersioningTest.java Thu Aug  4 06:03:39 2011
@@ -548,7 +548,7 @@ public class VersioningTest extends Abst
         assertEquals(versioningState == VersioningState.CHECKEDOUT, bVal);
 
         PropertyString pds = (PropertyString) props.get(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY);
-        assertNotNull(pdb);
+        assertNotNull(pds);
         sVal = pds.getFirstValue();
         if (versioningState == VersioningState.CHECKEDOUT) {
             assertTrue(sVal != null && sVal.length() > 0);