Implemented juplo:variables, that imports variables from JSON-data
[juplo-dialect] / src / main / java / de / juplo / thymeleaf / ImportVariablesAttrProcessor.java
diff --git a/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java b/src/main/java/de/juplo/thymeleaf/ImportVariablesAttrProcessor.java
new file mode 100644 (file)
index 0000000..f679591
--- /dev/null
@@ -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<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;
+  }
+}