Implemented juplo:variables, that imports variables from JSON-data
[juplo-dialect] / src / main / java / de / juplo / thymeleaf / ImportVariablesAttrProcessor.java
1 package de.juplo.thymeleaf;
2
3
4 import com.fasterxml.jackson.core.JsonFactory;
5 import de.juplo.jackson.SimpleMapper;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.util.Iterator;
9 import java.util.Locale;
10 import java.util.Map.Entry;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.thymeleaf.Arguments;
14 import org.thymeleaf.Configuration;
15 import org.thymeleaf.TemplateProcessingParameters;
16 import org.thymeleaf.context.IContext;
17 import org.thymeleaf.context.VariablesMap;
18 import org.thymeleaf.dom.Element;
19 import org.thymeleaf.processor.ProcessorResult;
20 import org.thymeleaf.processor.attr.AbstractAttrProcessor;
21 import org.thymeleaf.resourceresolver.IResourceResolver;
22 import org.thymeleaf.templateresolver.ITemplateResolver;
23 import org.thymeleaf.templateresolver.TemplateResolution;
24
25
26
27 /**
28  * Retrievs and parses JSON-data and imports the parsed variables as node-local
29  * variables.
30  * @author Kai Moritz
31  */
32 public class ImportVariablesAttrProcessor extends AbstractAttrProcessor
33 {
34   public static final int ATTR_PRECEDENCE = 200;
35
36   private static final Logger LOG =
37       LoggerFactory.getLogger(ImportVariablesAttrProcessor.class);
38   private static final JsonFactory FACTORY = new JsonFactory();
39
40
41   public ImportVariablesAttrProcessor()
42   {
43     super("variables");
44   }
45
46
47   @Override
48   public final ProcessorResult processAttribute(
49       final Arguments arguments,
50       final Element element,
51       final String name
52       )
53   {
54     Configuration config = arguments.getConfiguration();
55     String templateName = element.getAttributeValue(name);
56
57     TemplateProcessingParameters params =
58         new TemplateProcessingParameters(
59             config,
60             templateName,
61             new IContext() // << We will not execute the template, hence we need no context
62             {
63               @Override
64               public VariablesMap<String, Object> getVariables()
65               {
66                 return new VariablesMap<>();
67               }
68
69               @Override
70               public Locale getLocale()
71               {
72                 return Locale.getDefault();
73               }
74
75               @Override
76               public void addContextExecutionInfo(String templateName)
77               {
78               }
79             });
80
81     for (ITemplateResolver t_resolver : config.getTemplateResolvers())
82     {
83       TemplateResolution resolution = t_resolver.resolveTemplate(params);
84       if (resolution == null)
85         continue;
86       if (!"JSON".equals(resolution.getTemplateMode()))
87         continue;
88       IResourceResolver r_resolver = resolution.getResourceResolver();
89       InputStream is =
90           r_resolver.getResourceAsStream(params, resolution.getResourceName());
91       if (is == null)
92         continue;
93
94       try
95       {
96         Iterator<Entry<String, Object>> it =
97             SimpleMapper.getObjectIterator(FACTORY.createParser(is));
98         while(it.hasNext())
99         {
100           Entry<String, Object> entry = it.next();
101           element.setNodeLocalVariable(entry.getKey(), entry.getValue());
102         }
103       }
104       catch (IOException e)
105       {
106         LOG.error("cannot retreive {} as JSON: {}", templateName, e.getMessage());
107         throw new RuntimeException(e);
108       }
109       catch (IllegalArgumentException e)
110       {
111         LOG.error("cannot parse {} as JSON: {}", templateName, e.getMessage());
112         throw new RuntimeException(e);
113       }
114     }
115
116     element.removeAttribute(name);
117
118     return ProcessorResult.OK;
119   }
120
121
122   @Override
123   public int getPrecedence()
124   {
125     return ATTR_PRECEDENCE;
126   }
127 }