chemistry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dcaru...@apache.org
Subject svn commit: r910572 [27/36] - in /incubator/chemistry/trunk/opencmis: ./ _dev/ opencmis-client/ opencmis-client/opencmis-client-api/ opencmis-client/opencmis-client-api/src/ opencmis-client/opencmis-client-api/src/main/ opencmis-client/opencmis-client-...
Date Tue, 16 Feb 2010 16:04:07 GMT
Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/FilterParser.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/FilterParser.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/FilterParser.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/FilterParser.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+/**
+ * @author Jens
+*/
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class FilterParser {
+
+  public static boolean isContainedInFilter(String propertyId, List<String> requestedIds) {
+    if (requestedIds.contains("*"))
+      return true;
+    return requestedIds.contains(propertyId);
+  }
+
+  public static List<String> getRequestedIdsFromFilter(String filter) {
+    if (filter == null || filter.length() == 0)
+      return Collections.singletonList("*");
+    else {
+      List<String> requestedIds = Arrays.asList(filter.split(",\\s*")); // comma plus whitespace
+      if (requestedIds.contains("*"))
+        requestedIds = Collections.singletonList("*");
+      return requestedIds;
+    }
+  }
+
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/FilterParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MapConfigReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MapConfigReader.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MapConfigReader.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MapConfigReader.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+
+/**
+ * An implementation of 
+ * @author jens
+ *
+ */
+public class MapConfigReader implements ConfigMap {
+  Map<String, String> fMap;
+  
+  public MapConfigReader(Map<String, String> map) {
+    fMap = map;
+  }
+  
+  public String get(String key) {
+
+    return fMap.get(key);
+  }
+
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/MapConfigReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NameValidator.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NameValidator.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NameValidator.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NameValidator.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+public class NameValidator {
+  public static final String ERROR_ILLEGAL_ID = 
+    "Id contains illegal characters, allowed are 'a'..'z', 'A'..'Z', '0'..'9', '-', '_'";
+
+  public static final String ERROR_ILLEGAL_NAME = 
+    "Id contains illegal characters, allowed are 'a'..'z', 'A'..'Z', '0'..'9', '-', '_', '.', ' '";
+
+  /**
+   * check whether id contains only valid characters Allowed are 'a'..'z', 'A'..'Z', '0'..'9', '.', '-', ' ',
+   * '_';
+   * 
+   * @param s
+   *          string to verify
+   */
+  static public boolean isValidId(String s) {
+    if (s.startsWith("cmis:"))
+        s = s.substring(5);
+    		
+    for (int i = 0; i < s.length(); i++) {
+      char c = s.charAt(i);
+      if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.'
+          || c == '-' || c == '_' || c == ' '))
+        return false;
+    }
+    return true;
+  }
+
+  static public boolean isValidLocalName(String s) {
+    return isValidId(s);
+  }
+
+  /**
+   * check whether id contains only valid characters Allowed are 'a'..'z', 'A'..'Z', '0'..'9', '.', '-', ' ',
+   * '_';
+   * 
+   * @param s
+   *          string to verify
+   */
+  static public boolean isValidName(String s) {
+    for (int i = 0; i < s.length(); i++) {
+      char c = s.charAt(i);
+      if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.'
+          || c == '-' || c == '_' || c == ' '))
+        return false;
+    }
+    return true;
+  }
+
+  static public boolean isValidNamespace(String s) {
+    return isValidId(s);
+  }
+
+  static public boolean isValidQueryName(String s) {
+    return isValidId(s);
+  }
+
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NameValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 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=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,338 @@
+/*
+ * 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;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.opencmis.commons.PropertyIds;
+import org.apache.opencmis.commons.api.ExtensionsData;
+import org.apache.opencmis.commons.enums.IncludeRelationships;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.opencmis.commons.impl.dataobjects.ObjectDataImpl;
+import org.apache.opencmis.commons.impl.dataobjects.ObjectInFolderContainerImpl;
+import org.apache.opencmis.commons.impl.dataobjects.ObjectInFolderDataImpl;
+import org.apache.opencmis.commons.impl.dataobjects.ObjectInFolderListImpl;
+import org.apache.opencmis.commons.impl.dataobjects.ObjectListImpl;
+import org.apache.opencmis.commons.impl.dataobjects.ObjectParentDataImpl;
+import org.apache.opencmis.commons.provider.NavigationService;
+import org.apache.opencmis.commons.provider.ObjectData;
+import org.apache.opencmis.commons.provider.ObjectInFolderContainer;
+import org.apache.opencmis.commons.provider.ObjectInFolderData;
+import org.apache.opencmis.commons.provider.ObjectInFolderList;
+import org.apache.opencmis.commons.provider.ObjectList;
+import org.apache.opencmis.commons.provider.ObjectParentData;
+import org.apache.opencmis.commons.provider.PropertiesData;
+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.StoreManager;
+import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
+import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
+import org.apache.opencmis.inmemory.types.PropertyCreationHelper;
+
+/**
+ * Navigation Service interface. See CMIS 1.0 domain model for details.
+ * @author Jens
+ */
+
+public class NavigationServiceImpl extends AbstractServiceImpl implements NavigationService {
+  private static Log log = LogFactory.getLog(NavigationServiceImpl.class);
+  
+  public NavigationServiceImpl(StoreManager storeManager) {
+    super(storeManager);
+    fStoreManager = storeManager;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.client.provider.NavigationService#getCheckedOutDocs(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean, org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.math.BigInteger, java.math.BigInteger, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectList getCheckedOutDocs(String repositoryId, String folderId, String filter,
+      String orderBy, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+    
+    ObjectListImpl res = new ObjectListImpl();
+    List<ObjectData> odList = new ArrayList<ObjectData>();
+    
+    log.debug("start getCheckedOutDocs()");
+    if (null != folderId)
+      checkStandardParameters(repositoryId, folderId);
+    else
+      checkRepositoryId(repositoryId);
+
+    if (null == folderId) {
+      List<VersionedDocument> checkedOuts = fStoreManager.getObjectStore(repositoryId).getCheckedOutDocuments(orderBy);
+      for (VersionedDocument checkedOut : checkedOuts) {
+        ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, checkedOut, filter,
+            includeAllowableActions, includeRelationships, renditionFilter, false,
+            false, extension);
+        odList.add(od);
+      }
+    } else {
+      ObjectInFolderList children = getChildrenIntern(repositoryId, folderId, filter, orderBy, includeAllowableActions,
+          includeRelationships, renditionFilter, false, -1, -1, false); 
+      for (ObjectInFolderData child: children.getObjects()) {
+        ObjectData obj = child.getObject();
+        StoredObject so = fStoreManager.getObjectStore(repositoryId).getObjectById(obj.getId());
+        if (so instanceof VersionedDocument && ((VersionedDocument)so).isCheckedOut())
+          odList.add(obj);
+      }
+    }
+    res.setObjects(odList);
+    res.setNumItems(BigInteger.valueOf(odList.size()));
+    
+    log.debug("end getCheckedOutDocs()");
+    return res; 
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.client.provider.NavigationService#getChildren(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean, org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean, java.math.BigInteger, java.math.BigInteger, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectInFolderList getChildren(String repositoryId, String folderId, String filter,
+      String orderBy, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includePathSegments, BigInteger maxItems,
+      BigInteger skipCount, ExtensionsData extension) {
+    
+    log.debug("start getChildren()");
+    checkStandardParameters(repositoryId, folderId);
+
+    int maxItemsInt = maxItems==null ? -1 : maxItems.intValue();
+    int skipCountInt = skipCount==null ? -1 : skipCount.intValue();
+    ObjectInFolderList res = getChildrenIntern(repositoryId, folderId, filter, orderBy, includeAllowableActions,
+        includeRelationships, renditionFilter, includePathSegments, maxItemsInt, 
+        skipCountInt, false);
+    log.debug("stop getChildren()");
+    return res;
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.client.provider.NavigationService#getDescendants(java.lang.String, java.lang.String, java.math.BigInteger, java.lang.String, java.lang.Boolean, org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<ObjectInFolderContainer> getDescendants(String repositoryId, String folderId,
+      BigInteger depth, String filter, Boolean includeAllowableActions,
+      IncludeRelationships includeRelationships, String renditionFilter,
+      Boolean includePathSegments, ExtensionsData extension) {
+    
+    log.debug("start getDescendants()");
+    checkStandardParameters(repositoryId, folderId);
+
+    int levels;
+    if (depth == null)
+      levels = 2; // one of the recommended defaults (should it be -1?)
+    else if (depth.intValue() == 0)
+      throw new CmisInvalidArgumentException("A zero depth is not allowed for getDescendants().");
+    else
+      levels = depth.intValue();
+    
+    int level = 0;
+    List<ObjectInFolderContainer> result = getDescendantsIntern(repositoryId, folderId,
+            filter, includeAllowableActions, includeRelationships, renditionFilter,
+            includePathSegments, level, levels, false);
+    log.debug("stop getDescendants()");
+    return result;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.client.provider.NavigationService#getFolderTree(java.lang.String, java.lang.String, java.math.BigInteger, java.lang.String, java.lang.Boolean, org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<ObjectInFolderContainer> getFolderTree(String repositoryId, String folderId,
+      BigInteger depth, String filter, Boolean includeAllowableActions,
+      IncludeRelationships includeRelationships, String renditionFilter,
+      Boolean includePathSegments, ExtensionsData extension) {
+
+    log.debug("start getFolderTree()");
+    checkStandardParameters(repositoryId, folderId);
+
+    if (depth == null || depth.intValue() == 0)
+      throw new CmisInvalidArgumentException("A zero depth is not allowed for getFolderTree().");
+    
+    int levels = depth.intValue();
+    int level = 0;
+    List<ObjectInFolderContainer> result = getDescendantsIntern(repositoryId, folderId,
+            filter, includeAllowableActions, includeRelationships, renditionFilter,
+            includePathSegments, level, levels, true);
+    log.debug("stop getFolderTree()");
+    return result;
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.client.provider.NavigationService#getFolderParent(java.lang.String, java.lang.String, java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectData getFolderParent(String repositoryId, String folderId, String filter,
+      ExtensionsData extension) {
+
+    log.debug("start getFolderParent()");
+    checkStandardParameters(repositoryId, folderId);
+
+    ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = fs.getObjectById(folderId);
+    Folder folder = null;
+    
+    if (so instanceof Folder)
+      folder = (Folder) so;
+    else
+      throw new CmisInvalidArgumentException("Can't get folder parent, id does not refer to a folder: "
+          + folderId);
+    
+    ObjectData res = getFolderParentIntern(repositoryId, folder, filter);
+    log.debug("stop getFolderParent()");
+    return res;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.opencmis.client.provider.NavigationService#getObjectParents(java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean, org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<ObjectParentData> getObjectParents(String repositoryId, String objectId,
+      String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includeRelativePathSegment, ExtensionsData extension) {
+
+    log.debug("start getObjectParents()");
+    checkStandardParameters(repositoryId, objectId);
+
+    // 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 = new ObjectParentDataImpl();
+    ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
+    
+    StoredObject so = fs.getObjectById(objectId);
+    Path spo = null;
+    
+    if (so instanceof Path)
+      spo = (Path) so;
+    else
+      throw new CmisInvalidArgumentException("Can't get object parent, id does not refer to a folder or document: "
+          + objectId);
+    
+    if (null != spo) {
+      result.setObject(getFolderParentIntern(repositoryId, spo, filter));
+      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);
+    }
+    log.debug("stop getObjectParents()");
+    return Collections.singletonList((ObjectParentData)result);
+  }
+
+  // private helpers
+  
+  private ObjectInFolderList getChildrenIntern(String repositoryId, String folderId, String filter,
+      String orderBy, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includePathSegments, int maxItems,
+      int skipCount, boolean folderOnly) {
+    
+    ObjectInFolderListImpl result = new ObjectInFolderListImpl();
+    List<ObjectInFolderData> folderList = new ArrayList<ObjectInFolderData>();
+    ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = fs.getObjectById(folderId);
+    Folder folder = null;
+
+    if (so instanceof Folder)
+      folder = (Folder) so;
+    else
+      return null; // it is a document and has no children
+
+    List<? extends StoredObject> children = folderOnly ? folder.getFolderChildren(maxItems,
+        skipCount) : folder.getChildren(maxItems, skipCount);
+    
+    List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
+    
+    for (StoredObject spo : children) {
+        ObjectInFolderDataImpl oifd = new ObjectInFolderDataImpl();
+        ObjectDataImpl objectData = new ObjectDataImpl();
+        if (includePathSegments!=null && includePathSegments)
+          oifd.setPathSegment(spo.getName());
+        if (includeAllowableActions!=null && includeAllowableActions) {
+          objectData.setAllowableActions(null /*f.getAllowableActions()*/);
+        }
+        if (includeRelationships!=null && includeRelationships != IncludeRelationships.NONE) {
+          objectData.setRelationships(null /*f.getRelationships()*/);
+        }
+        if (renditionFilter != null && renditionFilter.length() > 0) {
+          objectData.setRelationships(null /*f.getRenditions(renditionFilter)*/);
+        }
+        
+      PropertiesData props = PropertyCreationHelper.getPropertiesFromObject(repositoryId, spo,
+          fStoreManager, requestedIds);
+        objectData.setProperties(props);
+       
+        oifd.setObject(objectData);
+        folderList.add(oifd);
+      }
+    result.setObjects(folderList);
+    return result;
+  }
+
+  private List<ObjectInFolderContainer> getDescendantsIntern(String repositoryId, String folderId,
+      String filter, Boolean includeAllowableActions,
+      IncludeRelationships includeRelationships, String renditionFilter,
+      Boolean includePathSegments, int level, int maxLevels, boolean folderOnly) {
+  
+//    log.info("getDescendantsIntern: " + folderId + ", in level " + level 
+//        + ", max levels " + maxLevels);
+
+    List<ObjectInFolderContainer> childrenOfFolderId=null;
+    if (maxLevels==-1 || level < maxLevels) {
+      String orderBy = PropertyIds.CMIS_NAME;
+      ObjectInFolderList children = getChildrenIntern(repositoryId, folderId, filter, orderBy,
+          includeAllowableActions, includeRelationships, renditionFilter, includePathSegments, 1000, 0, folderOnly);
+      
+      if (null != children) {        
+        if (children.getObjects().size() > 0)
+          childrenOfFolderId = new ArrayList<ObjectInFolderContainer>();
+
+        for (ObjectInFolderData child : children.getObjects()) {      
+          ObjectInFolderContainerImpl oifc = new ObjectInFolderContainerImpl();
+          String childId = child.getObject().getId();
+          List<ObjectInFolderContainer> subChildren = getDescendantsIntern(repositoryId, childId,
+              filter, includeAllowableActions, includeRelationships, renditionFilter,
+              includePathSegments, level + 1, maxLevels, folderOnly);
+
+          oifc.setObject(child);
+          if (null != subChildren)
+            oifc.setChildren(subChildren);   
+          childrenOfFolderId.add(oifc);
+        }
+      }
+    }
+    return childrenOfFolderId;
+  }
+
+  private ObjectData getFolderParentIntern(String repositoryId, Path sop,
+      String filter) {
+
+    ObjectDataImpl parent = new ObjectDataImpl();
+
+    Folder parentFolder = sop.getParent();
+
+    if (parentFolder == null)
+      throw new CmisInvalidArgumentException("Cannot get parent of a root folder");
+
+    List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
+    PropertiesData props = PropertyCreationHelper.getPropertiesFromObject(repositoryId,
+        parentFolder, fStoreManager, requestedIds);
+    parent.setProperties(props);
+    return parent;
+  }
+
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/NavigationServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 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=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,838 @@
+/*
+ * 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;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+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.api.DocumentTypeDefinition;
+import org.apache.opencmis.commons.api.ExtensionsData;
+import org.apache.opencmis.commons.api.PropertyDefinition;
+import org.apache.opencmis.commons.api.TypeDefinition;
+import org.apache.opencmis.commons.enums.IncludeRelationships;
+import org.apache.opencmis.commons.enums.UnfileObjects;
+import org.apache.opencmis.commons.enums.Updatability;
+import org.apache.opencmis.commons.enums.VersioningState;
+import org.apache.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.opencmis.commons.exceptions.CmisNotSupportedException;
+import org.apache.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.apache.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl;
+import org.apache.opencmis.commons.impl.dataobjects.PropertiesDataImpl;
+import org.apache.opencmis.commons.provider.AccessControlList;
+import org.apache.opencmis.commons.provider.AllowableActionsData;
+import org.apache.opencmis.commons.provider.ContentStreamData;
+import org.apache.opencmis.commons.provider.FailedToDeleteData;
+import org.apache.opencmis.commons.provider.Holder;
+import org.apache.opencmis.commons.provider.ObjectData;
+import org.apache.opencmis.commons.provider.ObjectService;
+import org.apache.opencmis.commons.provider.PropertiesData;
+import org.apache.opencmis.commons.provider.PropertyData;
+import org.apache.opencmis.commons.provider.RenditionData;
+import org.apache.opencmis.inmemory.server.RuntimeContext;
+import org.apache.opencmis.inmemory.storedobj.api.Content;
+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.ObjectStore;
+import org.apache.opencmis.inmemory.storedobj.api.Path;
+import org.apache.opencmis.inmemory.storedobj.api.StoreManager;
+import org.apache.opencmis.inmemory.storedobj.api.StoredObject;
+import org.apache.opencmis.inmemory.storedobj.api.VersionedDocument;
+import org.apache.opencmis.inmemory.types.InMemoryDocumentTypeDefinition;
+import org.apache.opencmis.inmemory.types.InMemoryFolderTypeDefinition;
+import org.apache.opencmis.inmemory.types.PropertyCreationHelper;
+
+public class ObjectServiceImpl extends AbstractServiceImpl implements ObjectService {
+  private static Log log = LogFactory.getLog(ObjectService.class);
+
+  public ObjectServiceImpl(StoreManager storeManager) {
+    super(storeManager);
+    fStoreManager = storeManager;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#createDocument(java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.lang.String,
+   * org.apache.opencmis.client.provider.ContentStreamData,
+   * org.apache.opencmis.commons.enums.VersioningState, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createDocument(String repositoryId, PropertiesData properties, String folderId,
+      ContentStreamData contentStream, VersioningState versioningState, List<String> policies,
+      AccessControlList addACEs, AccessControlList removeACEs, ExtensionsData extension) {
+
+    log.debug("start createDocument()");
+    checkStandardParameters(repositoryId, folderId);
+
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+
+    // get name from properties
+    PropertyData<?> pd = properties.getProperties().get(PropertyIds.CMIS_NAME);
+    String name = (String) pd.getFirstValue();
+
+    // Validation stuff
+    StoredObject so = folderStore.getObjectById(folderId);
+    Folder folder = null;
+
+    if (null == so)
+      throw new CmisInvalidArgumentException(" Cannot create document, folderId: " + folderId
+          + " is invalid");
+
+    if (so instanceof Folder)
+      folder = (Folder) so;
+    else
+      throw new CmisInvalidArgumentException(
+          "Can't creat document, folderId does not refer to a folder: " + folderId);
+
+    TypeValidator.validateRequiredSystemProperties(properties);
+    TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
+    TypeValidator.validateAllowedChildObjectTypes(typeDef, folder.getAllowedChildObjectTypeIds());
+
+    // check if the given type is a document type
+    if (!typeDef.getBaseId().equals(
+        InMemoryDocumentTypeDefinition.getRootDocumentType().getBaseId()))
+      throw new RuntimeException("Cannot create a document, with a non-document type: " + typeDef.getId());
+
+    TypeValidator.validateVersionStateForCreate((DocumentTypeDefinition) typeDef, versioningState);
+    TypeValidator.validateProperties(typeDef, properties, true);
+
+    // set user, creation date, etc.
+    String user = RuntimeContext.getRuntimeConfigValue(ConfigConstants.USERNAME);
+    if (user == null)
+      user = "unknown";
+    
+    String resId = null;
+    
+    // Now we are sure to have document type definition:
+    if (((DocumentTypeDefinition)typeDef).isVersionable()) {
+      VersionedDocument verDoc = fStoreManager.getObjectStore(repositoryId).createVersionedDocument(name);
+      verDoc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+      verDoc.setCustomProperties(properties.getProperties());
+      DocumentVersion version = verDoc.addVersion(contentStream, versioningState, user);
+      // add document to folder
+      folder.addChildDocument(verDoc); // sets parent in doc
+      version.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+      version.setCustomProperties(properties.getProperties());
+      version.persist();
+      verDoc.persist();
+      resId = version.getId(); // return the version and not the version series to caller
+    } else {
+      Document doc = fStoreManager.getObjectStore(repositoryId).createDocument(name);
+      doc.setContent(contentStream, false);
+      // add document to folder
+      folder.addChildDocument(doc); // sets parent in doc
+      doc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+      doc.setCustomProperties(properties.getProperties());
+      doc.persist(); // first persist document, only if this succeeds persist folder with added child
+      resId = doc.getId();
+    }
+        
+    folder.persist();
+
+    // versioningState, policies, addACEs, removeACEs, extension are ignored for
+    // now.
+    log.debug("stop createDocument()");
+    return resId;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#createDocumentFromSource(java
+   * .lang.String, java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.lang.String,
+   * org.apache.opencmis.commons.enums.VersioningState, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createDocumentFromSource(String repositoryId, String sourceId,
+      PropertiesData properties, String folderId, VersioningState versioningState,
+      List<String> policies, AccessControlList addACEs, AccessControlList removeACEs,
+      ExtensionsData extension) {
+
+    log.debug("start createDocumentFromSource()");
+
+    checkStandardParameters(repositoryId, sourceId);
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    checkExistingObjectId(folderStore, sourceId);
+
+    ContentStreamData content = getContentStream(repositoryId, sourceId, null, BigInteger
+        .valueOf(-1), BigInteger.valueOf(-1), null);
+
+    // get all properties of existing document
+    StoredObject so = folderStore.getObjectById(sourceId);
+
+    if (so == null)
+      throw new CmisObjectNotFoundException("Unknown object id: " + sourceId);
+
+    // build properties collection
+    List<String> requestedIds = FilterParser.getRequestedIdsFromFilter("*");
+
+    PropertiesData existingProps = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so,
+        fStoreManager, requestedIds);
+
+    PropertiesDataImpl newPD = new PropertiesDataImpl();
+    // copy all existing properties
+    for (PropertyData<?> prop : existingProps.getProperties().values()) {
+      newPD.addProperty(prop);
+    }
+    // overwrite all new properties
+    for (PropertyData<?> prop : properties.getProperties().values()) {
+      newPD.addProperty(prop);
+    }
+
+    String res = createDocument(repositoryId, newPD, folderId, content, versioningState, policies,
+        addACEs, removeACEs, null);
+    log.debug("stop createDocumentFromSource()");
+    return res;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#createFolder(java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.lang.String,
+   * java.util.List, org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createFolder(String repositoryId, PropertiesData properties, String folderId,
+      List<String> policies, AccessControlList addACEs, AccessControlList removeACEs,
+      ExtensionsData extension) {
+    
+    log.debug("start createFolder()");
+    
+    checkStandardParameters(repositoryId, folderId);
+
+    ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = null;
+    Folder parent = null;
+
+    // get required properties
+    PropertyData<?> pd = properties.getProperties().get(PropertyIds.CMIS_NAME);
+    String folderName = (String) pd.getFirstValue();
+    if (null == folderName || folderName.length() == 0)
+      throw new CmisInvalidArgumentException("Cannot create a folder without a name.");
+
+    TypeValidator.validateRequiredSystemProperties(properties);
+
+    TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
+
+        // check if the given type is a folder type
+    if (!typeDef.getBaseId().equals(
+        InMemoryFolderTypeDefinition.getRootFolderType().getBaseId()))
+      throw new RuntimeException("Cannot create a folder, with a non-folder type: " + typeDef.getId());
+
+    TypeValidator.validateProperties(typeDef, properties, true);
+
+    // create folder
+    try {
+      log.info("get folder for id: " + folderId);
+      so = fs.getObjectById(folderId);
+    } catch (Exception e) {
+      throw new CmisObjectNotFoundException("Failed to retrieve folder.", e);
+    }
+
+    if (so instanceof Folder)
+      parent = (Folder) so;
+    else
+      throw new CmisInvalidArgumentException(
+          "Can't create folder, folderId does not refer to a folder: " + folderId);
+    try {
+      ObjectStore objStore = fStoreManager.getObjectStore(repositoryId);
+      Folder newFolder = objStore.createFolder(folderName);
+      // set default system attributes
+      String user = RuntimeContext.getRuntimeConfigValue(ConfigConstants.USERNAME);
+      if (user == null)
+        user = "unknown";
+      newFolder.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+      newFolder.setCustomProperties(properties.getProperties());
+      parent.addChildFolder(newFolder);
+      newFolder.persist();
+      parent.persist();
+      log.debug("stop createFolder()");
+      return newFolder.getId();
+    } catch (Exception e) {
+      throw new CmisInvalidArgumentException("Failed to create child folder.", e);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#createPolicy(java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.lang.String,
+   * java.util.List, org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createPolicy(String repositoryId, PropertiesData properties, String folderId,
+      List<String> policies, AccessControlList addACEs, AccessControlList removeACEs,
+      ExtensionsData extension) {
+    // TODO to be completed if ACLs are implemented
+    log.debug("start createPolicy()");
+    checkStandardParameters(repositoryId, folderId);
+    log.debug("stop createPolicy()");
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#createRelationship(java.lang
+   * .String, org.apache.opencmis.client.provider.PropertiesData, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createRelationship(String repositoryId, PropertiesData properties,
+      List<String> policies, AccessControlList addACEs, AccessControlList removeACEs,
+      ExtensionsData extension) {
+    // TODO to be completed if relationships are implemented
+    log.debug("start createRelationship()");
+    checkRepositoryId(repositoryId);
+    log.debug("stop createRelationship()");
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#deleteContentStream(java.lang
+   * .String, org.apache.opencmis.client.provider.Holder,
+   * org.apache.opencmis.client.provider.Holder,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void deleteContentStream(String repositoryId, Holder<String> objectId,
+      Holder<String> changeToken, ExtensionsData extension) {
+    log.debug("start deleteContentStream()");
+    checkStandardParameters(repositoryId, objectId.getValue());
+    
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = folderStore.getObjectById(objectId.getValue());
+
+    if (so == null)
+      throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+    if (!(so instanceof Document))
+      throw new CmisObjectNotFoundException("Id" + objectId
+          + " does not refer to a document, but only documents can have content");
+
+    ((Document) so).setContent(null, true);
+    log.debug("stop deleteContentStream()");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#deleteObject(java.lang.String,
+   * java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void deleteObject(String repositoryId, String objectId, Boolean allVersions,
+      ExtensionsData extension) {
+
+    log.debug("start deleteObject()");
+    checkStandardParameters(repositoryId, objectId);
+    ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
+    log.info("delete object for id: " + objectId);
+
+    // check if it is the root folder
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    if (objectId.equals(folderStore.getRootFolder().getId()))
+      throw new CmisNotSupportedException("You can't delete a root folder");
+
+    fs.deleteObject(objectId);
+    log.debug("stop deleteObject()");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#deleteTree(java.lang.String,
+   * java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.UnfileObject, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public FailedToDeleteData deleteTree(String repositoryId, String folderId, Boolean allVersions,
+      UnfileObjects unfileObject, Boolean continueOnFailure, ExtensionsData extension) {
+    log.debug("start deleteTree()");
+    checkStandardParameters(repositoryId, folderId);
+    List<String> failedToDeleteIds = new ArrayList<String>();
+    FailedToDeleteDataImpl result = new FailedToDeleteDataImpl();
+
+    if (null == allVersions)
+      allVersions = true;
+    if (null == unfileObject)
+      unfileObject = UnfileObjects.DELETE;
+    if (null == continueOnFailure)
+      continueOnFailure = false;
+    
+    
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = folderStore.getObjectById(folderId);
+
+    if (null == so)
+      throw new RuntimeException("Cannot delete object with id  " + folderId
+          + ". Object does not exist.");
+
+    if (!(so instanceof Folder))
+      throw new RuntimeException("deleteTree can only be invoked on a folder, but id " + folderId
+          + " does not refer to a folder");
+
+    if (unfileObject == UnfileObjects.UNFILE)
+      throw new CmisNotSupportedException("This repository does not support unfile operations.");
+
+    // check if it is the root folder
+    if (folderId.equals(folderStore.getRootFolder().getId()))
+      throw new CmisNotSupportedException("You can't delete a root folder");
+
+    // recursively delete folder
+    deleteRecursive(folderStore, (Folder) so, continueOnFailure, allVersions, failedToDeleteIds);
+
+    result.setIds(failedToDeleteIds);
+    log.debug("stop deleteTree()");
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#getAllowableActions(java.lang
+   * .String, java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public AllowableActionsData getAllowableActions(String repositoryId, String objectId,
+      ExtensionsData extension) {
+    log.debug("start getAllowableActions()");
+    checkStandardParameters(repositoryId, objectId);
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = folderStore.getObjectById(objectId);
+
+    if (so == null)
+      throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+    AllowableActionsData allowableActions = DataObjectCreator.fillAllowableActions(so);
+    log.debug("stop getAllowableActions()");
+    return allowableActions;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#getContentStream(java.lang.String
+   * , java.lang.String, java.lang.String, java.math.BigInteger,
+   * java.math.BigInteger, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ContentStreamData getContentStream(String repositoryId, String objectId, String streamId,
+      BigInteger offset, BigInteger length, ExtensionsData extension) {
+
+    log.debug("start getContentStream()");
+    checkStandardParameters(repositoryId, objectId);
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = folderStore.getObjectById(objectId);
+
+    if (so == null)
+      throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+    if (!(so instanceof Content))
+      throw new CmisObjectNotFoundException("Id" + objectId
+          + " does not refer to a document or version, but only those can have content");
+
+    ContentStreamData csd = getContentStream(so, streamId, offset, length);
+    log.debug("stop getContentStream()");
+    return csd;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#getObject(java.lang.String,
+   * java.lang.String, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String,
+   * java.lang.Boolean, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectData getObject(String repositoryId, String objectId, String filter,
+      Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includePolicyIds, Boolean includeACL, ExtensionsData extension) {
+
+    log.debug("start getObject()");
+    checkStandardParameters(repositoryId, objectId);
+    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = objectStore.getObjectById(objectId);
+
+    if (so == null)
+      throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+    ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter,
+        includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
+        includeACL, extension);
+    
+    log.debug("stop getObject()");
+    return od;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#getObjectByPath(java.lang.String
+   * , java.lang.String, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String,
+   * java.lang.Boolean, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectData getObjectByPath(String repositoryId, String path, String filter,
+      Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includePolicyIds, Boolean includeACL, ExtensionsData extension) {
+    log.debug("start getObjectByPath()");
+    checkRepositoryId(repositoryId);
+    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = objectStore.getObjectByPath(path);
+
+    if (so == null)
+      throw new CmisObjectNotFoundException("Unknown path: " + path);
+
+    ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter,
+        includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
+        includeACL, extension);
+    
+    log.debug("stop getObjectByPath()");
+    return od;
+  }
+
+  public PropertiesData getProperties(String repositoryId, String objectId, String filter,
+      ExtensionsData extension) {
+
+    log.debug("start getProperties()");
+    checkStandardParameters(repositoryId, objectId);
+
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = folderStore.getObjectById(objectId);
+
+    if (so == null)
+      throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+    // build properties collection
+    List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
+    PropertiesData props = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so,
+        fStoreManager, requestedIds);
+    log.debug("stop getProperties()");
+    return props;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#getRenditions(java.lang.String,
+   * java.lang.String, java.lang.String, java.math.BigInteger,
+   * java.math.BigInteger, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<RenditionData> getRenditions(String repositoryId, String objectId,
+      String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+    // TODO to be completed if renditions are implemented
+    log.debug("start getRenditions()");
+    checkStandardParameters(repositoryId, objectId);
+    log.debug("stop getRenditions()");
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#moveObject(java.lang.String,
+   * org.apache.opencmis.client.provider.Holder, java.lang.String, java.lang.String,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void moveObject(String repositoryId, Holder<String> objectId, String targetFolderId,
+      String sourceFolderId, ExtensionsData extension) {
+    log.debug("start moveObject()");
+    checkStandardParameters(repositoryId, objectId.getValue());
+    Folder targetFolder = null;
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = folderStore.getObjectById(objectId.getValue());
+    Path spo = null;
+
+    if (null == so)
+      throw new CmisObjectNotFoundException("Unknown object: " + objectId.getValue());
+    else if (so instanceof Path)
+      spo = (Path) so;
+    else
+      throw new CmisInvalidArgumentException("Object must be folder or document: "
+          + objectId.getValue());
+
+    StoredObject soTarget = folderStore.getObjectById(targetFolderId);
+    if (soTarget instanceof Folder)
+      targetFolder = (Folder) soTarget;
+    else
+      throw new CmisNotSupportedException("Destination of a move operation must be a folder");
+
+    if (so instanceof Folder && hasDescendant((Folder) so, targetFolder)) {
+      throw new CmisNotSupportedException(
+          "Destination of a move cannot be a subfolder of the source");
+    }
+    spo.move(targetFolder);
+    objectId.setValue(so.getId());
+    log.debug("stop moveObject()");
+  }
+
+  private boolean hasDescendant(Folder sourceFolder, Folder targetFolder) {
+    String sourceId = sourceFolder.getId();
+    String targetId = targetFolder.getId();
+    while (targetId != null) {
+      // log.info("comparing source id " + sourceId + " with predecessor " +
+      // targetId);
+      if (targetId.equals(sourceId))
+        return true;
+      targetFolder = targetFolder.getParent();
+      if (null != targetFolder)
+        targetId = targetFolder.getId();
+      else
+        targetId = null;
+    }
+    return false;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#setContentStream(java.lang.String
+   * , org.apache.opencmis.client.provider.Holder, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.Holder,
+   * org.apache.opencmis.client.provider.ContentStreamData,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void setContentStream(String repositoryId, Holder<String> objectId, Boolean overwriteFlag,
+      Holder<String> changeToken, ContentStreamData contentStream, ExtensionsData extension) {
+    
+    log.debug("start setContentStream()");
+    checkStandardParameters(repositoryId, objectId.getValue());
+
+    ObjectStore folderStore = fStoreManager.getObjectStore(repositoryId);
+    StoredObject so = folderStore.getObjectById(objectId.getValue());
+    Content content;
+
+    if (!(so instanceof Document || so instanceof VersionedDocument || so instanceof DocumentVersion))
+      throw new CmisObjectNotFoundException("Id" + objectId
+          + " does not refer to a document, but only documents can have content");
+    
+    if (so instanceof Document) 
+      content = ((Document) so);
+    else if (so instanceof DocumentVersion) {
+      // something that is versionable check the proper status of the object
+      String user = RuntimeContext.getRuntimeConfigValue(ConfigConstants.USERNAME);
+      testHasProperCheckedOutStatus(so, user);
+      content = (DocumentVersion) so;
+    } else
+      throw new IllegalArgumentException("Content cannot be set on this object (must be document or version)");
+
+    if (!overwriteFlag && content.getContent() != null)
+      throw new CmisConstraintException(
+          "cannot overwrite existing content if overwrite flag is not set");
+
+    content.setContent(contentStream, true);
+    log.debug("stop setContentStream()");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#updateProperties(java.lang.String
+   * , org.apache.opencmis.client.provider.Holder, org.apache.opencmis.client.provider.Holder,
+   * org.apache.opencmis.client.provider.PropertiesData,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void updateProperties(String repositoryId, Holder<String> objectId,
+      Holder<String> changeToken, PropertiesData properties, ExtensionsData extension) {
+
+    log.debug("start updateProperties()");
+    checkStandardParameters(repositoryId, objectId.getValue());
+    
+    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+    // Validation stuff
+    StoredObject so = objectStore.getObjectById(objectId.getValue());
+
+    TypeDefinition typeDef = getTypeDefinition(repositoryId, so);
+    boolean isCheckedOut = false;
+    
+    // if the object is a versionable object it must be checked-out
+    if (so instanceof VersionedDocument || so instanceof DocumentVersion) {
+      String user = RuntimeContext.getRuntimeConfigValue(ConfigConstants.USERNAME);
+      VersionedDocument verDoc = testIsNotCheckedOutBySomeoneElse(so, user); 
+      isCheckedOut = verDoc.isCheckedOut();
+      // so = verDoc; TODO
+    }
+
+    Map<String, PropertyData<?>> oldProperties = so.getProperties();
+
+    // check properties for validity
+    TypeValidator.validateProperties(typeDef, properties, false);
+
+    if (changeToken != null && changeToken.getValue() != null
+        && Long.valueOf(so.getChangeToken()) > Long.valueOf(changeToken.getValue()))
+      throw new CmisUpdateConflictException(" updateProperties failed: outdated changeToken");
+
+    // update properties
+    boolean hasUpdatedName = false;
+    boolean hasUpdatedOtherProps = false;
+
+    for (String key : properties.getProperties().keySet()) {
+      if (key.equals(PropertyIds.CMIS_NAME))
+        continue; // ignore here
+
+      PropertyData<?> value = properties.getProperties().get(key);
+      PropertyDefinition<?> propDef = typeDef.getPropertyDefinitions().get(key);
+      if (value.getValues() == null || value.getFirstValue() == null) {
+        // delete property
+        // check if a required a property
+        if (propDef.isRequired())
+          throw new CmisConstraintException(
+              "updateProperties failed, following property can't be deleted, because it is required: "
+                  + key);
+        oldProperties.remove(key);
+        hasUpdatedOtherProps = true;
+      } else {
+        if (propDef.getUpdatability().equals(Updatability.WHENCHECKEDOUT) && !isCheckedOut)
+          throw new CmisConstraintException(
+              "updateProperties failed, following property can't be updated, because it is not checked-out: "
+                  + key);
+        else if (!propDef.getUpdatability().equals(Updatability.READWRITE) )
+          throw new CmisConstraintException(
+              "updateProperties failed, following property can't be updated, because it is not writable: "
+                  + key);
+        oldProperties.put(key, value);
+        hasUpdatedOtherProps = true;
+      }
+    }
+
+    // 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)
+        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.");
+
+      so.rename((String) pd.getFirstValue()); // note: this does persist
+      hasUpdatedName = true;
+    }
+
+    if (hasUpdatedOtherProps) {
+      // set user, creation date, etc.
+      String user = RuntimeContext.getRuntimeConfigValue(ConfigConstants.USERNAME);
+
+      if (user == null)
+        user = "unknown";
+      so.updateSystemBasePropertiesWhenModified(properties.getProperties(), user);
+      // set changeToken
+      so.persist();
+    }
+
+    if (hasUpdatedName || hasUpdatedOtherProps) {
+      objectId.setValue(so.getId()); // might have a new id
+      if (null != changeToken) {
+        String changeTokenVal = so.getChangeToken();
+        log.info("updateProperties(), new change token is: " + changeTokenVal);
+        changeToken.setValue(changeTokenVal);
+      }
+    }
+    log.debug("stop updateProperties()");
+  }
+
+  // ///////////////////////////////////////////////////////
+  // private helper methods
+
+  /**
+   * Recursively delete a tree by traversing it and first deleting all children
+   * and then the object itself
+   * 
+   * @param folderStore
+   * @param parentFolder
+   * @param continueOnFailure
+   * @param allVersions
+   * @param failedToDeleteIds
+   * @return returns true if operation should continue, false if it should stop
+   */
+  private boolean deleteRecursive(ObjectStore folderStore, Folder parentFolder,
+      boolean continueOnFailure, boolean allVersions, List<String> failedToDeleteIds) {
+    List<StoredObject> children = parentFolder.getChildren(-1, -1);
+
+    if (null == children)
+      return true;
+
+    for (StoredObject child : children) {
+      if (child instanceof Folder) {
+        boolean mustContinue = deleteRecursive(folderStore, (Folder) child, continueOnFailure,
+            allVersions, failedToDeleteIds);
+        if (!mustContinue && !continueOnFailure)
+          return false; // stop further deletions
+      } else {
+        try {
+          folderStore.deleteObject(child.getId());
+        } catch (Exception e) {
+          failedToDeleteIds.add(child.getId());
+        }
+      }
+    }
+    folderStore.deleteObject(parentFolder.getId());
+    return true;
+  }
+
+  private ContentStreamData getContentStream(StoredObject so, String streamId, BigInteger offset,
+      BigInteger length) {
+
+    Long lOffset = offset == null ? null : offset.longValue();
+    Long lLength = length == null ? null : length.longValue();
+    ContentStreamData csd = ((Content) so).getContent();
+    return csd;
+  }
+
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/ObjectServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfo.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfo.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfo.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfo.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+public interface RepositoryInfo {
+  
+  String getRepositoryId();
+
+  String getTypeDefinitionsId();
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfoCreator.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfoCreator.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfoCreator.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfoCreator.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import org.apache.opencmis.commons.provider.RepositoryInfoData;
+
+/**
+ * A simple interface to create the repository info. This needs to be implemented by a client (like a unit
+ * test) in class and the name of the class is passed to the session. The in-memory repository
+ * creates an instance of this class to generate the repository info for its instance.
+ * 
+ * @author Jens
+ * 
+ */
+public interface RepositoryInfoCreator {
+  RepositoryInfoData createRepositoryInfo();
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryInfoCreator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryServiceImpl.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryServiceImpl.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryServiceImpl.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,213 @@
+/*
+ * 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;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.opencmis.commons.api.ExtensionsData;
+import org.apache.opencmis.commons.api.TypeDefinition;
+import org.apache.opencmis.commons.api.TypeDefinitionContainer;
+import org.apache.opencmis.commons.api.TypeDefinitionList;
+import org.apache.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.opencmis.commons.impl.dataobjects.AbstractTypeDefinition;
+import org.apache.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
+import org.apache.opencmis.commons.impl.dataobjects.TypeDefinitionListImpl;
+import org.apache.opencmis.commons.provider.RepositoryInfoData;
+import org.apache.opencmis.commons.provider.RepositoryService;
+import org.apache.opencmis.inmemory.storedobj.api.StoreManager;
+
+/**
+ * InMemory Repository Service.
+ * 
+ * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
+ * 
+ */
+public class RepositoryServiceImpl extends AbstractServiceImpl implements RepositoryService {
+
+  /**
+   * Constructor.
+   */
+  public RepositoryServiceImpl(StoreManager storeManager) {
+    super (storeManager);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getRepositoryInfo(java.lang.String,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public RepositoryInfoData getRepositoryInfo(String repositoryId, ExtensionsData extension) {
+    RepositoryInfoData repoInfo = getRepositoryInfoFromStoreManager(repositoryId);
+
+    return repoInfo;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getRepositoryInfos(boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<RepositoryInfoData> getRepositoryInfos(ExtensionsData extension) {
+    List<RepositoryInfoData> res = new ArrayList<RepositoryInfoData>();
+    List<String> repIds = fStoreManager.getAllRepositoryIds();
+    for (String repId : repIds) {
+      res.add(fStoreManager.getRepositoryInfo(repId));
+    }
+    return res;
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getTypeChildren(java.lang.String,
+   * java.lang.String, java.lang.Boolean, java.math.BigInteger, java.math.BigInteger,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public TypeDefinitionList getTypeChildren(String repositoryId, String typeId,
+      Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount,
+      ExtensionsData extension) {
+
+    getRepositoryInfoFromStoreManager(repositoryId); // just to check if repository exists
+
+    int skip = skipCount == null ? 0 : skipCount.intValue();
+    int max = maxItems == null ? -1 : maxItems.intValue();
+      
+    TypeDefinitionListImpl result = new TypeDefinitionListImpl();
+    List<TypeDefinitionContainer> children = getTypeDescendants(repositoryId, typeId, 
+        BigInteger.valueOf(1), includePropertyDefinitions, null);
+    result.setNumItems(BigInteger.valueOf(children.size()));
+    result.setHasMoreItems(children.size() > max - skip);
+    List<TypeDefinition> childrenTypes = new ArrayList<TypeDefinition>();
+    ListIterator<TypeDefinitionContainer> it = children.listIterator(skip);
+    if (max<0)
+      max = children.size();
+    for (int i=0; i<max && it.hasNext(); i++)
+      childrenTypes.add(it.next().getTypeDefinition());
+
+    result.setList(childrenTypes);      
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getTypeDefinition(java.lang.String,
+   * java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public TypeDefinition getTypeDefinition(String repositoryId, String typeId,
+      ExtensionsData extension) {
+    
+    getRepositoryInfoFromStoreManager(repositoryId); // just to check if repository exists
+
+    TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId);
+    if (tc != null) {
+      return tc.getTypeDefinition();
+    }
+    else
+      throw new CmisObjectNotFoundException("unknown type id: " + typeId);        
+ }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getTypeDescendants(java.lang.String,
+   * java.lang.String, java.math.BigInteger, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<TypeDefinitionContainer> getTypeDescendants(String repositoryId, String typeId,
+      BigInteger depth, Boolean includePropertyDefinitions, ExtensionsData extension) {
+    
+    getRepositoryInfoFromStoreManager(repositoryId); // just to check if repository exists
+
+    if (depth != null && depth.intValue() == 0)
+      throw new CmisInvalidArgumentException("depth == 0 is illegal in getTypeDescendants");
+    
+    List<TypeDefinitionContainer> result =  null;
+    if (typeId == null) {
+      // spec says that depth must be ignored in this case
+        Collection<TypeDefinitionContainer> typeColl = fStoreManager.getTypeDefinitionList(repositoryId);
+        result = new ArrayList<TypeDefinitionContainer>(typeColl);
+    }
+    else {
+      TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId);
+      if (tc != null) {
+        if (null==depth || depth.intValue() == -1)
+          result = tc.getChildren();
+        else {
+          result = getLimitedChildrenTypeList(depth.intValue(), tc.getChildren());
+        }
+      }
+      else
+        throw new CmisInvalidArgumentException("unknown type id: " + typeId);        
+    }
+    
+    if (!includePropertyDefinitions) {
+      // copy list and omit properties
+      List<TypeDefinitionContainer> newResult = new ArrayList<TypeDefinitionContainer>(result.size());
+      for (TypeDefinitionContainer c : result) {
+        AbstractTypeDefinition td = ((AbstractTypeDefinition)c.getTypeDefinition()).clone();
+        TypeDefinitionContainerImpl tdc = new TypeDefinitionContainerImpl(td);
+        tdc.setChildren(c.getChildren());
+        td.setPropertyDefinitions(null);
+        newResult.add(tdc);
+      }
+      result = newResult;
+    }
+    return result;
+  }
+
+ 
+  private List<TypeDefinitionContainer> getLimitedChildrenTypeList(int depth,
+      List<TypeDefinitionContainer> types) {
+    List<TypeDefinitionContainer> result = new ArrayList<TypeDefinitionContainer>();
+
+    for (TypeDefinitionContainer type : types) {
+      result.addAll(getLimitedChildrenTypeList(depth, type));
+    }
+    return result;
+  }
+
+  private List<TypeDefinitionContainer> getLimitedChildrenTypeList(int depth,
+      TypeDefinitionContainer root) {
+    List<TypeDefinitionContainer> typeDescs = new ArrayList<TypeDefinitionContainer>();
+    if (depth > 0 && root != null) {
+      typeDescs.add(root);
+      for (TypeDefinitionContainer c : root.getChildren()) {
+        typeDescs.addAll(getLimitedChildrenTypeList(depth - 1, c));
+      }
+    }
+    return typeDescs;
+  }
+
+  private RepositoryInfoData getRepositoryInfoFromStoreManager(String repositoryId ) {
+    RepositoryInfoData repoInfo = fStoreManager.getRepositoryInfo(repositoryId);
+    if (null == repoInfo || !repoInfo.getRepositoryId().equals(repositoryId)) {
+      throw new CmisInvalidArgumentException("Unknown repository: " + repositoryId);
+    }
+    return repoInfo;
+  }
+
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/RepositoryServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeCreator.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeCreator.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeCreator.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeCreator.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.apache.opencmis.commons.api.TypeDefinition;
+
+/**
+ * A simple interface to create a type system. This needs to be implemented by a client (like a unit
+ * test) in class and the name of the class is passed to the session. The in-memory repository
+ * creates an instance of this class to generate the type system for this instance
+ * 
+ * @author Jens
+ * 
+ */
+public interface TypeCreator {
+
+  List<TypeDefinition> createTypesList();
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeCreator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeManager.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeManager.java?rev=910572&view=auto
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeManager.java (added)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeManager.java Tue Feb 16 16:03:38 2010
@@ -0,0 +1,223 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.opencmis.commons.api.PropertyDefinition;
+import org.apache.opencmis.commons.api.TypeDefinition;
+import org.apache.opencmis.commons.api.TypeDefinitionContainer;
+import org.apache.opencmis.commons.impl.Converter;
+import org.apache.opencmis.commons.impl.dataobjects.AbstractPropertyDefinition;
+import org.apache.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
+import org.apache.opencmis.commons.impl.jaxb.CmisPropertyDefinitionType;
+import org.apache.opencmis.inmemory.types.DocumentTypeCreationHelper;
+import org.apache.opencmis.inmemory.types.InMemoryDocumentTypeDefinition;
+import org.apache.opencmis.inmemory.types.InMemoryFolderTypeDefinition;
+import org.apache.opencmis.inmemory.types.InMemoryPolicyTypeDefinition;
+import org.apache.opencmis.inmemory.types.InMemoryRelationshipTypeDefinition;
+
+/**
+ * Class that manages a type system for a repository types can be added, the inheritance can be
+ * managed and type can be retrieved for a given type id.
+ * 
+ * @author Jens
+ * 
+ */
+public class TypeManager {
+
+  /**
+   * map from repository id to a types map
+   */
+  private Map<String, TypeDefinitionContainer> fTypesMap = new HashMap<String, TypeDefinitionContainer>();
+
+  /**
+   * return a type definition from the type definition id
+   * 
+   * @param typeId
+   *    id of the type definition
+   * @return
+   *    type definition for this id
+   */
+  public TypeDefinitionContainer getTypeById(String typeId) {
+    return fTypesMap.get(typeId);
+  }
+
+  /**
+   * return a list of all types known in this repository
+   * @return
+   */
+  public synchronized Collection<TypeDefinitionContainer> getTypeDefinitionList() {
+    return fTypesMap.values();
+  }
+
+  /**
+   * return a list of the root types as defined in the CMIS spec (for document,
+   * folder, policy and relationship
+   * 
+   * @return
+   */
+  public List<TypeDefinitionContainer> getRootTypes() {
+    // just take first repository
+    List<TypeDefinitionContainer> rootTypes = new ArrayList<TypeDefinitionContainer>();
+
+    for (TypeDefinitionContainer type : fTypesMap.values())
+      if (isRootType(type))
+        rootTypes.add(type);
+
+    return rootTypes;
+  }
+
+  /**
+   * Initialize the type system with the given types. This list must not contain the CMIS
+   * default types. The default type are always contained by default.
+   * 
+   * @param typesList
+   *    list of types to add to the repository
+   *    
+   */
+  public void initTypeSystem(List<TypeDefinition> typesList) {
+    
+    createCmisDefaultTypes();
+    
+    // merge all types from the list and build the correct hierachy with children
+    // and property lists
+    if (null != typesList) {
+      for (TypeDefinition typeDef : typesList)
+        addTypeDefinition(typeDef);
+    }
+
+  }
+  
+
+  /**
+   * Add a type to the type system. Add all properties from inherited types, add type to children of
+   * parent types.
+   * 
+   * @param repositoryId
+   *          repository to which the type is added
+   * @param cmisType
+   *          new type to add
+   */
+  public void addTypeDefinition(TypeDefinition cmisType) {
+    if (fTypesMap.containsKey(cmisType.getId()))
+      throw new RuntimeException("You cannot add type with id " + cmisType.getId()
+          + " because it already exists.");
+
+    TypeDefinitionContainerImpl typeContainer = new TypeDefinitionContainerImpl(cmisType);
+
+    if (!fTypesMap.containsKey(cmisType.getParentId()))
+      throw new RuntimeException("Cannot add type, because parent with id "
+          + cmisType.getParentId() + " does not exist.");
+
+    // add new type to children of parent types
+    TypeDefinitionContainer parentTypeContainer = fTypesMap.get(cmisType.getParentId());
+    parentTypeContainer.getChildren().add(typeContainer);
+
+    // recursively add inherited properties
+    Map<String, PropertyDefinition<?>> propDefs = typeContainer.getTypeDefinition()
+        .getPropertyDefinitions();
+    addInheritedProperties(propDefs, parentTypeContainer.getTypeDefinition());
+
+    // add type to type map
+    fTypesMap.put(cmisType.getId(), typeContainer);
+  }
+
+  /**
+   * Remove all types from the type system. After this call only the default CMIS types are present
+   * in the type system. Use this method with care, its mainly intended for unit tests
+   * 
+   * @param repositoryId
+   */
+  public void clearTypeSystem() {
+    fTypesMap.clear();
+    createCmisDefaultTypes();
+  }
+
+  private void addInheritedProperties(Map<String, PropertyDefinition<?>> propDefs,
+      TypeDefinition typeDefinition) {
+
+    if (null == typeDefinition)
+      return;
+
+    if (null != typeDefinition.getPropertyDefinitions())
+      addInheritedPropertyDefinitions(propDefs, typeDefinition.getPropertyDefinitions());
+      // propDefs.putAll(typeDefinition.getPropertyDefinitions());
+
+    TypeDefinitionContainer parentTypeContainer = fTypesMap.get(typeDefinition.getParentId());
+    TypeDefinition parentType = (null == parentTypeContainer ? null : parentTypeContainer
+        .getTypeDefinition());
+    addInheritedProperties(propDefs, parentType);
+  }
+
+  private void addInheritedPropertyDefinitions(Map<String, PropertyDefinition<?>> propDefs,
+      Map<String, PropertyDefinition<?>> superPropDefs) {
+    
+    for (Entry<String, PropertyDefinition<?>> superProp: superPropDefs.entrySet() ) {
+      PropertyDefinition<?> superPropDef = superProp.getValue();
+      PropertyDefinition<?> clone = clonePropertyDefinition(superPropDef);
+      ((AbstractPropertyDefinition<?>)clone).setIsInherited(true);
+      propDefs.put(superProp.getKey(), clone);
+    }
+  }
+
+  private void createCmisDefaultTypes() {
+    List<TypeDefinition> typesList = DocumentTypeCreationHelper.createDefaultTypes();
+    for (TypeDefinition typeDef : typesList) {
+      TypeDefinitionContainerImpl typeContainer = new TypeDefinitionContainerImpl(typeDef);
+      fTypesMap.put(typeDef.getId(), typeContainer);
+    }
+  }
+
+  private static boolean isRootType(TypeDefinitionContainer c) {
+    if (c.getTypeDefinition().equals(InMemoryFolderTypeDefinition.getRootFolderType())
+        || c.getTypeDefinition().equals(InMemoryDocumentTypeDefinition.getRootDocumentType())
+        || c.getTypeDefinition().equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType())
+        || c.getTypeDefinition().equals(InMemoryPolicyTypeDefinition.getRootPolicyType()))
+      return true;
+    else
+      return false;
+  }
+  
+  private static PropertyDefinition<?> clonePropertyDefinition(PropertyDefinition<?> src) {
+    // use JAXB converter to easily clone a property definition
+    CmisPropertyDefinitionType tmp = Converter.convert(src);
+    PropertyDefinition<?> clone = Converter.convert(tmp);
+    return clone;
+  }
+  
+//  private static PropertyDefinition<?> clonePropertyDefinition2(PropertyDefinition<?> src)
+//      throws IOException, ClassNotFoundException {
+//    ByteArrayOutputStream bout = new ByteArrayOutputStream();
+//    ObjectOutputStream oout = new ObjectOutputStream(bout);
+//    oout.writeObject(src);
+//    byte[] bytes = bout.toByteArray();
+//
+//    ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+//    ObjectInputStream oin = new ObjectInputStream(bin);
+//    PropertyDefinition<?> clone = (PropertyDefinition<?>) oin.readObject();
+//    return clone;
+//  }
+
+}

Propchange: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/TypeManager.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message