Escaping multi-line string
[ccsdk/sli/plugins.git] / restapi-call-node / provider / src / main / java / org / onap / ccsdk / sli / plugins / restapicall / XmlJsonUtil.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                      reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.plugins.restapicall;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import org.apache.commons.text.StringEscapeUtils;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 public final class XmlJsonUtil {
33
34     private static final Logger log = LoggerFactory.getLogger(XmlJsonUtil.class);
35
36     private XmlJsonUtil() {
37         // Preventing instantiation of the same.
38     }
39
40     public static String getXml(Map<String, String> varmap, String var) {
41         boolean escape = true;
42         if (var.startsWith("'")) {
43             var = var.substring(1);
44             escape = false;
45         }
46
47         Object o = createStructure(varmap, var);
48         return generateXml(o, 0, escape);
49     }
50
51     public static String getJson(Map<String, String> varmap, String var) {
52         boolean escape = true;
53         if (var.startsWith("'")) {
54             var = var.substring(1);
55             escape = false;
56         }
57
58         boolean quotes = true;
59         if (var.startsWith("\"")) {
60             var = var.substring(1);
61             quotes = false;
62         }
63
64         Object o = createStructure(varmap, var);
65         return generateJson(o, escape, quotes);
66     }
67
68     private static Object createStructure(Map<String, String> flatmap, String var) {
69         if (flatmap.containsKey(var)) {
70             if (var.endsWith("_length") || var.endsWith("].key")) {
71                 return null;
72             }
73             return flatmap.get(var);
74         }
75
76         Map<String, Object> mm = new HashMap<>();
77         for (String k : flatmap.keySet()) {
78             if (k.startsWith(var + ".")) {
79                 int i1 = k.indexOf('.', var.length() + 1);
80                 int i2 = k.indexOf('[', var.length() + 1);
81                 int i3 = k.length();
82                 if (i1 > 0 && i1 < i3) {
83                     i3 = i1;
84                 }
85                 if (i2 > 0 && i2 < i3) {
86                     i3 = i2;
87                 }
88                 String k1 = k.substring(var.length() + 1, i3);
89                 String var1 = k.substring(0, i3);
90                 if (!mm.containsKey(k1)) {
91                     Object str = createStructure(flatmap, var1);
92                     if (str != null && (!(str instanceof String) || ((String) str).trim().length() > 0)) {
93                         mm.put(k1, str);
94                     }
95                 }
96             }
97         }
98         if (!mm.isEmpty()) {
99             return mm;
100         }
101
102         boolean arrayFound = false;
103         for (String k : flatmap.keySet()) {
104             if (k.startsWith(var + "[")) {
105                 arrayFound = true;
106                 break;
107             }
108         }
109
110         if (arrayFound) {
111             List<Object> ll = new ArrayList<>();
112
113             int length = Integer.MAX_VALUE;
114             String lengthStr = flatmap.get(var + "_length");
115             if (lengthStr != null) {
116                 try {
117                     length = Integer.parseInt(lengthStr);
118                 } catch (Exception e) {
119                     log.warn("Invalid number for {}_length:{}", var, lengthStr, e);
120                 }
121             }
122
123             for (int i = 0; i < length; i++) {
124                 Object v = createStructure(flatmap, var + '[' + i + ']');
125                 if (v == null) {
126                     break;
127                 }
128                 ll.add(v);
129             }
130
131             if (!ll.isEmpty()) {
132                 return ll;
133             }
134         }
135
136         return null;
137     }
138
139     @SuppressWarnings("unchecked")
140     private static String generateXml(Object o, int indent, boolean escape) {
141         if (o == null) {
142             return null;
143         }
144
145         if (o instanceof String) {
146             return escape ? StringEscapeUtils.escapeXml10((String) o) : (String) o;
147         };
148
149         if (o instanceof Map) {
150             StringBuilder ss = new StringBuilder();
151             Map<String, Object> mm = (Map<String, Object>) o;
152             for (Map.Entry<String, Object> entry : mm.entrySet()) {
153                 Object v = entry.getValue();
154                 String key = entry.getKey();
155                 if (v instanceof String) {
156                     String s = escape ? StringEscapeUtils.escapeXml10((String) v) : (String) v;
157                     ss.append(pad(indent)).append('<').append(key).append('>');
158                     ss.append(s);
159                     ss.append("</").append(key).append('>').append('\n');
160                 } else if (v instanceof Map) {
161                     ss.append(pad(indent)).append('<').append(key).append('>').append('\n');
162                     ss.append(generateXml(v, indent + 1, escape));
163                     ss.append(pad(indent)).append("</").append(key).append('>').append('\n');
164                 } else if (v instanceof List) {
165                     List<Object> ll = (List<Object>) v;
166                     for (Object o1 : ll) {
167                         ss.append(pad(indent)).append('<').append(key).append('>').append('\n');
168                         ss.append(generateXml(o1, indent + 1, escape));
169                         ss.append(pad(indent)).append("</").append(key).append('>').append('\n');
170                     }
171                 }
172             }
173             return ss.toString();
174         }
175
176         return null;
177     }
178     private static String generateJson(Object o, boolean escape, boolean quotes) {
179         if (o == null) {
180             return null;
181         }
182         if (o instanceof String && ((String) o).length() == 0) {
183             return null;
184         }
185
186         StringBuilder ss = new StringBuilder();
187         generateJson(ss, o, 0, false, escape, quotes);
188         return ss.toString();
189     }
190
191     @SuppressWarnings("unchecked")
192     private static void generateJson(StringBuilder ss, Object o, int indent, boolean padFirst, boolean escape, boolean quotes) {
193         if (o instanceof String) {
194             String s = escape ? StringEscapeUtils.escapeJson((String) o) : (String) o;
195             if (padFirst) {
196                 ss.append(pad(indent));
197             }
198             if (quotes) {
199                 ss.append('"').append(s).append('"');
200             } else {
201                 ss.append(s);
202             }
203             return;
204         }
205
206         if (o instanceof Map) {
207             Map<String, Object> mm = (Map<String, Object>) o;
208
209             if (padFirst) {
210                 ss.append(pad(indent));
211             }
212             ss.append("{\n");
213
214             boolean first = true;
215             for (Map.Entry<String, Object> entry : mm.entrySet()) {
216                 if (!first) {
217                     ss.append(",\n");
218                 }
219                 first = false;
220                 Object v = entry.getValue();
221                 String key = entry.getKey();
222                 ss.append(pad(indent + 1)).append('"').append(key).append("\": ");
223                 generateJson(ss, v, indent + 1, false, escape, true);
224             }
225
226             ss.append("\n");
227             ss.append(pad(indent)).append('}');
228
229             return;
230         }
231
232         if (o instanceof List) {
233             List<Object> ll = (List<Object>) o;
234
235             if (padFirst) {
236                 ss.append(pad(indent));
237             }
238             ss.append("[\n");
239
240             boolean first = true;
241             for (Object o1 : ll) {
242                 if (!first) {
243                     ss.append(",\n");
244                 }
245                 first = false;
246
247                 generateJson(ss, o1, indent + 1, true, escape, quotes);
248             }
249
250             ss.append("\n");
251             ss.append(pad(indent)).append(']');
252         }
253     }
254
255     public static String removeLastCommaJson(String s) {
256         StringBuilder sb = new StringBuilder();
257         int k = 0;
258         int start = 0;
259         while (k < s.length()) {
260             int i11 = s.indexOf('}', k);
261             int i12 = s.indexOf(']', k);
262             int i1 = -1;
263             if (i11 < 0) {
264                 i1 = i12;
265             } else if (i12 < 0) {
266                 i1 = i11;
267             } else {
268                 i1 = i11 < i12 ? i11 : i12;
269             }
270             if (i1 < 0) {
271                 break;
272             }
273
274             int i2 = s.lastIndexOf(',', i1);
275             if (i2 < 0) {
276                 k = i1 + 1;
277                 continue;
278             }
279
280             String between = s.substring(i2 + 1, i1);
281             if (between.trim().length() > 0) {
282                 k = i1 + 1;
283                 continue;
284             }
285
286             sb.append(s.substring(start, i2));
287             start = i2 + 1;
288             k = i1 + 1;
289         }
290
291         sb.append(s.substring(start, s.length()));
292
293         return sb.toString();
294     }
295
296     public static String removeEmptyStructJson(String template, String s) {
297         int k = 0;
298         while (k < s.length()) {
299             boolean curly = true;
300             int i11 = s.indexOf('{', k);
301             int i12 = s.indexOf('[', k);
302             int i1 = -1;
303             if (i11 < 0) {
304                 i1 = i12;
305                 curly = false;
306             } else if (i12 < 0) {
307                 i1 = i11;
308             } else if (i11 < i12) {
309                 i1 = i11;
310             } else {
311                 i1 = i12;
312                 curly = false;
313             }
314
315             if (i1 >= 0) {
316                 int i2 = curly ? s.indexOf('}', i1) : s.indexOf(']', i1);
317                 if (i2 > 0) {
318                     String value = s.substring(i1 + 1, i2);
319                     if (value.trim().length() == 0) {
320                         int i4 = s.lastIndexOf('\n', i1);
321                         if (i4 < 0) {
322                             i4 = 0;
323                         }
324                         int i5 = s.indexOf('\n', i2);
325                         if (i5 < 0) {
326                             i5 = s.length();
327                         }
328
329
330                         /*If template mandates empty construct to be present, those should not be removed.*/
331                         if (template != null && template.contains(s.substring(i4))) {
332                             k = i1 + 1;
333                         } else {
334                             s = s.substring(0, i4) + s.substring(i5);
335                             k = 0;
336                         }
337                     } else {
338                         k = i1 + 1;
339                     }
340                 } else {
341                     break;
342                 }
343             } else {
344                 break;
345             }
346         }
347
348         return s;
349     }
350
351     public static String removeEmptyStructXml(String s) {
352         int k = 0;
353         while (k < s.length()) {
354             int i1 = s.indexOf('<', k);
355             if (i1 < 0 || i1 == s.length() - 1) {
356                 break;
357             }
358
359             char c1 = s.charAt(i1 + 1);
360             if (c1 == '?' || c1 == '!') {
361                 k = i1 + 2;
362                 continue;
363             }
364
365             int i2 = s.indexOf('>', i1);
366             if (i2 < 0) {
367                 k = i1 + 1;
368                 continue;
369             }
370
371             String closingTag = "</" + s.substring(i1 + 1, i2 + 1);
372             int i3 = s.indexOf(closingTag, i2 + 1);
373             if (i3 < 0) {
374                 k = i2 + 1;
375                 continue;
376             }
377
378             String value = s.substring(i2 + 1, i3);
379             if (value.trim().length() > 0) {
380                 k = i2 + 1;
381                 continue;
382             }
383
384             int i4 = s.lastIndexOf('\n', i1);
385             if (i4 < 0) {
386                 i4 = 0;
387             }
388             int i5 = s.indexOf('\n', i3);
389             if (i5 < 0) {
390                 i5 = s.length();
391             }
392
393             s = s.substring(0, i4) + s.substring(i5);
394             k = 0;
395         }
396
397         return s;
398     }
399
400     private static String pad(int n) {
401         StringBuilder s = new StringBuilder();
402         for (int i = 0; i < n; i++) {
403             s.append(Character.toString('\t'));
404         }
405         return s.toString();
406     }
407 }