From 433e9677d4fdb8a695c25bbe848647d7b9bcfbd6 Mon Sep 17 00:00:00 2001 From: Devin Smith Date: Tue, 21 Aug 2018 17:20:00 -0500 Subject: [PATCH] added MustacheCustomContext --- README.md | 1 + .../java/com/samskivert/mustache/BasicCollector.java | 12 ++++++++++++ .../samskivert/mustache/MustacheCustomContext.java | 8 ++++++++ .../java/com/samskivert/mustache/MustacheTest.java | 9 +++++++++ 4 files changed, 30 insertions(+) create mode 100644 src/main/java/com/samskivert/mustache/MustacheCustomContext.java diff --git a/README.md b/README.md index 83c1ee2..4cd749f 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ void executeTemplate (Reader template, Writer out, Map data) { The execution context can be any Java object. Variables will be resolved via the following mechanisms: + * If the context is a `MustacheCustomContext`, `MustacheCustomContext.get` will be used. * If the context is a `Map`, `Map.get` will be used. * If a non-void method with the same name as the variable exists, it will be called. * If a non-void method named (for variable `foo`) `getFoo` exists, it will be called. diff --git a/src/main/java/com/samskivert/mustache/BasicCollector.java b/src/main/java/com/samskivert/mustache/BasicCollector.java index 38e14a9..0765f32 100644 --- a/src/main/java/com/samskivert/mustache/BasicCollector.java +++ b/src/main/java/com/samskivert/mustache/BasicCollector.java @@ -35,6 +35,7 @@ public abstract class BasicCollector implements Mustache.Collector } public Mustache.VariableFetcher createFetcher (Object ctx, String name) { + if (ctx instanceof MustacheCustomContext) return CUSTOM_FETCHER; if (ctx instanceof Map) return MAP_FETCHER; // if the name looks like a number, potentially use one of our 'indexing' fetchers @@ -65,6 +66,17 @@ public abstract class BasicCollector implements Mustache.Collector return null; } + protected static final Mustache.VariableFetcher CUSTOM_FETCHER = new Mustache.VariableFetcher() { + public Object get (Object ctx, String name) throws Exception { + MustacheCustomContext custom = (MustacheCustomContext)ctx; + Object val = custom.get(name); + return val == null ? Template.NO_FETCHER_FOUND : val; + } + @Override public String toString () { + return "CUSTOM_FETCHER"; + } + }; + protected static final Mustache.VariableFetcher MAP_FETCHER = new Mustache.VariableFetcher() { public Object get (Object ctx, String name) throws Exception { Map map = (Map)ctx; diff --git a/src/main/java/com/samskivert/mustache/MustacheCustomContext.java b/src/main/java/com/samskivert/mustache/MustacheCustomContext.java new file mode 100644 index 0000000..2f9d5cb --- /dev/null +++ b/src/main/java/com/samskivert/mustache/MustacheCustomContext.java @@ -0,0 +1,8 @@ +package com.samskivert.mustache; + +/** + * Provides a simple interface for callers to implement their own logic for contextual values. + */ +public interface MustacheCustomContext { + Object get(String name) throws Exception; +} diff --git a/src/test/java/com/samskivert/mustache/MustacheTest.java b/src/test/java/com/samskivert/mustache/MustacheTest.java index f0f5738..ce446ae 100644 --- a/src/test/java/com/samskivert/mustache/MustacheTest.java +++ b/src/test/java/com/samskivert/mustache/MustacheTest.java @@ -45,6 +45,15 @@ public class MustacheTest extends SharedTests }); } + @Test public void testMustacheCustomContext() { + test("bar", "{{foo}}", new MustacheCustomContext() { + @Override + public Object get(String name) { + return "foo".equals(name) ? "bar" : null; + } + }); + } + public interface HasDefault { default String getFoo () { return "bar"; } }