diff options
author | Paul Duncan <pabs@pablotron.org> | 2018-09-06 18:08:34 -0400 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2018-09-06 18:08:34 -0400 |
commit | c4f3f955179cd217c6e7273561d06468b33e8973 (patch) | |
tree | 7a81b08c2847bdbd43f9fe4d0dbf4a1790ab3b15 /java/src/main | |
parent | 2be7535e09e359d70b924013c9f4d25149fdf0ae (diff) | |
download | luigi-template-c4f3f955179cd217c6e7273561d06468b33e8973.tar.bz2 luigi-template-c4f3f955179cd217c6e7273561d06468b33e8973.zip |
update errors, fix filters, add tests
Diffstat (limited to 'java/src/main')
9 files changed, 234 insertions, 47 deletions
diff --git a/java/src/main/java/org/pablotron/luigi/Cache.java b/java/src/main/java/org/pablotron/luigi/Cache.java index 97fa0ab..4a591bc 100644 --- a/java/src/main/java/org/pablotron/luigi/Cache.java +++ b/java/src/main/java/org/pablotron/luigi/Cache.java @@ -28,24 +28,25 @@ public final class Cache { final String key, final Map<String, String> args ) throws LuigiError { - Template t; + // run template with args + return get(key).run(args); + } + + public boolean containsKey(final String key) { + return strings.containsKey(key); + } - if (templates.containsKey(key)) { - // get template - t = templates.get(key); - } else { + public Template get(final String key) throws LuigiError { + if (!templates.containsKey(key)) { // make sure template exists if (!strings.containsKey(key)) - throw new LuigiError("unknown template: " + key); - - // create template - t = new Template(strings.get(key), filters); + throw new UnknownTemplateError(key); - // cache template - templates.put(key, t); + // create and cache template + templates.put(key, new Template(strings.get(key), filters)); } - // run template with args - return t.run(args); + // get template + return templates.get(key); } }; diff --git a/java/src/main/java/org/pablotron/luigi/Filter.java b/java/src/main/java/org/pablotron/luigi/Filter.java index b00491f..d2cd432 100644 --- a/java/src/main/java/org/pablotron/luigi/Filter.java +++ b/java/src/main/java/org/pablotron/luigi/Filter.java @@ -2,12 +2,26 @@ package org.pablotron.luigi; import java.util.Map; import java.util.HashMap; +import java.nio.charset.Charset; public final class Filter { public interface Handler { - public String filter(String val, String args[], Map<String, String> row); + public String filter( + String val, + String args[], + Map<String, String> row + ) throws FilterError; }; + protected static byte[] getBytes(final String val, final String args[]) { + final Charset charset = (args.length > 0) ? Charset.forName(args[0]) : Charset.defaultCharset(); + return val.getBytes(charset); + } + + protected static int toUInt(final byte b) { + return (b < 0) ? (256 + b) : b; + } + public static Map<String, Handler> FILTERS = new HashMap<String, Handler>() {{ put("null", new Handler() { public String filter(String val, String args[], Map<String, String> row) { @@ -48,41 +62,136 @@ public final class Filter { put("h", new Handler() { public String filter(String val, String args[], Map<String, String> row) { - StringBuilder r = new StringBuilder(val.length()); - - for (int i = 0, l = val.length(); i < l; i++) { - char c = val.charAt(i); - - switch (c) { - case '&': - r.append("&"); - break; - case '<': - r.append("<"); - break; - case '>': - r.append(">"); - break; - case '\'': - r.append("'"); - break; - case '"': - r.append("""); - break; - default: - r.append(c); + StringBuilder r = new StringBuilder(); + final byte bytes[] = getBytes(val, args); + + for (int i = 0, l = bytes.length; i < l; i++) { + final byte b = bytes[i]; + + switch (b) { + case '&': + r.append("&"); + break; + case '<': + r.append("<"); + break; + case '>': + r.append(">"); + break; + case '\'': + r.append("'"); + break; + case '"': + r.append("""); + break; + default: + if (b < 32 || b > 126) { + r.append(String.format("&#%d;", toUInt(b))); + } else { + final byte bs[] = {b}; + r.append(new String(bs)); + } } } return r.toString(); -/* - * return val - * .replace("&", "&") - * .replace("<", "<") - * .replace(">", ">") - * .replace("'", "'") - * .replace("\"", """); - */ + } + }); + + put("u", new Handler() { + public String filter(String val, String args[], Map<String, String> row) { + final StringBuilder r = new StringBuilder(); + final byte bytes[] = getBytes(val, args); + + for (int i = 0, l = bytes.length; i < l; i++) { + final byte b = bytes[i]; + + switch (b) { + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + case '_': + case '.': + case '~': + // unreserved character + final byte bs[] = {b}; + r.append(new String(bs)); + break; + case ' ': + r.append("+"); + break; + default: + r.append(String.format("%%%02X", toUInt(b))); + } + } + + return r.toString(); + } + }); + + put("trim", new Handler() { + public String filter(String val, String args[], Map<String, String> row) { + return val.replaceAll("\\A\\s+|\\s+\\Z", ""); } }); }}; diff --git a/java/src/main/java/org/pablotron/luigi/FilterError.java b/java/src/main/java/org/pablotron/luigi/FilterError.java new file mode 100644 index 0000000..cb631a7 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/FilterError.java @@ -0,0 +1,7 @@ +package org.pablotron.luigi; + +public class FilterError extends LuigiError { + public FilterError(final String message) { + super(message); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/Template.java b/java/src/main/java/org/pablotron/luigi/Template.java index 9af3a74..e5f25a9 100644 --- a/java/src/main/java/org/pablotron/luigi/Template.java +++ b/java/src/main/java/org/pablotron/luigi/Template.java @@ -47,4 +47,38 @@ public final class Template { public String toString() { return this.template; } + + public static String run( + final String template, + final Map<String, String> args + ) throws LuigiError { + return Template.run(template, args, Filter.FILTERS); + } + + public static void run( + final String template, + final Map<String, String> args, + final ResultHandler r + ) throws LuigiError { + run(template, args, Filter.FILTERS, r); + } + + public static String run( + final String template, + final Map<String, String> args, + final Map<String, Filter.Handler> filters + ) throws LuigiError { + final Template t = new Template(template, filters); + return t.run(args); + } + + public static void run( + final String template, + final Map<String, String> args, + final Map<String, Filter.Handler> filters, + final ResultHandler r + ) throws LuigiError { + final Template t = new Template(template, filters); + t.run(args, r); + } }; diff --git a/java/src/main/java/org/pablotron/luigi/UnknownEntryError.java b/java/src/main/java/org/pablotron/luigi/UnknownEntryError.java new file mode 100644 index 0000000..8b8a0fd --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/UnknownEntryError.java @@ -0,0 +1,13 @@ +package org.pablotron.luigi; + +public class UnknownEntryError extends LuigiError { + public final String type; + public final String name; + + public UnknownEntryError(final String type, final String name) { + super(String.format("unknown %s: %s", type, name)); + + this.type = type; + this.name = name; + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/UnknownFilterError.java b/java/src/main/java/org/pablotron/luigi/UnknownFilterError.java new file mode 100644 index 0000000..a56a6c1 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/UnknownFilterError.java @@ -0,0 +1,7 @@ +package org.pablotron.luigi; + +public class UnknownFilterError extends UnknownEntryError { + public UnknownFilterError(final String name) { + super("filter", name); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/UnknownKeyError.java b/java/src/main/java/org/pablotron/luigi/UnknownKeyError.java new file mode 100644 index 0000000..88da21a --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/UnknownKeyError.java @@ -0,0 +1,7 @@ +package org.pablotron.luigi; + +public class UnknownKeyError extends UnknownEntryError { + public UnknownKeyError(final String name) { + super("key", name); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/UnknownTemplateError.java b/java/src/main/java/org/pablotron/luigi/UnknownTemplateError.java new file mode 100644 index 0000000..15dae97 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/UnknownTemplateError.java @@ -0,0 +1,7 @@ +package org.pablotron.luigi; + +public class UnknownTemplateError extends UnknownEntryError { + public UnknownTemplateError(final String name) { + super("template", name); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/actions/FilterAction.java b/java/src/main/java/org/pablotron/luigi/actions/FilterAction.java index 9115a68..19565dc 100644 --- a/java/src/main/java/org/pablotron/luigi/actions/FilterAction.java +++ b/java/src/main/java/org/pablotron/luigi/actions/FilterAction.java @@ -5,6 +5,8 @@ import org.pablotron.luigi.actions.Action; import org.pablotron.luigi.FilterReference; import org.pablotron.luigi.Filter; import org.pablotron.luigi.LuigiError; +import org.pablotron.luigi.UnknownFilterError; +import org.pablotron.luigi.UnknownKeyError; public final class FilterAction implements Action { private final String key; @@ -21,7 +23,7 @@ public final class FilterAction implements Action { ) throws LuigiError { // check for key if (!args.containsKey(key)) - throw new LuigiError("unknown key: " + key); + throw new UnknownKeyError(key); // reduce value to result String r = args.get(key); @@ -29,7 +31,7 @@ public final class FilterAction implements Action { // get/check filter Filter.Handler f = filters.get(this.filters[i].name); if (f == null) - throw new LuigiError("unknown filter: " + this.filters[i].name); + throw new UnknownFilterError(this.filters[i].name); // run filter r = f.filter(r, this.filters[i].args, args); |