From 5059ccf31513c67ef6fce671c3385888b92c4a86 Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Sat, 18 Jun 2016 12:26:02 +0200 Subject: [PATCH] Implemented juplo:variables, that imports variables from JSON-data The processor interprets its argument as name of a thymeleaf-template and parses the retrieved template as JSON-data. The root-element of the JSON- data has to be an object. The variables, that are defined in this object, are imported as node-local variables. --- pom.xml | 11 ++ .../ImportVariablesAttrProcessor.java | 127 ++++++++++++++++++ .../java/de/juplo/thymeleaf/JuploDialect.java | 6 +- 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java diff --git a/pom.xml b/pom.xml index 485b597..6daf99a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,15 +9,26 @@ UTF-8 1.8 + 1.0.0 2.1.5.RELEASE + + org.thymeleaf thymeleaf ${thymeleaf.version} + + + + de.juplo.jackson + simple-mapper + ${simple-mapper.version} + + diff --git a/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java b/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java new file mode 100644 index 0000000..f679591 --- /dev/null +++ b/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java @@ -0,0 +1,127 @@ +package de.juplo.thymeleaf; + + +import com.fasterxml.jackson.core.JsonFactory; +import de.juplo.jackson.SimpleMapper; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map.Entry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.thymeleaf.Arguments; +import org.thymeleaf.Configuration; +import org.thymeleaf.TemplateProcessingParameters; +import org.thymeleaf.context.IContext; +import org.thymeleaf.context.VariablesMap; +import org.thymeleaf.dom.Element; +import org.thymeleaf.processor.ProcessorResult; +import org.thymeleaf.processor.attr.AbstractAttrProcessor; +import org.thymeleaf.resourceresolver.IResourceResolver; +import org.thymeleaf.templateresolver.ITemplateResolver; +import org.thymeleaf.templateresolver.TemplateResolution; + + + +/** + * Retrievs and parses JSON-data and imports the parsed variables as node-local + * variables. + * @author Kai Moritz + */ +public class ImportVariablesAttrProcessor extends AbstractAttrProcessor +{ + public static final int ATTR_PRECEDENCE = 200; + + private static final Logger LOG = + LoggerFactory.getLogger(ImportVariablesAttrProcessor.class); + private static final JsonFactory FACTORY = new JsonFactory(); + + + public ImportVariablesAttrProcessor() + { + super("variables"); + } + + + @Override + public final ProcessorResult processAttribute( + final Arguments arguments, + final Element element, + final String name + ) + { + Configuration config = arguments.getConfiguration(); + String templateName = element.getAttributeValue(name); + + TemplateProcessingParameters params = + new TemplateProcessingParameters( + config, + templateName, + new IContext() // << We will not execute the template, hence we need no context + { + @Override + public VariablesMap getVariables() + { + return new VariablesMap<>(); + } + + @Override + public Locale getLocale() + { + return Locale.getDefault(); + } + + @Override + public void addContextExecutionInfo(String templateName) + { + } + }); + + for (ITemplateResolver t_resolver : config.getTemplateResolvers()) + { + TemplateResolution resolution = t_resolver.resolveTemplate(params); + if (resolution == null) + continue; + if (!"JSON".equals(resolution.getTemplateMode())) + continue; + IResourceResolver r_resolver = resolution.getResourceResolver(); + InputStream is = + r_resolver.getResourceAsStream(params, resolution.getResourceName()); + if (is == null) + continue; + + try + { + Iterator> it = + SimpleMapper.getObjectIterator(FACTORY.createParser(is)); + while(it.hasNext()) + { + Entry entry = it.next(); + element.setNodeLocalVariable(entry.getKey(), entry.getValue()); + } + } + catch (IOException e) + { + LOG.error("cannot retreive {} as JSON: {}", templateName, e.getMessage()); + throw new RuntimeException(e); + } + catch (IllegalArgumentException e) + { + LOG.error("cannot parse {} as JSON: {}", templateName, e.getMessage()); + throw new RuntimeException(e); + } + } + + element.removeAttribute(name); + + return ProcessorResult.OK; + } + + + @Override + public int getPrecedence() + { + return ATTR_PRECEDENCE; + } +} diff --git a/src/main/java/de/juplo/thymeleaf/JuploDialect.java b/src/main/java/de/juplo/thymeleaf/JuploDialect.java index 599791b..e4d2d5b 100644 --- a/src/main/java/de/juplo/thymeleaf/JuploDialect.java +++ b/src/main/java/de/juplo/thymeleaf/JuploDialect.java @@ -13,6 +13,9 @@ import org.thymeleaf.processor.IProcessor; */ public class JuploDialect extends AbstractDialect { + public static final String DIALECT_PREFIX = "juplo"; + + public JuploDialect() { super(); @@ -22,7 +25,7 @@ public class JuploDialect extends AbstractDialect @Override public String getPrefix() { - return "juplo"; + return DIALECT_PREFIX; } @Override @@ -31,6 +34,7 @@ public class JuploDialect extends AbstractDialect final Set processors = new HashSet<>(); processors.add(new ActiveAttrProcessor()); processors.add(new InactiveAttrProcessor()); + processors.add(new ImportVariablesAttrProcessor()); return processors; } } -- 2.20.1