X-Git-Url: https://juplo.de/gitweb/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fde%2Fjuplo%2Fthymeleaf%2FImportVariablesAttrProcessor.java;h=63963faa32f7ed32db26af71d90153815b77575e;hb=d5f095b05c68b3cf143138faf6a084298cf9de36;hp=bc3f3dae3f6658937b691e175645eb5308af83da;hpb=8b776e8369adb62272bafca7185f90cd0e27b9f0;p=maven-thymeleaf-skin diff --git a/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java b/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java index bc3f3da..63963fa 100644 --- a/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java +++ b/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java @@ -2,16 +2,18 @@ package de.juplo.thymeleaf; import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.io.InputStream; import java.time.format.DateTimeFormatter; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; -import java.util.Map.Entry; -import java.util.logging.Level; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -21,14 +23,13 @@ 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.standard.expression.IStandardExpression; import org.thymeleaf.templateresolver.ITemplateResolver; import org.thymeleaf.templateresolver.TemplateResolution; -import org.thymeleaf.util.StringUtils; @@ -62,7 +63,7 @@ public class ImportVariablesAttrProcessor extends AbstractAttrProcessor public ImportVariablesAttrProcessor() { - super("crumb"); + super("variables"); } @@ -80,8 +81,25 @@ public class ImportVariablesAttrProcessor extends AbstractAttrProcessor new TemplateProcessingParameters( config, templateName, - (IContext)null // << We will not execute the template, hence we need no context - ); + 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()) { @@ -91,7 +109,8 @@ public class ImportVariablesAttrProcessor extends AbstractAttrProcessor if (!"JSON".equals(resolution.getTemplateMode())) continue; IResourceResolver r_resolver = resolution.getResourceResolver(); - InputStream is = r_resolver.getResourceAsStream(params, templateName); + InputStream is = + r_resolver.getResourceAsStream(params, resolution.getResourceName()); if (is == null) continue; @@ -100,18 +119,15 @@ public class ImportVariablesAttrProcessor extends AbstractAttrProcessor /** Read the JSON and create the variables */ JsonParser parser = FACTORY.createParser(is); - JsonToken root = parser.nextToken(); - + JsonToken token = parser.nextToken(); - JsonNode root = MAPPER.readTree(is); - - if (root == null) + if (token == null) { LOG.warn("found empty content for {}", templateName); break; } - if (!root.isObject()) + if (!JsonToken.START_OBJECT.equals(token)) { LOG.error("{} must contain an object as root-element", templateName); throw new RuntimeException( @@ -120,12 +136,40 @@ public class ImportVariablesAttrProcessor extends AbstractAttrProcessor " has to be an object, that contains the variable-definitions!" ); } -root. - for (Entry entry : root.fields()) + + token = parser.nextToken(); + if (token == null) + fail(parser, "unexpected EOF"); + if (JsonToken.END_OBJECT.equals(token)) + { + LOG.warn("found empty object for {}", templateName); + break; + } + + do { - Object var = ImportVariablesAttrProcessor.convert(root.get(i)); - element.setNodeLocalVariable(name, var); + if (!JsonToken.FIELD_NAME.equals(token)) + fail(parser, "expected a field-name"); + + String var_name = parser.getText(); + parser.nextToken(); + Object var_value = convert(parser); + + LOG.debug( + "defining variable {} of type {}", + var_name, + var_value == null ? "NULL" : var_value.getClass().getSimpleName() + ); + element.setNodeLocalVariable(var_name, var_value); + + token = parser.nextToken(); + if (token == null) + fail(parser, "unexpected EOF"); } + while (!JsonToken.END_OBJECT.equals(token)); + + if (parser.nextToken() != null) + fail(parser, "unexpected data after parsed variables"); } catch (IOException e) { @@ -147,8 +191,84 @@ root. } - public static Object convert(JsonNode node) + static Object convert(JsonParser parser) throws IOException + { + JsonToken token = parser.getCurrentToken(); + if (token == null) + fail(parser, "unexpected EOF"); + + switch (token) + { + case VALUE_STRING: return parser.getText(); + case VALUE_NUMBER_INT: return parser.getIntValue(); + case VALUE_NUMBER_FLOAT: return parser.getDoubleValue(); + case START_OBJECT: return convertObject(parser); + case START_ARRAY: return convertArray(parser); + case VALUE_TRUE: return Boolean.TRUE; + case VALUE_FALSE: return Boolean.FALSE; + case VALUE_NULL: return null; + } + + fail(parser, "unexpected token " + token.toString()); + return null; // << Will never be reached, because fail always throws an exception + } + + static Map convertObject(JsonParser parser) throws IOException + { + JsonToken token = parser.nextToken(); + if (token == null) + fail(parser, "unexpected EOF"); + + Map map = new LinkedHashMap<>(); + + while (!JsonToken.END_OBJECT.equals(token)) + { + if (!JsonToken.FIELD_NAME.equals(token)) + fail(parser, "expected a field-name"); + + String name = parser.getText(); + parser.nextToken(); + Object value = convert(parser); + map.put(name, value); + + token = parser.nextToken(); + if (token == null) + fail(parser, "unexpected EOF"); + } + + return map; + } + + static List convertArray(JsonParser parser) throws IOException + { + JsonToken token = parser.nextToken(); + if (token == null) + fail(parser, "unexpected EOF"); + + List list = new LinkedList<>(); + + while (!JsonToken.END_ARRAY.equals(token)) + { + list.add(convert(parser)); + + token = parser.nextToken(); + if (token == null) + fail(parser, "unexpected EOF"); + } + + return list; + } + + static void fail(JsonParser parser, String message) { - return null; + JsonLocation location = parser.getCurrentLocation(); + LOG.error( + "{} at char-offset {} (line {}, column {})", + message, + location.getCharOffset(), + location.getLineNr(), + location.getColumnNr() + ); + throw new RuntimeException("Cannot parse JSON: " + message); } }