# HG changeset patch # User Sascha L. Teichmann # Date 1369886640 -7200 # Node ID 57fb50f8c9fc3191d3fac69bbaef7feb05e0490d # Parent 243558474334460af6c97e3c391344183f8d4fee Datacage: Added function dc:replace-all(haystack, needle, replacement) to do regular expression replacements. Mapped to Java's String haystack.replaceAll(needle, replacement). diff -r 243558474334 -r 57fb50f8c9fc artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/FunctionResolver.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/FunctionResolver.java Wed May 29 10:36:40 2013 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/FunctionResolver.java Thu May 30 06:04:00 2013 +0200 @@ -9,11 +9,11 @@ package org.dive4elements.river.artifacts.datacage.templating; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -38,24 +38,32 @@ public static final double FAR_AWAY = 99999d; - public static final class Entry { + protected static final class Entry { - String name; + Entry next; XPathFunction function; int arity; - public Entry() { + public Entry(Entry next, XPathFunction function, int arity) { + this.next = next; + this.function = function; + this.arity = arity; } - public Entry(String name, XPathFunction function, int arity) { - this.name = name; - this.function = function; - this.arity = arity; + XPathFunction find(int arity) { + Entry current = this; + while (current != null) { + if (current.arity == arity) { + return current.function; + } + current = current.next; + } + return null; } } // class Entry /** List of functions. */ - protected List functions; + protected Map functions; protected Builder.BuildHelper buildHelper; @@ -67,7 +75,7 @@ public FunctionResolver(Builder.BuildHelper buildHelper) { this.buildHelper = buildHelper; - functions = new ArrayList(); + functions = new HashMap(); addFunction("contains", 2, new XPathFunction() { @Override @@ -97,6 +105,13 @@ } }); + addFunction("replace-all", 3, new XPathFunction() { + @Override + public Object evaluate(List args) throws XPathFunctionException { + return replaceAll(args); + } + }); + addFunction("has-result", 0, new XPathFunction() { @Override public Object evaluate(List args) throws XPathFunctionException { @@ -133,7 +148,15 @@ * @param function the function itself. */ public void addFunction(String name, int arity, XPathFunction function) { - functions.add(new Entry(name, function, arity)); + Entry entry = functions.get(name); + if (entry == null) { + entry = new Entry(null, function, arity); + functions.put(name, entry); + } + else { + Entry newEntry = new Entry(entry.next, function, arity); + entry.next = newEntry; + } } @Override @@ -143,14 +166,10 @@ return null; } - String name = functionName.getLocalPart(); - for (Entry entry: functions) { - if (entry.arity == arity && entry.name.equals(name)) { - return entry.function; - } - } - - return null; + Entry entry = functions.get(functionName.getLocalPart()); + return entry != null + ? entry.find(arity) + : null; } /** Implementation of case-ignoring dc:contains. */ @@ -291,7 +310,7 @@ try { return Double.parseDouble(t); } - catch(NumberFormatException nfe) { + catch (NumberFormatException nfe) { return FAR_AWAY; } } @@ -309,14 +328,30 @@ Object needle = args.get(1); Object replacement = args.get(2); - if (needle instanceof String && - haystack instanceof String && - replacement instanceof String) { + if (needle instanceof String + && haystack instanceof String + && replacement instanceof String) { return ((String)haystack).replace( (String)needle, (String)replacement); - } else { - return haystack; } + return haystack; + } + + /** Implementation for doing a string replace + * dc:replace-all + */ + public Object replaceAll(List args) throws XPathFunctionException { + Object haystack = args.get(0); + Object needle = args.get(1); + Object replacement = args.get(2); + + if (needle instanceof String + && haystack instanceof String + && replacement instanceof String) { + return ((String)haystack).replaceAll( + (String)needle, (String)replacement); + } + return haystack; } public Object dateFormat(List args) throws XPathFunctionException {