From: Ray Lee Date: Tue, 5 Nov 2019 23:51:22 +0000 (-0800) Subject: DRYD-748: Update MergeAuthorityItemsBatchJob to work in 5.2+, and to be invokable... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=21d3f1f64c7661b4f9d59becc73e60d156edceff;p=tmp%2Fjakarta-migration.git DRYD-748: Update MergeAuthorityItemsBatchJob to work in 5.2+, and to be invokable from the UI. --- diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/AbstractBatchInvocable.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/AbstractBatchInvocable.java index 92b9507de..961e806fc 100644 --- a/services/batch/service/src/main/java/org/collectionspace/services/batch/AbstractBatchInvocable.java +++ b/services/batch/service/src/main/java/org/collectionspace/services/batch/AbstractBatchInvocable.java @@ -38,7 +38,7 @@ public abstract class AbstractBatchInvocable implements BatchInvocable { public final int INT_ERROR_STATUS = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); protected final String CSID_VALUES_NOT_PROVIDED_IN_INVOCATION_CONTEXT = "Could not find required CSID values in the invocation context for this batch job."; - + private ServiceContext ctx; private List invocationModes; private ResourceMap resourceMap; @@ -83,37 +83,37 @@ public abstract class AbstractBatchInvocable implements BatchInvocable { public void setServiceContext(ServiceContext context) { this.ctx = context; } - + @Override public ServiceContext getServiceContext() { return ctx; } - + @Override public CoreSessionInterface getRepoSession() { CoreSessionInterface result = null; - + if (ctx != null) { result = (CoreSessionInterface) ctx.getCurrentRepositorySession(); } else { - logger.error(String.format("Batch job '%s' invoked with a null/empty service context.", + logger.error(String.format("Batch job '%s' invoked with a null/empty service context.", this.getClass().getName())); } - + return result; } - - @Override + + @Override public String getTenantId() { String result = null; - + if (ctx != null) { result = ctx.getTenantId(); } else { - logger.error(String.format("Batch job '%s' invoked with a null/empty service context.", + logger.error(String.format("Batch job '%s' invoked with a null/empty service context.", this.getClass().getName())); } - + return result; } @@ -170,6 +170,10 @@ public abstract class AbstractBatchInvocable implements BatchInvocable { return (INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(getInvocationContext().getMode()) ? true : false); } + protected String getSingleCsid() { + return this.getInvocationContext().getSingleCSID(); + } + protected List getListCsids() { List emptyCsidsList = Collections.emptyList(); InvocationContext.ListCSIDs lcsids = getInvocationContext().getListCSIDs(); @@ -200,6 +204,10 @@ public abstract class AbstractBatchInvocable implements BatchInvocable { } } + protected String getDocType() { + return this.getInvocationContext().getDocType(); + } + protected void setErrorResult(String message) { setErrorResult(message, INT_ERROR_STATUS); } diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/AbstractBatchJob.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/AbstractBatchJob.java index a9b9af5f4..625476517 100644 --- a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/AbstractBatchJob.java +++ b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/AbstractBatchJob.java @@ -28,6 +28,7 @@ import org.collectionspace.services.client.RelationClient; import org.collectionspace.services.client.TaxonomyAuthorityClient; import org.collectionspace.services.client.workflow.WorkflowClient; import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants; +import org.collectionspace.services.common.CollectionSpaceResource; import org.collectionspace.services.common.NuxeoBasedResource; import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.UriTemplateRegistry; @@ -56,27 +57,27 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { final Logger logger = LoggerFactory.getLogger(AbstractBatchJob.class); private Map authorityServiceNamesByDocType; - + protected String getFieldXml(Map fields, String fieldName) { return getFieldXml(fieldName, fields.get(fieldName)); } protected String getFieldXml(Map fields) { StringBuffer xmlBuffer = new StringBuffer(); - + for (String fieldName : fields.keySet()) { xmlBuffer.append(getFieldXml(fields, fieldName)); } - + return xmlBuffer.toString(); } - + protected String getFieldXml(String fieldName, String fieldValue) { String xml = "<" + fieldName + ">" + (fieldValue == null ? "" : StringEscapeUtils.escapeXml(fieldValue)) + ""; - + return xml; } - + protected String createRelation(String subjectCsid, String subjectDocType, String objectCsid, String objectDocType, String relationshipType) throws ResourceException { String relationCsid = null; @@ -108,7 +109,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { /** * Return related records, based on the supplied search criteria. Soft-deleted relations * are filtered from the list, but soft-deleted subject/object records are not. - * + * * @param subjectCsid The csid of the subject record. If null or empty, match any subject. * @param subjectDocType The document type of the subject record. If null or empty, match any subject type. * @param predicate The predicate of the relation. If null or empty, match any predicate. @@ -123,14 +124,14 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { return relationList.getRelationListItem(); } - + protected List findRelatedObjects(String subjectCsid, String subjectDocType, String predicate, String objectCsid, String objectDocType) throws URISyntaxException { List csids = new ArrayList(); for (RelationsCommonList.RelationListItem item : findRelated(subjectCsid, subjectDocType, predicate, objectCsid, objectDocType)) { csids.add(item.getObjectCsid()); } - + return csids; } @@ -140,7 +141,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { for (RelationsCommonList.RelationListItem item : findRelated(subjectCsid, subjectDocType, predicate, objectCsid, objectDocType)) { csids.add(item.getSubjectCsid()); } - + return csids; } @@ -157,7 +158,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { // There should be only one broader object. String broader = relatedObjects.size() > 0 ? relatedObjects.get(0) : null; - + return broader; } @@ -168,7 +169,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { /** * Returns the movement record related to the specified record, if there is only one. * Returns null if there are zero or more than one related movement records. - * + * * @param subjectCsid The csid of the record * @return * @throws URISyntaxException @@ -177,16 +178,16 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { protected String findSingleRelatedMovement(String subjectCsid) throws URISyntaxException, DocumentException { String foundMovementCsid = null; List movementCsids = findRelatedMovements(subjectCsid); - + for (String movementCsid : movementCsids) { PoxPayloadOut movementPayload = findMovementByCsid(movementCsid); String movementWorkflowState = getFieldValue(movementPayload, CollectionSpaceClient.COLLECTIONSPACE_CORE_SCHEMA, CollectionSpaceClient.COLLECTIONSPACE_CORE_WORKFLOWSTATE); - + if (!movementWorkflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)) { if (foundMovementCsid != null) { return null; } - + foundMovementCsid = movementCsid; } } @@ -197,11 +198,11 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { protected PoxPayloadOut findByUri(String uri) throws URISyntaxException, DocumentException { PoxPayloadOut payload = null; String[] uriParts = uri.split("/"); - + if (uriParts.length == 3) { String serviceName = uriParts[1]; String csid = uriParts[2]; - + payload = findByCsid(serviceName, csid); } else if (uriParts.length == 5) { @@ -209,7 +210,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { String vocabularyCsid = uriParts[2]; String items = uriParts[3]; String csid = uriParts[4]; - + if (items.equals("items")) { payload = findAuthorityItemByCsid(serviceName, vocabularyCsid, csid); } @@ -234,17 +235,17 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { protected PoxPayloadOut findMovementByCsid(String csid) throws URISyntaxException, DocumentException { return findByCsid(MovementClient.SERVICE_NAME, csid); } - + protected List findAll(String serviceName, int pageSize, int pageNum) throws URISyntaxException, DocumentException { return findAll(serviceName, pageSize, pageNum, null); } - + protected List findAll(String serviceName, int pageSize, int pageNum, String sortBy) throws URISyntaxException, DocumentException { - NuxeoBasedResource resource = (NuxeoBasedResource) getResourceMap().get(serviceName); + NuxeoBasedResource resource = (NuxeoBasedResource) getResourceMap().get(serviceName); return findAll(resource, pageSize, pageNum, null); } - + protected List findAll(NuxeoBasedResource resource, int pageSize, int pageNum, String sortBy) throws URISyntaxException, DocumentException { AbstractCommonList list = resource.getList(createPagedListUriInfo(resource.getServiceName(), pageNum, pageSize, sortBy)); List csids = new ArrayList(); @@ -257,7 +258,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { else { for (AbstractCommonList.ListItem item : list.getListItem()) { for (org.w3c.dom.Element element : item.getAny()) { - + if (element.getTagName().equals("csid")) { csids.add(element.getTextContent()); break; @@ -265,14 +266,14 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { } } } - + return csids; - } - + } + protected List findAllCollectionObjects(int pageSize, int pageNum) throws URISyntaxException, DocumentException { return findAll(CollectionObjectClient.SERVICE_NAME, pageSize, pageNum); } - + protected List getVocabularyCsids(String serviceName) throws URISyntaxException { AuthorityResource resource = (AuthorityResource) getResourceMap().get(serviceName); @@ -282,7 +283,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { protected List getVocabularyCsids(AuthorityResource resource) throws URISyntaxException { AbstractCommonList vocabularyList = resource.getAuthorityList(createDeleteFilterUriInfo()); List csids = new ArrayList(); - + for (AbstractCommonList.ListItem item : vocabularyList.getListItem()) { for (org.w3c.dom.Element element : item.getAny()) { if (element.getTagName().equals("csid")) { @@ -294,110 +295,110 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { return csids; } - + protected List findAllAuthorityItems(String serviceName, String vocabularyCsid, int pageSize, int pageNum) throws URISyntaxException, DocumentException { return findAllAuthorityItems(serviceName, vocabularyCsid, pageSize, pageNum, null); } - + protected List findAllAuthorityItems(String serviceName, String vocabularyCsid, int pageSize, int pageNum, String sortBy) throws URISyntaxException, DocumentException { AuthorityResource resource = (AuthorityResource) getResourceMap().get(serviceName); return findAllAuthorityItems(resource, vocabularyCsid, pageSize, pageNum, sortBy); } - + protected List findAllAuthorityItems(AuthorityResource resource, String vocabularyCsid, int pageSize, int pageNum, String sortBy) throws URISyntaxException, DocumentException { AbstractCommonList list = resource.getAuthorityItemList(vocabularyCsid, createPagedListUriInfo(resource.getServiceName(), pageNum, pageSize, sortBy)); - List csids = new ArrayList(); - + List csids = new ArrayList(); + for (AbstractCommonList.ListItem item : list.getListItem()) { for (org.w3c.dom.Element element : item.getAny()) { - + if (element.getTagName().equals("csid")) { csids.add(element.getTextContent()); break; } } } - + return csids; - } - + } + protected PoxPayloadOut findAuthorityItemByCsid(String serviceName, String csid) throws URISyntaxException, DocumentException { List vocabularyCsids = getVocabularyCsids(serviceName); PoxPayloadOut itemPayload = null; - + for (String vocabularyCsid : vocabularyCsids) { logger.debug("vocabularyCsid=" + vocabularyCsid); - + // FIXME: This throws DocumentNotFoundException, so will never go to the next vocabulary itemPayload = findAuthorityItemByCsid(serviceName, vocabularyCsid, csid); - + if (itemPayload != null) { break; } } - + return itemPayload; } - + protected PoxPayloadOut findAuthorityItemByCsid(String serviceName, String vocabularyCsid, String csid) throws URISyntaxException, DocumentException { AuthorityResource resource = (AuthorityResource) getResourceMap().get(serviceName); byte[] response = resource.getAuthorityItem(null, createDeleteFilterUriInfo(), getResourceMap(), vocabularyCsid, csid); - + PoxPayloadOut payload = new PoxPayloadOut(response); return payload; } - + protected String getAuthorityServiceNameForDocType(String authorityDocType) { if (authorityServiceNamesByDocType == null) { authorityServiceNamesByDocType = new HashMap(); - + for (String serviceName : getResourceMap().keySet()) { - AuthorityResource resource = (AuthorityResource) getResourceMap().get(serviceName); - + CollectionSpaceResource resource = (CollectionSpaceResource) getResourceMap().get(serviceName); + if (resource instanceof AuthorityResource) { AuthorityResource authorityResource = (AuthorityResource) resource; String docType = authorityResource.getItemDocType(getTenantId()); - + authorityServiceNamesByDocType.put(docType, serviceName); } } } - + return authorityServiceNamesByDocType.get(authorityDocType); } - + protected PoxPayloadOut findTaxonByCsid(String csid) throws URISyntaxException, DocumentException { return findAuthorityItemByCsid(TaxonomyAuthorityClient.SERVICE_NAME, csid); } - + protected PoxPayloadOut findAuthorityItemByShortId(String serviceName, String vocabularyShortId, String itemShortId) throws URISyntaxException, DocumentException { AuthorityResource resource = (AuthorityResource) getResourceMap().get(serviceName); byte[] response = resource.getAuthorityItem(null, createDeleteFilterUriInfo(), getResourceMap(), "urn:cspace:name(" + vocabularyShortId + ")", "urn:cspace:name(" + itemShortId + ")"); - + PoxPayloadOut payload = new PoxPayloadOut(response); return payload; } - + protected PoxPayloadOut findAuthorityItemByRefName(String serviceName, String refName) throws URISyntaxException, DocumentException { RefName.AuthorityItem item = RefName.AuthorityItem.parse(refName); - + String vocabularyShortId = item.getParentShortIdentifier(); String itemShortId = item.getShortIdentifier(); - + return findAuthorityItemByShortId(serviceName, vocabularyShortId, itemShortId); } protected PoxPayloadOut findPlaceByRefName(String refName) throws URISyntaxException, DocumentException { return findAuthorityItemByRefName(PlaceAuthorityClient.SERVICE_NAME, refName); } - + protected PoxPayloadOut findTaxonByRefName(String refName) throws URISyntaxException, DocumentException { return findAuthorityItemByRefName(TaxonomyAuthorityClient.SERVICE_NAME, refName); } - + protected List findReferencingFields(String serviceName, String parentCsid, String csid, String type, int pageNum, int pageSize) throws URISyntaxException { AuthorityResource resource = (AuthorityResource) getResourceMap().get(serviceName); @@ -405,15 +406,15 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { // More items than the pageSize might be returned, and the next page may // contain repeats of items already returned on the previous page. Any // code that uses this function should be aware of this. - + AuthorityRefDocList refDocList = resource.getReferencingObjects(parentCsid, csid, createRefSearchFilterUriInfo(type, pageNum, pageSize)); - + return refDocList.getAuthorityRefDocItem(); } /** * Finds records that reference a given authority item. Soft-deleted records are not included. - * + * * @param serviceName The name of the authority service, e.g. "personauthorities" * @param parentCsid The csid of the authority instance (aka vocabulary). This may be a guid or a urn, * e.g. "7a4981c4-77b7-433b-8086", "urn:cspace:name(person)" @@ -435,14 +436,14 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { List items = findReferencingFields(serviceName, parentCsid, csid, type, 0, 0); List csids = new ArrayList(); - + for (AuthorityRefDocList.AuthorityRefDocItem item : items) { /* * If a multivalue field contains a reference to the object multiple times, the referencing object * seems to get returned multiple times in the list, but only the first has a non-null workflow state. * A bug? Handle this by discarding list items with a null workflow state. */ - + if (item.getWorkflowState() != null && !item.getWorkflowState().equals(WorkflowClient.WORKFLOWSTATE_DELETED) && (sourceField == null || item.getSourceField().equals(sourceField))) { csids.add(item.getDocId()); } @@ -450,27 +451,27 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { return csids; } - + protected List findReferencingObjects(String serviceName, String csid, String type, String sourceField) throws URISyntaxException, DocumentException { logger.debug("findReferencingObjects serviceName=" + serviceName + " csid=" + csid + " type=" + type + " sourceField=" + sourceField); List vocabularyCsids = getVocabularyCsids(serviceName); String parentCsid = null; - + if (vocabularyCsids.size() == 1) { parentCsid = vocabularyCsids.get(0); } else { for (String vocabularyCsid : vocabularyCsids) { PoxPayloadOut itemPayload = findAuthorityItemByCsid(serviceName, vocabularyCsid, csid); - + if (itemPayload != null) { parentCsid = vocabularyCsid; break; } } } - + return findReferencingObjects(serviceName, parentCsid, csid, type, sourceField); } @@ -481,29 +482,36 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { protected List findReferencingCollectionObjects(String serviceName, String vocabularyShortId, String csid, String sourceField) throws URISyntaxException, DocumentException { return findReferencingObjects(serviceName, "urn:cspace:name(" + vocabularyShortId + ")", csid, ServiceBindingUtils.SERVICE_TYPE_OBJECT, sourceField); } - + /** * Create a stub UriInfo - * - * @throws URISyntaxException + * + * @throws URISyntaxException */ protected UriInfo createUriInfo() throws URISyntaxException { return createUriInfo(""); } protected UriInfo createUriInfo(String queryString) throws URISyntaxException { - return createUriInfo(queryString, Collections. emptyList()); + List pathSegments = new ArrayList(); + + // Some code in services assumes pathSegments will have at least one element, + // so add an empty one. + + pathSegments.add(new PathSegmentImpl("", false)); + + return createUriInfo(queryString, pathSegments); } - + protected UriInfo createUriInfo(String queryString, List pathSegments) throws URISyntaxException { queryString = escapeQueryString(queryString); - + URI absolutePath = new URI(""); URI baseUri = new URI(""); return new UriInfoImpl(absolutePath, baseUri, "", queryString, pathSegments); } - + protected UriInfo createDeleteFilterUriInfo() throws URISyntaxException { return createUriInfo("wf_deleted=false&pgSz=0"); } @@ -514,7 +522,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { protected UriInfo createRelationSearchUriInfo(String subjectCsid, String subjectDocType, String predicate, String objectCsid, String objectDocType) throws URISyntaxException { List queryParams = new ArrayList(6); - + if (StringUtils.isNotEmpty(subjectCsid)) { queryParams.add(IRelationsManager.SUBJECT_QP + "=" + subjectCsid); } @@ -530,39 +538,39 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { if (StringUtils.isNotEmpty(objectCsid)) { queryParams.add(IRelationsManager.OBJECT_QP + "=" + objectCsid); } - + if (StringUtils.isNotEmpty(objectDocType)) { queryParams.add(IRelationsManager.OBJECT_TYPE_QP + "=" + objectDocType); } - + queryParams.add("wf_deleted=false"); queryParams.add("pgSz=0"); - + return createUriInfo(StringUtils.join(queryParams, "&")); } - + protected UriInfo createRefSearchFilterUriInfo(String type) throws URISyntaxException { return createRefSearchFilterUriInfo(type, 1, 0); } protected UriInfo createRefSearchFilterUriInfo(String type, int pageNum, int pageSize) throws URISyntaxException { String queryString = "wf_deleted=false&pgSz=" + pageSize + "&pgNum=" + pageNum; - + if (type != null) { queryString = "type=" + type + "&" + queryString; } - + return createUriInfo(queryString); } protected UriInfo createPagedListUriInfo(String serviceName, int pageNum, int pageSize) throws URISyntaxException { return createPagedListUriInfo(serviceName, pageNum, pageSize, null); } - + protected UriInfo createPagedListUriInfo(String serviceName, int pageNum, int pageSize, String sortBy) throws URISyntaxException { List pathSegments = new ArrayList(1); pathSegments.add(new PathSegmentImpl(serviceName, false)); - + return createUriInfo("pgSz=" + pageSize + "&pgNum=" + pageNum + (sortBy != null ? "&sortBy=" + sortBy : "") + "&wf_deleted=false", pathSegments); } @@ -571,7 +579,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { return uri.getRawQuery(); } - + /** * Get a field value from a PoxPayloadOut, given a part name and xpath expression. */ @@ -590,7 +598,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { return value; } - + protected String getFieldValue(PoxPayloadOut payload, String fieldPath) { String value = null; @@ -603,16 +611,16 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { break; } } - + return value; } protected boolean getBooleanFieldValue(PoxPayloadOut payload, String partLabel, String fieldPath) { String value = getFieldValue(payload, partLabel, fieldPath); - + return (value != null && value.equals("true")); } - + protected List getFieldValues(PoxPayloadOut payload, String partLabel, String fieldPath) { List values = new ArrayList(); PayloadOutputPart part = payload.getPart(partLabel); @@ -630,18 +638,18 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { return values; } - + protected String getDisplayNameFromRefName(String refName) { RefName.AuthorityItem item = RefName.AuthorityItem.parse(refName); return (item == null ? refName : item.displayName); } - + protected String getCsid(PoxPayloadOut payload) { String uri = getFieldValue(payload, CollectionSpaceClient.COLLECTIONSPACE_CORE_SCHEMA, CollectionSpaceClient.COLLECTIONSPACE_CORE_URI); String[] elements = StringUtils.split(uri, '/'); String csid = elements[elements.length - 1]; - + return csid; } @@ -653,7 +661,7 @@ public abstract class AbstractBatchJob extends AbstractBatchInvocable { private static final long serialVersionUID = 1L; private Response response; - + public ResourceException(Response response, String message) { super(message); this.setResponse(response); diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/MergeAuthorityItemsBatchJob.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/MergeAuthorityItemsBatchJob.java index ece795a6f..9778e13b7 100644 --- a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/MergeAuthorityItemsBatchJob.java +++ b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/MergeAuthorityItemsBatchJob.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -73,9 +74,19 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { setCompletionStatus(STATUS_MIN_PROGRESS); try { - String docType = null; - String targetCsid = null; - List sourceCsids = new ArrayList(); + String target = null; + Set sourceCsids = new LinkedHashSet(); + String docType = this.getDocType(); + + if (this.requestIsForInvocationModeSingle()) { + String singleCsid = this.getSingleCsid(); + + if (singleCsid != null) { + sourceCsids.add(singleCsid); + } + } else if (this.requestIsForInvocationModeList()) { + sourceCsids.addAll(this.getListCsids()); + } for (Param param : this.getParams()) { String key = param.getKey(); @@ -88,27 +99,26 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { if (key.equals("docType")) { docType = param.getValue(); } + else if (key.equals("target")) { + target = param.getValue(); + } else if (key.equals("targetCSID")) { - targetCsid = param.getValue(); + target = param.getValue(); } else if (key.equals("sourceCSID")) { sourceCsids.add(param.getValue()); } } - if (docType == null || docType.equals("")) { - throw new Exception("a docType must be supplied"); - } - - if (targetCsid == null || targetCsid.equals("")) { - throw new Exception("a target csid parameter (targetCSID) must be supplied"); + if (target == null || target.equals("")) { + throw new Exception("a target or targetCSID parameter must be supplied"); } if (sourceCsids.size() == 0) { throw new Exception("a source csid must be supplied"); } - InvocationResults results = merge(docType, targetCsid, sourceCsids); + InvocationResults results = merge(docType, target, sourceCsids); setResults(results); setCompletionStatus(STATUS_COMPLETE); @@ -119,16 +129,19 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { } } - public InvocationResults merge(String docType, String targetCsid, String sourceCsid) throws URISyntaxException, DocumentException { - return merge(docType, targetCsid, Arrays.asList(sourceCsid)); + public InvocationResults merge(String docType, String target, String sourceCsid) throws URISyntaxException, DocumentException { + return merge(docType, target, new LinkedHashSet(Arrays.asList(sourceCsid))); } - public InvocationResults merge(String docType, String targetCsid, List sourceCsids) throws URISyntaxException, DocumentException { - logger.debug("Merging docType=" + docType + " targetCsid=" + targetCsid + " sourceCsids=" + StringUtils.join(sourceCsids, ",")); + public InvocationResults merge(String docType, String target, Set sourceCsids) throws URISyntaxException, DocumentException { + logger.debug("Merging docType=" + docType + " target=" + target + " sourceCsids=" + StringUtils.join(sourceCsids, ",")); String serviceName = getAuthorityServiceNameForDocType(docType); - PoxPayloadOut targetItemPayload = findAuthorityItemByCsid(serviceName, targetCsid); + PoxPayloadOut targetItemPayload = RefNameUtils.isTermRefname(target) + ? findAuthorityItemByRefName(serviceName, target) + : findAuthorityItemByCsid(serviceName, target); + List sourceItemPayloads = new ArrayList(); for (String sourceCsid : sourceCsids) { @@ -169,7 +182,9 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { updateAuthorityItem(docType, inAuthority, targetCsid, getUpdatePayload(targetTermGroupListElement, mergedTermGroupListElement)); - userNotes.add("The target record with CSID " + targetCsid + " (" + targetRefName + ") was updated."); + String targetDisplayName = RefNameUtils.getDisplayName(targetRefName); + + userNotes.add("Updated the target record, " + targetDisplayName + "."); numAffected++; String serviceName = getAuthorityServiceNameForDocType(docType); @@ -192,7 +207,7 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { String sourceCsid = getCsid(sourceItemPayload); String sourceRefName = getRefName(sourceItemPayload); - InvocationResults results = deleteAuthorityItem(docType, getFieldValue(sourceItemPayload, "inAuthority"), sourceCsid); + InvocationResults results = deleteAuthorityItem(docType, getFieldValue(sourceItemPayload, "inAuthority"), sourceCsid, sourceRefName); userNotes.add(results.getUserNote()); numAffected += results.getNumAffected(); @@ -208,6 +223,8 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { private InvocationResults updateReferences(String serviceName, String inAuthority, String sourceCsid, String sourceRefName, String targetRefName) throws URISyntaxException, DocumentException { logger.debug("Updating references: serviceName=" + serviceName + " inAuthority=" + inAuthority + " sourceCsid=" + sourceCsid + " sourceRefName=" + sourceRefName + " targetRefName=" + targetRefName); + String sourceDisplayName = RefNameUtils.getDisplayName(sourceRefName); + int pageNum = 0; int pageSize = 100; List items; @@ -273,9 +290,18 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { InvocationResults results = new InvocationResults(); results.setNumAffected(numUpdated); - results.setUserNote(numUpdated > 0 ? - numUpdated + " records that referenced the source record with CSID " + sourceCsid + " were updated." : - "No records referenced the source record with CSID " + sourceCsid + "."); + + if (numUpdated > 0) { + results.setUserNote( + "Updated " + + numUpdated + + (numUpdated == 1 ? " record " : " records ") + + "that referenced the source record, " + + sourceDisplayName + "." + ); + } else { + results.setUserNote("No records referenced the source record, " + sourceDisplayName + "."); + } return results; } @@ -372,9 +398,10 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { resource.updateAuthorityItem(getResourceMap(), createUriInfo(), inAuthority, csid, payload); } - private InvocationResults deleteAuthorityItem(String docType, String inAuthority, String csid) throws URISyntaxException { + private InvocationResults deleteAuthorityItem(String docType, String inAuthority, String csid, String refName) throws URISyntaxException { int numAffected = 0; List userNotes = new ArrayList(); + String displayName = RefNameUtils.getDisplayName(refName); // If the item is the broader context of any items, warn and do nothing. @@ -383,26 +410,34 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { if (narrowerItemCsids.size() > 0) { logger.debug("Item " + csid + " has narrower items -- not deleting"); - userNotes.add("The source record with CSID " + csid + " was not deleted because it has narrower context items."); + userNotes.add("The source record, " + displayName + ", was not deleted because it has narrower items in its hierarchy."); } else { // If the item has a broader context, delete the relation. - List relationCsids = new ArrayList(); + List relationItems = new ArrayList(); for (RelationsCommonList.RelationListItem item : findRelated(csid, null, "hasBroader", null, null)) { - relationCsids.add(item.getCsid()); + relationItems.add(item); } - if (relationCsids.size() > 0) { + if (relationItems.size() > 0) { RelationResource relationResource = (RelationResource) getResourceMap().get(RelationClient.SERVICE_NAME); - for (String relationCsid : relationCsids) { + for (RelationsCommonList.RelationListItem item : relationItems) { + String relationCsid = item.getCsid(); + + String subjectRefName = item.getSubject().getRefName(); + String subjectDisplayName = RefNameUtils.getDisplayName(subjectRefName); + + String objectRefName = item.getObject().getRefName(); + String objectDisplayName = RefNameUtils.getDisplayName(objectRefName); + logger.debug("Deleting hasBroader relation " + relationCsid); relationResource.delete(relationCsid); - userNotes.add("The broader relation with CSID " + relationCsid + " was deleted."); + userNotes.add("Deleted the \"has broader\" relation from " + subjectDisplayName + " to " + objectDisplayName + "."); numAffected++; } } @@ -414,7 +449,7 @@ public class MergeAuthorityItemsBatchJob extends AbstractBatchJob { resource.updateItemWorkflowWithTransition(null, inAuthority, csid, "delete"); - userNotes.add("The source record with CSID " + csid + " was soft deleted."); + userNotes.add("Deleted the source record, " + displayName + "."); numAffected++; }