From: Richard Millet Date: Mon, 18 Apr 2016 15:22:42 +0000 (-0700) Subject: CSPACE-6937-A: Adding support for deleting and/or deprecated local terms that no... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=13845725b48b7a8381bfa514b220ac3db743fa31;p=tmp%2Fjakarta-migration.git CSPACE-6937-A: Adding support for deleting and/or deprecated local terms that no longer exist on the SAS. --- diff --git a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemJAXBSchema.java b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemJAXBSchema.java index 2a1397a4f..3d4172699 100644 --- a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemJAXBSchema.java +++ b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemJAXBSchema.java @@ -34,6 +34,9 @@ public interface AuthorityItemJAXBSchema { final static String SHORT_IDENTIFIER = "shortIdentifier"; final static String CSID = "csid"; final static String REV = "rev"; + final static String SAS = "sas"; + final static String DEPRECATED = "deprecated"; + final static String PROPOSED = "proposed"; final static String DISPLAY_NAME = "displayName"; // This is the display name element for the Vocabulary service's item final static String TERM_DISPLAY_NAME = "termDisplayName"; // This is the display name element for all Authority services' items final static String TERM_NAME = "termName"; diff --git a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemListItemJAXBSchema.java b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemListItemJAXBSchema.java index e12f0b651..2735496e3 100644 --- a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemListItemJAXBSchema.java +++ b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityItemListItemJAXBSchema.java @@ -29,6 +29,9 @@ public interface AuthorityItemListItemJAXBSchema { final static String REF_NAME = "refName"; final static String SHORT_IDENTIFIER = "shortIdentifier"; final static String CSID = "csid"; - final static String REV = "rev"; + final static String REV = "rev"; + final static String SAS = "sas"; + final static String PROPOSED = "proposed"; + final static String DEPRECATED = "deprecated"; final static String URI = "url"; } diff --git a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityJAXBSchema.java b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityJAXBSchema.java index d3cfd7127..b0714322d 100644 --- a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityJAXBSchema.java +++ b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityJAXBSchema.java @@ -30,6 +30,7 @@ public interface AuthorityJAXBSchema { final static String VOCAB_TYPE = "vocabType"; final static String CSID = "csid"; final static String REV = "rev"; + final static String SAS = "sas"; // boolean flag indicating if authority is a shared authority } diff --git a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityListItemJAXBSchema.java b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityListItemJAXBSchema.java index a4d128096..c1c093347 100644 --- a/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityListItemJAXBSchema.java +++ b/services/authority/jaxb/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityListItemJAXBSchema.java @@ -30,5 +30,6 @@ public interface AuthorityListItemJAXBSchema { final static String VOCAB_TYPE = "vocabType"; final static String CSID = "csid"; final static String REV = "rev"; + final static String SAS = "sas"; // boolean flag indicating if authority is a shared authority item final static String URI = "url"; } 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 c6bb8652e..c52f3cf3f 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 @@ -95,24 +95,14 @@ import org.slf4j.LoggerFactory; /** * The Class AuthorityResource. */ -/** - * @author pschmitz - * - * @param - * @param - */ -/** - * @author pschmitz - * - * @param - * @param - */ + @Consumes("application/xml") @Produces("application/xml") public abstract class AuthorityResource extends NuxeoBasedResource { final static String SEARCH_TYPE_TERMSTATUS = "ts"; + public final static String hierarchy = "hierarchy"; protected Class authCommonClass; protected Class resourceClass; @@ -398,6 +388,7 @@ public abstract class AuthorityResource ServiceContext ctx = createServiceContext(ui); AuthorityDocumentModelHandler handler = (AuthorityDocumentModelHandler)createDocumentHandler(ctx); specifier = getSpecifier(csid, "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) { @@ -622,7 +613,18 @@ public abstract class AuthorityResource } } - protected Response createAuthorityItem(ServiceContext ctx, String parentspecifier, boolean shouldUpdateRevNumber) throws Exception { + /** + * + * @param ctx + * @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 proposed - 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 parentspecifier, + boolean shouldUpdateRevNumber, + boolean proposed) throws Exception { Response result = null; // Note: must have the parentShortId, to do the create. @@ -630,6 +632,7 @@ public abstract class AuthorityResource AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler) createItemDocumentHandler(ctx, parent.CSID, parent.shortIdentifier); handler.setShouldUpdateRevNumber(shouldUpdateRevNumber); + handler.setIsProposed(proposed); String itemcsid = getRepositoryClient(ctx).create(ctx, handler); UriBuilder path = UriBuilder.fromResource(resourceClass); path.path(parent.CSID + "/items/" + itemcsid); @@ -649,7 +652,8 @@ public abstract class AuthorityResource public Response createAuthorityItemWithParentContext(ServiceContext parentCtx, String parentspecifier, PoxPayloadIn input, - boolean shouldUpdateRevNumber) throws Exception { + boolean shouldUpdateRevNumber, + boolean isProposed) throws Exception { Response result = null; ServiceContext ctx = createServiceContext(getItemServiceName(), input, @@ -657,7 +661,7 @@ public abstract class AuthorityResource if (parentCtx.getCurrentRepositorySession() != null) { ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession()); } - result = this.createAuthorityItem(ctx, parentspecifier, shouldUpdateRevNumber); + result = this.createAuthorityItem(ctx, parentspecifier, shouldUpdateRevNumber, isProposed); return result; } @@ -679,7 +683,8 @@ public abstract class AuthorityResource try { PoxPayloadIn input = new PoxPayloadIn(xmlPayload); ServiceContext ctx = createServiceContext(getItemServiceName(), input, resourceMap, uriInfo); - result = this.createAuthorityItem(ctx, parentspecifier, AuthorityServiceUtils.UPDATE_REV); + result = this.createAuthorityItem(ctx, parentspecifier, AuthorityServiceUtils.UPDATE_REV, + AuthorityServiceUtils.PROPOSED); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.CREATE_FAILED); } @@ -732,14 +737,14 @@ public abstract class AuthorityResource /** * Update an authority item's workflow state. * @param existingContext - * @param csid - * @param itemcsid + * @param parentCsid + * @param itemCsid * @param transition * @return */ public PoxPayloadOut updateItemWorkflowWithTransition(ServiceContext existingContext, - String csid, - String itemcsid, + String parentCsid, + String itemCsid, String transition, boolean updateRevNumber) { PoxPayloadOut result = null; @@ -772,10 +777,10 @@ public abstract class AuthorityResource ctx.setProperty(WorkflowClient.TRANSITION_ID, transitionDef); WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx); - getRepositoryClient(ctx).update(ctx, itemcsid, handler); + getRepositoryClient(ctx).update(ctx, itemCsid, handler); result = ctx.getOutput(); } catch (Exception e) { - throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid); + throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, itemCsid); } return result; @@ -882,6 +887,63 @@ public abstract class AuthorityResource return result; } + /** + * Return a paged list of authority items. + * + * @param existingContext + * @param specifier + * @param uriInfo + * @return + * @throws Exception + */ + public AbstractCommonList getAuthorityItemList(ServiceContext existingContext, + String specifier, + UriInfo uriInfo) throws Exception { + 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()); + } + + String orderBy = queryParams.getFirst(IClientQueryParams.ORDER_BY_PARAM); + String termStatus = queryParams.getFirst(SEARCH_TYPE_TERMSTATUS); + String keywords = queryParams.getFirst(IQueryManager.SEARCH_TYPE_KEYWORDS_KW); + String advancedSearch = queryParams.getFirst(IQueryManager.SEARCH_TYPE_KEYWORDS_AS); + String partialTerm = queryParams.getFirst(IQueryManager.SEARCH_TYPE_PARTIALTERM); + + // 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(specifier) ? null : + lookupParentCSID(specifier, "getAuthorityItemList", "LIST", uriInfo); + DocumentHandler handler = + createItemDocumentHandler(ctx, parentcsid, null); + + DocumentFilter myFilter = handler.getDocumentFilter(); + // If we are not wildcarding the parent, add a restriction + if (parentcsid != null) { + myFilter.appendWhereClause(authorityItemCommonSchemaName + ":" + + AuthorityItemJAXBSchema.IN_AUTHORITY + "=" + + "'" + parentcsid + "'", + IQueryManager.SEARCH_QUALIFIER_AND); + } + + if (Tools.notBlank(termStatus)) { + // 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); + myFilter.appendWhereClause(tsClause, IQueryManager.SEARCH_QUALIFIER_AND); + } + + result = search(ctx, handler, uriInfo, orderBy, keywords, advancedSearch, partialTerm); + + return result; + } + /** * Gets the authorityItem list for the specified authority * If partialPerm is specified, keywords will be ignored. @@ -901,41 +963,7 @@ public abstract class AuthorityResource AbstractCommonList result = null; try { - ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); - MultivaluedMap queryParams = ctx.getQueryParams(); - - String orderBy = queryParams.getFirst(IClientQueryParams.ORDER_BY_PARAM); - String termStatus = queryParams.getFirst(SEARCH_TYPE_TERMSTATUS); - String keywords = queryParams.getFirst(IQueryManager.SEARCH_TYPE_KEYWORDS_KW); - String advancedSearch = queryParams.getFirst(IQueryManager.SEARCH_TYPE_KEYWORDS_AS); - String partialTerm = queryParams.getFirst(IQueryManager.SEARCH_TYPE_PARTIALTERM); - - // 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(specifier) ? null : - lookupParentCSID(specifier, "getAuthorityItemList", "LIST", uriInfo); - DocumentHandler handler = - createItemDocumentHandler(ctx, parentcsid, null); - - DocumentFilter myFilter = handler.getDocumentFilter(); - // If we are not wildcarding the parent, add a restriction - if (parentcsid != null) { - myFilter.appendWhereClause(authorityItemCommonSchemaName + ":" - + AuthorityItemJAXBSchema.IN_AUTHORITY + "=" - + "'" + parentcsid + "'", - IQueryManager.SEARCH_QUALIFIER_AND); - } - - if (Tools.notBlank(termStatus)) { - // 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); - myFilter.appendWhereClause(tsClause, IQueryManager.SEARCH_QUALIFIER_AND); - } - - result = search(ctx, handler, uriInfo, orderBy, keywords, advancedSearch, partialTerm); + result = getAuthorityItemList(NULL_CONTEXT, specifier, uriInfo); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.LIST_FAILED); } @@ -958,8 +986,8 @@ public abstract class AuthorityResource * for the service bindings. If not set, the type defaults to * ServiceBindingUtils.SERVICE_TYPE_PROCEDURE. * - * @param parentspecifier either a CSID or one of the urn forms - * @param itemspecifier either a CSID or one of the urn forms + * @param parentSpecifier either a CSID or one of the urn forms + * @param itemSpecifier either a CSID or one of the urn forms * @param ui the ui * * @return the info for the referencing objects @@ -968,40 +996,59 @@ public abstract class AuthorityResource @Path("{csid}/items/{itemcsid}/refObjs") @Produces("application/xml") public AuthorityRefDocList getReferencingObjects( - @PathParam("csid") String parentspecifier, - @PathParam("itemcsid") String itemspecifier, + @PathParam("csid") String parentSpecifier, + @PathParam("itemcsid") String itemSpecifier, @Context UriTemplateRegistry uriTemplateRegistry, @Context UriInfo uriInfo) { AuthorityRefDocList authRefDocList = null; try { - ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); - MultivaluedMap queryParams = ctx.getQueryParams(); - - String parentcsid = lookupParentCSID(parentspecifier, "getReferencingObjects(parent)", "GET_ITEM_REF_OBJS", uriInfo); - String itemcsid = lookupItemCSID(ctx, itemspecifier, parentcsid, "getReferencingObjects(item)", "GET_ITEM_REF_OBJS"); - - List serviceTypes = queryParams.remove(ServiceBindingUtils.SERVICE_TYPE_PROP); - if(serviceTypes == null || serviceTypes.isEmpty()) { - serviceTypes = ServiceBindingUtils.getCommonServiceTypes(true); //CSPACE-5359: Should now include objects, procedures, and authorities - } - - // Note that we have to create the service context for the Items, not the main service - // We omit the parentShortId, only needed when doing a create... - AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler) - createItemDocumentHandler(ctx, parentcsid, null); - - authRefDocList = handler.getReferencingObjects(ctx, uriTemplateRegistry, serviceTypes, getRefPropName(), itemcsid); + authRefDocList = getReferencingObjects(null, parentSpecifier, itemSpecifier, uriTemplateRegistry, uriInfo); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.GET_FAILED); } + if (authRefDocList == null) { Response response = Response.status(Response.Status.NOT_FOUND).entity( - "Get failed, the requested Item CSID:" + itemspecifier + ": was not found.").type( + "Get failed, the requested Item CSID:" + itemSpecifier + ": was not found.").type( "text/plain").build(); throw new CSWebApplicationException(response); } return authRefDocList; } + + public AuthorityRefDocList getReferencingObjects( + ServiceContext existingContext, + String parentspecifier, + String itemspecifier, + UriTemplateRegistry uriTemplateRegistry, + UriInfo uriInfo) throws Exception { + AuthorityRefDocList authRefDocList = null; + + ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); + MultivaluedMap queryParams = ctx.getQueryParams(); + // + // 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()); + } + + String parentcsid = lookupParentCSID(parentspecifier, "getReferencingObjects(parent)", "GET_ITEM_REF_OBJS", uriInfo); + String itemcsid = lookupItemCSID(ctx, itemspecifier, parentcsid, "getReferencingObjects(item)", "GET_ITEM_REF_OBJS"); + + List serviceTypes = queryParams.remove(ServiceBindingUtils.SERVICE_TYPE_PROP); + if(serviceTypes == null || serviceTypes.isEmpty()) { + serviceTypes = ServiceBindingUtils.getCommonServiceTypes(true); //CSPACE-5359: Should now include objects, procedures, and authorities + } + + // Note that we have to create the service handler for the Items, not the main parent resource + // We omit the parentShortId, only needed when doing a create... + AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parentcsid, null); + authRefDocList = handler.getReferencingObjects(ctx, uriTemplateRegistry, serviceTypes, getRefPropName(), itemcsid); + + return authRefDocList; + } /** * Gets the authority terms used in the indicated Authority item. @@ -1047,7 +1094,7 @@ public abstract class AuthorityResource * @return * @throws Exception */ - protected PoxPayloadOut synchronizeItem( + private PoxPayloadOut synchronizeItem( ServiceContext ctx, String parentIdentifier, String itemIdentifier) throws Exception { @@ -1058,6 +1105,8 @@ public abstract class AuthorityResource 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 + // Create an authority item specifier Specifier parentSpecifier = getSpecifier(parent.CSID, "getAuthority", "GET"); Specifier itemSpecifier = getSpecifier(itemIdentifier, "getAuthorityItem", "GET"); specifier = new AuthorityItemSpecifier(parentSpecifier, itemSpecifier); @@ -1162,7 +1211,8 @@ public abstract class AuthorityResource try { PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload); result = updateAuthorityItem(null, resourceMap, uriInfo, parentSpecifier, itemSpecifier, theUpdate, - AuthorityServiceUtils.UPDATE_REV); // passing TRUE so rev num increases + 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 } catch (Exception e) { throw bigReThrow(e, ServiceMessages.UPDATE_FAILED); } @@ -1177,7 +1227,8 @@ public abstract class AuthorityResource String parentspecifier, String itemspecifier, PoxPayloadIn theUpdate, - boolean shouldUpdateRevNumber) throws Exception { + boolean shouldUpdateRevNumber, + Boolean isProposed) throws Exception { PoxPayloadOut result = null; CsidAndShortIdentifier csidAndShortId = lookupParentCSIDAndShortIdentifer(itemServiceCtx, parentspecifier, "updateAuthorityItem(parent)", "UPDATE_ITEM", null); @@ -1198,6 +1249,9 @@ public abstract class AuthorityResource // We omit the parentShortId, only needed when doing a create... AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parentcsid, parentShortId); handler.setShouldUpdateRevNumber(shouldUpdateRevNumber); + if (isProposed != null) { + handler.setIsProposed(isProposed); + } getRepositoryClient(ctx).update(ctx, itemcsid, handler); result = ctx.getOutput(); @@ -1217,29 +1271,39 @@ public abstract class AuthorityResource public Response deleteAuthorityItem( @PathParam("csid") String parentcsid, @PathParam("itemcsid") String itemcsid) { - //try{ + Response result = null; + if (logger.isDebugEnabled()) { logger.debug("deleteAuthorityItem with parentcsid=" + parentcsid + " and itemcsid=" + itemcsid); } + try { - ensureCSID(parentcsid, ServiceMessages.DELETE_FAILED, "AuthorityItem.parentcsid"); - ensureCSID(itemcsid, ServiceMessages.DELETE_FAILED, "AuthorityItem.itemcsid"); - //Laramie, removing this catch, since it will surely fail below, since itemcsid or parentcsid will be null. - // }catch (Throwable t){ - // System.out.println("ERROR in setting up DELETE: "+t); - // } - // try { - // Note that we have to create the service context for the Items, not the main service - ServiceContext ctx = createServiceContext(getItemServiceName()); - DocumentHandler handler = createDocumentHandler(ctx); - getRepositoryClient(ctx).delete(ctx, itemcsid, handler); - return Response.status(HttpResponseCodes.SC_OK).build(); + deleteAuthorityItem(null, parentcsid, itemcsid); + result = Response.status(HttpResponseCodes.SC_OK).build(); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.DELETE_FAILED + " itemcsid: " + itemcsid + " parentcsid:" + parentcsid); } + + return result; } - public final static String hierarchy = "hierarchy"; - + + public void deleteAuthorityItem(ServiceContext existingCtx, + String parentcsid, + String itemcsid) throws Exception { + Response result = null; + + ensureCSID(parentcsid, ServiceMessages.DELETE_FAILED, "AuthorityItem.parentcsid"); + ensureCSID(itemcsid, ServiceMessages.DELETE_FAILED, "AuthorityItem.itemcsid"); + // Note that we have to create the service context for the Items, not the main service + ServiceContext ctx = createServiceContext(getItemServiceName()); + if (existingCtx != null && existingCtx.getCurrentRepositorySession() != null) { + ctx.setCurrentRepositorySession(existingCtx.getCurrentRepositorySession()); // Use existing repo session if one exists + ctx.setProperties(existingCtx.getProperties()); + } + DocumentHandler handler = createDocumentHandler(ctx); + getRepositoryClient(ctx).delete(ctx, itemcsid, handler); + } + @GET @Path("{csid}/items/{itemcsid}/" + hierarchy) @Produces("application/xml") diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java index 7213612d2..d192bf53b 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java @@ -15,9 +15,21 @@ import org.slf4j.LoggerFactory; public class AuthorityServiceUtils { private static final Logger logger = LoggerFactory.getLogger(AuthorityIdentifierUtils.class); + // Used to keep track if an authority item's is deprecated + public static final String IS_DEPRECATED_PROPERTY = "IS_DEPRECATED_PROPERTY"; + public static final Boolean DEPRECATED = true; + public static final Boolean NOT_DEPRECATED = !DEPRECATED; + + // Used to keep track if an authority item's rev number should be updated public static final String SHOULD_UPDATE_REV_PROPERTY = "SHOULD_UPDATE_REV_PROPERTY"; - public static final boolean DONT_UPDATE_REV = false; public static final boolean UPDATE_REV = true; + public static final boolean DONT_UPDATE_REV = !UPDATE_REV; + + // Used to keep track if an authority item is a locally proposed member of a SAS authority + public static final String IS_PROPOSED_PROPERTY = "IS_PROPOSED"; + public static final Boolean PROPOSED = true; + public static final Boolean NOT_PROPOSED = !PROPOSED; + public static final Boolean NO_CHANGE = null; static public PoxPayloadIn requestPayloadIn(ServiceContext ctx, Specifier specifier, Class responseType) throws Exception { PoxPayloadIn result = null; diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java index ee0ead044..72ccc315a 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java @@ -23,17 +23,20 @@ */ package org.collectionspace.services.common.vocabulary.nuxeo; +import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.ws.rs.core.Response; +import org.collectionspace.services.client.AbstractCommonListUtils; import org.collectionspace.services.client.AuthorityClient; import org.collectionspace.services.client.CollectionSpaceClient; import org.collectionspace.services.client.PayloadInputPart; import org.collectionspace.services.client.VocabularyClient; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; +import org.collectionspace.services.client.workflow.WorkflowClient; import org.collectionspace.services.common.ResourceMap; import org.collectionspace.services.common.XmlTools; import org.collectionspace.services.common.api.RefName; @@ -55,6 +58,8 @@ import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Author import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier; import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm; import org.collectionspace.services.config.service.ObjectPartType; +import org.collectionspace.services.jaxb.AbstractCommonList; +import org.collectionspace.services.jaxb.AbstractCommonList.ListItem; import org.collectionspace.services.lifecycle.TransitionDef; import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; @@ -123,7 +128,7 @@ public abstract class AuthorityDocumentModelHandler ServiceContext ctx = getServiceContext(); Specifier specifier = (Specifier) wrapDoc.getWrappedObject(); // - // Get the rev number of the authority so we can compare with rev number of shared authority + // Get the rev number and short ID of the local authority // DocumentModel docModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), authorityCommonSchemaName, specifier); Long localRev = (Long) NuxeoUtils.getProperyValue(docModel, AuthorityJAXBSchema.REV); @@ -134,12 +139,13 @@ public abstract class AuthorityDocumentModelHandler Specifier sasSpecifier = new Specifier(SpecifierForm.URN_NAME, RefNameUtils.createShortIdRefName(shortId)); PoxPayloadIn sasPayloadIn = AuthorityServiceUtils.requestPayloadIn(ctx, sasSpecifier, getEntityResponseType()); // + // Compare revision number of local authority with that of the shared authority on the SAS. // If the authority on the SAS is newer, synch all the items and then the authority record as well // Long sasRev = getRevision(sasPayloadIn); if (sasRev > localRev) { // - // First, sync all the authority items + // First, synchronize all the authority item records/resources. // syncAllItems(ctx, sasSpecifier); // @@ -148,6 +154,8 @@ public abstract class AuthorityDocumentModelHandler ResourceMap resourceMap = ctx.getResourceMap(); String resourceName = ctx.getClient().getServiceName(); AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName); + // Set this context property since we don't want to update the revision number on sync updates + ctx.setProperty(AuthorityServiceUtils.SHOULD_UPDATE_REV_PROPERTY, AuthorityServiceUtils.DONT_UPDATE_REV); PoxPayloadOut payloadOut = authorityResource.update(ctx, resourceMap, ctx.getUriInfo(), docModel.getName(), sasPayloadIn); if (payloadOut != null) { @@ -168,7 +176,9 @@ public abstract class AuthorityDocumentModelHandler int created = 0; int synched = 0; int alreadySynched = 0; + int deprecated = 0; int totalItemsProcessed = 0; + ArrayList itemsInRemoteAuthority = new ArrayList(); // // Iterate over the list of items/terms in the remote authority // @@ -177,6 +187,7 @@ public abstract class AuthorityDocumentModelHandler if (itemList != null) { for (Element e:itemList) { String remoteRefName = XmlTools.getElementValue(e, "refName"); + itemsInRemoteAuthority.add(remoteRefName); long status = syncRemoteItemWithLocalItem(ctx, remoteRefName); if (status == 1) { created++; @@ -188,6 +199,20 @@ public abstract class AuthorityDocumentModelHandler totalItemsProcessed++; } } + // + // Now see if we need to deprecate or delete items that have been hard-deleted from the SAS but still exist + // locally. Subtract (remove) the list of remote items from the list of local items to determine which + // of the remote items have been hard deleted. + // + ArrayList itemsInLocalAuthority = getItemsInLocalAuthority(ctx, sasSpecifier); + if (itemsInLocalAuthority.removeAll(itemsInRemoteAuthority) == true) { + ArrayList remainingItems = itemsInLocalAuthority; // now a subset of local items + // + // We now need to either hard-deleted or deprecate the remaining authorities + // + deleteOrDeprecateItems(ctx, remainingItems); + } + logger.info(String.format("Total number of items processed during sync: %d", totalItemsProcessed)); logger.info(String.format("Number of items synchronized: %d", synched)); @@ -197,6 +222,109 @@ public abstract class AuthorityDocumentModelHandler return result; } + private long deleteOrDeprecateItems(ServiceContext ctx, ArrayList refNameList) throws Exception { + long result = 0; + ArrayList failureList = new ArrayList(); + + for (String refName:refNameList) { + AuthorityTermInfo itemInfo = RefNameUtils.parseAuthorityTermInfo(refName); + AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(); + try { + authorityResource.deleteAuthorityItem(ctx, itemInfo.inAuthority.csid, itemInfo.csid); + result++; + } catch (DocumentException de) { + // + // If we can't delete the item, it might be because there are existing records referencing it. So + // we need to mark the item as deprecated + // + logger.info(String.format("Hit document exception trying to delete or deprecate '%s' during sync", + refName), de); + boolean marked = markAuthorityItemAsDeprecated(ctx, itemInfo); + if (marked == true) { + result++; + } + } catch (Exception e) { + logger.warn(String.format("Unable to delete authority item '%s'", refName), e); + } + } + + if (logger.isWarnEnabled() == true) { + if (result != refNameList.size()) { + logger.warn(String.format("Unable to delete or deprecate some authority items during synchronization with SAS. Deleted or deprecated %d of %d", + result, refNameList.size())); + } + } + + return result; + } + + /** + * Mark the authority item as deprecated. + * + * @param ctx + * @param itemInfo + * @throws Exception + */ + private boolean markAuthorityItemAsDeprecated(ServiceContext ctx, AuthorityTermInfo itemInfo) throws Exception { + boolean result = false; + + try { + String itemCsid = itemInfo.csid; + DocumentModel docModel = NuxeoUtils.getDocFromCsid(ctx, (CoreSessionInterface)ctx.getCurrentRepositorySession(), itemCsid); + docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.DEPRECATED, + new Boolean(AuthorityServiceUtils.DEPRECATED)); + result = true; + } catch (Exception e) { + logger.warn(String.format("Could not mark item '%s' as deprecated.", itemInfo.name), e); + } + + return result; + } + + /** + * Gets the list of SAS related items in the local authority. We exlude items with the "proposed" flags because + * we want a list with only SAS created items. + * + * We need to add pagination support to this call!!! + * + * @param ctx + * @param specifier + * @return + * @throws Exception + */ + private ArrayList getItemsInLocalAuthority(ServiceContext ctx, Specifier specifier) throws Exception { + ArrayList result = new ArrayList(); + + ResourceMap resourceMap = ctx.getResourceMap(); + String resourceName = ctx.getClient().getServiceName(); + AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName); + AbstractCommonList acl = authorityResource.getAuthorityItemList(ctx, specifier.value, ctx.getUriInfo()); + List listItemList = acl.getListItem(); + for (ListItem listItem:listItemList) { + Boolean proposed = getBooleanValue(listItem, AuthorityItemJAXBSchema.PROPOSED); + if (proposed == false) { // exclude "proposed" (i.e., local-only items) + result.add(AbstractCommonListUtils.ListItemGetElementValue(listItem, AuthorityItemJAXBSchema.REF_NAME)); + } + } + + return result; + } + + private Boolean getBooleanValue(ListItem listItem, String name) { + Boolean result = null; + + String value = AbstractCommonListUtils.ListItemGetElementValue(listItem, name); + if (value != null) { + result = Boolean.valueOf(value); + } + + return result; + } + + private String getStringValue(ListItem listItem, String name) { + return AbstractCommonListUtils.ListItemGetElementValue(listItem, AuthorityItemJAXBSchema.REF_NAME); + } + /** * This is a sync method. * @param ctx @@ -223,17 +351,19 @@ public abstract class AuthorityDocumentModelHandler String resourceName = ctx.getClient().getServiceName(); AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName); Response response = authorityResource.createAuthorityItemWithParentContext(ctx, authoritySpecifier.value, - sasPayloadIn, AuthorityServiceUtils.DONT_UPDATE_REV); + sasPayloadIn, AuthorityServiceUtils.DONT_UPDATE_REV, AuthorityServiceUtils.NOT_PROPOSED); // // Check the response for successful POST result // if (response.getStatus() != Response.Status.CREATED.getStatusCode()) { throw new DocumentException(String.format("Could not create new authority item '%s' during synchronization of the '%s' authority.", itemIdentifier, parentIdentifier)); + } // - // Handle the workflow state + // Handle the workflow state by "locking" this new copy of the SAS item. // - } + authorityResource.updateItemWorkflowWithTransition(ctx, parentIdentifier, itemIdentifier, + WorkflowClient.WORKFLOWTRANSITION_LOCK, AuthorityServiceUtils.DONT_UPDATE_REV); } /** @@ -257,7 +387,7 @@ public abstract class AuthorityDocumentModelHandler String parentIdentifier = RefNameUtils.createShortIdRefName(authorityTermInfo.inAuthority.name); String itemIdentifier = RefNameUtils.createShortIdRefName(authorityTermInfo.name); // - // We'll use the Authority JAX-RS resource to peform sync operations (creates and updates) + // We'll use the Authority JAX-RS resource class to peform sync operations (creates and updates) // ResourceMap resourceMap = ctx.getResourceMap(); String resourceName = ctx.getClient().getServiceName(); @@ -268,14 +398,15 @@ public abstract class AuthorityDocumentModelHandler localItemPayloadOut = authorityResource.getAuthorityItemWithParentContext(ctx, parentIdentifier, itemIdentifier); } catch (DocumentNotFoundException dnf) { // - // Document not found, means we need to create an item/term that exists only on the SAS + // Document not found, means we need to create a local item/term that exists only on the SAS // logger.info(String.format("Remote item with refname='%s' doesn't exist locally, so we'll create it.", remoteRefName)); createLocalItem(ctx, parentIdentifier, itemIdentifier); return 1; // exit with status of 1 means we created a new authority item } // - // If we get here, we know the item exists both locally and remotely, so we need to synchronize them + // If we get here, we know the item exists both locally and remotely, so we need to synchronize them. + // We synchronize by calling the authority resource (the JAX-RS resource) class' sync method for an item. // PoxPayloadOut theUpdate = authorityResource.synchronizeItemWithParentContext(ctx, parentIdentifier, itemIdentifier); if (theUpdate != null) { 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 e5762339a..679038fc6 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 @@ -28,7 +28,9 @@ import org.collectionspace.services.client.CollectionSpaceClient; import org.collectionspace.services.client.IQueryManager; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; +import org.collectionspace.services.client.workflow.WorkflowClient; import org.collectionspace.services.common.ResourceMap; +import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.UriTemplateRegistry; import org.collectionspace.services.common.api.RefName; import org.collectionspace.services.common.api.RefNameUtils; @@ -92,6 +94,8 @@ public abstract class AuthorityItemDocumentModelHandler protected String authorityCommonSchemaName; protected String authorityItemCommonSchemaName; private String authorityItemTermGroupXPathBase; + + private boolean isProposed = false; // used by local authority to propose a new shared item. Allows local deployments to use new terms until they become official private boolean shouldUpdateRevNumber = true; // by default we should update the revision number -not true on synchronization with SAS /** * inVocabulary is the parent Authority for this context @@ -110,6 +114,20 @@ public abstract class AuthorityItemDocumentModelHandler abstract public String getParentCommonSchemaName(); + // + // Getter and Setter for 'proposed' + // + public boolean getIsProposed() { + return this.isProposed; + } + + public void setIsProposed(boolean flag) { + this.isProposed = flag; + } + + // + // Getter and Setter for 'shouldUpdateRevNumber' + // public boolean getShouldUpdateRevNumber() { return this.shouldUpdateRevNumber; } @@ -362,7 +380,9 @@ public abstract class AuthorityItemDocumentModelHandler } /** - * This method synchronizes/updates a single authority item resource. + * This method synchronizes/updates a single authority item resource with the corresponding SAS items. + * The argument 'wrapDoc' in most CSpace methods usually contains a resource payload -like a nuxeo document model. However, + * for the handleSync method, the wrapDoc argument contains a authority item specifier. */ @Override public boolean handleSync(DocumentWrapper wrapDoc) throws Exception { @@ -370,7 +390,7 @@ public abstract class AuthorityItemDocumentModelHandler ServiceContext ctx = getServiceContext(); // - // Get information about the local authority item so we can compare with corresponding item on the shared authority server + // Get information about the local authority item so we can compare with the corresponding item on the shared authority server // AuthorityItemSpecifier authorityItemSpecifier = (AuthorityItemSpecifier) wrapDoc.getWrappedObject(); DocumentModel itemDocModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), getAuthorityItemCommonSchemaName(), @@ -380,6 +400,7 @@ public abstract class AuthorityItemDocumentModelHandler authorityItemSpecifier.getItemSpecifier().value)); } Long localItemRev = (Long) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.REV); + Boolean localIsProposed = (Boolean) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.PROPOSED); String localItemCsid = itemDocModel.getName(); String localItemWorkflowState = (String) NuxeoUtils.getProperyValue(itemDocModel, CollectionSpaceClient.CORE_WORKFLOWSTATE); String itemShortId = (String) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.SHORT_IDENTIFIER); @@ -391,31 +412,33 @@ public abstract class AuthorityItemDocumentModelHandler authorityItemSpecifier.getParentSpecifier()); String authorityShortId = (String) NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.SHORT_IDENTIFIER); String localParentCsid = authorityDocModel.getName(); + // // Using the short IDs of the local authority and item, create URN specifiers to retrieve the SAS authority item // Specifier sasAuthoritySpecifier = new Specifier(SpecifierForm.URN_NAME, RefNameUtils.createShortIdRefName(authorityShortId)); Specifier sasItemSpecifier = new Specifier(SpecifierForm.URN_NAME, RefNameUtils.createShortIdRefName(itemShortId)); AuthorityItemSpecifier sasAuthorityItemSpecifier = new AuthorityItemSpecifier(sasAuthoritySpecifier, sasItemSpecifier); - // Get the shared authority server's copy + // Get the shared authority server's copy of the item/term PoxPayloadIn sasPayloadIn = AuthorityServiceUtils.requestPayloadIn(sasAuthorityItemSpecifier, getAuthorityServicePath(), getEntityResponseType()); Long sasRev = getRevision(sasPayloadIn); String sasWorkflowState = getWorkflowState(sasPayloadIn); // - // If the shared authority item is newer, update our local copy + // Update the local item if the shared authority item is newer or if the local item is a proposed item that is now becoming a true SAS item // - if (sasRev > localItemRev) { + if (sasRev > localItemRev || localIsProposed) { ResourceMap resourceMap = ctx.getResourceMap(); String resourceName = this.getAuthorityServicePath(); AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName); PoxPayloadOut payloadOut = authorityResource.updateAuthorityItem(ctx, resourceMap, 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 + 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 if (payloadOut != null) { ctx.setOutput(payloadOut); result = true; @@ -429,7 +452,7 @@ public abstract class AuthorityItemDocumentModelHandler String resourceName = this.getAuthorityServicePath(); AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName); // - // We need to move the local item to the SAS workflow state. This might involve multiple transitions. + // We need to move the local item to the SAS workflow state -i.e., the locked state. // List transitionList = getTransitionList(sasWorkflowState, localItemWorkflowState); for (String transition:transitionList) { @@ -441,11 +464,23 @@ public abstract class AuthorityItemDocumentModelHandler } /** - * We need to move the local item to the SAS workflow state. This might involve multiple transitions. + * We need to move the local item to the SAS item's workflow state. This might involve multiple transitions. */ private List getTransitionList(String sasWorkflowState, String localItemWorkflowState) { List result = new ArrayList(); - // TO BE COMPLETELED + // + // If the SAS authority items is soft-deleted, we need to mark the local item as soft-deleted + // + if (sasWorkflowState.contains(WorkflowClient.WORKFLOWSTATE_DELETED) == true) { + result.add(WorkflowClient.WORKFLOWTRANSITION_DELETE); + } + // + // Ensure the local item is in a "locked" state. Items sync'd with a SAS should always be locked + // + if (localItemWorkflowState.contains(WorkflowClient.WORKFLOWSTATE_LOCKED) != true) { + result.add(WorkflowClient.WORKFLOWTRANSITION_LOCK); + } + return result; } @@ -459,6 +494,34 @@ public abstract class AuthorityItemDocumentModelHandler // Ensure we have required fields set properly handleInAuthority(wrapDoc.getWrappedObject()); } + + /* This method ensures that before we delete an authority item, there are no records in the system that reference it. + * + * (non-Javadoc) + * @see org.collectionspace.services.common.document.DocumentHandler#handleDelete(org.collectionspace.services.common.document.DocumentWrapper) + */ + @Override + public void handleDelete(DocumentWrapper wrapDoc) throws Exception { + UriTemplateRegistry uriTemplateRegistry = ServiceMain.getInstance().getUriTemplateRegistry(); + ServiceContext ctx = getServiceContext(); + DocumentModel docModel = wrapDoc.getWrappedObject(); + String inAuthorityCsid = (String) docModel.getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.IN_AUTHORITY); + String itemCsid = docModel.getName(); + + ResourceMap resourceMap = ctx.getResourceMap(); + String resourceName = this.getAuthorityServicePath(); + AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName); + // + // If the authority item has references to it from other resources, we can't and won't + // delete it. + // + AuthorityRefDocList refObjs = authorityResource.getReferencingObjects(ctx, inAuthorityCsid, itemCsid, + uriTemplateRegistry, ctx.getUriInfo()); + if (refObjs.getTotalItems() != 0) { + throw new DocumentException(String.format("Can not delete authority item '%s' because it still has records in the system that are referencing it.", + itemCsid)); + } + } /* * This method gets called after the primary update to an authority item has happened. If the authority item's refName @@ -524,6 +587,9 @@ 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); // @@ -532,6 +598,12 @@ public abstract class AuthorityItemDocumentModelHandler if (this.getShouldUpdateRevNumber() == true) { // We won't update rev numbers on synchronization with SAS updateRevNumbers(wrapDoc); } + // + // If this is a proposed item (not part of the SAS), mark it as such + // + DocumentModel documentModel = wrapDoc.getWrappedObject(); + documentModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.PROPOSED, + new Boolean(this.getIsProposed())); } /** diff --git a/services/client/src/main/java/org/collectionspace/services/client/AbstractCommonListUtils.java b/services/client/src/main/java/org/collectionspace/services/client/AbstractCommonListUtils.java index 1741033bd..e4019cbc9 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/AbstractCommonListUtils.java +++ b/services/client/src/main/java/org/collectionspace/services/client/AbstractCommonListUtils.java @@ -3,6 +3,7 @@ package org.collectionspace.services.client; import java.util.List; import org.collectionspace.services.jaxb.AbstractCommonList; + import org.slf4j.Logger; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -28,19 +29,20 @@ public class AbstractCommonListUtils { public static String ListItemGetCSID(AbstractCommonList.ListItem item) { return ListItemGetElementValue(item, "csid"); } - + public static String ListItemGetElementValue(AbstractCommonList.ListItem item, String elName) { + String result = null; + List elList = item.getAny(); - for(Element el : elList) { - if(elName.equalsIgnoreCase(el.getNodeName())) { + for (Element el : elList) { + if (elName.equalsIgnoreCase(el.getNodeName())) { Node textEl = el.getFirstChild(); - return textEl.getNodeValue(); + result = textEl.getNodeValue(); + break; } - } - return null; + } + + return result; } - - - } 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 db4da7375..b8db13132 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 @@ -65,7 +65,7 @@ public abstract class AbstractCollectionSpaceResourceImpl protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - + protected final ServiceContext NULL_CONTEXT = null; // Fields for default client factory and client /** The repository client factory. */ private RepositoryClientFactory repositoryClientFactory; diff --git a/services/common/src/main/java/org/collectionspace/services/common/ResourceMap.java b/services/common/src/main/java/org/collectionspace/services/common/ResourceMap.java index 6d1ef8642..e74ed266d 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ResourceMap.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ResourceMap.java @@ -5,6 +5,6 @@ import java.util.Map; /* * Maps service names to Resource instances. Use the Service Client Class to get the service name. */ -public interface ResourceMap extends Map { +public interface ResourceMap extends Map { } diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java index e030f7439..3ab5372b2 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java @@ -24,8 +24,10 @@ package org.collectionspace.services.common.context; import java.lang.reflect.Constructor; + import javax.ws.rs.core.UriInfo; +import org.collectionspace.services.common.CollectionSpaceResource; import org.collectionspace.services.common.ResourceMap; import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.config.ConfigUtils; @@ -33,7 +35,6 @@ import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl; import org.collectionspace.services.common.security.UnauthorizedException; import org.collectionspace.services.config.service.ServiceBindingType; import org.collectionspace.services.config.tenant.TenantBindingType; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -173,6 +174,23 @@ public class RemoteServiceContextImpl this.output = output; } + /** + * Return the JAX-RS resource for the current context. + * + * @param ctx + * @return + * @throws Exception + */ + public CollectionSpaceResource getResource(ServiceContext ctx) throws Exception { + CollectionSpaceResource result = null; + + ResourceMap resourceMap = ctx.getResourceMap(); + String resourceName = ctx.getClient().getServiceName(); + result = resourceMap.get(resourceName); + + return result; + } + /** * @return the map of service names to resource classes. */ diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java index 0cb4cf8f2..d971c791b 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java @@ -30,6 +30,7 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriInfo; import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.common.CollectionSpaceResource; import org.collectionspace.services.common.ResourceMap; import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.document.ValidatorHandler; @@ -235,6 +236,11 @@ public interface ServiceContext { */ public void setOutput(OT output); + /** + * + */ + public CollectionSpaceResource getResource(); + /** * @return the map of service names to resource classes. */ diff --git a/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java b/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java index c65da9b96..696bc4641 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/common/workflow/service/nuxeo/WorkflowDocumentModelHandler.java @@ -71,7 +71,7 @@ public class WorkflowDocumentModelHandler DocumentModelHandler targetDocHandler = (DocumentModelHandler)ctx.getProperty(WorkflowClient.TARGET_DOCHANDLER); targetDocHandler.setRepositorySession(this.getRepositorySession()); // Make sure the target doc handler has a repository session to work with TransitionDef transitionDef = (TransitionDef)ctx.getProperty(WorkflowClient.TRANSITION_ID); - targetDocHandler.handleWorkflowTransition(wrapDoc, transitionDef); // Call the parent resouce's handler first + targetDocHandler.handleWorkflowTransition(wrapDoc, transitionDef); // Call the target resouce's handler first // // If no exception occurred, then call the super's method //