]> git.basschouten.com Git - openhab-addons.git/blob
5d38917d746eed02a9f10325b76dd72fa9c1fb71
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.transform.jinja.internal;
14
15 import java.io.IOException;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Map.Entry;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.core.transform.TransformationException;
26 import org.openhab.core.transform.TransformationService;
27 import org.osgi.service.component.annotations.Component;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import com.fasterxml.jackson.databind.JsonNode;
32 import com.fasterxml.jackson.databind.ObjectMapper;
33 import com.hubspot.jinjava.Jinjava;
34
35 /**
36  * <p>
37  * The implementation of {@link TransformationService} which transforms the input by Jinja2 Expressions.
38  *
39  * @author Jochen Klein - Initial contribution
40  *
41  */
42 @NonNullByDefault
43 @Component(property = { "openhab.transform=JINJA" })
44 public class JinjaTransformationService implements TransformationService {
45
46     private final Logger logger = LoggerFactory.getLogger(JinjaTransformationService.class);
47
48     private Jinjava jinjava = new Jinjava();
49
50     /**
51      * Transforms the input <code>value</code> by Jinja template.
52      *
53      * @param template Jinja template
54      * @param value String may contain JSON
55      * @throws TransformationException
56      */
57     @Override
58     public @Nullable String transform(String template, String value) throws TransformationException {
59         logger.debug("about to transform '{}' by the function '{}'", value, template);
60
61         Map<String, @Nullable Object> bindings = new HashMap<>();
62         bindings.put("value", value);
63
64         try {
65             JsonNode tree = new ObjectMapper().readTree(value);
66             bindings.put("value_json", toObject(tree));
67         } catch (IOException e) {
68             // ok, then value_json is null...
69         }
70
71         String transformationResult = jinjava.render(template, bindings);
72
73         logger.debug("transformation resulted in '{}'", transformationResult);
74
75         return transformationResult;
76     }
77
78     private static @Nullable Object toObject(JsonNode node) {
79         switch (node.getNodeType()) {
80             case ARRAY: {
81                 List<@Nullable Object> result = new ArrayList<>();
82                 for (JsonNode el : node) {
83                     result.add(toObject(el));
84                 }
85                 return result;
86             }
87             case NUMBER:
88                 return node.decimalValue();
89             case OBJECT: {
90                 Map<String, @Nullable Object> result = new HashMap<>();
91                 Iterator<Entry<String, JsonNode>> it = node.fields();
92                 while (it.hasNext()) {
93                     Entry<String, JsonNode> field = it.next();
94                     result.put(field.getKey(), toObject(field.getValue()));
95                 }
96                 return result;
97             }
98             case STRING:
99                 return node.asText();
100             case BOOLEAN:
101                 return node.asBoolean();
102             case NULL:
103             default:
104                 return null;
105         }
106     }
107 }