changeset 1972:3c3e81fca092

Added a CollectionDescriptionHelper that helps generating DESCRIBE documents for Collections. flys-artifacts/trunk@3391 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 13 Dec 2011 08:43:48 +0000
parents 741d2067cfe1
children e0b081105a82
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/collections/CollectionDescriptionHelper.java flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java
diffstat 3 files changed, 229 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Mon Dec 12 11:19:56 2011 +0000
+++ b/flys-artifacts/ChangeLog	Tue Dec 13 08:43:48 2011 +0000
@@ -1,3 +1,12 @@
+2011-12-13  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/collections/CollectionDescriptionHelper.java:
+	  New. This class helps generating the DESCRIBE document of a collection.
+
+	* src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
+	  Moved some of the code to create the DESCRIBE document out to
+	  CollectionDescriptionHelper.
+
 2011-12-12	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
 
 	Resolve todo about wrongly named cross sections.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/CollectionDescriptionHelper.java	Tue Dec 13 08:43:48 2011 +0000
@@ -0,0 +1,204 @@
+package de.intevation.flys.collections;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifacts.ArtifactDatabase;
+import de.intevation.artifacts.ArtifactDatabaseException;
+import de.intevation.artifacts.ArtifactNamespaceContext;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
+
+
+public class CollectionDescriptionHelper {
+
+    private static final Logger logger =
+        Logger.getLogger(CollectionDescriptionHelper.class);
+
+
+    public static final String XPATH_ARTIFACT_STATE_DATA =
+        "/art:result/art:ui/art:static/art:state/art:data";
+
+    /** Constant XPath that points to the outputmodes of an artifact. */
+    public static final String XPATH_ARTIFACT_OUTPUTMODES =
+        "/art:result/art:outputmodes";
+
+
+    protected ElementCreator ec;
+
+    protected CallContext      context;
+    protected ArtifactDatabase database;
+
+    protected String name;
+    protected String uuid;
+    protected Date   creation;
+    protected long   ttl;
+
+    protected List<String> artifacts;
+    protected Node         attribute;
+
+
+    /**
+     * @param name The name of the collection.
+     * @param uuid The uuid of the collection.
+     * @param creation The creation time of the collection.
+     * @param ttl The time to live of the collection.
+     */
+    public CollectionDescriptionHelper(
+        String      name,
+        String      uuid,
+        Date        creation,
+        long        ttl,
+        CallContext callContext
+    ) {
+        this.name     = name;
+        this.uuid     = uuid;
+        this.creation = creation;
+        this.ttl      = ttl;
+        this.context  = callContext;
+        this.database = callContext.getDatabase();
+    }
+
+
+    public void addArtifact(String uuid) {
+        if (artifacts == null) {
+            artifacts = new ArrayList<String>();
+        }
+
+        if (uuid != null && uuid.length() > 0) {
+            artifacts.add(uuid);
+        }
+    }
+
+
+    public void setAttribute(Node attribute) {
+        if (attribute != null) {
+            this.attribute = attribute;
+        }
+    }
+
+
+    public Document toXML() {
+        Document doc = XMLUtils.newDocument();
+
+        ec = new ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element root = ec.create("artifact-collection");
+        doc.appendChild(root);
+
+        String creationTime = creation != null
+            ? Long.toString(creation.getTime())
+            : "";
+
+        ec.addAttr(root, "name", name, true);
+        ec.addAttr(root, "uuid", uuid, true);
+        ec.addAttr(root, "creation", creationTime, true);
+        ec.addAttr(root, "ttl", String.valueOf(ttl), true);
+
+        appendArtifacts(root);
+        appendAttribute(root);
+
+        return doc;
+    }
+
+
+    /**
+     * Appends parts of the DESCRIBE document of each Artifact to <i>root</i>.
+     *
+     * @param root The root node.
+     */
+    protected void appendArtifacts(Element root) {
+        Element artifactsEl = ec.create("artifacts");
+
+        for (String uuid: artifacts) {
+            try {
+                Element e = buildArtifactNode(uuid);
+
+                if (e != null) {
+                    artifactsEl.appendChild(e);
+                }
+            }
+            catch (ArtifactDatabaseException dbe) {
+                logger.warn(dbe, dbe);
+            }
+        }
+
+        root.appendChild(artifactsEl);
+    }
+
+
+    /**
+     * Create the Artifacts Node that contains outputmode and statedata.
+     *
+     * @param uuid uuid of the artifact.
+     */
+    protected Element buildArtifactNode(String uuid)
+    throws    ArtifactDatabaseException
+    {
+        logger.debug("Append artifact '" + uuid + "' to collection description");
+
+        // TODO
+        String hash = "MYHASH";
+
+        Element ci = ec.create("artifact");
+        ec.addAttr(ci, "uuid", uuid, true);
+        ec.addAttr(ci, "hash", hash, true);
+
+        // XXX I am not sure if it works well every time with an empty document
+        // in the describe operation of an artifact.
+        Document description = database.describe(uuid, null, context.getMeta());
+
+        // Add outputmode element(s).
+        Node outputModes = (Node) XMLUtils.xpath(
+            description,
+            XPATH_ARTIFACT_OUTPUTMODES,
+            XPathConstants.NODE,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (outputModes != null) {
+            Document doc = ci.getOwnerDocument();
+            ci.appendChild(doc.importNode(outputModes, true));
+        }
+
+        // Add state-data element(s).
+        Node dataNode = ci.appendChild(
+            ci.getOwnerDocument().createElement("art:data-items"));
+
+        NodeList dataNodes = (NodeList) XMLUtils.xpath(
+            description,
+            XPATH_ARTIFACT_STATE_DATA,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (dataNodes != null) {
+            Document doc = ci.getOwnerDocument();
+            for (int i = 0; i < dataNodes.getLength(); i++) {
+                dataNode.appendChild(doc.importNode(dataNodes.item(i), true));
+            }
+        }
+
+        return ci;
+    }
+
+
+    protected void appendAttribute(Element root) {
+        Document owner = root.getOwnerDocument();
+
+        root.appendChild(owner.importNode(attribute, true));
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java	Mon Dec 12 11:19:56 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java	Tue Dec 13 08:43:48 2011 +0000
@@ -3,7 +3,6 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -79,28 +78,9 @@
     public Document describe(CallContext context) {
         log.debug("FLYSArtifactCollection.describe: " + identifier);
 
-        Document doc = XMLUtils.newDocument();
-
-        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
-            doc,
-            ArtifactNamespaceContext.NAMESPACE_URI,
-            ArtifactNamespaceContext.NAMESPACE_PREFIX);
-
-        Date creationTime = getCreationTime();
-        String creation   = creationTime != null
-            ? Long.toString(creationTime.getTime())
-            : "";
-
-        Element collection = ec.create("artifact-collection");
-        Element artifacts  = ec.create("artifacts");
-
-        ec.addAttr(collection, "name", getName(), true);
-        ec.addAttr(collection, "uuid", identifier(), true);
-        ec.addAttr(collection, "creation", creation,  true);
-        ec.addAttr(collection, "ttl", String.valueOf(getTTL()), true);
-
-        collection.appendChild(artifacts);
-        doc.appendChild(collection);
+        CollectionDescriptionHelper helper = new CollectionDescriptionHelper(
+            getName(), identifier(), getCreationTime(), getTTL(),
+            context);
 
         ArtifactDatabase db = context.getDatabase();
         Document oldAttrs   = getAttribute();
@@ -109,7 +89,7 @@
             String[] aUUIDs = getArtifactUUIDs(context);
             Node newAttr    = mergeAttributes(db, context, oldAttrs, aUUIDs);
 
-            collection.appendChild(doc.importNode(newAttr, true));
+            helper.setAttribute(newAttr);
 
             // Make it an empty array if null.
             if (aUUIDs == null) {
@@ -117,22 +97,18 @@
             }
 
             for (String uuid: aUUIDs) {
-                try {
-                    artifacts.appendChild(
-                        buildArtifactNode(db, uuid, context, ec));
-                }
-                catch (ArtifactDatabaseException dbe) {
-                    log.warn(dbe, dbe);
-                }
+                helper.addArtifact(uuid);
             }
         }
         catch (ArtifactDatabaseException ade) {
-            log.error(ade, ade);
+            log.error("Error while merging attribute documents.", ade);
 
-            collection.appendChild(
-                doc.importNode(oldAttrs.getFirstChild(), true));
+            helper.setAttribute(oldAttrs);
         }
 
+        Document doc = helper.toXML();
+        log.debug("HELPER DOC: " + XMLUtils.toString(doc));
+
         return doc;
     }
 
@@ -354,7 +330,8 @@
 
         return dataProviders;
     }
-    
+
+
     /**
      * @return masterartifact or null if exception/not found.
      */
@@ -365,7 +342,7 @@
             CallMeta callMeta   = context.getMeta();
             Document document   = db.getCollectionsMasterArtifact(
                 identifier(), callMeta);
-    
+
             String masterUUID   = XMLUtils.xpathString(
                 document, XPATH_MASTER_UUID, ArtifactNamespaceContext.INSTANCE);
             FLYSArtifact masterArtifact =
@@ -396,15 +373,15 @@
         FLYSContext.STATE_ENGINE_KEY);
 
         FLYSArtifact masterArtifact = getMasterArtifact(context);
-    
+
         XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
             doc,
             ArtifactNamespaceContext.NAMESPACE_URI,
             ArtifactNamespaceContext.NAMESPACE_PREFIX);
-    
+
         AttributeParser aParser = new AttributeParser();
         OutputParser    oParser = new OutputParser(db, context);
-    
+
         if (uuids != null) {
             for (String uuid: uuids) {
                 try {
@@ -830,63 +807,6 @@
 
 
     /**
-     * Create the Artifacts Node that contains outputmode and statedata.
-     * @param uuid uuid of the artifact.
-     */
-    protected Element buildArtifactNode(
-        ArtifactDatabase        database,
-        String                  uuid,
-        CallContext             context,
-        XMLUtils.ElementCreator ec)
-    throws ArtifactDatabaseException
-    {
-        log.debug("Append artifact '" + uuid + "' to collection description");
-
-        // TODO
-        String hash = "MYHASH";
-
-        Element ci = ec.create("artifact");
-        ec.addAttr(ci, "uuid", uuid, true);
-        ec.addAttr(ci, "hash", hash, true);
-
-        // XXX I am not sure if it works well every time with an empty document
-        // in the describe operation of an artifact.
-        Document description = database.describe(uuid, null, context.getMeta());
-
-        // Add outputmode element(s).
-        Node outputModes = (Node) XMLUtils.xpath(
-            description,
-            XPATH_ARTIFACT_OUTPUTMODES,
-            XPathConstants.NODE,
-            ArtifactNamespaceContext.INSTANCE);
-
-        if (outputModes != null) {
-            Document doc = ci.getOwnerDocument();
-            ci.appendChild(doc.importNode(outputModes, true));
-        }
-
-        // Add state-data element(s).
-        Node dataNode = ci.appendChild(
-            ci.getOwnerDocument().createElement("art:data-items"));
-
-        NodeList dataNodes = (NodeList) XMLUtils.xpath(
-            description,
-            XPATH_ARTIFACT_STATE_DATA,
-            XPathConstants.NODESET,
-            ArtifactNamespaceContext.INSTANCE);
-
-        if (dataNodes != null) {
-            Document doc = ci.getOwnerDocument();
-            for (int i = 0; i < dataNodes.getLength(); i++) {
-                dataNode.appendChild(doc.importNode(dataNodes.item(i), true));
-            }
-        }
-
-        return ci;
-    }
-
-
-    /**
      * Inner class to structure/order the themes of a chart.
      */
     private static class ThemeList {

http://dive4elements.wald.intevation.org