ingo@107: /*
ingo@107:  * Copyright (c) 2011 by Intevation GmbH
ingo@107:  *
ingo@107:  * This program is free software under the LGPL (>=v2.1)
ingo@107:  * Read the file LGPL.txt coming with the software for details
ingo@107:  * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@107:  */
ingo@107: package de.intevation.artifactdatabase;
ingo@107: 
ingo@109: import java.util.List;
ingo@107: 
ingo@295: import org.w3c.dom.Document;
ingo@107: import org.w3c.dom.Element;
ingo@295: import org.w3c.dom.Node;
ingo@295: 
ingo@295: import de.intevation.artifacts.ArtifactNamespaceContext;
ingo@107: 
ingo@107: import de.intevation.artifacts.common.utils.XMLUtils;
ingo@295: import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
ingo@107: 
ingo@227: import de.intevation.artifactdatabase.state.Facet;
ingo@211: import de.intevation.artifactdatabase.state.Output;
ingo@109: import de.intevation.artifactdatabase.state.State;
ingo@109: 
ingo@107: 
ingo@107: /**
ingo@107:  * This class provides methods that help creating the artifact protocol
ingo@107:  * documents describe, feed, advance and out.
ingo@107:  *
ingo@107:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
ingo@107:  */
ingo@107: public class ProtocolUtils {
ingo@107: 
ingo@107:     /**
ingo@107:      * It should not be necessary to create instances of this class.
ingo@107:      */
ingo@107:     private ProtocolUtils() {}
ingo@107: 
ingo@107: 
ingo@107:     /**
ingo@107:      * This method creates a node that might be used for the artifact protocol.
ingo@107:      *
ingo@107:      * @param creator The ElementCreator that is used to create the node.
ingo@107:      * @param nodeName The node name.
ingo@107:      * @param attrName The names of optional attributes.
ingo@107:      * @param value The values for the optional attributes.
ingo@107:      *
ingo@107:      * @return the created node.
ingo@107:      */
ingo@107:     public static Element createArtNode(
ingo@107:         XMLUtils.ElementCreator creator,
ingo@107:         String nodeName, String[] attrName, String[] value)
ingo@107:     {
ingo@107:         Element typeNode = creator.create(nodeName);
ingo@107: 
ingo@107:         if (attrName != null && value != null) {
ingo@107:             for (int i = 0; i < attrName.length; i++) {
ingo@107:                 if (i < value.length) {
ingo@107:                     creator.addAttr(typeNode, attrName[i], value[i], true);
ingo@107:                 }
ingo@107:                 else {
ingo@107:                     break;
ingo@107:                 }
ingo@107:             }
ingo@107:         }
ingo@107: 
ingo@107:         return typeNode;
ingo@107:     }
ingo@107: 
ingo@107: 
ingo@107:     /**
ingo@107:      * This method creates the root node for all artifact protocol documents.
ingo@107:      *
ingo@107:      * @param creator The ElementCreator used to create new elements.
ingo@107:      *
ingo@107:      * @return the root node for the artifact protocol document.
ingo@107:      */
ingo@107:     public static Element createRootNode(XMLUtils.ElementCreator creator) {
ingo@107:         return createArtNode(creator, "result", null, null);
ingo@107:     }
ingo@107: 
ingo@107: 
ingo@107:     /**
ingo@107:      * This method appends the three necessary nodes <i>type</i>, <i>uuid</i>
ingo@107:      * and <i>hash</i> of the describe document to <i>root</i> node.
ingo@107:      *
ingo@107:      * @param creator The ElementCreator that is used to create new nodes.
ingo@107:      * @param root The root node of the describe document.
ingo@107:      * @param uuid The UUID of the artifact.
ingo@107:      * @param hash The hash if the artifact.
ingo@107:      */
ingo@107:     public static void appendDescribeHeader(
ingo@107:         XMLUtils.ElementCreator creator, Element root, String uuid, String hash)
ingo@107:     {
ingo@107:         root.appendChild(createArtNode(
ingo@107:             creator,
ingo@107:             "type",
ingo@107:             new String[] {"name"},
ingo@107:             new String[] {"describe"}));
ingo@107: 
ingo@107:         root.appendChild(createArtNode(
ingo@107:             creator,
ingo@107:             "uuid",
ingo@107:             new String[] {"value"},
ingo@107:             new String[] {uuid}));
ingo@107: 
ingo@107:         root.appendChild(createArtNode(
ingo@107:             creator,
ingo@107:             "hash",
ingo@107:             new String[] {"value"},
ingo@107:             new String[] {hash}));
ingo@107:     }
ingo@109: 
ingo@109: 
ingo@109:     /**
ingo@109:      * This method appends a node that describes the current state to
ingo@109:      * <i>root</i>.
ingo@109:      *
ingo@109:      * @param creator The ElementCreator used to create new elements.
ingo@109:      * @param root The parent node for new elements.
ingo@109:      * @param state The state to be appended.
ingo@109:      */
ingo@109:     public static void appendState(
ingo@109:         XMLUtils.ElementCreator creator, Element root, State state)
ingo@109:     {
ingo@109:         root.appendChild(createArtNode(
ingo@109:             creator, "state",
ingo@109:             new String[] { "description", "name" },
ingo@109:             new String[] { state.getDescription(), state.getID() }));
ingo@109:     }
ingo@109: 
ingo@109: 
ingo@109:     /**
ingo@109:      * This method appends a node with reachable states to <i>root</i>.
ingo@109:      *
ingo@109:      * @param creator The ElementCreator used to create new elements.
ingo@109:      * @param root The parent node for new elements.
ingo@109:      * @param states The reachable states to be appended.
ingo@109:      */
ingo@109:     public static void appendReachableStates(
ingo@109:         XMLUtils.ElementCreator creator,
ingo@109:         Element                 root,
ingo@109:         List<State>             states)
ingo@109:     {
ingo@109:         Element reachable = createArtNode(
ingo@109:             creator, "reachable-states", null, null);
ingo@109: 
ingo@109:         for (State s: states) {
ingo@109:             appendState(creator, reachable, s);
ingo@109:         }
ingo@109: 
ingo@109:         root.appendChild(reachable);
ingo@109:     }
ingo@211: 
ingo@211: 
ingo@227:     /**
ingo@227:      * This method appends a node for each Output in the <i>outputs</i> list to
ingo@227:      * <i>out</i>. Note: an output node includes its provided facets!
ingo@227:      *
ingo@227:      * @param creator The ElementCreator used to create new elements.
ingo@227:      * @param out The parent node for new elements.
ingo@227:      * @param outputs The list of reachable outputs.
ingo@227:      */
ingo@211:     public static void appendOutputModes(
ingo@295:         Document     doc,
ingo@295:         Element      out,
ingo@295:         List<Output> outputs)
ingo@211:     {
ingo@295:         ElementCreator creator = new ElementCreator(
ingo@295:             doc,
ingo@295:             ArtifactNamespaceContext.NAMESPACE_URI,
ingo@295:             ArtifactNamespaceContext.NAMESPACE_PREFIX);
ingo@295: 
ingo@211:         for (Output o: outputs) {
ingo@227:             Element newOut = createArtNode(
ingo@211:                 creator,
ingo@211:                 "output",
ingo@290:                 new String[] {"name", "description", "mime-type", "type"},
ingo@290:                 new String[] {
ingo@290:                     o.getName(),
ingo@290:                     o.getDescription(),
ingo@290:                     o.getMimeType(),
ingo@290:                     o.getType() });
ingo@227: 
ingo@227:             Element facets = createArtNode(creator, "facets", null, null);
ingo@295:             appendFacets(doc, facets, o.getFacets());
ingo@227: 
ingo@227:             newOut.appendChild(facets);
ingo@227:             out.appendChild(newOut);
ingo@227:         }
ingo@227:     }
ingo@227: 
ingo@227: 
ingo@227:     /**
ingo@227:      * This method appends a node for each Facet in the <i>facets</i> list to
ingo@227:      * <i>facet</i>.
ingo@227:      *
ingo@227:      * @param creator The ElementCreator used to create new elements.
ingo@227:      * @param facet The root node for new elements.
ingo@227:      * @param facets The list of facets.
ingo@227:      */
ingo@227:     public static void appendFacets(
ingo@295:         Document    doc,
ingo@295:         Element     facet,
ingo@295:         List<Facet> facets)
ingo@227:     {
ingo@227:         if (facets == null || facets.size() == 0) {
ingo@227:             return;
ingo@227:         }
ingo@227: 
ingo@295:         ElementCreator creator = new ElementCreator(
ingo@295:             doc,
ingo@295:             ArtifactNamespaceContext.NAMESPACE_URI,
ingo@295:             ArtifactNamespaceContext.NAMESPACE_PREFIX);
ingo@295: 
ingo@227:         for (Facet f: facets) {
ingo@295:             Node node = f.toXML(doc);
ingo@227: 
ingo@295:             if (node != null) {
ingo@295:                 facet.appendChild(node);
ingo@295:             }
ingo@211:         }
ingo@211:     }
ingo@107: }
ingo@107: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: