]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5728: Alternate approach to getting field values via JDOM, rather than dom4j...
authorAron Roberts <aron@socrates.berkeley.edu>
Wed, 9 Jan 2013 02:04:05 +0000 (18:04 -0800)
committerAron Roberts <aron@socrates.berkeley.edu>
Wed, 9 Jan 2013 02:04:05 +0000 (18:04 -0800)
services/batch/service/pom.xml
services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java

index 49bebb0f201ccfd4fa113394b0dc3b5f460335de..73798b3c0ec77f301a442111f18899cc7b7287d0 100644 (file)
             <scope>provided</scope>
         </dependency>
         
+        <dependency>
+            <groupId>jdom</groupId>
+            <artifactId>jdom</artifactId>
+            <version>1.0</version>
+            <scope>provided</scope>        
+        </dependency>
+        
         <!-- jboss -->
 
         <dependency>
index 3787d2e3a45e9fb17ddc466c9018773304abbc6a..a61f30f63f6c45938d02563deb9e5d794bb42853 100644 (file)
@@ -26,12 +26,24 @@ import org.collectionspace.services.movement.nuxeo.MovementConstants;
 import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+
+import java.io.StringReader;
+
 import org.dom4j.DocumentException;
-import org.dom4j.DocumentHelper;
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.dom4j.XPath;
+
+
+/*
+ import org.dom4j.DocumentHelper;
+ import org.dom4j.Element;
+ import org.dom4j.Node;
+ import org.dom4j.XPath;
+ */
+
 import org.jboss.resteasy.specimpl.UriInfoImpl;
+import org.jdom.Namespace;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
 import org.slf4j.Logger;
@@ -47,6 +59,8 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
     private final static String CURRENT_LOCATION_ELEMENT_NAME = "currentLocation";
     private final static String LOCATION_DATE_ELEMENT_NAME = "locationDate";
     private final static String OBJECT_NUMBER_ELEMENT_NAME = "objectNumber";
+    private final static Namespace COLLECTIONOBJECTS_COMMON_NAMESPACE =
+            Namespace.getNamespace("ns2", "http://collectionspace.org/services/collectionobject");
     private InvocationResults results = new InvocationResults();
     private final String CLASSNAME = this.getClass().getSimpleName();
     private final Logger logger = LoggerFactory.getLogger(UpdateObjectLocationBatchJob.class);
@@ -136,53 +150,74 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
         return createUriInfo(uri.getRawQuery());
     }
 
+    protected String getFieldValue(PoxPayloadOut payload, String partLabel, Namespace partNamespace, String fieldPath) {
+        String value = null;
+        SAXBuilder builder = new SAXBuilder();
+        try {
+            Document document = builder.build(new StringReader(payload.toXML()));
+            Element root = document.getRootElement();
+            Element part = root.getChild(partLabel, partNamespace);
+            Element field = part.getChild(fieldPath, partNamespace);
+            value = field.getText();
+        } catch (Exception e) {
+            logger.error("Error getting value from field path " + fieldPath
+                    + " in schema part " + partLabel);
+            return null;
+        }
+        return value;
+    }
+
+    /**
+     * Get a field value from a PoxPayloadOut, given a part name and xpath
+     * expression.
+     */
+    /*
+     protected String getFieldValue(PoxPayloadOut payload, String partLabel, String fieldPath) {
+     String value = null;
+     PayloadOutputPart part = payload.getPart(partLabel);
+
+     if (part != null) {
+     Element element = part.asElement();
+     Node node = element.selectSingleNode(fieldPath);
+
+     if (node != null) {
+     value = node.getText();
+     }
+     }
+
+     return value;
+     }
+     */
     /**
      * Get a field value from a PoxPayloadOut, given a part name and
      * namespace-qualified xpath expression.
      */
-    protected String getFieldValue(PoxPayloadOut payload, String partLabel, String namespacePrefix, String namespace, String fieldPath) {
-        String value = null;
-        PayloadOutputPart part = payload.getPart(partLabel);
-
-        if (part != null) {
-            Element element = part.asElement();
-            logger.info(partLabel + " part element =" + element.asXML());
-
-            Map<String, String> namespaceUris = new HashMap<String, String>();
-            namespaceUris.put(namespacePrefix, namespace);
-
-            XPath xPath = DocumentHelper.createXPath(fieldPath);
-            xPath.setNamespaceURIs(namespaceUris);
-
-            Node node = xPath.selectSingleNode(element);
-            // Node node = element.selectSingleNode(fieldPath);
-
-            if (node != null) {
-                value = node.getText();
-            }
-        }
+    /*
+     protected String getFieldValue(PoxPayloadOut payload, String partLabel, String namespacePrefix, String namespace, String fieldPath) {
+     String value = null;
+     PayloadOutputPart part = payload.getPart(partLabel);
 
-        return value;
-    }
+     if (part != null) {
+     Element element = part.asElement();
+     logger.info(partLabel + " part element =" + element.asXML());
 
-    protected List<String> getFieldValues(PoxPayloadOut payload, String partLabel, String fieldPath) {
-        List<String> values = new ArrayList<String>();
-        PayloadOutputPart part = payload.getPart(partLabel);
+     Map<String, String> namespaceUris = new HashMap<String, String>();
+     namespaceUris.put(namespacePrefix, namespace);
 
-        if (part != null) {
-            Element element = part.asElement();
-            List<Node> nodes = element.selectNodes(fieldPath);
+     XPath xPath = DocumentHelper.createXPath(fieldPath);
+     xPath.setNamespaceURIs(namespaceUris);
 
-            if (nodes != null) {
-                for (Node node : nodes) {
-                    values.add(node.getText());
-                }
-            }
-        }
+     Node node = xPath.selectSingleNode(element);
+     // Node node = element.selectSingleNode(fieldPath);
 
-        return values;
-    }
+     if (node != null) {
+     value = node.getText();
+     }
+     }
 
+     return value;
+     }
+     */
     private InvocationResults updateComputedCurrentLocations(List<String> csids) {
 
         ResourceMap resourcemap = getResourceMap();
@@ -192,8 +227,6 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
         String objectNumber;
         String computedCurrentLocation;
         int numAffected = 0;
-        // FIXME: Temporary during testing/development
-        final String COMPUTED_CURRENT_LOCATION = "FOO_COMPUTED_CURRENT_LOCATION";
 
         try {
 
@@ -203,33 +236,32 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
                 // Get the movement records related to this record
 
                 // FIXME: Create a convenience method for constructing queries like the following
-                String queryString = "rtObj=" + csid;
+                String queryString = "rtObj=" + csid; // FIXME: Get from constant
                 URI uri = new URI(null, null, null, queryString, null);
                 UriInfo uriInfo = createUriInfo(uri.getRawQuery());
 
                 AbstractCommonList relatedMovements = movementResource.getList(uriInfo);
                 if (logger.isInfoEnabled()) {
                     logger.info("Identified " + relatedMovements.getTotalItems()
-                            + " movement records related to CollectionObject record " + csid);
+                            + " Movement records related to the object CollectionObject record " + csid);
                 }
 
-                // FIXME: Get relation records in the reverse direction as well,
-                // via rtSbj=, merge with records obtained above, and remove duplicates
-
-                queryString = "rtSbj=" + csid;
+                // Get relation records in the reverse direction as well,
+                // merge with records obtained above, and remove duplicates
+                queryString = "rtSbj=" + csid; // FIXME: Get from constant
                 uri = new URI(null, null, null, queryString, null);
                 uriInfo = createUriInfo(uri.getRawQuery());
 
                 AbstractCommonList reverseRelatedMovements = movementResource.getList(uriInfo);
                 if (logger.isInfoEnabled()) {
                     logger.info("Identified " + reverseRelatedMovements.getTotalItems()
-                            + " movement records related in the reverse  to CollectionObject record " + csid);
+                            + " Movement records related to the subject CollectionObject record " + csid);
                 }
-                
+
                 if ((relatedMovements.getTotalItems() == 0) && reverseRelatedMovements.getTotalItems() == 0) {
                     continue;
                 }
-                
+
                 // Merge the two lists
                 relatedMovements.getListItem().addAll(reverseRelatedMovements.getListItem());
 
@@ -240,25 +272,28 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
                 String locationDate;
                 String mostRecentLocationDate = "";
                 for (AbstractCommonList.ListItem movementRecord : relatedMovements.getListItem()) {
+
+                    // FIXME: Add 'de-duping' code here to avoid processing any
+                    // related Movement record more than once
+
                     locationDate = AbstractCommonListUtils.ListItemGetElementValue(movementRecord, LOCATION_DATE_ELEMENT_NAME);
-                    if (Tools.notBlank(locationDate)) {
-                        if (logger.isInfoEnabled()) {
-                            logger.info("Location date value = " + locationDate);
-                        }
+                    if (Tools.isBlank(locationDate)) {
+                        continue;
                     }
                     currentLocation = AbstractCommonListUtils.ListItemGetElementValue(movementRecord, CURRENT_LOCATION_ELEMENT_NAME);
-                    if (Tools.notBlank(currentLocation)) {
-                        if (logger.isInfoEnabled()) {
-                            logger.info("Current location value = " + currentLocation);
-                        }
+                    if (Tools.isBlank(currentLocation)) {
+                        continue;
                     }
-                    if (Tools.notBlank(locationDate) && Tools.notBlank(currentLocation)) {
-                        // Assumes that all values for this element/field will be ISO 8601
-                        // date representations, each of which can be ordered via string comparison.
-                        if (locationDate.compareTo(mostRecentLocationDate) > 0) {
-                            mostRecentLocationDate = locationDate;
-                            computedCurrentLocation = currentLocation;
-                        }
+                    if (logger.isInfoEnabled()) {
+                        logger.info("Location date value = " + locationDate);
+                        logger.info("Current location value = " + currentLocation);
+                    }
+                    // Assumes that all values for this element/field will be consistent ISO 8601
+                    // date/time representations, each of which can be ordered via string comparison.
+                    if (locationDate.compareTo(mostRecentLocationDate) > 0) {
+                        mostRecentLocationDate = locationDate;
+                        // FIXME: Add validation here that the currentLocation value parses successfully as an item refName
+                        computedCurrentLocation = currentLocation;
                     }
 
                 }
@@ -270,17 +305,18 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
                         logger.info("Payload: " + "\n" + collectionObjectPayload);
                     }
                     // Silently fails at various places in dom4j calls (selectSingleNode, selectNode,
-                    // createXpath) in any of the methods tried above, without throwing an Exception
-                    /*
-                     objectNumber = getFieldValue(collectionObjectPayload,
-                     COLLECTIONOBJECTS_COMMON_SCHEMA_NAME,
-                     "ns2", "http://collectionspace.org/services/collectionobject",
-                     OBJECT_NUMBER_ELEMENT_NAME);
-                     if (logger.isInfoEnabled()) {
-                     logger.info("Object number: " + objectNumber);
-                     }
-                     */
-                    objectNumber = "BAR"; // FIXME
+                    // createXpath) in any of the methods tried, without throwing an Exception.
+                    //
+                    // Those methods are now commented out, in favor of a replacement, however temporary,
+                    // using JDOM.
+                    //
+                    // FIXME: Get namespace from constant; verify whether prefix or URI is required
+                    objectNumber = getFieldValue(collectionObjectPayload,
+                            COLLECTIONOBJECTS_COMMON_SCHEMA_NAME, COLLECTIONOBJECTS_COMMON_NAMESPACE,
+                            OBJECT_NUMBER_ELEMENT_NAME);
+                    if (logger.isInfoEnabled()) {
+                        logger.info("Object number: " + objectNumber);
+                    }
                     if (Tools.notBlank(objectNumber)) {
                         String collectionObjectUpdatePayload =
                                 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -305,6 +341,7 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
         } catch (Exception e) {
             String errMsg = "Error encountered in " + CLASSNAME + ": " + e.getLocalizedMessage() + " ";
             errMsg = errMsg + "Successfully updated " + numAffected + " CollectionObject record(s) prior to error.";
+            logger.error(errMsg);
             setErrorResult(errMsg);
             getResults().setNumAffected(numAffected);
             return getResults();