From a56a31d95cf916c0c426a1c9f38622bbf8fac359 Mon Sep 17 00:00:00 2001 From: Richard Millet Date: Thu, 3 May 2012 14:50:12 -0700 Subject: [PATCH] CSPACE-5130: Finished most of the special case handling for the Vocabulary item schema. --- .../vocabulary/AuthorityItemJAXBSchema.java | 22 +-- .../AuthorityItemDocumentModelHandler.java | 125 ++++++++++-------- .../java/RemoteDocumentModelHandlerImpl.java | 96 ++++++++------ services/vocabulary/service/pom.xml | 6 +- .../VocabularyItemDocumentModelHandler.java | 41 ++++++ 5 files changed, 180 insertions(+), 110 deletions(-) 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 6c01bb5e7..e5e47982e 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 @@ -25,24 +25,24 @@ package org.collectionspace.services.common.vocabulary; /** * @author pschmitz - * + * */ public interface AuthorityItemJAXBSchema { - final static String IN_AUTHORITY = "inAuthority"; + final static String IN_AUTHORITY = "inAuthority"; final static String REF_NAME = "refName"; final static String ORDER = "order"; final static String SHORT_IDENTIFIER = "shortIdentifier"; final static String CSID = "csid"; - final static String TERM_DISPLAY_NAME = "termDisplayName"; - final static String TERM_NAME = "termName"; - final static String TERM_STATUS = "termStatus"; - final static String TERM_INFO_GROUP_SCHEMA_NAME = ""; //FIXME: REM - Needs to be defined. - // CSPACE-4813 - Remove all the below values and recompile all authorityitem related classes - final static String DISPLAY_NAME = "displayName"; + 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"; + final static String TERM_NAME = "termName"; + final static String TERM_STATUS = "termStatus"; + final static String TERM_INFO_GROUP_SCHEMA_NAME = ""; // FIXME: REM - Needs + // to be defined. + // CSPACE-4813 - Remove all the below values and recompile all authorityitem + // related classes final static String DISPLAY_NAME_COMPUTED = "displayNameComputed"; final static String SHORT_DISPLAY_NAME = "shortDisplayName"; final static String SHORT_DISPLAY_NAME_COMPUTED = "shortDisplayNameComputed"; - //final static String TERM_STATUS = "termStatus"; + // final static String TERM_STATUS = "termStatus"; } - - 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 904a67307..7d894f58c 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 @@ -140,6 +140,25 @@ public abstract class AuthorityItemDocumentModelHandler this.authorityRefNameBase = value; } + /* + * Note that the Vocabulary service's item-documentmodel-handler will override this method. + */ + protected ListResultField getListResultField() { + ListResultField result = new ListResultField(); + // Per CSPACE-5132, the name of this element remains 'displayName' + // for backwards compatibility, although its value is obtained + // from the termDisplayName field. + // + // In CSPACE-5134, these list results will change substantially + // to return display names for both the preferred term and for + // each non-preferred term (if any). + result.setElement(AuthorityItemJAXBSchema.DISPLAY_NAME); + result.setXpath(NuxeoUtils.getPrimaryXPathPropertyName( + authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_DISPLAY_NAME)); + + return result; + } + @Override public List getListItemsArray() throws DocumentException { List list = super.getListItemsArray(); @@ -154,7 +173,7 @@ public abstract class AuthorityItemDocumentModelHandler for (int i = 0; i < nFields; i++) { ListResultField field = list.get(i); String elName = field.getElement(); - if (AuthorityItemJAXBSchema.TERM_DISPLAY_NAME.equals(elName)) { //FIXME: Add a special if-case for Vocabulary item's displayName + if (AuthorityItemJAXBSchema.TERM_DISPLAY_NAME.equals(elName) || AuthorityItemJAXBSchema.DISPLAY_NAME.equals(elName)) { hasDisplayName = true; } else if (AuthorityItemJAXBSchema.SHORT_IDENTIFIER.equals(elName)) { hasShortId = true; @@ -166,17 +185,7 @@ public abstract class AuthorityItemDocumentModelHandler } ListResultField field; if (!hasDisplayName) { - field = new ListResultField(); - // Per CSPACE-5132, the name of this element remains 'displayName' //FIXME: Add a special case again for Vocab item's displayName - // for backwards compatibility, although its value is obtained - // from the termDisplayName field. - // - // In CSPACE-5134, these list results will change substantially - // to return display names for both the preferred term and for - // each non-preferred term (if any). - field.setElement(AuthorityItemJAXBSchema.DISPLAY_NAME); - field.setXpath(NuxeoUtils.getPrimaryXPathPropertyName( - authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_DISPLAY_NAME)); + field = getListResultField(); list.add(field); } if (!hasShortId) { @@ -198,8 +207,8 @@ public abstract class AuthorityItemDocumentModelHandler authorityItemCommonSchemaName, getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_STATUS)); list.add(field); } + return list; - } @@ -212,17 +221,6 @@ public abstract class AuthorityItemDocumentModelHandler super.handleCreate(wrapDoc); // Ensure we have required fields set properly handleInAuthority(wrapDoc.getWrappedObject()); - - // CSPACE-4813 - /* - handleComputedDisplayNames(wrapDoc.getWrappedObject()); - String displayName = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName, - AuthorityItemJAXBSchema.DISPLAY_NAME); - if (Tools.isEmpty(displayName)) { - logger.warn("Creating Authority Item with no displayName!"); - } - * - */ // CSPACE-3178: // handleDisplayNameAsShortIdentifier(wrapDoc.getWrappedObject(), authorityItemCommonSchemaName); @@ -230,6 +228,18 @@ public abstract class AuthorityItemDocumentModelHandler updateRefnameForAuthorityItem(wrapDoc, authorityItemCommonSchemaName, getAuthorityRefNameBase()); } + /* + * Note that the Vocabulary service's document-model for items overrides this method. + */ + protected String getPrimaryDisplayName(DocumentModel docModel, String schema, + String complexPropertyName, String fieldName) { + String result = null; + + result = getStringValueInPrimaryRepeatingComplexProperty(docModel, schema, complexPropertyName, fieldName); + + return result; + } + /* (non-Javadoc) * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#handleUpdate(org.collectionspace.services.common.document.DocumentWrapper) */ @@ -238,18 +248,14 @@ public abstract class AuthorityItemDocumentModelHandler // First, get a copy of the old displayName // oldDisplayNameOnUpdate = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName, // AuthorityItemJAXBSchema.DISPLAY_NAME); - oldDisplayNameOnUpdate = (String) getStringValueInPrimaryRepeatingComplexProperty( //FIXME - This won't work for vocabulary items - wrapDoc.getWrappedObject(), authorityItemCommonSchemaName, - getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + oldDisplayNameOnUpdate = getPrimaryDisplayName(wrapDoc.getWrappedObject(), authorityItemCommonSchemaName, + getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); oldRefNameOnUpdate = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REF_NAME); super.handleUpdate(wrapDoc); - // handleComputedDisplayNames(wrapDoc.getWrappedObject()); - // String newDisplayName = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName, - // AuthorityItemJAXBSchema.DISPLAY_NAME); - String newDisplayName = (String) getStringValueInPrimaryRepeatingComplexProperty( //FIXME - This won't work for vocabulary items - wrapDoc.getWrappedObject(), authorityItemCommonSchemaName, + + // Now, check the new display and handle the refname update. + String newDisplayName = (String) getPrimaryDisplayName(wrapDoc.getWrappedObject(), authorityItemCommonSchemaName, this.authorityItemTermGroupXPathBase, AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); if (newDisplayName != null && !newDisplayName.equals(oldDisplayNameOnUpdate)) { @@ -328,24 +334,28 @@ public abstract class AuthorityItemDocumentModelHandler * If no short identifier was provided in the input payload, generate a * short identifier from the preferred term display name or term name. */ - private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception { - String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER); - String termDisplayName = - (String) getStringValueInPrimaryRepeatingComplexProperty( //FIXME - This won't work for vocabulary items - docModel, authorityItemCommonSchemaName, - getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); - String termName = - (String) getStringValueInPrimaryRepeatingComplexProperty( //FIXME - This won't work for vocabulary items - docModel, authorityItemCommonSchemaName, - getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_NAME); - if (Tools.isEmpty(shortIdentifier)) { - String generatedShortIdentifier = - AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(termDisplayName, termName); - docModel.setProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER, generatedShortIdentifier); - } - } + private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, + String schemaName) throws Exception { + String shortIdentifier = (String) docModel.getProperty(schemaName, + AuthorityItemJAXBSchema.SHORT_IDENTIFIER); + + String termDisplayName = getPrimaryDisplayName( + docModel, authorityItemCommonSchemaName, + getItemTermInfoGroupXPathBase(), + AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + + String termName = getPrimaryDisplayName( + docModel, authorityItemCommonSchemaName, + getItemTermInfoGroupXPathBase(), + AuthorityItemJAXBSchema.TERM_NAME); + + if (Tools.isEmpty(shortIdentifier)) { + String generatedShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(termDisplayName, + termName); + docModel.setProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER, + generatedShortIdentifier); + } + } /** * Generate a refName for the authority item from the short identifier @@ -363,14 +373,13 @@ public abstract class AuthorityItemDocumentModelHandler String authorityRefBaseName) throws Exception { DocumentModel docModel = wrapDoc.getWrappedObject(); String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER); - String displayName = - (String) getStringValueInPrimaryRepeatingComplexProperty( //FIXME - This won't work for vocabulary items - docModel, authorityItemCommonSchemaName, - getItemTermInfoGroupXPathBase(), - AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + String displayName = getPrimaryDisplayName(docModel, authorityItemCommonSchemaName, + getItemTermInfoGroupXPathBase(), AuthorityItemJAXBSchema.TERM_DISPLAY_NAME); + if (Tools.isEmpty(authorityRefBaseName)) { throw new Exception("Could not create the refName for this authority term, because the refName for its authority parent was empty."); } + RefName.Authority authority = RefName.Authority.parse(authorityRefBaseName); String refName = RefName.buildAuthorityItem(authority, shortIdentifier, displayName).toString(); docModel.setProperty(schemaName, AuthorityItemJAXBSchema.REF_NAME, refName); @@ -1120,4 +1129,8 @@ public abstract class AuthorityItemDocumentModelHandler public void setItemTermInfoGroupXPathBase(String itemTermInfoGroupXPathBase) { this.authorityItemTermGroupXPathBase = itemTermInfoGroupXPathBase; } + + protected String getAuthorityItemCommonSchemaName() { + return authorityItemCommonSchemaName; + } } diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java index 95d82fb24..f05ee9a9f 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java @@ -671,17 +671,19 @@ public abstract class RemoteDocumentModelHandlerImpl * @param listName The name of the scalar list property * @return first value in list, as a String, or empty string if the list is empty */ - protected String getStringValueInPrimaryRepeatingComplexProperty( //FIXME - This won't work for vocabulary items - DocumentModel docModel, String schema, String complexPropertyName, String fieldName) { + protected String getStringValueInPrimaryRepeatingComplexProperty( + DocumentModel docModel, String schema, String complexPropertyName, String fieldName) { + String result = null; + String xpath = "/" + NuxeoUtils.getPrimaryXPathPropertyName(schema, complexPropertyName, fieldName); try { - return (String)docModel.getPropertyValue(xpath); + result = (String)docModel.getPropertyValue(xpath); } catch(PropertyException pe) { throw new RuntimeException("Problem retrieving property {"+xpath+"}. Bad propertyNames?" +pe.getLocalizedMessage()); } catch(IndexOutOfBoundsException ioobe) { // Nuxeo sometimes handles missing sub, and sometimes does not. Odd. - return ""; // gracefully handle missing elements + result = ""; // gracefully handle missing elements } catch(ClassCastException cce) { throw new RuntimeException("Problem retrieving property {"+xpath+"} as String. Not a String property?" +cce.getLocalizedMessage()); @@ -689,6 +691,8 @@ public abstract class RemoteDocumentModelHandlerImpl throw new RuntimeException("Unknown problem retrieving property {"+xpath+"}." +e.getLocalizedMessage()); } + + return result; } /** @@ -707,43 +711,51 @@ public abstract class RemoteDocumentModelHandlerImpl * @param xpath The XPath expression (without schema prefix) * @return value the indicated property value as a String */ - protected static String getXPathStringValue(DocumentModel docModel, String schema, String xpath) { - xpath = schema+":"+xpath; - try { - Object value = docModel.getPropertyValue(xpath); - String returnVal = null; - if(value==null) { - // Nothing to do - leave returnVal null - } else if(value instanceof GregorianCalendar) { - returnVal = DateTimeFormatUtils.formatAsISO8601Timestamp((GregorianCalendar)value); - } else { - returnVal = value.toString(); - } - return returnVal; - } catch(PropertyException pe) { - throw new RuntimeException("Problem retrieving property {"+xpath+"}. Bad XPath spec?" - +pe.getLocalizedMessage()); - } catch(ClassCastException cce) { - throw new RuntimeException("Problem retrieving property {"+xpath+"} as String. Not a String property?" - +cce.getLocalizedMessage()); - } catch(IndexOutOfBoundsException ioobe) { - // Nuxeo seems to handle foo/[0]/bar when it is missing, - // but not foo/bar[0] (for repeating scalars). - if(xpath.endsWith("[0]")) { // gracefully handle missing elements - return ""; - } else { - String msg = ioobe.getMessage(); - if(msg!=null && msg.equals("Index: 0, Size: 0")) { - // Some other variant on a missing sub-field; quietly absorb. - return ""; - } // Otherwise, e.g., for true OOB indices, propagate the exception. - } - throw new RuntimeException("Problem retrieving property {"+xpath+"}:" - +ioobe.getLocalizedMessage()); - } catch(Exception e) { - throw new RuntimeException("Unknown problem retrieving property {"+xpath+"}." - +e.getLocalizedMessage()); - } - } + protected static String getXPathStringValue(DocumentModel docModel, + String schema, String xpath) { + String result = null; + + xpath = schema + ":" + xpath; + try { + Object value = docModel.getPropertyValue(xpath); + String returnVal = null; + if (value == null) { + // Nothing to do - leave returnVal null + } else if (value instanceof GregorianCalendar) { + returnVal = DateTimeFormatUtils.formatAsISO8601Timestamp((GregorianCalendar) value); + } else { + returnVal = value.toString(); + } + result = returnVal; + } catch (PropertyException pe) { + throw new RuntimeException("Problem retrieving property {" + xpath + + "}. Bad XPath spec?" + pe.getLocalizedMessage()); + } catch (ClassCastException cce) { + throw new RuntimeException("Problem retrieving property {" + xpath + + "} as String. Not a String property?" + + cce.getLocalizedMessage()); + } catch (IndexOutOfBoundsException ioobe) { + // Nuxeo seems to handle foo/[0]/bar when it is missing, + // but not foo/bar[0] (for repeating scalars). + if (xpath.endsWith("[0]")) { // gracefully handle missing elements + result = ""; + } else { + String msg = ioobe.getMessage(); + if (msg != null && msg.equals("Index: 0, Size: 0")) { + // Some other variant on a missing sub-field; quietly + // absorb. + result = ""; + } // Otherwise, e.g., for true OOB indices, propagate the + // exception. + } + throw new RuntimeException("Problem retrieving property {" + xpath + + "}:" + ioobe.getLocalizedMessage()); + } catch (Exception e) { + throw new RuntimeException("Unknown problem retrieving property {" + + xpath + "}." + e.getLocalizedMessage()); + } + + return result; + } } diff --git a/services/vocabulary/service/pom.xml b/services/vocabulary/service/pom.xml index 05b700e8f..dcea97925 100644 --- a/services/vocabulary/service/pom.xml +++ b/services/vocabulary/service/pom.xml @@ -7,7 +7,6 @@ 4.0.0 - org.collectionspace.services org.collectionspace.services.vocabulary.service services.vocabulary.service jar @@ -27,6 +26,11 @@ org.collectionspace.services.common ${project.version} + + org.collectionspace.services + org.collectionspace.services.config + ${project.version} + org.collectionspace.services org.collectionspace.services.authority.service diff --git a/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyItemDocumentModelHandler.java b/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyItemDocumentModelHandler.java index c941ce5c5..dcd7f2bf6 100644 --- a/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyItemDocumentModelHandler.java +++ b/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyItemDocumentModelHandler.java @@ -25,8 +25,13 @@ package org.collectionspace.services.vocabulary.nuxeo; import org.collectionspace.services.client.VocabularyClient; import org.collectionspace.services.common.context.ServiceBindingUtils; +import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema; import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler; +import org.collectionspace.services.config.service.ListResultField; +import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.collectionspace.services.vocabulary.VocabularyitemsCommon; +import org.nuxeo.ecm.core.api.ClientException; +import org.nuxeo.ecm.core.api.DocumentModel; /** * VocabularyItemDocumentModelHandler @@ -62,5 +67,41 @@ public class VocabularyItemDocumentModelHandler public String getQProperty(String prop) { return VocabularyItemConstants.NUXEO_SCHEMA_NAME + ":" + prop; } + + /* + * Because the Vocabulary service's item schema is not standard, we need to override the default authority item schema behavior. + * (non-Javadoc) + * @see org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler#getPrimaryDisplayName(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, java.lang.String, java.lang.String) + */ + @Override + protected String getPrimaryDisplayName(DocumentModel docModel, + String schema, String complexPropertyName, String fieldName) { + String result = null; + + try { + result = (String) docModel.getProperty(schema, AuthorityItemJAXBSchema.DISPLAY_NAME); + } catch (Exception e) { + throw new RuntimeException("Unknown problem retrieving property {" + + schema + ":" + fieldName + "}." + e.getLocalizedMessage()); + } + + return result; + } + + /* + * Because the Vocabulary service's item schema is not standard, we need to override this method. + */ + @Override + protected ListResultField getListResultField() { + ListResultField result = new ListResultField(); + + result.setElement(AuthorityItemJAXBSchema.DISPLAY_NAME); + result.setXpath(NuxeoUtils.getPrimaryXPathPropertyName(this.getAuthorityItemCommonSchemaName(), + getItemTermInfoGroupXPathBase(), + AuthorityItemJAXBSchema.TERM_DISPLAY_NAME)); + + return result; + } + } -- 2.47.3