view flys-artifacts/src/main/java/de/intevation/flys/collections/CollectionDescriptionHelper.java @ 4031:e4e345d81a65

issue889/2
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Thu, 04 Oct 2012 14:54:44 +0200
parents a5f65e8983be
children
line wrap: on
line source
package de.intevation.flys.collections;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.xpath.XPathConstants;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

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 CollectionAttribute 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();
        this.artifacts = new ArrayList<String>();
    }


    public void addArtifact(String uuid) {
        if (uuid != null && uuid.length() > 0) {
            artifacts.add(uuid);
        }
    }


    public void setAttribute(CollectionAttribute 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, D = dataNodes.getLength(); i < D; i++) {
                dataNode.appendChild(doc.importNode(dataNodes.item(i), true));
            }
        }

        return ci;
    }


    protected void appendAttribute(Element root) {
        if (attribute != null) {
            Document owner = root.getOwnerDocument();
            Document attr  = attribute.toXML();

            root.appendChild(owner.importNode(attr.getFirstChild(), true));
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org