teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.collections; ingo@1972: ingo@1972: import java.util.ArrayList; ingo@1972: import java.util.Date; ingo@1972: import java.util.List; ingo@1972: ingo@1972: import javax.xml.xpath.XPathConstants; ingo@1972: ingo@3785: import org.apache.log4j.Logger; ingo@1972: import org.w3c.dom.Document; ingo@1972: import org.w3c.dom.Element; ingo@1972: import org.w3c.dom.Node; ingo@1972: import org.w3c.dom.NodeList; ingo@1972: teichmann@5831: import org.dive4elements.artifacts.ArtifactDatabase; teichmann@5831: import org.dive4elements.artifacts.ArtifactDatabaseException; teichmann@5831: import org.dive4elements.artifacts.ArtifactNamespaceContext; teichmann@5831: import org.dive4elements.artifacts.CallContext; teichmann@5831: import org.dive4elements.artifacts.common.utils.XMLUtils; teichmann@5831: import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator; ingo@1972: ingo@1972: ingo@1972: public class CollectionDescriptionHelper { ingo@1972: teichmann@8202: private static final Logger log = ingo@1972: Logger.getLogger(CollectionDescriptionHelper.class); ingo@1972: ingo@1972: ingo@1972: public static final String XPATH_ARTIFACT_STATE_DATA = ingo@1972: "/art:result/art:ui/art:static/art:state/art:data"; ingo@1972: ingo@1972: /** Constant XPath that points to the outputmodes of an artifact. */ ingo@1972: public static final String XPATH_ARTIFACT_OUTPUTMODES = ingo@1972: "/art:result/art:outputmodes"; ingo@1972: ingo@1972: ingo@1972: protected ElementCreator ec; ingo@1972: ingo@1972: protected CallContext context; ingo@1972: protected ArtifactDatabase database; ingo@1972: ingo@1972: protected String name; ingo@1972: protected String uuid; ingo@1972: protected Date creation; ingo@1972: protected long ttl; ingo@1972: ingo@1976: protected List artifacts; ingo@1976: protected CollectionAttribute attribute; ingo@1972: ingo@1972: ingo@1972: /** ingo@1972: * @param name The name of the collection. ingo@1972: * @param uuid The uuid of the collection. ingo@1972: * @param creation The creation time of the collection. ingo@1972: * @param ttl The time to live of the collection. ingo@1972: */ ingo@1972: public CollectionDescriptionHelper( ingo@1972: String name, ingo@1972: String uuid, ingo@1972: Date creation, ingo@1972: long ttl, ingo@1972: CallContext callContext ingo@1972: ) { ingo@3785: this.name = name; ingo@3785: this.uuid = uuid; ingo@3785: this.creation = creation; ingo@3785: this.ttl = ttl; ingo@3785: this.context = callContext; ingo@3785: this.database = callContext.getDatabase(); ingo@3785: this.artifacts = new ArrayList(); ingo@1972: } ingo@1972: ingo@1972: ingo@1972: public void addArtifact(String uuid) { ingo@1972: if (uuid != null && uuid.length() > 0) { ingo@1972: artifacts.add(uuid); ingo@1972: } ingo@1972: } ingo@1972: ingo@1972: ingo@1976: public void setAttribute(CollectionAttribute attribute) { ingo@1972: if (attribute != null) { ingo@1972: this.attribute = attribute; ingo@1972: } ingo@1972: } ingo@1972: ingo@1972: ingo@1972: public Document toXML() { ingo@1972: Document doc = XMLUtils.newDocument(); ingo@1972: ingo@1972: ec = new ElementCreator( ingo@1972: doc, ingo@1972: ArtifactNamespaceContext.NAMESPACE_URI, ingo@1972: ArtifactNamespaceContext.NAMESPACE_PREFIX); ingo@1972: ingo@1972: Element root = ec.create("artifact-collection"); ingo@1972: doc.appendChild(root); ingo@1972: ingo@1972: String creationTime = creation != null ingo@1972: ? Long.toString(creation.getTime()) ingo@1972: : ""; ingo@1972: ingo@1972: ec.addAttr(root, "name", name, true); ingo@1972: ec.addAttr(root, "uuid", uuid, true); ingo@1972: ec.addAttr(root, "creation", creationTime, true); ingo@1972: ec.addAttr(root, "ttl", String.valueOf(ttl), true); ingo@1972: ingo@1972: appendArtifacts(root); ingo@1972: appendAttribute(root); ingo@1972: ingo@1972: return doc; ingo@1972: } ingo@1972: ingo@1972: ingo@1972: /** ingo@1972: * Appends parts of the DESCRIBE document of each Artifact to root. ingo@1972: * ingo@1972: * @param root The root node. ingo@1972: */ ingo@1972: protected void appendArtifacts(Element root) { ingo@1972: Element artifactsEl = ec.create("artifacts"); ingo@1972: ingo@1972: for (String uuid: artifacts) { ingo@1972: try { ingo@1972: Element e = buildArtifactNode(uuid); ingo@1972: ingo@1972: if (e != null) { ingo@1972: artifactsEl.appendChild(e); ingo@1972: } ingo@1972: } ingo@1972: catch (ArtifactDatabaseException dbe) { teichmann@8202: log.warn(dbe, dbe); ingo@1972: } ingo@1972: } ingo@1972: ingo@1972: root.appendChild(artifactsEl); ingo@1972: } ingo@1972: ingo@1972: ingo@1972: /** ingo@1972: * Create the Artifacts Node that contains outputmode and statedata. ingo@1972: * ingo@1972: * @param uuid uuid of the artifact. ingo@1972: */ ingo@1972: protected Element buildArtifactNode(String uuid) ingo@1972: throws ArtifactDatabaseException ingo@1972: { teichmann@8202: log.debug("Append artifact '" + uuid + "' to collection description"); ingo@1972: ingo@1972: // TODO ingo@1972: String hash = "MYHASH"; ingo@1972: ingo@1972: Element ci = ec.create("artifact"); ingo@1972: ec.addAttr(ci, "uuid", uuid, true); ingo@1972: ec.addAttr(ci, "hash", hash, true); ingo@1972: ingo@1972: // XXX I am not sure if it works well every time with an empty document ingo@1972: // in the describe operation of an artifact. ingo@1972: Document description = database.describe(uuid, null, context.getMeta()); ingo@1972: ingo@1972: // Add outputmode element(s). ingo@1972: Node outputModes = (Node) XMLUtils.xpath( ingo@1972: description, ingo@1972: XPATH_ARTIFACT_OUTPUTMODES, ingo@1972: XPathConstants.NODE, ingo@1972: ArtifactNamespaceContext.INSTANCE); ingo@1972: ingo@1972: if (outputModes != null) { ingo@1972: Document doc = ci.getOwnerDocument(); ingo@1972: ci.appendChild(doc.importNode(outputModes, true)); ingo@1972: } ingo@1972: ingo@1972: // Add state-data element(s). ingo@1972: Node dataNode = ci.appendChild( ingo@1972: ci.getOwnerDocument().createElement("art:data-items")); ingo@1972: ingo@1972: NodeList dataNodes = (NodeList) XMLUtils.xpath( ingo@1972: description, ingo@1972: XPATH_ARTIFACT_STATE_DATA, ingo@1972: XPathConstants.NODESET, ingo@1972: ArtifactNamespaceContext.INSTANCE); ingo@1972: ingo@1972: if (dataNodes != null) { ingo@1972: Document doc = ci.getOwnerDocument(); sascha@3087: for (int i = 0, D = dataNodes.getLength(); i < D; i++) { ingo@1972: dataNode.appendChild(doc.importNode(dataNodes.item(i), true)); ingo@1972: } ingo@1972: } ingo@1972: ingo@1972: return ci; ingo@1972: } ingo@1972: ingo@1972: ingo@1972: protected void appendAttribute(Element root) { ingo@3785: if (attribute != null) { ingo@3785: Document owner = root.getOwnerDocument(); ingo@3785: Document attr = attribute.toXML(); ingo@1972: ingo@3785: root.appendChild(owner.importNode(attr.getFirstChild(), true)); ingo@3785: } ingo@1972: } ingo@1972: } sascha@3083: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :