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/03/23 13:23:29 UTC

svn commit: r926534 [1/2] - in /incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src: main/java/org/apache/opencmis/inmemory/clientprovider/ main/java/org/apache/opencmis/inmemory/server/ test/java/org/apache/opencmis/inmemory/

Author: jens
Date: Tue Mar 23 12:23:29 2010
New Revision: 926534

URL: http://svn.apache.org/viewvc?rev=926534&view=rev
Log:
Cleanup thread local storage in InMemory server after use

Modified:
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/clientprovider/AbstractService.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryDiscoveryServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryMultiFilingServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryObjectServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryRepositoryServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryVersioningServiceImpl.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/RuntimeContext.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/ServiceFactory.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/AbstractServiceTst.java
    incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/test/java/org/apache/opencmis/inmemory/VersioningTest.java

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/clientprovider/AbstractService.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/clientprovider/AbstractService.java?rev=926534&r1=926533&r2=926534&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/clientprovider/AbstractService.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/clientprovider/AbstractService.java Tue Mar 23 12:23:29 2010
@@ -18,13 +18,15 @@
  */
 package org.apache.opencmis.inmemory.clientprovider;
 
+import org.apache.opencmis.inmemory.server.RuntimeContext;
 import org.apache.opencmis.server.spi.CallContext;
 
 public class AbstractService  {
   protected CallContext fDummyCallContext;
   
   protected AbstractService() {
-    fDummyCallContext = null; // currently always set to null
+    // use an existing context if there is one, otherwise use null
+    fDummyCallContext = RuntimeContext.getCurrentContext(); 
   }
   
   public void setCallContext(CallContext ctx) {

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryDiscoveryServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryDiscoveryServiceImpl.java?rev=926534&r1=926533&r2=926534&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryDiscoveryServiceImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryDiscoveryServiceImpl.java Tue Mar 23 12:23:29 2010
@@ -46,8 +46,8 @@ public class InMemoryDiscoveryServiceImp
   InMemoryNavigationServiceImpl fNavigationService; // real implementation of the service
   InMemoryRepositoryServiceImpl fRepositoryService;
 
-  public InMemoryDiscoveryServiceImpl(StoreManager storeManager, InMemoryRepositoryServiceImpl repSvc,
-      InMemoryNavigationServiceImpl navSvc) {
+  public InMemoryDiscoveryServiceImpl(StoreManager storeManager,
+      InMemoryRepositoryServiceImpl repSvc, InMemoryNavigationServiceImpl navSvc) {
     fStoreManager = storeManager;
     fAtomLinkProvider = new AtomLinkInfoProvider(fStoreManager);
     fNavigationService = navSvc;
@@ -60,28 +60,33 @@ public class InMemoryDiscoveryServiceImp
       ObjectInfoHolder objectInfos) {
     // dummy implementation using hard coded values
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-
-    RepositoryInfoData rep = fRepositoryService.getRepositoryInfo(context, repositoryId, null);
-    String rootFolderId = rep.getRootFolderId();
+    try {
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
+
+      RepositoryInfoData rep = fRepositoryService.getRepositoryInfo(context, repositoryId, null);
+      String rootFolderId = rep.getRootFolderId();
+
+      ObjectListImpl objList = new ObjectListImpl();
+      List<ObjectInFolderContainer> tempRes = fNavigationService.getDescendants(context,
+          repositoryId, rootFolderId, BigInteger.valueOf(3), filter, false,
+          IncludeRelationships.NONE, null, false, extension, null);
+
+      // convert ObjectInFolderContainerList to objectList
+      List<ObjectData> lod = new ArrayList<ObjectData>();
+      for (ObjectInFolderContainer obj : tempRes) {
+        convertList(lod, obj);
+      }
+      objList.setObjects(lod);
+      objList.setNumItems(BigInteger.valueOf(lod.size()));
 
-    ObjectListImpl objList = new ObjectListImpl();
-    List<ObjectInFolderContainer> tempRes = fNavigationService.getDescendants(context,
-        repositoryId, rootFolderId, BigInteger.valueOf(3), filter, false,
-        IncludeRelationships.NONE, null, false, extension, null);
-
-    // convert ObjectInFolderContainerList to objectList
-    List<ObjectData> lod = new ArrayList<ObjectData>();
-    for (ObjectInFolderContainer obj : tempRes) {
-      convertList(lod, obj);
+      // To be able to provide all Atom links in the response we need additional information:
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, null, objectInfos, objList);
+      return objList;
+    }
+    finally {
+      RuntimeContext.remove();
     }
-    objList.setObjects(lod);
-    objList.setNumItems(BigInteger.valueOf(lod.size()));
-
-    // To be able to provide all Atom links in the response we need additional information:
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, null, objectInfos, objList);
-    return objList;
   }
 
   private void convertList(List<ObjectData> lod, ObjectInFolderContainer obj) {
@@ -106,26 +111,31 @@ public class InMemoryDiscoveryServiceImp
       BigInteger skipCount, ExtensionsData extension) {
     // dummy implementation using hard coded values
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    try {
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
+
+      // use descendants of root folder as result
+      RepositoryInfoData rep = fRepositoryService.getRepositoryInfo(context, repositoryId, null);
+      String rootFolderId = rep.getRootFolderId();
+      ObjectListImpl objList = new ObjectListImpl();
+      List<ObjectInFolderContainer> tempRes = fNavigationService.getDescendants(context,
+          repositoryId, rootFolderId, BigInteger.valueOf(3), "*", includeAllowableActions,
+          includeRelationships, renditionFilter, false, extension, null);
+
+      // convert ObjectInFolderContainerList to objectList
+      List<ObjectData> lod = new ArrayList<ObjectData>();
+      for (ObjectInFolderContainer obj : tempRes) {
+        convertList(lod, obj);
+      }
+      objList.setObjects(lod);
+      objList.setNumItems(BigInteger.valueOf(lod.size()));
 
-    // use descendants of root folder as result
-    RepositoryInfoData rep = fRepositoryService.getRepositoryInfo(context, repositoryId, null);
-    String rootFolderId = rep.getRootFolderId();
-    ObjectListImpl objList = new ObjectListImpl();
-    List<ObjectInFolderContainer> tempRes = fNavigationService.getDescendants(context,
-        repositoryId, rootFolderId, BigInteger.valueOf(3), "*", includeAllowableActions,
-        includeRelationships, renditionFilter, false, extension, null);
-
-    // convert ObjectInFolderContainerList to objectList
-    List<ObjectData> lod = new ArrayList<ObjectData>();
-    for (ObjectInFolderContainer obj : tempRes) {
-      convertList(lod, obj);
+      return objList;
+    }
+    finally {
+      RuntimeContext.remove();
     }
-    objList.setObjects(lod);
-    objList.setNumItems(BigInteger.valueOf(lod.size()));
-
-    return objList;
   }
 
 }

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryMultiFilingServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryMultiFilingServiceImpl.java?rev=926534&r1=926533&r2=926534&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryMultiFilingServiceImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryMultiFilingServiceImpl.java Tue Mar 23 12:23:29 2010
@@ -50,59 +50,69 @@ public class InMemoryMultiFilingServiceI
   public ObjectData addObjectToFolder(CallContext context, String repositoryId, String objectId,
       String folderId, Boolean allVersions, ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    LOG.debug("Begin addObjectToFolder()");
+    try {
+      LOG.debug("Begin addObjectToFolder()");
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    StoredObject[] so2 = checkParams(repositoryId, objectId, folderId);
-    if (allVersions != null && allVersions.booleanValue() == false)
-      throw new CmisNotSupportedException(
-          "Cannot add object to folder, version specific filing is not supported.");
-    StoredObject so = so2[0];
-    StoredObject folder = so2[1];
-    checkObjects(so, folder);
-
-    Folder newParent = (Folder) folder;
-    MultiFiling obj = (MultiFiling) so;
-    obj.addParent(newParent);
-
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, folder, objectInfos);
-
-    ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
-        IncludeRelationships.NONE, null, false, false, extension);
-
-    LOG.debug("End addObjectToFolder()");
-    return od;
+      StoredObject[] so2 = checkParams(repositoryId, objectId, folderId);
+      if (allVersions != null && allVersions.booleanValue() == false)
+        throw new CmisNotSupportedException(
+            "Cannot add object to folder, version specific filing is not supported.");
+      StoredObject so = so2[0];
+      StoredObject folder = so2[1];
+      checkObjects(so, folder);
+
+      Folder newParent = (Folder) folder;
+      MultiFiling obj = (MultiFiling) so;
+      obj.addParent(newParent);
+
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, folder, objectInfos);
+
+      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+          IncludeRelationships.NONE, null, false, false, extension);
+
+      LOG.debug("End addObjectToFolder()");
+      return od;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public ObjectData removeObjectFromFolder(CallContext context, String repositoryId,
       String objectId, String folderId, ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    LOG.debug("Begin removeObjectFromFolder()");
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-
-    StoredObject so = checkStandardParameters(repositoryId, objectId);
-    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
-    StoredObject folder = checkExistingObjectId(objectStore, folderId);
-
-    checkObjects(so, folder);
-    Folder parent = (Folder) folder;
-    MultiFiling obj = (MultiFiling) so;
-    obj.removeParent(parent);
-
-    // To be able to provide all Atom links in the response we need additional information:
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, folder, objectInfos);
-
-    ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
-        IncludeRelationships.NONE, null, false, false, extension);
-
-    LOG.debug("End removeObjectFromFolder()");
-
-    return od;
+    try {
+      LOG.debug("Begin removeObjectFromFolder()");
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
+
+      StoredObject so = checkStandardParameters(repositoryId, objectId);
+      ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+      StoredObject folder = checkExistingObjectId(objectStore, folderId);
+
+      checkObjects(so, folder);
+      Folder parent = (Folder) folder;
+      MultiFiling obj = (MultiFiling) so;
+      obj.removeParent(parent);
+
+      // To be able to provide all Atom links in the response we need additional information:
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, folder, objectInfos);
+
+      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+          IncludeRelationships.NONE, null, false, false, extension);
+
+      LOG.debug("End removeObjectFromFolder()");
+
+      return od;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   private StoredObject[] checkParams(String repositoryId, String objectId, String folderId) {

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java?rev=926534&r1=926533&r2=926534&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryNavigationServiceImpl.java Tue Mar 23 12:23:29 2010
@@ -77,50 +77,55 @@ public class InMemoryNavigationServiceIm
       String filter, String orderBy, Boolean includeAllowableActions,
       IncludeRelationships includeRelationships, String renditionFilter, BigInteger maxItems,
       BigInteger skipCount, ExtensionsData extension, ObjectInfoHolder objectInfos) {
-    
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
 
-    ObjectListImpl res = new ObjectListImpl();
-    List<ObjectData> odList = new ArrayList<ObjectData>();
-
-    LOG.debug("start getCheckedOutDocs()");
-    if (null != folderId)
-      checkStandardParameters(repositoryId, folderId);
-    else
-      checkRepositoryId(repositoryId);
+    try {
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
+
+      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);
-        fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, checkedOut, objectInfos);
-        odList.add(od);
+      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);
+          fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, checkedOut, objectInfos);
+          odList.add(od);
+        }
       }
-    }
-    else {
-      ObjectInFolderList children = getChildrenIntern(repositoryId, folderId, filter, orderBy,
-          includeAllowableActions, includeRelationships, renditionFilter, false, -1, -1, false,
-          objectInfos);
-      for (ObjectInFolderData child : children.getObjects()) {
-        ObjectData obj = child.getObject();
-        StoredObject so = fStoreManager.getObjectStore(repositoryId).getObjectById(obj.getId());
-        LOG.info("Checked out: children:" + obj.getId());
-        if (so instanceof DocumentVersion
-            && ((DocumentVersion) so).getParentDocument().isCheckedOut()) {
-          odList.add(obj);
-          fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+      else {
+        ObjectInFolderList children = getChildrenIntern(repositoryId, folderId, filter, orderBy,
+            includeAllowableActions, includeRelationships, renditionFilter, false, -1, -1, false,
+            objectInfos);
+        for (ObjectInFolderData child : children.getObjects()) {
+          ObjectData obj = child.getObject();
+          StoredObject so = fStoreManager.getObjectStore(repositoryId).getObjectById(obj.getId());
+          LOG.info("Checked out: children:" + obj.getId());
+          if (so instanceof DocumentVersion
+              && ((DocumentVersion) so).getParentDocument().isCheckedOut()) {
+            odList.add(obj);
+            fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+          }
         }
       }
-    }
-    res.setObjects(odList);
-    res.setNumItems(BigInteger.valueOf(odList.size()));
+      res.setObjects(odList);
+      res.setNumItems(BigInteger.valueOf(odList.size()));
 
-    LOG.debug("end getCheckedOutDocs()");
-    return res;
+      LOG.debug("end getCheckedOutDocs()");
+      return res;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public ObjectInFolderList getChildren(CallContext context, String repositoryId, String folderId,
@@ -129,20 +134,25 @@ public class InMemoryNavigationServiceIm
       Boolean includePathSegment, BigInteger maxItems, BigInteger skipCount,
       ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    LOG.debug("start getChildren()");
-    
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-
-    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, includePathSegment,
-        maxItemsInt, skipCountInt, false, objectInfos);
-    LOG.debug("stop getChildren()");
-    return res;
+    try {
+      LOG.debug("start getChildren()");
+
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
+
+      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, includePathSegment,
+          maxItemsInt, skipCountInt, false, objectInfos);
+      LOG.debug("stop getChildren()");
+      return res;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public List<ObjectInFolderContainer> getDescendants(CallContext context, String repositoryId,
@@ -150,54 +160,64 @@ public class InMemoryNavigationServiceIm
       IncludeRelationships includeRelationships, String renditionFilter,
       Boolean includePathSegment, ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    LOG.debug("start getDescendants()");
-    
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-
-    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();
+    try {
+      LOG.debug("start getDescendants()");
 
-    int level = 0;
-    List<ObjectInFolderContainer> result = getDescendantsIntern(repositoryId, folderId, filter,
-        includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, level,
-        levels, false, objectInfos);
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    LOG.debug("stop getDescendants()");
-    return result;
+      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, includePathSegment,
+          level, levels, false, objectInfos);
+
+      LOG.debug("stop getDescendants()");
+      return result;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public ObjectData getFolderParent(CallContext context, String repositoryId, String folderId,
       String filter, ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    LOG.debug("start getFolderParent()");
-    
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    try {
+      LOG.debug("start getFolderParent()");
 
-    StoredObject so = checkStandardParameters(repositoryId, folderId);
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    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);
+      StoredObject so = checkStandardParameters(repositoryId, folderId);
 
-    ObjectData res = getFolderParentIntern(repositoryId, folder, filter, objectInfos);
+      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);
 
-    // To be able to provide all Atom links in the response we need additional information:
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+      ObjectData res = getFolderParentIntern(repositoryId, folder, filter, objectInfos);
 
-    LOG.debug("stop getFolderParent()");
-    return res;
+      // To be able to provide all Atom links in the response we need additional information:
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+
+      LOG.debug("stop getFolderParent()");
+      return res;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public List<ObjectInFolderContainer> getFolderTree(CallContext context, String repositoryId,
@@ -205,57 +225,66 @@ public class InMemoryNavigationServiceIm
       IncludeRelationships includeRelationships, String renditionFilter,
       Boolean includePathSegment, ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    LOG.debug("start getFolderTree()");
-    
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-
-    checkStandardParameters(repositoryId, folderId);
-
-    if (depth != null && depth.intValue() == 0)
-      throw new CmisInvalidArgumentException("A zero depth is not allowed for getFolderTree().");
-
-    int levels = depth == null ? 2 : depth.intValue();
-    int level = 0;
-    List<ObjectInFolderContainer> result = getDescendantsIntern(repositoryId, folderId, filter,
-        includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, level,
-        levels, true, objectInfos);
+    try {
+      LOG.debug("start getFolderTree()");
 
-    LOG.debug("stop getFolderTree()");
-    return result;
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
+
+      checkStandardParameters(repositoryId, folderId);
+
+      if (depth != null && depth.intValue() == 0)
+        throw new CmisInvalidArgumentException("A zero depth is not allowed for getFolderTree().");
+
+      int levels = depth == null ? 2 : depth.intValue();
+      int level = 0;
+      List<ObjectInFolderContainer> result = getDescendantsIntern(repositoryId, folderId, filter,
+          includeAllowableActions, includeRelationships, renditionFilter, includePathSegment,
+          level, levels, true, objectInfos);
+
+      LOG.debug("stop getFolderTree()");
+      return result;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public List<ObjectParentData> getObjectParents(CallContext context, String repositoryId,
       String objectId, String filter, Boolean includeAllowableActions,
       IncludeRelationships includeRelationships, String renditionFilter,
       Boolean includeRelativePathSegment, ExtensionsData extension, ObjectInfoHolder objectInfos) {
-    
-    LOG.debug("start getObjectParents()");
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    try {
+      LOG.debug("start getObjectParents()");
 
-    StoredObject so = checkStandardParameters(repositoryId, objectId);
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    // 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)
-    List<ObjectParentData> result = null;
+      StoredObject so = checkStandardParameters(repositoryId, objectId);
 
-    Filing spo = null;
-    if (so instanceof Filing)
-      spo = (Filing) so;
-    else
-      throw new CmisInvalidArgumentException(
-          "Can't get object parent, id does not refer to a folder or document: " + objectId);
+      // 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)
+      List<ObjectParentData> result = null;
 
-    result = getObjectParentsIntern(repositoryId, spo, filter, objectInfos);
+      Filing spo = null;
+      if (so instanceof Filing)
+        spo = (Filing) so;
+      else
+        throw new CmisInvalidArgumentException(
+            "Can't get object parent, id does not refer to a folder or document: " + objectId);
 
-    // To be able to provide all Atom links in the response we need additional information:
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+      result = getObjectParentsIntern(repositoryId, spo, filter, objectInfos);
 
+      // To be able to provide all Atom links in the response we need additional information:
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
 
-    LOG.debug("stop getObjectParents()");
-    return result;
+      LOG.debug("stop getObjectParents()");
+      return result;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   // private helpers
@@ -355,13 +384,14 @@ public class InMemoryNavigationServiceIm
 
     List<ObjectParentData> result = null;
     if (sop instanceof SingleFiling) {
-      ObjectData parent = getFolderParentIntern(repositoryId, (SingleFiling) sop, filter, objectInfos);
+      ObjectData parent = getFolderParentIntern(repositoryId, (SingleFiling) sop, filter,
+          objectInfos);
       if (null != parent) {
         ObjectParentDataImpl parentData = new ObjectParentDataImpl();
         parentData.setObject(parent);
         String path = ((SingleFiling) sop).getPath();
         int beginIndex = path.lastIndexOf(Filing.PATH_SEPARATOR) + 1; // Note: if / not found
-                                                                      // results in 0
+        // results in 0
         String relPathSeg = path.substring(beginIndex, path.length());
         parentData.setRelativePathSegment(relPathSeg);
         result = Collections.singletonList((ObjectParentData) parentData);
@@ -387,7 +417,8 @@ public class InMemoryNavigationServiceIm
     return result;
   }
 
-  private ObjectData getFolderParentIntern(String repositoryId, SingleFiling sop, String filter, ObjectInfoHolder objectInfos) {
+  private ObjectData getFolderParentIntern(String repositoryId, SingleFiling sop, String filter,
+      ObjectInfoHolder objectInfos) {
 
     ObjectDataImpl parent = new ObjectDataImpl();
 

Modified: incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryObjectServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryObjectServiceImpl.java?rev=926534&r1=926533&r2=926534&view=diff
==============================================================================
--- incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryObjectServiceImpl.java (original)
+++ incubator/chemistry/trunk/opencmis/opencmis-server/opencmis-server-inmemory/src/main/java/org/apache/opencmis/inmemory/server/InMemoryObjectServiceImpl.java Tue Mar 23 12:23:29 2010
@@ -82,21 +82,25 @@ public class InMemoryObjectServiceImpl e
     super(storeManager);
     fAtomLinkProvider = new AtomLinkInfoProvider(fStoreManager);
   }
-  
+
   public String createDocument(CallContext context, String repositoryId, PropertiesData properties,
       String folderId, ContentStreamData contentStream, VersioningState versioningState,
       List<String> policies, AccessControlList addAces, AccessControlList removeAces,
       ExtensionsData extension) {
 
-    LOG.debug("start createDocument()");
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-
-    StoredObject so = createDocumentIntern(repositoryId, properties, folderId, contentStream,
-        versioningState, policies, addAces, removeAces, extension);
-    LOG.debug("stop createDocument()");
-
-    return so.getId();
+    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,
@@ -104,566 +108,670 @@ public class InMemoryObjectServiceImpl e
       List<String> policies, AccessControlList addAces, AccessControlList removeAces,
       ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    try {
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    LOG.debug("start createDocumentFromSource()");
+      LOG.debug("start createDocumentFromSource()");
 
-    StoredObject so = checkStandardParameters(repositoryId, sourceId);
+      StoredObject so = checkStandardParameters(repositoryId, sourceId);
 
-    ContentStreamData content = getContentStream(context, repositoryId, sourceId, null, BigInteger
-        .valueOf(-1), BigInteger.valueOf(-1), null);
+      ContentStreamData content = getContentStream(context, repositoryId, sourceId, null,
+          BigInteger.valueOf(-1), BigInteger.valueOf(-1), null);
 
-    if (so == null)
-      throw new CmisObjectNotFoundException("Unknown object id: " + sourceId);
+      if (so == null)
+        throw new CmisObjectNotFoundException("Unknown object id: " + sourceId);
 
-    // build properties collection
-    List<String> requestedIds = FilterParser.getRequestedIdsFromFilter("*");
+      // build properties collection
+      List<String> requestedIds = FilterParser.getRequestedIdsFromFilter("*");
 
-    PropertiesData existingProps = PropertyCreationHelper.getPropertiesFromObject(repositoryId, so,
-        fStoreManager, requestedIds);
+      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);
+      }
 
-    PropertiesDataImpl newPD = new PropertiesDataImpl();
-    // copy all existing properties
-    for (PropertyData<?> prop : existingProps.getProperties().values()) {
-      newPD.addProperty(prop);
+      String res = createDocument(context, repositoryId, newPD, folderId, content, versioningState,
+          policies, addAces, removeAces, null);
+      LOG.debug("stop createDocumentFromSource()");
+      return res;
     }
-    // overwrite all new properties
-    for (PropertyData<?> prop : properties.getProperties().values()) {
-      newPD.addProperty(prop);
+    finally {
+      RuntimeContext.remove();
     }
-
-    String res = createDocument(context, repositoryId, newPD, folderId, content, versioningState, policies,
-        addAces, removeAces, null);
-    LOG.debug("stop createDocumentFromSource()");
-    return res;
   }
 
   public String createFolder(CallContext context, String repositoryId, PropertiesData properties,
       String folderId, List<String> policies, AccessControlList addAces,
       AccessControlList removeAces, ExtensionsData extension) {
-    LOG.debug("start createFolder()");
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-    
-    Folder folder = createFolderIntern(repositoryId, properties, folderId, policies,
-        addAces, removeAces, extension);
-    LOG.debug("stop createFolder()");
-    return folder.getId();
+    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, PropertiesData properties,
       String folderId, List<String> policies, AccessControlList addAces,
       AccessControlList removeAces, ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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();
+      // 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,
       PropertiesData properties, List<String> policies, AccessControlList addAces,
       AccessControlList removeAces, ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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();
+      // 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)
+  /*
+   * (non-Javadoc)
    * 
-   * 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.
+   * @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, PropertiesData properties,
-      String folderId, ContentStreamData contentStream, VersioningState versioningState, List<String> policies,
-      ExtensionsData extension, ObjectInfoHolder objectInfos) {
+      String folderId, ContentStreamData contentStream, VersioningState versioningState,
+      List<String> policies, ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
-    
-    if (null==properties || null==properties.getProperties())
-        throw new RuntimeException("Cannot create object, without properties.");
+    try {
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    // Find out what kind of object needs to be created
-    PropertyData<String> pd = (PropertyData<String>) properties.getProperties().get(PropertyIds.CMIS_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");
+      if (null == properties || null == properties.getProperties())
+        throw new RuntimeException("Cannot create object, without properties.");
 
-    // check if the given type is a document type
-    BaseObjectTypeIds typeBaseId = typeDefC.getTypeDefinition().getBaseId();
-    StoredObject so= null;
-    if (typeBaseId.equals(InMemoryDocumentTypeDefinition.getRootDocumentType().getBaseId())) {
-      so = createDocumentIntern(repositoryId, properties, folderId, contentStream, versioningState, 
-          null, null, null, null);
-    } else if (typeBaseId.equals(InMemoryFolderTypeDefinition.getRootFolderType().getBaseId())) {
-      so = createFolderIntern(repositoryId, properties, folderId, null, null, null, null);
-    } else if (typeBaseId.equals(InMemoryPolicyTypeDefinition.getRootPolicyType().getBaseId())) {
-      so = createPolicyIntern(repositoryId, properties, folderId, null, null, null, null);
-    } else if (typeBaseId.equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType().getBaseId())) {
-      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);    
+      // Find out what kind of object needs to be created
+      PropertyData<String> pd = (PropertyData<String>) properties.getProperties().get(
+          PropertyIds.CMIS_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
+      BaseObjectTypeIds typeBaseId = typeDefC.getTypeDefinition().getBaseId();
+      StoredObject so = null;
+      if (typeBaseId.equals(InMemoryDocumentTypeDefinition.getRootDocumentType().getBaseId())) {
+        so = createDocumentIntern(repositoryId, properties, folderId, contentStream,
+            versioningState, null, null, null, null);
+      }
+      else if (typeBaseId.equals(InMemoryFolderTypeDefinition.getRootFolderType().getBaseId())) {
+        so = createFolderIntern(repositoryId, properties, folderId, null, null, null, null);
+      }
+      else if (typeBaseId.equals(InMemoryPolicyTypeDefinition.getRootPolicyType().getBaseId())) {
+        so = createPolicyIntern(repositoryId, properties, folderId, null, null, null, null);
+      }
+      else if (typeBaseId.equals(InMemoryRelationshipTypeDefinition.getRootRelationshipType()
+          .getBaseId())) {
+        so = createRelationshipIntern(repositoryId, properties, null, null, null, null);
+      }
+      else
+        LOG.error("The type contains an unknown base object id, object can't be created");
 
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+      // 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);
 
-    return od;
+      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) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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());
 
-    LOG.debug("start deleteContentStream()");
-    StoredObject so = checkStandardParameters(repositoryId, objectId.getValue());
-    
-    if (so == null)
-      throw new CmisObjectNotFoundException("Unknown object id: " + 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, but only documents can have content");
+      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()");
+      ((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) {
+  public void deleteObjectOrCancelCheckOut(CallContext context, String repositoryId,
+      String objectId, Boolean allVersions, ExtensionsData extension) {
 
-    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");
+    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()");
+      objectStore.deleteObject(objectId);
+      LOG.debug("stop deleteObject()");
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public FailedToDeleteData deleteTree(CallContext context, String repositoryId, String folderId,
       Boolean allVersions, UnfileObjects unfileObjects, Boolean continueOnFailure,
       ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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 = UnfileObjects.DELETE;
-    if (null == continueOnFailure)
-      continueOnFailure = false;
-    
-    ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+      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 = UnfileObjects.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 (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 == UnfileObjects.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;
+      if (unfileObjects == UnfileObjects.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 AllowableActionsData getAllowableActions(CallContext context, String repositoryId,
       String objectId, ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().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);
+    try {
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    AllowableActionsData allowableActions = DataObjectCreator.fillAllowableActions(objectStore, so);
-    LOG.debug("stop getAllowableActions()");
-    return allowableActions;
- }
+      LOG.debug("start getAllowableActions()");
+      StoredObject so = checkStandardParameters(repositoryId, objectId);
+      ObjectStore objectStore = fStoreManager.getObjectStore(repositoryId);
+
+      if (so == null)
+        throw new CmisObjectNotFoundException("Unknown object id: " + objectId);
+
+      AllowableActionsData allowableActions = DataObjectCreator.fillAllowableActions(objectStore,
+          so);
+      LOG.debug("stop getAllowableActions()");
+      return allowableActions;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
+  }
 
   public ContentStreamData getContentStream(CallContext context, String repositoryId,
       String objectId, String streamId, BigInteger offset, BigInteger length,
       ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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);
+      LOG.debug("start getContentStream()");
+      StoredObject so = checkStandardParameters(repositoryId, objectId);
 
-    if (so == null)
-      throw new CmisObjectNotFoundException("Unknown object id: " + 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");
+      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;
- }
+      ContentStreamData 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) {
 
-    LOG.debug("start getObject()");
+    try {
+      LOG.debug("start getObject()");
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+      // Attach the CallContext to a thread local context that can be accessed from everywhere
+      RuntimeContext.attachCfg(context);
 
-    StoredObject so = checkStandardParameters(repositoryId, objectId);
+      StoredObject so = checkStandardParameters(repositoryId, objectId);
 
-    if (so == null)
-      throw new CmisObjectNotFoundException("Unknown object id: " + 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;
- }
+      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) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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);
+      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);
 
-    if (so == null)
-      throw new CmisObjectNotFoundException("Unknown path: " + path);
+      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter,
+          includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
+          includeAcl, extension);
 
-    ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, filter,
-        includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
-        includeAcl, extension);
-    
-    LOG.debug("stop getObjectByPath()");
+      LOG.debug("stop getObjectByPath()");
 
-    // To be able to provide all Atom links in the response we need additional information:
-    fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
+      // To be able to provide all Atom links in the response we need additional information:
+      fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfos);
 
-    return od;
+      return od;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
   public PropertiesData getProperties(CallContext context, String repositoryId, String objectId,
       String filter, ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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);
+      LOG.debug("start getProperties()");
+      StoredObject so = checkStandardParameters(repositoryId, objectId);
 
-    if (so == null)
-      throw new CmisObjectNotFoundException("Unknown object id: " + 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;
+      // build properties collection
+      List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
+      PropertiesData 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) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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;
+      // 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) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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;
+      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());
+      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 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");
+      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);
 
-    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;
+      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, ContentStreamData contentStream,
       ExtensionsData extension) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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());
+      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)");
+      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");
+      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()");
+      content.setContent(contentStream, true);
+      LOG.debug("stop setContentStream()");
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
 
-  public ObjectData updateProperties(CallContext context, String repositoryId, Holder<String> objectId,
-      Holder<String> changeToken, PropertiesData properties, AccessControlList acl, ExtensionsData extension,
-      ObjectInfoHolder objectInfos) {
+  public ObjectData updateProperties(CallContext context, String repositoryId,
+      Holder<String> objectId, Holder<String> changeToken, PropertiesData properties,
+      AccessControlList acl, ExtensionsData extension, ObjectInfoHolder objectInfos) {
 
-    // Attach the CallContext to a thread local context that can be accessed from everywhere
-    RuntimeContext.getRuntimeConfig().attachCfg(context);
+    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.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;
+      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;
       }
-    }
 
-    // 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 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))
+      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 Filing) {
+        String newName = (String) pd.getFirstValue();
+        List<Folder> parents = ((Filing) so).getParents();
+        if (so instanceof Folder && parents.isEmpty())
           throw new CmisConstraintException(
-              "updateProperties failed, cannot rename because path already exists.");
+              "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;
       }
-      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 (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 (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 (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);
       }
-    }
-     
-    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);
+      // 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);
+      ObjectData od = PropertyCreationHelper.getObjectData(fStoreManager, so, null, false,
+          IncludeRelationships.NONE, null, false, false, extension);
 
-    LOG.debug("stop updateProperties()");
-    
-    return od;
+      LOG.debug("stop updateProperties()");
+
+      return od;
+    }
+    finally {
+      RuntimeContext.remove();
+    }
   }
+
   // ///////////////////////////////////////////////////////
   // private helper methods
 
@@ -755,7 +863,7 @@ public class InMemoryObjectServiceImpl e
       AccessControlList removeAces, ExtensionsData extension) {
 
     // Attach the CallContext to a thread local context that can be accessed from everywhere
-     checkStandardParameters(repositoryId, folderId);
+    checkStandardParameters(repositoryId, folderId);
 
     ObjectStore fs = fStoreManager.getObjectStore(repositoryId);
     StoredObject so = null;
@@ -771,10 +879,10 @@ public class InMemoryObjectServiceImpl e
 
     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());
+    // 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);
 
@@ -782,7 +890,8 @@ public class InMemoryObjectServiceImpl e
     try {
       LOG.info("get folder for id: " + folderId);
       so = fs.getObjectById(folderId);
-    } catch (Exception e) {
+    }
+    catch (Exception e) {
       throw new CmisObjectNotFoundException("Failed to retrieve folder.", e);
     }
 
@@ -803,7 +912,8 @@ public class InMemoryObjectServiceImpl e
       parent.addChildFolder(newFolder);
       LOG.debug("stop createFolder()");
       return newFolder;
-    } catch (Exception e) {
+    }
+    catch (Exception e) {
       throw new CmisInvalidArgumentException("Failed to create child folder.", e);
     }
   }
@@ -814,9 +924,9 @@ public class InMemoryObjectServiceImpl e
     return null;
   }
 
-  private StoredObject createRelationshipIntern(String repositoryId,
-      PropertiesData properties, List<String> policies, AccessControlList addAces,
-      AccessControlList removeAces, ExtensionsData extension) {
+  private StoredObject createRelationshipIntern(String repositoryId, PropertiesData properties,
+      List<String> policies, AccessControlList addAces, AccessControlList removeAces,
+      ExtensionsData extension) {
     return null;
   }
 
@@ -837,10 +947,9 @@ public class InMemoryObjectServiceImpl e
     return false;
   }
 
-  
- /**
-   * Recursively delete a tree by traversing it and first deleting all children
-   * and then the object itself
+  /**
+   * Recursively delete a tree by traversing it and first deleting all children and then the object
+   * itself
    * 
    * @param folderStore
    * @param parentFolder
@@ -862,10 +971,12 @@ public class InMemoryObjectServiceImpl e
             allVersions, failedToDeleteIds);
         if (!mustContinue && !continueOnFailure)
           return false; // stop further deletions
-      } else {
+      }
+      else {
         try {
           folderStore.deleteObject(child.getId());
-        } catch (Exception e) {
+        }
+        catch (Exception e) {
           failedToDeleteIds.add(child.getId());
         }
       }