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.HashMap;
+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;
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;
/** 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(
" has to be an object, that contains the variable-definitions!"
);
}
-root.
- for (Entry<String, JsonNode> entry : root.fields())
+
+ token = parser.nextToken();
+ if (token == null)
+ fail(parser, "unexpected EOF");
+ if (!JsonToken.END_OBJECT.equals(token))
{
- Object var = ImportVariablesAttrProcessor.convert(root.get(i));
- element.setNodeLocalVariable(name, var);
+ LOG.warn("found empty object for {}", templateName);
+ break;
}
+
+ do
+ {
+ if (!JsonToken.FIELD_NAME.equals(token))
+ fail(parser, "expected a field-name");
+
+ String var_name = parser.getText();
+ 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)
{
}
- public static Object convert(JsonNode node)
+ static Object convert(JsonParser parser) throws IOException
+ {
+ JsonToken token = parser.nextToken();
+ 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<String, Object> convertObject(JsonParser parser) throws IOException
+ {
+ JsonToken token = parser.nextToken();
+ if (token == null)
+ fail(parser, "unexpected EOF");
+
+ Map<String, Object> map = new HashMap<>();
+
+ while (!JsonToken.END_OBJECT.equals(token))
+ {
+ if (!JsonToken.FIELD_NAME.equals(token))
+ fail(parser, "expected a field-name");
+
+ map.put(parser.getText(), convert(parser));
+
+ token = parser.nextToken();
+ if (token == null)
+ fail(parser, "unexpected EOF");
+ }
+
+ return map;
+ }
+
+ static List<Object> convertArray(JsonParser parser) throws IOException
+ {
+ JsonToken token = parser.nextToken();
+ if (token == null)
+ fail(parser, "unexpected EOF");
+
+ List<Object> 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);
}
}