WIP: variables-dialect
[maven-thymeleaf-skin] / src / main / java / de / juplo / thymeleaf / ImportVariablesAttrProcessor.java
1 package de.juplo.thymeleaf;
2
3
4 import com.fasterxml.jackson.core.JsonFactory;
5 import com.fasterxml.jackson.core.JsonParser;
6 import com.fasterxml.jackson.core.JsonToken;
7 import com.fasterxml.jackson.databind.JsonNode;
8 import com.fasterxml.jackson.databind.ObjectMapper;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.time.format.DateTimeFormatter;
12 import java.util.Locale;
13 import java.util.Map.Entry;
14 import java.util.logging.Level;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.annotation.Autowired;
18 import org.springframework.beans.factory.annotation.Configurable;
19 import org.springframework.context.MessageSource;
20 import org.thymeleaf.Arguments;
21 import org.thymeleaf.Configuration;
22 import org.thymeleaf.TemplateProcessingParameters;
23 import org.thymeleaf.context.IContext;
24 import org.thymeleaf.dom.Element;
25 import org.thymeleaf.processor.ProcessorResult;
26 import org.thymeleaf.processor.attr.AbstractAttrProcessor;
27 import org.thymeleaf.resourceresolver.IResourceResolver;
28 import org.thymeleaf.standard.expression.IStandardExpression;
29 import org.thymeleaf.templateresolver.ITemplateResolver;
30 import org.thymeleaf.templateresolver.TemplateResolution;
31 import org.thymeleaf.util.StringUtils;
32
33
34
35 /**
36  *
37  * @author kai
38  */
39 @Configurable
40 public class ImportVariablesAttrProcessor extends AbstractAttrProcessor
41 {
42   public static final int ATTR_PRECEDENCE = 200;
43   public static final String ATTR_VAR_NAME =
44       JuploDialect.DIALECT_PREFIX + ":var";
45   public static final String ATTR_LOCALE_NAME =
46       JuploDialect.DIALECT_PREFIX + ":locale";
47   public static final String DEFAULT_VAR_NAME = "crumb";
48
49   private static final Logger LOG =
50       LoggerFactory.getLogger(ImportVariablesAttrProcessor.class);
51   private static final DateTimeFormatter FORMATTER =
52       DateTimeFormatter.ofPattern("dd.MM");
53   private static final ObjectMapper MAPPER = new ObjectMapper();
54   private static final JsonFactory FACTORY = new JsonFactory();
55
56
57   @Autowired
58   MessageSource messageSource;
59   @Autowired
60   Locale defaultLocale;
61
62
63   public ImportVariablesAttrProcessor()
64   {
65     super("crumb");
66   }
67
68
69   @Override
70   public final ProcessorResult processAttribute(
71       final Arguments arguments,
72       final Element element,
73       final String name
74       )
75   {
76     Configuration config = arguments.getConfiguration();
77     String templateName = element.getAttributeValue(name);
78
79     TemplateProcessingParameters params =
80         new TemplateProcessingParameters(
81             config,
82             templateName,
83             (IContext)null // << We will not execute the template, hence we need no context
84             );
85
86     for (ITemplateResolver t_resolver : config.getTemplateResolvers())
87     {
88       TemplateResolution resolution = t_resolver.resolveTemplate(params);
89       if (resolution == null)
90         continue;
91       if (!"JSON".equals(resolution.getTemplateMode()))
92         continue;
93       IResourceResolver r_resolver = resolution.getResourceResolver();
94       InputStream is = r_resolver.getResourceAsStream(params, templateName);
95       if (is == null)
96         continue;
97
98       try
99       {
100         /** Read the JSON and create the variables */
101         JsonParser parser = FACTORY.createParser(is);
102
103         JsonToken root = parser.nextToken();
104
105
106         JsonNode root = MAPPER.readTree(is);
107
108         if (root == null)
109         {
110           LOG.warn("found empty content for {}", templateName);
111           break;
112         }
113
114         if (!root.isObject())
115         {
116           LOG.error("{} must contain an object as root-element", templateName);
117           throw new RuntimeException(
118               "The root-element of " +
119               templateName +
120               " has to be an object, that contains the variable-definitions!"
121               );
122         }
123 root.
124         for (Entry<String, JsonNode> entry : root.fields())
125         {
126           Object var = ImportVariablesAttrProcessor.convert(root.get(i));
127           element.setNodeLocalVariable(name, var);
128         }
129       }
130       catch (IOException e)
131       {
132         LOG.error("cannot parse {} as JSON: {}", templateName, e.getMessage());
133         throw new RuntimeException(e);
134       }
135     }
136
137     element.removeAttribute(name);
138
139     return ProcessorResult.OK;
140   }
141
142
143   @Override
144   public int getPrecedence()
145   {
146     return ATTR_PRECEDENCE;
147   }
148
149
150   public static Object convert(JsonNode node)
151   {
152     return null;
153   }
154 }