From f422534cd4cf1ba32523c9fc798c207065038ca5 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Thu, 6 Sep 2018 08:40:23 -0400 Subject: java: add pom.xml, mv sources to src/main/java/org/pablotron, add src/test, add initial junit tests, update makefile and .gitignore --- .gitignore | 1 + java/Makefile | 8 +- java/pablotron/luigi/Cache.java | 51 --------- java/pablotron/luigi/Filter.java | 89 --------------- java/pablotron/luigi/FilterReference.java | 11 -- java/pablotron/luigi/LuigiError.java | 7 -- java/pablotron/luigi/Parser.java | 122 --------------------- java/pablotron/luigi/Template.java | 37 ------- java/pablotron/luigi/Test.java | 57 ---------- java/pablotron/luigi/actions/Action.java | 12 -- java/pablotron/luigi/actions/FilterAction.java | 41 ------- java/pablotron/luigi/actions/TextAction.java | 22 ---- java/pom.xml | 52 +++++++++ java/src/main/java/org/pablotron/luigi/Cache.java | 51 +++++++++ java/src/main/java/org/pablotron/luigi/Filter.java | 89 +++++++++++++++ .../java/org/pablotron/luigi/FilterReference.java | 11 ++ .../main/java/org/pablotron/luigi/LuigiError.java | 7 ++ java/src/main/java/org/pablotron/luigi/Parser.java | 122 +++++++++++++++++++++ .../main/java/org/pablotron/luigi/Template.java | 41 +++++++ java/src/main/java/org/pablotron/luigi/Test.java | 57 ++++++++++ .../java/org/pablotron/luigi/actions/Action.java | 12 ++ .../org/pablotron/luigi/actions/FilterAction.java | 41 +++++++ .../org/pablotron/luigi/actions/TextAction.java | 22 ++++ .../org/pablotron/luigi/tests/TemplateTest.java | 69 ++++++++++++ 24 files changed, 579 insertions(+), 453 deletions(-) delete mode 100644 java/pablotron/luigi/Cache.java delete mode 100644 java/pablotron/luigi/Filter.java delete mode 100644 java/pablotron/luigi/FilterReference.java delete mode 100644 java/pablotron/luigi/LuigiError.java delete mode 100644 java/pablotron/luigi/Parser.java delete mode 100644 java/pablotron/luigi/Template.java delete mode 100644 java/pablotron/luigi/Test.java delete mode 100644 java/pablotron/luigi/actions/Action.java delete mode 100644 java/pablotron/luigi/actions/FilterAction.java delete mode 100644 java/pablotron/luigi/actions/TextAction.java create mode 100644 java/pom.xml create mode 100644 java/src/main/java/org/pablotron/luigi/Cache.java create mode 100644 java/src/main/java/org/pablotron/luigi/Filter.java create mode 100644 java/src/main/java/org/pablotron/luigi/FilterReference.java create mode 100644 java/src/main/java/org/pablotron/luigi/LuigiError.java create mode 100644 java/src/main/java/org/pablotron/luigi/Parser.java create mode 100644 java/src/main/java/org/pablotron/luigi/Template.java create mode 100644 java/src/main/java/org/pablotron/luigi/Test.java create mode 100644 java/src/main/java/org/pablotron/luigi/actions/Action.java create mode 100644 java/src/main/java/org/pablotron/luigi/actions/FilterAction.java create mode 100644 java/src/main/java/org/pablotron/luigi/actions/TextAction.java create mode 100644 java/src/test/java/org/pablotron/luigi/tests/TemplateTest.java diff --git a/.gitignore b/.gitignore index 675d0c0..a026d80 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ php/docs/ php/examples/* ruby/*.gem ruby/docs/ +java/target/ diff --git a/java/Makefile b/java/Makefile index fee0c59..2643080 100644 --- a/java/Makefile +++ b/java/Makefile @@ -1,14 +1,14 @@ -SOURCES=$(shell find . -type f -name \*.java) -OUT=luigi-template.jar +SOURCES=$(shell find src/main/java -type f -name \*.java) +OUT=$(shell pwd)/luigi-template.jar all: $(SOURCES) javac $(SOURCES) $(OUT): all - jar cf $(OUT) pablotron + cd src/main/java && jar cf $(OUT) org jar: $(OUT) clean: - find . -type f -name \*.class -exec rm -f '{}' ';' + find src/main/java -type f -name \*.class -exec rm -f '{}' ';' rm -f $(OUT) diff --git a/java/pablotron/luigi/Cache.java b/java/pablotron/luigi/Cache.java deleted file mode 100644 index b550b46..0000000 --- a/java/pablotron/luigi/Cache.java +++ /dev/null @@ -1,51 +0,0 @@ -package pablotron.luigi; - -import java.util.Map; -import java.util.HashMap; -import pablotron.luigi.Filter; -import pablotron.luigi.Template; -import pablotron.luigi.LuigiError; -import pablotron.luigi.actions.Action; - -public final class Cache { - private final Map strings; - private final Map filters; - private final Map templates = new HashMap(); - - public Cache( - final Map strings, - final Map filters - ) { - this.strings = strings; - this.filters = filters; - } - - public Cache(final Map strings) { - this(strings, Filter.FILTERS); - } - - public String run( - final String key, - final Map args - ) throws LuigiError { - Template t; - - if (templates.containsKey(key)) { - // get template - t = templates.get(key); - } else { - // make sure template exists - if (!strings.containsKey(key)) - throw new LuigiError("unknown template: " + key); - - // create template - t = new Template(strings.get(key), filters); - - // cache template - templates.put(key, t); - } - - // run template with args - return t.run(args); - } -}; diff --git a/java/pablotron/luigi/Filter.java b/java/pablotron/luigi/Filter.java deleted file mode 100644 index d89beab..0000000 --- a/java/pablotron/luigi/Filter.java +++ /dev/null @@ -1,89 +0,0 @@ -package pablotron.luigi; - -import java.util.Map; -import java.util.HashMap; - -public final class Filter { - public interface Handler { - public String filter(String val, String args[], Map row); - }; - - public static Map FILTERS = new HashMap() {{ - put("null", new Handler() { - public String filter(String val, String args[], Map row) { - return ""; - } - }); - - put("s", new Handler() { - public String filter(String val, String args[], Map row) { - int v = Integer.parseInt(val); - return (v == 1) ? "" : "s"; - } - }); - - put("uc", new Handler() { - public String filter(String val, String args[], Map row) { - return val.toUpperCase(); - } - }); - - put("lc", new Handler() { - public String filter(String val, String args[], Map row) { - return val.toLowerCase(); - } - }); - - put("length", new Handler() { - public String filter(String val, String args[], Map row) { - return Integer.toString(val.length()); - } - }); - - put("trim", new Handler() { - public String filter(String val, String args[], Map row) { - return val.trim(); - } - }); - - put("h", new Handler() { - public String filter(String val, String args[], Map 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); - } - } - - return r.toString(); -/* - * return val - * .replace("&", "&") - * .replace("<", "<") - * .replace(">", ">") - * .replace("'", "'") - * .replace("\"", """); - */ - } - }); - }}; -}; diff --git a/java/pablotron/luigi/FilterReference.java b/java/pablotron/luigi/FilterReference.java deleted file mode 100644 index d0f9d3d..0000000 --- a/java/pablotron/luigi/FilterReference.java +++ /dev/null @@ -1,11 +0,0 @@ -package pablotron.luigi; - -public final class FilterReference { - public final String name; - public final String[] args; - - public FilterReference(final String name, final String args[]) { - this.name = name; - this.args = args; - } -}; diff --git a/java/pablotron/luigi/LuigiError.java b/java/pablotron/luigi/LuigiError.java deleted file mode 100644 index 4ff4c01..0000000 --- a/java/pablotron/luigi/LuigiError.java +++ /dev/null @@ -1,7 +0,0 @@ -package pablotron.luigi; - -public class LuigiError extends Exception { - public LuigiError(final String message) { - super(message); - } -}; diff --git a/java/pablotron/luigi/Parser.java b/java/pablotron/luigi/Parser.java deleted file mode 100644 index 0e415c4..0000000 --- a/java/pablotron/luigi/Parser.java +++ /dev/null @@ -1,122 +0,0 @@ -package pablotron.luigi; - -import java.util.ArrayList; -import java.util.regex.Pattern; -import java.util.regex.Matcher; - -import pablotron.luigi.actions.Action; -import pablotron.luigi.actions.FilterAction; -import pablotron.luigi.actions.TextAction; -import pablotron.luigi.FilterReference; -import pablotron.luigi.LuigiError; - -public final class Parser { - private static final Pattern RE_ACTION = Pattern.compile( - // match opening brace - "%\\{" + - - // match optional whitespace - "\\s*" + - - // match key - // "(?[^\\s\\|\\}]+)" + - "([^\\s\\|\\}]+)" + - - // match filter(s) - // "(?(\\s*\\|(\\s*[^\\s\\|\\}]+)+)*)" + - "((\\s*\\|(\\s*[^\\s\\|\\}]+)+)*)" + - - // match optional whitespace - "\\s*" + - - // match closing brace - "\\}" + - - // or match up all non-% chars or a single % char - // "| (?[^%]* | %)", - "| ([^%]* | %)", - - Pattern.COMMENTS - ); - - private static final Pattern RE_FILTER = Pattern.compile( - // match filter name - // "(?\\S+)" + - "(\\S+)" + - - // match filter arguments (optional) - // "(?(\\s*\\S+)*)" + - "((\\s*\\S+)*)" + - - // optional trailing whitespace - "\\s*", - - Pattern.COMMENTS - ); - - private static final Pattern RE_DELIM_FILTERS = Pattern.compile( - "\\s*\\|\\s*" - ); - - private static final Pattern RE_DELIM_ARGS = Pattern.compile( - "\\s+" - ); - - public static Action[] parse_template( - final String template - ) throws LuigiError { - final ArrayList r = new ArrayList(); - - // match on text - final Matcher m = RE_ACTION.matcher(template); - - while (m.find()) { - // String key = m.group("key"); - final String key = m.group(1); - - if (key != null && key.length() > 0) { - // r.add(new FilterAction(key, parse_filters(m.group("filters")))); - r.add(new FilterAction(key, parse_filters(m.group(2)))); - } else { - // r.add(new TextAction(m.group("text"))); - r.add(new TextAction(m.group(5))); - } - } - - // build array of results - return r.toArray(new Action[r.size()]); - } - - private static final String[] NO_ARGS = {}; - - public static FilterReference[] parse_filters( - final String filters_str - ) throws LuigiError { - final ArrayList r = new ArrayList(); - - // split string into individual filters and handle each one - for (String f: RE_DELIM_FILTERS.split(filters_str)) { - // trim filter string and skip empty filters - f = f.trim(); - if (f.length() == 0) - continue; - - // match on filter and check for error - final Matcher m = RE_FILTER.matcher(f); - if (!m.find()) - throw new LuigiError("invalid filter: " + f); - - // get arguments string - final String args = m.group(2).trim(); - - // append new filter reference to result - r.add(new FilterReference( - m.group(1), - (args.length() > 0) ? RE_DELIM_ARGS.split(args) : NO_ARGS - )); - } - - // return result - return r.toArray(new FilterReference[r.size()]); - } -}; diff --git a/java/pablotron/luigi/Template.java b/java/pablotron/luigi/Template.java deleted file mode 100644 index 8ab1d77..0000000 --- a/java/pablotron/luigi/Template.java +++ /dev/null @@ -1,37 +0,0 @@ -package pablotron.luigi; - -import java.util.Map; -import pablotron.luigi.Parser; -import pablotron.luigi.Filter; -import pablotron.luigi.LuigiError; -import pablotron.luigi.actions.Action; - -public final class Template { - private static final String VERSION = "0.4.0"; - - private final String template; - private final Action actions[]; - private final Map filters; - - public Template( - final String template, - final Map filters - ) throws LuigiError { - this.template = template; - this.filters = filters; - this.actions = Parser.parse_template(template); - } - - public Template(final String template) throws LuigiError { - this(template, Filter.FILTERS); - } - - public String run(final Map args) throws LuigiError { - final StringBuilder r = new StringBuilder(); - - for (Action a: this.actions) - r.append(a.run(this.filters, args)); - - return r.toString(); - } -}; diff --git a/java/pablotron/luigi/Test.java b/java/pablotron/luigi/Test.java deleted file mode 100644 index 7163c52..0000000 --- a/java/pablotron/luigi/Test.java +++ /dev/null @@ -1,57 +0,0 @@ -package pablotron.luigi; - -import java.util.Map; -import java.util.HashMap; - -import pablotron.luigi.LuigiError; -import pablotron.luigi.Filter; -import pablotron.luigi.Template; -import pablotron.luigi.Cache; - -public final class Test { - // test template - private static final String TEMPLATE = - "test basic: hello %{name}\n" + - "test filter: hello %{name | uc}\n" + - "test custom: %{name | custom | uc | lc}\n" + - "test custom_with_arg: %{name | custom_with_arg hello}\n"; - - // test template cache - private static final Cache cache = new Cache(new HashMap() {{ - put("test-template", TEMPLATE); - }}); - - // test arguments - private static final Map args = new HashMap() {{ - put("name", "paul"); - }}; - - // custom filters - private static final Map filters = new HashMap() {{ - // add custom filter - put("custom", new Filter.Handler() { - public String filter(String val, String args[], Map row) { - return "custom"; - } - }); - - // add custom filter with argument - put("custom_with_arg", new Filter.Handler() { - public String filter(String val, String args[], Map row) { - return (args.length > 0) ? args[0] : "custom"; - } - }); - }}; - - public static void main(String params[]) throws Exception { - // add custom filters - Filter.FILTERS.putAll(filters); - - // create and run template - final Template t = new Template(TEMPLATE); - System.out.print(t.run(args)); - - // run cache - System.out.print(cache.run("test-template", args)); - } -}; diff --git a/java/pablotron/luigi/actions/Action.java b/java/pablotron/luigi/actions/Action.java deleted file mode 100644 index 010622a..0000000 --- a/java/pablotron/luigi/actions/Action.java +++ /dev/null @@ -1,12 +0,0 @@ -package pablotron.luigi.actions; - -import java.util.Map; -import pablotron.luigi.Filter; -import pablotron.luigi.LuigiError; - -public interface Action { - public String run( - Map filters, - Map args - ) throws LuigiError; -}; diff --git a/java/pablotron/luigi/actions/FilterAction.java b/java/pablotron/luigi/actions/FilterAction.java deleted file mode 100644 index b69923b..0000000 --- a/java/pablotron/luigi/actions/FilterAction.java +++ /dev/null @@ -1,41 +0,0 @@ -package pablotron.luigi.actions; - -import java.util.Map; -import pablotron.luigi.actions.Action; -import pablotron.luigi.FilterReference; -import pablotron.luigi.Filter; -import pablotron.luigi.LuigiError; - -public final class FilterAction implements Action { - private final String key; - private final FilterReference filters[]; - - public FilterAction(final String key, final FilterReference filters[]) { - this.key = key; - this.filters = filters; - } - - public String run( - Map filters, - Map args - ) throws LuigiError { - // check for key - if (!args.containsKey(key)) - throw new LuigiError("unknown key: " + key); - - // reduce value to result - String r = args.get(key); - for (int i = 0, l = this.filters.length; i < l; i++) { - // get/check filter - Filter.Handler f = filters.get(this.filters[i].name); - if (f == null) - throw new LuigiError("unknown filter: " + this.filters[i].name); - - // run filter - r = f.filter(r, this.filters[i].args, args); - } - - // return result - return r; - } -}; diff --git a/java/pablotron/luigi/actions/TextAction.java b/java/pablotron/luigi/actions/TextAction.java deleted file mode 100644 index 3024f23..0000000 --- a/java/pablotron/luigi/actions/TextAction.java +++ /dev/null @@ -1,22 +0,0 @@ -package pablotron.luigi.actions; - -import java.util.Map; -import pablotron.luigi.actions.Action; -import pablotron.luigi.Filter; -import pablotron.luigi.LuigiError; - -public final class TextAction implements Action { - private final String text; - - public TextAction(final String text) { - this.text = text; - } - - public String run( - Map filters, - Map args - ) throws LuigiError { - return this.text; - } -}; - diff --git a/java/pom.xml b/java/pom.xml new file mode 100644 index 0000000..63e777d --- /dev/null +++ b/java/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + org.pablotron.luigi + luigi-template + 0.4.2 + + + UTF-8 + 1.8 + ${maven.compiler.source} + + 5.3.0 + + + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + + org.junit.jupiter + junit-jupiter-params + ${junit.jupiter.version} + test + + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + + + + + + maven-surefire-plugin + 2.22.0 + + + + diff --git a/java/src/main/java/org/pablotron/luigi/Cache.java b/java/src/main/java/org/pablotron/luigi/Cache.java new file mode 100644 index 0000000..97fa0ab --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/Cache.java @@ -0,0 +1,51 @@ +package org.pablotron.luigi; + +import java.util.Map; +import java.util.HashMap; +import org.pablotron.luigi.Filter; +import org.pablotron.luigi.Template; +import org.pablotron.luigi.LuigiError; +import org.pablotron.luigi.actions.Action; + +public final class Cache { + private final Map strings; + private final Map filters; + private final Map templates = new HashMap(); + + public Cache( + final Map strings, + final Map filters + ) { + this.strings = strings; + this.filters = filters; + } + + public Cache(final Map strings) { + this(strings, Filter.FILTERS); + } + + public String run( + final String key, + final Map args + ) throws LuigiError { + Template t; + + if (templates.containsKey(key)) { + // get template + t = templates.get(key); + } else { + // make sure template exists + if (!strings.containsKey(key)) + throw new LuigiError("unknown template: " + key); + + // create template + t = new Template(strings.get(key), filters); + + // cache template + templates.put(key, t); + } + + // run template with args + return t.run(args); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/Filter.java b/java/src/main/java/org/pablotron/luigi/Filter.java new file mode 100644 index 0000000..b00491f --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/Filter.java @@ -0,0 +1,89 @@ +package org.pablotron.luigi; + +import java.util.Map; +import java.util.HashMap; + +public final class Filter { + public interface Handler { + public String filter(String val, String args[], Map row); + }; + + public static Map FILTERS = new HashMap() {{ + put("null", new Handler() { + public String filter(String val, String args[], Map row) { + return ""; + } + }); + + put("s", new Handler() { + public String filter(String val, String args[], Map row) { + int v = Integer.parseInt(val); + return (v == 1) ? "" : "s"; + } + }); + + put("uc", new Handler() { + public String filter(String val, String args[], Map row) { + return val.toUpperCase(); + } + }); + + put("lc", new Handler() { + public String filter(String val, String args[], Map row) { + return val.toLowerCase(); + } + }); + + put("length", new Handler() { + public String filter(String val, String args[], Map row) { + return Integer.toString(val.length()); + } + }); + + put("trim", new Handler() { + public String filter(String val, String args[], Map row) { + return val.trim(); + } + }); + + put("h", new Handler() { + public String filter(String val, String args[], Map 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); + } + } + + return r.toString(); +/* + * return val + * .replace("&", "&") + * .replace("<", "<") + * .replace(">", ">") + * .replace("'", "'") + * .replace("\"", """); + */ + } + }); + }}; +}; diff --git a/java/src/main/java/org/pablotron/luigi/FilterReference.java b/java/src/main/java/org/pablotron/luigi/FilterReference.java new file mode 100644 index 0000000..38c134b --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/FilterReference.java @@ -0,0 +1,11 @@ +package org.pablotron.luigi; + +public final class FilterReference { + public final String name; + public final String[] args; + + public FilterReference(final String name, final String args[]) { + this.name = name; + this.args = args; + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/LuigiError.java b/java/src/main/java/org/pablotron/luigi/LuigiError.java new file mode 100644 index 0000000..edeb7c7 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/LuigiError.java @@ -0,0 +1,7 @@ +package org.pablotron.luigi; + +public class LuigiError extends Exception { + public LuigiError(final String message) { + super(message); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/Parser.java b/java/src/main/java/org/pablotron/luigi/Parser.java new file mode 100644 index 0000000..5be4a9c --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/Parser.java @@ -0,0 +1,122 @@ +package org.pablotron.luigi; + +import java.util.ArrayList; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import org.pablotron.luigi.actions.Action; +import org.pablotron.luigi.actions.FilterAction; +import org.pablotron.luigi.actions.TextAction; +import org.pablotron.luigi.FilterReference; +import org.pablotron.luigi.LuigiError; + +public final class Parser { + private static final Pattern RE_ACTION = Pattern.compile( + // match opening brace + "%\\{" + + + // match optional whitespace + "\\s*" + + + // match key + // "(?[^\\s\\|\\}]+)" + + "([^\\s\\|\\}]+)" + + + // match filter(s) + // "(?(\\s*\\|(\\s*[^\\s\\|\\}]+)+)*)" + + "((\\s*\\|(\\s*[^\\s\\|\\}]+)+)*)" + + + // match optional whitespace + "\\s*" + + + // match closing brace + "\\}" + + + // or match up all non-% chars or a single % char + // "| (?[^%]* | %)", + "| ([^%]* | %)", + + Pattern.COMMENTS + ); + + private static final Pattern RE_FILTER = Pattern.compile( + // match filter name + // "(?\\S+)" + + "(\\S+)" + + + // match filter arguments (optional) + // "(?(\\s*\\S+)*)" + + "((\\s*\\S+)*)" + + + // optional trailing whitespace + "\\s*", + + Pattern.COMMENTS + ); + + private static final Pattern RE_DELIM_FILTERS = Pattern.compile( + "\\s*\\|\\s*" + ); + + private static final Pattern RE_DELIM_ARGS = Pattern.compile( + "\\s+" + ); + + public static Action[] parse_template( + final String template + ) throws LuigiError { + final ArrayList r = new ArrayList(); + + // match on text + final Matcher m = RE_ACTION.matcher(template); + + while (m.find()) { + // String key = m.group("key"); + final String key = m.group(1); + + if (key != null && key.length() > 0) { + // r.add(new FilterAction(key, parse_filters(m.group("filters")))); + r.add(new FilterAction(key, parse_filters(m.group(2)))); + } else { + // r.add(new TextAction(m.group("text"))); + r.add(new TextAction(m.group(5))); + } + } + + // build array of results + return r.toArray(new Action[r.size()]); + } + + private static final String[] NO_ARGS = {}; + + public static FilterReference[] parse_filters( + final String filters_str + ) throws LuigiError { + final ArrayList r = new ArrayList(); + + // split string into individual filters and handle each one + for (String f: RE_DELIM_FILTERS.split(filters_str)) { + // trim filter string and skip empty filters + f = f.trim(); + if (f.length() == 0) + continue; + + // match on filter and check for error + final Matcher m = RE_FILTER.matcher(f); + if (!m.find()) + throw new LuigiError("invalid filter: " + f); + + // get arguments string + final String args = m.group(2).trim(); + + // append new filter reference to result + r.add(new FilterReference( + m.group(1), + (args.length() > 0) ? RE_DELIM_ARGS.split(args) : NO_ARGS + )); + } + + // return result + return r.toArray(new FilterReference[r.size()]); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/Template.java b/java/src/main/java/org/pablotron/luigi/Template.java new file mode 100644 index 0000000..2b17a54 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/Template.java @@ -0,0 +1,41 @@ +package org.pablotron.luigi; + +import java.util.Map; +import org.pablotron.luigi.Parser; +import org.pablotron.luigi.Filter; +import org.pablotron.luigi.LuigiError; +import org.pablotron.luigi.actions.Action; + +public final class Template { + private static final String VERSION = "0.4.0"; + + private final String template; + private final Action actions[]; + private final Map filters; + + public Template( + final String template, + final Map filters + ) throws LuigiError { + this.template = template; + this.filters = filters; + this.actions = Parser.parse_template(template); + } + + public Template(final String template) throws LuigiError { + this(template, Filter.FILTERS); + } + + public String run(final Map args) throws LuigiError { + final StringBuilder r = new StringBuilder(); + + for (Action a: this.actions) + r.append(a.run(this.filters, args)); + + return r.toString(); + } + + public String toString() { + return this.template; + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/Test.java b/java/src/main/java/org/pablotron/luigi/Test.java new file mode 100644 index 0000000..2a560e2 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/Test.java @@ -0,0 +1,57 @@ +package org.pablotron.luigi; + +import java.util.Map; +import java.util.HashMap; + +import org.pablotron.luigi.LuigiError; +import org.pablotron.luigi.Filter; +import org.pablotron.luigi.Template; +import org.pablotron.luigi.Cache; + +public final class Test { + // test template + private static final String TEMPLATE = + "test basic: hello %{name}\n" + + "test filter: hello %{name | uc}\n" + + "test custom: %{name | custom | uc | lc}\n" + + "test custom_with_arg: %{name | custom_with_arg hello}\n"; + + // test template cache + private static final Cache cache = new Cache(new HashMap() {{ + put("test-template", TEMPLATE); + }}); + + // test arguments + private static final Map args = new HashMap() {{ + put("name", "paul"); + }}; + + // custom filters + private static final Map filters = new HashMap() {{ + // add custom filter + put("custom", new Filter.Handler() { + public String filter(String val, String args[], Map row) { + return "custom"; + } + }); + + // add custom filter with argument + put("custom_with_arg", new Filter.Handler() { + public String filter(String val, String args[], Map row) { + return (args.length > 0) ? args[0] : "custom"; + } + }); + }}; + + public static void main(String params[]) throws Exception { + // add custom filters + Filter.FILTERS.putAll(filters); + + // create and run template + final Template t = new Template(TEMPLATE); + System.out.print(t.run(args)); + + // run cache + System.out.print(cache.run("test-template", args)); + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/actions/Action.java b/java/src/main/java/org/pablotron/luigi/actions/Action.java new file mode 100644 index 0000000..9708199 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/actions/Action.java @@ -0,0 +1,12 @@ +package org.pablotron.luigi.actions; + +import java.util.Map; +import org.pablotron.luigi.Filter; +import org.pablotron.luigi.LuigiError; + +public interface Action { + public String run( + Map filters, + Map args + ) throws LuigiError; +}; diff --git a/java/src/main/java/org/pablotron/luigi/actions/FilterAction.java b/java/src/main/java/org/pablotron/luigi/actions/FilterAction.java new file mode 100644 index 0000000..9115a68 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/actions/FilterAction.java @@ -0,0 +1,41 @@ +package org.pablotron.luigi.actions; + +import java.util.Map; +import org.pablotron.luigi.actions.Action; +import org.pablotron.luigi.FilterReference; +import org.pablotron.luigi.Filter; +import org.pablotron.luigi.LuigiError; + +public final class FilterAction implements Action { + private final String key; + private final FilterReference filters[]; + + public FilterAction(final String key, final FilterReference filters[]) { + this.key = key; + this.filters = filters; + } + + public String run( + Map filters, + Map args + ) throws LuigiError { + // check for key + if (!args.containsKey(key)) + throw new LuigiError("unknown key: " + key); + + // reduce value to result + String r = args.get(key); + for (int i = 0, l = this.filters.length; i < l; i++) { + // get/check filter + Filter.Handler f = filters.get(this.filters[i].name); + if (f == null) + throw new LuigiError("unknown filter: " + this.filters[i].name); + + // run filter + r = f.filter(r, this.filters[i].args, args); + } + + // return result + return r; + } +}; diff --git a/java/src/main/java/org/pablotron/luigi/actions/TextAction.java b/java/src/main/java/org/pablotron/luigi/actions/TextAction.java new file mode 100644 index 0000000..0ad4382 --- /dev/null +++ b/java/src/main/java/org/pablotron/luigi/actions/TextAction.java @@ -0,0 +1,22 @@ +package org.pablotron.luigi.actions; + +import java.util.Map; +import org.pablotron.luigi.actions.Action; +import org.pablotron.luigi.Filter; +import org.pablotron.luigi.LuigiError; + +public final class TextAction implements Action { + private final String text; + + public TextAction(final String text) { + this.text = text; + } + + public String run( + Map filters, + Map args + ) throws LuigiError { + return this.text; + } +}; + diff --git a/java/src/test/java/org/pablotron/luigi/tests/TemplateTest.java b/java/src/test/java/org/pablotron/luigi/tests/TemplateTest.java new file mode 100644 index 0000000..5ff9ede --- /dev/null +++ b/java/src/test/java/org/pablotron/luigi/tests/TemplateTest.java @@ -0,0 +1,69 @@ +import java.util.Map; +import java.util.HashMap; + +import org.pablotron.luigi.LuigiError; +import org.pablotron.luigi.Template; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; + + +public final class TemplateTest { + private static final Map TEST_ARGS = new HashMap() {{ + put("bar", "foo"); + }}; + + private static final Map TEST_MULTIPLE_ARGS = new HashMap() {{ + put("bar", "foo"); + put("baz", "bar"); + }}; + + @Test + public void testNew() throws LuigiError { + final Template t = new Template(""); + + assertNotNull(t); + } + + @Test + public void testRun() throws LuigiError { + final Template t = new Template("foo%{bar}"); + final String r = t.run(TEST_ARGS); + + assertEquals("foofoo", r); + } + + @Test + public void testMultipleKeys() throws LuigiError { + final Template t = new Template("foo%{bar}%{baz}"); + final String r = t.run(TEST_MULTIPLE_ARGS); + + assertEquals("foofoobar", r); + } + + @Test + public void testWhitespace() throws LuigiError { + final Template t = new Template("%{ bar}%{ bar }%{bar }"); + final String r = t.run(TEST_ARGS); + + assertEquals("foofoofoo", r); + } + + @Test + public void testNewlines() throws LuigiError { + final Template t = new Template("%{\nbar}%{\n bar\n }%{bar\n}"); + final String r = t.run(TEST_ARGS); + + assertEquals("foofoofoo", r); + } + + @Test + public void testToString() throws LuigiError { + final Template t = new Template("foo%{bar}"); + final String r = t.toString(); + + assertEquals("foo%{bar}", r); + } +}; -- cgit v1.2.3