]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
DRYD-769: Deprecate items that are in use locally when deleted on a remote server.
authorRay Lee <ray.lee@lyrasis.org>
Fri, 11 Oct 2019 00:14:59 +0000 (17:14 -0700)
committerRay Lee <ray.lee@lyrasis.org>
Thu, 17 Oct 2019 22:50:29 +0000 (15:50 -0700)
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java
services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java

index efca5dcebf8ac723724eb880e3adf8c78947d72f..2d3252fbb61092b2b148b0f0e9727a0e6fbf9b8a 100644 (file)
@@ -38,9 +38,9 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Request;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
-import javax.ws.rs.core.Response.ResponseBuilder;
 
 import org.collectionspace.services.client.IClientQueryParams;
 import org.collectionspace.services.client.IQueryManager;
@@ -49,7 +49,6 @@ import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.client.XmlTools;
 import org.collectionspace.services.client.workflow.WorkflowClient;
-
 import org.collectionspace.services.common.CSWebApplicationException;
 import org.collectionspace.services.common.NuxeoBasedResource;
 import org.collectionspace.services.common.ResourceMap;
@@ -79,26 +78,24 @@ import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.document.Hierarchy;
 import org.collectionspace.services.common.query.QueryManager;
 import org.collectionspace.services.common.repository.RepositoryClient;
-import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityDocumentModelHandler;
-import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
-import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
-
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
+import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityDocumentModelHandler;
+import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler;
+import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
 import org.collectionspace.services.config.ClientType;
 import org.collectionspace.services.config.service.ServiceBindingType;
+import org.collectionspace.services.description.ServiceDescription;
 import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.collectionspace.services.jaxb.AbstractCommonList.ListItem;
 import org.collectionspace.services.lifecycle.TransitionDef;
-import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
+import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentFilter;
 import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.collectionspace.services.workflow.WorkflowCommon;
-import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
-import org.collectionspace.services.description.ServiceDescription;
-
 import org.jboss.resteasy.util.HttpResponseCodes;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
@@ -934,6 +931,14 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         return result.getBytes();
     }
 
+    public PoxPayloadOut updateItemWorkflowWithTransition(ServiceContext<PoxPayloadIn, PoxPayloadOut> existingContext,
+            String parentIdentifier,
+            String itemIdentifier,
+            String transition,
+            boolean updateRevNumber) throws DocumentReferenceException {
+        return updateItemWorkflowWithTransition(existingContext, parentIdentifier, itemIdentifier, transition, updateRevNumber, true);
+    }
+
     /**
      * Update an authority item's workflow state.
      * @param existingContext
@@ -947,7 +952,8 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             String parentIdentifier,
             String itemIdentifier,
             String transition,
-            boolean updateRevNumber) throws DocumentReferenceException {
+            boolean updateRevNumber,
+            boolean rollbackOnException) throws DocumentReferenceException {
         PoxPayloadOut result = null;
 
         try {
@@ -963,6 +969,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             PoxPayloadIn input = new PoxPayloadIn(WorkflowClient.SERVICE_PAYLOAD_NAME, new WorkflowCommon(),
                     WorkflowClient.SERVICE_COMMONPART_NAME);
             MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, input);
+            ctx.setRollbackOnException(rollbackOnException);
             if (existingContext != null && existingContext.getCurrentRepositorySession() != null) {
                 ctx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession());// If a repo session is already open, we need to use it and not create a new one
             }
@@ -1534,6 +1541,13 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         return result;
     }
 
+    public boolean deleteAuthorityItem(ServiceContext<PoxPayloadIn, PoxPayloadOut> existingCtx,
+            String parentIdentifier,
+            String itemIdentifier,
+            boolean shouldUpdateRevNumber) throws Exception {
+        return deleteAuthorityItem(existingCtx, parentIdentifier, itemIdentifier, shouldUpdateRevNumber, true);
+    }
+
     /**
      *
      * @param existingCtx
@@ -1544,11 +1558,13 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
     public boolean deleteAuthorityItem(ServiceContext<PoxPayloadIn, PoxPayloadOut> existingCtx,
             String parentIdentifier,
             String itemIdentifier,
-            boolean shouldUpdateRevNumber
+            boolean shouldUpdateRevNumber,
+            boolean rollbackOnException
             ) throws Exception {
         boolean result = true;
 
         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), existingCtx.getUriInfo());
+        ctx.setRollbackOnException(rollbackOnException);
         if (existingCtx != null && existingCtx.getCurrentRepositorySession() != null) {
             ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession());
             ctx.setProperties(existingCtx.getProperties());
index 6bc5112c25d831f0eb1c7f57ae465b361a4e7c43..e82bb881a7b6ce9395b78cee90533a2bf741fb1e 100644 (file)
@@ -1,5 +1,6 @@
 package org.collectionspace.services.common.vocabulary;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -10,15 +11,17 @@ import javax.ws.rs.core.Response;
 
 import org.collectionspace.services.client.AuthorityClient;
 import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.workflow.WorkflowClient;
 import org.collectionspace.services.common.ServiceMain;
 import org.collectionspace.services.common.api.RefNameUtils;
 import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo;
 import org.collectionspace.services.common.api.Tools;
 import org.collectionspace.services.common.context.MultipartServiceContextImpl;
 import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
-import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityIdentifierUtils;
 import org.collectionspace.services.config.service.ServiceBindingType;
 import org.collectionspace.services.config.tenant.RemoteClientConfig;
 import org.collectionspace.services.config.tenant.RemoteClientConfigurations;
@@ -29,8 +32,6 @@ import org.dom4j.Document;
 import org.dom4j.DocumentHelper;
 import org.dom4j.Node;
 import org.dom4j.XPath;
-import org.collectionspace.services.common.document.DocumentException;
-import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -50,6 +51,9 @@ public class AuthorityServiceUtils {
        public static final boolean UPDATE_REV = true;
        public static final boolean DONT_UPDATE_REV = !UPDATE_REV;
 
+       public static final boolean ROLLBACK_ON_EXCEPTION = true;
+       public static final boolean DONT_ROLLBACK_ON_EXCEPTION = !ROLLBACK_ON_EXCEPTION;
+
        // Used to keep track if an authority item is a locally proposed member of a SAS authority
        public static final String IS_PROPOSED_PROPERTY = "IS_PROPOSED";
        public static final Boolean PROPOSED = true;
@@ -186,19 +190,6 @@ public class AuthorityServiceUtils {
                return result;
        }
 
-       public static boolean setAuthorityItemDeprecated(ServiceContext ctx,
-                       DocumentModel docModel, String authorityItemCommonSchemaName, Boolean flag) throws Exception {
-               boolean result = false;
-
-               docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.DEPRECATED,
-                               new Boolean(flag));
-               CoreSessionInterface repoSession = (CoreSessionInterface) ctx.getCurrentRepositorySession();
-               repoSession.saveDocument(docModel);
-               result = true;
-
-               return result;
-       }
-
        /*
         * The domain name part of refnames on a remote SAS may not match that of local refnames.
         * Update all the payload's refnames with the local domain name.
@@ -350,16 +341,131 @@ public class AuthorityServiceUtils {
         * @param itemInfo
         * @throws Exception
         */
-       public static boolean markAuthorityItemAsDeprecated(ServiceContext ctx, String authorityItemCommonSchemaName, AuthorityItemSpecifier authorityItemSpecifier) throws Exception {
-               boolean result = false;
+       public static boolean setAuthorityItemDeprecated(ServiceContext ctx, AuthorityResource authorityResource, String authorityItemCommonSchemaName, AuthorityItemSpecifier authorityItemSpecifier) throws Exception {
+               DocumentModel docModel = NuxeoUtils.getDocFromSpecifier(ctx, (CoreSessionInterface)ctx.getCurrentRepositorySession(),
+                               authorityItemCommonSchemaName, authorityItemSpecifier);
 
-               try {
-                       DocumentModel docModel = NuxeoUtils.getDocFromSpecifier(ctx, (CoreSessionInterface)ctx.getCurrentRepositorySession(),
-                                       authorityItemCommonSchemaName, authorityItemSpecifier);
-                       result = setAuthorityItemDeprecated(ctx, docModel, authorityItemCommonSchemaName, AuthorityServiceUtils.DEPRECATED);
-               } catch (Exception e) {
-                       logger.warn(String.format("Could not mark item '%s' as deprecated.", authorityItemSpecifier.getItemSpecifier().getURNValue()), e);
-                       throw e;
+               return setAuthorityItemDeprecated(ctx, authorityResource, authorityItemSpecifier.getParentSpecifier().value, authorityItemSpecifier.getItemSpecifier().getURNValue(), docModel);
+       }
+
+       public static boolean setAuthorityItemDeprecated(ServiceContext ctx, AuthorityResource authorityResource, String parentIdentifier, String itemIdentifier, DocumentModel docModel) throws Exception {
+               String currentWorkflowState = docModel.getCurrentLifeCycleState();
+
+               // Find the transitions needed to get from the current state to the replicated deprecated state.
+               List<String> transitions = AuthorityServiceUtils.getTransitionList(WorkflowClient.WORKFLOWSTATE_DEPRECATED, currentWorkflowState);
+
+               if (!transitions.isEmpty()) {
+                       for (String transition : transitions) {
+                               authorityResource.updateItemWorkflowWithTransition(ctx, parentIdentifier, itemIdentifier, transition, AuthorityServiceUtils.DONT_UPDATE_REV);
+                       }
+               }
+
+               return true;
+       }
+
+       /**
+        * We need to change the local item's state to one that maps to the replication server's workflow
+        * state.  This might involve making multiple transitions.
+        *
+        * WIKI:
+        *       See table at https://collectionspace.atlassian.net/wiki/spaces/SDR/pages/665886940/Workflow+transitions+to+map+SAS+item+states+to+Local+item+states
+        *       (was https://wiki.collectionspace.org/pages/viewpage.action?pageId=162496564)
+        *
+        */
+       public static List<String> getTransitionList(String sasWorkflowState, String localItemWorkflowState) throws DocumentException {
+               List<String> result = new ArrayList<String>();
+               //
+               // The first set of conditions maps a replication-server "project" state to a local client state of "replicated"
+               //
+               if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
+                       // Do nothing.  We're good with this state
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+               //
+               // The second set of conditions maps a replication-server "deleted" state to a local client state of "deleted"
+               //
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
+                       // Do nothing.  We're good with this state
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+               //
+               // The third set of conditions maps a replication-server "replicated" state to a local state of "replicated"
+               //
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
+                       // Do nothing.  We're good with this state
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+               //
+               // The fourth set of conditions maps a replicatation-server "deprecated" state to a local state of "replicated_deprecated"
+               //
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
+                       // Do nothing.
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
+               //
+               // The last set of conditions maps a replication-server "replicated_deleted" state to a local client state of "deleted"
+               //
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
+                       // Do nothing.  We're good with this state
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
+               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
+                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
+               } else {
+                       //
+                       // If we get here, we've encountered a SAS workflow state that we don't recognize.
+                       //
+                       throw new DocumentException(String.format("Encountered an invalid workflow state of '%s' on a SAS authority item.", sasWorkflowState));
                }
 
                return result;
index 7439209b6b58ccf015e41333c5d3fd9d8ed5ff43..6054afdd7f107ff6131b2bb0673e431fbe461b03 100644 (file)
@@ -310,22 +310,18 @@ public abstract class AuthorityDocumentModelHandler<AuthCommon> extends NuxeoDoc
 
                        try {
                                authorityResource.deleteAuthorityItem(ctx, parentSpecifier.getURNValue(),
-                                               itemSpecifier.getURNValue(), AuthorityServiceUtils.DONT_UPDATE_REV);
+                                               itemSpecifier.getURNValue(), AuthorityServiceUtils.DONT_UPDATE_REV, AuthorityServiceUtils.DONT_ROLLBACK_ON_EXCEPTION);
 
                                handledCount++;
                        } catch (DocumentReferenceException dre) {
-                               logger.info(String.format("Item %s has existing references and cannot be deleted.", itemShortId), dre);
+                               logger.info(String.format("Failed to delete %s: item is referenced, and will be deprecated instead", itemShortId));
 
                                AuthorityItemSpecifier authorityItemSpecifier = new AuthorityItemSpecifier(parentSpecifier, itemSpecifier);
-                               boolean deprecated = AuthorityServiceUtils.markAuthorityItemAsDeprecated(ctx, authorityItemCommonSchemaName, authorityItemSpecifier);
+                               boolean deprecated = AuthorityServiceUtils.setAuthorityItemDeprecated(ctx, authorityResource, authorityItemCommonSchemaName, authorityItemSpecifier);
 
                                if (deprecated == true) {
                                        handledCount++;
                                }
-                       } catch (Exception e) {
-                               logger.error(String.format("Unable to delete or deprecate item %s", itemShortId), e);
-
-                               throw(e);
                        }
                }
 
index 68c11156e82d6a5c8aeb22097852f49b7adae55e..c3d895e53c07b2467bde3bc6486175efcb0e8b79 100644 (file)
  */
 package org.collectionspace.services.common.vocabulary.nuxeo;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.ws.rs.core.MultivaluedMap;
+
 import org.collectionspace.services.client.AuthorityClient;
 import org.collectionspace.services.client.IQueryManager;
-import org.collectionspace.services.client.PayloadInputPart;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
-import org.collectionspace.services.client.RelationClient;
 import org.collectionspace.services.client.workflow.WorkflowClient;
 import org.collectionspace.services.common.api.RefName;
 import org.collectionspace.services.common.api.Tools;
@@ -41,8 +50,8 @@ import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentReferenceException;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.repository.RepositoryClient;
-import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
+import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityResource;
 import org.collectionspace.services.common.vocabulary.AuthorityServiceUtils;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
@@ -51,31 +60,18 @@ import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specif
 import org.collectionspace.services.config.service.ListResultField;
 import org.collectionspace.services.config.service.ObjectPartType;
 import org.collectionspace.services.lifecycle.TransitionDef;
-import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
+import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
 import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.collectionspace.services.relation.RelationsCommonList;
 import org.collectionspace.services.vocabulary.VocabularyItemJAXBSchema;
-
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.model.PropertyException;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.ws.rs.core.MultivaluedMap;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
 //import org.collectionspace.services.common.authority.AuthorityItemRelations;
 /**
  * AuthorityItemDocumentModelHandler
@@ -518,133 +514,32 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
                //
                // Check to see if we need to update the local items's workflow state to reflect that of the remote's
                //
-               List<String> transitionList = getTransitionList(sasWorkflowState, localItemWorkflowState);
+               List<String> transitionList = AuthorityServiceUtils.getTransitionList(sasWorkflowState, localItemWorkflowState);
+
                if (transitionList.isEmpty() == false) {
                        AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); // Get the authority (parent) client not the item client
                        //
                        // We need to move the local item to the SAS workflow state.  This might involve multiple transitions.
                        //
-                       for (String transition:transitionList) {
-                               try {
-                                       authorityResource.updateItemWorkflowWithTransition(ctx, localParentCsid, localItemCsid, transition, AuthorityServiceUtils.DONT_UPDATE_REV);
-                               } catch (DocumentReferenceException de) {
-                                       //
-                                       // This exception means we tried unsuccessfully to soft-delete (workflow transition 'delete') an item that still has references to it from other records.
-                                       //
-                                       AuthorityServiceUtils.setAuthorityItemDeprecated(ctx, itemDocModel, authorityItemCommonSchemaName, AuthorityServiceUtils.DEPRECATED);  // Since we can't sof-delete it, we need to mark it as deprecated since it is soft-deleted on the SAS
-                                       logger.warn(String.format("Could not transition item CSID='%s' from workflow state '%s' to '%s'.  Check the services log file for details.",
-                                                       localItemCsid, localItemWorkflowState, sasWorkflowState));
+                       try {
+                               for (String transition:transitionList) {
+                                       authorityResource.updateItemWorkflowWithTransition(ctx, localParentCsid, localItemCsid, transition, AuthorityServiceUtils.DONT_UPDATE_REV, AuthorityServiceUtils.DONT_ROLLBACK_ON_EXCEPTION);
                                }
-                       }
-                       result = true;
-               }
+                       } catch (DocumentReferenceException de) {
+                               //
+                               // This exception means we tried unsuccessfully to soft-delete (workflow transition 'delete') an item that still has references to it from other records.
+                               //
+                               logger.info(String.format("Failed to soft-delete %s (transition from %s to %s): item is referenced, and will be deprecated instead", localItemCsid, localItemWorkflowState, sasWorkflowState));
 
-               return result;
-       }
+                               // One or more of the transitions may have succeeded, so refresh the document model to make sure it
+                               // reflects the current workflow state.
+                               itemDocModel.refresh();
 
-       /**
-        * We need to change the local item's state to one that maps to the replication server's workflow
-        * state.  This might involve making multiple transitions.
-        *
-        * WIKI:
-        *       See table at https://collectionspace.atlassian.net/wiki/spaces/SDR/pages/665886940/Workflow+transitions+to+map+SAS+item+states+to+Local+item+states
-        *       (was https://wiki.collectionspace.org/pages/viewpage.action?pageId=162496564)
-        *
-        */
-       private List<String> getTransitionList(String sasWorkflowState, String localItemWorkflowState) throws DocumentException {
-               List<String> result = new ArrayList<String>();
-               //
-               // The first set of conditions maps a replication-server "project" state to a local client state of "replicated"
-               //
-               if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
-                       // Do nothing.  We're good with this state
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-               //
-               // The second set of conditions maps a replication-server "deleted" state to a local client state of "deleted"
-               //
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
-                       // Do nothing.  We're good with this state
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-               //
-               // The third set of conditions maps a replication-server "replicated" state to a local state of "replicated"
-               //
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
-                       // Do nothing.  We're good with this state
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-               //
-               // The fourth set of conditions maps a replicatation-server "deprecated" state to a local state of "replicated_deprecated"
-               //
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DEPRECATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
-                       // Do nothing.
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DEPRECATED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE);
-               //
-               // The last set of conditions maps a replication-server "replicated_deleted" state to a local client state of "deleted"
-               //
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_REPLICATE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED)) {
-                       // Do nothing.  We're good with this state
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE);
-               } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_REPLICATED_DEPRECATED_DELETED)) {
-                       result.add(WorkflowClient.WORKFLOWTRANSITION_UNDEPRECATE);
-               } else {
-                       //
-                       // If we get here, we've encountered a SAS workflow state that we don't recognize.
-                       //
-                       throw new DocumentException(String.format("Encountered an invalid workflow state of '%s' on a SAS authority item.", sasWorkflowState));
+                               // Since we can't soft-delete it, we need to mark it as deprecated since it is soft-deleted on the SAS.
+                               AuthorityServiceUtils.setAuthorityItemDeprecated(ctx, authorityResource, localParentCsid, localItemCsid, itemDocModel);
+                       }
+
+                       result = true;
                }
 
                return result;
index c88323d6ae6483f4e1ef71edcda78aed8e3a9bce..25caaab683e6049ca304753149632e25b7155ac2 100644 (file)
@@ -34,7 +34,6 @@ import javax.ws.rs.core.Request;
 import javax.ws.rs.core.UriInfo;
 
 import org.collectionspace.authentication.AuthN;
-import org.collectionspace.authentication.spi.AuthNContext;
 import org.collectionspace.services.client.AuthorityClient;
 import org.collectionspace.services.client.CollectionSpaceClient;
 import org.collectionspace.services.client.IClientQueryParams;
@@ -42,12 +41,11 @@ import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.workflow.WorkflowClient;
 import org.collectionspace.services.common.ServiceMain;
 import org.collectionspace.services.common.api.Tools;
-import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;
 import org.collectionspace.services.common.config.PropertyItemUtils;
 import org.collectionspace.services.common.config.ServiceConfigUtils;
 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
-import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.DocumentFilter;
+import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.ValidatorHandler;
 import org.collectionspace.services.common.security.SecurityContext;
 import org.collectionspace.services.common.security.SecurityContextImpl;
@@ -87,7 +85,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
     /** The logger. */
     final Logger logger = LoggerFactory.getLogger(AbstractServiceContextImpl.class);
-    
+
     /** The properties. */
     Map<String, Object> properties = new HashMap<String, Object>();
     /** The object part map. */
@@ -116,7 +114,9 @@ public abstract class AbstractServiceContextImpl<IT, OT>
     private Object currentRepositorySession;
     /** A reference count for the current repository session */
     private int currentRepoSesssionRefCount = 0;
-        
+    /** Should the current transaction be rolled back when an exception is caught */
+    private boolean rollbackOnException = true;
+
     /**
      * Instantiates a new abstract service context impl.
      */
@@ -129,9 +129,9 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
     /**
      * Instantiates a new abstract service context impl.
-     * 
+     *
      * @param serviceName the service name
-     * 
+     *
      * @throws UnauthorizedException the unauthorized exception
      */
     protected AbstractServiceContextImpl(String serviceName, UriInfo uriInfo) throws UnauthorizedException {
@@ -180,7 +180,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                }
         }
     }
-    
+
     public int getTimeoutParam(UriInfo ui) {
                int result = DEFAULT_TX_TIMEOUT;
 
@@ -190,9 +190,9 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                        if (timeoutString == null) {
                                timeoutString = queryParams.getFirst(IClientQueryParams.IMPORT_TIMOUT_PARAM);
                        }
-                       
+
                        if (timeoutString != null) {
-                               try {                                   
+                               try {
                                        result = Integer.parseInt(timeoutString);
                                } catch (NumberFormatException e) {
                                        logger.warn("Transaction timeout period parameter could not be parsed.  The characters in the parameter string must all be decimal digits.  The Import service will use the default timeout period instead.",
@@ -203,7 +203,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
                return result;
        }
-    
+
     @Override
     public int getTimeoutSecs() {
        UriInfo uriInfo = this.getUriInfo();
@@ -217,7 +217,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
     @Override
     public boolean shouldUpdateCoreValues() {
                boolean recordUpdates = true;
-               
+
                MultivaluedMap<String, String> queryParams = getQueryParams();
                String paramValue = queryParams.getFirst(IClientQueryParams.UPDATE_CORE_VALUES);
                if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.FALSE.toString())) { // Find our if the caller wants us to record updates
@@ -225,10 +225,10 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                } else if (paramValue != null && paramValue.equals(Long.toString(0))) {
                        recordUpdates = false;
                }
-               
+
                return recordUpdates;
     }
-    
+
        /**
         * Default value is 'FALSE'
         * If this returns true, it means that the refname values in referencing objects (records that reference authority or vocabulary terms) will be updated
@@ -238,7 +238,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
     @Override
     public boolean shouldForceUpdateRefnameReferences() {
                boolean forceUpdates = false;
-               
+
                MultivaluedMap<String, String> queryParams = getQueryParams();
                String paramValue = queryParams.getFirst(IClientQueryParams.FORCE_REFNAME_UPDATES);
                if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.TRUE.toString())) { // Find our if the caller wants us to force refname updates
@@ -246,11 +246,11 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                } else if (paramValue != null && paramValue.equals(Long.toString(1))) {
                        forceUpdates = true;
                }
-               
+
                return forceUpdates;
     }
-    
-    
+
+
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.context.ServiceContext#getCommonPartLabel()
      */
@@ -280,9 +280,9 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
     /**
      * Gets the properties for part.
-     * 
+     *
      * @param partLabel the part label
-     * 
+     *
      * @return the properties for part
      */
     public List<PropertyItemType> getPropertiesForPart(String partLabel) {
@@ -327,7 +327,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
     /**
      * Gets the common part properties.
-     * 
+     *
      * @return the common part properties
      */
     public List<PropertyItemType> getCommonPartProperties() {
@@ -436,16 +436,16 @@ public abstract class AbstractServiceContextImpl<IT, OT>
         // object.
         return (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
     }
-    
+
     @Override
     public String getTenantQualifiedDoctype(String docType) {
         // If they have not overridden the setting, use the type of the service
         // object.
         String result = ServiceBindingUtils.getTenantQualifiedDocType(this.getTenantId(), docType);
-        
+
         return result;
     }
-    
+
     @Override
     public String getTenantQualifiedDoctype() {
         String docType = (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
@@ -565,9 +565,9 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
     /**
      * Helps to filter for queries that either want to include or exclude documents in deleted workflow states.
-     * 
+     *
      * By default, we return *all* objects/records.
-     * 
+     *
      * @param queryParams
      * @return
      */
@@ -576,14 +576,14 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
                String includeDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_DELETED_QP);
                String includeOnlyDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED_QP);  // if set to true, it doesn't matter what the value is for 'includeDeleted'
-               
-               if (includeOnlyDeleted != null) {                       
+
+               if (includeOnlyDeleted != null) {
                        if (Tools.isTrue(includeOnlyDeleted)) {
                                //
                                // A value of 'true' for 'includeOnlyDeleted' means we're looking *only* for soft-deleted records/documents.
                                //
                                result = String.format("(ecm:currentLifeCycleState = '%s' OR ecm:currentLifeCycleState = '%s' OR ecm:currentLifeCycleState = '%s')",
-                                               WorkflowClient.WORKFLOWSTATE_DELETED, 
+                                               WorkflowClient.WORKFLOWSTATE_DELETED,
                                                WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED,
                                                WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED);
                        }
@@ -593,24 +593,24 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                        // Ensure we don't return soft-deleted records
                        //
                        result = String.format("(ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s')",
-                                       WorkflowClient.WORKFLOWSTATE_DELETED, 
+                                       WorkflowClient.WORKFLOWSTATE_DELETED,
                                        WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED,
                                        WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED);
                }
 
                return result;
        }
-    
+
     /**
      * Creates the document handler instance.
-     * 
+     *
      * @return the document handler
-     * 
+     *
      * @throws Exception the exception
      */
     private DocumentHandler createDocumentHandlerInstance() throws Exception {
         docHandler = ServiceConfigUtils.createDocumentHandlerInstance(tenantBinding, serviceBinding);
-        
+
         //
         // The docHandler for a Service can be null, but usually is not.
         //
@@ -631,13 +631,13 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                  docFilter.setPagination(queryParameters);
                  String workflowWhereClause = buildWorkflowWhereClause(queryParameters);
                  if (workflowWhereClause != null) {
-                         docFilter.appendWhereClause(workflowWhereClause, IQueryManager.SEARCH_QUALIFIER_AND);                 
-                 }            
-       
+                         docFilter.appendWhereClause(workflowWhereClause, IQueryManager.SEARCH_QUALIFIER_AND);
+                 }
+
                }
                docHandler.setDocumentFilter(docFilter);
         }
-        
+
         return docHandler;
     }
 
@@ -671,7 +671,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
         documentFilter.setPagination(queryParams);
         return result;
     }
-    
+
     /*
      * If this element is set in the service binding then use it otherwise
      * assume that asserts are NOT disabled.
@@ -682,7 +682,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
        result = (disableAsserts != null) ? disableAsserts : false;
        return result;
     }
-    
+
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.context.ServiceContext#getValidatorHandlers()
      */
@@ -714,7 +714,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
         valHandlers = handlers;
         return valHandlers;
     }
-    
+
     /**
      * If one doesn't already exist, use the default properties filename to load a set of properties that
      * will be used to create an HTTP client to a CollectionSpace instance.
@@ -726,33 +726,33 @@ public abstract class AbstractServiceContextImpl<IT, OT>
         if (authorityClient == null) {
                result = authorityClient = getClient(CollectionSpaceClient.DEFAULT_CLIENT_PROPERTIES_FILENAME);
         }
-       
+
         return result;
     }
-    
+
     /*
      * Use the properties filename passed in to load the URL and credentials that will be used
      * to create a new HTTP client.
-     * 
+     *
      * Never uses or resets the this.authorityClient member.  Always creates a new HTTP client using
      * the loaded properties.
-     * 
+     *
      * (non-Javadoc)
      * @see org.collectionspace.services.common.context.ServiceContext#getClient(java.lang.String)
      */
        @Override
     public AuthorityClient getClient(String clientPropertiesFilename) throws Exception {
        AuthorityClient result = null;
-       
+
         Properties inProperties = Tools.loadProperties(clientPropertiesFilename, true);
         result = getClient(inProperties);
-        
+
         return result;
     }
-    
+
     public AuthorityClient getClient(Properties inProperties) throws Exception {
        AuthorityClient result = null;
-       
+
         String authorityClientClazz = getServiceBinding().getClientHandler();
         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
         authorityClientClazz = authorityClientClazz.trim();
@@ -770,14 +770,14 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                logger.warn(msg);
                logger.trace(msg, e);
         }
-        
+
         return result;
     }
-    
+
     @Override
     public AuthorityClient getClient(RemoteClientConfig remoteClientConfig) throws Exception {
        AuthorityClient result = null;
-       
+
         Properties properties = new Properties();
         properties.setProperty(AuthorityClient.URL_PROPERTY, remoteClientConfig.getUrl());
         properties.setProperty(AuthorityClient.USER_PROPERTY, remoteClientConfig.getUser());
@@ -794,12 +794,12 @@ public abstract class AbstractServiceContextImpl<IT, OT>
         if (tenantName != null) {
                properties.setProperty(AuthorityClient.TENANT_NAME_PROPERTY, tenantName);
         }
-        
+
         result = getClient(properties);
-        
+
         return result;
     }
-    
+
     @Override
     public void addValidatorHandler(ValidatorHandler<IT, OT> validator) throws Exception {
         if (valHandlers == null) {
@@ -832,7 +832,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
 
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.context.ServiceContext#getQueryParams()
-     * 
+     *
      * When we first created these services, the RESTEasy query parameters used to be a modifiable map.  That changed in a
      * more recent version of RESTEasy, so we need to make a copy of the params into a modifiable map and return it instead.
      */
@@ -872,17 +872,17 @@ public abstract class AbstractServiceContextImpl<IT, OT>
        public UriInfo getUriInfo() {
                return this.uriInfo;
        }
-       
+
        @Override
        public Request getRequestInfo() {
                return this.requestInfo;
        }
-       
+
        @Override
        public void setRequestInfo(Request requestInfo) {
                this.requestInfo = requestInfo;
        }
-       
+
        /*
         * We expect the 'currentRepositorySession' member to be set only once per instance.  Also, we expect only one open repository session
         * per HTTP request.  We'll log an error if we see more than one attempt to set a service context's current repo session.
@@ -900,42 +900,42 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                        logger.error(errMsg);
                        throw new Exception(errMsg);
                }
-               
+
                currentRepositorySession = repoSession;
                this.currentRepoSesssionRefCount++;
        }
-       
+
        @Override
        public void clearCurrentRepositorySession() {
                if (this.currentRepoSesssionRefCount > 0) {
                        currentRepoSesssionRefCount--;
                }
-               
+
                if (currentRepoSesssionRefCount == 0) {
                        this.currentRepositorySession = null;
                }
-               
+
                if (currentRepoSesssionRefCount < 0) {
                        throw new RuntimeException("Attempted to clear/close a repository session that has already been cleared/closed.");
                }
        }
-       
+
        @Override
        public Object getCurrentRepositorySession() {
                // TODO Auto-generated method stub
                return currentRepositorySession;
-       }       
+       }
 
-       @Override       
+       @Override
        public RepositoryDomainType getRepositoryDomain() {
                return repositoryDomain;
        }
 
-       @Override       
+       @Override
        public void setRepositoryDomain(RepositoryDomainType repositoryDomain) {
                this.repositoryDomain = repositoryDomain;
        }
-       
+
        /**
         * Check for a query parameter that indicates if we should force a sync even if the revision numbers indicate otherwise.
         * @return
@@ -943,7 +943,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
        @Override
        public boolean shouldForceSync() {
                boolean forceSync = false;
-               
+
                MultivaluedMap<String, String> queryParams = getQueryParams();
                String paramValue = queryParams.getFirst(IClientQueryParams.FORCE_SYCN);
                if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.TRUE.toString())) { // Find our if the caller wants us to force refname updates
@@ -951,8 +951,17 @@ public abstract class AbstractServiceContextImpl<IT, OT>
                } else if (paramValue != null && paramValue.equals(Long.toString(1))) {
                        forceSync = true;
                }
-               
+
                return forceSync;
     }
-       
+
+    @Override
+    public void setRollbackOnException(boolean rollbackOnException) {
+        this.rollbackOnException = rollbackOnException;
+    }
+
+    @Override
+    public boolean isRollbackOnException() {
+        return this.rollbackOnException;
+    }
 }
index 5adce86dff23cc71f0cab1258b59c1bd8c4c05ce..bcdec5065a100309d7826fbad8751117906d5c7a 100644 (file)
@@ -66,9 +66,9 @@ public interface ServiceContext<IT, OT> {
     /** The Constant PART_COMMON_LABEL. */
     public static final String PART_COMMON_LABEL = "common";
     /** Used to qualify document types **/
-       public static final String TENANT_SUFFIX = "Tenant";    
+       public static final String TENANT_SUFFIX = "Tenant";
 
-    /** 
+    /**
      * Tells the TransactionManager to use the default value.  The default value can
      * be set in this file:
      *                 services/JaxRsServiceProvider/src/main/webapp/META-INF/context.xml
@@ -78,25 +78,25 @@ public interface ServiceContext<IT, OT> {
      *                 transactionTimeoutSeconds="300"/>
      * See the following documentation page for more details:
      *                 http://docs.oracle.com/javaee/7/api/javax/transaction/TransactionManager.html#setTransactionTimeout(int)
-     * 
+     *
      */
        public static final int DEFAULT_TX_TIMEOUT = 0;
-       
-       /* 
+
+       /*
         * Sets the current/open repository session
         */
        public void setCurrentRepositorySession(Object repoSession) throws Exception;
-       
+
        /*
         * Decrements the context's repo session ref count and nulls it if the count becomes 0.
         */
        public void clearCurrentRepositorySession();
-       
+
        /*
         * If a current repository session exists, returns it.
         */
        public Object getCurrentRepositorySession();
-       
+
     /**
      * getSecurityContext is contains security info. for the service layer
      */
@@ -108,12 +108,12 @@ public interface ServiceContext<IT, OT> {
      * @return
      */
     public boolean shouldUpdateCoreValues();
-    
+
     /**
      * getTimeoutSecs();
      */
     public int getTimeoutSecs();
-    
+
     /**
      * getUserId get authenticated user's userId
      */
@@ -149,16 +149,16 @@ public interface ServiceContext<IT, OT> {
      * @return service name
      */
     public String getDocumentType();
-    
+
     /**
      * Returns a tenant qualified document type.
-     * 
+     *
      */
     public String getTenantQualifiedDoctype();
-    
+
     /**
      * Returns a tenant qualified document type.
-     * 
+     *
      */
     public String getTenantQualifiedDoctype(String docType);
 
@@ -180,16 +180,16 @@ public interface ServiceContext<IT, OT> {
      * @return repository domain for the tenant
      */
     public String getRepositoryDomainName();
-    
+
     /*
      * The name of the repository/db for the current context
      */
     public String getRepositoryName() throws Exception;
-    
+
     /*
      * Get's the name/label used to create the storage container (folder or directory name)
      */
-    public String getRepositoryDomainStorageName();    
+    public String getRepositoryDomainStorageName();
 
     /**
      * getRepositoryClientName returns the repository client name as
@@ -228,7 +228,7 @@ public interface ServiceContext<IT, OT> {
      * @return the input
      */
     public IT getInput();
-    
+
     /**
      * setInput is used to set request input before starting to
      * process input data
@@ -257,9 +257,9 @@ public interface ServiceContext<IT, OT> {
      * @param map the map of service names to resource instances.
      */
     public void setResourceMap(ResourceMap map);
-    
+
     /**
-     * 
+     *
      * @param jaxsRsRequest - Keep track of the JAX-RS request information
      */
     public void setRequestInfo(Request jaxsRsRequest);
@@ -271,14 +271,14 @@ public interface ServiceContext<IT, OT> {
     public Map<String, ObjectPartType> getPartsMetadata();
 
     /**
-     * getCommonPartLabel returns label for common part of a service 
+     * getCommonPartLabel returns label for common part of a service
      * @return label
      */
     public String getCommonPartLabel();
 
     /**
      * getCommonPartLabel returns label for common part of a specified schema.
-     * This is useful for sub-resources. 
+     * This is useful for sub-resources.
      * @return label
      */
     public String getCommonPartLabel(String schemaName);
@@ -325,11 +325,11 @@ public interface ServiceContext<IT, OT> {
 
     /**
      * Gets the document hanlder.
-     * 
+     *
      * @param queryParams the query params
-     * 
+     *
      * @return the document hanlder
-     * 
+     *
      * @throws Exception the exception
      */
     public DocumentHandler getDocumentHandler(MultivaluedMap<String, String> queryParams) throws Exception;
@@ -350,7 +350,7 @@ public interface ServiceContext<IT, OT> {
 
     /**
      * Gets the query params.
-     * 
+     *
      * @return the query params
      */
     public MultivaluedMap<String, String> getQueryParams();
@@ -359,7 +359,7 @@ public interface ServiceContext<IT, OT> {
 
     /**
      * Sets the query params.
-     * 
+     *
      * @param queryParams the query params
      */
     public void setQueryParams(MultivaluedMap<String, String> queryParams);
@@ -373,20 +373,20 @@ public interface ServiceContext<IT, OT> {
        public void setRepositoryDomain(RepositoryDomainType repositoryDomain);
 
        public CollectionSpaceClient getClient() throws Exception;
-       
+
        public CollectionSpaceClient getClient(String clientProperitesFilename) throws Exception;
-       
+
        public CollectionSpaceClient getClient(RemoteClientConfig remoteClientConfig) throws Exception;
 
     /**
      * @return the JAX-RS resource of service for the current context.
-     * @throws Exception 
+     * @throws Exception
      */
     public CollectionSpaceResource<IT, OT> getResource() throws Exception;
 
     /**
      * @return the JAX-RS resource of service for the current context.
-     * @throws Exception 
+     * @throws Exception
      */
        public CollectionSpaceResource<IT, OT> getResource(
                        String serviceName) throws Exception;
@@ -405,44 +405,44 @@ public interface ServiceContext<IT, OT> {
        public boolean shouldForceSync();
 
        /**
-        * 
+        *
         * @return The JAX-RS request information
         */
        Request getRequestInfo();
-       
+
        /**
-        * 
+        *
         */
        public TransactionContext openConnection() throws TransactionException; // Only 1 active connection at a time
-       
+
        /**
-        * 
+        *
         */
        public boolean hasActiveConnection();
-       
+
        /**
-        * 
+        *
         */
        public void closeConnection() throws TransactionException; // Assumes there's been a call to getConnection.
-       
+
        /**
-        * @throws TransactionException 
-        * 
+        * @throws TransactionException
+        *
         */
        void setTransactionContext(TransactionContext transactionCtx) throws TransactionException; // For sharing a transaction context with another service context.
-       
+
        /**
-        * 
+        *
         */
        public boolean isTransactionContextShared() throws TransactionException;
 
        /**
-        * 
+        *
         * @return
         */
        TransactionContext getCurrentTransactionContext();
 
-}
-
-
+       public void setRollbackOnException(boolean rollbackOnException);
 
+       public boolean isRollbackOnException();
+}
index 461ae716e152072921d6670a24e4ec329c7406b4..4cb45327d2c4a70da112bb616a89108271045f96 100644 (file)
@@ -32,9 +32,13 @@ import java.util.UUID;
 import javax.sql.rowset.CachedRowSet;
 import javax.ws.rs.core.MultivaluedMap;
 
-import org.collectionspace.services.lifecycle.TransitionDef;
-import org.collectionspace.services.nuxeo.util.CSReindexFulltextRoot;
-import org.collectionspace.services.nuxeo.util.NuxeoUtils;
+//
+// CSPACE-5036 - How to make CMISQL queries from Nuxeo
+//
+import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
+import org.apache.chemistry.opencmis.server.shared.ThresholdOutputStreamFactory;
 import org.collectionspace.services.client.CollectionSpaceClient;
 import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.PoxPayloadIn;
@@ -42,57 +46,50 @@ import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.client.Profiler;
 import org.collectionspace.services.client.index.IndexClient;
 import org.collectionspace.services.client.workflow.WorkflowClient;
+import org.collectionspace.services.common.CSWebApplicationException;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.api.Tools;
+import org.collectionspace.services.common.config.ConfigUtils;
+import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
+import org.collectionspace.services.common.config.TenantBindingUtils;
 import org.collectionspace.services.common.context.ServiceContext;
-import org.collectionspace.services.common.query.QueryContext;
-import org.collectionspace.services.common.repository.RepositoryClient;
-import org.collectionspace.services.common.storage.JDBCTools;
-import org.collectionspace.services.common.storage.PreparedStatementSimpleBuilder;
 import org.collectionspace.services.common.document.BadRequestException;
 import org.collectionspace.services.common.document.DocumentException;
 import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentHandler;
-import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentHandler.Action;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.document.DocumentWrapperImpl;
 import org.collectionspace.services.common.document.TransactionException;
-import org.collectionspace.services.common.CSWebApplicationException;
-import org.collectionspace.services.common.ServiceMain;
-import org.collectionspace.services.common.api.Tools;
-import org.collectionspace.services.common.config.ConfigUtils;
-import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
-import org.collectionspace.services.common.config.TenantBindingUtils;
+import org.collectionspace.services.common.query.QueryContext;
+import org.collectionspace.services.common.repository.RepositoryClient;
+import org.collectionspace.services.common.storage.JDBCTools;
 import org.collectionspace.services.common.storage.PreparedStatementBuilder;
+import org.collectionspace.services.common.storage.PreparedStatementSimpleBuilder;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
 import org.collectionspace.services.config.service.ServiceBindingType;
-import org.collectionspace.services.config.tenant.TenantBindingType;
 import org.collectionspace.services.config.tenant.RepositoryDomainType;
-
-//
-// CSPACE-5036 - How to make CMISQL queries from Nuxeo
-//
-import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
-import org.apache.chemistry.opencmis.commons.server.CallContext;
-import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
-import org.apache.chemistry.opencmis.server.shared.ThresholdOutputStreamFactory;
+import org.collectionspace.services.config.tenant.TenantBindingType;
+import org.collectionspace.services.lifecycle.TransitionDef;
+import org.collectionspace.services.nuxeo.util.CSReindexFulltextRoot;
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.nuxeo.common.utils.IdUtils;
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
-import org.nuxeo.ecm.core.api.IterableQueryResult;
-import org.nuxeo.ecm.core.api.VersioningOption;
-import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
 import org.nuxeo.ecm.core.api.DocumentRef;
 import org.nuxeo.ecm.core.api.IdRef;
+import org.nuxeo.ecm.core.api.IterableQueryResult;
 import org.nuxeo.ecm.core.api.PathRef;
-import org.nuxeo.runtime.api.Framework;
-import org.nuxeo.runtime.transaction.TransactionRuntimeException;
+import org.nuxeo.ecm.core.api.VersioningOption;
+import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
 import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactory;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
-import org.nuxeo.elasticsearch.api.ElasticSearchAdmin;
-import org.nuxeo.elasticsearch.api.ElasticSearchIndexing;
-import org.nuxeo.elasticsearch.api.ElasticSearchService;
 import org.nuxeo.elasticsearch.ElasticSearchComponent;
+import org.nuxeo.elasticsearch.api.ElasticSearchService;
+import org.nuxeo.runtime.api.Framework;
+import org.nuxeo.runtime.transaction.TransactionRuntimeException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -216,10 +213,14 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
             handler.complete(Action.CREATE, wrapDoc);
             return id;
         } catch (BadRequestException bre) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw bre;
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
                if (logger.isDebugEnabled()) {
                        logger.debug("Call to low-level Nuxeo document create call failed: ", e);
                }
@@ -278,7 +279,9 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
             CSReindexFulltextRoot indexer = new CSReindexFulltextRoot(repoSession);
             indexer.reindexFulltext(0, 0, queryString);
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception trying to reindex Nuxeo repository ", e);
             }
@@ -342,7 +345,9 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
 
             result = true;
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception trying to reindex Nuxeo repository ", e);
             }
@@ -374,13 +379,19 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
             result = handler.handle(Action.SYNC, wrapDoc);
             handler.complete(Action.SYNC, wrapDoc);
         } catch (IllegalArgumentException iae) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw iae;
         } catch (DocumentException de) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw de;
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
@@ -413,13 +424,19 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
             result = handler.handle(Action.SYNC, wrapDoc);
             handler.complete(Action.SYNC, wrapDoc);
         } catch (IllegalArgumentException iae) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw iae;
         } catch (DocumentException de) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw de;
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
@@ -1709,16 +1726,25 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
             doc.refresh();
             handler.complete(Action.UPDATE, wrapDoc);
         } catch (BadRequestException bre) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw bre;
         } catch (DocumentException de) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
+
             throw de;
         } catch (CSWebApplicationException wae) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw wae;
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
@@ -1868,10 +1894,14 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
                    handler.complete(Action.DELETE, wrapDoc);
             }
         } catch (DocumentException de) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                   rollbackTransaction(repoSession);
+            }
             throw de;
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            if (ctx.isRollbackOnException()) {
+                rollbackTransaction(repoSession);
+            }
             throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
@@ -1961,7 +1991,7 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
                 logger.debug("Path to Workspaces root: " + workspacesRoot.getPathAsString());
             }
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            rollbackTransaction(repoSession);
             if (logger.isDebugEnabled()) {
                 logger.debug("Could not create tenant domain name=" + repositoryDomain.getStorageName() + " caught exception ", e);
             }
@@ -2063,7 +2093,7 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient<PoxPayloadIn,
                         + " id=" + workspaceId);
             }
         } catch (Throwable e) {
-               rollbackTransaction(repoSession);
+            rollbackTransaction(repoSession);
             if (logger.isDebugEnabled()) {
                 logger.debug("createWorkspace caught exception ", e);
             }