9dbd4b171d5163908f6962886ee7734c48201794
[so.git] / bpmn / MSOCoreBPMN / src / main / java / org / openecomp / mso / bpmn / core / json / JsonUtils.java
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * ONAP - SO\r
4  * ================================================================================\r
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
6  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.\r
7  * ================================================================================\r
8  * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * you may not use this file except in compliance with the License.\r
10  * You may obtain a copy of the License at\r
11  * \r
12  *      http://www.apache.org/licenses/LICENSE-2.0\r
13  * \r
14  * Unless required by applicable law or agreed to in writing, software\r
15  * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * See the License for the specific language governing permissions and\r
18  * limitations under the License.\r
19  * ============LICENSE_END=========================================================\r
20  */\r
21 \r
22 package org.openecomp.mso.bpmn.core.json;\r
23 \r
24 import java.util.ArrayList;\r
25 import java.util.Iterator;\r
26 import java.util.List;\r
27 import java.util.Map;\r
28 import java.util.HashMap;\r
29 import java.util.StringTokenizer;\r
30 \r
31 import org.camunda.bpm.engine.runtime.Execution;\r
32 import org.json.JSONArray;\r
33 import org.json.JSONException;\r
34 import org.json.JSONObject;\r
35 import org.json.XML;\r
36 \r
37 //import org.openecomp.mso.bpmn.core.BPMNLogger;\r
38 import org.openecomp.mso.bpmn.core.xml.XmlTool;\r
39 import org.openecomp.mso.logger.MsoLogger;\r
40 \r
41 /**\r
42  * Utility class for JSON processing\r
43  * \r
44  * @version 1.0\r
45  */\r
46 \r
47 public class JsonUtils {\r
48 \r
49         private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL);\r
50         private static int MSOJsonIndentFactor = 3;\r
51 \r
52         /**\r
53          * Uses the JSONObject static method to convert a XML doc to JSON.\r
54          *\r
55          * @param  xml          String containing the XML doc\r
56          * @param  pretty       flag to determine if the output should be formatted\r
57          * @return String containing the JSON translation\r
58          */\r
59         public static String xml2json(String xml, Boolean pretty) {\r
60 //              String isDebugLogEnabled = "true";\r
61                 try {\r
62                         // name spaces cause problems, so just remove them\r
63                         JSONObject jsonObj = XML.toJSONObject(XmlTool.removeNamespaces(xml));\r
64                         if (!pretty) {\r
65                                 return jsonObj.toString();\r
66                         } else {\r
67                                 // add an indent to make it 'pretty'\r
68                                 return jsonObj.toString(MSOJsonIndentFactor);\r
69                         }\r
70                 } catch (Exception e){\r
71                                 msoLogger.debug("xml2json(): unable to parse xml and convert to json. Exception was: " + e.toString(), e);\r
72                                 return null;\r
73                 }\r
74         }\r
75 \r
76         /**\r
77          * Invokes xml2json(String, Boolean) defaulting to 'pretty' output.\r
78          *\r
79          * @param  xml  String containing the XML doc\r
80          * @return String containing the JSON translation\r
81          */\r
82         public static String xml2json(String xml) {\r
83                 return xml2json(xml, true);\r
84         }\r
85 \r
86         /**\r
87          * Uses the JSONObject static method to convert a JSON doc to XML.\r
88          * Note: this method may not generate valid XML if the JSONObject\r
89          * contains JSONArrays which are used to represent XML attributes\r
90          * in the JSON doc.\r
91          *\r
92          * @param  jsonStr      String containing the JSON doc\r
93          * @param  pretty       flag to determine if the output should be formatted\r
94          * @return String containing the XML translation\r
95          */\r
96         public static String json2xml(String jsonStr, Boolean pretty) {\r
97 //              String isDebugLogEnabled = "true";\r
98                 try {\r
99                         JSONObject jsonObj = new JSONObject(jsonStr);\r
100                         if (pretty) {\r
101 //                              return XmlTool.normalize(XML.toString(jsonObj));\r
102 //                              use the local class method which properly handles certain JSONArray content\r
103                                 return XmlTool.normalize(toXMLString(jsonObj, null));\r
104                         } else {\r
105 //                              return XML.toString(jsonObj);\r
106 //                              use the local class method which properly handles certain JSONArray content\r
107                                 return toXMLString(jsonObj, null);\r
108                         }\r
109                 } catch (Exception e){\r
110                                 msoLogger.debug("json2xml(): unable to parse json and convert to xml. Exception was: " + e.toString(), e);\r
111                                 return null;\r
112                 }\r
113         }\r
114 \r
115         /**\r
116          * Uses a modified version of the org.json.XML toString() algorithm\r
117          * to convert a JSONObject to an XML Doc. The intent of this is to\r
118          * correctly generate XML from JSON including TAGs for JSONArrays\r
119          *\r
120          * @param  jsonObj      org.json.JSON object to be converted to XML\r
121          * @param  tagName      optional XML tagname supplied primarily during recursive calls\r
122          * @return String containing the XML translation\r
123          */\r
124         public static String toXMLString(Object obj, String tagName) throws JSONException {\r
125                 StringBuffer strBuf = new StringBuffer();\r
126                 int i;\r
127                 JSONArray jsonArr;\r
128                 JSONObject jsonObj;\r
129                 String key;\r
130                 Iterator<String> keys;\r
131                 int len;\r
132                 String str;\r
133                 Object curObj;\r
134                 if (obj instanceof JSONObject) {\r
135                         // msoLogger.debug("toXMLString(): is a JSONObject");\r
136                         // append "<tagName>" to the XML output\r
137                         if (tagName != null) {\r
138 //                              msoLogger.debug("toXMLString(): adding opening tagName: " + tagName);\r
139                                 strBuf.append("<");\r
140                                 strBuf.append(tagName);\r
141                                 strBuf.append(">");\r
142                         }\r
143                         // iterate thru the keys.\r
144                         jsonObj = (JSONObject) obj;\r
145                         keys = jsonObj.keys();\r
146                         while (keys.hasNext()) {\r
147                                 key = keys.next();\r
148                                 // msoLogger.debug("toXMLString(): key is " + k);\r
149                                 curObj = jsonObj.opt(key);\r
150                                 if (curObj == null) {\r
151                                         curObj = "";\r
152                                 }\r
153                                 if (curObj instanceof String) {\r
154                                         str = (String) curObj;\r
155                                 } else {\r
156                                         str = null;\r
157                                 }\r
158                                 // append the content to the XML output\r
159                                 if (key.equals("content")) {\r
160                                         if (curObj instanceof JSONArray) {\r
161                                                 jsonArr = (JSONArray) curObj;\r
162                                                 len = jsonArr.length();\r
163                                                 for (i = 0; i < len; i += 1) {\r
164                                                         if (i > 0) {\r
165                                                                 strBuf.append('\n');\r
166                                                         }\r
167                                                         strBuf.append(XML.escape(jsonArr.get(i).toString()));\r
168                                                 }\r
169                                         } else {\r
170                                                 strBuf.append(XML.escape(curObj.toString()));\r
171                                         }\r
172                                 // append an array of similar keys to the XML output\r
173                                 } else if (curObj instanceof JSONArray) {\r
174                                         jsonArr = (JSONArray) curObj;\r
175                                         len = jsonArr.length();\r
176 //                                      msoLogger.debug("toXMLString(): found JSONArray: " + key + ", size: " + len);\r
177                                         for (i = 0; i < len; i += 1) {\r
178                                                 curObj = jsonArr.get(i);\r
179                                                 if (curObj instanceof JSONArray) {\r
180 //                                                      The XML tags for the nested array should be generated below when this method\r
181 //                                                      is called recursively and the JSONArray object is passed\r
182 //                                                      strBuf.append("<");\r
183 //                                                      strBuf.append(key);\r
184 //                                                      strBuf.append(">");\r
185                                                         strBuf.append(toXMLString(curObj, null));\r
186 //                                                      strBuf.append("</");\r
187 //                                                      strBuf.append(key);\r
188 //                                                      strBuf.append(">");\r
189                                                 } else {\r
190 //                                                      msoLogger.debug("toXMLString(): recursive call toXML() with tagName null");\r
191                                                         // append the opening tag for the array (before 1st element)\r
192                                                         if (i == 0) {\r
193                                                                 strBuf.append("<");\r
194                                                                 strBuf.append(key);\r
195                                                                 strBuf.append(">");\r
196                                                         }\r
197                                                         // append the opening tag for the array\r
198                                                         strBuf.append(toXMLString(curObj, null));\r
199                                                         // append the closing tag for the array (after last element)\r
200                                                         if (i == (len - 1)) {\r
201                                                                 strBuf.append("</");\r
202                                                                 strBuf.append(key);\r
203                                                                 strBuf.append(">");\r
204                                                         }\r
205                                                 }\r
206                                         }\r
207                                 } else if (curObj.equals("")) {\r
208                                         // append a closing tag "<key>" to the XML output\r
209                                         strBuf.append("<");\r
210                                         strBuf.append(key);\r
211                                         strBuf.append("/>");\r
212                                 } else {\r
213 //                                      msoLogger.debug("toXMLString(): recursive call toXMLString() with tagName: " + key);\r
214                                         strBuf.append(toXMLString(curObj, key));\r
215                                 }\r
216                                 // msoLogger.debug("toXML(): partial XML: " + strBuf.toString());\r
217                         }\r
218                         if (tagName != null) {\r
219                                 // append the closing tag "</tagName>" to the XML output\r
220 //                              msoLogger.debug("toXMLString(): adding closing tagName: " + tagName);\r
221                                 strBuf.append("</");\r
222                                 strBuf.append(tagName);\r
223                                 strBuf.append(">");\r
224                         }\r
225                         return strBuf.toString();\r
226                 // XML does not have good support for arrays. If an array appears in a place\r
227                 // where XML is lacking, synthesize an < array > element.\r
228                 } else if (obj instanceof JSONArray) {\r
229                         jsonArr = (JSONArray) obj;\r
230                         len = jsonArr.length();\r
231                         for (i = 0; i < len; ++i) {\r
232                                 curObj = jsonArr.opt(i);\r
233                                 strBuf.append(toXMLString(curObj, (tagName == null) ? "array"\r
234                                                 : tagName));\r
235                         }\r
236                         return strBuf.toString();\r
237                 } else {\r
238 //                      msoLogger.debug("toXML(): in else block with tagName: " + tagName);\r
239                         str = (obj == null) ? "null" : XML.escape(obj.toString());\r
240                         return (tagName == null) ? "\"" + str + "\""\r
241                                         : (str.length() == 0) ? "<" + tagName + "/>" : "<"\r
242                                                         + tagName + ">" + str + "</" + tagName + ">";\r
243                 }\r
244         }\r
245 \r
246         /**\r
247          * Invokes json2xml(String, Boolean) defaulting to 'pretty' output.\r
248          *\r
249          * @param  jsonStr      String containing the XML doc\r
250          * @return String containing the JSON translation\r
251          */\r
252         public static String json2xml(String jsonStr) {\r
253                 return json2xml(jsonStr, true);\r
254         }\r
255 \r
256         /**\r
257          * Formats the JSON String using the value of MSOJsonIndentFactor.\r
258          *\r
259          * @param  jsonStr      String containing the JSON doc\r
260          * @return String containing the formatted JSON doc\r
261          */\r
262         public static String prettyJson(String jsonStr) {\r
263 //              String isDebugLogEnabled = "true";\r
264                 try {\r
265                         JSONObject jsonObj = new JSONObject(jsonStr);\r
266                         return jsonObj.toString(MSOJsonIndentFactor);\r
267                 } catch (Exception e){\r
268                         msoLogger.debug("prettyJson(): unable to parse/format json input. Exception was: " + e.toString(), e);\r
269                         return null;\r
270                 }\r
271         }\r
272 \r
273         /**\r
274          * Returns an Iterator over the JSON keys in the specified JSON doc.\r
275          *\r
276          * @param  jsonStr      String containing the JSON doc\r
277          * @return Iterator over the JSON keys\r
278          * @throws JSONException if the doc cannot be parsed\r
279          */\r
280         public static Iterator <String> getJsonIterator(String jsonStr) throws JSONException {\r
281                 return new JSONObject(jsonStr).keys();\r
282         }\r
283 \r
284         /**\r
285          * Returns the name of the "root" property in the specified JSON doc. The\r
286          * "root" property is the single top-level property in the JSON doc. An\r
287          * exception is thrown if the doc is empty or if it contains more than one\r
288          * top-level property.\r
289          *\r
290          * @param  jsonStr      String containing the JSON doc\r
291          * @return the name of the "root" property\r
292          * @throws JSONException if the doc cannot be parsed, or if it is empty, or if\r
293          *         it contains more than one top-level property\r
294          */\r
295         public static String getJsonRootProperty(String jsonStr) throws JSONException {\r
296                 Iterator<String> iter = getJsonIterator(jsonStr);\r
297 \r
298                 if (!iter.hasNext()) {\r
299                         throw new JSONException("Empty JSON object");\r
300                 }\r
301 \r
302                 String rootPropertyName = iter.next();\r
303 \r
304                 if (iter.hasNext()) {\r
305                         throw new JSONException("JSON object has more than one root property");\r
306                 }\r
307 \r
308                 return rootPropertyName;\r
309         }\r
310 \r
311         /**\r
312          * Invokes the getJsonRawValue() method and returns the String equivalent of\r
313          * the object returned.\r
314          *\r
315          * TBD: May need separate methods for boolean, float, and integer fields if the\r
316          * String representation is not sufficient to meet client needs.\r
317          *\r
318          * @param  jsonStr      String containing the JSON doc\r
319          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
320          * @return String field value associated with keys\r
321          */\r
322         public static String getJsonValue(String jsonStr, String keys) {\r
323 //              String isDebugLogEnabled = "true";\r
324                 try {\r
325                                 Object rawValue = getJsonRawValue(jsonStr, keys);\r
326                                 if (rawValue == null) {\r
327                                         return null;\r
328                                 } else {\r
329                                         if (rawValue instanceof String) {\r
330                                                 msoLogger.debug("getJsonValue(): the raw value is a String Object=" + ((String) rawValue));\r
331                                                 return (String) rawValue;\r
332                                         } else {\r
333                                                 msoLogger.debug("getJsonValue(): the raw value is NOT a String Object=" + rawValue.toString());\r
334                                                 return rawValue.toString();\r
335                                         }\r
336                                 }\r
337                 } catch (Exception e) {\r
338                                 msoLogger.debug("getJsonValue(): unable to parse json to retrieve value for field=" + keys + ". Exception was: " + e.toString(),e);\r
339                 }\r
340                 return null;\r
341         }\r
342 \r
343         /**\r
344          * Invokes the getJsonRawValue() method with the wrap flag set to true\r
345          * and returns the String equivalent of the json node object returned.\r
346          *\r
347          * @param  jsonStr      String containing the JSON doc\r
348          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
349          * @return String field value associated with keys\r
350          */\r
351         public static String getJsonNodeValue(String jsonStr, String keys) {\r
352 //              String isDebugLogEnabled = "true";\r
353                 try {\r
354                                 Object rawValue = getJsonRawValue(jsonStr, keys, true);\r
355                                 if (rawValue == null) {\r
356                                         return null;\r
357                                 } else {\r
358                                         if (rawValue instanceof String) {\r
359                                                 msoLogger.debug("getJsonNodeValue(): the raw value is a String Object=" + ((String) rawValue));\r
360                                                 return (String) rawValue;\r
361                                         } else {\r
362                                                 msoLogger.debug("getJsonNodeValue(): the raw value is NOT a String Object=" + rawValue.toString());\r
363                                                 return rawValue.toString();\r
364                                         }\r
365                                 }\r
366                 } catch (Exception e) {\r
367                                 msoLogger.debug("getJsonNodeValue(): unable to parse json to retrieve node for field=" + keys + ". Exception was: " + e.toString(), e);\r
368                 }\r
369                 return null;\r
370         }\r
371 \r
372         /**\r
373          * Invokes the getJsonRawValue() method and returns the String equivalent of\r
374          * the object returned.\r
375          *\r
376          * TBD: May need separate methods for boolean, float, and integer fields if the\r
377          * String representation is not sufficient to meet client needs.\r
378          *\r
379          * @param  jsonStr      String containing the JSON doc\r
380          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
381          * @return String field value associated with keys\r
382          */\r
383         public static int getJsonIntValue(String jsonStr, String keys) {\r
384 //              String isDebugLogEnabled = "true";\r
385                 try {\r
386                                 Object rawValue = getJsonRawValue(jsonStr, keys);\r
387                                 if (rawValue == null) {\r
388                                         return 0;\r
389                                 } else {\r
390                                         if (rawValue instanceof Integer) {\r
391                                                 msoLogger.debug("getJsonValue(): the raw value is an Integer Object=" + ((String) rawValue).toString());\r
392                                                 return (Integer) rawValue;\r
393                                         } else {\r
394                                                 msoLogger.debug("getJsonValue(): the raw value is NOT an Integer Object=" + rawValue.toString());\r
395                                                 return 0;\r
396                                         }\r
397                                 }\r
398                 } catch (Exception e) {\r
399                                 msoLogger.debug("getJsonValue(): unable to parse json to retrieve value for field=" + keys + ". Exception was: " + e.toString(), e);\r
400                 }\r
401                 return 0;\r
402         }\r
403 \r
404         /**\r
405          * Invokes the getJsonRawValue() method and returns the boolean equivalent of\r
406          * the object returned.\r
407          *\r
408          * @param  jsonStr      String containing the JSON doc\r
409          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
410          * @return boolean field value associated with keys - default is false\r
411          */\r
412         public static boolean getJsonBooleanValue(String jsonStr, String keys) {\r
413                 try {\r
414                                 Object rawValue = getJsonRawValue(jsonStr, keys);\r
415                                 if (rawValue == null) {\r
416                                         return false;\r
417                                 } else {\r
418                                         if (rawValue instanceof Boolean) {\r
419                                                 msoLogger.debug("getJsonValue(): the raw value is a Boolean Object=" + ((String) rawValue));\r
420                                                 return (Boolean) rawValue;\r
421                                         } else {\r
422                                                 msoLogger.debug("getJsonValue(): the raw value is NOT an Boolean Object=" + rawValue.toString());\r
423                                                 return false;\r
424                                         }\r
425                                 }\r
426                 } catch (Exception e) {\r
427                                 msoLogger.debug("getJsonValue(): unable to parse json to retrieve value for field=" + keys + ". Exception was: " + e.toString(),e);\r
428                 }\r
429                 return false;\r
430         }\r
431 \r
432         /**\r
433          * Invokes the getJsonParamValue() method to obtain the JSONArray associated with\r
434          * the specified keys. The JSONArray is then walked to retrieve the first array\r
435          * value associated with the specified field name (index=0).\r
436          *\r
437          * @param  jsonStr      String containing the JSON doc\r
438          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
439          * @param  name         field name for the param to be retrieved\r
440          * @return String param value associated with field name\r
441          */\r
442         public static String getJsonParamValue(String jsonStr, String keys, String name) {\r
443                 return getJsonParamValue(jsonStr, keys, name, 0);\r
444         }\r
445 \r
446         /**\r
447          * Invokes the getJsonRawValue() method to obtain the JSONArray associated with\r
448          * the specified keys. The JSONArray is then walked to retrieve the nth array\r
449          * value associated with the specified field name and index.\r
450          *\r
451          * @param  jsonStr      String containing the JSON doc\r
452          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
453          * @param  name         field name for the param to be retrieved\r
454          * @param  index    the nth param associated with name starting at 0\r
455          * @return String param value associated with field name\r
456          */\r
457         public static String getJsonParamValue(String jsonStr, String keys, String name, int index) {\r
458 //              String isDebugLogEnabled = "true";\r
459                 try {\r
460                         Object rawValue = getJsonRawValue(jsonStr, keys);\r
461                         if (rawValue == null) {\r
462                                 return null;\r
463                         } else {\r
464                                 if (rawValue instanceof JSONArray) {\r
465                                         msoLogger.debug("getJsonParamValue(): keys=" + keys + " points to JSONArray: " + ((JSONArray) rawValue).toString());\r
466                                         int arrayLen = ((JSONArray) rawValue).length();\r
467                                         if (index < 0 || arrayLen < index+1) {\r
468                                                 msoLogger.debug("getJsonParamValue(): index: " + index + " is out of bounds for array size of " + arrayLen);\r
469                                                 return null;\r
470                                         }\r
471                                         int foundCnt = 0;\r
472                                         for (int i = 0; i < arrayLen; i++) {\r
473                                                 msoLogger.debug("getJsonParamValue(): index: " + i + ", value: " + ((JSONArray) rawValue).get(i).toString());\r
474                                                 if (((JSONArray) rawValue).get(i) instanceof JSONObject) {\r
475                                                         msoLogger.debug("getJsonParamValue(): index: " + i + " is a JSONObject");\r
476                                                         JSONObject jsonObj = (JSONObject)((JSONArray) rawValue).get(i);\r
477                                                         String parmValue = jsonObj.get(name).toString();\r
478                                                         if (parmValue != null) {\r
479                                                                 msoLogger.debug("getJsonParamValue(): found value: " + parmValue + " for name: " + name + " and index: " + i);\r
480                                                                 if (foundCnt == index) {\r
481                                                                         return parmValue;\r
482                                                                 } else {\r
483                                                                         foundCnt++;\r
484                                                                         continue;\r
485                                                                 }\r
486                                                         } else {\r
487                                                                 continue;\r
488                                                         }\r
489                                                 } else {\r
490                                                         msoLogger.debug("getJsonParamValue(): the JSONArray element is NOT a JSONObject=" + rawValue.toString());\r
491                                                         return null;\r
492                                                 }\r
493                                         }\r
494                                         msoLogger.debug("getJsonParamValue(): content value NOT found for name: " + name);\r
495                                         return null;\r
496                                 } else {\r
497                                         msoLogger.debug("getJsonParamValue(): the raw value is NOT a JSONArray Object=" + rawValue.toString());\r
498                                         return null;\r
499                                 }\r
500                         }\r
501                 } catch (JSONException je) {\r
502                                 // JSONObject::get() throws this exception if one of the specified keys is not found\r
503                                 msoLogger.debug("getJsonParamValue(): caught JSONException attempting to retrieve param value for keys:" + keys + ", name=" + name, je);\r
504                 } catch (Exception e) {\r
505                                 msoLogger.debug("getJsonParamValue(): unable to parse json to retrieve value for field=" + keys + ". Exception was: " + e.toString(), e);\r
506                 }\r
507                 return null;\r
508         }\r
509 \r
510         /**\r
511          * Wrapper to generate the JSONObject to pass to the getJsonValueForKey(JSONObject, String)\r
512          * method so that recursion over the subobjects can be supported there\r
513          *\r
514          * @param  jsonStr      String containing the JSON doc\r
515          * @param  key          key to the target value\r
516          * @return String field value associated with key\r
517          */\r
518         public static String getJsonValueForKey(String jsonStr, String key) {\r
519 //              String isDebugLogEnabled = "true";\r
520                 try {\r
521                         JSONObject jsonObj = new JSONObject(jsonStr);\r
522                         if (jsonObj != null) {\r
523                                 return getJsonValueForKey(jsonObj, key);\r
524                         }\r
525                 } catch (Exception e) {\r
526                                 msoLogger.debug("getJsonValueForKey(): unable to parse json to retrieve value for field=" + key + ". Exception was: " + e.toString(), e);\r
527                 }\r
528                 return null;\r
529         }\r
530 \r
531         /**\r
532          * Walks the JSONObject (and sub-objects recursively), searching for the first value associated with the\r
533          * single key/field name specified. Returns the associated value if found or null if the key is not found\r
534          *\r
535          * @param  jsonObj      JSONObject representation of the the JSON doc\r
536          * @param  key          key to the target value\r
537          * @return String field value associated with key\r
538          */\r
539         public static String getJsonValueForKey(JSONObject jsonObj, String key) {\r
540 //              String isDebugLogEnabled = "true";\r
541                 String keyValue = null;\r
542                 try {\r
543                         if (jsonObj.has(key)) {\r
544                                 msoLogger.debug("getJsonValueForKey(): found value for key=" + key);\r
545                                 Object value = jsonObj.get(key);\r
546                                 if (value == null)\r
547                                         return null;\r
548                                 else\r
549                                         return ((String) value);\r
550                         } else {\r
551                                 msoLogger.debug("getJsonValueForKey(): iterating over the keys");\r
552                                 Iterator <String> itr = jsonObj.keys();\r
553                                 while (itr.hasNext()) {\r
554                                         String nextKey = (String) itr.next();\r
555                                         Object obj = jsonObj.get(nextKey);\r
556                                         if (obj instanceof JSONObject) {\r
557                                                 msoLogger.debug("getJsonValueForKey(): key=" + nextKey + ", points to JSONObject, recursive call");\r
558                                                 keyValue = getJsonValueForKey((JSONObject) obj, key);\r
559                                                 if (keyValue != null) {\r
560                                                         msoLogger.debug("getJsonValueForKey(): found value=" + keyValue + ", for key=" + key);\r
561                                                         break;\r
562                                                 }\r
563                                         } else {\r
564                                                 msoLogger.debug("getJsonValueForKey(): key=" + nextKey + ", does not point to a JSONObject, next key");\r
565                                         }\r
566                                 }\r
567                         }\r
568                 } catch (JSONException je) {\r
569                                 // JSONObject::get() throws this exception if one of the specified keys is not found\r
570                                 msoLogger.debug("getJsonValueForKey(): caught JSONException attempting to retrieve value for key=" + key, je);\r
571                                 keyValue = null;\r
572                 } catch (Exception e) {\r
573                                 msoLogger.debug("getJsonValueForKey(): unable to parse json to retrieve value for field=" + key + ". Exception was: " + e.toString(), e);\r
574                 }\r
575                 return keyValue;\r
576         }\r
577 \r
578         /**\r
579          * Walks the JSONObject (and sub-objects recursively), searching for the first value associated with the\r
580          * single key/field name specified. Returns the associated value if found or null if the key is not found\r
581          *\r
582          * @param  jsonObj      JSONObject representation of the the JSON doc\r
583          * @param  key          key to the target value\r
584          * @return String field value associated with key\r
585          */\r
586         public static Integer getJsonIntValueForKey(JSONObject jsonObj, String key) {\r
587 //              String isDebugLogEnabled = "true";\r
588                 Integer keyValue = 0;\r
589                 try {\r
590                         if (jsonObj.has(key)) {\r
591                                 msoLogger.debug("getJsonValueForKey(): found value for key=" + key);\r
592                                 return (Integer) jsonObj.get(key);\r
593                         } else {\r
594                                 msoLogger.debug("getJsonValueForKey(): iterating over the keys");\r
595                                 Iterator <String> itr = jsonObj.keys();\r
596                                 while (itr.hasNext()) {\r
597                                         String nextKey = (String) itr.next();\r
598                                         Object obj = jsonObj.get(nextKey);\r
599                                         if (obj instanceof JSONObject) {\r
600                                                 msoLogger.debug("getJsonValueForKey(): key=" + nextKey + ", points to JSONObject, recursive call");\r
601                                                 keyValue = getJsonIntValueForKey((JSONObject) obj, key);\r
602                                                 if (keyValue != null) {\r
603                                                         msoLogger.debug("getJsonValueForKey(): found value=" + keyValue + ", for key=" + key);\r
604                                                         break;\r
605                                                 }\r
606                                         } else {\r
607                                                 msoLogger.debug("getJsonValueForKey(): key=" + nextKey + ", does not point to a JSONObject, next key");\r
608                                         }\r
609                                 }\r
610                         }\r
611                 } catch (JSONException je) {\r
612                                 // JSONObject::get() throws this exception if one of the specified keys is not found\r
613                                 msoLogger.debug("getJsonValueForKey(): caught JSONException attempting to retrieve value for key=" + key, je);\r
614                                 keyValue = null;\r
615                 } catch (Exception e) {\r
616                                 msoLogger.debug("getJsonValueForKey(): unable to parse json to retrieve value for field=" + key + ". Exception was: " + e.toString(),e);\r
617                 }\r
618                 return keyValue;\r
619         }\r
620 \r
621         /**\r
622          * Walks the JSONObject (and sub-objects recursively), searching for the first value associated with the\r
623          * single key/field name specified. Returns the associated value if found or null if the key is not found\r
624          *\r
625          * @param  jsonObj      JSONObject representation of the the JSON doc\r
626          * @param  key          key to the target value\r
627          * @return String field value associated with key\r
628          */\r
629         public static Boolean getJsonBooleanValueForKey(JSONObject jsonObj, String key) {\r
630                 Boolean keyValue = false;\r
631                 try {\r
632                         if (jsonObj.has(key)) {\r
633                                 msoLogger.debug("getJsonBooleanValueForKey(): found value for key=" + key);\r
634                                 return (Boolean) jsonObj.get(key);\r
635                         } else {\r
636                                 msoLogger.debug("getJsonBooleanValueForKey(): iterating over the keys");\r
637                                 Iterator <String> itr = jsonObj.keys();\r
638                                 while (itr.hasNext()) {\r
639                                         String nextKey = (String) itr.next();\r
640                                         Object obj = jsonObj.get(nextKey);\r
641                                         if (obj instanceof JSONObject) {\r
642                                                 msoLogger.debug("getJsonBooleanValueForKey(): key=" + nextKey + ", points to JSONObject, recursive call");\r
643                                                 keyValue = getJsonBooleanValueForKey((JSONObject) obj, key);\r
644                                                 if (keyValue != null) {\r
645                                                         msoLogger.debug("getJsonBooleanValueForKey(): found value=" + keyValue + ", for key=" + key);\r
646                                                         break;\r
647                                                 }\r
648                                         } else {\r
649                                                 msoLogger.debug("getJsonBooleanValueForKey(): key=" + nextKey + ", does not point to a JSONObject, next key");\r
650                                         }\r
651                                 }\r
652                         }\r
653                 } catch (JSONException je) {\r
654                                 // JSONObject::get() throws this exception if one of the specified keys is not found\r
655                                 msoLogger.debug("getJsonBooleanValueForKey(): caught JSONException attempting to retrieve value for key=" + key,je);\r
656                                 keyValue = null;\r
657                 } catch (Exception e) {\r
658                                 msoLogger.debug("getJsonBooleanValueForKey(): unable to parse json to retrieve value for field=" + key + ". Exception was: " + e.toString(),e);\r
659                 }\r
660                 return keyValue;\r
661         }\r
662 \r
663         /**\r
664          * Boolean method to determine if a key path is valid for the JSON doc. Invokes\r
665          * getJsonValue().\r
666          *\r
667          * @param  jsonStr      String containing the JSON doc\r
668          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
669          * @return Boolean true if keys points to value in the JSON doc\r
670          */\r
671         public static Boolean jsonValueExists(String jsonStr, String keys) {\r
672                 if (getJsonRawValue(jsonStr, keys) == null) {\r
673                         return false;\r
674                 } else {\r
675                         return true;\r
676                 }\r
677         }\r
678 \r
679         /**\r
680          * Inserts the new key/value pair at the appropriate location in the JSON\r
681          * document after first determining if keyed field already exists. If\r
682          * it does exist, return the JSON unmodified, otherwise return the new JSON\r
683          * Note: this method currently only supports String value inserts.\r
684          *\r
685          * @param  jsonStr      String containing the JSON doc\r
686          * @param  keys         full key path to the value to be added in the format of "key1.key2.key3..."\r
687          * @return String containing the updated JSON doc\r
688          */\r
689         public static String addJsonValue(String jsonStr, String keys, String value) {\r
690 //              String isDebugLogEnabled = "true";\r
691                 // only attempt to insert the key/value pair if it does not exist\r
692                 if (!jsonValueExists(jsonStr, keys)) {\r
693                         return putJsonValue(jsonStr, keys, value);\r
694                 } else {\r
695                         msoLogger.debug("addJsonValue(): JSON add failed, key=" + keys + "/value=" + (String) value + " already exists");\r
696                         return jsonStr;\r
697                 }\r
698         }\r
699 \r
700         /**\r
701          * Updates the value for the specified key in the JSON document\r
702          * after first determining if keyed field exists. If it does\r
703          * not exist, return the JSON unmodified, otherwise return the updated JSON.\r
704          * Note: this method currently only supports String value updates.\r
705          *\r
706          * @param  jsonStr      String containing the JSON doc\r
707          * @param  keys         full key path to the value to be updated in the format of "key1.key2.key3..."\r
708          * @return String containing the updated JSON doc\r
709          */\r
710         public static String updJsonValue(String jsonStr, String keys, String newValue) {\r
711 //              String isDebugLogEnabled = "true";\r
712                 // only attempt to modify the key/value pair if it exists\r
713                 if (jsonValueExists(jsonStr, keys)) {\r
714                         return putJsonValue(jsonStr, keys, newValue);\r
715                 } else {\r
716                         msoLogger.debug("updJsonValue(): JSON update failed, no value exists for key=" + keys);\r
717                         return jsonStr;\r
718                 }\r
719         }\r
720 \r
721         /**\r
722          * Deletes the value for the specified key in the JSON document\r
723          * after first determining if keyed field exists. If it does\r
724          * not exist, return the JSON unmodified, otherwise return the updated JSON\r
725          *\r
726          * @param  jsonStr      String containing the JSON doc\r
727          * @param  keys         full key path to the value to be deleted in the format of "key1.key2.key3..."\r
728          * @return String containing the updated JSON doc\r
729          */\r
730         public static String delJsonValue(String jsonStr, String keys) {\r
731 //              String isDebugLogEnabled = "true";\r
732                 // only attempt to remove the key/value pair if it exists\r
733                 if (jsonValueExists(jsonStr, keys)) {\r
734                         // passing a null value results in a delete\r
735                         return putJsonValue(jsonStr, keys, null);\r
736                 } else {\r
737                         msoLogger.debug("delJsonValue(): JSON delete failed, no value exists for key=" + keys);\r
738                         return jsonStr;\r
739                 }\r
740         }\r
741 \r
742         /**\r
743          * Walks the JSON doc using the full key path to retrieve the associated\r
744          * value. All but the last key points to the 'parent' object name(s) in order\r
745          * in the JSON hierarchy with the last key pointing to the target value.\r
746          * The value returned is a Java object.\r
747          *\r
748          * @param  jsonStr      String containing the JSON doc\r
749          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
750          * @return Object field value associated with keys\r
751          */\r
752         private static Object getJsonRawValue(String jsonStr, String keys) {\r
753                 return getJsonRawValue(jsonStr, keys, false);\r
754         }\r
755 \r
756         /**\r
757          * Walks the JSON doc using the full key path to retrieve the associated\r
758          * value. All but the last key points to the 'parent' object name(s) in order\r
759          * in the JSON hierarchy with the last key pointing to the target value.\r
760          * The value returned is a Java object.\r
761          *\r
762          * @param  jsonStr      String containing the JSON doc\r
763          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
764          * @param  wrap         Boolean which determines if returned JSONObjects sould be "wrapped"\r
765          *                  Note: wrap does not apply to returned scalar values\r
766          * @return Object field value associated with keys\r
767          */\r
768         private static Object getJsonRawValue(String jsonStr, String keys, Boolean wrap) {\r
769 //              String isDebugLogEnabled = "true";\r
770                 String keyStr = "";\r
771                 try {\r
772                         JSONObject jsonObj = new JSONObject(jsonStr);\r
773                         StringTokenizer keyTokens = new StringTokenizer(keys, ".");\r
774                         while (keyTokens.hasMoreElements()) {\r
775                                 keyStr = keyTokens.nextToken();\r
776                                 Object keyValue = jsonObj.get(keyStr);\r
777                                 if (keyValue instanceof JSONObject) {\r
778                                         msoLogger.debug("getJsonRawValue(): key=" + keyStr + " points to json object");\r
779                                         jsonObj = (JSONObject) keyValue;\r
780                                 } else {\r
781                                         if (keyTokens.hasMoreElements()) {\r
782                                                 msoLogger.debug("getJsonRawValue(): value found prior to last key for key=" + keyStr);\r
783                                         }\r
784                                         return keyValue;\r
785                                 }\r
786                         }\r
787                         // return the json 'node' that the key points to\r
788                         // note: since this is a json object and not a scalar value,\r
789                         //       use the wrap flag to determine if the object should\r
790                         //       be wrapped with a root node value\r
791                         //       (the last key in the keys String)\r
792                         if (wrap) {\r
793                                 JSONObject wrappedJsonObj = new JSONObject();\r
794                                 wrappedJsonObj.put(keyStr, jsonObj);\r
795                                 return wrappedJsonObj.toString();\r
796                         } else {\r
797                                 return jsonObj.toString();\r
798                         }\r
799 \r
800                 } catch (JSONException je) {\r
801                                 // JSONObject::get() throws this exception if one of the specified keys is not found\r
802                                 msoLogger.debug("getJsonRawValue(): caught JSONException attempting to retrieve raw value for key=" + keyStr,je);\r
803                 } catch (Exception e) {\r
804                                 msoLogger.debug("getJsonRawValue(): unable to parse json to retrieve value for field=" + keys + ". Exception was: " + e.toString(),e);\r
805                 }\r
806                 return null;\r
807         }\r
808 \r
809         /**\r
810          * Private method invoked by the public add, update, and delete methods.\r
811          *\r
812          * @param  jsonStr      String containing the JSON doc\r
813          * @param  keys         full key path to the value to be deleted in the format of "key1.key2.key3..."\r
814          * @return String containing the updated JSON doc\r
815          */\r
816         private static String putJsonValue(String jsonStr, String keys, String value) {\r
817 //              String isDebugLogEnabled = "true";\r
818                 String keyStr = "";\r
819                 try {\r
820                         JSONObject jsonObj = new JSONObject(jsonStr);\r
821                         JSONObject jsonObjOut = jsonObj;\r
822                         StringTokenizer keyTokens = new StringTokenizer(keys, ".");\r
823                         while (keyTokens.hasMoreElements()) {\r
824                                 keyStr = keyTokens.nextToken();\r
825                                 if (keyTokens.hasMoreElements()) {\r
826                                         Object keyValue = jsonObj.get(keyStr);\r
827                                         if (keyValue instanceof JSONObject) {\r
828                                                 msoLogger.debug("putJsonValue(): key=" + keyStr + " points to json object");\r
829                                                 jsonObj = (JSONObject) keyValue;\r
830                                         } else {\r
831                                                 msoLogger.debug("putJsonValue(): key=" + keyStr + " not the last key but points to non-json object: " + (String) keyValue);\r
832                                                 return null;\r
833                                         }\r
834                                 } else { // at the last/new key value\r
835                                         jsonObj.put(keyStr, value);\r
836                                         return jsonObjOut.toString(3);\r
837                                 }\r
838                         }\r
839                         // should not hit this point if the key points to a valid key value\r
840                         return null;\r
841 \r
842                 } catch (JSONException je) {\r
843                                 // JSONObject::get() throws this exception if one of the specified keys is not found\r
844                                 msoLogger.debug("putJsonValue(): caught JSONException attempting to retrieve value for key=" + keyStr,je);\r
845                                 return null;\r
846                 } catch (Exception e) {\r
847                                 msoLogger.debug("putJsonValue(): unable to parse json to put value for key=" + keys + ". Exception was: " + e.toString(),e);\r
848                 }\r
849                 return null;\r
850         }\r
851 \r
852         /**\r
853          * This json util method converts a json array of Key Value\r
854          * pair objects into a Java Map.\r
855          *\r
856          * @param execution\r
857          * @param entryArray - the getJsonValue of a json Array of key/value pairs\r
858          *\r
859          * @return Map - a Map containing the entries\r
860          */\r
861         public Map<String, String> entryArrayToMap(Execution execution, String entryArray) {\r
862                 msoLogger.debug("Started Entry Array To Map Util Method");\r
863 \r
864                 Map<String, String> map = new HashMap<>();\r
865 \r
866                 //Populate Map\r
867                 String entryListJson = "{ \"entry\":" + entryArray + "}";\r
868                 JSONObject obj = new JSONObject(entryListJson);\r
869                 JSONArray arr = obj.getJSONArray("entry");\r
870                 for (int i = 0; i < arr.length(); i++){\r
871                         JSONObject jo = arr.getJSONObject(i);\r
872                         String key = jo.getString("key");\r
873                         String value =jo.getString("value");\r
874                         map.put(key, value);\r
875                 }\r
876                 msoLogger.debug("Outgoing Map is: " + map);\r
877                 msoLogger.debug("Completed Entry Array To Map Util Method");\r
878                 return map;\r
879         }\r
880 \r
881         /**\r
882          * This json util method converts a json array of Key Value\r
883          * pair objects into a Java Map.\r
884          *\r
885          * @param execution\r
886          * @param entryArray - the getJsonValue of a json Array of key/value pairs\r
887          * @param keyNode - the name of the node that represents the key\r
888          * @param valueNode - the name of the node that represents the value\r
889          *\r
890          * @return Map - a Map containing the entries\r
891          *\r
892          */\r
893         public Map<String, String> entryArrayToMap(Execution execution, String entryArray, String keyNode, String valueNode) {\r
894                 msoLogger.debug("Started Entry Array To Map Util Method");\r
895 \r
896                 Map<String, String> map = new HashMap<>();\r
897                 //Populate Map\r
898                 String entryListJson = "{ \"entry\":" + entryArray + "}";\r
899                 JSONObject obj = new JSONObject(entryListJson);\r
900                 JSONArray arr = obj.getJSONArray("entry");\r
901                 for (int i = 0; i < arr.length(); i++){\r
902                         JSONObject jo = arr.getJSONObject(i);\r
903                         String key = jo.getString(keyNode);\r
904                         String value =jo.getString(valueNode);\r
905                         map.put(key, value);\r
906                 }\r
907                 msoLogger.debug("Outgoing Map is: " + map);\r
908                 msoLogger.debug("Completed Entry Array To Map Util Method");\r
909                 return map;\r
910         }\r
911 \r
912         /**\r
913          * This json util method converts a json Array of Strings\r
914          * to a Java List. It takes each String in the json Array\r
915          * and puts it in a Java List<String>.\r
916          *\r
917          * @param execution\r
918          * @param stringArray - the getJsonValue of a json array of strings\r
919          *\r
920          * @return List - a java list containing the strings\r
921          *\r
922          *\r
923          */\r
924         public List<String> StringArrayToList(Execution execution, String jsonArrayOfStrings) {\r
925                 msoLogger.debug("Started  String Array To List Util Method");\r
926 \r
927                 List<String> list = new ArrayList<>();\r
928                 //Populate List\r
929                 String stringListJson = "{ \"strings\":" + jsonArrayOfStrings + "}";\r
930                 JSONObject obj = new JSONObject(stringListJson);\r
931                 JSONArray arr = obj.getJSONArray("strings");\r
932                 for (int i = 0; i < arr.length(); i++){\r
933                         String s = arr.getString(i);\r
934                         list.add(s);\r
935                 }\r
936                 msoLogger.debug("Outgoing List is: " + list);\r
937                 msoLogger.debug("Completed String Array To List Util Method");\r
938                 return list;\r
939         }\r
940 \r
941         /**\r
942          *\r
943          * Invokes the getJsonRawValue() method to determine if the\r
944          * json element/variable exist. Returns true if the\r
945          * json element exist\r
946          *\r
947          * @param  jsonStr      String containing the JSON doc\r
948          * @param  keys         full key path to the target value in the format of "key1.key2.key3..."\r
949          * @return boolean field value associated with keys\r
950          *\r
951          *\r
952          */\r
953         public static boolean jsonElementExist(String jsonStr, String keys) {\r
954 \r
955                 try {\r
956                         Object rawValue = getJsonRawValue(jsonStr, keys);\r
957                         if (rawValue == null) {\r
958                                 return false;\r
959                         } else {\r
960                                 return true;\r
961                         }\r
962                 } catch (Exception e) {\r
963                                 msoLogger.debug("jsonElementExist(): unable to determine if json element exist. Exception is: " + e.toString(),e);\r
964                 }\r
965                 return true;\r
966         }\r
967 \r
968 }