Support merge JSON to SvcLogicContext
[ccsdk/sli/core.git] / sli / common / src / main / java / org / onap / ccsdk / sli / core / sli / SvcLogicContext.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.core.sli;
23
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Properties;
27 import java.util.Set;
28
29 import com.google.gson.*;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.w3c.dom.Document;
33 import org.w3c.dom.Element;
34 import org.w3c.dom.Node;
35 import org.w3c.dom.NodeList;
36 import org.w3c.dom.Text;
37
38
39 public class SvcLogicContext {
40
41         private static final Logger LOG = LoggerFactory.getLogger(SvcLogicContext.class);
42
43         private HashMap<String, String> attributes;
44
45     private String status = SvcLogicConstants.SUCCESS;
46
47         public SvcLogicContext()
48         {
49                 this.attributes = new HashMap<> ();
50
51         }
52
53         public SvcLogicContext(Properties props)
54         {
55                 this.attributes = new HashMap<> ();
56
57                 if (props.containsKey(CommonConstants.SERVICE_LOGIC_STATUS))
58                 {
59                         this.status = props.getProperty(CommonConstants.SERVICE_LOGIC_STATUS);
60                 }
61
62                 for (Object nameObj : props.keySet())
63                 {
64                         String propName = (String) nameObj;
65                         attributes.put(propName, props.getProperty(propName));
66                 }
67         }
68
69         public String getAttribute(String name)
70         {
71                 if (attributes.containsKey(name))
72                 {
73                         return attributes.get(name);
74                 }
75                 else
76                 {
77                         return null;
78                 }
79         }
80
81         public void setAttribute(String name, String value)
82         {
83                 if (value == null) {
84                         if (attributes.containsKey(name)) {
85                                 attributes.remove(name);
86                         }
87                 } else {
88                         attributes.put(name, value);
89                 }
90         }
91
92         public Set<String> getAttributeKeySet()
93         {
94                 return attributes.keySet();
95         }
96     public Boolean isSuccess() {
97         return status.equals(SvcLogicConstants.SUCCESS);
98   }
99
100     @Deprecated
101         public String getStatus() {
102                 return status;
103         }
104
105     @Deprecated
106         public void setStatus(String status) {
107                 this.status = status;
108         }
109
110     public void markFailed() {
111         this.status = SvcLogicConstants.FAILURE;
112     }
113
114     public void markSuccess() {
115         this.status = SvcLogicConstants.SUCCESS;
116     }
117
118         public Properties toProperties()
119         {
120                 Properties props = new Properties();
121
122                 if (status != null)
123                 {
124                         props.setProperty(CommonConstants.SERVICE_LOGIC_STATUS, status);
125                 }
126
127                 String attrName;
128                 String attrVal;
129                 for (Map.Entry<String, String> entry : attributes.entrySet())
130                 {
131                         attrName = entry.getKey();
132                         attrVal = entry.getValue();
133                         if (attrVal == null) {
134                                 LOG.warn("attribute {} value is null - setting to empty string", attrName);
135                                 props.setProperty(attrName, "");
136                         } else {
137                                 props.setProperty(attrName, attrVal);
138                         }
139                 }
140
141                 return props;
142         }
143
144         public void mergeDocument(String pfx, Document doc) {
145                 String prefix = "";
146
147                 if (pfx != null) {
148                         prefix = pfx;
149                 }
150
151                 Element root = doc.getDocumentElement();
152
153                 mergeElement(prefix, root, null);
154         }
155
156         public void mergeElement(String pfx, Element element, Map<String, Integer> nodeMap) {
157
158                 // In XML, cannot tell the difference between containers and lists.
159                 // So, have to treat each element as both (ugly but necessary).
160                 // We do this by passing a nodeMap to be used to count instance of each tag,
161                 // which will be used to set _length and to set index
162
163                 LOG.trace("mergeElement({},{},{})", pfx, element.getTagName(), nodeMap);
164
165                 String curTagName = element.getTagName();
166                 String prefix = curTagName;
167
168                 if (pfx != null) {
169                         prefix = pfx + "." + prefix;
170                 }
171
172                 int myIdx = 0;
173
174                 if (nodeMap != null) {
175                         if (nodeMap.containsKey(curTagName)) {
176                                 myIdx = nodeMap.get(curTagName);
177                         }
178
179                         nodeMap.put(curTagName, myIdx+1);
180                         this.setAttribute(prefix+"_length", Integer.toString(myIdx+1));
181                 }
182
183                 NodeList children = element.getChildNodes();
184
185                 int numChildren  = children.getLength();
186
187                 Map<String, Integer> childMap = new HashMap<>();
188                 Map<String, Integer> idxChildMap = new HashMap<>();
189
190                 for (int i = 0 ; i < numChildren ; i++) {
191                         Node curNode = children.item(i);
192
193                         if (curNode instanceof Text) {
194                                 Text curText = (Text) curNode;
195                                 String curTextValue = curText.getTextContent();
196                                 LOG.trace("Setting ctx variable {} = {}", prefix, curTextValue);
197                                 this.setAttribute(prefix, curText.getTextContent());
198
199
200                         } else if (curNode instanceof Element) {
201                                 mergeElement(prefix, (Element) curNode, childMap);
202                                 if (nodeMap != null) {
203
204                                         mergeElement(prefix+"["+myIdx+"]", (Element)curNode, idxChildMap);
205
206                                 }
207                         }
208                 }
209
210         }
211
212         public void mergeJson(String pfx, String jsonString) {
213                 JsonParser jp = new JsonParser();
214                 JsonElement element = jp.parse(jsonString);
215
216                 mergeJsonObject(element.getAsJsonObject(), pfx+".");
217         }
218
219         public void mergeJsonObject(JsonObject jsonObject, String pfx) {
220                 for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
221                         if (entry.getValue().isJsonObject()) {
222                                 mergeJsonObject(entry.getValue().getAsJsonObject(), pfx + entry.getKey() + ".");
223                         } else if (entry.getValue().isJsonArray()) {
224                                 JsonArray array = entry.getValue().getAsJsonArray();
225                                 this.setAttribute(pfx + entry.getKey() + "_length", String.valueOf(array.size()));
226                                 Integer arrayIdx = 0;
227                                 for (JsonElement element : array) {
228                                         if (element.isJsonObject()) {
229                                                 mergeJsonObject(element.getAsJsonObject(), pfx + entry.getKey() + "[" + arrayIdx + "].");
230                                         }
231                                         arrayIdx++;
232                                 }
233                         } else {
234                                 if (entry.getValue() instanceof JsonNull) {
235                                         LOG.debug("Skipping parameter {} with null value",entry.getKey());
236
237                                 } else {
238                                         this.setAttribute(pfx + entry.getKey(), entry.getValue().getAsString());
239                                 }
240                         }
241                 }
242         }
243
244         public String resolve(String ctxVarName) {
245
246                 if (ctxVarName.indexOf('[') == -1) {
247                         // Ctx variable contains no arrays
248                         return getAttribute(ctxVarName);
249                 }
250
251                 // Resolve any array references
252                 StringBuilder sbuff = new StringBuilder();
253                 String[] ctxVarParts = ctxVarName.split("\\[");
254                 sbuff.append(ctxVarParts[0]);
255                 for (int i = 1; i < ctxVarParts.length; i++) {
256                         if (ctxVarParts[i].startsWith("$")) {
257                                 int endBracketLoc = ctxVarParts[i].indexOf(']');
258                                 if (endBracketLoc == -1) {
259                                         // Missing end bracket ... give up parsing
260                                         LOG.warn("Variable reference {} seems to be missing a ']'", ctxVarName);
261                                         return getAttribute(ctxVarName);
262                                 }
263
264                                 String idxVarName = ctxVarParts[i].substring(1, endBracketLoc);
265                                 String remainder = ctxVarParts[i].substring(endBracketLoc);
266
267                                 sbuff.append("[");
268                                 sbuff.append(this.getAttribute(idxVarName));
269                                 sbuff.append(remainder);
270
271                         } else {
272                                 // Index is not a variable reference
273                                 sbuff.append("[");
274                                 sbuff.append(ctxVarParts[i]);
275                         }
276                 }
277
278                 return getAttribute(sbuff.toString());
279         }
280
281 }