From: remillet Date: Thu, 21 Apr 2016 04:30:11 +0000 (-0700) Subject: CSPACE-6937-A: Added mapping for SAS workflow states to the client workflow states... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=40f419961800a12d1673333dc809d3dc8c4125f9;p=tmp%2Fjakarta-migration.git CSPACE-6937-A: Added mapping for SAS workflow states to the client workflow states for authority items. --- diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java index 198519283..33c719806 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java @@ -69,6 +69,7 @@ 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.DocumentReferenceException; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.Hierarchy; import org.collectionspace.services.common.query.QueryManager; @@ -231,7 +232,7 @@ public abstract class AuthorityResource private CsidAndShortIdentifier lookupParentCSIDAndShortIdentifer( - ServiceContext itemServiceCtx, // Ok to be null + ServiceContext existingCtx, // Ok to be null String parentIdentifier, String method, String op, @@ -253,8 +254,8 @@ public abstract class AuthorityResource String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, parentShortIdentifier); ServiceContext ctx = createServiceContext(getServiceName(), uriInfo); CoreSessionInterface repoSession = null; - if (itemServiceCtx != null) { - repoSession = (CoreSessionInterface) itemServiceCtx.getCurrentRepositorySession(); // We want to use the thread's current repo session + if (existingCtx != null) { + repoSession = (CoreSessionInterface) existingCtx.getCurrentRepositorySession(); // We want to use the thread's current repo session } parentcsid = getRepositoryClient(ctx).findDocCSID(repoSession, ctx, whereClause); //FIXME: REM - If the parent has been soft-deleted, should we be looking for the item? } @@ -265,15 +266,20 @@ public abstract class AuthorityResource return result; } - public String lookupItemCSID(ServiceContext ctx, String itemspecifier, String parentcsid, String method, String op) - throws DocumentException { + public String lookupItemCSID(ServiceContext existingContext, String itemspecifier, String parentcsid, String method, String op) + throws Exception { String itemcsid; Specifier itemSpec = Specifier.getSpecifier(itemspecifier, method, op); if (itemSpec.form == SpecifierForm.CSID) { itemcsid = itemSpec.value; } else { String itemWhereClause = RefNameServiceUtils.buildWhereForAuthItemByName(authorityItemCommonSchemaName, itemSpec.value, parentcsid); - itemcsid = getRepositoryClient(ctx).findDocCSID(null, ctx, itemWhereClause); //FIXME: REM - Should we be looking for the 'wf_deleted' query param and filtering on it? + MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(getItemServiceName()); + CoreSessionInterface repoSession = null; + if (existingContext != null) { + repoSession = (CoreSessionInterface) existingContext.getCurrentRepositorySession(); // We want to use the thread's current repo session + } + itemcsid = getRepositoryClient(ctx).findDocCSID(repoSession, ctx, itemWhereClause); //FIXME: REM - Should we be looking for the 'wf_deleted' query param and filtering on it? } return itemcsid; } @@ -688,16 +694,16 @@ public abstract class AuthorityResource @PUT @Path("{csid}/items/{itemcsid}" + WorkflowClient.SERVICE_PATH + "/{transition}") public byte[] updateItemWorkflowWithTransition( - @PathParam("csid") String csid, - @PathParam("itemcsid") String itemcsid, + @PathParam("csid") String parentIdentifier, + @PathParam("itemcsid") String itemIdentifier, @PathParam("transition") String transition) { PoxPayloadOut result = null; try { - result = updateItemWorkflowWithTransition(NULL_CONTEXT, // Ok to send null - csid, itemcsid, transition, AuthorityServiceUtils.UPDATE_REV); + result = updateItemWorkflowWithTransition(NULL_CONTEXT, + parentIdentifier, itemIdentifier, transition, AuthorityServiceUtils.UPDATE_REV); } catch (Exception e) { - throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid); + throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, parentIdentifier); } return result.getBytes(); @@ -710,16 +716,23 @@ public abstract class AuthorityResource * @param itemcsid * @param transition * @return + * @throws DocumentReferenceException */ public PoxPayloadOut updateItemWorkflowWithTransition(ServiceContext existingContext, - String parentCsid, - String itemCsid, + String parentIdentifier, + String itemIdentifier, String transition, - boolean updateRevNumber) { + boolean updateRevNumber) throws DocumentReferenceException { PoxPayloadOut result = null; try { // + // We need CSIDs for both the parent authority and the authority item + // + CsidAndShortIdentifier csidAndShortId = lookupParentCSIDAndShortIdentifer(existingContext, parentIdentifier, "updateItemWorkflowWithTransition(parent)", "UPDATE_ITEM", null); + String itemCsid = lookupItemCSID(existingContext, itemIdentifier, csidAndShortId.CSID, "updateAuthorityItem(item)", "UPDATE_ITEM"); + + // // Create an empty workflow_commons input part and set it into a new "workflow" sub-resource context // PoxPayloadIn input = new PoxPayloadIn(WorkflowClient.SERVICE_PAYLOAD_NAME, new WorkflowCommon(), @@ -748,8 +761,10 @@ public abstract class AuthorityResource WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx); getRepositoryClient(ctx).update(ctx, itemCsid, handler); result = ctx.getOutput(); + } catch (DocumentReferenceException de) { + throw de; } catch (Exception e) { - throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, itemCsid); + throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, itemIdentifier); } return result; @@ -786,7 +801,6 @@ public abstract class AuthorityResource } } - return result; } @@ -1003,10 +1017,10 @@ public abstract class AuthorityResource UriTemplateRegistry uriTemplateRegistry, UriInfo uriInfo) throws Exception { AuthorityRefDocList authRefDocList = null; - - ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); - MultivaluedMap queryParams = ctx.getQueryParams(); - + + ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); + MultivaluedMap queryParams = ctx.getQueryParams(); + // // Merge parts of existing context with our new context // if (existingContext != null && existingContext.getCurrentRepositorySession() != null) { @@ -1014,16 +1028,14 @@ public abstract class AuthorityResource ctx.setProperties(existingContext.getProperties()); } - String parentcsid = lookupParentCSID(parentspecifier, "getReferencingObjects(parent)", "GET_ITEM_REF_OBJS", uriInfo); - String itemcsid = lookupItemCSID(ctx, itemspecifier, parentcsid, "getReferencingObjects(item)", "GET_ITEM_REF_OBJS"); + String parentcsid = lookupParentCSID(parentspecifier, "getReferencingObjects(parent)", "GET_ITEM_REF_OBJS", uriInfo); + String itemcsid = lookupItemCSID(ctx, itemspecifier, parentcsid, "getReferencingObjects(item)", "GET_ITEM_REF_OBJS"); - List serviceTypes = queryParams.remove(ServiceBindingUtils.SERVICE_TYPE_PROP); - if(serviceTypes == null || serviceTypes.isEmpty()) { - serviceTypes = ServiceBindingUtils.getCommonServiceTypes(true); //CSPACE-5359: Should now include objects, procedures, and authorities - } + List serviceTypes = queryParams.remove(ServiceBindingUtils.SERVICE_TYPE_PROP); + if (serviceTypes == null || serviceTypes.isEmpty()) { + serviceTypes = ServiceBindingUtils.getCommonServiceTypes(true); //CSPACE-5359: Should now include objects, procedures, and authorities + } - // Note that we have to create the service context for the Items, not the main service - // We omit the parentShortId, only needed when doing a create... AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parentcsid, null); authRefDocList = handler.getReferencingObjects(ctx, uriTemplateRegistry, serviceTypes, getRefPropName(), itemcsid); diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java index 14b346c19..8b694b8cd 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java @@ -4,11 +4,15 @@ import javax.ws.rs.core.Response; import org.collectionspace.services.client.AuthorityClient; import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo; import org.collectionspace.services.common.context.MultipartServiceContextImpl; import org.collectionspace.services.common.context.ServiceContext; 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.nuxeo.client.java.CoreSessionInterface; +import org.collectionspace.services.nuxeo.util.NuxeoUtils; +import org.nuxeo.ecm.core.api.DocumentModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -78,4 +82,37 @@ public class AuthorityServiceUtils { return result; } + + static public boolean setAuthorityItemDeprecated(DocumentModel docModel, String authorityItemCommonSchemaName, Boolean flag) throws Exception { + boolean result = false; + + docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.DEPRECATED, + new Boolean(flag)); + CoreSessionInterface session = (CoreSessionInterface) docModel.getCoreSession(); + session.saveDocument(docModel); + result = true; + + return result; + } + + /** + * Mark the authority item as deprecated. + * + * @param ctx + * @param itemInfo + * @throws Exception + */ + static public boolean markAuthorityItemAsDeprecated(ServiceContext ctx, String authorityItemCommonSchemaName, String itemCsid) throws Exception { + boolean result = false; + + try { + DocumentModel docModel = NuxeoUtils.getDocFromCsid(ctx, (CoreSessionInterface)ctx.getCurrentRepositorySession(), itemCsid); + result = setAuthorityItemDeprecated(docModel, authorityItemCommonSchemaName, AuthorityServiceUtils.DEPRECATED); + } catch (Exception e) { + logger.warn(String.format("Could not mark item '%s' as deprecated.", itemCsid), e); + throw e; + } + + return result; + } } \ No newline at end of file diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java index da8b055ce..37060f9bc 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java @@ -243,7 +243,8 @@ public abstract class AuthorityDocumentModelHandler } catch (DocumentReferenceException de) { logger.info(String.format("Authority item '%s' has existing references and cannot be removed during sync.", refName), de); - boolean marked = markAuthorityItemAsDeprecated(ctx, itemInfo); + boolean marked = AuthorityServiceUtils.markAuthorityItemAsDeprecated(ctx, authorityItemCommonSchemaName, + itemInfo.csid); if (marked == true) { result++; } @@ -263,32 +264,6 @@ public abstract class AuthorityDocumentModelHandler return result; } - /** - * Mark the authority item as deprecated. - * - * @param ctx - * @param itemInfo - * @throws Exception - */ - private boolean markAuthorityItemAsDeprecated(ServiceContext ctx, AuthorityTermInfo itemInfo) throws Exception { - boolean result = false; - - try { - String itemCsid = itemInfo.csid; - DocumentModel docModel = NuxeoUtils.getDocFromCsid(ctx, (CoreSessionInterface)ctx.getCurrentRepositorySession(), itemCsid); - docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.DEPRECATED, - new Boolean(AuthorityServiceUtils.DEPRECATED)); - CoreSessionInterface session = (CoreSessionInterface) ctx.getCurrentRepositorySession(); - session.saveDocument(docModel); - result = true; - } catch (Exception e) { - logger.warn(String.format("Could not mark item '%s' as deprecated.", itemInfo.name), e); - throw e; - } - - return result; - } - /** * Gets the list of SAS related items in the local authority. We exlude items with the "proposed" flags because * we want a list with only SAS created items. @@ -366,7 +341,7 @@ public abstract class AuthorityDocumentModelHandler itemIdentifier, parentIdentifier)); } // - // Handle the workflow state + // Since we're creating an item that was sourced from the SAS, we need to lock it. // authorityResource.updateItemWorkflowWithTransition(ctx, parentIdentifier, itemIdentifier, WorkflowClient.WORKFLOWTRANSITION_LOCK, AuthorityServiceUtils.DONT_UPDATE_REV); @@ -499,7 +474,7 @@ public abstract class AuthorityDocumentModelHandler * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#handleWorkflowTransition(org.collectionspace.services.common.document.DocumentWrapper, org.collectionspace.services.lifecycle.TransitionDef) */ @Override - public void handleWorkflowTransition(DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception { + public void handleWorkflowTransition(ServiceContext ctx, DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception { // Update the revision number updateRevNumbers(wrapDoc); } diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java index 95804a67b..fd6d102f3 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java @@ -373,15 +373,20 @@ public abstract class AuthorityItemDocumentModelHandler * Warning: This method might change the transitionDef's transtionName value */ @Override - public void handleWorkflowTransition(DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception { + public void handleWorkflowTransition(ServiceContext ctx, DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception { // Decide whether or not to update the revision number if (this.getShouldUpdateRevNumber() == true) { // We don't update the rev number of synchronization requests updateRevNumbers(wrapDoc); } - + // + // We can't delete an authority item that has referencing records. + // DocumentModel docModel = wrapDoc.getWrappedObject(); - if (this.hasReferencingObjects(this.getServiceContext(), docModel) == true) { - + if (transitionDef.getName().equalsIgnoreCase(WorkflowClient.WORKFLOWTRANSITION_DELETE)) { + if (hasReferencingObjects(this.getServiceContext(), docModel) == true) { + throw new DocumentReferenceException(String.format("Cannot delete authority item '%s' because it still has records in the system that are referencing it. See the service layer log file for details.", + docModel.getName())); + } } } @@ -447,20 +452,23 @@ public abstract class AuthorityItemDocumentModelHandler // // If the workflow states are different, we need to update the local's to reflects the remote's // - if (localItemWorkflowState.equalsIgnoreCase(sasWorkflowState) == false) { + List transitionList = 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. // - List transitionList = getTransitionList(sasWorkflowState, localItemWorkflowState); for (String transition:transitionList) { - if (transition.equalsIgnoreCase(WorkflowClient.WORKFLOWTRANSITION_DELETE) == true) { - if (hasReferencingObjects(ctx, itemDocModel)) { - throw new DocumentReferenceException(String.format("Cannot soft-delete authority item '%s' because it still has records in the system that are referencing it. See the service layer log file for details.", - itemDocModel.getName())); - } + 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(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)); } - authorityResource.updateItemWorkflowWithTransition(ctx, localParentCsid, localItemCsid, transition, AuthorityServiceUtils.DONT_UPDATE_REV); } result = true; } @@ -470,26 +478,66 @@ public abstract class AuthorityItemDocumentModelHandler /** * We need to move the local item to the SAS workflow state. This might involve multiple transitions. + * See table at https://wiki.collectionspace.org/pages/viewpage.action?pageId=162496556 + * @throws DocumentException */ - private List getTransitionList(String sasWorkflowState, String localItemWorkflowState) { - List result = new ArrayList(); - + private List getTransitionList(String sasWorkflowState, String localItemWorkflowState) throws DocumentException { + List result = new ArrayList(); // - // If the SAS authority items is soft-deleted, we need to mark the local item as soft-deleted + // The first set of conditions maps a SAS "project" state to a local state of "locked" // - if (sasWorkflowState.contains(WorkflowClient.WORKFLOWSTATE_DELETED)) { - result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE); - } else if (sasWorkflowState.equalsIgnoreCase(WorkflowClient.WORKFLOWSTATE_PROJECT)) { + if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) { result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE); - } - + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED)) { + // Do nothing. We're good with this state + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE); + // + // The second set of conditions maps a SAS "deleted" state to a local state of "deleted" + // + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED)) { + // Do nothing. We're good with this state // - // Ensure the local item is always in a "locked" state. Items sync'd with a SAS should always be locked + // The third set of conditions maps a SAS "locked" state to a local state of "locked" + // + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE); + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED)) { + // Do nothing. We're good with this state + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_UNDELETE); + // + // The last set of conditions maps a SAS "locked_deleted" state to a local state of "deleted" // - if (localItemWorkflowState.contains(WorkflowClient.WORKFLOWSTATE_LOCKED) != true) { // REM - This may be a bad assumption to make. + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_PROJECT)) { result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED)) { + result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE); + } else if (sasWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED) && localItemWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED)) { + // Do nothing. We're good with this state + } 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; } @@ -543,7 +591,9 @@ public abstract class AuthorityItemDocumentModelHandler result = true; logger.error(String.format("Cannot delete authority item '%s' because it still has %d records in the system that are referencing it.", itemCsid, refObjs.getTotalItems())); - logReferencingObjects(docModel, refObjs); + if (logger.isWarnEnabled() == true) { + logReferencingObjects(docModel, refObjs); + } } return result; @@ -552,8 +602,9 @@ public abstract class AuthorityItemDocumentModelHandler private void logReferencingObjects(DocumentModel docModel, AuthorityRefDocList refObjs) { List items = refObjs.getAuthorityRefDocItem(); int i = 0; + logger.warn(String.format("The authority item '%s' has the following references:", docModel.getName())); for (AuthorityRefDocList.AuthorityRefDocItem item : items) { - logger.debug(docModel.getName() + ": list-item[" + i + "] " + logger.warn(docModel.getName() + " referenced by : list-item[" + i + "] " + item.getDocType() + "(" + item.getDocId() + ") Name:[" + item.getDocName() + "] Number:[" @@ -763,7 +814,7 @@ public abstract class AuthorityItemDocumentModelHandler String propertyName, String itemcsid) throws Exception { AuthorityRefDocList authRefDocList = null; - CoreSessionInterface repoSession = null; + CoreSessionInterface repoSession = (CoreSessionInterface) ctx.getCurrentRepositorySession(); boolean releaseRepoSession = false; try { diff --git a/services/client/src/main/java/org/collectionspace/services/client/workflow/WorkflowClient.java b/services/client/src/main/java/org/collectionspace/services/client/workflow/WorkflowClient.java index 634b66c0c..7f9d68432 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/workflow/WorkflowClient.java +++ b/services/client/src/main/java/org/collectionspace/services/client/workflow/WorkflowClient.java @@ -50,6 +50,7 @@ public class WorkflowClient extends AbstractCommonListPoxServiceClientImpl { /** * updateWorkflowTransition - prepare for a workflow transition */ - public void handleWorkflowTransition(DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception; + public void handleWorkflowTransition(ServiceContext ctx, DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception; /** * prepareCreate processes documents before creating document in repository diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java index 65f577013..9ce64108e 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java @@ -3,6 +3,7 @@ package org.collectionspace.services.common.storage.jpa; import java.util.List; import org.collectionspace.services.common.api.RefName; +import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; @@ -65,8 +66,7 @@ public abstract class JpaDocumentHandler } @Override - public void handleWorkflowTransition( - DocumentWrapper wrapDoc, TransitionDef transitionDef) + public void handleWorkflowTransition(ServiceContext ctx, DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception { // Do nothing. JPA document handlers do not support workflow transitions yet. } diff --git a/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java b/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java index 696bc4641..089411984 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java @@ -69,9 +69,13 @@ public class WorkflowDocumentModelHandler // ServiceContext ctx = this.getServiceContext(); DocumentModelHandler targetDocHandler = (DocumentModelHandler)ctx.getProperty(WorkflowClient.TARGET_DOCHANDLER); + + // We need to make sure the repo session is available to the handler and its service context targetDocHandler.setRepositorySession(this.getRepositorySession()); // Make sure the target doc handler has a repository session to work with + targetDocHandler.getServiceContext().setCurrentRepositorySession(this.getRepositorySession()); + TransitionDef transitionDef = (TransitionDef)ctx.getProperty(WorkflowClient.TRANSITION_ID); - targetDocHandler.handleWorkflowTransition(wrapDoc, transitionDef); // Call the target resouce's handler first + targetDocHandler.handleWorkflowTransition(ctx, wrapDoc, transitionDef); // Call the target resouce's handler first // // If no exception occurred, then call the super's method // @@ -201,6 +205,6 @@ public class WorkflowDocumentModelHandler ClientException ce = new ClientException("Unable to follow workflow transition: " + transitionToFollow); throw ce; } - } + } } diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java index a70327bea..0d46995d5 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java @@ -79,13 +79,10 @@ import org.collectionspace.services.relation.RelationsCommon; import org.collectionspace.services.relation.RelationsCommonList; import org.collectionspace.services.relation.RelationsDocListItem; import org.collectionspace.services.relation.RelationshipType; - import org.dom4j.Element; - import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.core.api.model.PropertyException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -193,9 +190,8 @@ public abstract class RemoteDocumentModelHandlerImpl return result; } - @Override - public void handleWorkflowTransition(DocumentWrapper wrapDoc, TransitionDef transitionDef) + public void handleWorkflowTransition(ServiceContext ctx, DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception { // Do nothing by default, but children can override if they want. The real workflow transition happens in the WorkflowDocumemtModelHandler class } diff --git a/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java b/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java index 98d94e5c6..8d30d6c87 100644 --- a/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java +++ b/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java @@ -115,7 +115,7 @@ public class RelationDocumentModelHandler * * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#handleWorkflowTransition(org.collectionspace.services.common.document.DocumentWrapper, org.collectionspace.services.lifecycle.TransitionDef) */ - public void handleWorkflowTransition(DocumentWrapper wrapDoc, TransitionDef transitionDef) + public void handleWorkflowTransition(ServiceContext ctx, DocumentWrapper wrapDoc, TransitionDef transitionDef) throws Exception { if (subjectOrObjectInWorkflowState(wrapDoc, WorkflowClient.WORKFLOWSTATE_LOCKED) == true) { throw new ServiceException(HttpURLConnection.HTTP_FORBIDDEN,