changeset 6088:127cc609c12b

merged
author Sascha L. Teichmann <teichmann@intevation.de>
date Fri, 24 May 2013 12:22:05 +0200
parents 47775e3a8cf6 (diff) af29a0bc254a (current diff)
children 0c3301fe23bd
files
diffstat 2 files changed, 123 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/Builder.java	Fri May 24 12:17:23 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/Builder.java	Fri May 24 12:22:05 2013 +0200
@@ -453,6 +453,117 @@
                 : groupExprStack.peek();
         }
 
+        protected void virtualColumn(Node parent, Element current)
+        throws SQLException
+        {
+            log.debug("dc:virtual-column");
+
+            if (connectionsStack.isEmpty()) {
+                log.debug("dc:virtual-column without having results");
+                return;
+            }
+
+            NodeList subs = current.getChildNodes();
+            int S = subs.getLength();
+
+            if (S == 0) {
+                log.debug("dc:virtual-column has no children");
+                return;
+            }
+
+            String name = expand(current.getAttribute("name"));
+            String expr = current.getAttribute("expr").trim();
+            String type = current.getAttribute("type").trim();
+
+            QName returnType = typeToQName(type);
+
+            XPathExpression x;
+            try {
+                x = getXPathExpression(expr);
+            }
+            catch (XPathExpressionException xee) {
+                log.warn("Invalid expression '" + expr + "'.");
+                return;
+            }
+
+            Pair<Builder.NamedConnection, ResultData> pair =
+                connectionsStack.peek();
+
+            ResultData orig = connectionsStack.peek().getB();
+
+            int index = orig.indexOfColumn(name);
+
+            ResultData rd = index >= 0 // Already has column with this name?
+                ? replaceColumn(orig, index, x, returnType)
+                : addColumn(orig, name, x, returnType);
+
+            pair.setB(rd);
+            try {
+                for (int i = 0; i < S; ++i) {
+                    build(parent, subs.item(i));
+                }
+            }
+            finally {
+                pair.setB(orig);
+            }
+        }
+
+        protected ResultData addColumn(
+            ResultData      rd,
+            String          name,
+            XPathExpression expr,
+            QName           returnType
+        ) {
+            String [] origColumns = rd.getColumnLabels();
+            int index = origColumns.length;
+            String [] newColumns = Arrays.copyOf(origColumns, index+1);
+            ResultData result = new ResultData(newColumns);
+            fillResult(result, rd, index, index+1, expr, returnType);
+            return result;
+        }
+
+        protected ResultData replaceColumn(
+            ResultData      rd,
+            int             index,
+            XPathExpression expr,
+            QName           returnType
+        ) {
+            String [] columns = rd.getColumnLabels();
+            ResultData result = new ResultData(columns);
+            fillResult(result, rd, index, columns.length, expr, returnType);
+            return result;
+        }
+
+        protected void fillResult(
+            ResultData result,
+            ResultData rd,
+            int        index,
+            int size,
+            XPathExpression expr,
+            QName returnType
+        ) {
+            List<Object []> rows = rd.getRows();
+            String [] origColumns = rd.getColumnLabels();
+            for (int i = 0, R = rows.size(); i < R; ++i) {
+                Object [] row = rows.get(i);
+                frames.enter();
+                try {
+                    frames.put(origColumns, row);
+                    Object value = expr.evaluate(EVAL_DOCUMENT, returnType);
+                    Object [] copy = Arrays.copyOf(row, size);
+                    copy[index] = value;
+                    result.add(copy);
+                }
+                catch (XPathExpressionException xxe) {
+                    log.warn("unable to apply expression '" +
+                        expr + "' to dataset.", xxe);
+                }
+                finally {
+                    frames.leave();
+                }
+            }
+        }
+
         protected void iterate(Node parent, Element current)
         throws SQLException
         {
@@ -907,6 +1018,9 @@
                     else if ("group".equals(localName)) {
                         group(parent, curr);
                     }
+                    else if ("virtual-column".equals(localName)) {
+                        virtualColumn(parent, curr);
+                    }
                     else if ("text".equals(localName)) {
                         text(parent, curr);
                     }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/ResultData.java	Fri May 24 12:17:23 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/ResultData.java	Fri May 24 12:22:05 2013 +0200
@@ -77,6 +77,15 @@
         return this;
     }
 
+    public int indexOfColumn(String column) {
+        for (int i = 0; i < columns.length; ++i) {
+            if (columns[i].equalsIgnoreCase(column)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     public void add(Object [] result) {
         rows.add(result);
     }

http://dive4elements.wald.intevation.org