--- /dev/null
+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<String, Object> 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<Entry<String, Object>> it =
+ SimpleMapper.getObjectIterator(FACTORY.createParser(is));
+ while(it.hasNext())
+ {
+ Entry<String, Object> 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;
+ }
+}