]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-1927 - Refactoring and adding detection of displayName and refName changes...
authorPatrick Schmitz <pschmitz@berkeley.edu>
Mon, 10 Oct 2011 23:14:28 +0000 (23:14 +0000)
committerPatrick Schmitz <pschmitz@berkeley.edu>
Mon, 10 Oct 2011 23:14:28 +0000 (23:14 +0000)
services/authority/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java
services/authority/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java
services/common-api/src/main/java/org/collectionspace/services/common/api/RefName.java

index 004785164344ba2f99fbcfb99ef777566c3fc66d..0731d476bd8ab4b7b690a3b130e37e3e66ba6666 100644 (file)
@@ -59,7 +59,7 @@ import org.collectionspace.services.nuxeo.util.NuxeoUtils;
  */\r
 public class RefNameServiceUtils {\r
 \r
-    private final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class);\r
+    private static final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class);\r
 \r
     public static AuthorityRefDocList getAuthorityRefDocs(ServiceContext ctx,\r
             RepositoryClient repoClient,\r
@@ -70,24 +70,52 @@ public class RefNameServiceUtils {
         AbstractCommonList commonList = (AbstractCommonList) wrapperList;\r
         commonList.setPageNum(pageNum);\r
         commonList.setPageSize(pageSize);\r
-\r
-        \r
         List<AuthorityRefDocList.AuthorityRefDocItem> list =\r
                 wrapperList.getAuthorityRefDocItem();\r
+\r
+        // Get the service bindings for this tenant\r
         TenantBindingConfigReaderImpl tReader =\r
                 ServiceMain.getInstance().getTenantBindingConfigReader();\r
         List<ServiceBindingType> servicebindings = tReader.getServiceBindingsByType(ctx.getTenantId(), serviceType);\r
         if (servicebindings == null || servicebindings.isEmpty()) {\r
+               logger.error("RefNameServiceUtils.getAuthorityRefDocs: No services bindings found, cannot proceed!");\r
             return null;\r
         }\r
+        \r
         // Need to escape the quotes in the refName\r
         // TODO What if they are already escaped?\r
         String escapedRefName = refName.replaceAll("'", "\\\\'");\r
-//     String domain = \r
-//             tReader.getTenantBinding(ctx.getTenantId()).getRepositoryDomain();\r
         ArrayList<String> docTypes = new ArrayList<String>();\r
         Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();\r
         Map<String, Map<String, String>> authRefFieldsByService = new HashMap<String, Map<String, String>>();\r
+        \r
+        String query = computeWhereClauseForAuthorityRefDocs(escapedRefName, docTypes, servicebindings, \r
+                                                                                               queriedServiceBindings, authRefFieldsByService );\r
+        if (query == null) { // found no authRef fields - nothing to query\r
+            return wrapperList;\r
+        }\r
+        // Now we have to issue the search\r
+        DocumentWrapper<DocumentModelList> docListWrapper = repoClient.findDocs(ctx,\r
+                docTypes, query, pageSize, pageNum, computeTotal);\r
+        // Now we gather the info for each document into the list and return\r
+        DocumentModelList docList = docListWrapper.getWrappedObject();\r
+        // Set num of items in list. this is useful to our testing framework.\r
+        commonList.setItemsInPage(docList.size());\r
+        // set the total result size\r
+        commonList.setTotalItems(docList.totalSize());\r
+        \r
+        processRefObjsDocList(docList, refName, servicebindings,\r
+                                                       queriedServiceBindings, authRefFieldsByService,\r
+                                                       list, null);\r
+        return wrapperList;\r
+    }\r
+    \r
+    private static String computeWhereClauseForAuthorityRefDocs(\r
+               String escapedRefName,\r
+               ArrayList<String> docTypes,\r
+               List<ServiceBindingType> servicebindings,\r
+               Map<String, ServiceBindingType> queriedServiceBindings,\r
+               Map<String, Map<String, String>> authRefFieldsByService ) {\r
         StringBuilder whereClause = new StringBuilder();\r
         boolean fFirst = true;\r
         List<String> authRefFieldPaths = new ArrayList<String>();\r
@@ -133,25 +161,30 @@ public class RefNameServiceUtils {
             }\r
         }\r
         String whereClauseStr = whereClause.toString(); // for debugging\r
-        if (fFirst) // found no authRef fields - nothing to query\r
-        {\r
-            return wrapperList;\r
+        if (fFirst) { // found no authRef fields - nothing to query\r
+            return null;\r
+        } else {\r
+               return whereClause.toString(); \r
         }\r
-        String fullQuery = whereClause.toString(); // for debug\r
-        // Now we have to issue the search\r
-        DocumentWrapper<DocumentModelList> docListWrapper = repoClient.findDocs(ctx,\r
-                docTypes, whereClause.toString(), pageSize, pageNum, computeTotal);\r
-        // Now we gather the info for each document into the list and return\r
-        DocumentModelList docList = docListWrapper.getWrappedObject();\r
-        // Set num of items in list. this is useful to our testing framework.\r
-        commonList.setItemsInPage(docList.size());\r
-        // set the total result size\r
-        commonList.setTotalItems(docList.totalSize());\r
+    }\r
+    \r
+    /*\r
+     * Runs through the list of found docs, processing them. \r
+     * If list is non-null, then processing means gather the info for items.\r
+     * If list is null, and newRefName is non-null, then processing means replacing and updating.\r
+     */\r
+    private static void processRefObjsDocList(DocumentModelList docList,\r
+               String refName,\r
+               List<ServiceBindingType> servicebindings,\r
+               Map<String, ServiceBindingType> queriedServiceBindings,\r
+               Map<String, Map<String, String>> authRefFieldsByService,\r
+                       List<AuthorityRefDocList.AuthorityRefDocItem> list, \r
+                       String newAuthorityRefName) {\r
         Iterator<DocumentModel> iter = docList.iterator();\r
         while (iter.hasNext()) {\r
             DocumentModel docModel = iter.next();\r
-            AuthorityRefDocList.AuthorityRefDocItem ilistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
-            String csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());\r
+            AuthorityRefDocList.AuthorityRefDocItem ilistItem;\r
+\r
             String docType = docModel.getDocumentType().getName();\r
             ServiceBindingType sb = queriedServiceBindings.get(docType);\r
             if (sb == null) {\r
@@ -159,14 +192,21 @@ public class RefNameServiceUtils {
                         "getAuthorityRefDocs: No Service Binding for docType: " + docType);\r
             }\r
             String serviceContextPath = "/" + sb.getName().toLowerCase() + "/";\r
-            // The id and URI are the same on all doctypes\r
-            ilistItem.setDocId(csid);\r
-            ilistItem.setUri(serviceContextPath + csid);\r
-            ilistItem.setDocType(docType);\r
-            ilistItem.setDocNumber(\r
-                    ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NUMBER_PROP, docModel));\r
-            ilistItem.setDocName(\r
-                    ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NAME_PROP, docModel));\r
+            \r
+            if(list == null) {\r
+               ilistItem = null;\r
+            } else {\r
+               ilistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
+                String csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());\r
+                ilistItem.setDocId(csid);\r
+                ilistItem.setUri(serviceContextPath + csid);\r
+                // The id and URI are the same on all doctypes\r
+                ilistItem.setDocType(docType);\r
+                ilistItem.setDocNumber(\r
+                        ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NUMBER_PROP, docModel));\r
+                ilistItem.setDocName(\r
+                        ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NAME_PROP, docModel));\r
+            }\r
             // Now, we have to loop over the authRefFieldsByService to figure\r
             // out which field matched this. Ignore multiple matches.\r
             Map<String,String> matchingAuthRefFields = authRefFieldsByService.get(docType);\r
@@ -209,12 +249,18 @@ public class RefNameServiceUtils {
                         // Handle multiple fields matching in one Doc. See CSPACE-2863.\r
                        if(fRefFound) {\r
                                // We already added ilistItem, so we need to clone that and add again\r
-                            ilistItem = cloneAuthRefDocItem(ilistItem, sourceField);\r
+                               if(ilistItem != null) {\r
+                                       ilistItem = cloneAuthRefDocItem(ilistItem, sourceField);\r
+                               }\r
                        } else {\r
-                               ilistItem.setSourceField(sourceField);\r
+                               if(ilistItem != null) {\r
+                                       ilistItem.setSourceField(sourceField);\r
+                               }\r
                             fRefFound = true;\r
                        }\r
-                        list.add(ilistItem);\r
+                               if(ilistItem != null) {\r
+                                       list.add(ilistItem);\r
+                               }\r
                     }\r
 \r
                 } catch (ClientException ce) {\r
@@ -225,10 +271,10 @@ public class RefNameServiceUtils {
             if (!fRefFound) {\r
                 throw new RuntimeException(\r
                         "getAuthorityRefDocs: Could not find refname in object:"\r
-                        + docType + ":" + csid);\r
+                        + docType + ":" + NuxeoUtils.getCsid(docModel));\r
             }\r
         }\r
-        return wrapperList;\r
+\r
     }\r
     \r
     private static AuthorityRefDocList.AuthorityRefDocItem cloneAuthRefDocItem(\r
index a0fe1b802cb139a307665ce0ffceaf78a691ff04..59cf1e37d1f82ea3ff33a4cce6d1215a037e6c97 100644 (file)
@@ -42,6 +42,7 @@ import org.collectionspace.services.common.repository.RepositoryClientFactory;
 import org.collectionspace.services.common.service.ObjectPartType;
 import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
 import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.collectionspace.services.relation.RelationResource;
@@ -79,6 +80,11 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
      */
     protected String inAuthority;
     protected String authorityRefNameBase;
+    
+    // Used to determine when the displayName changes as part of the update.
+    protected String oldDisplayNameOnUpdate = null;
+    protected String oldRefNameOnUpdate = null;
+    protected String newRefNameOnUpdate = null;
 
     public AuthorityItemDocumentModelHandler(String authorityItemCommonSchemaName) {
         this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
@@ -121,6 +127,11 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         super.handleCreate(wrapDoc);
         handleInAuthority(wrapDoc.getWrappedObject());
        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:
         // Uncomment once debugged and App layer is read to integrate
         // Experimenting with these uncommented now ...
@@ -133,8 +144,23 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
      */
     @Override
     public void handleUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
+       // First, get a copy of the old displayName
+       oldDisplayNameOnUpdate = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName, 
+                                                                                                                               AuthorityItemJAXBSchema.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);
+       if(newDisplayName != null && !newDisplayName.equals(oldDisplayNameOnUpdate)) {
+               // Need to update the refName, and then fix all references.
+               newRefNameOnUpdate = handleItemRefNameUpdateForDisplayName(wrapDoc.getWrappedObject(), newDisplayName);
+       } else {
+               // Mark as not needing attention in completeUpdate phase.
+               newRefNameOnUpdate = null;
+               oldRefNameOnUpdate = null;
+       }
     }
 
     /**
@@ -147,6 +173,44 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
        // Do nothing by default.
     }
 
+    /**
+     * Handle refName updates for changes to display name.
+     * Assumes refName is already correct. Just ensures it is right.
+     *
+     * @param docModel the doc model
+     * @throws Exception the exception
+     */
+    protected String handleItemRefNameUpdateForDisplayName(DocumentModel docModel,
+            String newDisplayName) throws Exception {
+        //String suppliedRefName = (String) docModel.getProperty(authorityItemCommonSchemaName, 
+        //                                                                                                             AuthorityItemJAXBSchema.REF_NAME);
+        RefName.AuthorityItem authItem = RefName.AuthorityItem.parse(oldRefNameOnUpdate);
+        if(authItem == null) {
+               String err = "Authority Item has illegal refName: "+oldRefNameOnUpdate;
+               logger.debug(err);
+               throw new IllegalArgumentException(err);
+        }
+        authItem.displayName = newDisplayName;
+        String updatedRefName = authItem.toString();
+        docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REF_NAME, updatedRefName);
+        return updatedRefName;
+    }
+
+    
+    /**
+     * Checks to see if the refName has changed, and if so, 
+     * uses utilities to find all references and update them.
+     */
+    protected void handleItemRefNameReferenceUpdate() {
+       if(newRefNameOnUpdate != null && oldRefNameOnUpdate!= null) {
+               // We have work to do.
+               logger.debug("Need to find and update references to Item.");
+               logger.debug("Old refName" + oldRefNameOnUpdate);
+               logger.debug("New refName" + newRefNameOnUpdate);
+       }
+    }
+
+
     private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
         String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
         String displayName = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
@@ -169,8 +233,17 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         String suppliedRefName = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.REF_NAME);
         // CSPACE-3178:
         // Temporarily accept client-supplied refName values, rather than always generating such values.
-        // Remove the surrounding 'if' statement when clients should no longer supply refName values.
-        if (suppliedRefName == null || suppliedRefName.isEmpty()) {
+        // Remove first block and the surrounding 'if' statement when clients should no longer supply refName values.
+        if(!Tools.isEmpty(suppliedRefName) ) {
+               // Supplied refName must at least be legal
+               RefName.AuthorityItem item = RefName.AuthorityItem.parse(suppliedRefName);
+               if(item==null) {
+                logger.error("Passed refName for authority item not legal: "+suppliedRefName);
+                suppliedRefName = null; // Clear this and compute a new one below.
+               }
+        } 
+        // Recheck, in case we cleared it for being illegal
+        if(Tools.isEmpty(suppliedRefName) ) {
             String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
             String displayName = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
             if (Tools.isEmpty(authorityRefBaseName)) {
@@ -386,6 +459,7 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         ServiceContext ctx = getServiceContext();
         PayloadOutputPart foo = (PayloadOutputPart) ctx.getProperty(RelationClient.SERVICE_COMMON_LIST_NAME);
         ((PoxPayloadOut) ctx.getOutput()).addPart(foo);
+        handleItemRefNameReferenceUpdate();
     }
 
     /**  updateRelations strategy:
index 6a9370649194e0a7fc3150d8d7234121a307b2d5..3ed0c33b78b766587b824703ae15ab6bcd4a5722 100755 (executable)
@@ -3,6 +3,9 @@ package org.collectionspace.services.common.api;
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
 \r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
 /**\r
  * Usage for this class, if you have a URN and would like to get at its fields, is to call one of these methods:\r
  *\r
@@ -37,6 +40,9 @@ import java.util.regex.Pattern;
  * User: laramie\r
  */\r
 public class RefName {\r
+       \r
+    /** The logger. */\r
+    private static final Logger logger = LoggerFactory.getLogger(RefName.class);\r
 \r
     public static final String HACK_VOCABULARIES = "Vocabularies"; //TODO: get rid of these.\r
     public static final String HACK_ORGANIZATIONS = "Organizations"; //TODO: get rid of these.\r
@@ -124,6 +130,9 @@ public class RefName {
             Matcher m = p.matcher(urn);\r
             if (m.find()) {\r
                 if (m.groupCount() < 5) {\r
+                       if (m.groupCount() == 4 && logger.isDebugEnabled()) {\r
+                               logger.debug("AuthorityItem.parse only found 4 items; Missing displayName? Urn:"+urn);\r
+                       }\r
                     return null;\r
                 }\r
                 termInfo.inAuthority.tenantName = m.group(1);\r