Mercurial > dive4elements > river
changeset 7669:f1abd257f933
Datacage: Added <dc:sort>
<dc:sort expr="Expression" type="Type">
...
</dc:sort>
sorts the current dataset by Expression. Type is optional (default string).
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Fri, 06 Dec 2013 16:34:58 +0100 |
parents | e0219f4079a8 |
children | 03dc5cc22e26 |
files | artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/Builder.java |
diffstat | 1 files changed, 111 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/Builder.java Fri Dec 06 15:36:47 2013 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/Builder.java Fri Dec 06 16:34:58 2013 +0100 @@ -75,6 +75,26 @@ protected Map<String, Element> macros; + private static final class KV implements Comparable<KV> { + + private Comparable<Object> key; + private Object [] data; + + public KV(Comparable<Object> key, Object [] data) { + this.key = key; + this.data = data; + } + + @Override + public int compareTo(KV other) { + return key.compareTo(other.key); + } + + public Object [] getData() { + return data; + } + } + /** Connection to either of the databases. */ public static class NamedConnection { @@ -581,6 +601,94 @@ } } + + protected ResultData createSortedResultData( + ResultData orig, + String expr, + String type + ) { + XPathExpression x; + try { + x = getXPathExpression(expr); + } + catch (XPathExpressionException xee) { + log.warn("Invalid sort expression '" + expr + "'."); + return orig; + } + + QName returnType = typeToQName(type); + + List<Object []> rows = orig.getRows(); + String [] columns = orig.getColumnLabels(); + + List<KV> sorted = new ArrayList<KV>(rows.size()); + + for (Object [] row: rows) { + frames.enter(); + try { + frames.put(columns, row); + Object key = x.evaluate(EVAL_DOCUMENT, returnType); + + if (key instanceof Comparable) { + sorted.add(new KV((Comparable<Object>)key, row)); + } + } + catch (XPathExpressionException xee) { + log.warn("unable to apply expression '" + + expr + "' to dataset. " + xee.getMessage(), xee); + } + finally { + frames.leave(); + } + } + Collections.sort(sorted); + List<Object []> result = new ArrayList<Object []>(sorted.size()); + for (KV kv: sorted) { + result.add(kv.getData()); + } + return new ResultData(columns, result); + } + + protected void sort(Node parent, Element current) + throws SQLException + { + log.debug("dc:sort"); + + if (connectionsStack.isEmpty()) { + log.debug("dc:sort without having results"); + return; + } + + String expr = current.getAttribute("expr").trim(); + String type = current.getAttribute("type").trim(); + + if (expr.isEmpty()) { + log.warn("missing 'expr' in dc:sort"); + return; + } + + Pair<Builder.NamedConnection, ResultData> pair = + connectionsStack.peek(); + + ResultData orig = connectionsStack.peek().getB(); + + ResultData sorted = createSortedResultData(orig, expr, type); + + NodeList subs = current.getChildNodes(); + + pair.setB(sorted); + try { + for (int i = 0, S = subs.getLength(); i < S; ++i) { + build(parent, subs.item(i)); + } + } + finally { + if (orig != null) { + pair.setB(orig); + } + } + } + public Object getGroupKey() { return groupExprStack.isEmpty() ? null @@ -1145,6 +1253,9 @@ else if ("group".equals(localName)) { group(parent, curr); } + else if ("sort".equals(localName)) { + sort(parent, curr); + } else if ("virtual-column".equals(localName)) { virtualColumn(parent, curr); }