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 2010/02/24 15:58:09 UTC

svn commit: r915814 [1/2] - in /incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src: main/java/org/apache/opencmis/inmemory/ main/java/org/apache/opencmis/inmemory/server/ main/java/org/apache/opencmis/inmemory/storedobj/api...

Author: jens
Date: Wed Feb 24 14:58:07 2010
New Revision: 915814

URL: http://svn.apache.org/viewvc?rev=915814&view=rev
Log:
CMIS-125 
Add support for unfiled and multifiled documents in OpenCMIS InMemory impl

Added:
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Filing.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/MultiFiling.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/SingleFiling.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractMultiFilingImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractSingleFilingImpl.java
Removed:
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Path.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractPathImpl.java
Modified:
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MultiFilingServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/AtomLinkInfoProvider.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Document.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/DocumentVersion.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Folder.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/VersionedDocument.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentVersionImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/FolderImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/ObjectStoreImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/StoreManagerImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/VersionedDocumentImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/AbstractServiceTst.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/FolderTest.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/MultiFilingTest.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/NavigationServiceTest.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/ObjectServiceTest.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/RepositoryServiceTest.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/TypeValidationTest.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/UnitTestTypeSystemCreator.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/VersioningTest.java

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MultiFilingServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MultiFilingServiceImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MultiFilingServiceImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MultiFilingServiceImpl.java Wed Feb 24 14:58:07 2010
@@ -19,8 +19,14 @@
 package org.apache.opencmis.inmemory;
 
 import org.apache.opencmis.commons.api.ExtensionsData;
+import org.apache.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.opencmis.commons.exceptions.CmisNotSupportedException;
 import org.apache.opencmis.commons.provider.MultiFilingService;
+import org.apache.opencmis.inmemory.storedobj.api.Folder;
+import org.apache.opencmis.inmemory.storedobj.api.MultiFiling;
+import org.apache.opencmis.inmemory.storedobj.api.ObjectStore;
 import org.apache.opencmis.inmemory.storedobj.api.StoreManager;
+import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
 
 public class MultiFilingServiceImpl extends AbstractServiceImpl implements MultiFilingService {
 
@@ -30,14 +36,54 @@
 
   public void addObjectToFolder(String repositoryId, String objectId, String folderId,
       Boolean allVersions, ExtensionsData extension) {
-    // TODO Auto-generated method stub
 
+    checkParams(repositoryId, objectId, folderId);
+    if (allVersions != null && allVersions.booleanValue() == false)
+      throw new CmisNotSupportedException(
+          "Cannot add object to folder, version specific filing is not supported.");
+    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = objectStore.getObjectById(objectId);
+    StoredObject folder = objectStore.getObjectById(folderId);
+    checkObjects(so, folder);
+    
+    Folder newParent = (Folder) folder;
+    MultiFiling obj = (MultiFiling) so;
+    obj.addParent(newParent);
   }
 
   public void removeObjectFromFolder(String repositoryId, String objectId, String folderId,
       ExtensionsData extension) {
-    // TODO Auto-generated method stub
+    checkStandardParameters(repositoryId, objectId);
+    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+    checkExistingObjectId(objectStore, folderId);
+
+    StoredObject so = objectStore.getObjectById(objectId);
+    StoredObject folder = objectStore.getObjectById(folderId);
+    checkObjects(so, folder);
+    Folder parent = (Folder) folder;
+    MultiFiling obj = (MultiFiling) so;
+    obj.removeParent(parent);   
+  }
 
+  private void checkParams(String repositoryId, String objectId, String folderId) {
+    checkStandardParameters(repositoryId, objectId);
+    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+    checkExistingObjectId(objectStore, folderId);    
+  }
+  
+  private void checkObjects(StoredObject so, StoredObject folder) {
+    if (!(so instanceof MultiFiling))
+      throw new CmisConstraintException("Cannot add object to folder, object id " + so.getId()
+          + " is not a multi-filed object.");
+
+    if ((so instanceof Folder))
+      throw new CmisConstraintException("Cannot add object to folder, object id " + folder.getId()
+          + " is a folder and folders are not multi-filed.");
+
+    if (!(folder instanceof Folder))
+      throw new CmisConstraintException("Cannot add object to folder, folder id " + folder.getId()
+          + " does not refer to a folder.");    
   }
 
+  
 }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java Wed Feb 24 14:58:07 2010
@@ -48,8 +48,10 @@
 import org.apache.opencmis.inmemory.storedobj.api.Children;
 import org.apache.opencmis.inmemory.storedobj.api.DocumentVersion;
 import org.apache.opencmis.inmemory.storedobj.api.Folder;
+import org.apache.opencmis.inmemory.storedobj.api.MultiFiling;
 import org.apache.opencmis.inmemory.storedobj.api.ObjectStore;
-import org.apache.opencmis.inmemory.storedobj.api.Path;
+import org.apache.opencmis.inmemory.storedobj.api.Filing;
+import org.apache.opencmis.inmemory.storedobj.api.SingleFiling;
 import org.apache.opencmis.inmemory.storedobj.api.StoreManager;
 import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
 import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
@@ -208,7 +210,6 @@
   /* (non-Javadoc)
    * @see org.opencmis.client.provider.NavigationService#getObjectParents(java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean, org.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean, org.opencmis.client.provider.ExtensionsData)
    */
-  @SuppressWarnings("unchecked")
   public List<ObjectParentData> getObjectParents(String repositoryId, String objectId,
       String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
       String renditionFilter, Boolean includeRelativePathSegment, ExtensionsData extension) {
@@ -218,31 +219,22 @@
 
     // for now we have only folders that have a parent and the in-memory provider only has one
     // parent for each object (no multi-filing)
-    ObjectParentDataImpl result = null;
+    List<ObjectParentData> result = null;
     ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
     
     StoredObject so = fs.getObjectById(objectId);
-    Path spo = null;
-    
-    if (so instanceof Path)
-      spo = (Path) so;
+    Filing spo = null;
+        
+    if (so instanceof Filing)
+      spo = (Filing) so;
     else
       throw new CmisInvalidArgumentException("Can't get object parent, id does not refer to a folder or document: "
           + objectId);
     
-    if (null != spo) {
-      ObjectData parents = getFolderParentIntern(repositoryId, spo, filter);
-      if (null != parents) {
-        result = new ObjectParentDataImpl();
-        result.setObject(parents);
-        String path = spo.getPath();
-        int beginIndex = path.lastIndexOf(Path.PATH_SEPARATOR)+1; // Note: if / not found results in 0
-        String relPathSeg = path.substring(beginIndex, path.length());
-        result.setRelativePathSegment(relPathSeg);
-      }
-    }
+    result = getObjectParentsIntern(repositoryId, spo, filter);
+    
     log.debug("stop getObjectParents()");
-    return null == result ? (List<ObjectParentData>) Collections.EMPTY_LIST : Collections.singletonList((ObjectParentData)result);
+    return result;
   }
 
   // private helpers
@@ -332,7 +324,41 @@
     return childrenOfFolderId;
   }
 
-  private ObjectData getFolderParentIntern(String repositoryId, Path sop,
+  private  List<ObjectParentData> getObjectParentsIntern(String repositoryId, Filing sop,
+      String filter) {
+    
+    List<ObjectParentData> result = null;
+    if (sop instanceof SingleFiling) {
+      ObjectData parent = getFolderParentIntern(repositoryId, (SingleFiling)sop, filter);
+      if (null != parent) {
+        ObjectParentDataImpl parentData = new ObjectParentDataImpl();
+        parentData.setObject(parent);
+        String path = ((SingleFiling)sop).getPath();
+        int beginIndex = path.lastIndexOf(Filing.PATH_SEPARATOR)+1; // Note: if / not found results in 0
+        String relPathSeg = path.substring(beginIndex, path.length());
+        parentData.setRelativePathSegment(relPathSeg);
+        result = Collections.singletonList((ObjectParentData)parentData);
+      }
+      else
+        result = Collections.emptyList();
+    } else if (sop instanceof MultiFiling) {
+      result = new ArrayList<ObjectParentData>();
+      MultiFiling multiParentObj = (MultiFiling) sop;
+      List<Folder> parents = multiParentObj.getParents();
+      if (null != parents)
+        for (Folder parent : parents) {
+          ObjectParentDataImpl parentData = new ObjectParentDataImpl();
+          ObjectDataImpl objData = new ObjectDataImpl();
+          copyFilteredProperties(repositoryId, parent, filter, objData);
+          parentData.setObject(objData);
+          parentData.setRelativePathSegment(multiParentObj.getPathSegment());
+          result.add(parentData);
+        }      
+    }
+    return result;
+  }
+  
+  private ObjectData getFolderParentIntern(String repositoryId, SingleFiling sop,
       String filter) {
 
     ObjectDataImpl parent = new ObjectDataImpl();
@@ -346,11 +372,16 @@
         return null; // an unfiled document
     }
     
-    List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
-    PropertiesData props = PropertyCreationHelper.getPropertiesFromObject(repositoryId,
-        parentFolder, fStoreManager, requestedIds);
-    parent.setProperties(props);
+    copyFilteredProperties(repositoryId, parentFolder, filter, parent);
     return parent;
   }
+  
+  void copyFilteredProperties(String repositoryId, StoredObject so, String filter,
+      ObjectDataImpl objData) {
+    List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
+    PropertiesData props = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so,
+        fStoreManager, requestedIds);
+    objData.setProperties(props);
+  }
 
 }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java Wed Feb 24 14:58:07 2010
@@ -58,7 +58,8 @@
 import org.apache.opencmis.inmemory.storedobj.api.DocumentVersion;
 import org.apache.opencmis.inmemory.storedobj.api.Folder;
 import org.apache.opencmis.inmemory.storedobj.api.ObjectStore;
-import org.apache.opencmis.inmemory.storedobj.api.Path;
+import org.apache.opencmis.inmemory.storedobj.api.Filing;
+import org.apache.opencmis.inmemory.storedobj.api.SingleFiling;
 import org.apache.opencmis.inmemory.storedobj.api.StoreManager;
 import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
 import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
@@ -597,12 +598,12 @@
     Folder sourceFolder = null;
     ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
     StoredObject so = folderStore.getObjectById(objectId.getValue());
-    Path spo = null;
+    Filing spo = null;
 
     if (null == so)
       throw new CmisObjectNotFoundException("Unknown object: " + objectId.getValue());
-    else if (so instanceof Path)
-      spo = (Path) so;
+    else if (so instanceof Filing)
+      spo = (Filing) so;
     else
       throw new CmisInvalidArgumentException("Object must be folder or document: "
           + objectId.getValue());
@@ -623,9 +624,16 @@
     else
       throw new CmisNotSupportedException("Source " + sourceFolderId + " of a move operation must be a folder");
 
-    if (spo.getParent() != soSource)
+    boolean foundOldParent = false;
+    for (Folder parent: spo.getParents()) {
+      if (parent.getId().equals(soSource.getId())) {
+        foundOldParent = true;
+        break;
+      }
+    }
+    if (!foundOldParent)
       throw new CmisNotSupportedException("Cannot move object, source folder " + sourceFolderId + "is not a parent of object " + objectId.getValue());
-      
+    
     if (so instanceof Folder && hasDescendant((Folder) so, targetFolder)) {
       throw new CmisNotSupportedException(
           "Destination of a move cannot be a subfolder of the source");
@@ -771,15 +779,17 @@
     // get name from properties and perform special rename to check if path
     // already exists
     PropertyData<?> pd = properties.getProperties().get(PropertyIds.CMIS_NAME);
-    if (pd != null && so instanceof Path) {
-      Folder parent = ((Path) so).getParent();
-      if (parent == null)
+    if (pd != null && so instanceof Filing) {
+      String newName = (String) pd.getFirstValue();
+      List<Folder> parents = ((Filing) so).getParents();
+      if (so instanceof Folder && parents.isEmpty())
         throw new CmisConstraintException(
             "updateProperties failed, you cannot rename the root folder");
-      if (parent.hasChild((String) pd.getFirstValue()))
-        throw new CmisConstraintException(
-            "updateProperties failed, cannot rename because path already exists.");
-
+      for (Folder parent : parents) {
+        if (parent.hasChild(newName))
+          throw new CmisConstraintException(
+              "updateProperties failed, cannot rename because path already exists.");
+      }
       so.rename((String) pd.getFirstValue()); // note: this does persist
       hasUpdatedName = true;
     }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/AtomLinkInfoProvider.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/AtomLinkInfoProvider.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/AtomLinkInfoProvider.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/AtomLinkInfoProvider.java Wed Feb 24 14:58:07 2010
@@ -30,7 +30,8 @@
 import org.apache.opencmis.inmemory.storedobj.api.Content;
 import org.apache.opencmis.inmemory.storedobj.api.DocumentVersion;
 import org.apache.opencmis.inmemory.storedobj.api.ObjectStore;
-import org.apache.opencmis.inmemory.storedobj.api.Path;
+import org.apache.opencmis.inmemory.storedobj.api.Filing;
+import org.apache.opencmis.inmemory.storedobj.api.SingleFiling;
 import org.apache.opencmis.inmemory.storedobj.api.StoreManager;
 import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
 import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
@@ -116,9 +117,9 @@
     }
     
     // Filing
-    if (so instanceof Path) {
-      Path sop = ((Path)so);
-      objInfo.setHasParent(sop.getParent()!= null);
+    if (so instanceof Filing) {
+      Filing sop = ((Filing)so);
+      objInfo.setHasParent(!sop.getParents().isEmpty());
     } else {
       objInfo.setHasParent(false);      
     }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Document.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Document.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Document.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Document.java Wed Feb 24 14:58:07 2010
@@ -27,7 +27,7 @@
  *
  */
 
-public interface Document extends StoredObject, Path, Content {
+public interface Document extends StoredObject, MultiFiling, Content {
 
 }
 

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/DocumentVersion.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/DocumentVersion.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/DocumentVersion.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/DocumentVersion.java Wed Feb 24 14:58:07 2010
@@ -27,6 +27,6 @@
  * @author Jens
  *
  */
-public interface DocumentVersion extends Version, Content, StoredObject, Path {
+public interface DocumentVersion extends Version, Content, StoredObject, MultiFiling {
 
 }

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Filing.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Filing.java?rev=915814&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Filing.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Filing.java Wed Feb 24 14:58:07 2010
@@ -0,0 +1,58 @@
+/*
+ * 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.opencmis.inmemory.storedobj.api;
+
+import java.util.List;
+
+
+/**
+ * Path is the capability of an object to get accessed by a path in addition to the identifier.
+ * Paths are hierarchical, each object with a path has a parent where the parent is always a 
+ * folder. Paths do not exist on its own but are part of other objects (documents and folders).
+ * Most of the functionality is defined in interfaces that are subclasses.
+ * 
+ * @author Jens
+ */
+public interface Filing {
+
+  /**
+   * character indicating how folders are separated within a path string. This char must not be a
+   * valid character of an object name.
+   */
+  public static final String PATH_SEPARATOR = "/";
+
+  /**
+   * return a list of parents. for single parent object this list must contain
+   * only one element. returns an empty list if this is an unfiled document.
+   * 
+   * @return
+   *    list of parent folders
+   */
+  List<Folder> getParents();
+  
+  /**
+   * Move an object to a different folder. Source and target object are persisted in this 
+   * call as part of a transactional step.
+   *  
+   * @param newParent
+   *    new parent folder for the object
+   */
+  public void move(Folder oldParent, Folder newParent);
+  
+}
\ No newline at end of file

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Folder.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Folder.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Folder.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/Folder.java Wed Feb 24 14:58:07 2010
@@ -29,7 +29,7 @@
  *
  */
 
-public interface Folder extends Children, Path, StoredObject {
+public interface Folder extends Children, SingleFiling, StoredObject {
   
   /**
    * return a list of allowed types of children in this folder

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/MultiFiling.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/MultiFiling.java?rev=915814&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/MultiFiling.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/MultiFiling.java Wed Feb 24 14:58:07 2010
@@ -0,0 +1,53 @@
+/*
+ * 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.opencmis.inmemory.storedobj.api;
+
+import java.util.List;
+
+/**
+ * Documents can have in the CMIS specification multiple parents. This interface describes
+ * the behavior of objects with multiple parent objects.
+ * 
+ * @author Jens
+ *
+ */
+public interface MultiFiling extends Filing {
+
+  /**
+   * retrieve the path segment of this folder
+   * @return
+   */
+  String getPathSegment();
+
+  /** 
+   * Add this document to a new parent folder as child object
+   * 
+   * @param parent
+   *    new parent folder of the document.
+   */
+  void addParent(Folder parent);
+  
+  /**
+   * Remove this object from the children of parent
+   * 
+   * @param parent
+   *    parent folder of the document
+   */
+  void removeParent(Folder parent);
+}

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/SingleFiling.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/SingleFiling.java?rev=915814&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/SingleFiling.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/SingleFiling.java Wed Feb 24 14:58:07 2010
@@ -0,0 +1,49 @@
+/*
+ * 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.opencmis.inmemory.storedobj.api;
+
+/**
+ * Folders have in the CMIS specification exactly one parent. This interface describes
+ * the behavior of objects with a single parent object.
+ * 
+ * @author Jens
+ *
+ */
+public interface SingleFiling extends Filing {
+
+  /**
+   * @return
+   */
+  String getPath();
+
+  /**
+   * @return
+   */
+  Folder getParent();
+
+  /** Put the document in a folder and set the parent. This method should not 
+   * be used to file a document in a folder. It is used internally when a document
+   * is filed to the folder. The document does not get persisted in this call.
+   * 
+   * @param parent
+   *    parent folder of the document to be assigned.
+   */
+  void setParent(Folder parent);
+  
+}

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/VersionedDocument.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/VersionedDocument.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/VersionedDocument.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/api/VersionedDocument.java Wed Feb 24 14:58:07 2010
@@ -32,7 +32,7 @@
  * @author Jens
  *
  */
-public interface VersionedDocument extends Path, StoredObject {
+public interface VersionedDocument extends MultiFiling, StoredObject {
   
   DocumentVersion addVersion(ContentStreamData content, VersioningState verState, String user);
   

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractMultiFilingImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractMultiFilingImpl.java?rev=915814&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractMultiFilingImpl.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractMultiFilingImpl.java Wed Feb 24 14:58:07 2010
@@ -0,0 +1,93 @@
+/*
+ * 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.opencmis.inmemory.storedobj.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.opencmis.inmemory.storedobj.api.Document;
+import org.apache.opencmis.inmemory.storedobj.api.Folder;
+import org.apache.opencmis.inmemory.storedobj.api.MultiFiling;
+import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
+
+/**
+ * @author Jens
+ * 
+ * AbstractMultiPathImpl is the common superclass of all objects hold in the repository that 
+ * have multiple parent folders, these are: Folders
+ */
+public abstract class AbstractMultiFilingImpl extends StoredObjectImpl implements MultiFiling {
+
+  protected List<Folder> fParents = new ArrayList<Folder>(1);
+
+  AbstractMultiFilingImpl(ObjectStoreImpl objStore) {
+    super(objStore);
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.inmemory.storedobj.api.MultiParentPath#addParent(org.apache.opencmis.inmemory.storedobj.api.Folder)
+   */
+  public void addParent(Folder parent) {
+    
+    if (parent.hasChild(getName()))
+      throw new IllegalArgumentException(
+          "Cannot assign new parent folder, this name already exists in target folder.");
+
+    if (null == fParents)
+      fParents = new ArrayList<Folder>();
+    
+    fParents.add(parent);
+  }
+
+  
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.inmemory.storedobj.api.MultiParentPath#removeParent(org.apache.opencmis.inmemory.storedobj.api.Folder)
+   */
+  public void removeParent(Folder parent){
+    fParents.remove(parent);
+    if (fParents.isEmpty())
+      fParents = null;
+  }
+  
+  
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.inmemory.storedobj.api.MultiParentPath#getParents()
+   */
+  public List<Folder> getParents() {
+    return fParents;
+  }
+
+  
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.inmemory.storedobj.api.MultiParentPath#getPathSegment()
+   */
+  public String getPathSegment() {
+    return getName();
+  }
+
+  
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.inmemory.storedobj.api.Path#move(org.apache.opencmis.inmemory.storedobj.api.Folder, org.apache.opencmis.inmemory.storedobj.api.Folder)
+   */
+  public void move(Folder oldParent, Folder newParent) {
+    addParent(newParent);
+    removeParent(oldParent);
+  }
+
+}

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractSingleFilingImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractSingleFilingImpl.java?rev=915814&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractSingleFilingImpl.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/AbstractSingleFilingImpl.java Wed Feb 24 14:58:07 2010
@@ -0,0 +1,124 @@
+/*
+ * 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.opencmis.inmemory.storedobj.impl;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.opencmis.inmemory.NameValidator;
+import org.apache.opencmis.inmemory.storedobj.api.Document;
+import org.apache.opencmis.inmemory.storedobj.api.Folder;
+import org.apache.opencmis.inmemory.storedobj.api.SingleFiling;
+import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
+
+/**
+ * 
+ * @author Jens
+ * 
+ * AbstractPathImpl is the common superclass of all objects hold in the repository that
+ * have a single parent, these are: Folders
+ * 
+ */
+
+public abstract class AbstractSingleFilingImpl extends StoredObjectImpl implements
+    SingleFiling {
+
+  protected FolderImpl fParent;
+
+  protected AbstractSingleFilingImpl(ObjectStoreImpl objStore) {
+    super(objStore);
+  }
+    
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.opencmis.client.provider.spi.inmemory.StoredObjectWithPath#getPath()
+   */
+  public String getPath() {
+    StringBuffer path= new StringBuffer(getName());
+    if (null == getParent())
+      path.replace(0, path.length(), PATH_SEPARATOR); // root folder--> set /
+    else {
+      Folder f = getParent();
+      while (f.getParent() != null) {
+        path.insert(0,  PATH_SEPARATOR);
+        path.insert(0,  f.getName());
+        f = f.getParent();
+      }
+      path.insert(0,  PATH_SEPARATOR);
+    }
+//    if (LOG.isDebugEnabled())
+//      LOG.debug("getPath() returns: " + path.toString());
+    return path.toString();    
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.opencmis.client.provider.spi.inmemory.StoredObjectWithPath#getParent()
+   */
+  public Folder getParent() {
+    return fParent;
+  }
+  
+  public List<Folder> getParents() {
+    if (null==fParent)
+      return Collections.emptyList();
+    else
+      return Collections.singletonList((Folder)fParent);
+  }
+
+  /* (non-Javadoc)
+   * @see org.opencmis.client.provider.spi.inmemory.storedobj.api.StoredObjectWithPath#setParent(org.opencmis.client.provider.spi.inmemory.storedobj.api.Folder)
+   */
+  public void setParent(Folder parent) {
+    fParent = (FolderImpl) parent;
+  }
+  
+  public void rename(String newName) {
+    if (!NameValidator.isValidId(newName))
+      throw new IllegalArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
+    if (getParent() == null)
+      throw new IllegalArgumentException("Root folder cannot be renamed.");
+    if (getParent().hasChild(newName))
+      throw new IllegalArgumentException("Cannot rename object to " + newName
+          + ". This path already exists.");
+
+    setName(newName);
+  }
+  
+  public void move(Folder oldParent, Folder newParent) {
+    
+    if (this instanceof Document || this instanceof VersionedDocument)
+      fParent.moveChildDocument(this, oldParent, newParent);    
+    else {// it must be a folder
+      if (getParent() == null)
+        throw new IllegalArgumentException("Root folder cannot be moved.");
+      if (newParent == null)
+        throw new IllegalArgumentException("null is not a valid move target.");
+      if (newParent.hasChild(getName()))
+        throw new IllegalArgumentException(
+            "Cannot move folder, this name already exists in target.");
+
+      setParent(newParent);
+    }
+  }
+
+
+}

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentImpl.java Wed Feb 24 14:58:07 2010
@@ -38,10 +38,10 @@
  * 
  */
 
-public class DocumentImpl extends AbstractPathImpl implements Document{
+public class DocumentImpl extends AbstractMultiFilingImpl implements Document {
   private ContentStreamDataImpl fContent;
 
-  private static final Log LOG = LogFactory.getLog(AbstractPathImpl.class.getName());
+  private static final Log LOG = LogFactory.getLog(AbstractSingleFilingImpl.class.getName());
 
   DocumentImpl(ObjectStoreImpl objStore) { // visibility should be package
     super(objStore);

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentVersionImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentVersionImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentVersionImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/DocumentVersionImpl.java Wed Feb 24 14:58:07 2010
@@ -19,6 +19,7 @@
 package org.apache.opencmis.inmemory.storedobj.impl;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -195,20 +196,25 @@
     }
   }
 
-  public Folder getParent() {
-    return fContainer.getParent();
+  public List<Folder> getParents() {
+    return fContainer.getParents();
   }
 
-  public String getPath() {
-    return fContainer.getPath();
+  public String getPathSegment() {
+    return fContainer.getPathSegment();
   }
 
   public void move(Folder oldParent, Folder newParent) {
     fContainer.move(oldParent, newParent);
   }
 
-  public void setParent(Folder parent) {
-    fContainer.setParent(parent);    
+  public void addParent(Folder parent) {
+    fContainer.addParent(parent);    
   }
-  
+
+  public void removeParent(Folder parent) {
+    fContainer.removeParent(parent);
+  }
+
+ 
 }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/FolderImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/FolderImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/FolderImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/FolderImpl.java Wed Feb 24 14:58:07 2010
@@ -16,12 +16,14 @@
 import org.apache.opencmis.inmemory.storedobj.api.Document;
 import org.apache.opencmis.inmemory.storedobj.api.DocumentVersion;
 import org.apache.opencmis.inmemory.storedobj.api.Folder;
-import org.apache.opencmis.inmemory.storedobj.api.Path;
+import org.apache.opencmis.inmemory.storedobj.api.MultiFiling;
+import org.apache.opencmis.inmemory.storedobj.api.Filing;
+import org.apache.opencmis.inmemory.storedobj.api.SingleFiling;
 import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
 import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
 
-public class FolderImpl extends AbstractPathImpl implements Folder {
-  private static final Log LOG = LogFactory.getLog(AbstractPathImpl.class.getName());
+public class FolderImpl extends AbstractSingleFilingImpl implements Folder {
+  private static final Log LOG = LogFactory.getLog(AbstractSingleFilingImpl.class.getName());
 
   FolderImpl(ObjectStoreImpl objStore) {
     super(objStore);
@@ -69,7 +71,13 @@
       throw new RuntimeException("Cannot create document " + name
           + ". Name already exists in parent folder");
 
-    ((Path)so).setParent(this);
+    if (so instanceof SingleFiling)
+      ((SingleFiling)so).setParent(this);
+    else if (so instanceof MultiFiling)
+      ((MultiFiling)so).addParent(this);
+    else 
+      throw new RuntimeException("Cannot create document, object is not fileable.");
+      
     so.persist();
   }
   
@@ -82,8 +90,8 @@
     List<StoredObject> result = new ArrayList<StoredObject>();
     for (String id : fObjStore.getIds()) {
       StoredObject obj = fObjStore.getObject(id);
-      Path pathObj = (Path) obj;
-      if (pathObj.getParent() == this) {
+      Filing pathObj = (Filing) obj;
+      if (pathObj.getParents().contains(this)) {
         if (pathObj instanceof VersionedDocument) {
           DocumentVersion ver = ((VersionedDocument) pathObj).getLatestVersion(false);
           result.add(ver);
@@ -115,8 +123,8 @@
     List<Folder> result = new ArrayList<Folder>();
     for (String id : fObjStore.getIds()) {
       StoredObject obj = fObjStore.getObject(id);
-      if (obj instanceof Path) {
-        Path pathObj = (Path) obj;
+      if (obj instanceof SingleFiling) {
+        SingleFiling pathObj = (SingleFiling) obj;
         if (pathObj.getParent() == this && pathObj instanceof Folder)
           result.add((Folder)obj);
       }
@@ -134,16 +142,11 @@
    * @see org.opencmis.client.provider.spi.inmemory.IFolder#hasChild(java.lang.String)
    */
   public boolean hasChild(String name) {
-//    String path = getPath();
-//    if (path.equals(PATH_SEPARATOR))
-//      path = path + name;
-//    else
-//      path = path + PATH_SEPARATOR + name;
     for (String id : fObjStore.getIds()) {
       StoredObject obj = fObjStore.getObject(id);
-      if (obj instanceof Path) {
-        Path pathObj = (Path) obj;
-        if (pathObj.getParent() == this && obj.getName().equals(name))
+      if (obj instanceof Filing) {
+        Filing pathObj = (Filing) obj;
+        if (pathObj.getParents().contains(this) && obj.getName().equals(name))
           return true;
       }
     }
@@ -200,17 +203,22 @@
     Collections.sort(list, new FolderComparator());
   }
 
-  public void moveChildDocument(StoredObject so, Folder newParent) {
+  public void moveChildDocument(StoredObject so, Folder oldParent, Folder newParent) {
     if (newParent.hasChild(so.getName()))
       throw new IllegalArgumentException(
           "Cannot move object, this name already exists in target.");
-    if (!(so instanceof Path))
+    if (!(so instanceof Filing))
       throw new IllegalArgumentException(
       "Cannot move object, object does not have a path.");
     
-    Path pathObj = (Path) so;
-    pathObj.setParent(newParent);
-    // so.persist(); // not needed for in memory
+    if (so instanceof SingleFiling) {
+      SingleFiling pathObj = (SingleFiling) so;
+      pathObj.setParent(newParent);
+    } else if (so instanceof MultiFiling) {
+      MultiFiling pathObj = (MultiFiling) so;
+      pathObj.addParent(newParent);
+      pathObj.removeParent(oldParent);      
+    }
   }
 
   public List<String> getAllowedChildObjectTypeIds() {

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/ObjectStoreImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/ObjectStoreImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/ObjectStoreImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/ObjectStoreImpl.java Wed Feb 24 14:58:07 2010
@@ -31,8 +31,10 @@
 import org.apache.opencmis.inmemory.storedobj.api.Document;
 import org.apache.opencmis.inmemory.storedobj.api.DocumentVersion;
 import org.apache.opencmis.inmemory.storedobj.api.Folder;
+import org.apache.opencmis.inmemory.storedobj.api.MultiFiling;
 import org.apache.opencmis.inmemory.storedobj.api.ObjectStore;
-import org.apache.opencmis.inmemory.storedobj.api.Path;
+import org.apache.opencmis.inmemory.storedobj.api.Filing;
+import org.apache.opencmis.inmemory.storedobj.api.SingleFiling;
 import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
 import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
 
@@ -86,11 +88,24 @@
   public StoredObject getObjectByPath(String path) {
     
     for (StoredObject so : fStoredObjectMap.values()) {
-      if (so instanceof Path) {
-        String soPath = ((Path) so).getPath();
+      if (so instanceof SingleFiling) {
+        String soPath = ((SingleFiling) so).getPath();
         if (soPath.equals(path))
           return so;
       }
+      else if (so instanceof MultiFiling) {
+        MultiFiling mfo = (MultiFiling)so;
+        List<Folder> parents = mfo.getParents();
+        for (Folder parent : parents) {
+          String parentPath = parent.getPath();
+          String mfPath = parentPath.equals(Folder.PATH_SEPARATOR) ? parentPath
+              + mfo.getPathSegment() : parentPath + Folder.PATH_SEPARATOR + mfo.getPathSegment();
+          if (mfPath.equals(path))
+            return so;
+        }
+      }
+      else
+        return null;
     }
     return null;
   }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/StoreManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/StoreManagerImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/StoreManagerImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/StoreManagerImpl.java Wed Feb 24 14:58:07 2010
@@ -246,8 +246,8 @@
     caps.setIsPwcUpdatable(true);
     caps.setSupportsGetDescendants(true);
     caps.setSupportsGetFolderTree(true);
-    caps.setSupportsMultifiling(false);
-    caps.setSupportsUnfiling(false);
+    caps.setSupportsMultifiling(true);
+    caps.setSupportsUnfiling(true);
     caps.setSupportsVersionSpecificFiling(false);
     repoInfo.setRepositoryCapabilities(caps);
     

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/VersionedDocumentImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/VersionedDocumentImpl.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/VersionedDocumentImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/storedobj/impl/VersionedDocumentImpl.java Wed Feb 24 14:58:07 2010
@@ -32,7 +32,7 @@
 import org.apache.opencmis.inmemory.storedobj.api.DocumentVersion;
 import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
 
-public class VersionedDocumentImpl extends AbstractPathImpl implements VersionedDocument {
+public class VersionedDocumentImpl extends AbstractMultiFilingImpl implements VersionedDocument {
   
   private boolean fIsCheckedOut;
   private String fCheckedOutUser;

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/AbstractServiceTst.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/AbstractServiceTst.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/AbstractServiceTst.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/AbstractServiceTst.java Wed Feb 24 14:58:07 2010
@@ -1,5 +1,10 @@
 package org.apache.opencmis.inmemory;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -9,8 +14,6 @@
 import java.util.List;
 import java.util.Map;
 
-import junit.framework.TestCase;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.opencmis.client.provider.factory.CmisProviderFactory;
@@ -38,7 +41,7 @@
 import org.apache.opencmis.inmemory.server.RuntimeContext;
 import org.apache.opencmis.inmemory.storedobj.impl.ContentStreamDataImpl;
 
-public class AbstractServiceTst  extends TestCase {
+public class AbstractServiceTst /* extends TestCase*/ {
   private static Log LOG = LogFactory.getLog(AbstractServiceTst.class);
   protected static final String REPOSITORY_ID = "UnitTestRepository";
   protected ProviderObjectFactory fFactory = new ProviderObjectFactoryImpl();
@@ -70,7 +73,7 @@
   }
   
   protected void setUp() throws Exception {
-    super.setUp();
+    //super.setUp();
     LOG.debug("Initializing InMemory Test with type creator class: " + fTypeCreatorClassName);
     Map<String, String> parameters = new HashMap<String, String>();
     parameters.put(SessionParameter.BINDING_SPI_CLASS, CmisProviderFactory.BINDING_SPI_INMEMORY);
@@ -113,7 +116,7 @@
   }
 
   protected void tearDown() throws Exception {
-    super.tearDown();
+    // super.tearDown();
   }
   
   public void testDummy() {
@@ -133,9 +136,8 @@
     return id;
   }
  
-  protected String createDocument(String name, String folderId, String typeId, boolean withContent) {
-      ContentStreamData contentStream = null;
-    VersioningState versioningState = VersioningState.NONE;
+  protected String createDocument(String name, String folderId, String typeId, VersioningState versioningState, boolean withContent) {
+    ContentStreamData contentStream = null;
     List<String> policies = null;
     AccessControlList addACEs = null;
     AccessControlList removeACEs = null;
@@ -156,6 +158,11 @@
       fail("createDocument() failed with exception: " + e);
     }
     return id;
+    
+  }
+  protected String createDocument(String name, String folderId, String typeId, boolean withContent) {
+    VersioningState versioningState = VersioningState.NONE;
+    return createDocument(name, folderId, typeId, versioningState, withContent);
   }
   
   protected PropertiesData createDocumentProperties(String name, String typeId) {

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/FolderTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/FolderTest.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/FolderTest.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/FolderTest.java Wed Feb 24 14:58:07 2010
@@ -24,10 +24,12 @@
 
 import org.apache.opencmis.inmemory.storedobj.api.Folder;
 import org.apache.opencmis.inmemory.storedobj.api.ObjectStore;
-import org.apache.opencmis.inmemory.storedobj.api.Path;
+import org.apache.opencmis.inmemory.storedobj.api.Filing;
 import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
 import org.apache.opencmis.inmemory.storedobj.impl.FolderImpl;
 import org.apache.opencmis.inmemory.storedobj.impl.ObjectStoreImpl;
+import org.junit.Before;
+import org.junit.Test;
 
 /**
  * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
@@ -49,11 +51,13 @@
   private FolderImpl f11;
   private static final String TEST_REPOSITORY_ID = "TestRepositoryId";
 
+  @Before
   protected void setUp() throws Exception {
     fStore = new ObjectStoreImpl(TEST_REPOSITORY_ID);
     createFolders();
   }
     
+  @Test
   public void testCreatAndGetFolders() {
     try {
       Folder childFolder = fStore.createFolder("Folder 1");
@@ -66,7 +70,7 @@
     assertNull(fRoot.getParent());
     assertEquals(fRoot, f1.getParent());
     assertEquals(f1, f11.getParent());
-    assertEquals(Path.PATH_SEPARATOR, fRoot.getPath());
+    assertEquals(Filing.PATH_SEPARATOR, fRoot.getPath());
     assertEquals("/Folder 1", f1.getPath());
     assertEquals("/Folder 1/Folder 1.1", f11.getPath());
     StoredObject fTest = fStore.getObjectByPath("/");
@@ -83,15 +87,16 @@
     assertEquals(1, subFolders.size()); 
   }
 
+  @Test
   public void testRenameFolder() {
     // rename top level folder
     String newName = "Folder B";
     String oldPath = f2.getPath();
     f2.rename(newName);
     assertEquals(f2.getName(), newName);
-    assertEquals(f2.getPath(), Path.PATH_SEPARATOR + newName);
+    assertEquals(f2.getPath(), Filing.PATH_SEPARATOR + newName);
     assertNull(fStore.getObjectByPath(oldPath));
-    assertEquals(f2, fStore.getObjectByPath(Path.PATH_SEPARATOR + newName));
+    assertEquals(f2, fStore.getObjectByPath(Filing.PATH_SEPARATOR + newName));
     try {
       f2.rename("Folder 3");
       fail("Should not allow to rename a folder to an existing name");
@@ -124,6 +129,7 @@
     }    
   }
   
+  @Test
   public void testMoveFolder() {
     String oldPath = f1.getPath();
     Folder f1Parent = f1.getParent();
@@ -141,6 +147,7 @@
     }
   }
   
+  @Test
   public void testDeleteFolder() {
     String oldPath = f2.getPath();
     fStore.deleteObject(f2.getId());

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/MultiFilingTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/MultiFilingTest.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/MultiFilingTest.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/MultiFilingTest.java Wed Feb 24 14:58:07 2010
@@ -18,36 +18,59 @@
  */
 package org.apache.opencmis.inmemory;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.opencmis.commons.PropertyIds;
 import org.apache.opencmis.commons.enums.BaseObjectTypeIds;
 import org.apache.opencmis.commons.enums.IncludeRelationships;
+import org.apache.opencmis.commons.enums.VersioningState;
+import org.apache.opencmis.commons.exceptions.CmisConstraintException;
 import org.apache.opencmis.commons.exceptions.CmisNotSupportedException;
+import org.apache.opencmis.commons.provider.Holder;
+import org.apache.opencmis.commons.provider.ObjectData;
 import org.apache.opencmis.commons.provider.ObjectParentData;
+import org.apache.opencmis.commons.provider.PropertiesData;
+import org.apache.opencmis.commons.provider.PropertyData;
+import org.apache.opencmis.inmemory.VersioningTest.VersionTestTypeSystemCreator;
 import org.apache.opencmis.inmemory.types.InMemoryFolderTypeDefinition;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 public class MultiFilingTest extends AbstractServiceTst {
 
   private static Log LOG = LogFactory.getLog(MultiFilingTest.class);
   private static final String DOCUMENT_TYPE_ID = UnitTestTypeSystemCreator.COMPLEX_TYPE;
   private static final String FOLDER_TYPE_ID =  InMemoryFolderTypeDefinition.getRootFolderType().getId();
+  private static final String UNFILED_DOC_NAME = "Unfiled document";
+  private static final String RENAMED_DOC_NAME = "My Renamed Document";
   
   private String fId1;
   private String fId2;
   private String fId11;
 
-  protected void setUp() throws Exception {
+  @Before
+  public void setUp() throws Exception {
     super.setUp();
   }
 
-  protected void tearDown() throws Exception {
+  @After
+  public void tearDown() throws Exception {
     super.tearDown();
   }
 
+  @Test
   public void testCreateUnfiledDocument() {
     LOG.debug("Begin testCreatUnfiledDocument()");
     String docId = createUnfiledDocument();    
@@ -64,7 +87,8 @@
     LOG.debug("End testCreatUnfiledDocument()");    
   }
   
-  public void xtestMakeFiledDocumentUnfiled() {
+  @Test
+  public void testMakeFiledDocumentUnfiled() {
     LOG.debug("Begin testMakeFiledDocumentUnfiled()");
     
     String docId = createDocument("Filed document", fRootFolderId, DOCUMENT_TYPE_ID, true);
@@ -77,10 +101,99 @@
     LOG.debug("End testMakeFiledDocumentUnfiled()");    
   }
 
-  public void xtestAddDocumentToFolder() {
-    LOG.debug("Begin testAddDocumentToFolder()");
+ @Test
+ public void testAddDocumentToFolder() {
+   LOG.debug("Begin testAddDocumentToFolder()");
+   String docId = createUnfiledDocument();
+   addDocumentToFolder(docId);
+   LOG.debug("End testAddDocumentToFolder()");    
+ }
+   
+  @Test
+  public void testRemoveDocumentFromFolder() {
+    LOG.debug("Begin testRemoveDocumentFromFolder()");
+
+    String docId = createUnfiledDocument();
+    removeDocumentFromFolder(docId);
+    LOG.debug("End testRemoveDocumentFromFolder()");    
+  }
+  
+  @Test 
+  public void testMoveMultiFiledDocument() {
+    LOG.debug("begin testMoveMultiFiledDocument()");    
+    String docId = createUnfiledDocument();
+    prepareMultiFiledDocument(docId);
+    String newFolderId = createFolder("folder2.1", fId2, FOLDER_TYPE_ID);
     
+    Holder<String> idHolder = new Holder<String>(docId);
+    fObjSvc.moveObject(fRepositoryId, idHolder, newFolderId, fId11, null);
+    List<ObjectParentData> parents = fNavSvc.getObjectParents(fRepositoryId, docId, "*", false,
+        IncludeRelationships.NONE, null, true, null);
+    assertEquals(3, parents.size());
+    boolean foundNewParent = false;
+    boolean foundOldParent = false;
+    for (ObjectParentData parentData: parents) {
+      if (parentData.getObject().getId().equals(newFolderId))
+        foundNewParent = true;
+      if (parentData.getObject().getId().equals(fId11))
+        foundOldParent = true;
+    }
+    assertTrue("After move new target should be a parent", foundNewParent);
+    assertFalse("After move old source should no longer be a parent", foundOldParent);
+    LOG.debug("End testMoveMultiFiledDocument()");    
+  }
+  
+  @Test 
+  public void testRenameMultiFiledDocument() {
+    LOG.debug("begin testRenameMultiFiledDocument()");    
+    String docId = createUnfiledDocument();
+    prepareMultiFiledDocument(docId);    
+    renameDocumentAndCheckResult(docId);
+    LOG.debug("End testRenameMultiFiledDocument()");        
+  }
+  
+  @Test 
+  public void testRenameMultiFiledDocumentWithNameConflict() {
+    LOG.debug("begin testRenameMultiFiledDocument()");    
     String docId = createUnfiledDocument();
+    prepareMultiFiledDocument(docId);    
+    // create a document with the new name in one of the folders
+    createDocument(RENAMED_DOC_NAME, fId11, DOCUMENT_TYPE_ID, true);
+    // try to rename which should fail now
+    try {
+      renameDocumentAndCheckResult(docId);
+      fail("A rename to an existing name in one of the filed folders should fail");
+    } catch (Exception e) {
+      assertTrue(e instanceof CmisConstraintException);
+    }
+    LOG.debug("End testRenameMultiFiledDocument()");        
+  }
+  
+  @Test
+  public void testAddVersionedDocumentToFolder() {
+    LOG.debug("Begin testAddVersionedDocumentToFolder()");
+    String docId = createVersionedDocument();
+    addDocumentToFolder(docId);
+    LOG.debug("End testAddVersionedDocumentToFolder()");    
+  }
+    
+   @Test
+   public void testRemoveVersionedDocumentFromFolder() {
+     LOG.debug("Begin testRemoveVersionedDocumentFromFolder()");
+
+     String docId = createVersionedDocument();
+     removeDocumentFromFolder(docId);
+     LOG.debug("End testRemoveVersionedDocumentFromFolder()");    
+   }
+
+   private void createFolders() {
+    fId1 = createFolder("folder1", fRootFolderId, FOLDER_TYPE_ID);
+    fId2 = createFolder("folder2", fRootFolderId, FOLDER_TYPE_ID);
+    fId11 = createFolder("folder1.1", fId1, FOLDER_TYPE_ID);    
+  }
+  
+  private void addDocumentToFolder(String docId) {
+    
     List<String> folderIds = prepareMultiFiledDocument(docId);
     
     // get object parents, must contain all folders
@@ -89,9 +202,8 @@
     assertEquals(3, res.size());
     for (ObjectParentData opd : res) {
       assertTrue(folderIds.contains(opd.getObject().getId()));
-      assertEquals(BaseObjectTypeIds.CMIS_FOLDER.value(), opd.getObject().getBaseTypeId());
-      String name = getStringProperty(opd.getObject(), PropertyIds.CMIS_NAME);
-      assertEquals(name, opd.getRelativePathSegment());      
+      assertEquals(BaseObjectTypeIds.CMIS_FOLDER, opd.getObject().getBaseTypeId());
+      assertEquals(UNFILED_DOC_NAME, opd.getRelativePathSegment());      
     }
     
     // try version specific filing, should fail
@@ -101,13 +213,9 @@
     } catch (Exception e) {
       assertTrue(e instanceof CmisNotSupportedException);
     }
-    LOG.debug("End testAddDocumentToFolder()");    
   }
   
-  public void xtestRemoveDocumentFromFolder() {
-    LOG.debug("Begin testRemoveDocumentFromFolder()");
-
-    String docId = createUnfiledDocument();
+  private void removeDocumentFromFolder(String docId) {
     prepareMultiFiledDocument(docId);
     
     fMultiSvc.removeObjectFromFolder(fRepositoryId, docId, fId1,  null);
@@ -130,18 +238,10 @@
     parents = fNavSvc.getObjectParents(fRepositoryId, docId, "*", false,
         IncludeRelationships.NONE, null, true, null);
     assertEquals(0, parents.size());
-
-    LOG.debug("End testRemoveDocumentFromFolder()");    
-  }
-  
-  private void createFolders() {
-    fId1 = createFolder("folder1", fRootFolderId, FOLDER_TYPE_ID);
-    fId2 = createFolder("folder2", fRootFolderId, FOLDER_TYPE_ID);
-    fId11 = createFolder("folder1.1", fId1, FOLDER_TYPE_ID);    
   }
   
   private String createUnfiledDocument() {
-    return createDocument("Unfiled document", null, DOCUMENT_TYPE_ID, true);
+    return createDocument(UNFILED_DOC_NAME , null, DOCUMENT_TYPE_ID, true);
   }
   
   private List<String> prepareMultiFiledDocument(String docId) {
@@ -159,4 +259,27 @@
     
     return folderIds;
   }
+  
+  private void renameDocumentAndCheckResult(String docId) {
+    Holder<String> idHolder = new Holder<String>(docId);    
+    List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
+    properties.add(fFactory.createPropertyIdData(PropertyIds.CMIS_NAME, RENAMED_DOC_NAME));      
+    PropertiesData newProps = fFactory.createPropertiesData(properties);
+    Holder<String> changeTokenHolder = new Holder<String>();
+    fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
+    docId = idHolder.getValue(); 
+    ObjectData  res = fObjSvc.getObject(fRepositoryId, docId, "*", false, IncludeRelationships.NONE,
+        null, false, false, null);
+    assertNotNull(res);
+    Map<String, PropertyData<?>> propMap = res.getProperties().getProperties();
+    PropertyData<?> pd = propMap.get(PropertyIds.CMIS_NAME);
+    assertNotNull(pd);
+    assertEquals(RENAMED_DOC_NAME, pd.getFirstValue());    
+  }
+
+  private String createVersionedDocument() {
+    
+    return createDocument(UNFILED_DOC_NAME , null, UnitTestTypeSystemCreator.VERSION_DOCUMENT_TYPE_ID, VersioningState.MAJOR, true);
+
+  }
 }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/NavigationServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/NavigationServiceTest.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/NavigationServiceTest.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/NavigationServiceTest.java Wed Feb 24 14:58:07 2010
@@ -35,7 +35,11 @@
 import org.apache.opencmis.commons.provider.PropertyData;
 import org.apache.opencmis.inmemory.types.InMemoryFolderTypeDefinition;
 import org.apache.opencmis.util.repository.ObjectGenerator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
+import static org.junit.Assert.*;
 
 /**
  * @author Jens
@@ -45,14 +49,17 @@
   private static final int NUM_ROOT_FOLDERS = 10;
   private String fLevel1FolderId;
 
-  protected void setUp() throws Exception {
+  @Before
+  public void setUp() throws Exception {
     super.setUp();
   }
 
-  protected void tearDown() throws Exception {
+  @After
+  public void tearDown() throws Exception {
     super.tearDown();
   }
 
+  @Test
   public void testGetChildren() {
     log.info("starting testGetChildren() ...");
     createLevel1Folders();
@@ -86,6 +93,7 @@
     log.info("... testGetChildren() finished.");
   }
 
+  @Test
   public void testGetFolderTree() {
     log.info("starting testGetFolderTree() ...");    
     createFolderHierachy(3, 5);
@@ -124,6 +132,7 @@
     }
   }
 
+  @Test
   public void testGetDescendants() {
     log.info("starting testGetDescendants() ...");
     final int numLevels = 3;
@@ -166,6 +175,7 @@
     log.info("... testGetDescendants() finished.");
   }
   
+  @Test
   public void testGetFolderParent() {
     log.info("starting testGetFolderParent() ...");
     createLevel1Folders();

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/ObjectServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/ObjectServiceTest.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/ObjectServiceTest.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/ObjectServiceTest.java Wed Feb 24 14:58:07 2010
@@ -53,6 +53,11 @@
 import org.apache.opencmis.inmemory.types.InMemoryFolderTypeDefinition;
 import org.apache.opencmis.inmemory.types.PropertyCreationHelper;
 import org.apache.opencmis.util.repository.ObjectGenerator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
 
 /**
  * @author Jens
@@ -80,16 +85,19 @@
   
   ObjectCreator fCreator;
   
-  protected void setUp() throws Exception {
+  @Before
+  public void setUp() throws Exception {
     super.setTypeCreatorClass(ObjectTestTypeSystemCreator.class.getName());
     super.setUp();
     fCreator = new ObjectCreator(fFactory, fObjSvc, fRepositoryId);
   }
 
-  protected void tearDown() throws Exception {
+  @After
+  public void tearDown() throws Exception {
     super.tearDown();
   }
 
+  @Test
   public void testCreateDocument() {
     log.info("starting testCreateObject() ...");
     String id = createDocument(fRootFolderId, false);
@@ -99,6 +107,7 @@
   }
 
 
+  @Test
   public void testGetObject() {
     log.info("starting testGetObject() ...");
     log.info("  creating object");
@@ -111,6 +120,7 @@
     log.info("... testGetObject() finished.");
   }
   
+  @Test
   public void testGetObjectByPath() {
     log.info("starting testGetObjectByPath() ...");
     log.info("  creating object");
@@ -160,6 +170,7 @@
     log.info("... testGetObjectByPath() finished.");
   }   
 
+  @Test
   public void testCreateDocumentWithContent() {
     log.info("starting testCreateDocumentWithContent() ...");
     String id = createDocument(fRootFolderId, true);
@@ -198,6 +209,7 @@
     log.info("... testCreateDocumentWithContent() finished.");
   }
 
+  @Test
   public void testCreateDocumentFromSource() {
     log.info("starting testCreateDocumentFromSource() ...");
     // create a 1st document
@@ -227,6 +239,7 @@
     log.info("... testCreateDocumentFromSource() finished.");
   }
 
+  @Test
   public void testCreatedDocumentInherited() {
     log.info("starting testCreatedDocumentInherited() ...");
     log.info("  creating object");
@@ -272,6 +285,7 @@
     log.info("... testCreatedDocumentInherited() finished.");
   }
   
+  @Test
   public void testBuildFolderAndDocuments() {
     // Create a hierarchy of folders and fill it with some documents
 
@@ -310,6 +324,7 @@
   }
   
   
+  @Test
   public void testDeleteObject() {
     log.info("starting testDeleteObject() ...");
     log.info("Testing to delete a document");
@@ -410,6 +425,7 @@
     log.info("... testDeleteObject() finished.");    
   }
   
+  @Test
   public void testDeleteTree() {
     log.info("starting testDeleteTree() ...");
     ObjectGenerator gen = new ObjectGenerator(fFactory, fNavSvc, fObjSvc, fRepositoryId);
@@ -443,18 +459,21 @@
     log.info("... testDeleteTree() finished.");
   }
 
+  @Test
   public void testMoveFolder() {
     log.info("starting testMoveFolder() ...");
     moveObjectTest(true);
     log.info("... testMoveFolder() finished.");    
   }
   
+  @Test
   public void testMoveDocument() {
     log.info("starting testMoveDocument() ...");
     moveObjectTest(false);
     log.info("... testMoveDocument() finished.");    
   }
 
+  @Test
   public void testUpdateProperties() {
     log.info("starting testUpdateProperties() ...");
     String oldChangeToken, newChangeToken;
@@ -614,6 +633,7 @@
     log.info("... testUpdateProperties() finished.");
   }
 
+  @Test
   public void testAllowableActions() {
     log.info("starting testAllowableActions() ...");
     String id = createDocument(fRootFolderId, false);

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/RepositoryServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/RepositoryServiceTest.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/RepositoryServiceTest.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/RepositoryServiceTest.java Wed Feb 24 14:58:07 2010
@@ -57,6 +57,12 @@
 import org.apache.opencmis.inmemory.types.DocumentTypeCreationHelper;
 import org.apache.opencmis.inmemory.types.InMemoryDocumentTypeDefinition;
 import org.apache.opencmis.inmemory.types.PropertyCreationHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
 /**
  * @author Jens
  */
@@ -107,17 +113,18 @@
     }    
   }
   
-
-  protected void setUp() throws Exception {
+  @Before
+  public void setUp() throws Exception {
     super.setTypeCreatorClass(RepositoryTestTypeSystemCreator.class.getName());
     super.setUp();
   }
 
-  protected void tearDown() throws Exception {
+  @After
+  public void tearDown() throws Exception {
     super.tearDown();
   }
 
-
+  @Test
   public void testRepositoryInfo() throws Exception {
     log.info("starting testRepositoryInfo() ...");
     List<RepositoryInfoData> repositories = fRepSvc.getRepositoryInfos(
@@ -138,6 +145,7 @@
     log.info("... testRepositoryInfo() finished.");
   }
 
+  @Test
   public void testTypeDefinition() throws Exception {
     log.info("");
     log.info("starting testTypeDefinition() ...");
@@ -155,6 +163,7 @@
     log.info("... testTypeDefinition() finished.");
   }
 
+  @Test
   public void testGetAllTypesUnlimitedDepth() {
     log.info("");
     log.info("starting testGetAllTypesUnlimitedDepth()...");
@@ -187,6 +196,7 @@
     log.info("... testGetAllTypesUnlimitedDepth() finished.");
   }
 
+  @Test
   public void testGetAllTypesLimitedDepth() {
     log.info("");
     log.info("starting testGetAllTypesLimitedDepth()...");
@@ -229,6 +239,7 @@
     log.info("... testGetAllTypesLimitedDepth() finished.");
   }
 
+  @Test
   public void testGetSpecificTypeLimitedDepth() {
     log.info("");
     log.info("starting testGetSpecificTypeLimitedDepth()...");
@@ -264,6 +275,7 @@
     log.info("... testGetSpecificTypeLimitedDepth() finished.");
   }
   
+  @Test
   public void testGetTypesWithoutProperties() {
     log.info("");
     log.info("starting testGetTypesWithoutProperties()...");
@@ -293,6 +305,7 @@
     log.info("... testGetTypesWithoutProperties() finished.");
   }
 
+  @Test
   public void testGetTypeChildren() {
     log.info("");
     log.info("starting testGetTypeChildren()...");
@@ -330,6 +343,7 @@
     log.info("... testGetTypeChildren() finished.");
   }
 
+  @Test
   public void testGetWrongParameters() {
     log.info("");
     log.info("starting testGetWrongParameters()...");
@@ -415,6 +429,7 @@
 
   }
 
+  @Test
   public void testInheritedProperties() {
     log.info("");
     log.info("starting testInheritedProperties()...");

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/TypeValidationTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/TypeValidationTest.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/TypeValidationTest.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/TypeValidationTest.java Wed Feb 24 14:58:07 2010
@@ -49,6 +49,9 @@
 import org.apache.opencmis.commons.provider.ProviderObjectFactory;
 import org.apache.opencmis.inmemory.types.InMemoryDocumentTypeDefinition;
 import org.apache.opencmis.inmemory.types.PropertyCreationHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 /**
  * @author Jens
@@ -69,10 +72,12 @@
   private static final String STRING_PROP_TYPE_SUB = "StringPropSub";
   private static final ProviderObjectFactory FACTORY = new ProviderObjectFactoryImpl();
   
+  @Before
   protected void setUp() throws Exception {
     super.setUp();
   }
 
+  @After
   protected void tearDown() throws Exception {
     super.tearDown();
   }
@@ -84,6 +89,7 @@
     return properties;
   }
 
+  @Test
   public void testMandatoryPropertyValidation() {
     // create properties in the same way as we would pass them to a createDocument call
     // of the ObjectService
@@ -114,6 +120,7 @@
     }
   }
 
+  @Test
   public void testStringPropertyValidation() {
     TypeDefinition typeDef = buildTypeWithStringProp(); // we only have one
 
@@ -142,6 +149,7 @@
     }
   }
 
+  @Test
   public void testIntegerPropertyValidation() {
 
     TypeDefinition typeDef = buildTypeWithIntegerProp();
@@ -171,6 +179,7 @@
 
   }
 
+  @Test
   public void testDecimalPropertyValidation() {
     TypeDefinition typeDef = buildTypeWithDecimalProp();
 
@@ -198,6 +207,7 @@
     }
   }
 
+  @Test
   public void testPickListValidationSingleValue() {
     TypeDefinition typeDef =buildTypeWithPickList(Cardinality.SINGLE);
 
@@ -227,6 +237,7 @@
     }
   }
 
+  @Test
   public void testPickListValidationMultiValue() {
     TypeDefinition typeDef =buildTypeWithPickList(Cardinality.MULTI);
 
@@ -261,6 +272,7 @@
     }
   }
 
+  @Test
   public void testPickListValidationMultiUsingMultipleValueLists() {
     TypeDefinition typeDef = buildTypeWithMultiPickList();
 
@@ -298,6 +310,7 @@
     }
   }
 
+  @Test
   public void testHierachicalPickListValidationSingleValue() {
     TypeDefinition typeDef = buildTypeWithHierachicalPickList(Cardinality.SINGLE);
 
@@ -327,6 +340,7 @@
     }
   }
 
+  @Test
   public void testHierachicalPickListValidationMultiValue() {
     TypeDefinition typeDef = buildTypeWithHierachicalPickList(Cardinality.MULTI);
 
@@ -362,6 +376,7 @@
     }
   }
 
+  @Test
   public void testInheritedPropertyValidation() {
     TypeManager tm = buildInheritedTypes();
     TypeDefinition superType = tm.getTypeById(DOC_TYPE_SUPER).getTypeDefinition();

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/UnitTestTypeSystemCreator.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/UnitTestTypeSystemCreator.java?rev=915814&r1=915813&r2=915814&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/UnitTestTypeSystemCreator.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/UnitTestTypeSystemCreator.java Wed Feb 24 14:58:07 2010
@@ -50,6 +50,8 @@
   public static final String TOPLEVEL_TYPE = "DocumentTopLevel";
   public static final String LEVEL1_TYPE = "DocumentLevel1";;
   public static final String LEVEL2_TYPE = "DocumentLevel2";
+  public static final String VERSION_DOCUMENT_TYPE_ID = "MyVersionedType";
+  public static final String VERSION_PROPERTY_ID = "StringProp";
 
   /**
    * in the public interface of this class we return the singleton containing the required types
@@ -242,11 +244,27 @@
     propertyDefinitions.put(propLevel2.getId(), propLevel2);
     cmisDocTypeLevel2.addCustomPropertyDefinitions(propertyDefinitions);    
 
+    
+    // create a versioned type with properties
+    InMemoryDocumentTypeDefinition cmisVersionedType = new InMemoryDocumentTypeDefinition(VERSION_DOCUMENT_TYPE_ID,
+        "VersionedType", InMemoryDocumentTypeDefinition.getRootDocumentType());
+    
+    // create a single String property definition
+    
+    propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
+    
+    PropertyStringDefinitionImpl prop1 = PropertyCreationHelper.createStringDefinition(VERSION_PROPERTY_ID, "Sample String Property");
+    propertyDefinitions.put(prop1.getId(), prop1);
+    
+    cmisVersionedType.addCustomPropertyDefinitions(propertyDefinitions);    
+    cmisVersionedType.setIsVersionable(true); // make it a versionable type;
+    
     // add type to types collection
     typesList.add(cmisDocTypeTopLevel);
     typesList.add(cmisDocTypeLevel1);
     typesList.add(cmisDocTypeLevel2);
-    
+    typesList.add(cmisVersionedType);
+
     return typesList;
   }