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/04/16 16:00:25 UTC

svn commit: r934878 [4/13] - in /incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src: main/java/org/apache/chemistry/opencmis/inmemory/ main/java/org/apache/chemistry/opencmis/inmemory/clientprovider/ mai...

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java?rev=934878&r1=934877&r2=934878&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java Fri Apr 16 14:00:23 2010
@@ -75,932 +75,906 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 public class InMemoryObjectServiceImpl extends AbstractServiceImpl implements CmisObjectService {
-  private static final Log LOG = LogFactory.getLog(ServiceFactory.class.getName());
+	private static final Log LOG = LogFactory.getLog(ServiceFactory.class.getName());
 
-  AtomLinkInfoProvider fAtomLinkProvider;
+	AtomLinkInfoProvider fAtomLinkProvider;
 
-  public InMemoryObjectServiceImpl(StoreManager storeManager) {
-    super(storeManager);
-    fAtomLinkProvider = new AtomLinkInfoProvider(fStoreManager);
-  }
-
-  public String createDocument(CallContext context, String repositoryId, Properties properties,
-      String folderId, ContentStream contentStream, VersioningState versioningState,
-      List<String> policies, Acl addAces, Acl removeAces,
-      ExtensionsData extension) {
-
-    try {
-      LOG.debug("start createDocument()");
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      StoredObject so = createDocumentIntern(repositoryId, properties, folderId, contentStream,
-          versioningState, policies, addAces, removeAces, extension);
-      LOG.debug("stop createDocument()");
-      return so.getId();
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public String createDocumentFromSource(CallContext context, String repositoryId, String sourceId,
-      Properties properties, String folderId, VersioningState versioningState,
-      List<String> policies, Acl addAces, Acl removeAces,
-      ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start createDocumentFromSource()");
-
-      StoredObject so = checkStandardParameters(repositoryId, sourceId);
-
-      ContentStream content = getContentStream(context, repositoryId, sourceId, null,
-          BigInteger.valueOf(-1), BigInteger.valueOf(-1), null);
-
-      if (so == null)
-        throw new CmisObjectNotFoundException("Unknown object id: " + sourceId);
-
-      // build properties collection
-      List<String> requestedIds = FilterParser.getRequestedIdsFromFilter("*");
-
-      Properties existingProps = PropertyCreationHelper.getPropertiesFromObject(repositoryId,
-          so, fStoreManager, requestedIds);
-
-      PropertiesImpl newPD = new PropertiesImpl();
-      // 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(context, repositoryId, newPD, folderId, content, versioningState,
-          policies, addAces, removeAces, null);
-      LOG.debug("stop createDocumentFromSource()");
-      return res;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public String createFolder(CallContext context, String repositoryId, Properties properties,
-      String folderId, List<String> policies, Acl addAces,
-      Acl removeAces, ExtensionsData extension) {
-    try {
-      LOG.debug("start createFolder()");
-      RuntimeContext.attachCfg(context);
-
-      Folder folder = createFolderIntern(repositoryId, properties, folderId, policies, addAces,
-          removeAces, extension);
-      LOG.debug("stop createFolder()");
-      return folder.getId();
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public String createPolicy(CallContext context, String repositoryId, Properties properties,
-      String folderId, List<String> policies, Acl addAces,
-      Acl removeAces, ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      // TODO to be completed if ACLs are implemented
-      LOG.debug("start createPolicy()");
-      checkStandardParameters(repositoryId, folderId);
-      StoredObject so = createPolicyIntern(repositoryId, properties, folderId, policies, addAces,
-          removeAces, extension);
-      LOG.debug("stop createPolicy()");
-      return so == null ? null : so.getId();
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public String createRelationship(CallContext context, String repositoryId,
-      Properties properties, List<String> policies, Acl addAces,
-      Acl removeAces, ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      // TODO to be completed if relationships are implemented
-      LOG.debug("start createRelationship()");
-      checkRepositoryId(repositoryId);
-      StoredObject so = createRelationshipIntern(repositoryId, properties, policies, addAces,
-          removeAces, extension);
-      LOG.debug("stop createRelationship()");
-      return so == null ? null : so.getId();
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  /*
-   * (non-Javadoc)
-   * 
-   * @see org.opencmis.server.spi.CmisObjectService#create(org.opencmis.server.spi.CallContext,
-   * java.lang.String, org.opencmis.client.provider.PropertiesData, java.lang.String,
-   * org.opencmis.client.provider.ContentStreamData, org.opencmis.commons.enums.VersioningState,
-   * org.opencmis.client.provider.ExtensionsData, org.opencmis.server.spi.ObjectInfoHolder)
-   * 
-   * An additional create call compared to the ObjectService from the CMIS spec. This one is needed
-   * because the Atom binding in the server implementation does not know what kind of object needs
-   * to be created. Also the ObjectInfoHolder needs to be filled.
-   */
-  @SuppressWarnings("unchecked")
-  public ObjectData create(CallContext context, String repositoryId, Properties properties,
-      String folderId, ContentStream contentStream, VersioningState versioningState,
-      List<String> policies, ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      if (null == properties || null == properties.getProperties())
-        throw new RuntimeException("Cannot create object, without properties.");
-
-      // Find out what kind of object needs to be created
-      PropertyData<String> pd = (PropertyData<String>) properties.getProperties().get(
-          PropertyIds.OBJECT_TYPE_ID);
-      String typeId = pd == null ? null : pd.getFirstValue();
-      if (null == typeId)
-        throw new RuntimeException(
-            "Cannot create object, without a type (no property with id CMIS_OBJECT_TYPE_ID).");
-
-      TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, typeId);
-      if (typeDefC == null)
-        throw new RuntimeException("Cannot create object, a type with id " + typeId + " is unknown");
-
-      // check if the given type is a document type
-      BaseTypeId typeBaseId = typeDefC.getTypeDefinition().getBaseTypeId();
-      StoredObject so = null;
-      if (typeBaseId.equals(InMemoryDocumentTypeDefinition.getRootDocumentType().getBaseTypeId())) {
-        so = createDocumentIntern(repositoryId, properties, folderId, contentStream,
-            versioningState, null, null, null, null);
-      }
-      else if (typeBaseId.equals(InMemoryFolderTypeDefinition.getRootFolderType().getBaseTypeId())) {
-        so = createFolderIntern(repositoryId, properties, folderId, null, null, null, null);
-      }
-      else if (typeBaseId.equals(InMemoryPolicyTypeDefinition.getRootPolicyType().getBaseTypeId())) {
-        so = createPolicyIntern(repositoryId, properties, folderId, null, null, null, null);
-      }
-      else if (typeBaseId.equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType()
-          .getBaseTypeId())) {
-        so = createRelationshipIntern(repositoryId, properties, null, null, null, null);
-      }
-      else
-        LOG.error("The type contains an unknown base object id, object can't be created");
-
-      // Make a call to getObject to convert the resulting id into an ObjectData
-      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
-          IncludeRelationships.NONE, null, false, false, extension);
-
-      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-      return od;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public void deleteContentStream(CallContext context, String repositoryId,
-      Holder<String> objectId, Holder<String> changeToken, ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start deleteContentStream()");
-      StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
-
-      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, but only documents can have content");
-
-      ((Content) so).setContent(null, true);
-      LOG.debug("stop deleteContentStream()");
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public void deleteObjectOrCancelCheckOut(CallContext context, String repositoryId,
-      String objectId, Boolean allVersions, ExtensionsData extension) {
-
-    try {
-      LOG.debug("start deleteObject()");
-      checkStandardParameters(repositoryId, objectId);
-      ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-      LOG.info("delete object for id: " + objectId);
-
-      // check if it is the root folder
-      if (objectId.equals(objectStore.getRootFolder().getId()))
-        throw new CmisNotSupportedException("You can't delete a root folder");
-
-      objectStore.deleteObject(objectId);
-      LOG.debug("stop deleteObject()");
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public FailedToDeleteData deleteTree(CallContext context, String repositoryId, String folderId,
-      Boolean allVersions, UnfileObject unfileObjects, Boolean continueOnFailure,
-      ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start deleteTree()");
-      StoredObject so = checkStandardParameters(repositoryId, folderId);
-      List<String> failedToDeleteIds = new ArrayList<String>();
-      FailedToDeleteDataImpl result = new FailedToDeleteDataImpl();
-
-      if (null == allVersions)
-        allVersions = true;
-      if (null == unfileObjects)
-        unfileObjects = UnfileObject.DELETE;
-      if (null == continueOnFailure)
-        continueOnFailure = false;
-
-      ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-
-      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 (unfileObjects == UnfileObject.UNFILE)
-        throw new CmisNotSupportedException("This repository does not support unfile operations.");
-
-      // check if it is the root folder
-      if (folderId.equals(objectStore.getRootFolder().getId()))
-        throw new CmisNotSupportedException("You can't delete a root folder");
-
-      // recursively delete folder
-      deleteRecursive(objectStore, (Folder) so, continueOnFailure, allVersions, failedToDeleteIds);
-
-      result.setIds(failedToDeleteIds);
-      LOG.debug("stop deleteTree()");
-      return result;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public AllowableActions getAllowableActions(CallContext context, String repositoryId,
-      String objectId, ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start getAllowableActions()");
-      StoredObject so = checkStandardParameters(repositoryId, objectId);
-      ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-
-      if (so == null)
-        throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
-      AllowableActions allowableActions = DataObjectCreator.fillAllowableActions(objectStore,
-          so);
-      LOG.debug("stop getAllowableActions()");
-      return allowableActions;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public ContentStream getContentStream(CallContext context, String repositoryId,
-      String objectId, String streamId, BigInteger offset, BigInteger length,
-      ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start getContentStream()");
-      StoredObject so = checkStandardParameters(repositoryId, 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");
-
-      ContentStream csd = getContentStream(so, streamId, offset, length);
-      LOG.debug("stop getContentStream()");
-      return csd;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public ObjectData getObject(CallContext context, String repositoryId, String objectId,
-      String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
-      String renditionFilter, Boolean includePolicyIds, Boolean includeAcl,
-      ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
-    try {
-      LOG.debug("start getObject()");
-
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      StoredObject so = checkStandardParameters(repositoryId, objectId);
-
-      if (so == null)
-        throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
-      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter,
-          includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
-          includeAcl, extension);
-
-      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
-      LOG.debug("stop getObject()");
-
-      return od;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public ObjectData getObjectByPath(CallContext context, String repositoryId, String path,
-      String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
-      String renditionFilter, Boolean includePolicyIds, Boolean includeAcl,
-      ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      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()");
-
-      // To be able to provide all Atom links in the response we need additional information:
-      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
-      return od;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public Properties getProperties(CallContext context, String repositoryId, String objectId,
-      String filter, ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start getProperties()");
-      StoredObject so = checkStandardParameters(repositoryId, objectId);
-
-      if (so == null)
-        throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
-
-      // build properties collection
-      List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
-      Properties props = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so,
-          fStoreManager, requestedIds);
-      LOG.debug("stop getProperties()");
-      return props;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public List<RenditionData> getRenditions(CallContext context, String repositoryId,
-      String objectId, String renditionFilter, BigInteger maxItems, BigInteger skipCount,
-      ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      // TODO to be completed if renditions are implemented
-      LOG.debug("start getRenditions()");
-      checkStandardParameters(repositoryId, objectId);
-      LOG.debug("stop getRenditions()");
-      return null;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public ObjectData moveObject(CallContext context, String repositoryId, Holder<String> objectId,
-      String targetFolderId, String sourceFolderId, ExtensionsData extension,
-      ObjectInfoHolder objectInfos) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start moveObject()");
-      StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
-      Folder targetFolder = null;
-      Folder sourceFolder = null;
-      ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-      Filing spo = null;
-
-      if (null == so)
-        throw new CmisObjectNotFoundException("Unknown object: " + objectId.getValue());
-      else if (so instanceof Filing)
-        spo = (Filing) so;
-      else
-        throw new CmisInvalidArgumentException("Object must be folder or document: "
-            + objectId.getValue());
-
-      StoredObject soTarget = objectStore.getObjectById(targetFolderId);
-      if (null == soTarget)
-        throw new CmisObjectNotFoundException("Unknown target folder: " + targetFolderId);
-      else if (soTarget instanceof Folder)
-        targetFolder = (Folder) soTarget;
-      else
-        throw new CmisNotSupportedException("Destination " + targetFolderId
-            + " of a move operation must be a folder");
-
-      StoredObject soSource = objectStore.getObjectById(sourceFolderId);
-      if (null == soSource)
-        throw new CmisObjectNotFoundException("Unknown source folder: " + sourceFolderId);
-      else if (soSource instanceof Folder)
-        sourceFolder = (Folder) soSource;
-      else
-        throw new CmisNotSupportedException("Source " + sourceFolderId
-            + " of a move operation must be a folder");
-
-      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");
-      }
-
-      spo.move(sourceFolder, targetFolder);
-      objectId.setValue(so.getId());
-      LOG.debug("stop moveObject()");
-
-      // To be able to provide all Atom links in the response we need additional information:
-      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
-      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
-          IncludeRelationships.NONE, null, false, false, extension);
-
-      return od;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public void setContentStream(CallContext context, String repositoryId, Holder<String> objectId,
-      Boolean overwriteFlag, Holder<String> changeToken, ContentStream contentStream,
-      ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      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(CallContext.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(0, -1) != null)
-        throw new CmisConstraintException(
-            "cannot overwrite existing content if overwrite flag is not set");
-
-      content.setContent(contentStream, true);
-      LOG.debug("stop setContentStream()");
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public ObjectData updateProperties(CallContext context, String repositoryId,
-      Holder<String> objectId, Holder<String> changeToken, Properties properties,
-      Acl acl, ExtensionsData extension, ObjectInfoHolder objectInfos) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      LOG.debug("start updateProperties()");
-      StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
-
-      // Validation
-      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(CallContext.USERNAME);
-        // VersionedDocument verDoc = testIsNotCheckedOutBySomeoneElse(so, user);
-        testHasProperCheckedOutStatus(so, user);
-        isCheckedOut = true;
-      }
-
-      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.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.NAME);
-      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");
-        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;
-      }
-
-      if (hasUpdatedOtherProps) {
-        // set user, creation date, etc.
-        String user = RuntimeContext.getRuntimeConfigValue(CallContext.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);
-        }
-      }
-
-      if (null != acl) {
-        LOG.warn("Setting ACLs is currently not supported by this implementation, acl is ignored");
-        // if implemented add this call:
-        // fAclService.appyAcl(context, repositoryId, acl, null, AclPropagation.OBJECTONLY,
-        // extension);
-      }
-
-      // To be able to provide all Atom links in the response we need additional information:
-      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-
-      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
-          IncludeRelationships.NONE, null, false, false, extension);
-
-      LOG.debug("stop updateProperties()");
-
-      return od;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  // ///////////////////////////////////////////////////////
-  // private helper methods
-
-  private StoredObject createDocumentIntern(String repositoryId, Properties properties,
-      String folderId, ContentStream contentStream, VersioningState versioningState,
-      List<String> policies, Acl addACEs, Acl removeACEs,
-      ExtensionsData extension) {
-    checkRepositoryId(repositoryId);
-
-    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-
-    // get name from properties
-    PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
-    String name = (String) pd.getFirstValue();
-
-    // Validation stuff
-    TypeValidator.validateRequiredSystemProperties(properties);
-    TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
-
-    Folder folder = null;
-    if (null != folderId) {
-      StoredObject so = objectStore.getObjectById(folderId);
-
-      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.validateAllowedChildObjectTypes(typeDef, folder.getAllowedChildObjectTypeIds());
-    }
-
-    // check if the given type is a document type
-    if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_DOCUMENT))
-      throw new RuntimeException("Cannot create a document, with a non-document type: "
-          + typeDef.getId());
-
-    // check name syntax
-    if (!NameValidator.isValidId(name))
-      throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
-
-    TypeValidator.validateVersionStateForCreate((DocumentTypeDefinition) typeDef, versioningState);
-    TypeValidator.validateProperties(typeDef, properties, true);
-
-    // set user, creation date, etc.
-    String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
-    if (user == null)
-      user = "unknown";
-
-    StoredObject so = 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);
-      if (null != folder)
-        folder.addChildDocument(verDoc); // add document to folder and set parent in doc
-      else
-        verDoc.persist();
-      version.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
-      version.setCustomProperties(properties.getProperties());
-      version.persist();
-      so = version; // 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
-      doc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
-      doc.setCustomProperties(properties.getProperties());
-      if (null != folder)
-        folder.addChildDocument(doc); // add document to folder and set parent in doc
-      else
-        doc.persist();
-      so = doc;
-    }
-
-    // policies, addACEs, removeACEs, extension are ignored for
-    // now.
-    return so;
-  }
-
-  private Folder createFolderIntern(String repositoryId, Properties properties,
-      String folderId, List<String> policies, Acl addAces,
-      Acl removeAces, ExtensionsData extension) {
-
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    checkStandardParameters(repositoryId, folderId);
-
-    ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
-    StoredObject so = null;
-    Folder parent = null;
-
-    // get required properties
-    PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
-    String folderName = (String) pd.getFirstValue();
-    if (null == folderName || folderName.length() == 0)
-      throw new CmisInvalidArgumentException("Cannot create a folder without a name.");
-
-    // check name syntax
-    if (!NameValidator.isValidId(folderName))
-      throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
-
-
-    TypeValidator.validateRequiredSystemProperties(properties);
-
-    TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
-
-    // check if the given type is a folder type
-    if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_FOLDER))
-      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(CallContext.USERNAME);
-      if (user == null)
-        user = "unknown";
-      newFolder.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
-      newFolder.setCustomProperties(properties.getProperties());
-      parent.addChildFolder(newFolder);
-      LOG.debug("stop createFolder()");
-      return newFolder;
-    }
-    catch (Exception e) {
-      throw new CmisInvalidArgumentException("Failed to create child folder.", e);
-    }
-  }
-
-  private StoredObject createPolicyIntern(String repositoryId, Properties properties,
-      String folderId, List<String> policies, Acl addAces,
-      Acl removeAces, ExtensionsData extension) {
-    return null;
-  }
-
-  private StoredObject createRelationshipIntern(String repositoryId, Properties properties,
-      List<String> policies, Acl addAces, Acl removeAces,
-      ExtensionsData extension) {
-    return null;
-  }
-
-  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;
-  }
-
-  /**
-   * 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 ContentStream getContentStream(StoredObject so, String streamId, BigInteger offset,
-      BigInteger length) {
-
-    long lOffset = offset == null ? 0 : offset.longValue();
-    long lLength = length == null ? -1 : length.longValue();
-    ContentStream csd = ((Content) so).getContent(lOffset, lLength);
-    return csd;
-  }
+	public InMemoryObjectServiceImpl(StoreManager storeManager) {
+		super(storeManager);
+		fAtomLinkProvider = new AtomLinkInfoProvider(fStoreManager);
+	}
+
+	public String createDocument(CallContext context, String repositoryId, Properties properties, String folderId,
+			ContentStream contentStream, VersioningState versioningState, List<String> policies, Acl addAces,
+			Acl removeAces, ExtensionsData extension) {
+
+		try {
+			LOG.debug("start createDocument()");
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			StoredObject so = createDocumentIntern(repositoryId, properties, folderId, contentStream, versioningState,
+					policies, addAces, removeAces, extension);
+			LOG.debug("stop createDocument()");
+			return so.getId();
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public String createDocumentFromSource(CallContext context, String repositoryId, String sourceId,
+			Properties properties, String folderId, VersioningState versioningState, List<String> policies,
+			Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start createDocumentFromSource()");
+
+			StoredObject so = checkStandardParameters(repositoryId, sourceId);
+
+			ContentStream content = getContentStream(context, repositoryId, sourceId, null, BigInteger.valueOf(-1),
+					BigInteger.valueOf(-1), null);
+
+			if (so == null)
+				throw new CmisObjectNotFoundException("Unknown object id: " + sourceId);
+
+			// build properties collection
+			List<String> requestedIds = FilterParser.getRequestedIdsFromFilter("*");
+
+			Properties existingProps = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so, fStoreManager,
+					requestedIds);
+
+			PropertiesImpl newPD = new PropertiesImpl();
+			// 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(context, repositoryId, newPD, folderId, content, versioningState, policies,
+					addAces, removeAces, null);
+			LOG.debug("stop createDocumentFromSource()");
+			return res;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public String createFolder(CallContext context, String repositoryId, Properties properties, String folderId,
+			List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+		try {
+			LOG.debug("start createFolder()");
+			RuntimeContext.attachCfg(context);
+
+			Folder folder = createFolderIntern(repositoryId, properties, folderId, policies, addAces, removeAces,
+					extension);
+			LOG.debug("stop createFolder()");
+			return folder.getId();
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public String createPolicy(CallContext context, String repositoryId, Properties properties, String folderId,
+			List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			// TODO to be completed if ACLs are implemented
+			LOG.debug("start createPolicy()");
+			checkStandardParameters(repositoryId, folderId);
+			StoredObject so = createPolicyIntern(repositoryId, properties, folderId, policies, addAces, removeAces,
+					extension);
+			LOG.debug("stop createPolicy()");
+			return so == null ? null : so.getId();
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public String createRelationship(CallContext context, String repositoryId, Properties properties,
+			List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			// TODO to be completed if relationships are implemented
+			LOG.debug("start createRelationship()");
+			checkRepositoryId(repositoryId);
+			StoredObject so = createRelationshipIntern(repositoryId, properties, policies, addAces, removeAces,
+					extension);
+			LOG.debug("stop createRelationship()");
+			return so == null ? null : so.getId();
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.opencmis.server.spi.CmisObjectService#create(org.opencmis.server.
+	 * spi.CallContext, java.lang.String,
+	 * org.opencmis.client.provider.PropertiesData, java.lang.String,
+	 * org.opencmis.client.provider.ContentStreamData,
+	 * org.opencmis.commons.enums.VersioningState,
+	 * org.opencmis.client.provider.ExtensionsData,
+	 * org.opencmis.server.spi.ObjectInfoHolder)
+	 * 
+	 * An additional create call compared to the ObjectService from the CMIS
+	 * spec. This one is needed because the Atom binding in the server
+	 * implementation does not know what kind of object needs to be created.
+	 * Also the ObjectInfoHolder needs to be filled.
+	 */
+	@SuppressWarnings("unchecked")
+	public ObjectData create(CallContext context, String repositoryId, Properties properties, String folderId,
+			ContentStream contentStream, VersioningState versioningState, List<String> policies,
+			ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			if (null == properties || null == properties.getProperties())
+				throw new RuntimeException("Cannot create object, without properties.");
+
+			// Find out what kind of object needs to be created
+			PropertyData<String> pd = (PropertyData<String>) properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID);
+			String typeId = pd == null ? null : pd.getFirstValue();
+			if (null == typeId)
+				throw new RuntimeException(
+						"Cannot create object, without a type (no property with id CMIS_OBJECT_TYPE_ID).");
+
+			TypeDefinitionContainer typeDefC = fStoreManager.getTypeById(repositoryId, typeId);
+			if (typeDefC == null)
+				throw new RuntimeException("Cannot create object, a type with id " + typeId + " is unknown");
+
+			// check if the given type is a document type
+			BaseTypeId typeBaseId = typeDefC.getTypeDefinition().getBaseTypeId();
+			StoredObject so = null;
+			if (typeBaseId.equals(InMemoryDocumentTypeDefinition.getRootDocumentType().getBaseTypeId())) {
+				so = createDocumentIntern(repositoryId, properties, folderId, contentStream, versioningState, null,
+						null, null, null);
+			} else if (typeBaseId.equals(InMemoryFolderTypeDefinition.getRootFolderType().getBaseTypeId())) {
+				so = createFolderIntern(repositoryId, properties, folderId, null, null, null, null);
+			} else if (typeBaseId.equals(InMemoryPolicyTypeDefinition.getRootPolicyType().getBaseTypeId())) {
+				so = createPolicyIntern(repositoryId, properties, folderId, null, null, null, null);
+			} else if (typeBaseId.equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType().getBaseTypeId())) {
+				so = createRelationshipIntern(repositoryId, properties, null, null, null, null);
+			} else
+				LOG.error("The type contains an unknown base object id, object can't be created");
+
+			// Make a call to getObject to convert the resulting id into an
+			// ObjectData
+			ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+					IncludeRelationships.NONE, null, false, false, extension);
+
+			fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+			return od;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public void deleteContentStream(CallContext context, String repositoryId, Holder<String> objectId,
+			Holder<String> changeToken, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start deleteContentStream()");
+			StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
+
+			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, but only documents can have content");
+
+			((Content) so).setContent(null, true);
+			LOG.debug("stop deleteContentStream()");
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public void deleteObjectOrCancelCheckOut(CallContext context, String repositoryId, String objectId,
+			Boolean allVersions, ExtensionsData extension) {
+
+		try {
+			LOG.debug("start deleteObject()");
+			checkStandardParameters(repositoryId, objectId);
+			ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+			LOG.info("delete object for id: " + objectId);
+
+			// check if it is the root folder
+			if (objectId.equals(objectStore.getRootFolder().getId()))
+				throw new CmisNotSupportedException("You can't delete a root folder");
+
+			objectStore.deleteObject(objectId);
+			LOG.debug("stop deleteObject()");
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public FailedToDeleteData deleteTree(CallContext context, String repositoryId, String folderId,
+			Boolean allVersions, UnfileObject unfileObjects, Boolean continueOnFailure, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start deleteTree()");
+			StoredObject so = checkStandardParameters(repositoryId, folderId);
+			List<String> failedToDeleteIds = new ArrayList<String>();
+			FailedToDeleteDataImpl result = new FailedToDeleteDataImpl();
+
+			if (null == allVersions)
+				allVersions = true;
+			if (null == unfileObjects)
+				unfileObjects = UnfileObject.DELETE;
+			if (null == continueOnFailure)
+				continueOnFailure = false;
+
+			ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+			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 (unfileObjects == UnfileObject.UNFILE)
+				throw new CmisNotSupportedException("This repository does not support unfile operations.");
+
+			// check if it is the root folder
+			if (folderId.equals(objectStore.getRootFolder().getId()))
+				throw new CmisNotSupportedException("You can't delete a root folder");
+
+			// recursively delete folder
+			deleteRecursive(objectStore, (Folder) so, continueOnFailure, allVersions, failedToDeleteIds);
+
+			result.setIds(failedToDeleteIds);
+			LOG.debug("stop deleteTree()");
+			return result;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public AllowableActions getAllowableActions(CallContext context, String repositoryId, String objectId,
+			ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start getAllowableActions()");
+			StoredObject so = checkStandardParameters(repositoryId, objectId);
+			ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+			if (so == null)
+				throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+			AllowableActions allowableActions = DataObjectCreator.fillAllowableActions(objectStore, so);
+			LOG.debug("stop getAllowableActions()");
+			return allowableActions;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public ContentStream getContentStream(CallContext context, String repositoryId, String objectId, String streamId,
+			BigInteger offset, BigInteger length, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start getContentStream()");
+			StoredObject so = checkStandardParameters(repositoryId, 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");
+
+			ContentStream csd = getContentStream(so, streamId, offset, length);
+			LOG.debug("stop getContentStream()");
+			return csd;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public ObjectData getObject(CallContext context, String repositoryId, String objectId, String filter,
+			Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
+			Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+		try {
+			LOG.debug("start getObject()");
+
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			StoredObject so = checkStandardParameters(repositoryId, objectId);
+
+			if (so == null)
+				throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+			ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter, includeAllowableActions,
+					includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension);
+
+			fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+			LOG.debug("stop getObject()");
+
+			return od;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public ObjectData getObjectByPath(CallContext context, String repositoryId, String path, String filter,
+			Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
+			Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			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()");
+
+			// To be able to provide all Atom links in the response we need
+			// additional information:
+			fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+			return od;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public Properties getProperties(CallContext context, String repositoryId, String objectId, String filter,
+			ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start getProperties()");
+			StoredObject so = checkStandardParameters(repositoryId, objectId);
+
+			if (so == null)
+				throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+			// build properties collection
+			List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
+			Properties props = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so, fStoreManager,
+					requestedIds);
+			LOG.debug("stop getProperties()");
+			return props;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public List<RenditionData> getRenditions(CallContext context, String repositoryId, String objectId,
+			String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			// TODO to be completed if renditions are implemented
+			LOG.debug("start getRenditions()");
+			checkStandardParameters(repositoryId, objectId);
+			LOG.debug("stop getRenditions()");
+			return null;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public ObjectData moveObject(CallContext context, String repositoryId, Holder<String> objectId,
+			String targetFolderId, String sourceFolderId, ExtensionsData extension, ObjectInfoHolder objectInfos) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start moveObject()");
+			StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
+			Folder targetFolder = null;
+			Folder sourceFolder = null;
+			ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+			Filing spo = null;
+
+			if (null == so)
+				throw new CmisObjectNotFoundException("Unknown object: " + objectId.getValue());
+			else if (so instanceof Filing)
+				spo = (Filing) so;
+			else
+				throw new CmisInvalidArgumentException("Object must be folder or document: " + objectId.getValue());
+
+			StoredObject soTarget = objectStore.getObjectById(targetFolderId);
+			if (null == soTarget)
+				throw new CmisObjectNotFoundException("Unknown target folder: " + targetFolderId);
+			else if (soTarget instanceof Folder)
+				targetFolder = (Folder) soTarget;
+			else
+				throw new CmisNotSupportedException("Destination " + targetFolderId
+						+ " of a move operation must be a folder");
+
+			StoredObject soSource = objectStore.getObjectById(sourceFolderId);
+			if (null == soSource)
+				throw new CmisObjectNotFoundException("Unknown source folder: " + sourceFolderId);
+			else if (soSource instanceof Folder)
+				sourceFolder = (Folder) soSource;
+			else
+				throw new CmisNotSupportedException("Source " + sourceFolderId
+						+ " of a move operation must be a folder");
+
+			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");
+			}
+
+			spo.move(sourceFolder, targetFolder);
+			objectId.setValue(so.getId());
+			LOG.debug("stop moveObject()");
+
+			// To be able to provide all Atom links in the response we need
+			// additional information:
+			fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+			ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+					IncludeRelationships.NONE, null, false, false, extension);
+
+			return od;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public void setContentStream(CallContext context, String repositoryId, Holder<String> objectId,
+			Boolean overwriteFlag, Holder<String> changeToken, ContentStream contentStream, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			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(CallContext.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(0, -1) != null)
+				throw new CmisConstraintException("cannot overwrite existing content if overwrite flag is not set");
+
+			content.setContent(contentStream, true);
+			LOG.debug("stop setContentStream()");
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public ObjectData updateProperties(CallContext context, String repositoryId, Holder<String> objectId,
+			Holder<String> changeToken, Properties properties, Acl acl, ExtensionsData extension,
+			ObjectInfoHolder objectInfos) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			LOG.debug("start updateProperties()");
+			StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
+
+			// Validation
+			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(CallContext.USERNAME);
+				// VersionedDocument verDoc =
+				// testIsNotCheckedOutBySomeoneElse(so, user);
+				testHasProperCheckedOutStatus(so, user);
+				isCheckedOut = true;
+			}
+
+			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.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.NAME);
+			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");
+				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;
+			}
+
+			if (hasUpdatedOtherProps) {
+				// set user, creation date, etc.
+				String user = RuntimeContext.getRuntimeConfigValue(CallContext.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);
+				}
+			}
+
+			if (null != acl) {
+				LOG.warn("Setting ACLs is currently not supported by this implementation, acl is ignored");
+				// if implemented add this call:
+				// fAclService.appyAcl(context, repositoryId, acl, null,
+				// AclPropagation.OBJECTONLY,
+				// extension);
+			}
+
+			// To be able to provide all Atom links in the response we need
+			// additional information:
+			fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+			ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+					IncludeRelationships.NONE, null, false, false, extension);
+
+			LOG.debug("stop updateProperties()");
+
+			return od;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	// ///////////////////////////////////////////////////////
+	// private helper methods
+
+	private StoredObject createDocumentIntern(String repositoryId, Properties properties, String folderId,
+			ContentStream contentStream, VersioningState versioningState, List<String> policies, Acl addACEs,
+			Acl removeACEs, ExtensionsData extension) {
+		checkRepositoryId(repositoryId);
+
+		ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+		// get name from properties
+		PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
+		String name = (String) pd.getFirstValue();
+
+		// Validation stuff
+		TypeValidator.validateRequiredSystemProperties(properties);
+		TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
+
+		Folder folder = null;
+		if (null != folderId) {
+			StoredObject so = objectStore.getObjectById(folderId);
+
+			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.validateAllowedChildObjectTypes(typeDef, folder.getAllowedChildObjectTypeIds());
+		}
+
+		// check if the given type is a document type
+		if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_DOCUMENT))
+			throw new RuntimeException("Cannot create a document, with a non-document type: " + typeDef.getId());
+
+		// check name syntax
+		if (!NameValidator.isValidId(name))
+			throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
+
+		TypeValidator.validateVersionStateForCreate((DocumentTypeDefinition) typeDef, versioningState);
+		TypeValidator.validateProperties(typeDef, properties, true);
+
+		// set user, creation date, etc.
+		String user = RuntimeContext.getRuntimeConfigValue(CallContext.USERNAME);
+		if (user == null)
+			user = "unknown";
+
+		StoredObject so = 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);
+			if (null != folder)
+				folder.addChildDocument(verDoc); // add document to folder and
+													// set parent in doc
+			else
+				verDoc.persist();
+			version.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+			version.setCustomProperties(properties.getProperties());
+			version.persist();
+			so = version; // 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
+			doc.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+			doc.setCustomProperties(properties.getProperties());
+			if (null != folder)
+				folder.addChildDocument(doc); // add document to folder and set
+												// parent in doc
+			else
+				doc.persist();
+			so = doc;
+		}
+
+		// policies, addACEs, removeACEs, extension are ignored for
+		// now.
+		return so;
+	}
+
+	private Folder createFolderIntern(String repositoryId, Properties properties, String folderId,
+			List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+
+		// Attach the CallContext to a thread local context that can be accessed
+		// from everywhere
+		checkStandardParameters(repositoryId, folderId);
+
+		ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
+		StoredObject so = null;
+		Folder parent = null;
+
+		// get required properties
+		PropertyData<?> pd = properties.getProperties().get(PropertyIds.NAME);
+		String folderName = (String) pd.getFirstValue();
+		if (null == folderName || folderName.length() == 0)
+			throw new CmisInvalidArgumentException("Cannot create a folder without a name.");
+
+		// check name syntax
+		if (!NameValidator.isValidId(folderName))
+			throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
+
+		TypeValidator.validateRequiredSystemProperties(properties);
+
+		TypeDefinition typeDef = getTypeDefinition(repositoryId, properties);
+
+		// check if the given type is a folder type
+		if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_FOLDER))
+			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(CallContext.USERNAME);
+			if (user == null)
+				user = "unknown";
+			newFolder.createSystemBasePropertiesWhenCreated(properties.getProperties(), user);
+			newFolder.setCustomProperties(properties.getProperties());
+			parent.addChildFolder(newFolder);
+			LOG.debug("stop createFolder()");
+			return newFolder;
+		} catch (Exception e) {
+			throw new CmisInvalidArgumentException("Failed to create child folder.", e);
+		}
+	}
+
+	private StoredObject createPolicyIntern(String repositoryId, Properties properties, String folderId,
+			List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
+		return null;
+	}
+
+	private StoredObject createRelationshipIntern(String repositoryId, Properties properties, List<String> policies,
+			Acl addAces, Acl removeAces, ExtensionsData extension) {
+		return null;
+	}
+
+	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;
+	}
+
+	/**
+	 * 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 ContentStream getContentStream(StoredObject so, String streamId, BigInteger offset, BigInteger length) {
+
+		long lOffset = offset == null ? 0 : offset.longValue();
+		long lLength = length == null ? -1 : length.longValue();
+		ContentStream csd = ((Content) so).getContent(lOffset, lLength);
+		return csd;
+	}
 
 }

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java?rev=934878&r1=934877&r2=934878&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java Fri Apr 16 14:00:23 2010
@@ -36,144 +36,145 @@ import org.apache.chemistry.opencmis.inm
 import org.apache.chemistry.opencmis.server.spi.CallContext;
 import org.apache.chemistry.opencmis.server.spi.CmisRepositoryService;
 
-public class InMemoryRepositoryServiceImpl extends AbstractServiceImpl implements
-    CmisRepositoryService {
+public class InMemoryRepositoryServiceImpl extends AbstractServiceImpl implements CmisRepositoryService {
 
-  public InMemoryRepositoryServiceImpl(StoreManager storeManager) {
-    super(storeManager);
-  }
-
-  public RepositoryInfo getRepositoryInfo(CallContext context, String repositoryId,
-      ExtensionsData extension) {
-
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.attachCfg(context);
-
-    RepositoryInfo repoInfo = getRepositoryInfoFromStoreManager(repositoryId);
-
-    return repoInfo;
-  }
-
-  public List<RepositoryInfo> getRepositoryInfos(CallContext context, ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      List<RepositoryInfo> res = new ArrayList<RepositoryInfo>();
-      List<String> repIds = fStoreManager.getAllRepositoryIds();
-      for (String repId : repIds) {
-        res.add(fStoreManager.getRepositoryInfo(repId));
-      }
-      return res;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public TypeDefinitionList getTypeChildren(CallContext context, String repositoryId,
-      String typeId, Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount,
-      ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      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;
-      if (typeId == null) {
-        // spec says that base types must be returned in this case
-        children = fStoreManager.getRootTypes(repositoryId);
-      }
-      else {
-        children = getTypeDescendants(context, 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 = skip; i < max + skip && it.hasNext(); i++)
-        childrenTypes.add(it.next().getTypeDefinition());
-
-      result.setList(childrenTypes);
-      return result;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public TypeDefinition getTypeDefinition(CallContext context, String repositoryId, String typeId,
-      ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      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);
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  public List<TypeDefinitionContainer> getTypeDescendants(CallContext context, String repositoryId,
-      String typeId, BigInteger depth, Boolean includePropertyDefinitions, ExtensionsData extension) {
-
-    try {
-      // Attach the CallContext to a thread local context that can be accessed from everywhere
-      RuntimeContext.attachCfg(context);
-
-      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> tmp = fStoreManager.getTypeDefinitionList(repositoryId,
-            includePropertyDefinitions);
-        result = new ArrayList<TypeDefinitionContainer> (tmp);
-      }
-      else {
-        TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId,
-            includePropertyDefinitions, depth==null ? -1 : depth.intValue());
-        if (tc == null) 
-          throw new CmisInvalidArgumentException("unknown type id: " + typeId);
-        else
-          result = tc.getChildren();
-      }
-
-      return result;
-    }
-    finally {
-      RuntimeContext.remove();
-    }
-  }
-
-  private RepositoryInfo getRepositoryInfoFromStoreManager(String repositoryId) {
-    RepositoryInfo repoInfo = fStoreManager.getRepositoryInfo(repositoryId);
-    if (null == repoInfo || !repoInfo.getId().equals(repositoryId)) {
-      throw new CmisInvalidArgumentException("Unknown repository: " + repositoryId);
-    }
-    return repoInfo;
-  }
+	public InMemoryRepositoryServiceImpl(StoreManager storeManager) {
+		super(storeManager);
+	}
+
+	public RepositoryInfo getRepositoryInfo(CallContext context, String repositoryId, ExtensionsData extension) {
+
+		// Attach the CallContext to a thread local context that can be accessed
+		// from everywhere
+		RuntimeContext.attachCfg(context);
+
+		RepositoryInfo repoInfo = getRepositoryInfoFromStoreManager(repositoryId);
+
+		return repoInfo;
+	}
+
+	public List<RepositoryInfo> getRepositoryInfos(CallContext context, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			List<RepositoryInfo> res = new ArrayList<RepositoryInfo>();
+			List<String> repIds = fStoreManager.getAllRepositoryIds();
+			for (String repId : repIds) {
+				res.add(fStoreManager.getRepositoryInfo(repId));
+			}
+			return res;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public TypeDefinitionList getTypeChildren(CallContext context, String repositoryId, String typeId,
+			Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			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;
+			if (typeId == null) {
+				// spec says that base types must be returned in this case
+				children = fStoreManager.getRootTypes(repositoryId);
+			} else {
+				children = getTypeDescendants(context, 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 = skip; i < max + skip && it.hasNext(); i++)
+				childrenTypes.add(it.next().getTypeDefinition());
+
+			result.setList(childrenTypes);
+			return result;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public TypeDefinition getTypeDefinition(CallContext context, String repositoryId, String typeId,
+			ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			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);
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	public List<TypeDefinitionContainer> getTypeDescendants(CallContext context, String repositoryId, String typeId,
+			BigInteger depth, Boolean includePropertyDefinitions, ExtensionsData extension) {
+
+		try {
+			// Attach the CallContext to a thread local context that can be
+			// accessed from everywhere
+			RuntimeContext.attachCfg(context);
+
+			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> tmp = fStoreManager.getTypeDefinitionList(repositoryId,
+						includePropertyDefinitions);
+				result = new ArrayList<TypeDefinitionContainer>(tmp);
+			} else {
+				TypeDefinitionContainer tc = fStoreManager.getTypeById(repositoryId, typeId,
+						includePropertyDefinitions, depth == null ? -1 : depth.intValue());
+				if (tc == null)
+					throw new CmisInvalidArgumentException("unknown type id: " + typeId);
+				else
+					result = tc.getChildren();
+			}
+
+			return result;
+		} finally {
+			RuntimeContext.remove();
+		}
+	}
+
+	private RepositoryInfo getRepositoryInfoFromStoreManager(String repositoryId) {
+		RepositoryInfo repoInfo = fStoreManager.getRepositoryInfo(repositoryId);
+		if (null == repoInfo || !repoInfo.getId().equals(repositoryId)) {
+			throw new CmisInvalidArgumentException("Unknown repository: " + repositoryId);
+		}
+		return repoInfo;
+	}
 
 }