Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/meta/Builder.java @ 950:22bc87a42a0d
First step to factor out the "Datenkorb" logic into a service independent singleton.
flys-artifacts/trunk@2367 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 20 Jul 2011 09:56:39 +0000 |
parents | c09c9e05ecfa |
children | e91996b46e3c |
line wrap: on
line source
package de.intevation.flys.artifacts.services.meta; import java.util.regex.Matcher; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.Map; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.w3c.dom.Element; import java.sql.SQLException; import java.sql.Connection; import de.intevation.artifacts.common.utils.XMLUtils; import org.apache.log4j.Logger; public class Builder { private static Logger log = Logger.getLogger(Builder.class); public static final String DC_NAMESPACE_URI = "http://www.intevation.org/2011/Datacage"; protected Document template; public class BuildHelper { protected Document output; protected StackFrames frames; protected Connection connection; protected Map<String, CompiledStatement> statements; public BuildHelper( Document output, Connection connection, Map<String, Object> parameters ) { this.output = output; this.connection = connection; frames = new StackFrames(parameters); statements = new HashMap<String, CompiledStatement>(); } public void build(List<Node> elements) throws SQLException { try { for (Node current: elements) { build(output, current); } } finally { for (CompiledStatement cs: statements.values()) { cs.close(); } statements.clear(); } } protected void context(Node parent, Element current) throws SQLException { NodeList elements = current.getElementsByTagNameNS( DC_NAMESPACE_URI, "elements"); if (elements.getLength() < 1) { log.warn("no elements found -> ignore"); return; } NodeList subs = elements.item(0).getChildNodes(); int S = subs.getLength(); if (S < 1) { log.warn("elements is empty -> ignore"); return; } NodeList stmntNode = current.getElementsByTagNameNS( DC_NAMESPACE_URI, "statement"); if (stmntNode.getLength() < 1) { log.warn("dc:context: too less statements"); return; } String stmntText = stmntNode.item(0).getTextContent(); if (stmntText == null || (stmntText = stmntText.trim()).length() == 0) { log.warn("dc:context: no sql statement found -> ignored"); return; } CompiledStatement cs = statements.get(stmntText); if (cs == null) { cs = new CompiledStatement(stmntText); statements.put(stmntText, cs); } ResultData rd = cs.execute(connection, frames); String [] columns = rd.getColumnLabels(); for (Object [] row: rd.getRows()) { frames.enter(); try { frames.put(columns, row); for (int i = 0; i < S; ++i) { build(parent, subs.item(i)); } } finally { frames.leave(); } } } protected void element(Node parent, Element current) throws SQLException { String attr = expand(current.getAttribute("name")); if (log.isDebugEnabled()) { log.debug("dc:element -> '" + attr + "'"); } if (attr.length() == 0) { log.warn("no name attribute found"); return; } Element element = output.createElement(attr); NodeList children = current.getChildNodes(); for (int i = 0, N = children.getLength(); i < N; ++i) { build(element, children.item(i)); } parent.appendChild(element); } protected void text(Node parent, Element current) throws SQLException { log.debug("dc:text"); String value = expand(current.getTextContent()); parent.appendChild(output.createTextNode(value)); } protected void attribute(Node parent, Element current) { if (parent.getNodeType() != Node.ELEMENT_NODE) { log.warn("need element here"); return; } String name = expand(current.getAttribute("name")); String value = expand(current.getAttribute("value")); Element element = (Element)parent; element.setAttribute(name, value); } protected void convert(Node parent, Element current) { String variable = expand(current.getAttribute("var")); String type = expand(current.getAttribute("type")); if (frames.containsKey(variable)) { Object object = TypeConverter.convert( frames.get(variable), type); frames.put(variable, object); } } protected String expand(String s) { Matcher m = CompiledStatement.VAR.matcher(s); StringBuffer sb = new StringBuffer(); while (m.find()) { String key = m.group(1); Object value = frames.get(key); m.appendReplacement(sb, value != null ? value.toString() : ""); } m.appendTail(sb); return sb.toString(); } protected void build(Node parent, Node current) throws SQLException { String ns = current.getNamespaceURI(); if (ns != null && ns.equals(DC_NAMESPACE_URI)) { if (current.getNodeType() != Node.ELEMENT_NODE) { log.warn("need elements here"); } else { String localName = current.getLocalName(); if ("context".equals(localName)) { context(parent, (Element)current); } else if ("attribute".equals(localName)) { attribute(parent, (Element)current); } else if ("element".equals(localName)) { element(parent, (Element)current); } else if ("text".equals(localName)) { text(parent, (Element)current); } else if ("convert".equals(localName)) { convert(parent, (Element)current); } else { log.warn("unknown '" + localName + "' -> ignore"); } } return; } if (current.getNodeType() == Node.TEXT_NODE) { String txt = current.getNodeValue(); if (txt != null && txt.trim().length() == 0) { return; } } Node copy = output.importNode(current, false); NodeList children = current.getChildNodes(); for (int i = 0, N = children.getLength(); i < N; ++i) { build(copy, children.item(i)); } parent.appendChild(copy); } } // class BuildHelper public Builder() { } public Builder(Document template) { this.template = template; } public Document build(Connection connection) throws SQLException { return build(connection, XMLUtils.newDocument(), null); } public Document build( Connection connection, Document output, Map<String, Object> parameters ) throws SQLException { NodeList roots = template.getElementsByTagNameNS( DC_NAMESPACE_URI, "template"); BuildHelper helper = new BuildHelper(output, connection, parameters); List<Node> elements = new ArrayList<Node>(); for (int i = 0, N = roots.getLength(); i < N; ++i) { NodeList rootChildren = roots.item(i).getChildNodes(); for (int j = 0, M = rootChildren.getLength(); j < M; ++j) { Node child = rootChildren.item(j); if (child.getNodeType() == Node.ELEMENT_NODE) { elements.add(child); } } } helper.build(elements); return output; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :