sascha@372: package de.intevation.flys.artifacts.services.meta; sascha@372: sascha@372: import java.util.regex.Matcher; sascha@372: sascha@372: import java.util.ArrayList; sascha@372: import java.util.List; sascha@372: import java.util.HashMap; sascha@372: import java.util.Map; sascha@372: sascha@372: import org.w3c.dom.Document; sascha@372: import org.w3c.dom.NodeList; sascha@372: import org.w3c.dom.Node; sascha@372: import org.w3c.dom.Element; sascha@372: sascha@372: import java.sql.SQLException; sascha@372: import java.sql.Connection; sascha@372: sascha@372: import de.intevation.artifacts.common.utils.XMLUtils; sascha@372: sascha@372: import org.apache.log4j.Logger; sascha@372: sascha@372: public class Builder sascha@372: { sascha@372: private static Logger log = Logger.getLogger(Builder.class); sascha@372: sascha@372: public static final String DC_NAMESPACE_URI = sascha@372: "http://www.intevation.org/2011/Datacage"; sascha@372: sascha@372: protected Document template; sascha@372: sascha@372: public class BuildHelper sascha@372: { sascha@372: protected Document output; sascha@372: protected StackFrames frames; sascha@372: protected Connection connection; sascha@372: protected Map statements; sascha@372: sascha@372: public BuildHelper() { sascha@372: frames = new StackFrames(); sascha@372: statements = new HashMap(); sascha@372: } sascha@372: sascha@372: public BuildHelper(Document output, Connection connection) { sascha@372: this(); sascha@372: this.output = output; sascha@372: this.connection = connection; sascha@372: } sascha@372: sascha@372: public void build(List elements) throws SQLException { sascha@372: try { sascha@372: for (Node current: elements) { sascha@372: build(output, current); sascha@372: } sascha@372: } sascha@372: finally { sascha@372: for (CompiledStatement cs: statements.values()) { sascha@372: cs.close(); sascha@372: } sascha@372: statements.clear(); sascha@372: } sascha@372: } sascha@372: sascha@372: protected void context(Node parent, Element current) sascha@372: throws SQLException sascha@372: { sascha@372: NodeList elements = current.getElementsByTagNameNS( sascha@372: DC_NAMESPACE_URI, "elements"); sascha@372: sascha@372: if (elements.getLength() < 1) { sascha@372: log.warn("no elements found -> ignore"); sascha@372: return; sascha@372: } sascha@372: sascha@372: NodeList subs = elements.item(0).getChildNodes(); sascha@372: int S = subs.getLength(); sascha@372: sascha@372: if (S < 1) { sascha@372: log.warn("elements is empty -> ignore"); sascha@372: return; sascha@372: } sascha@372: sascha@372: NodeList stmntNode = current.getElementsByTagNameNS( sascha@372: DC_NAMESPACE_URI, "statement"); sascha@372: sascha@372: if (stmntNode.getLength() < 1) { sascha@372: log.warn("dc:context: too less statements"); sascha@372: return; sascha@372: } sascha@372: sascha@372: String stmntText = stmntNode.item(0).getTextContent(); sascha@372: sascha@372: if (stmntText == null) { sascha@372: log.warn("dc:context: no sql statement found"); sascha@372: } sascha@372: sascha@372: CompiledStatement cs = statements.get(stmntText); sascha@372: sascha@372: if (cs == null) { sascha@372: cs = new CompiledStatement(stmntText); sascha@372: statements.put(stmntText, cs); sascha@372: } sascha@372: sascha@372: ResultData rd = cs.execute(connection, frames); sascha@372: sascha@372: String [] columns = rd.getColumnLabels(); sascha@372: sascha@372: sascha@372: for (Object [] row: rd.getRows()) { sascha@372: frames.enter(); sascha@372: try { sascha@372: frames.put(columns, row); sascha@372: for (int i = 0; i < S; ++i) { sascha@372: build(parent, subs.item(i)); sascha@372: } sascha@372: } sascha@372: finally { sascha@372: frames.leave(); sascha@372: } sascha@372: } sascha@372: } sascha@372: sascha@372: protected void element(Node parent, Element current) sascha@372: throws SQLException sascha@372: { sascha@372: String attr = expand(current.getAttribute("name")); sascha@372: sascha@372: if (log.isDebugEnabled()) { sascha@372: log.debug("dc:element -> '" + attr + "'"); sascha@372: } sascha@372: sascha@372: if (attr.length() == 0) { sascha@372: log.warn("no name attribute found"); sascha@372: return; sascha@372: } sascha@372: sascha@372: Element element = output.createElement(attr); sascha@372: sascha@372: NodeList children = current.getChildNodes(); sascha@372: for (int i = 0, N = children.getLength(); i < N; ++i) { sascha@372: build(element, children.item(i)); sascha@372: } sascha@372: sascha@372: parent.appendChild(element); sascha@372: } sascha@372: sascha@372: protected void text(Node parent, Element current) sascha@372: throws SQLException sascha@372: { sascha@372: log.debug("dc:text"); sascha@372: String value = expand(current.getTextContent()); sascha@372: parent.appendChild(output.createTextNode(value)); sascha@372: } sascha@372: sascha@372: sascha@372: protected void attribute(Node parent, Element current) { sascha@372: sascha@372: if (parent.getNodeType() != Node.ELEMENT_NODE) { sascha@372: log.warn("need element here"); sascha@372: return; sascha@372: } sascha@372: sascha@372: String name = expand(current.getAttribute("name")); sascha@372: String value = expand(current.getAttribute("value")); sascha@372: sascha@372: Element element = (Element)parent; sascha@372: sascha@372: element.setAttribute(name, value); sascha@372: } sascha@372: sascha@372: protected String expand(String s) { sascha@372: Matcher m = CompiledStatement.VAR.matcher(s); sascha@372: sascha@372: StringBuffer sb = new StringBuffer(); sascha@372: while (m.find()) { sascha@372: String key = m.group(1); sascha@372: Object value = frames.get(key); sascha@372: m.appendReplacement(sb, value != null ? value.toString() : ""); sascha@372: } sascha@372: m.appendTail(sb); sascha@372: return sb.toString(); sascha@372: } sascha@372: sascha@372: protected void build(Node parent, Node current) sascha@372: throws SQLException sascha@372: { sascha@372: String ns = current.getNamespaceURI(); sascha@372: if (ns != null && ns.equals(DC_NAMESPACE_URI)) { sascha@372: if (current.getNodeType() != Node.ELEMENT_NODE) { sascha@372: log.warn("need elements here"); sascha@372: } sascha@372: else { sascha@372: String localName = current.getLocalName(); sascha@372: if ("context".equals(localName)) { sascha@372: context(parent, (Element)current); sascha@372: } sascha@372: else if ("attribute".equals(localName)) { sascha@372: attribute(parent, (Element)current); sascha@372: } sascha@372: else if ("element".equals(localName)) { sascha@372: element(parent, (Element)current); sascha@372: } sascha@372: else if ("text".equals(localName)) { sascha@372: text(parent, (Element)current); sascha@372: } sascha@372: else { sascha@372: log.warn("unknown '" + localName + "' -> ignore"); sascha@372: } sascha@372: } sascha@372: return; sascha@372: } sascha@372: sascha@372: Node copy = output.importNode(current, false); sascha@372: sascha@372: NodeList children = current.getChildNodes(); sascha@372: for (int i = 0, N = children.getLength(); i < N; ++i) { sascha@372: build(copy, children.item(i)); sascha@372: } sascha@372: parent.appendChild(copy); sascha@372: } sascha@372: } // class BuildHelper sascha@372: sascha@372: sascha@372: public Builder() { sascha@372: } sascha@372: sascha@372: public Builder(Document template) { sascha@372: this.template = template; sascha@372: } sascha@372: sascha@372: public Document build(Connection connection) sascha@372: throws SQLException sascha@372: { sascha@372: return build(connection, XMLUtils.newDocument()); sascha@372: } sascha@372: sascha@372: public Document build(Connection connection, Document output) sascha@372: throws SQLException sascha@372: { sascha@372: NodeList roots = template.getElementsByTagNameNS( sascha@372: DC_NAMESPACE_URI, "template"); sascha@372: sascha@372: BuildHelper helper = new BuildHelper(output, connection); sascha@372: sascha@372: List elements = new ArrayList(); sascha@372: sascha@372: for (int i = 0, N = roots.getLength(); i < N; ++i) { sascha@372: NodeList rootChildren = roots.item(i).getChildNodes(); sascha@372: for (int j = 0, M = rootChildren.getLength(); j < M; ++j) { sascha@372: Node child = rootChildren.item(j); sascha@372: if (child.getNodeType() == Node.ELEMENT_NODE) { sascha@372: elements.add(child); sascha@372: } sascha@372: } sascha@372: } sascha@372: helper.build(elements); sascha@372: sascha@372: return output; sascha@372: } sascha@372: } sascha@372: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :