From d7009f4a9a65a4d5e408fb210860d364607f9073 Mon Sep 17 00:00:00 2001 From: Aron Roberts Date: Thu, 19 Jul 2012 11:43:34 -0700 Subject: [PATCH] CSPACE-5406: First pass at generating valid values in refObjs list items for authority item records that also contain authority references in their fields. --- .../vocabulary/RefNameServiceUtils.java | 20 ++++- .../services/common/config/URIUtils.java | 68 +++++++++++++++++ .../services/imports/TemplateExpander.java | 73 +++---------------- 3 files changed, 95 insertions(+), 66 deletions(-) create mode 100644 services/config/src/main/java/org/collectionspace/services/common/config/URIUtils.java diff --git a/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java b/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java index ac72506ee..e3bc6afd1 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java @@ -51,6 +51,7 @@ import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo; import org.collectionspace.services.common.authorityref.AuthorityRefDocList; import org.collectionspace.services.common.authorityref.AuthorityRefList; import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl; +import org.collectionspace.services.common.config.URIUtils; import org.collectionspace.services.common.context.ServiceBindingUtils; import org.collectionspace.services.common.document.DocumentException; import org.collectionspace.services.common.document.DocumentFilter; @@ -59,6 +60,7 @@ import org.collectionspace.services.common.document.DocumentUtils; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.query.QueryManager; import org.collectionspace.services.common.repository.RepositoryClient; +// import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema; import org.collectionspace.services.nuxeo.client.java.DocHandlerBase; import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl; import org.collectionspace.services.common.security.SecurityUtils; @@ -556,7 +558,6 @@ public class RefNameServiceUtils { throw new RuntimeException( "getAuthorityRefDocs: No Service Binding for docType: " + docType); } - String serviceContextPath = "/" + sb.getName().toLowerCase() + "/"; if (list == null) { // no list - should be update refName case. if (newAuthorityRefName == null) { @@ -570,7 +571,22 @@ public class RefNameServiceUtils { ilistItem = new AuthorityRefDocList.AuthorityRefDocItem(); String csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString()); ilistItem.setDocId(csid); - ilistItem.setUri(serviceContextPath + csid); + String uri = ""; + // FIXME: Hack for CSPACE-5406; this instead should use the (forthcoming) + // URL pattern-to-Doctype registry described in CSPACE-5471 - ADR 2012-07-18 + if (sb.getType().equalsIgnoreCase(URIUtils.AUTHORITY_SERVICE_CATEGORY)) { + String authoritySvcName = URIUtils.getAuthoritySvcName(docType); + String inAuthorityCsid; + try { + inAuthorityCsid = (String) docModel.getPropertyValue("inAuthority"); // AuthorityItemJAXBSchema.IN_AUTHORITY + uri = URIUtils.getAuthorityItemUri(authoritySvcName, inAuthorityCsid, csid); + } catch (Exception e) { + logger.warn("Could not extract inAuthority property from authority item record: " + e.getMessage()); + } + } else { + uri = URIUtils.getUri(sb.getName(), csid);; + } + ilistItem.setUri(uri); try { ilistItem.setWorkflowState(docModel.getCurrentLifeCycleState()); ilistItem.setUpdatedAt(DocHandlerBase.getUpdatedAtAsString(docModel)); diff --git a/services/config/src/main/java/org/collectionspace/services/common/config/URIUtils.java b/services/config/src/main/java/org/collectionspace/services/common/config/URIUtils.java new file mode 100644 index 000000000..94307f438 --- /dev/null +++ b/services/config/src/main/java/org/collectionspace/services/common/config/URIUtils.java @@ -0,0 +1,68 @@ +package org.collectionspace.services.common.config; + +// import org.collectionspace.services.client.AuthorityClient; +import java.util.HashMap; +import java.util.Map; + +// Hack for CSPACE-5 + +public class URIUtils { + + private static Map docTypeSvcNameRegistry = new HashMap(); + + // FIXME: This is a quick hack, which assumes that URI construction + // behaviors are bound to categories of services. Those behaviors + // should instead be specified on a per-service basis via a registry, + // the mechanism we are intending to use in v2.5. (See comments below + // for more details.) - ADR 2012-05-24 + public static final String AUTHORITY_SERVICE_CATEGORY = "authority"; + public static final String OBJECT_SERVICE_CATEGORY = "object"; + public static final String PROCEDURE_SERVICE_CATEGORY = "procedure"; + + // FIXME: This is a quick hack; a stub / mock of a registry of + // authority document types and their associated parent authority + // service names. This MUST be replaced by a more general mechanism + // in v2.5. + // + // Per Patrick, this registry needs to be available system-wide, not + // just here in the Imports service; extend to all relevant record types; + // and be automatically built in some manner, such as via per-resource + // registration, from configuration, etc. - ADR 2012-05-24 + private static Map getDocTypeSvcNameRegistry() { + if (docTypeSvcNameRegistry.isEmpty()) { + docTypeSvcNameRegistry.put("Conceptitem", "Conceptauthorities"); + docTypeSvcNameRegistry.put("Locationitem", "Locationauthorities"); + docTypeSvcNameRegistry.put("Person", "Personauthorities"); + docTypeSvcNameRegistry.put("Placeitem", "Placeauthorities"); + docTypeSvcNameRegistry.put("Organization", "Orgauthorities"); + docTypeSvcNameRegistry.put("Taxon", "Taxonomyauthority"); + } + return docTypeSvcNameRegistry; + } + + /** + * Return the parent authority service name, based on the item document + * type. + */ + public static String getAuthoritySvcName(String docType) { + return getDocTypeSvcNameRegistry().get(docType); + } + + // FIXME: The following URI construction methods are also intended to be + // made generally available and associated to individual services, via the + // registry mechanism described above. - ADR, 2012-05-24 + public static String getUri(String serviceName, String docID) { + return "/" + serviceName.toLowerCase() + + "/" + docID; + } + + public static String getAuthorityItemUri(String authorityServiceName, String inAuthorityID, String docID) { + return "/" + authorityServiceName.toLowerCase() + + '/' + inAuthorityID + + '/' + "items" // AuthorityClient.ITEMS + + '/' + docID; + } + + // FIXME: Create equivalent getUri-type method(s) for sub-resources, + // such as contacts - ADR, 2012-05-24 +} diff --git a/services/imports/service/src/main/java/org/collectionspace/services/imports/TemplateExpander.java b/services/imports/service/src/main/java/org/collectionspace/services/imports/TemplateExpander.java index e7c10a054..2ef9d3be6 100644 --- a/services/imports/service/src/main/java/org/collectionspace/services/imports/TemplateExpander.java +++ b/services/imports/service/src/main/java/org/collectionspace/services/imports/TemplateExpander.java @@ -32,7 +32,6 @@ import java.util.UUID; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import org.collectionspace.services.client.AuthorityClient; import org.collectionspace.services.common.IFragmentHandler; import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.XmlSaxFragmenter; @@ -40,6 +39,7 @@ import org.collectionspace.services.common.XmlTools; import org.collectionspace.services.common.api.FileTools; import org.collectionspace.services.common.api.Tools; import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl; +import org.collectionspace.services.common.config.URIUtils; import org.collectionspace.services.common.context.ServiceBindingUtils; import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils; import org.collectionspace.services.config.service.ServiceBindingType; @@ -64,7 +64,6 @@ public class TemplateExpander { private final static Logger logger = LoggerFactory.getLogger(TemplateExpander.class); private static final String DEFAULT_WRAPPER_TEMPLATE_FILENAME = "service-document.xml"; - private static Map docTypeSvcNameRegistry = new HashMap(); private static XPath xpath = XPathFactory.newInstance().newXPath(); // XPath expressions to match the value of the inAuthority field in authority item records. // The first expression matches namespace-qualified elements, while the second matches @@ -208,15 +207,7 @@ public class TemplateExpander { // document type name private static String getDocUri(String tenantId, String docType, String docID, String partTmpl) throws Exception { - - // FIXME: This is a quick hack, which assumes that URI construction - // behaviors are bound to categories of services. Those behaviors - // should instead be specified on a per-service basis via a registry, - // the mechanism we are intending to use in v2.5. (See comments below - // for more details.) - ADR 2012-05-24 - final String AUTHORITY_SERVICE_CATEGORY = "authority"; - final String OBJECT_SERVICE_CATEGORY = "object"; - final String PROCEDURE_SERVICE_CATEGORY = "procedure"; + TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance().getTenantBindingConfigReader(); // We may have been supplied with the tenant-qualified name @@ -228,17 +219,17 @@ public class TemplateExpander { String serviceCategory = sb.getType(); String uri = ""; - if (serviceCategory.equalsIgnoreCase(AUTHORITY_SERVICE_CATEGORY)) { - String authoritySvcName = getAuthoritySvcName(docType); + if (serviceCategory.equalsIgnoreCase(URIUtils.AUTHORITY_SERVICE_CATEGORY)) { + String authoritySvcName = URIUtils.getAuthoritySvcName(docType); if (authoritySvcName == null) { return uri; } String inAuthorityID = getInAuthorityValue(partTmpl); - uri = getAuthorityItemUri(authoritySvcName, inAuthorityID, docID); - } else if (serviceCategory.equalsIgnoreCase(OBJECT_SERVICE_CATEGORY) || - serviceCategory.equalsIgnoreCase(PROCEDURE_SERVICE_CATEGORY) ) { - String serviceName = sb.getName().toLowerCase(); - uri = getUri(serviceName, docID); + uri = URIUtils.getAuthorityItemUri(authoritySvcName, inAuthorityID, docID); + } else if (serviceCategory.equalsIgnoreCase(URIUtils.OBJECT_SERVICE_CATEGORY) || + serviceCategory.equalsIgnoreCase(URIUtils.PROCEDURE_SERVICE_CATEGORY) ) { + String serviceName = sb.getName(); + uri = URIUtils.getUri(serviceName, docID); } else { // Currently returns a blank URI for any other cases, // including sub-resources like contacts @@ -246,52 +237,6 @@ public class TemplateExpander { return uri; } - // FIXME: This is a quick hack; a stub / mock of a registry of - // authority document types and their associated parent authority - // service names. This MUST be replaced by a more general mechanism - // in v2.5. - // - // Per Patrick, this registry needs to be available system-wide, not - // just here in the Imports service; extend to all relevant record types; - // and be automatically built in some manner, such as via per-resource - // registration, from configuration, etc. - ADR 2012-05-24 - private static Map getDocTypeSvcNameRegistry() { - if (docTypeSvcNameRegistry.isEmpty()) { - docTypeSvcNameRegistry.put("Conceptitem", "Conceptauthorities"); - docTypeSvcNameRegistry.put("Locationitem", "Locationauthorities"); - docTypeSvcNameRegistry.put("Person", "Personauthorities"); - docTypeSvcNameRegistry.put("Placeitem", "Placeauthorities"); - docTypeSvcNameRegistry.put("Organization", "Orgauthorities"); - docTypeSvcNameRegistry.put("Taxon", "Taxonomyauthority"); - } - return docTypeSvcNameRegistry; - } - - /** - * Return the parent authority service name, based on the item document type. - */ - private static String getAuthoritySvcName(String docType) { - return getDocTypeSvcNameRegistry().get(docType); - } - - // FIXME: The following URI construction methods are also intended to be - // made generally available and associated to individual services, via the - // registry mechanism described above. - ADR, 2012-05-24 - private static String getUri(String serviceName, String docID) { - return "/" + serviceName - + "/" + docID; - } - - private static String getAuthorityItemUri(String authorityServiceName, String inAuthorityID, String docID) { - return "/" + authorityServiceName.toLowerCase() - + '/' + inAuthorityID - + '/' + AuthorityClient.ITEMS - + '/' + docID; - } - - // FIXME: Create equivalent getUri-type method(s) for sub-resources, - // such as contacts - ADR, 2012-05-24 - // FIXME: It may also be desirable to explicitly validate the format of // CSID values provided in fields such as inAuthority, and perhaps later on, // their uniqueness against those already present in a running system. -- 2.47.3