From 01458d331c27e7b2d48a175fa6b23d482f91dcdc Mon Sep 17 00:00:00 2001 From: Richard Millet Date: Fri, 2 Mar 2018 18:55:21 -0800 Subject: [PATCH] DRYD-306: Added code to ensure vocab terms can be deleted when they're not being referenced by other records. --- .../common/vocabulary/AuthorityResource.java | 693 ++++++----- .../AuthorityItemDocumentModelHandler.java | 1078 +++++++++-------- .../services/authorization/RoleResource.java | 17 +- .../nuxeo/UpdateObjectLocationBatchJob.java | 2 +- .../services/client/ClaimProxy.java | 4 +- .../client/workflow/WorkflowClient.java | 6 +- .../services/common/api/Tools.java | 395 +++--- .../AbstractCollectionSpaceResourceImpl.java | 4 +- .../services/common/SecurityResourceBase.java | 79 +- .../context/AbstractServiceContextImpl.java | 14 +- .../common/document/DocumentException.java | 13 + .../common/document/DocumentHandler.java | 6 + .../storage/jpa/JpaDocumentHandler.java | 6 +- .../storage/jpa/JpaStorageClientImpl.java | 227 ++-- .../java/NuxeoDocumentModelHandler.java | 5 + .../java/NuxeoRepositoryClientImpl.java | 4 +- .../nuxeo/RelationDocumentModelHandler.java | 29 +- .../StructureddateDocumentHandler.java | 5 + .../systeminfo/SystemInfoDocumentHandler.java | 5 + 19 files changed, 1323 insertions(+), 1269 deletions(-) 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 6edc0e79f..2c13f9554 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 @@ -114,7 +114,7 @@ import org.w3c.dom.Element; @Produces("application/xml") public abstract class AuthorityResource extends NuxeoBasedResource { - + final Logger logger = LoggerFactory.getLogger(AuthorityResource.class); final static String SEARCH_TYPE_TERMSTATUS = "ts"; @@ -128,9 +128,9 @@ public abstract class AuthorityResource final static String FETCH_SHORT_ID = "_fetch_"; public final static String PARENT_WILDCARD = "_ALL_"; - protected static final boolean DONT_INCLUDE_ITEMS = false; - protected static final boolean INCLUDE_ITEMS = true; - + protected static final boolean DONT_INCLUDE_ITEMS = false; + protected static final boolean INCLUDE_ITEMS = true; + /** * Instantiates a new Authority resource. */ @@ -179,7 +179,7 @@ public abstract class AuthorityResource ServiceContext containerCtx = createServiceContext(getServiceName()); if (containerShortIdentifier.equals(FETCH_SHORT_ID)) { // We need to fetch this from the repo if (ctx.getCurrentRepositorySession() != null) { - containerCtx.setCurrentRepositorySession(ctx.getCurrentRepositorySession()); // We need to use the current repo session if one exists + containerCtx.setCurrentRepositorySession(ctx.getCurrentRepositorySession()); // We need to use the current repo session if one exists } // Get from parent document containerShortIdentifier = getAuthShortIdentifier(containerCtx, inAuthority); @@ -220,7 +220,7 @@ public abstract class AuthorityResource ServiceContext ctx, String shortIdentifier) { RefName.Authority authority = RefName.Authority.buildAuthority(ctx.getTenantName(), ctx.getServiceName(), - null, // Only use shortId form!!! + null, // Only use shortId form!!! shortIdentifier, null); return authority.toString(); } @@ -230,27 +230,27 @@ public abstract class AuthorityResource String shortIdentifier; } - protected String lookupParentCSID(String parentspecifier, String method, - String op, UriInfo uriInfo) throws Exception { - CsidAndShortIdentifier tempResult = lookupParentCSIDAndShortIdentifer(NULL_CONTEXT, - parentspecifier, method, op, uriInfo); - return tempResult.CSID; - } - - protected String lookupParentCSID(ServiceContext ctx, String parentspecifier, String method, - String op, UriInfo uriInfo) throws Exception { - CsidAndShortIdentifier tempResult = lookupParentCSIDAndShortIdentifer(ctx, - parentspecifier, method, op, uriInfo); - return tempResult.CSID; - } + protected String lookupParentCSID(String parentspecifier, String method, + String op, UriInfo uriInfo) throws Exception { + CsidAndShortIdentifier tempResult = lookupParentCSIDAndShortIdentifer(NULL_CONTEXT, + parentspecifier, method, op, uriInfo); + return tempResult.CSID; + } + + protected String lookupParentCSID(ServiceContext ctx, String parentspecifier, String method, + String op, UriInfo uriInfo) throws Exception { + CsidAndShortIdentifier tempResult = lookupParentCSIDAndShortIdentifer(ctx, + parentspecifier, method, op, uriInfo); + return tempResult.CSID; + } private CsidAndShortIdentifier lookupParentCSIDAndShortIdentifer( - ServiceContext existingCtx, // Ok to be null - String parentIdentifier, - String method, - String op, - UriInfo uriInfo) + ServiceContext existingCtx, // Ok to be null + String parentIdentifier, + String method, + String op, + UriInfo uriInfo) throws Exception { CsidAndShortIdentifier result = new CsidAndShortIdentifier(); Specifier parentSpec = Specifier.getSpecifier(parentIdentifier, method, op); @@ -269,7 +269,7 @@ public abstract class AuthorityResource ServiceContext ctx = createServiceContext(getServiceName(), uriInfo); CoreSessionInterface repoSession = null; if (existingCtx != null) { - repoSession = (CoreSessionInterface) existingCtx.getCurrentRepositorySession(); // We want to use the thread's current repo session + 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? } @@ -289,10 +289,10 @@ public abstract class AuthorityResource itemcsid = itemSpec.value; } else { String itemWhereClause = RefNameServiceUtils.buildWhereForAuthItemByName(authorityItemCommonSchemaName, itemSpec.value, parentcsid); - MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(getItemServiceName()); + 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 + 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? } @@ -306,11 +306,11 @@ public abstract class AuthorityResource * Resource. They then call this method on that resource. */ @Override - public DocumentModel getDocModelForAuthorityItem(CoreSessionInterface repoSession, RefName.AuthorityItem item) - throws Exception, DocumentNotFoundException { - if (item == null) { - return null; - } + public DocumentModel getDocModelForAuthorityItem(CoreSessionInterface repoSession, RefName.AuthorityItem item) + throws Exception, DocumentNotFoundException { + if (item == null) { + return null; + } String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, item.getParentShortIdentifier()); // Ensure we have the right context. ServiceContext ctx = createServiceContext(item.inAuthority.resource); @@ -329,36 +329,36 @@ public abstract class AuthorityResource @POST public Response createAuthority( - @Context ResourceMap resourceMap, - @Context UriInfo uriInfo, - String xmlPayload) { - // - // Requests to create new authorities come in on new threads. Unfortunately, we need to synchronize those threads on this block because, as of 8/27/2015, we can't seem to get Nuxeo - // transaction code to deal with a database level UNIQUE constraint violations on the 'shortidentifier' column of the vocabularies_common table. - // Therefore, to prevent having multiple authorities with the same shortid, we need to synchronize - // the code that creates new authorities. The authority document model handler will first check for authorities with the same short id before - // trying to create a new authority. - // - synchronized(AuthorityResource.class) { - try { - PoxPayloadIn input = new PoxPayloadIn(xmlPayload); - ServiceContext ctx = createServiceContext(input); - DocumentHandler handler = createDocumentHandler(ctx); - - String csid = getRepositoryClient(ctx).create(ctx, handler); - UriBuilder path = UriBuilder.fromResource(resourceClass); - path.path("" + csid); - Response response = Response.created(path.build()).build(); - return response; - } catch (Exception e) { - throw bigReThrow(e, ServiceMessages.CREATE_FAILED); - } - } + @Context ResourceMap resourceMap, + @Context UriInfo uriInfo, + String xmlPayload) { + // + // Requests to create new authorities come in on new threads. Unfortunately, we need to synchronize those threads on this block because, as of 8/27/2015, we can't seem to get Nuxeo + // transaction code to deal with a database level UNIQUE constraint violations on the 'shortidentifier' column of the vocabularies_common table. + // Therefore, to prevent having multiple authorities with the same shortid, we need to synchronize + // the code that creates new authorities. The authority document model handler will first check for authorities with the same short id before + // trying to create a new authority. + // + synchronized(AuthorityResource.class) { + try { + PoxPayloadIn input = new PoxPayloadIn(xmlPayload); + ServiceContext ctx = createServiceContext(input); + DocumentHandler handler = createDocumentHandler(ctx); + + String csid = getRepositoryClient(ctx).create(ctx, handler); + UriBuilder path = UriBuilder.fromResource(resourceClass); + path.path("" + csid); + Response response = Response.created(path.build()).build(); + return response; + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.CREATE_FAILED); + } + } } protected boolean supportsReplicating(String tenantId, String serviceName) { - boolean result = false; - + boolean result = false; + ServiceBindingType sb = getTenantBindingsReader().getServiceBinding(tenantId, getServiceName()); result = sb.isSupportsReplicating(); @@ -378,56 +378,56 @@ public abstract class AuthorityResource @Context Request request, @Context UriInfo uriInfo, @PathParam("csid") String identifier) { - uriInfo = new UriInfoWrapper(uriInfo); - byte[] result; - boolean neededSync = false; + uriInfo = new UriInfoWrapper(uriInfo); + byte[] result; + boolean neededSync = false; PoxPayloadOut payloadOut = null; Specifier specifier; // // Prevent multiple SAS synchronizations from occurring simultaneously by synchronizing this method. // - synchronized(AuthorityResource.class) { - try { - ServiceContext ctx = createServiceContext(uriInfo); - /* - * Make sure this authority service supports synchronization - */ - if (supportsReplicating(ctx.getTenantId(), ctx.getServiceName()) == false) { - throw new DocumentException(Response.Status.FORBIDDEN.getStatusCode()); - } - AuthorityDocumentModelHandler handler = (AuthorityDocumentModelHandler)createDocumentHandler(ctx); - specifier = Specifier.getSpecifier(identifier, "getAuthority", "GET"); - handler.setShouldUpdateRevNumber(AuthorityServiceUtils.DONT_UPDATE_REV); // Never update rev number on sync calls - neededSync = getRepositoryClient(ctx).synchronize(ctx, specifier, handler); - payloadOut = ctx.getOutput(); - } catch (Exception e) { - throw bigReThrow(e, ServiceMessages.SYNC_FAILED, identifier); - } - - // - // If a sync was needed and was successful, return a copy of the updated resource. Acts like an UPDATE. - // - if (neededSync == true) { - result = payloadOut.getBytes(); - } else { - result = String.format("Authority resource '%s' was already in sync with shared authority server.", - specifier.value).getBytes(); - Response response = Response.status(Response.Status.NOT_MODIFIED).entity(result).type("text/plain").build(); - throw new CSWebApplicationException(response); - } - } - - return result; + synchronized(AuthorityResource.class) { + try { + ServiceContext ctx = createServiceContext(uriInfo); + /* + * Make sure this authority service supports synchronization + */ + if (supportsReplicating(ctx.getTenantId(), ctx.getServiceName()) == false) { + throw new DocumentException(Response.Status.FORBIDDEN.getStatusCode()); + } + AuthorityDocumentModelHandler handler = (AuthorityDocumentModelHandler)createDocumentHandler(ctx); + specifier = Specifier.getSpecifier(identifier, "getAuthority", "GET"); + handler.setShouldUpdateRevNumber(AuthorityServiceUtils.DONT_UPDATE_REV); // Never update rev number on sync calls + neededSync = getRepositoryClient(ctx).synchronize(ctx, specifier, handler); + payloadOut = ctx.getOutput(); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.SYNC_FAILED, identifier); + } + + // + // If a sync was needed and was successful, return a copy of the updated resource. Acts like an UPDATE. + // + if (neededSync == true) { + result = payloadOut.getBytes(); + } else { + result = String.format("Authority resource '%s' was already in sync with shared authority server.", + specifier.value).getBytes(); + Response response = Response.status(Response.Status.NOT_MODIFIED).entity(result).type("text/plain").build(); + throw new CSWebApplicationException(response); + } + } + + return result; } /* * Builds a cached JAX-RS response. */ protected Response buildResponse(ServiceContext ctx, PoxPayloadOut payloadOut) { - Response result = null; + Response result = null; - ResponseBuilder responseBuilder = Response.ok(payloadOut.getBytes()); + ResponseBuilder responseBuilder = Response.ok(payloadOut.getBytes()); this.setCacheControl(ctx, responseBuilder); result = responseBuilder.build(); @@ -448,8 +448,8 @@ public abstract class AuthorityResource @Context Request request, @Context UriInfo uriInfo, @PathParam("csid") String specifier) { - Response result = null; - uriInfo = new UriInfoWrapper(uriInfo); + Response result = null; + uriInfo = new UriInfoWrapper(uriInfo); try { ServiceContext ctx = createServiceContext(request, uriInfo); @@ -469,13 +469,13 @@ public abstract class AuthorityResource return result; } - protected PoxPayloadOut getAuthority( - ServiceContext ctx, + protected PoxPayloadOut getAuthority( + ServiceContext ctx, Request request, UriInfo uriInfo, String specifier, boolean includeItems) throws Exception { - uriInfo = new UriInfoWrapper(uriInfo); + uriInfo = new UriInfoWrapper(uriInfo); PoxPayloadOut payloadout = null; DocumentHandler docHandler = createDocumentHandler(ctx); @@ -492,10 +492,10 @@ public abstract class AuthorityResource getRepositoryClient(ctx).get(ctx, docHandler); } - payloadout = ctx.getOutput(); + payloadout = ctx.getOutput(); if (includeItems == true) { - AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo); - payloadout.addPart(PoxPayload.ABSTRACT_COMMON_LIST_ROOT_ELEMENT_LABEL, itemsList); + AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo); + payloadout.addPart(PoxPayload.ABSTRACT_COMMON_LIST_ROOT_ELEMENT_LABEL, itemsList); } return payloadout; @@ -511,14 +511,14 @@ public abstract class AuthorityResource @GET @Produces("application/xml") public AbstractCommonList getAuthorityList(@Context UriInfo uriInfo) { //FIXME - REM 5/3/2012 - This is not reachable from the JAX-RS dispatcher. Instead the equivalent method in ResourceBase is getting called. - uriInfo = new UriInfoWrapper(uriInfo); - AbstractCommonList result = null; - - try { + uriInfo = new UriInfoWrapper(uriInfo); + AbstractCommonList result = null; + + try { MultivaluedMap queryParams = uriInfo.getQueryParameters(); ServiceContext ctx = createServiceContext(uriInfo); - DocumentHandler handler = createDocumentHandler(ctx); + DocumentHandler handler = createDocumentHandler(ctx); DocumentFilter myFilter = handler.getDocumentFilter(); // Need to make the default sort order for authority items // be on the displayName field @@ -555,7 +555,7 @@ public abstract class AuthorityResource AuthorityDocumentModelHandler handler = (AuthorityDocumentModelHandler) createDocumentHandler(ctx); Boolean shouldUpdateRev = (Boolean) ctx.getProperty(AuthorityServiceUtils.SHOULD_UPDATE_REV_PROPERTY); if (shouldUpdateRev != null) { - handler.setShouldUpdateRevNumber(shouldUpdateRev); + handler.setShouldUpdateRevNumber(shouldUpdateRev); } getRepositoryClient(ctx).update(ctx, csid, handler); return ctx.getOutput(); @@ -571,9 +571,9 @@ public abstract class AuthorityResource @PUT @Path("{csid}") public byte[] updateAuthority( - @Context Request request, - @Context ResourceMap resourceMap, - @Context UriInfo uriInfo, + @Context Request request, + @Context ResourceMap resourceMap, + @Context UriInfo uriInfo, @PathParam("csid") String specifier, String xmlPayload) { PoxPayloadOut result = null; @@ -612,23 +612,23 @@ public abstract class AuthorityResource try { ServiceContext ctx = createServiceContext(uriInfo); - RepositoryClient repoClient = this.getRepositoryClient(ctx); + RepositoryClient repoClient = this.getRepositoryClient(ctx); - CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx); - try { - DocumentHandler handler = createDocumentHandler(ctx); - // - // Delete all the items one by one - // - AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo); - for (ListItem item : itemsList.getListItem()) { - deleteAuthorityItem(ctx, specifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV); - } - } catch (Throwable t) { - repoSession.setTransactionRollbackOnly(); - throw t; + CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx); + try { + DocumentHandler handler = createDocumentHandler(ctx); + // + // Delete all the items one by one + // + AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo); + for (ListItem item : itemsList.getListItem()) { + deleteAuthorityItem(ctx, specifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV); + } + } catch (Throwable t) { + repoSession.setTransactionRollbackOnly(); + throw t; } finally { - repoClient.releaseRepositorySession(ctx, repoSession); + repoClient.releaseRepositorySession(ctx, repoSession); } return Response.status(HttpResponseCodes.SC_OK).build(); @@ -659,40 +659,40 @@ public abstract class AuthorityResource try { ServiceContext ctx = createServiceContext(uriInfo); Specifier spec = Specifier.getSpecifier(specifier, "getAuthority", "GET"); - RepositoryClient repoClient = this.getRepositoryClient(ctx); + RepositoryClient repoClient = this.getRepositoryClient(ctx); - CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx); - try { - DocumentHandler handler = createDocumentHandler(ctx); - // - // First try to delete all the items - // - AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo); - for (ListItem item : itemsList.getListItem()) { - deleteAuthorityItem(ctx, specifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV); - } - - // - // Lastly, delete the parent/container - // - if (spec.form == SpecifierForm.CSID) { - if (logger.isDebugEnabled()) { - logger.debug("deleteAuthority with csid=" + spec.value); - } - ensureCSID(spec.value, ServiceMessages.DELETE_FAILED, "Authority.csid"); - getRepositoryClient(ctx).delete(ctx, spec.value, handler); - } else { - if (logger.isDebugEnabled()) { - logger.debug("deleteAuthority with specifier=" + spec.value); - } - String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, spec.value); - getRepositoryClient(ctx).deleteWithWhereClause(ctx, whereClause, handler); - } - } catch (Throwable t) { - repoSession.setTransactionRollbackOnly(); - throw t; + CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx); + try { + DocumentHandler handler = createDocumentHandler(ctx); + // + // First try to delete all the items + // + AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo); + for (ListItem item : itemsList.getListItem()) { + deleteAuthorityItem(ctx, specifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV); + } + + // + // Lastly, delete the parent/container + // + if (spec.form == SpecifierForm.CSID) { + if (logger.isDebugEnabled()) { + logger.debug("deleteAuthority with csid=" + spec.value); + } + ensureCSID(spec.value, ServiceMessages.DELETE_FAILED, "Authority.csid"); + getRepositoryClient(ctx).delete(ctx, spec.value, handler); + } else { + if (logger.isDebugEnabled()) { + logger.debug("deleteAuthority with specifier=" + spec.value); + } + String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, spec.value); + getRepositoryClient(ctx).deleteWithWhereClause(ctx, whereClause, handler); + } + } catch (Throwable t) { + repoSession.setTransactionRollbackOnly(); + throw t; } finally { - repoClient.releaseRepositorySession(ctx, repoSession); + repoClient.releaseRepositorySession(ctx, repoSession); } return Response.status(HttpResponseCodes.SC_OK).build(); @@ -701,39 +701,39 @@ public abstract class AuthorityResource } } - private String getCsid(ListItem item) { - String result = null; - - for (Element ele : item.getAny()) { - String elementName = ele.getTagName().toLowerCase(); - if (elementName.equals("csid")) { - result = ele.getTextContent(); - break; - } - } - - return result; - } - - /** + private String getCsid(ListItem item) { + String result = null; + + for (Element ele : item.getAny()) { + String elementName = ele.getTagName().toLowerCase(); + if (elementName.equals("csid")) { + result = ele.getTextContent(); + break; + } + } + + return result; + } + + /** * * @param ctx - * @param parentspecifier - ID of the container. Can be URN or CSID form + * @param parentspecifier - ID of the container. Can be URN or CSID form * @param shouldUpdateRevNumber - Indicates if the revision number should be updated on create -won't do this when synching with SAS - * @param isProposed - In a shared authority context, indicates if this item just a proposed item and not yet part of the SAS authority + * @param isProposed - In a shared authority context, indicates if this item just a proposed item and not yet part of the SAS authority * @return * @throws Exception */ protected Response createAuthorityItem(ServiceContext ctx, String parentIdentifier, - boolean shouldUpdateRevNumber, - boolean isProposed, - boolean isSasItem) throws Exception { - Response result = null; - + boolean shouldUpdateRevNumber, + boolean isProposed, + boolean isSasItem) throws Exception { + Response result = null; + // Note: must have the parentShortId, to do the create. CsidAndShortIdentifier parent = lookupParentCSIDAndShortIdentifer(ctx, parentIdentifier, "createAuthorityItem", "CREATE_ITEM", null); AuthorityItemDocumentModelHandler handler = - (AuthorityItemDocumentModelHandler) createItemDocumentHandler(ctx, parent.CSID, parent.shortIdentifier); + (AuthorityItemDocumentModelHandler) createItemDocumentHandler(ctx, parent.CSID, parent.shortIdentifier); handler.setShouldUpdateRevNumber(shouldUpdateRevNumber); handler.setIsProposed(isProposed); handler.setIsSASItem(isSasItem); @@ -745,12 +745,12 @@ public abstract class AuthorityResource path.path(parent.CSID + "/items/" + itemcsid); result = Response.created(path.build()).build(); - return result; + return result; } public PoxPayloadOut updateAuthorityItem( - ServiceContext itemServiceCtx, // Ok to be null. Will be null on PUT calls, but not on sync calls - ResourceMap resourceMap, + ServiceContext itemServiceCtx, // Ok to be null. Will be null on PUT calls, but not on sync calls + ResourceMap resourceMap, UriInfo uriInfo, String parentspecifier, String itemspecifier, @@ -769,9 +769,9 @@ public abstract class AuthorityResource // ServiceContext ctx = itemServiceCtx; if (ctx == null) { - ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo); + ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo); } else { - ctx.setInput(theUpdate); // the update payload + ctx.setInput(theUpdate); // the update payload } String itemcsid = lookupItemCSID(ctx, itemspecifier, parentcsid, "updateAuthorityItem(item)", "UPDATE_ITEM"); //use itemServiceCtx if it is not null @@ -785,13 +785,13 @@ public abstract class AuthorityResource boolean updateSASFields = isProposed != null || isSASItem != null; handler.setshouldUpdateSASFields(updateSASFields); if (updateSASFields == true) { - handler.setshouldUpdateSASFields(true); - if (isProposed != null) { - handler.setIsProposed(isProposed); - } - if (isSASItem != null) { - handler.setIsSASItem(isSASItem); - } + handler.setshouldUpdateSASFields(true); + if (isProposed != null) { + handler.setIsProposed(isProposed); + } + if (isSASItem != null) { + handler.setIsSASItem(isSASItem); + } } getRepositoryClient(ctx).update(ctx, itemcsid, handler); @@ -809,21 +809,21 @@ public abstract class AuthorityResource * @throws Exception */ public Response createAuthorityItemWithParentContext(ServiceContext parentCtx, - String parentIdentifier, - PoxPayloadIn input, - boolean shouldUpdateRevNumber, - boolean isProposed, - boolean isSASItem) throws Exception { - Response result = null; - + String parentIdentifier, + PoxPayloadIn input, + boolean shouldUpdateRevNumber, + boolean isProposed, + boolean isSASItem) throws Exception { + Response result = null; + ServiceContext ctx = createServiceContext(getItemServiceName(), input, - parentCtx.getResourceMap(), parentCtx.getUriInfo()); + parentCtx.getResourceMap(), parentCtx.getUriInfo()); if (parentCtx.getCurrentRepositorySession() != null) { - ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession()); + ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession()); } result = this.createAuthorityItem(ctx, parentIdentifier, shouldUpdateRevNumber, isProposed, isSASItem); - return result; + return result; } /************************************************************************* @@ -834,18 +834,18 @@ public abstract class AuthorityResource @POST @Path("{csid}/items") public Response createAuthorityItem( - @Context ResourceMap resourceMap, - @Context UriInfo uriInfo, - @PathParam("csid") String parentIdentifier, // Either a CSID or a URN form -e.g., a8ad38ec-1d7d-4bf2-bd31 or urn:cspace:name(bugsbunny) - String xmlPayload) { - uriInfo = new UriInfoWrapper(uriInfo); - Response result = null; - + @Context ResourceMap resourceMap, + @Context UriInfo uriInfo, + @PathParam("csid") String parentIdentifier, // Either a CSID or a URN form -e.g., a8ad38ec-1d7d-4bf2-bd31 or urn:cspace:name(bugsbunny) + String xmlPayload) { + uriInfo = new UriInfoWrapper(uriInfo); + Response result = null; + try { PoxPayloadIn input = new PoxPayloadIn(xmlPayload); ServiceContext ctx = createServiceContext(getItemServiceName(), input, resourceMap, uriInfo); result = this.createAuthorityItem(ctx, parentIdentifier, AuthorityServiceUtils.UPDATE_REV, - AuthorityServiceUtils.PROPOSED, AuthorityServiceUtils.NOT_SAS_ITEM); + AuthorityServiceUtils.PROPOSED, AuthorityServiceUtils.NOT_SAS_ITEM); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.CREATE_FAILED); } @@ -884,13 +884,13 @@ public abstract class AuthorityResource @PathParam("csid") String parentIdentifier, @PathParam("itemcsid") String itemIdentifier, @PathParam("transition") String transition) { - uriInfo = new UriInfoWrapper(uriInfo); + uriInfo = new UriInfoWrapper(uriInfo); PoxPayloadOut result = null; try { ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); result = updateItemWorkflowWithTransition(ctx, - parentIdentifier, itemIdentifier, transition, AuthorityServiceUtils.UPDATE_REV); + parentIdentifier, itemIdentifier, transition, AuthorityServiceUtils.UPDATE_REV); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, parentIdentifier); } @@ -912,23 +912,23 @@ public abstract class AuthorityResource String itemIdentifier, String transition, boolean updateRevNumber) throws DocumentReferenceException { - PoxPayloadOut result = null; - + PoxPayloadOut result = null; + try { - // - // We need CSIDs for both the parent authority and the authority item - // + // + // 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(), - WorkflowClient.SERVICE_COMMONPART_NAME); + // 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(), + WorkflowClient.SERVICE_COMMONPART_NAME); MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, input); 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 + ctx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession());// If a repo session is already open, we need to use it and not create a new one } // // Create a service context and document handler for the target resource -not the workflow resource itself. @@ -943,11 +943,11 @@ public abstract class AuthorityResource String targetWorkspaceName = targetCtx.getRepositoryWorkspaceName(); ctx.setRespositoryWorkspaceName(targetWorkspaceName); //find the document in the parent's workspace - // Get the type of transition we're being asked to make and store it as a context parameter -used by the workflow document handler + // Get the type of transition we're being asked to make and store it as a context parameter -used by the workflow document handler TransitionDef transitionDef = getTransitionDef(targetCtx, transition); if (transitionDef == null) { - throw new DocumentException(String.format("The document with ID='%s' does not support the workflow transition '%s'.", - itemIdentifier, transition)); + throw new DocumentException(String.format("The document with ID='%s' does not support the workflow transition '%s'.", + itemIdentifier, transition)); } ctx.setProperty(WorkflowClient.TRANSITION_ID, transitionDef); @@ -955,20 +955,20 @@ public abstract class AuthorityResource getRepositoryClient(ctx).update(ctx, itemCsid, handler); result = ctx.getOutput(); } catch (DocumentReferenceException de) { - throw de; + throw de; } catch (Exception e) { throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, itemIdentifier); } - - return result; + + return result; } private PoxPayloadOut getAuthorityItem( - ServiceContext ctx, + ServiceContext ctx, String parentIdentifier, String itemIdentifier) throws Exception { - PoxPayloadOut result = null; - + PoxPayloadOut result = null; + String parentcsid = lookupParentCSID(ctx, parentIdentifier, "getAuthorityItem(parent)", "GET_ITEM", null); // We omit the parentShortId, only needed when doing a create... DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid, null); @@ -979,7 +979,7 @@ public abstract class AuthorityResource getRepositoryClient(ctx).get(ctx, itemSpec.value, handler); } else { String itemWhereClause = - RefNameServiceUtils.buildWhereForAuthItemByName(authorityItemCommonSchemaName, itemSpec.value, parentcsid); + RefNameServiceUtils.buildWhereForAuthItemByName(authorityItemCommonSchemaName, itemSpec.value, parentcsid); DocumentFilter myFilter = new NuxeoDocumentFilter(itemWhereClause, 0, 1); // start at page 0 and get 1 item handler.setDocumentFilter(myFilter); getRepositoryClient(ctx).get(ctx, handler); @@ -987,30 +987,30 @@ public abstract class AuthorityResource result = (PoxPayloadOut) ctx.getOutput(); if (result != null) { - String inAuthority = XmlTools.getElementValue(result.getDOMDocument(), "//" + AuthorityItemJAXBSchema.IN_AUTHORITY); - if (inAuthority.equalsIgnoreCase(parentcsid) == false) { - throw new Exception(String.format("Looked up item = '%s' and found with inAuthority = '%s', but expected inAuthority = '%s'.", - itemSpec.value, inAuthority, parentcsid)); - } + String inAuthority = XmlTools.getElementValue(result.getDOMDocument(), "//" + AuthorityItemJAXBSchema.IN_AUTHORITY); + if (inAuthority.equalsIgnoreCase(parentcsid) == false) { + throw new Exception(String.format("Looked up item = '%s' and found with inAuthority = '%s', but expected inAuthority = '%s'.", + itemSpec.value, inAuthority, parentcsid)); + } } - return result; + return result; } public PoxPayloadOut getAuthorityItemWithExistingContext( - ServiceContext existingCtx, + ServiceContext existingCtx, String parentIdentifier, String itemIdentifier) throws Exception { - PoxPayloadOut result = null; - + PoxPayloadOut result = null; + ServiceContext ctx = createServiceContext(getItemServiceName(), existingCtx.getResourceMap(), existingCtx.getUriInfo()); if (existingCtx.getCurrentRepositorySession() != null) { - ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession()); // Reuse the current repo session if one exists - ctx.setProperties(existingCtx.getProperties()); + ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession()); // Reuse the current repo session if one exists + ctx.setProperties(existingCtx.getProperties()); } result = getAuthorityItem(ctx, parentIdentifier, itemIdentifier); - - return result; + + return result; } /** @@ -1026,14 +1026,14 @@ public abstract class AuthorityResource public byte[] getAuthorityItem( @Context Request request, @Context UriInfo uriInfo, - @Context ResourceMap resourceMap, + @Context ResourceMap resourceMap, @PathParam("csid") String parentIdentifier, @PathParam("itemcsid") String itemIdentifier) { - uriInfo = new UriInfoWrapper(uriInfo); + uriInfo = new UriInfoWrapper(uriInfo); PoxPayloadOut result = null; try { RemoteServiceContext ctx = - (RemoteServiceContext) createServiceContext(getItemServiceName(), resourceMap, uriInfo); + (RemoteServiceContext) createServiceContext(getItemServiceName(), resourceMap, uriInfo); JaxRsContext jaxRsContext = new JaxRsContext(request, uriInfo); // Needed for getting account permissions part of the resource ctx.setJaxRsContext(jaxRsContext); @@ -1053,26 +1053,26 @@ public abstract class AuthorityResource * different enough that it will have to override this method in it's resource class. */ @Override - protected String getOrderByField(ServiceContext ctx) { - String result = null; + protected String getOrderByField(ServiceContext ctx) { + String result = null; - result = NuxeoUtils.getPrimaryElPathPropertyName( - authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + result = NuxeoUtils.getPrimaryElPathPropertyName( + authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), + AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); - return result; - } - + return result; + } + @Override - protected String getPartialTermMatchField(ServiceContext ctx) { - String result = null; - - result = NuxeoUtils.getMultiElPathPropertyName( - authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); - - return result; - } + protected String getPartialTermMatchField(ServiceContext ctx) { + String result = null; + + result = NuxeoUtils.getMultiElPathPropertyName( + authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), + AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + + return result; + } /** * Gets the authorityItem list for the specified authority @@ -1085,15 +1085,15 @@ public abstract class AuthorityResource * */ public AbstractCommonList getAuthorityItemList(ServiceContext existingContext, - String authorityIdentifier, + String authorityIdentifier, UriInfo uriInfo) throws Exception { - AbstractCommonList result = null; - + AbstractCommonList result = null; + ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); MultivaluedMap queryParams = ctx.getQueryParams(); if (existingContext != null && existingContext.getCurrentRepositorySession() != null) { // Merge some of the existing context properties with our new context - ctx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession()); - ctx.setProperties(existingContext.getProperties()); + ctx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession()); + ctx.setProperties(existingContext.getProperties()); } String orderBy = queryParams.getFirst(IClientQueryParams.ORDER_BY_PARAM); @@ -1105,9 +1105,9 @@ public abstract class AuthorityResource // For the wildcard case, parentcsid is null, but docHandler will deal with this. // We omit the parentShortId, only needed when doing a create... String parentcsid = PARENT_WILDCARD.equals(authorityIdentifier) ? null : - lookupParentCSID(ctx, authorityIdentifier, "getAuthorityItemList", "LIST", uriInfo); + lookupParentCSID(ctx, authorityIdentifier, "getAuthorityItemList", "LIST", uriInfo); DocumentHandler handler = - createItemDocumentHandler(ctx, parentcsid, null); + createItemDocumentHandler(ctx, parentcsid, null); DocumentFilter myFilter = handler.getDocumentFilter(); // If we are not wildcarding the parent, add a restriction @@ -1119,17 +1119,17 @@ public abstract class AuthorityResource } if (Tools.notBlank(termStatus)) { - // Start with the qualified termStatus field - String qualifiedTermStatusField = authorityItemCommonSchemaName + ":" + // Start with the qualified termStatus field + String qualifiedTermStatusField = authorityItemCommonSchemaName + ":" + AuthorityItemJAXBSchema.TERM_STATUS; - String[] filterTerms = termStatus.trim().split("\\|"); - String tsClause = QueryManager.createWhereClauseToFilterFromStringList(qualifiedTermStatusField, filterTerms, IQueryManager.FILTER_EXCLUDE); + String[] filterTerms = termStatus.trim().split("\\|"); + String tsClause = QueryManager.createWhereClauseToFilterFromStringList(qualifiedTermStatusField, filterTerms, IQueryManager.FILTER_EXCLUDE); myFilter.appendWhereClause(tsClause, IQueryManager.SEARCH_QUALIFIER_AND); } result = search(ctx, handler, uriInfo, orderBy, keywords, advancedSearch, partialTerm); - - return result; + + return result; } /** @@ -1148,9 +1148,9 @@ public abstract class AuthorityResource @Produces("application/xml") public AbstractCommonList getAuthorityItemList(@PathParam("csid") String authorityIdentifier, @Context UriInfo uriInfo) { - uriInfo = new UriInfoWrapper(uriInfo); - AbstractCommonList result = null; - + uriInfo = new UriInfoWrapper(uriInfo); + AbstractCommonList result = null; + try { result = getAuthorityItemList(NULL_CONTEXT, authorityIdentifier, uriInfo); } catch (Exception e) { @@ -1166,7 +1166,7 @@ public abstract class AuthorityResource * Some types (like Vocabulary) use a separate property. */ protected String getRefPropName() { - return ServiceBindingUtils.AUTH_REF_PROP; + return ServiceBindingUtils.AUTH_REF_PROP; } /** @@ -1189,7 +1189,7 @@ public abstract class AuthorityResource @PathParam("itemcsid") String itemSpecifier, @Context UriTemplateRegistry uriTemplateRegistry, @Context UriInfo uriInfo) { - uriInfo = new UriInfoWrapper(uriInfo); + uriInfo = new UriInfoWrapper(uriInfo); AuthorityRefDocList authRefDocList = null; try { authRefDocList = getReferencingObjects(null, parentSpecifier, itemSpecifier, uriTemplateRegistry, uriInfo); @@ -1207,13 +1207,12 @@ public abstract class AuthorityResource } public AuthorityRefDocList getReferencingObjects( - ServiceContext existingContext, + ServiceContext existingContext, String parentspecifier, String itemspecifier, UriTemplateRegistry uriTemplateRegistry, UriInfo uriInfo) throws Exception { - //uriInfo = new UriInfoWrapper(uriInfo); - AuthorityRefDocList authRefDocList = null; + AuthorityRefDocList authRefDocList = null; ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); MultivaluedMap queryParams = ctx.getQueryParams(); @@ -1221,8 +1220,8 @@ public abstract class AuthorityResource // Merge parts of existing context with our new context // if (existingContext != null && existingContext.getCurrentRepositorySession() != null) { - ctx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession()); // If one exists, use the existing repo session - ctx.setProperties(existingContext.getProperties()); + ctx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession()); // If one exists, use the existing repo session + ctx.setProperties(existingContext.getProperties()); } String parentcsid = lookupParentCSID(ctx, parentspecifier, "getReferencingObjects(parent)", "GET_ITEM_REF_OBJS", uriInfo); @@ -1231,7 +1230,7 @@ public abstract class AuthorityResource // Remove the "type" property from the query params 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 + serviceTypes = ServiceBindingUtils.getCommonServiceTypes(true); //CSPACE-5359: Should now include objects, procedures, and authorities } AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parentcsid, null); @@ -1256,7 +1255,7 @@ public abstract class AuthorityResource @PathParam("csid") String parentspecifier, @PathParam("itemcsid") String itemspecifier, @Context UriInfo uriInfo) { - uriInfo = new UriInfoWrapper(uriInfo); + uriInfo = new UriInfoWrapper(uriInfo); AuthorityRefList authRefList = null; try { @@ -1287,15 +1286,15 @@ public abstract class AuthorityResource * @throws Exception */ private PoxPayloadOut synchronizeItem( - ServiceContext ctx, + ServiceContext ctx, String parentIdentifier, String itemIdentifier, boolean syncHierarchicalRelationships) throws Exception { - PoxPayloadOut result = null; + PoxPayloadOut result = null; AuthorityItemSpecifier specifier; - boolean neededSync = false; + boolean neededSync = false; - CsidAndShortIdentifier parent = lookupParentCSIDAndShortIdentifer(ctx, parentIdentifier, "syncAuthorityItem(parent)", "SYNC_ITEM", null); + CsidAndShortIdentifier parent = lookupParentCSIDAndShortIdentifer(ctx, parentIdentifier, "syncAuthorityItem(parent)", "SYNC_ITEM", null); AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parent.CSID, parent.shortIdentifier); handler.setIsProposed(AuthorityServiceUtils.NOT_PROPOSED); // In case it was formally locally proposed, clear the proposed flag handler.setIsSASItem(AuthorityServiceUtils.SAS_ITEM); // Since we're sync'ing, this is now a SAS controlled item @@ -1307,10 +1306,10 @@ public abstract class AuthorityResource // neededSync = getRepositoryClient(ctx).synchronize(ctx, specifier, handler); if (neededSync == true) { - result = (PoxPayloadOut) ctx.getOutput(); + result = (PoxPayloadOut) ctx.getOutput(); } - - return result; + + return result; } /** @@ -1324,23 +1323,23 @@ public abstract class AuthorityResource * @throws Exception */ public PoxPayloadOut synchronizeItemWithExistingContext( - ServiceContext existingCtx, + ServiceContext existingCtx, String parentIdentifier, String itemIdentifier, boolean syncHierarchicalRelationships ) throws Exception { - PoxPayloadOut result = null; - + PoxPayloadOut result = null; + ServiceContext ctx = createServiceContext(getItemServiceName(), - existingCtx.getResourceMap(), - existingCtx.getUriInfo()); + existingCtx.getResourceMap(), + existingCtx.getUriInfo()); if (existingCtx.getCurrentRepositorySession() != null) { - ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession()); - + ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession()); + } result = synchronizeItem(ctx, parentIdentifier, itemIdentifier, syncHierarchicalRelationships); - - return result; + + return result; } /** @@ -1353,20 +1352,20 @@ public abstract class AuthorityResource @POST @Path("{csid}/items/{itemcsid}/sync") public byte[] synchronizeItem( - @Context ResourceMap resourceMap, + @Context ResourceMap resourceMap, @Context UriInfo uriInfo, @PathParam("csid") String parentIdentifier, @PathParam("itemcsid") String itemIdentifier) { - uriInfo = new UriInfoWrapper(uriInfo); - byte[] result; - boolean neededSync = false; + uriInfo = new UriInfoWrapper(uriInfo); + byte[] result; + boolean neededSync = false; PoxPayloadOut payloadOut = null; try { ServiceContext ctx = createServiceContext(getItemServiceName(), null, resourceMap, uriInfo); payloadOut = this.synchronizeItem(ctx, parentIdentifier, itemIdentifier, true); if (payloadOut != null) { - neededSync = true; + neededSync = true; } } catch (Exception e) { throw bigReThrow(e, ServiceMessages.SYNC_FAILED, itemIdentifier); @@ -1376,11 +1375,11 @@ public abstract class AuthorityResource // If a sync was needed and was successful, return a copy of the updated resource. Acts like an UPDATE. // if (neededSync == true) { - result = payloadOut.getBytes(); + result = payloadOut.getBytes(); } else { - result = String.format("Authority item resource '%s' was already in sync with shared authority server.", - itemIdentifier).getBytes(); - Response response = Response.status(Response.Status.NOT_MODIFIED).entity(result).type("text/plain").build(); + result = String.format("Authority item resource '%s' was already in sync with shared authority server.", + itemIdentifier).getBytes(); + Response response = Response.status(Response.Status.NOT_MODIFIED).entity(result).type("text/plain").build(); throw new CSWebApplicationException(response); } @@ -1398,20 +1397,20 @@ public abstract class AuthorityResource @PUT @Path("{csid}/items/{itemcsid}") public byte[] updateAuthorityItem( - @Context ResourceMap resourceMap, + @Context ResourceMap resourceMap, @Context UriInfo uriInfo, @PathParam("csid") String parentSpecifier, @PathParam("itemcsid") String itemSpecifier, String xmlPayload) { - uriInfo = new UriInfoWrapper(uriInfo); + uriInfo = new UriInfoWrapper(uriInfo); PoxPayloadOut result = null; try { PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload); result = updateAuthorityItem(null, resourceMap, uriInfo, parentSpecifier, itemSpecifier, theUpdate, - AuthorityServiceUtils.UPDATE_REV, // passing TRUE so rev num increases, passing - AuthorityServiceUtils.NO_CHANGE, // don't change the state of the "proposed" field -we could be performing a sync or just a plain update - AuthorityServiceUtils.NO_CHANGE); // don't change the state of the "sas" field -we could be performing a sync or just a plain update + AuthorityServiceUtils.UPDATE_REV, // passing TRUE so rev num increases, passing + AuthorityServiceUtils.NO_CHANGE, // don't change the state of the "proposed" field -we could be performing a sync or just a plain update + AuthorityServiceUtils.NO_CHANGE); // don't change the state of the "sas" field -we could be performing a sync or just a plain update } catch (Exception e) { throw bigReThrow(e, ServiceMessages.UPDATE_FAILED); } @@ -1435,8 +1434,8 @@ public abstract class AuthorityResource @Context UriInfo uriInfo, @PathParam("csid") String parentIdentifier, @PathParam("itemcsid") String itemIdentifier) { - uriInfo = new UriInfoWrapper(uriInfo); - Response result = null; + uriInfo = new UriInfoWrapper(uriInfo); + Response result = null; ensureCSID(parentIdentifier, ServiceMessages.DELETE_FAILED, "AuthorityItem.parentcsid"); ensureCSID(itemIdentifier, ServiceMessages.DELETE_FAILED, "AuthorityItem.itemcsid"); @@ -1462,27 +1461,27 @@ public abstract class AuthorityResource * @param itemIdentifier * @throws Exception */ - public boolean deleteAuthorityItem(ServiceContext existingCtx, + public boolean deleteAuthorityItem(ServiceContext existingCtx, String parentIdentifier, String itemIdentifier, boolean shouldUpdateRevNumber ) throws Exception { - boolean result = true; - + boolean result = true; + ServiceContext ctx = createServiceContext(getItemServiceName(), existingCtx.getUriInfo()); if (existingCtx != null && existingCtx.getCurrentRepositorySession() != null) { - ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession()); - ctx.setProperties(existingCtx.getProperties()); + ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession()); + ctx.setProperties(existingCtx.getProperties()); } String parentcsid = null; try { - parentcsid = lookupParentCSID(ctx, parentIdentifier, "deleteAuthorityItem(parent)", "DELETE_ITEM", null); + parentcsid = lookupParentCSID(ctx, parentIdentifier, "deleteAuthorityItem(parent)", "DELETE_ITEM", null); } catch (DocumentNotFoundException de) { - String msg = String.format("Could not find parent with ID='%s' when trying to delete item ID='%s'", - parentIdentifier, itemIdentifier); - logger.warn(msg); - throw de; + String msg = String.format("Could not find parent with ID='%s' when trying to delete item ID='%s'", + parentIdentifier, itemIdentifier); + logger.warn(msg); + throw de; } String itemCsid = lookupItemCSID(ctx, itemIdentifier, parentcsid, "deleteAuthorityItem(item)", "DELETE_ITEM"); //use itemServiceCtx if it is not null @@ -1497,16 +1496,16 @@ public abstract class AuthorityResource @Path("{csid}/items/{itemcsid}/" + hierarchy) @Produces("application/xml") public String getHierarchy( - @PathParam("csid") String parentIdentifier, + @PathParam("csid") String parentIdentifier, @PathParam("itemcsid") String itemIdentifier, @Context UriInfo uriInfo) throws Exception { - uriInfo = new UriInfoWrapper(uriInfo); - String result = null; + uriInfo = new UriInfoWrapper(uriInfo); + String result = null; try { - // + // // All items in dive can look at their child uri's to get uri. So we calculate the very first one. We could also do a GET and look at the common part uri field, but why...? - // + // String calledUri = uriInfo.getPath(); String uri = "/" + calledUri.substring(0, (calledUri.length() - ("/" + hierarchy).length())); ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); @@ -1557,14 +1556,14 @@ public abstract class AuthorityResource * */ @Override - public ServiceDescription getDescription(ServiceContext ctx) { - ServiceDescription result = super.getDescription(ctx); - result.setSubresourceDocumentType(this.getItemDocType(ctx.getTenantId())); - return result; + public ServiceDescription getDescription(ServiceContext ctx) { + ServiceDescription result = super.getDescription(ctx); + result.setSubresourceDocumentType(this.getItemDocType(ctx.getTenantId())); + return result; } - public Response createAuthority(String xmlPayload) { - return this.createAuthority(null, null, xmlPayload); - } + public Response createAuthority(String xmlPayload) { + return this.createAuthority(null, null, xmlPayload); + } } 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 dbd562817..b632c0b06 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 @@ -120,72 +120,72 @@ public abstract class AuthorityItemDocumentModelHandler // Getter and Setter for 'shouldUpdateSASFields' // public boolean getShouldUpdateSASFields() { - return shouldUpdateSASFields; + return shouldUpdateSASFields; } public void setshouldUpdateSASFields(boolean flag) { - shouldUpdateSASFields = flag; + shouldUpdateSASFields = flag; } // // Getter and Setter for 'proposed' // public boolean getIsProposed() { - return this.isProposed; + return this.isProposed; } public void setIsProposed(boolean flag) { - this.isProposed = flag; + this.isProposed = flag; } // // Getter and Setter for 'isSAS' // public boolean getIsSASItem() { - return this.isSAS; + return this.isSAS; } public void setIsSASItem(boolean flag) { - this.isSAS = flag; + this.isSAS = flag; } // // Getter and Setter for 'shouldUpdateRevNumber' // public boolean getShouldUpdateRevNumber() { - return this.shouldUpdateRevNumber; + return this.shouldUpdateRevNumber; } public void setShouldUpdateRevNumber(boolean flag) { - this.shouldUpdateRevNumber = flag; + this.shouldUpdateRevNumber = flag; } // // Getter and Setter for deciding if we need to synch hierarchical relationships // public boolean getShouldSyncHierarchicalRelationships() { - return this.syncHierarchicalRelationships; + return this.syncHierarchicalRelationships; } public void setShouldSyncHierarchicalRelationships(boolean flag) { - this.syncHierarchicalRelationships = flag; + this.syncHierarchicalRelationships = flag; } @Override public void prepareSync() throws Exception { - this.setShouldUpdateRevNumber(AuthorityServiceUtils.DONT_UPDATE_REV); // Never update rev nums on sync operations + this.setShouldUpdateRevNumber(AuthorityServiceUtils.DONT_UPDATE_REV); // Never update rev nums on sync operations } @Override protected String getRefnameDisplayName(DocumentWrapper docWrapper) { - String result = null; - - DocumentModel docModel = docWrapper.getWrappedObject(); - ServiceContext ctx = this.getServiceContext(); - RefName.AuthorityItem refname = (RefName.AuthorityItem)getRefName(ctx, docModel); - result = refname.getDisplayName(); - - return result; + String result = null; + + DocumentModel docModel = docWrapper.getWrappedObject(); + ServiceContext ctx = this.getServiceContext(); + RefName.AuthorityItem refname = (RefName.AuthorityItem)getRefName(ctx, docModel); + result = refname.getDisplayName(); + + return result; } /* @@ -195,37 +195,37 @@ public abstract class AuthorityItemDocumentModelHandler */ @Override public RefName.RefNameInterface getRefName(ServiceContext ctx, - DocumentModel docModel) { - RefName.RefNameInterface refname = null; - - try { - String displayName = getPrimaryDisplayName(docModel, authorityItemCommonSchemaName, + DocumentModel docModel) { + RefName.RefNameInterface refname = null; + + try { + String displayName = getPrimaryDisplayName(docModel, authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); - if (Tools.isEmpty(displayName)) { - throw new Exception("The displayName for this authority term was empty or not set."); - } + if (Tools.isEmpty(displayName)) { + throw new Exception("The displayName for this authority term was empty or not set."); + } - String shortIdentifier = (String) docModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER); - if (Tools.isEmpty(shortIdentifier)) { - // We didn't find a short ID in the payload request, so we need to synthesize one. - shortIdentifier = handleDisplayNameAsShortIdentifier(docModel); // updates the document model with the new short ID as a side-effect - } - - String authorityRefBaseName = getAuthorityRefNameBase(); - if (Tools.isEmpty(authorityRefBaseName)) { - throw new Exception("Could not create the refName for this authority term, because the refName for its authority parent was empty."); - } - - // Create the items refname using the parent's as a base - RefName.Authority parentsRefName = RefName.Authority.parse(authorityRefBaseName); - refname = RefName.buildAuthorityItem(parentsRefName, shortIdentifier, displayName); - // Now update the document model with the refname value - String refNameStr = refname.toString(); - docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REF_NAME, refNameStr); // REM - This field is deprecated now that the refName is part of the collection_space core schema + String shortIdentifier = (String) docModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER); + if (Tools.isEmpty(shortIdentifier)) { + // We didn't find a short ID in the payload request, so we need to synthesize one. + shortIdentifier = handleDisplayNameAsShortIdentifier(docModel); // updates the document model with the new short ID as a side-effect + } + + String authorityRefBaseName = getAuthorityRefNameBase(); + if (Tools.isEmpty(authorityRefBaseName)) { + throw new Exception("Could not create the refName for this authority term, because the refName for its authority parent was empty."); + } + + // Create the items refname using the parent's as a base + RefName.Authority parentsRefName = RefName.Authority.parse(authorityRefBaseName); + refname = RefName.buildAuthorityItem(parentsRefName, shortIdentifier, displayName); + // Now update the document model with the refname value + String refNameStr = refname.toString(); + docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REF_NAME, refNameStr); // REM - This field is deprecated now that the refName is part of the collection_space core schema - } catch (Exception e) { - logger.error(e.getMessage(), e); - } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } return refname; } @@ -247,18 +247,18 @@ public abstract class AuthorityItemDocumentModelHandler public String getUri(DocumentModel docModel) { // Laramie20110510 CSPACE-3932 String authorityServicePath = getAuthorityServicePath(); - if(inAuthority==null) { // Only true with the first document model received, on queries to wildcarded authorities + if(inAuthority==null) { // Only true with the first document model received, on queries to wildcarded authorities wildcardedAuthorityRequest = true; } // If this search crosses multiple authorities, get the inAuthority value // from each record, rather than using the cached value from the first record if(wildcardedAuthorityRequest) { - try { - inAuthority = (String) docModel.getProperty(authorityItemCommonSchemaName, - AuthorityItemJAXBSchema.IN_AUTHORITY); - } catch (ClientException pe) { - throw new RuntimeException("Could not get parent specifier for item!"); - } + try { + inAuthority = (String) docModel.getProperty(authorityItemCommonSchemaName, + AuthorityItemJAXBSchema.IN_AUTHORITY); + } catch (ClientException pe) { + throw new RuntimeException("Could not get parent specifier for item!"); + } } return "/" + authorityServicePath + '/' + inAuthority + '/' + AuthorityClient.ITEMS + '/' + getCsid(docModel); } @@ -275,8 +275,8 @@ public abstract class AuthorityItemDocumentModelHandler * Note: the Vocabulary service's VocabularyItemDocumentModelHandler class overrides this method. */ protected ListResultField getListResultsDisplayNameField() { - ListResultField result = new ListResultField(); - // Per CSPACE-5132, the name of this element remains 'displayName' + ListResultField result = new ListResultField(); + // Per CSPACE-5132, the name of this element remains 'displayName' // for backwards compatibility, although its value is obtained // from the termDisplayName field. // @@ -292,28 +292,28 @@ public abstract class AuthorityItemDocumentModelHandler // In CSPACE-5134, these list results will change substantially // to return display names for both the preferred term and for // each non-preferred term (if any). - result.setElement(AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); - result.setXpath(NuxeoUtils.getPrimaryXPathPropertyName( + result.setElement(AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + result.setXpath(NuxeoUtils.getPrimaryXPathPropertyName( authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_DISPLAY_NAME)); - - return result; + + return result; } /* * Note: the Vocabulary service's VocabularyItemDocumentModelHandler class overrides this method. */ protected ListResultField getListResultsTermStatusField() { - ListResultField result = new ListResultField(); + ListResultField result = new ListResultField(); - result.setElement(AuthorityItemJAXBSchema.TERM_STATUS); - result.setXpath(NuxeoUtils.getPrimaryXPathPropertyName( + result.setElement(AuthorityItemJAXBSchema.TERM_STATUS); + result.setXpath(NuxeoUtils.getPrimaryXPathPropertyName( authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_STATUS)); return result; } private boolean isTermDisplayName(String elName) { - return AuthorityItemJAXBSchema.TERM_DISPLAY_NAME.equals(elName) || VocabularyItemJAXBSchema.DISPLAY_NAME.equals(elName); + return AuthorityItemJAXBSchema.TERM_DISPLAY_NAME.equals(elName) || VocabularyItemJAXBSchema.DISPLAY_NAME.equals(elName); } /* @@ -329,28 +329,28 @@ public abstract class AuthorityItemDocumentModelHandler // One-time initialization for each authority item service. if (isListItemArrayExtended() == false) { - synchronized(AuthorityItemDocumentModelHandler.class) { - if (isListItemArrayExtended() == false) { - int nFields = list.size(); - // Ensure that each item in a list of Authority items includes - // a set of common fields, so we do not depend upon configuration - // for general logic. - List termDisplayNamePositionsInList = new ArrayList<>(); - boolean hasShortId = false; - boolean hasTermStatus = false; - for (int i = 0; i < nFields; i++) { - ListResultField field = list.get(i); - String elName = field.getElement(); - if (isTermDisplayName(elName) == true) { - termDisplayNamePositionsInList.add(i); - } else if (AuthorityItemJAXBSchema.SHORT_IDENTIFIER.equals(elName)) { - hasShortId = true; - } else if (AuthorityItemJAXBSchema.TERM_STATUS.equals(elName)) { - hasTermStatus = true; - } - } - - ListResultField field; + synchronized(AuthorityItemDocumentModelHandler.class) { + if (isListItemArrayExtended() == false) { + int nFields = list.size(); + // Ensure that each item in a list of Authority items includes + // a set of common fields, so we do not depend upon configuration + // for general logic. + List termDisplayNamePositionsInList = new ArrayList<>(); + boolean hasShortId = false; + boolean hasTermStatus = false; + for (int i = 0; i < nFields; i++) { + ListResultField field = list.get(i); + String elName = field.getElement(); + if (isTermDisplayName(elName) == true) { + termDisplayNamePositionsInList.add(i); + } else if (AuthorityItemJAXBSchema.SHORT_IDENTIFIER.equals(elName)) { + hasShortId = true; + } else if (AuthorityItemJAXBSchema.TERM_STATUS.equals(elName)) { + hasTermStatus = true; + } + } + + ListResultField field; // Certain fields in authority item list results // are handled specially here @@ -376,27 +376,27 @@ public abstract class AuthorityItemDocumentModelHandler // terms (if any). The following is a placeholder // entry that will trigger this code. See the // getListResultValue() method in this class. - field = getListResultsDisplayNameField(); - list.add(field); + field = getListResultsDisplayNameField(); + list.add(field); // Short identifier - if (!hasShortId) { - field = new ListResultField(); - field.setElement(AuthorityItemJAXBSchema.SHORT_IDENTIFIER); - field.setXpath(AuthorityItemJAXBSchema.SHORT_IDENTIFIER); - list.add(field); - } + if (!hasShortId) { + field = new ListResultField(); + field.setElement(AuthorityItemJAXBSchema.SHORT_IDENTIFIER); + field.setXpath(AuthorityItemJAXBSchema.SHORT_IDENTIFIER); + list.add(field); + } // Term status - if (!hasTermStatus) { - field = getListResultsTermStatusField(); - list.add(field); - } + if (!hasTermStatus) { + field = getListResultsTermStatusField(); + list.add(field); + } - } + } - setListItemArrayExtended(true); - } // end of synchronized block + setListItemArrayExtended(true); + } // end of synchronized block } return list; @@ -408,28 +408,28 @@ public abstract class AuthorityItemDocumentModelHandler */ @Override 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 (transitionDef.getName().equalsIgnoreCase(WorkflowClient.WORKFLOWTRANSITION_DELETE)) { - long refsToAllObjects = hasReferencingObjects(ctx, docModel, false); - long refsToSoftDeletedObjects = hasReferencingObjects(ctx, docModel, true); - if (refsToAllObjects > 0) { - if (refsToAllObjects > refsToSoftDeletedObjects) { - // - // If the number of refs to active objects is greater than the number of refs to - // soft deleted objects then we can't delete the item. - // - 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())); - } - } - } + // 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 (transitionDef.getName().equalsIgnoreCase(WorkflowClient.WORKFLOWTRANSITION_DELETE)) { + long refsToAllObjects = hasReferencingObjects(ctx, docModel, false); + long refsToSoftDeletedObjects = hasReferencingObjects(ctx, docModel, true); + if (refsToAllObjects > 0) { + if (refsToAllObjects > refsToSoftDeletedObjects) { + // + // If the number of refs to active objects is greater than the number of refs to + // soft deleted objects then we can't delete the item. + // + 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())); + } + } + } } /** @@ -439,18 +439,18 @@ public abstract class AuthorityItemDocumentModelHandler * @throws Exception */ protected boolean handleRelationsSync(DocumentWrapper wrapDoc) throws Exception { - boolean result = false; - ServiceContext ctx = getServiceContext(); + boolean result = false; + ServiceContext ctx = getServiceContext(); // // Get information about the local authority item so we can compare with corresponding item on the shared authority server // - AuthorityItemSpecifier authorityItemSpecifier = (AuthorityItemSpecifier) wrapDoc.getWrappedObject(); + AuthorityItemSpecifier authorityItemSpecifier = (AuthorityItemSpecifier) wrapDoc.getWrappedObject(); DocumentModel itemDocModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), getAuthorityItemCommonSchemaName(), - authorityItemSpecifier); + authorityItemSpecifier); if (itemDocModel == null) { - throw new DocumentNotFoundException(String.format("Could not find authority item resource with CSID='%s'", - authorityItemSpecifier.getItemSpecifier().value)); + throw new DocumentNotFoundException(String.format("Could not find authority item resource with CSID='%s'", + authorityItemSpecifier.getItemSpecifier().value)); } Long localItemRev = (Long) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.REV); Boolean localIsProposed = (Boolean) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.PROPOSED); @@ -462,7 +462,7 @@ public abstract class AuthorityItemDocumentModelHandler // Now get the item's Authority (the parent) information // DocumentModel authorityDocModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), authorityCommonSchemaName, - authorityItemSpecifier.getParentSpecifier()); + authorityItemSpecifier.getParentSpecifier()); String authorityShortId = (String)NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.SHORT_IDENTIFIER); String localParentCsid = authorityDocModel.getName(); String remoteClientConfigName = (String)NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.REMOTECLIENT_CONFIG_NAME); @@ -472,7 +472,7 @@ public abstract class AuthorityItemDocumentModelHandler AuthorityItemSpecifier sasAuthorityItemSpecifier = new AuthorityItemSpecifier(SpecifierForm.URN_NAME, authorityShortId, itemShortId); // Get the shared authority server's copy PoxPayloadIn sasPayloadIn = AuthorityServiceUtils.requestPayloadInFromRemoteServer(sasAuthorityItemSpecifier, - remoteClientConfigName, getAuthorityServicePath(), getEntityResponseType(), AuthorityClient.INCLUDE_RELATIONS); + remoteClientConfigName, getAuthorityServicePath(), getEntityResponseType(), AuthorityClient.INCLUDE_RELATIONS); // // Get the RelationsCommonList and remove the CSIDs since they are for remote items only. We'll use @@ -482,16 +482,16 @@ public abstract class AuthorityItemDocumentModelHandler relationsCommonListPart.clearElementBody(); // clear the existing DOM element that was created from the incoming XML payload RelationsCommonList rcl = (RelationsCommonList) relationsCommonListPart.getBody(); // Get the JAX-B object and clear the CSID values for (RelationsCommonList.RelationListItem listItem : rcl.getRelationListItem()) { - // clear the remote relation item's CSID - listItem.setCsid(null); - // clear the remote subject's CSID - listItem.setSubjectCsid(null); - listItem.getSubject().setCsid(null); - listItem.getSubject().setUri(null); - // clear the remote object's CSID - listItem.setObjectCsid(null); - listItem.getObject().setCsid(null); - listItem.getObject().setUri(null); + // clear the remote relation item's CSID + listItem.setCsid(null); + // clear the remote subject's CSID + listItem.setSubjectCsid(null); + listItem.getSubject().setCsid(null); + listItem.getSubject().setUri(null); + // clear the remote object's CSID + listItem.setObjectCsid(null); + listItem.getObject().setCsid(null); + listItem.getObject().setUri(null); } // @@ -502,36 +502,36 @@ public abstract class AuthorityItemDocumentModelHandler sasPayloadIn.setParts(newPartList); sasPayloadIn = new PoxPayloadIn(sasPayloadIn.toXML()); // Builds a new payload using the current set of parts -i.e., just the relations part - sasPayloadIn = AuthorityServiceUtils.filterRefnameDomains(ctx, sasPayloadIn); // We need to filter the domain name part of any and all refnames in the payload - AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); - PoxPayloadOut payloadOut = authorityResource.updateAuthorityItem(ctx, - ctx.getResourceMap(), - ctx.getUriInfo(), - localParentCsid, // parent's CSID - localItemCsid, // item's CSID - sasPayloadIn, // the payload from the remote SAS - AuthorityServiceUtils.DONT_UPDATE_REV, // don't update the parent's revision number - AuthorityServiceUtils.NOT_PROPOSED, // The items is not proposed, make it a real SAS item now - AuthorityServiceUtils.SAS_ITEM); // Since we're sync'ing, this must be a SAS item - if (payloadOut != null) { - ctx.setOutput(payloadOut); - result = true; - } - - return result; + sasPayloadIn = AuthorityServiceUtils.filterRefnameDomains(ctx, sasPayloadIn); // We need to filter the domain name part of any and all refnames in the payload + AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); + PoxPayloadOut payloadOut = authorityResource.updateAuthorityItem(ctx, + ctx.getResourceMap(), + ctx.getUriInfo(), + localParentCsid, // parent's CSID + localItemCsid, // item's CSID + sasPayloadIn, // the payload from the remote SAS + AuthorityServiceUtils.DONT_UPDATE_REV, // don't update the parent's revision number + AuthorityServiceUtils.NOT_PROPOSED, // The items is not proposed, make it a real SAS item now + AuthorityServiceUtils.SAS_ITEM); // Since we're sync'ing, this must be a SAS item + if (payloadOut != null) { + ctx.setOutput(payloadOut); + result = true; + } + + return result; } @Override public boolean handleSync(DocumentWrapper wrapDoc) throws Exception { - boolean result = false; + boolean result = false; - if (this.getShouldSyncHierarchicalRelationships() == true) { - result = handleRelationsSync(wrapDoc); - } else { - result = handlePayloadSync(wrapDoc); - } - - return result; + if (this.getShouldSyncHierarchicalRelationships() == true) { + result = handleRelationsSync(wrapDoc); + } else { + result = handlePayloadSync(wrapDoc); + } + + return result; } /** @@ -541,18 +541,18 @@ public abstract class AuthorityItemDocumentModelHandler * @throws Exception */ protected boolean handlePayloadSync(DocumentWrapper wrapDoc) throws Exception { - boolean result = false; - ServiceContext ctx = getServiceContext(); - + boolean result = false; + ServiceContext ctx = getServiceContext(); + // // Get information about the local authority item so we can compare with corresponding item on the shared authority server // - AuthorityItemSpecifier authorityItemSpecifier = (AuthorityItemSpecifier) wrapDoc.getWrappedObject(); + AuthorityItemSpecifier authorityItemSpecifier = (AuthorityItemSpecifier) wrapDoc.getWrappedObject(); DocumentModel itemDocModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), getAuthorityItemCommonSchemaName(), - authorityItemSpecifier); + authorityItemSpecifier); if (itemDocModel == null) { - throw new DocumentNotFoundException(String.format("Could not find authority item resource with CSID='%s'", - authorityItemSpecifier.getItemSpecifier().value)); + throw new DocumentNotFoundException(String.format("Could not find authority item resource with CSID='%s'", + authorityItemSpecifier.getItemSpecifier().value)); } Long localItemRev = (Long) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.REV); Boolean localIsProposed = (Boolean) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.PROPOSED); @@ -564,7 +564,7 @@ public abstract class AuthorityItemDocumentModelHandler // Now get the item's Authority (the parent) information // DocumentModel authorityDocModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), authorityCommonSchemaName, - authorityItemSpecifier.getParentSpecifier()); + authorityItemSpecifier.getParentSpecifier()); String authorityShortId = (String) NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.SHORT_IDENTIFIER); String localParentCsid = authorityDocModel.getName(); String remoteClientConfigName = (String)NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.REMOTECLIENT_CONFIG_NAME); @@ -575,51 +575,51 @@ public abstract class AuthorityItemDocumentModelHandler AuthorityItemSpecifier sasAuthorityItemSpecifier = new AuthorityItemSpecifier(SpecifierForm.URN_NAME, authorityShortId, itemShortId); // Get the shared authority server's copy PoxPayloadIn sasPayloadIn = AuthorityServiceUtils.requestPayloadInFromRemoteServer(sasAuthorityItemSpecifier, - remoteClientConfigName, getAuthorityServicePath(), getEntityResponseType(), AuthorityClient.DONT_INCLUDE_RELATIONS); + remoteClientConfigName, getAuthorityServicePath(), getEntityResponseType(), AuthorityClient.DONT_INCLUDE_RELATIONS); Long sasRev = getRevision(sasPayloadIn); String sasWorkflowState = getWorkflowState(sasPayloadIn); // // If the shared authority item is newer, update our local copy // if (sasRev > localItemRev || localIsProposed || ctx.shouldForceSync()) { - sasPayloadIn = AuthorityServiceUtils.filterRefnameDomains(ctx, sasPayloadIn); // We need to filter the domain name part of any and all refnames in the payload - AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); - PoxPayloadOut payloadOut = authorityResource.updateAuthorityItem(ctx, - ctx.getResourceMap(), - ctx.getUriInfo(), - localParentCsid, // parent's CSID - localItemCsid, // item's CSID - sasPayloadIn, // the payload from the remote SAS - AuthorityServiceUtils.DONT_UPDATE_REV, // don't update the parent's revision number - AuthorityServiceUtils.NOT_PROPOSED, // The items is not proposed, make it a real SAS item now - AuthorityServiceUtils.SAS_ITEM); // Since we're sync'ing, this must be a SAS item - if (payloadOut != null) { - ctx.setOutput(payloadOut); - result = true; - } + sasPayloadIn = AuthorityServiceUtils.filterRefnameDomains(ctx, sasPayloadIn); // We need to filter the domain name part of any and all refnames in the payload + AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); + PoxPayloadOut payloadOut = authorityResource.updateAuthorityItem(ctx, + ctx.getResourceMap(), + ctx.getUriInfo(), + localParentCsid, // parent's CSID + localItemCsid, // item's CSID + sasPayloadIn, // the payload from the remote SAS + AuthorityServiceUtils.DONT_UPDATE_REV, // don't update the parent's revision number + AuthorityServiceUtils.NOT_PROPOSED, // The items is not proposed, make it a real SAS item now + AuthorityServiceUtils.SAS_ITEM); // Since we're sync'ing, this must be a SAS item + if (payloadOut != null) { + ctx.setOutput(payloadOut); + result = true; + } } // // Check to see if we need to update the local items's workflow state to reflect that of the remote's // - List transitionList = getTransitionList(sasWorkflowState, localItemWorkflowState); + 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. - // - 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)); - } - } - result = true; + 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)); + } + } + result = true; } return result; @@ -630,67 +630,67 @@ public abstract class AuthorityItemDocumentModelHandler * state. This might involve making multiple transitions. * * WIKI: - * See table at https://wiki.collectionspace.org/pages/viewpage.action?pageId=162496564 + * See table at https://wiki.collectionspace.org/pages/viewpage.action?pageId=162496564 * */ private List getTransitionList(String sasWorkflowState, String localItemWorkflowState) throws DocumentException { - List result = new ArrayList(); - // - // 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); - // - // 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 - // - // 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); - // - // 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 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; + List result = new ArrayList(); + // + // 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); + // + // 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 + // + // 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); + // + // 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 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; } /* (non-Javadoc) @@ -712,42 +712,42 @@ public abstract class AuthorityItemDocumentModelHandler */ @Override public boolean handleDelete(DocumentWrapper wrapDoc) throws Exception { - boolean result = true; - - ServiceContext ctx = getServiceContext(); - DocumentModel docModel = wrapDoc.getWrappedObject(); - - long refsToAllObjects = hasReferencingObjects(ctx, docModel, false); - long refsToSoftDeletedObjects = hasReferencingObjects(ctx, docModel, true); - if (refsToAllObjects > 0) { - if (refsToAllObjects > refsToSoftDeletedObjects) { - // - // If the number of refs to active objects is greater than the number of refs to - // soft deleted objects then we can't delete the item. - // - 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())); - } else { - // - // If all the refs are to soft-deleted objects, we should soft-delete this authority item instead of hard-deleting it and instead of failing. - // - String parentCsid = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.IN_AUTHORITY); - String itemCsid = docModel.getName(); - AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); - authorityResource.updateItemWorkflowWithTransition(ctx, parentCsid, itemCsid, WorkflowClient.WORKFLOWTRANSITION_DELETE, - this.getShouldUpdateRevNumber()); - result = false; // Don't delete since we just soft-deleted it. - } - } - - // - // Since we've changed the state of the parent by deleting (or soft-deleting) one of its items, we might need to update the parent rev number - // - if (getShouldUpdateRevNumber() == true) { - updateRevNumbers(wrapDoc); - } - - return result; + boolean result = true; + + ServiceContext ctx = getServiceContext(); + DocumentModel docModel = wrapDoc.getWrappedObject(); + + long refsToAllObjects = hasReferencingObjects(ctx, docModel, false); + long refsToSoftDeletedObjects = hasReferencingObjects(ctx, docModel, true); + if (refsToAllObjects > 0) { + if (refsToAllObjects > refsToSoftDeletedObjects) { + // + // If the number of refs to active objects is greater than the number of refs to + // soft deleted objects then we can't delete the item. + // + 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())); + } else { + // + // If all the refs are to soft-deleted objects, we should soft-delete this authority item instead of hard-deleting it and instead of failing. + // + String parentCsid = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.IN_AUTHORITY); + String itemCsid = docModel.getName(); + AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); + authorityResource.updateItemWorkflowWithTransition(ctx, parentCsid, itemCsid, WorkflowClient.WORKFLOWTRANSITION_DELETE, + this.getShouldUpdateRevNumber()); + result = false; // Don't delete since we just soft-deleted it. + } + } + + // + // Since we've changed the state of the parent by deleting (or soft-deleting) one of its items, we might need to update the parent rev number + // + if (getShouldUpdateRevNumber() == true) { + updateRevNumbers(wrapDoc); + } + + return result; } /** @@ -759,41 +759,57 @@ public abstract class AuthorityItemDocumentModelHandler * @throws Exception */ private long hasReferencingObjects(ServiceContext ctx, DocumentModel docModel, boolean onlyRefsToDeletedObjects) throws Exception { - long result = 0; - - String inAuthorityCsid = (String) docModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.IN_AUTHORITY); - AuthorityResource authorityResource = (AuthorityResource)ctx.getResource(getAuthorityServicePath()); - String itemCsid = docModel.getName(); + long result = 0; + + String inAuthorityCsid = (String) docModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.IN_AUTHORITY); + AuthorityResource authorityResource = (AuthorityResource)ctx.getResource(getAuthorityServicePath()); + String itemCsid = docModel.getName(); UriTemplateRegistry uriTemplateRegistry = ServiceMain.getInstance().getUriTemplateRegistry(); if (ctx.getUriInfo() == null) { - // - // We need a UriInfo object so we can pass "query" params to the AuthorityResource's getReferencingObjects() method - // - ctx.setUriInfo(this.getServiceContext().getUriInfo()); // try to get a UriInfo instance from the handler's context + // + // We need a UriInfo object so we can pass "query" params to the AuthorityResource's getReferencingObjects() method + // + ctx.setUriInfo(this.getServiceContext().getUriInfo()); // try to get a UriInfo instance from the handler's context } + + // + // Since the call to get referencing objects might indirectly use the WorkflowClient.WORKFLOW_QUERY_NONDELETED query param, we need to + // temporarily remove that query param if it is set. If set, we'll save the value and reset once we're finished. + // + boolean doesContainValue = ctx.getUriInfo().getQueryParameters().containsKey(WorkflowClient.WORKFLOW_QUERY_DELETED_QP); + String previousValue = ctx.getUriInfo().getQueryParameters().getFirst(WorkflowClient.WORKFLOW_QUERY_DELETED_QP); + AuthorityRefDocList refObjs = null; + try { + if (doesContainValue) { + ctx.getUriInfo().getQueryParameters().remove(WorkflowClient.WORKFLOW_QUERY_DELETED_QP); + } - ctx.getUriInfo().getQueryParameters().addFirst(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED, Boolean.toString(onlyRefsToDeletedObjects)); // Add the wf_only_deleted query param to the resource call - AuthorityRefDocList refObjs = authorityResource.getReferencingObjects(ctx, inAuthorityCsid, itemCsid, - uriTemplateRegistry, ctx.getUriInfo()); - ctx.getUriInfo().getQueryParameters().remove(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED); // Need to clear wf_only_deleted values to prevent unexpected side effects - - result = refObjs.getTotalItems(); - if (result > 0) { - 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())); - if (logger.isWarnEnabled() == true) { - logReferencingObjects(docModel, refObjs); - } - } - - return result; + ctx.getUriInfo().getQueryParameters().addFirst(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED_QP, Boolean.toString(onlyRefsToDeletedObjects)); // Add the wf_only_deleted query param to the resource call + refObjs = authorityResource.getReferencingObjects(ctx, inAuthorityCsid, itemCsid, uriTemplateRegistry, ctx.getUriInfo()); + } finally { + ctx.getUriInfo().getQueryParameters().remove(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED_QP); // Need to clear wf_only_deleted values to prevent unexpected side effects + if (doesContainValue) { + ctx.getUriInfo().getQueryParameters().addFirst(WorkflowClient.WORKFLOW_QUERY_DELETED_QP, previousValue); + } + } + + result = refObjs.getTotalItems(); + if (result > 0) { + 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())); + if (logger.isWarnEnabled() == true) { + logReferencingObjects(docModel, refObjs); + } + } + + return result; } 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) { + 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.warn(docModel.getName() + " referenced by : list-item[" + i + "] " + item.getDocType() + "(" + item.getDocId() + ") Name:[" @@ -811,12 +827,12 @@ public abstract class AuthorityItemDocumentModelHandler * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#completeUpdate(org.collectionspace.services.common.document.DocumentWrapper) */ public void completeUpdate(DocumentWrapper wrapDoc) throws Exception { - // Must call our super class' version first - super.completeUpdate(wrapDoc); - - // - // Look for and update authority references with the updated refName - // + // Must call our super class' version first + super.completeUpdate(wrapDoc); + + // + // Look for and update authority references with the updated refName + // if (hasRefNameUpdate() == true) { // We have work to do. if (logger.isDebugEnabled()) { @@ -843,14 +859,14 @@ public abstract class AuthorityItemDocumentModelHandler /* * Note that the Vocabulary service's document-model for items overrides this method. */ - protected String getPrimaryDisplayName(DocumentModel docModel, String schema, - String complexPropertyName, String fieldName) { - String result = null; + protected String getPrimaryDisplayName(DocumentModel docModel, String schema, + String complexPropertyName, String fieldName) { + String result = null; - result = getStringValueInPrimaryRepeatingComplexProperty(docModel, schema, complexPropertyName, fieldName); - - return result; - } + result = getStringValueInPrimaryRepeatingComplexProperty(docModel, schema, complexPropertyName, fieldName); + + return result; + } /* (non-Javadoc) * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#handleUpdate(org.collectionspace.services.common.document.DocumentWrapper) @@ -859,11 +875,11 @@ public abstract class AuthorityItemDocumentModelHandler // FIXME: Once we remove the refName field from the authority item schemas, we can remove this override method since our super does everthing for us now. @Deprecated public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { - // Must call our super's version first, this updates the core schema and the relationship records to deal with possible refName changes/update + // Must call our super's version first, this updates the core schema and the relationship records to deal with possible refName changes/update super.handleUpdate(wrapDoc); if (this.hasRefNameUpdate() == true) { - DocumentModel docModel = wrapDoc.getWrappedObject(); - docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REF_NAME, this.newRefNameOnUpdate); // This field is deprecated since it is now a duplicate of what is in the collectionspace_core:refName field + DocumentModel docModel = wrapDoc.getWrappedObject(); + docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REF_NAME, this.newRefNameOnUpdate); // This field is deprecated since it is now a duplicate of what is in the collectionspace_core:refName field } } @@ -871,30 +887,30 @@ public abstract class AuthorityItemDocumentModelHandler // Handles both update calls (PUTS) AND create calls (POSTS) // public void fillAllParts(DocumentWrapper wrapDoc, Action action) throws Exception { - super.fillAllParts(wrapDoc, action); + super.fillAllParts(wrapDoc, action); DocumentModel documentModel = wrapDoc.getWrappedObject(); - // - // Update the record's revision number on both CREATE and UPDATE actions (as long as it is NOT a SAS authority item) - // + // + // Update the record's revision number on both CREATE and UPDATE actions (as long as it is NOT a SAS authority item) + // Boolean propertyValue = (Boolean) documentModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.SAS); boolean isMarkedAsSASItem = propertyValue != null ? propertyValue : false; - if (this.getShouldUpdateRevNumber() == true && !isMarkedAsSASItem) { // We won't update rev numbers on synchronization with SAS items and on local changes to SAS items - updateRevNumbers(wrapDoc); - } - - if (getShouldUpdateSASFields() == true) { - // - // If this is a proposed item (not part of the SAS), mark it as such - // - documentModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.PROPOSED, - new Boolean(this.getIsProposed())); - // - // If it is a SAS authority item, mark it as such - // - documentModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.SAS, - new Boolean(this.getIsSASItem())); - } + if (this.getShouldUpdateRevNumber() == true && !isMarkedAsSASItem) { // We won't update rev numbers on synchronization with SAS items and on local changes to SAS items + updateRevNumbers(wrapDoc); + } + + if (getShouldUpdateSASFields() == true) { + // + // If this is a proposed item (not part of the SAS), mark it as such + // + documentModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.PROPOSED, + new Boolean(this.getIsProposed())); + // + // If it is a SAS authority item, mark it as such + // + documentModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.SAS, + new Boolean(this.getIsSASItem())); + } } /** @@ -903,65 +919,65 @@ public abstract class AuthorityItemDocumentModelHandler * @throws Exception */ protected void updateRevNumbers(DocumentWrapper wrapDoc) throws Exception { - DocumentModel documentModel = wrapDoc.getWrappedObject(); - Long rev = (Long)documentModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REV); - if (rev == null) { - rev = (long)0; - } else { - rev++; - } - documentModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REV, rev); - // - // Next, update the inAuthority (the parent's) rev number - // - String inAuthorityCsid = this.getInAuthorityCsid(); - if (inAuthorityCsid == null) { - // When inAuthorityCsid is null, it usually means we're performing and update or synch with the SAS - inAuthorityCsid = (String)documentModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.IN_AUTHORITY); - } - DocumentModel inAuthorityDocModel = NuxeoUtils.getDocFromCsid(getServiceContext(), getRepositorySession(), inAuthorityCsid); - if (inAuthorityDocModel != null) { - Long parentRev = (Long)inAuthorityDocModel.getProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV); - if (parentRev == null) { - parentRev = new Long(0); - } - parentRev++; - inAuthorityDocModel.setProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV, parentRev); - getRepositorySession().saveDocument(inAuthorityDocModel); - } else { - logger.warn(String.format("Containing authority '%s' for item '%s' has been deleted. Item is orphaned, so revision numbers can't be updated.", - inAuthorityCsid, documentModel.getName())); - } + DocumentModel documentModel = wrapDoc.getWrappedObject(); + Long rev = (Long)documentModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REV); + if (rev == null) { + rev = (long)0; + } else { + rev++; + } + documentModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REV, rev); + // + // Next, update the inAuthority (the parent's) rev number + // + String inAuthorityCsid = this.getInAuthorityCsid(); + if (inAuthorityCsid == null) { + // When inAuthorityCsid is null, it usually means we're performing and update or synch with the SAS + inAuthorityCsid = (String)documentModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.IN_AUTHORITY); + } + DocumentModel inAuthorityDocModel = NuxeoUtils.getDocFromCsid(getServiceContext(), getRepositorySession(), inAuthorityCsid); + if (inAuthorityDocModel != null) { + Long parentRev = (Long)inAuthorityDocModel.getProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV); + if (parentRev == null) { + parentRev = new Long(0); + } + parentRev++; + inAuthorityDocModel.setProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV, parentRev); + getRepositorySession().saveDocument(inAuthorityDocModel); + } else { + logger.warn(String.format("Containing authority '%s' for item '%s' has been deleted. Item is orphaned, so revision numbers can't be updated.", + inAuthorityCsid, documentModel.getName())); + } } /** * If no short identifier was provided in the input payload, generate a * short identifier from the preferred term display name or term name. */ - private String handleDisplayNameAsShortIdentifier(DocumentModel docModel) throws Exception { - String result = (String) docModel.getProperty(authorityItemCommonSchemaName, - AuthorityItemJAXBSchema.SHORT_IDENTIFIER); + private String handleDisplayNameAsShortIdentifier(DocumentModel docModel) throws Exception { + String result = (String) docModel.getProperty(authorityItemCommonSchemaName, + AuthorityItemJAXBSchema.SHORT_IDENTIFIER); - if (Tools.isEmpty(result)) { - String termDisplayName = getPrimaryDisplayName( - docModel, authorityItemCommonSchemaName, - getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + if (Tools.isEmpty(result)) { + String termDisplayName = getPrimaryDisplayName( + docModel, authorityItemCommonSchemaName, + getItemTermInfoGroupXPathBase(), + AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); - String termName = getPrimaryDisplayName( - docModel, authorityItemCommonSchemaName, - getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_NAME); + String termName = getPrimaryDisplayName( + docModel, authorityItemCommonSchemaName, + getItemTermInfoGroupXPathBase(), + AuthorityItemJAXBSchema.TERM_NAME); - String generatedShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(termDisplayName, - termName); - docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER, - generatedShortIdentifier); - result = generatedShortIdentifier; - } - - return result; - } + String generatedShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(termDisplayName, + termName); + docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER, + generatedShortIdentifier); + result = generatedShortIdentifier; + } + + return result; + } /** * Generate a refName for the authority item from the short identifier @@ -976,8 +992,8 @@ public abstract class AuthorityItemDocumentModelHandler */ protected String updateRefnameForAuthorityItem(DocumentModel docModel, String schemaName) throws Exception { - String result = null; - + String result = null; + RefName.RefNameInterface refname = getRefName(getServiceContext(), docModel); String refNameStr = refname.toString(); docModel.setProperty(schemaName, AuthorityItemJAXBSchema.REF_NAME, refNameStr); @@ -994,12 +1010,12 @@ public abstract class AuthorityItemDocumentModelHandler * * @throws Exception the exception */ - private void handleInAuthority(DocumentModel docModel) throws Exception { - if (inAuthority == null) { // Only happens on queries to wildcarded authorities - throw new IllegalStateException("Trying to Create an object with no inAuthority value!"); - } - docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.IN_AUTHORITY, inAuthority); - } + private void handleInAuthority(DocumentModel docModel) throws Exception { + if (inAuthority == null) { // Only happens on queries to wildcarded authorities + throw new IllegalStateException("Trying to Create an object with no inAuthority value!"); + } + docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.IN_AUTHORITY, inAuthority); + } /** * Returns a list of records that reference this authority item @@ -1013,56 +1029,56 @@ public abstract class AuthorityItemDocumentModelHandler * @throws Exception */ public AuthorityRefDocList getReferencingObjects( - ServiceContext ctx, + ServiceContext ctx, UriTemplateRegistry uriTemplateRegistry, - List serviceTypes, - String propertyName, + List serviceTypes, + String propertyName, String itemcsid) throws Exception { AuthorityRefDocList authRefDocList = null; CoreSessionInterface repoSession = (CoreSessionInterface) ctx.getCurrentRepositorySession(); - boolean releaseRepoSession = false; + boolean releaseRepoSession = false; - try { - NuxeoRepositoryClientImpl repoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx); - repoSession = this.getRepositorySession(); - if (repoSession == null) { - repoSession = repoClient.getRepositorySession(ctx); - releaseRepoSession = true; - } + try { + NuxeoRepositoryClientImpl repoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx); + repoSession = this.getRepositorySession(); + if (repoSession == null) { + repoSession = repoClient.getRepositorySession(ctx); + releaseRepoSession = true; + } DocumentFilter myFilter = getDocumentFilter(); - try { - DocumentWrapper wrapper = repoClient.getDoc(repoSession, ctx, itemcsid); - DocumentModel docModel = wrapper.getWrappedObject(); - String refName = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.REF_NAME); //docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME); + try { + DocumentWrapper wrapper = repoClient.getDoc(repoSession, ctx, itemcsid); + DocumentModel docModel = wrapper.getWrappedObject(); + String refName = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.REF_NAME); //docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME); authRefDocList = RefNameServiceUtils.getAuthorityRefDocs( - repoSession, ctx, uriTemplateRegistry, repoClient, + repoSession, ctx, uriTemplateRegistry, repoClient, serviceTypes, refName, propertyName, myFilter, true /*computeTotal*/); - } catch (PropertyException pe) { - throw pe; - } catch (DocumentException de) { - throw de; - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("Caught exception ", e); - } - throw new DocumentException(e); - } finally { - // If we got/aquired a new seesion then we're responsible for releasing it. - if (releaseRepoSession && repoSession != null) { - repoClient.releaseRepositorySession(ctx, repoSession); - } - } - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("Caught exception ", e); - } - throw new DocumentException(e); - } - + } catch (PropertyException pe) { + throw pe; + } catch (DocumentException de) { + throw de; + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception ", e); + } + throw new DocumentException(e); + } finally { + // If we got/aquired a new seesion then we're responsible for releasing it. + if (releaseRepoSession && repoSession != null) { + repoClient.releaseRepositorySession(ctx, repoSession); + } + } + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception ", e); + } + throw new DocumentException(e); + } + return authRefDocList; } @@ -1117,8 +1133,8 @@ public abstract class AuthorityItemDocumentModelHandler * wildcards and anchor characters) are filtered out from both compared terms. */ protected List getPartialTermDisplayNameMatches(List termDisplayNameList, String partialTerm) { - List result = new ArrayList<>(); - String partialTermMatchExpression = filterAnchorAndWildcardChars(partialTerm).toLowerCase(); + List result = new ArrayList<>(); + String partialTermMatchExpression = filterAnchorAndWildcardChars(partialTerm).toLowerCase(); try { for (String termDisplayName : termDisplayNameList) { if (termDisplayName.toLowerCase() @@ -1130,7 +1146,7 @@ public abstract class AuthorityItemDocumentModelHandler logger.warn("Error in regex match pattern '%s' for term display names: %s", partialTermMatchExpression, pse.getMessage()); } - return result; + return result; } /** @@ -1208,72 +1224,72 @@ public abstract class AuthorityItemDocumentModelHandler } @SuppressWarnings("unchecked") - private List getPartialTermDisplayNameMatches(DocumentModel docModel, // REM - CSPACE-5133 - String schema, ListResultField field, String partialTerm) { - List result = null; - - String xpath = field.getXpath(); // results in something like "persons_common:personTermGroupList/[0]/termDisplayName" - int endOfTermGroup = xpath.lastIndexOf("/[0]/"); - String propertyName = endOfTermGroup != -1 ? xpath.substring(0, endOfTermGroup) : xpath; // it may not be multivalued so the xpath passed in would be the property name - Object value = null; - - try { - value = docModel.getProperty(schema, propertyName); - } catch (Exception e) { - logger.error("Could not extract term display name with property = " - + propertyName, e); - } - - if (value != null && value instanceof ArrayList) { - ArrayList> termGroupList = (ArrayList>)value; - int arrayListSize = termGroupList.size(); - if (arrayListSize > 1) { // if there's only 1 element in the list then we've already matched the primary term's display name - List displayNameList = new ArrayList(); - for (int i = 1; i < arrayListSize; i++) { // start at 1, skip the primary term's displayName since we will always return it - HashMap map = (HashMap)termGroupList.get(i); - String termDisplayName = (String) map.get(AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); - displayNameList.add(i - 1, termDisplayName); - } - - result = getPartialTermDisplayNameMatches(displayNameList, partialTerm); - } - } + private List getPartialTermDisplayNameMatches(DocumentModel docModel, // REM - CSPACE-5133 + String schema, ListResultField field, String partialTerm) { + List result = null; + + String xpath = field.getXpath(); // results in something like "persons_common:personTermGroupList/[0]/termDisplayName" + int endOfTermGroup = xpath.lastIndexOf("/[0]/"); + String propertyName = endOfTermGroup != -1 ? xpath.substring(0, endOfTermGroup) : xpath; // it may not be multivalued so the xpath passed in would be the property name + Object value = null; + + try { + value = docModel.getProperty(schema, propertyName); + } catch (Exception e) { + logger.error("Could not extract term display name with property = " + + propertyName, e); + } + + if (value != null && value instanceof ArrayList) { + ArrayList> termGroupList = (ArrayList>)value; + int arrayListSize = termGroupList.size(); + if (arrayListSize > 1) { // if there's only 1 element in the list then we've already matched the primary term's display name + List displayNameList = new ArrayList(); + for (int i = 1; i < arrayListSize; i++) { // start at 1, skip the primary term's displayName since we will always return it + HashMap map = (HashMap)termGroupList.get(i); + String termDisplayName = (String) map.get(AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + displayNameList.add(i - 1, termDisplayName); + } + + result = getPartialTermDisplayNameMatches(displayNameList, partialTerm); + } + } - return result; + return result; } @Override - protected Object getListResultValue(DocumentModel docModel, // REM - CSPACE-5133 - String schema, ListResultField field) throws DocumentException { - Object result = null; + protected Object getListResultValue(DocumentModel docModel, // REM - CSPACE-5133 + String schema, ListResultField field) throws DocumentException { + Object result = null; - result = NuxeoUtils.getXPathValue(docModel, schema, field.getXpath()); + result = NuxeoUtils.getXPathValue(docModel, schema, field.getXpath()); - // + // // Special handling of list item values for authority items (only) // takes place here: // - // If the list result field is the termDisplayName element, + // If the list result field is the termDisplayName element, // check whether a partial term matching query was made. // If it was, emit values for both the preferred (aka primary) // term and for all non-preferred terms, if any. - // - String elName = field.getElement(); - if (isTermDisplayName(elName) == true) { - MultivaluedMap queryParams = this.getServiceContext().getQueryParams(); - String partialTerm = queryParams != null ? queryParams.getFirst(IQueryManager.SEARCH_TYPE_PARTIALTERM) : null; - if (partialTerm != null && partialTerm.trim().isEmpty() == false) { - String primaryTermDisplayName = (String)result; - List matches = getPartialTermDisplayNameMatches(docModel, schema, field, partialTerm); - if (matches != null && matches.isEmpty() == false) { - matches.add(0, primaryTermDisplayName); // insert the primary term's display name at the beginning of the list - result = matches; // set the result to a list of matching term display names with the primary term's display name at the beginning - } - } - } - - return result; - } + // + String elName = field.getElement(); + if (isTermDisplayName(elName) == true) { + MultivaluedMap queryParams = this.getServiceContext().getQueryParams(); + String partialTerm = queryParams != null ? queryParams.getFirst(IQueryManager.SEARCH_TYPE_PARTIALTERM) : null; + if (partialTerm != null && partialTerm.trim().isEmpty() == false) { + String primaryTermDisplayName = (String)result; + List matches = getPartialTermDisplayNameMatches(docModel, schema, field, partialTerm); + if (matches != null && matches.isEmpty() == false) { + matches.add(0, primaryTermDisplayName); // insert the primary term's display name at the beginning of the list + result = matches; // set the result to a list of matching term display names with the primary term's display name at the beginning + } + } + } + + return result; + } @Override public void extractAllParts(DocumentWrapper wrapDoc) throws Exception { @@ -1335,23 +1351,23 @@ public abstract class AuthorityItemDocumentModelHandler } protected String getAuthorityItemCommonSchemaName() { - return authorityItemCommonSchemaName; + return authorityItemCommonSchemaName; } // @Override public boolean isJDBCQuery() { - boolean result = false; - - MultivaluedMap queryParams = getServiceContext().getQueryParams(); - // - // Look the query params to see if we need to make a SQL query. - // + boolean result = false; + + MultivaluedMap queryParams = getServiceContext().getQueryParams(); + // + // Look the query params to see if we need to make a SQL query. + // String partialTerm = queryParams.getFirst(IQueryManager.SEARCH_TYPE_PARTIALTERM); - if (partialTerm != null && partialTerm.trim().isEmpty() == false) { - result = true; - } - - return result; + if (partialTerm != null && partialTerm.trim().isEmpty() == false) { + result = true; + } + + return result; } // By convention, the name of the database table that contains diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java index 17bd0f7b5..4819fd1b6 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java @@ -30,6 +30,7 @@ import org.collectionspace.services.common.ServiceMessages; import org.collectionspace.services.common.context.RemoteServiceContextFactory; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.context.ServiceContextFactory; +import org.collectionspace.services.common.document.DocumentException; import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.storage.StorageClient; import org.collectionspace.services.common.storage.TransactionContext; @@ -91,7 +92,21 @@ public class RoleResource extends SecurityResourceBase { @POST public Response createRole(Role input) { - return create(input); + try { + return create(input); + } catch (CSWebApplicationException we) { + if (we.getCause() instanceof DocumentException) { + DocumentException de = (DocumentException)we.getCause(); + if (de.getErrorCode() == DocumentException.DUPLICATE_RECORD_ERR) { + // + // Replace the generic error message with a Role-specific error message + // + String msg = String.format("There is already a role with the name '%s'. Please choose a different name.", input.displayName); + throw bigReThrow(new DocumentException(msg, de, de.getErrorCode()), msg); + } + } + throw we; + } } @GET diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java index add7e158e..ee1d2011d 100644 --- a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java +++ b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java @@ -539,7 +539,7 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable { if (uriInfo == null) { uriInfo = createUriInfo(); } - uriInfo.getQueryParameters().add(WorkflowClient.WORKFLOW_QUERY_NONDELETED, Boolean.FALSE.toString()); + uriInfo.getQueryParameters().add(WorkflowClient.WORKFLOW_QUERY_DELETED_QP, Boolean.FALSE.toString()); return uriInfo; } diff --git a/services/claim/client/src/main/java/org/collectionspace/services/client/ClaimProxy.java b/services/claim/client/src/main/java/org/collectionspace/services/client/ClaimProxy.java index f513bf8f4..336037541 100644 --- a/services/claim/client/src/main/java/org/collectionspace/services/client/ClaimProxy.java +++ b/services/claim/client/src/main/java/org/collectionspace/services/client/ClaimProxy.java @@ -55,14 +55,14 @@ public interface ClaimProxy extends CollectionSpaceCommonListPoxProxy { @GET @Produces({"application/xml"}) ClientResponse readIncludeDeleted( - @QueryParam(WorkflowClient.WORKFLOW_QUERY_NONDELETED) String includeDeleted); + @QueryParam(WorkflowClient.WORKFLOW_QUERY_DELETED_QP) String includeDeleted); @Override @GET @Produces({"application/xml"}) ClientResponse keywordSearchIncludeDeleted( @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords, - @QueryParam(WorkflowClient.WORKFLOW_QUERY_NONDELETED) String includeDeleted); + @QueryParam(WorkflowClient.WORKFLOW_QUERY_DELETED_QP) String includeDeleted); @GET @Produces({"application/xml"}) 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 3e6358513..88584ccb2 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 @@ -109,9 +109,9 @@ public class WorkflowClient extends AbstractCommonListPoxServiceClientImpl entry : variablesMap.entrySet()){ - String key = entry.getKey(); - String replace = entry.getValue(); - String find = "\\$\\{"+key+"\\}"; //must add expression escapes - //because $ and braces are "special", and we want to find "${object.CSID}" - uri = Tools.searchAndReplace(uri, find, replace); - System.out.println("---- REPLACE.uri: "+initURI); - System.out.println("---- REPLACE.find: "+find); - System.out.println("---- REPLACE.replace: "+replace); - System.out.println("---- REPLACE.uri result: "+uri); - } - */ - - public static String searchAndReplace(String source, String find, String replace){ + public static String searchAndReplace(String source, String find, String replace){ Pattern pattern = Pattern.compile(find); Matcher matcher = pattern.matcher(source); String output = matcher.replaceAll(replace); @@ -132,7 +127,7 @@ public class Tools { static boolean m_fileSystemIsMac = ":".equals(File.separator); public final static String FILE_EXTENSION_SEPARATOR = "."; - public final static String OPTIONAL_VALUE_SUFFIX = "_OPT"; + public final static String OPTIONAL_VALUE_SUFFIX = "_OPT"; public static boolean fileSystemIsDOS(){return m_fileSystemIsDOS;} public static boolean fileSystemIsMac(){return m_fileSystemIsMac;} @@ -172,7 +167,7 @@ public class Tools { public static String getFilenameBase(String filename) { int dot = filename.lastIndexOf(FILE_EXTENSION_SEPARATOR); if(dot<0) - dot = filename.length(); + dot = filename.length(); int sep = filename.lastIndexOf(File.separator); // Note: if -1, then sep+1=0, which is right return filename.substring(sep + 1, dot); } @@ -182,23 +177,23 @@ public class Tools { } public static String implode(String strings[], String sep) { - String implodedString; - if (strings.length == 0) { - implodedString = ""; - } else { - StringBuffer sb = new StringBuffer(); - sb.append(strings[0]); - for (int i = 1; i < strings.length; i++) { - if (strings[i] != null && !strings[i].trim().isEmpty()) { - sb.append(sep); - sb.append(strings[i]); - } - } - implodedString = sb.toString(); - } - return implodedString; - } - + String implodedString; + if (strings.length == 0) { + implodedString = ""; + } else { + StringBuffer sb = new StringBuffer(); + sb.append(strings[0]); + for (int i = 1; i < strings.length; i++) { + if (strings[i] != null && !strings[i].trim().isEmpty()) { + sb.append(sep); + sb.append(strings[i]); + } + } + implodedString = sb.toString(); + } + return implodedString; + } + @@ -243,25 +238,25 @@ public class Tools { * presentation of error messages to clients. * @param includeLines if zero, return all lines of stack trace, otherwise return number of lines from top. */ - public static String errorToString(Throwable e, boolean stackTraceOnException, int includeLines) { - if (e == null) { - return ""; - } - String s = "\r\n -- Exception: " + e.getClass().getCanonicalName() + "\r\n -- Message: " + e.getMessage(); - - StringBuffer causeBuffer = new StringBuffer(); - Throwable cause = e.getCause(); - while (cause != null) { - causeBuffer.append(cause.getClass().getName() + "::" + cause.getMessage() + "\r\n"); - cause = cause.getCause(); - } - if (causeBuffer.length() > 0) { - s = s + "\r\n -- Causes: " + causeBuffer.toString(); - } - - s = s + "\r\n -- Stack Trace: \r\n -- " + getStackTrace(e, includeLines); - return s; - } + public static String errorToString(Throwable e, boolean stackTraceOnException, int includeLines) { + if (e == null) { + return ""; + } + String s = "\r\n -- Exception: " + e.getClass().getCanonicalName() + "\r\n -- Message: " + e.getMessage(); + + StringBuffer causeBuffer = new StringBuffer(); + Throwable cause = e.getCause(); + while (cause != null) { + causeBuffer.append(cause.getClass().getName() + "::" + cause.getMessage() + "\r\n"); + cause = cause.getCause(); + } + if (causeBuffer.length() > 0) { + s = s + "\r\n -- Causes: " + causeBuffer.toString(); + } + + s = s + "\r\n -- Stack Trace: \r\n -- " + getStackTrace(e, includeLines); + return s; + } /** * Return a set of properties from a properties file. @@ -269,147 +264,147 @@ public class Tools { * @param clientPropertiesFilename * @return */ - static public Properties loadProperties(String clientPropertiesFilename) { - Properties inProperties = new Properties(); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - InputStream is = null; - - try { - is = cl.getResourceAsStream(clientPropertiesFilename); - inProperties.load(is); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - if (is != null) { - try { - is.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - return inProperties; - } - - static public Properties loadProperties(String clientPropertiesFilename, boolean filterPasswords) throws Exception { - Properties result = loadProperties(clientPropertiesFilename); - - if (filterPasswords) { - result = filterPropertiesWithEnvVars(result); - } - - return result; - } - - /** - * Looks for property values if the form ${foo} and tries to find environment property "foo" value to replace with. - * - * For example, a property value of "${foo}" would be replaced with the value of the environment variable "foo" if a - * value for "foo" exists in the current environment. - * - * @param inProperties - * @return - * @throws Exception - */ - static public Properties filterPropertiesWithEnvVars(Properties inProperties) throws Exception { - final String filteredFlag = "fe915b1b-7411-4aaa-887f"; - final String filteredKey = filteredFlag; - Properties result = inProperties; - - if (inProperties.containsKey(filteredKey) == false) { - // Only process the properties once - if (inProperties != null && inProperties.size() > 0) { - for (String key : inProperties.stringPropertyNames()) { - String propertyValue = inProperties.getProperty(key); - String newPropertyValue = Tools.getValueFromEnv(propertyValue); - if (newPropertyValue != null) { // non-null result means the property value was the name of an environment variable - inProperties.setProperty(key, newPropertyValue); - } - } - inProperties.setProperty(filteredKey, filteredFlag); // set to indicated we've already process these properties - } - } - - return result; - } - - static public boolean isOptional(String properyValue) { - boolean result = false; - - result = properyValue.endsWith(OPTIONAL_VALUE_SUFFIX); - - return result; - } - - /** - * Try to find the value of a property variable in the system or JVM environment. This code substitutes only property values formed - * like ${cspace.password.mysecret} or ${cspace_password_mysecret_secret}. The corresponding environment variables would - * be "cspace.password.mysecret" and "cspace.password.mysecret.secret". - * - * Returns null if the passed in property value is not a property variable -i.e., not something of the form {$cspace.password.foo} - * - * Throws an exception if the passed in property value has a valid variable form but the corresponding environment variable is not - * set. - * - * @param propertyValue - * @return - * @throws Exception - */ - static public String getValueFromEnv(String propertyValue) throws Exception { - String result = null; - // - // Replace things like ${cspace.password.cow} with values from either the environment - // or from the JVM system properties. - // - Pattern pattern = Pattern.compile(PROPERTY_VAR_REGEX); // For example, "${cspace.password.mysecret}" or "${password_strong_longpassword}" - Matcher matcher = pattern.matcher(propertyValue); - String key = null; - if (matcher.find()) { - key = matcher.group(1); // Gets the string inside the ${} enclosure. For example, gets "cspace.password.mysecret" from "${cspace.password.mysecret}" - result = System.getenv(key); - if (result == null || result.isEmpty()) { - // If we couldn't find a value in the environment, check the JVM system properties - result = System.getProperty(key); - } - - if (result == null || result.isEmpty()) { - String errMsg = String.format("Could find neither an environment variable nor a systen variable named '%s'", key); - if (isOptional(key) == true) { - System.err.println(errMsg); - } else { - throw new Exception(errMsg); - } - } - } - - return result; - } - - /** - * Test to see if 'propertyValue' is actually a property variable - * @param propertyValue - * @return - */ - static public boolean isValuePropretyVar(String propertyValue) { - boolean result = false; - - if (propertyValue != null) { - Pattern pattern = Pattern.compile(PROPERTY_VAR_REGEX); // For example, "${cspace.password.mysecret}" or "${password_strong_longpassword}" - Matcher matcher = pattern.matcher(propertyValue); - if (matcher.find()) { - result = true; - } - } - - return result; - } - - public static boolean isEmpty(List theList) { - if (theList != null && theList.size() > 0) { - return false; - } else { - return true; - } - } + static public Properties loadProperties(String clientPropertiesFilename) { + Properties inProperties = new Properties(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + InputStream is = null; + + try { + is = cl.getResourceAsStream(clientPropertiesFilename); + inProperties.load(is); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + return inProperties; + } + + static public Properties loadProperties(String clientPropertiesFilename, boolean filterPasswords) throws Exception { + Properties result = loadProperties(clientPropertiesFilename); + + if (filterPasswords) { + result = filterPropertiesWithEnvVars(result); + } + + return result; + } + + /** + * Looks for property values if the form ${foo} and tries to find environment property "foo" value to replace with. + * + * For example, a property value of "${foo}" would be replaced with the value of the environment variable "foo" if a + * value for "foo" exists in the current environment. + * + * @param inProperties + * @return + * @throws Exception + */ + static public Properties filterPropertiesWithEnvVars(Properties inProperties) throws Exception { + final String filteredFlag = "fe915b1b-7411-4aaa-887f"; + final String filteredKey = filteredFlag; + Properties result = inProperties; + + if (inProperties.containsKey(filteredKey) == false) { + // Only process the properties once + if (inProperties != null && inProperties.size() > 0) { + for (String key : inProperties.stringPropertyNames()) { + String propertyValue = inProperties.getProperty(key); + String newPropertyValue = Tools.getValueFromEnv(propertyValue); + if (newPropertyValue != null) { // non-null result means the property value was the name of an environment variable + inProperties.setProperty(key, newPropertyValue); + } + } + inProperties.setProperty(filteredKey, filteredFlag); // set to indicated we've already process these properties + } + } + + return result; + } + + static public boolean isOptional(String properyValue) { + boolean result = false; + + result = properyValue.endsWith(OPTIONAL_VALUE_SUFFIX); + + return result; + } + + /** + * Try to find the value of a property variable in the system or JVM environment. This code substitutes only property values formed + * like ${cspace.password.mysecret} or ${cspace_password_mysecret_secret}. The corresponding environment variables would + * be "cspace.password.mysecret" and "cspace.password.mysecret.secret". + * + * Returns null if the passed in property value is not a property variable -i.e., not something of the form {$cspace.password.foo} + * + * Throws an exception if the passed in property value has a valid variable form but the corresponding environment variable is not + * set. + * + * @param propertyValue + * @return + * @throws Exception + */ + static public String getValueFromEnv(String propertyValue) throws Exception { + String result = null; + // + // Replace things like ${cspace.password.cow} with values from either the environment + // or from the JVM system properties. + // + Pattern pattern = Pattern.compile(PROPERTY_VAR_REGEX); // For example, "${cspace.password.mysecret}" or "${password_strong_longpassword}" + Matcher matcher = pattern.matcher(propertyValue); + String key = null; + if (matcher.find()) { + key = matcher.group(1); // Gets the string inside the ${} enclosure. For example, gets "cspace.password.mysecret" from "${cspace.password.mysecret}" + result = System.getenv(key); + if (result == null || result.isEmpty()) { + // If we couldn't find a value in the environment, check the JVM system properties + result = System.getProperty(key); + } + + if (result == null || result.isEmpty()) { + String errMsg = String.format("Could find neither an environment variable nor a systen variable named '%s'", key); + if (isOptional(key) == true) { + System.err.println(errMsg); + } else { + throw new Exception(errMsg); + } + } + } + + return result; + } + + /** + * Test to see if 'propertyValue' is actually a property variable + * @param propertyValue + * @return + */ + static public boolean isValuePropretyVar(String propertyValue) { + boolean result = false; + + if (propertyValue != null) { + Pattern pattern = Pattern.compile(PROPERTY_VAR_REGEX); // For example, "${cspace.password.mysecret}" or "${password_strong_longpassword}" + Matcher matcher = pattern.matcher(propertyValue); + if (matcher.find()) { + result = true; + } + } + + return result; + } + + public static boolean isEmpty(List theList) { + if (theList != null && theList.size() > 0) { + return false; + } else { + return true; + } + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java index 6f668f619..9055d766a 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java @@ -486,11 +486,11 @@ public abstract class AbstractCollectionSpaceResourceImpl } } - protected CSWebApplicationException bigReThrow(Exception e, String serviceMsg) throws CSWebApplicationException { + protected CSWebApplicationException bigReThrow(Throwable e, String serviceMsg) throws CSWebApplicationException { return bigReThrow(e, serviceMsg, ""); } - protected CSWebApplicationException bigReThrow(Exception e, String serviceMsg, String csid) throws CSWebApplicationException { + protected CSWebApplicationException bigReThrow(Throwable e, String serviceMsg, String csid) throws CSWebApplicationException { boolean logException = true; CSWebApplicationException result = null; Response response; diff --git a/services/common/src/main/java/org/collectionspace/services/common/SecurityResourceBase.java b/services/common/src/main/java/org/collectionspace/services/common/SecurityResourceBase.java index ab06f294d..1d59dd2d6 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/SecurityResourceBase.java +++ b/services/common/src/main/java/org/collectionspace/services/common/SecurityResourceBase.java @@ -18,15 +18,16 @@ import javax.ws.rs.core.UriInfo; @SuppressWarnings("rawtypes") public abstract class SecurityResourceBase extends AbstractCollectionSpaceResourceImpl { - @SuppressWarnings("hiding") - final Logger logger = LoggerFactory.getLogger(SecurityResourceBase.class); + final Logger logger = LoggerFactory.getLogger(SecurityResourceBase.class); public Response create(IT input) { - Response response = null; - + Response response = null; + try { ServiceContext ctx = createServiceContext(input, input.getClass()); response = create(ctx, input); + } catch (CSWebApplicationException we) { + throw we; } catch (Exception e) { throw bigReThrow(e, ServiceMessages.POST_FAILED+"create in "+this.getClass().getName()); } @@ -35,8 +36,8 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa } protected Response create(ServiceContext ctx, IT input) { - Response response = null; - + Response response = null; + try { DocumentHandler handler = createDocumentHandler(ctx); String csid = getStorageClient(ctx).create(ctx, handler); @@ -51,8 +52,8 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa } public Response create(JPATransactionContext jpaTransactionContext, IT input) { - Response response = null; - + Response response = null; + try { ServiceContext ctx = createServiceContext(jpaTransactionContext, input, input.getClass()); DocumentHandler handler = createDocumentHandler(ctx); @@ -68,18 +69,18 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa } private ServiceContext createServiceContext(JPATransactionContext jpaTransactionContext, IT input, - Class clazz) throws Exception { + Class clazz) throws Exception { ServiceContext result = createServiceContext(input, clazz); if (jpaTransactionContext != null) { - result.setTransactionContext(jpaTransactionContext); + result.setTransactionContext(jpaTransactionContext); } return result; - } + } - public Object get(String csid, Class objectClass) { - return get((UriInfo)null, csid, objectClass); + public Object get(String csid, Class objectClass) { + return get((UriInfo)null, csid, objectClass); } public Object get(UriInfo ui, String csid, Class objectClass) { @@ -93,12 +94,12 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa getStorageClient(ctx).get(ctx, csid, handler); result = ctx.getOutput(); } catch (DocumentException e) { - Exception cause = (Exception) e.getCause(); - if (cause instanceof NoResultException) { - Response response = Response.status(Response.Status.NOT_FOUND).entity(result).type("text/plain").build(); - throw new CSWebApplicationException(response); - } - } catch (Exception e) { + Exception cause = (Exception) e.getCause(); + if (cause instanceof NoResultException) { + Response response = Response.status(Response.Status.NOT_FOUND).entity(result).type("text/plain").build(); + throw new CSWebApplicationException(response); + } + } catch (Exception e) { throw bigReThrow(e, ServiceMessages.GET_FAILED, csid); } @@ -123,7 +124,7 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa return result; } - public Object getList(UriInfo ui, Class objectClass) { + public Object getList(UriInfo ui, Class objectClass) { try { ServiceContext ctx = createServiceContext((IT) null, objectClass, ui); DocumentHandler handler = createDocumentHandler(ctx); @@ -142,10 +143,10 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa } public Object update(String csid, IT theUpdate, Class objectClass) { - return update((UriInfo)null, csid, theUpdate, objectClass); + return update((UriInfo)null, csid, theUpdate, objectClass); } - public Object update(UriInfo ui, String csid, IT theUpdate, Class objectClass) { + public Object update(UriInfo ui, String csid, IT theUpdate, Class objectClass) { if (logger.isDebugEnabled()) { logger.debug("updateRole with csid=" + csid); } @@ -159,8 +160,8 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa throw bigReThrow(e, ServiceMessages.PUT_FAILED, csid); } } - - public Object update(ServiceContext parentCtx, UriInfo ui, String csid, IT theUpdate, Class objectClass) { + + public Object update(ServiceContext parentCtx, UriInfo ui, String csid, IT theUpdate, Class objectClass) { if (logger.isDebugEnabled()) { logger.debug("updateRole with csid=" + csid); } @@ -177,19 +178,19 @@ public abstract class SecurityResourceBase extends AbstractCollectionSpa } protected ServiceContext createServiceContext( - ServiceContext parentCtx, - IT input, - Class theClass, - UriInfo uriInfo) throws Exception { - ServiceContext ctx = createServiceContext(input, theClass, uriInfo); - JPATransactionContext parentTransactionContext = parentCtx != null ? (JPATransactionContext)parentCtx.getCurrentTransactionContext() : null; - // - // If the parent context has an active JPA connection then we'll use it. - // - if (parentTransactionContext != null) { - ctx.setTransactionContext(parentTransactionContext); - } - - return ctx; - } + ServiceContext parentCtx, + IT input, + Class theClass, + UriInfo uriInfo) throws Exception { + ServiceContext ctx = createServiceContext(input, theClass, uriInfo); + JPATransactionContext parentTransactionContext = parentCtx != null ? (JPATransactionContext)parentCtx.getCurrentTransactionContext() : null; + // + // If the parent context has an active JPA connection then we'll use it. + // + if (parentTransactionContext != null) { + ctx.setTransactionContext(parentTransactionContext); + } + + return ctx; + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java index 7326e2465..c88323d6a 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java @@ -566,14 +566,16 @@ public abstract class AbstractServiceContextImpl /** * 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 */ private static String buildWorkflowWhereClause(MultivaluedMap queryParams) { String result = null; - String includeDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_NONDELETED); - String includeOnlyDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED); // if set to true, it doesn't matter what the value is for 'includeDeleted' + 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 (Tools.isTrue(includeOnlyDeleted)) { @@ -581,16 +583,18 @@ public abstract class AbstractServiceContextImpl // 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_LOCKED_DELETED, + WorkflowClient.WORKFLOWSTATE_DELETED, + WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED, WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED); } - } else if (!Tools.isTrue(includeDeleted)) { + } else if (includeDeleted != null && Tools.isFalse(includeDeleted)) { // // We can only get here if the 'includeOnlyDeleted' query param is missing altogether. // 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_LOCKED_DELETED, + WorkflowClient.WORKFLOWSTATE_DELETED, + WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED, WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED); } diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentException.java b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentException.java index 60a9aea40..a402d01fb 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentException.java +++ b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentException.java @@ -31,6 +31,9 @@ import org.collectionspace.services.common.ServiceException; */ public class DocumentException extends ServiceException { + public static final int DUPLICATE_RECORD_ERR = 409; + public static final String DUPLICATE_RECORD_MSG = "Record already exists."; + static public DocumentException createDocumentException(Throwable ex) { DocumentException result = new DocumentException(ex); @@ -97,6 +100,11 @@ public class DocumentException extends ServiceException { public DocumentException(String message, Throwable cause) { super(message, cause); } + + public DocumentException(String message, Throwable cause, int errorCode) { + super(message, cause); + setErrorCode(errorCode); + } /** * Constructs a new exception with the specified cause and a detail @@ -115,6 +123,11 @@ public class DocumentException extends ServiceException { public DocumentException(Throwable cause) { super(cause); } + + public DocumentException(Throwable cause, int errorCode) { + super(cause); + setErrorCode(errorCode); + } public boolean exceptionChainContainsNetworkError() { boolean result = false; diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java index 668357c64..731dff906 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java @@ -387,4 +387,10 @@ public interface DocumentHandler { public void sanitize(DocumentWrapper wrapDoc); + /** + * Should return true if the document supports workflow states (usually, just Nuxeo documents/records) + * @return + */ + public boolean supportsWorkflowStates(); + } 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 152e12a49..41ec14889 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 @@ -72,5 +72,9 @@ public abstract class JpaDocumentHandler throws Exception { // Do nothing. JPA document handlers do not support workflow transitions yet. } - + + @Override + public boolean supportsWorkflowStates() { + return false; + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java index 831f17954..86665d0ac 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java @@ -21,6 +21,7 @@ import java.util.Date; import java.util.List; import javax.persistence.EntityExistsException; +import javax.persistence.PersistenceException; import javax.persistence.Query; import javax.persistence.RollbackException; @@ -43,7 +44,7 @@ import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.api.Tools; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.lifecycle.TransitionDef; - +import org.hibernate.exception.ConstraintViolationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -94,20 +95,20 @@ public class JpaStorageClientImpl implements StorageClient { * Instantiates a new jpa storage client. */ public JpaStorageClientImpl() { - //intentionally empty + //intentionally empty } /* (non-Javadoc) * @see org.collectionspace.services.common.storage.StorageClient#create(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.document.DocumentHandler) */ @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override + @Override public String create(ServiceContext ctx, DocumentHandler handler) throws BadRequestException, DocumentException { - String result = null; + String result = null; - JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); + JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); try { handler.prepare(Action.CREATE); Object entity = handler.getCommonPart(); @@ -115,35 +116,41 @@ public class JpaStorageClientImpl implements StorageClient { jpaConnectionContext.beginTransaction(); try { - handler.handle(Action.CREATE, wrapDoc); - JaxbUtils.setValue(entity, "setCreatedAtItem", Date.class, new Date()); - jpaConnectionContext.persist(entity); + handler.handle(Action.CREATE, wrapDoc); + JaxbUtils.setValue(entity, "setCreatedAtItem", Date.class, new Date()); + jpaConnectionContext.persist(entity); } catch (EntityExistsException ee) { // FIXME: No, don't allow duplicates - // - // We found an existing matching entity in the store, so we don't need to create one. Just update the transient 'entity' instance with the existing persisted entity we found. - // An entity's document handler class will throw this exception only if attempting to create (but not actually creating) duplicate is ok -e.g., Permission records. - // - entity = wrapDoc.getWrappedObject(); // the handler should have reset the wrapped transient object with the existing persisted entity we just found. + // + // We found an existing matching entity in the store, so we don't need to create one. Just update the transient 'entity' instance with the existing persisted entity we found. + // An entity's document handler class will throw this exception only if attempting to create (but not actually creating) duplicate is ok -e.g., Permission records. + // + entity = wrapDoc.getWrappedObject(); // the handler should have reset the wrapped transient object with the existing persisted entity we just found. } handler.complete(Action.CREATE, wrapDoc); jpaConnectionContext.commitTransaction(); result = (String)JaxbUtils.getValue(entity, "getCsid"); } catch (BadRequestException bre) { - jpaConnectionContext.markForRollback(); + jpaConnectionContext.markForRollback(); throw bre; } catch (DocumentException de) { - jpaConnectionContext.markForRollback(); + jpaConnectionContext.markForRollback(); throw de; } catch (RollbackException rbe) { - //jpaConnectionContext.markForRollback(); + //jpaConnectionContext.markForRollback(); throw DocumentException.createDocumentException(rbe); + } catch (PersistenceException pe) { + if (pe.getCause() instanceof ConstraintViolationException) { + throw new DocumentException(DocumentException.DUPLICATE_RECORD_MSG, pe, DocumentException.DUPLICATE_RECORD_ERR); + } else { + throw new DocumentException(pe); + } } catch (Exception e) { - jpaConnectionContext.markForRollback(); + jpaConnectionContext.markForRollback(); logger.debug("Caught exception ", e); throw DocumentException.createDocumentException(e); } finally { - ctx.closeConnection(); + ctx.closeConnection(); } return result; @@ -153,7 +160,7 @@ public class JpaStorageClientImpl implements StorageClient { * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler) */ @SuppressWarnings("rawtypes") - @Override + @Override public void get(ServiceContext ctx, List csidList, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { throw new UnsupportedOperationException(); @@ -163,11 +170,11 @@ public class JpaStorageClientImpl implements StorageClient { * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler) */ @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override + @Override public void get(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { - JPATransactionContext jpaTransactionContext = (JPATransactionContext)ctx.openConnection(); + JPATransactionContext jpaTransactionContext = (JPATransactionContext)ctx.openConnection(); try { handler.prepare(Action.GET); Object o = null; @@ -195,7 +202,7 @@ public class JpaStorageClientImpl implements StorageClient { * @see org.collectionspace.services.common.storage.StorageClient#getAll(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.document.DocumentHandler) */ @SuppressWarnings("rawtypes") - @Override + @Override public void getAll(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { throw new UnsupportedOperationException("use getFiltered instead"); @@ -205,16 +212,16 @@ public class JpaStorageClientImpl implements StorageClient { * @see org.collectionspace.services.common.storage.StorageClient#getFiltered(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.document.DocumentHandler) */ @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override + @Override public void getFiltered(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { - + DocumentFilter docFilter = handler.getDocumentFilter(); if (docFilter == null) { docFilter = handler.createDocumentFilter(); } - JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); + JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); try { handler.prepare(Action.GET_ALL); StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM "); @@ -264,9 +271,9 @@ public class JpaStorageClientImpl implements StorageClient { * Return the COUNT for a query to find the total number of matches independent of the paging restrictions. */ @SuppressWarnings("rawtypes") - private long getTotalItems(JPATransactionContext jpaTransactionContext, ServiceContext ctx, DocumentHandler handler) { - long result = -1; - + private long getTotalItems(JPATransactionContext jpaTransactionContext, ServiceContext ctx, DocumentHandler handler) { + long result = -1; + DocumentFilter docFilter = handler.getDocumentFilter(); StringBuilder queryStrBldr = new StringBuilder("SELECT COUNT(*) FROM "); queryStrBldr.append(getEntityName(ctx)); @@ -285,16 +292,16 @@ public class JpaStorageClientImpl implements StorageClient { return result; } - /* (non-Javadoc) + /* (non-Javadoc) * @see org.collectionspace.services.common.storage.StorageClient#update(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler) */ @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override + @Override public void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException { - JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); + JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); try { jpaConnectionContext.beginTransaction(); @@ -320,7 +327,7 @@ public class JpaStorageClientImpl implements StorageClient { } throw new DocumentException(e); } finally { - ctx.closeConnection(); + ctx.closeConnection(); } } @@ -334,12 +341,12 @@ public class JpaStorageClientImpl implements StorageClient { throws DocumentNotFoundException, DocumentException { - JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); + JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); try { - jpaConnectionContext.beginTransaction(); + jpaConnectionContext.beginTransaction(); Object entityFound = getEntity(ctx, id); if (entityFound == null) { - jpaConnectionContext.markForRollback(); + jpaConnectionContext.markForRollback(); String msg = "delete(ctx, id): could not find entity with id=" + id; logger.error(msg); throw new DocumentNotFoundException(msg); @@ -347,7 +354,7 @@ public class JpaStorageClientImpl implements StorageClient { jpaConnectionContext.remove(entityFound); jpaConnectionContext.commitTransaction(); } catch (DocumentException de) { - jpaConnectionContext.markForRollback(); + jpaConnectionContext.markForRollback(); throw de; } catch (Exception e) { if (logger.isDebugEnabled()) { @@ -372,7 +379,7 @@ public class JpaStorageClientImpl implements StorageClient { throws DocumentNotFoundException, DocumentException { - JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); + JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); try { StringBuilder deleteStr = new StringBuilder("DELETE FROM "); deleteStr.append(getEntityName(ctx)); @@ -387,14 +394,14 @@ public class JpaStorageClientImpl implements StorageClient { jpaConnectionContext.beginTransaction(); rcount = q.executeUpdate(); if (rcount != 1) { - jpaConnectionContext.markForRollback(); + jpaConnectionContext.markForRollback(); String msg = "deleteWhere(ctx, id) could not find entity with id=" + id; logger.error(msg); throw new DocumentNotFoundException(msg); } jpaConnectionContext.commitTransaction(); } catch (DocumentException de) { - jpaConnectionContext.markForRollback(); + jpaConnectionContext.markForRollback(); throw de; } catch (Exception e) { if (logger.isDebugEnabled()) { @@ -413,12 +420,12 @@ public class JpaStorageClientImpl implements StorageClient { * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String) */ @SuppressWarnings({ "rawtypes" }) - @Override + @Override public boolean delete(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { - boolean result = false; - - JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); + boolean result = false; + + JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); try { jpaConnectionContext.beginTransaction(); Object entityFound = getEntity(ctx, id); @@ -430,8 +437,8 @@ public class JpaStorageClientImpl implements StorageClient { result = delete(ctx, entityFound, handler); jpaConnectionContext.commitTransaction(); } catch (DocumentException de) { - jpaConnectionContext.markForRollback(); - throw de; + jpaConnectionContext.markForRollback(); + throw de; } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("delete(ctx, ix, handler): Caught exception ", e); @@ -439,19 +446,19 @@ public class JpaStorageClientImpl implements StorageClient { jpaConnectionContext.markForRollback(); throw new DocumentException(e); } finally { - ctx.closeConnection(); + ctx.closeConnection(); } return result; } @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override + @Override public boolean delete(ServiceContext ctx, Object entity, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { - boolean result = false; - - JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); + boolean result = false; + + JPATransactionContext jpaConnectionContext = (JPATransactionContext)ctx.openConnection(); try { jpaConnectionContext.beginTransaction(); handler.prepare(Action.DELETE); @@ -462,8 +469,8 @@ public class JpaStorageClientImpl implements StorageClient { jpaConnectionContext.commitTransaction(); result = true; } catch (DocumentException de) { - jpaConnectionContext.markForRollback(); - throw de; + jpaConnectionContext.markForRollback(); + throw de; } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("delete(ctx, ix, handler): Caught exception ", e); @@ -471,7 +478,7 @@ public class JpaStorageClientImpl implements StorageClient { jpaConnectionContext.markForRollback(); throw new DocumentException(e); } finally { - ctx.closeConnection(); + ctx.closeConnection(); } return result; @@ -528,72 +535,72 @@ public class JpaStorageClientImpl implements StorageClient { */ protected Object getEntity(@SuppressWarnings("rawtypes") ServiceContext ctx, String id, Class entityClazz) throws DocumentNotFoundException, TransactionException { - Object entityFound = null; - - JPATransactionContext jpaTransactionContext = (JPATransactionContext)ctx.openConnection(); - try { - entityFound = JpaStorageUtils.getEntity(jpaTransactionContext, id, entityClazz); // FIXME: # Should be qualifying with the tenant ID - if (entityFound == null) { - String msg = "could not find entity of type=" + entityClazz.getName() - + " with id=" + id; - logger.error(msg); - throw new DocumentNotFoundException(msg); - } - } finally { - ctx.closeConnection(); - } - + Object entityFound = null; + + JPATransactionContext jpaTransactionContext = (JPATransactionContext)ctx.openConnection(); + try { + entityFound = JpaStorageUtils.getEntity(jpaTransactionContext, id, entityClazz); // FIXME: # Should be qualifying with the tenant ID + if (entityFound == null) { + String msg = "could not find entity of type=" + entityClazz.getName() + + " with id=" + id; + logger.error(msg); + throw new DocumentNotFoundException(msg); + } + } finally { + ctx.closeConnection(); + } + return entityFound; } @SuppressWarnings("rawtypes") - @Override + @Override public void get(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { throw new UnsupportedOperationException(); } - @SuppressWarnings("rawtypes") - @Override - public void doWorkflowTransition(ServiceContext ctx, String id, - DocumentHandler handler, TransitionDef transitionDef) - throws BadRequestException, DocumentNotFoundException, - DocumentException { - // Do nothing. JPA services do not support workflow. - } - - @SuppressWarnings("rawtypes") - @Override - public void deleteWithWhereClause(ServiceContext ctx, String whereClause, - DocumentHandler handler) throws DocumentNotFoundException, - DocumentException { + @SuppressWarnings("rawtypes") + @Override + public void doWorkflowTransition(ServiceContext ctx, String id, + DocumentHandler handler, TransitionDef transitionDef) + throws BadRequestException, DocumentNotFoundException, + DocumentException { + // Do nothing. JPA services do not support workflow. + } + + @SuppressWarnings("rawtypes") + @Override + public void deleteWithWhereClause(ServiceContext ctx, String whereClause, + DocumentHandler handler) throws DocumentNotFoundException, + DocumentException { throw new UnsupportedOperationException(); - } - - @SuppressWarnings("rawtypes") - @Override - public boolean synchronize(ServiceContext ctx, Object specifier, - DocumentHandler handler) throws DocumentNotFoundException, - TransactionException, DocumentException { - // TODO Auto-generated method stub - // Do nothing. Subclasses can override if they want/need to. - return true; - } - - @SuppressWarnings("rawtypes") - @Override - public boolean synchronizeItem(ServiceContext ctx, AuthorityItemSpecifier itemSpecifier, - DocumentHandler handler) throws DocumentNotFoundException, - TransactionException, DocumentException { - // TODO Auto-generated method stub - // Do nothing. Subclasses can override if they want/need to. - return true; - } - - @Override - public void releaseRepositorySession(ServiceContext ctx, Object repoSession) - throws TransactionException { - // TODO Auto-generated method stub - } + } + + @SuppressWarnings("rawtypes") + @Override + public boolean synchronize(ServiceContext ctx, Object specifier, + DocumentHandler handler) throws DocumentNotFoundException, + TransactionException, DocumentException { + // TODO Auto-generated method stub + // Do nothing. Subclasses can override if they want/need to. + return true; + } + + @SuppressWarnings("rawtypes") + @Override + public boolean synchronizeItem(ServiceContext ctx, AuthorityItemSpecifier itemSpecifier, + DocumentHandler handler) throws DocumentNotFoundException, + TransactionException, DocumentException { + // TODO Auto-generated method stub + // Do nothing. Subclasses can override if they want/need to. + return true; + } + + @Override + public void releaseRepositorySession(ServiceContext ctx, Object repoSession) + throws TransactionException { + // TODO Auto-generated method stub + } } diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java index 162b982d2..31188b7c8 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java @@ -446,5 +446,10 @@ public abstract class NuxeoDocumentModelHandler extends RemoteDocumentModelHa return new ArrayList(); } } + + @Override + public boolean supportsWorkflowStates() { + return true; + } } diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java index 0a97f3c71..0d6c00fac 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java @@ -132,7 +132,7 @@ public class NuxeoRepositoryClientImpl implements RepositoryClient '" + WorkflowClient.WORKFLOWSTATE_DELETED + "')" 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 e79d37eca..6cd9d0120 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 @@ -472,29 +472,8 @@ public class RelationDocumentModelHandler } } - /* - private String getCommonSchemaNameForDocType(String docType) { - String common_schema = null; - if(docType!=null) { - // HACK - Use startsWith to allow for extension of schemas. - if(docType.startsWith("Person")) - common_schema = PersonAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME; - else if(docType.startsWith("Citation")) - common_schema = CitationAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME; - else if(docType.startsWith("Organization")) - common_schema = OrgAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME; - else if(docType.startsWith("Locationitem")) - common_schema = LocationAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME; - else if(docType.startsWith("Taxon")) - common_schema = TaxonomyAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME; - else if(docType.startsWith("Placeitem")) - common_schema = PlaceAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME; - else if(docType.startsWith("Conceptitem")) - common_schema = ConceptAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME; - //else leave it null. - } - return common_schema; - } - */ - + @Override + public boolean supportsWorkflowStates() { + return true; + } } diff --git a/services/structureddate/service/src/main/java/org/collectionspace/services/structureddate/StructureddateDocumentHandler.java b/services/structureddate/service/src/main/java/org/collectionspace/services/structureddate/StructureddateDocumentHandler.java index 610874eb8..ef6413607 100644 --- a/services/structureddate/service/src/main/java/org/collectionspace/services/structureddate/StructureddateDocumentHandler.java +++ b/services/structureddate/service/src/main/java/org/collectionspace/services/structureddate/StructureddateDocumentHandler.java @@ -127,4 +127,9 @@ public class StructureddateDocumentHandler extends AbstractMultipartDocumentHand public DocumentFilter createDocumentFilter() { throw new RuntimeException("Unimplemented method."); } + + @Override + public boolean supportsWorkflowStates() { + return false; + } } diff --git a/services/systeminfo/service/src/main/java/org/collectionspace/services/systeminfo/SystemInfoDocumentHandler.java b/services/systeminfo/service/src/main/java/org/collectionspace/services/systeminfo/SystemInfoDocumentHandler.java index 6e59c9d54..8f8ba9a4d 100644 --- a/services/systeminfo/service/src/main/java/org/collectionspace/services/systeminfo/SystemInfoDocumentHandler.java +++ b/services/systeminfo/service/src/main/java/org/collectionspace/services/systeminfo/SystemInfoDocumentHandler.java @@ -127,4 +127,9 @@ public class SystemInfoDocumentHandler extends AbstractMultipartDocumentHandlerI public DocumentFilter createDocumentFilter() { throw new RuntimeException("Unimplemented method."); } + + @Override + public boolean supportsWorkflowStates() { + return false; + } } -- 2.47.3