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