Refinements and test additions to XmlParser
[ccsdk/sli/plugins.git] / restapi-call-node / provider / src / main / java / org / onap / ccsdk / sli / plugins / restapicall / XmlParser.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 static com.google.common.base.Preconditions.checkNotNull;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Map;
32 import java.util.Set;
33
34 import javax.xml.parsers.ParserConfigurationException;
35 import javax.xml.parsers.SAXParser;
36 import javax.xml.parsers.SAXParserFactory;
37
38 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.xml.sax.Attributes;
42 import org.xml.sax.SAXException;
43 import org.xml.sax.helpers.DefaultHandler;
44
45 public final class XmlParser {
46
47     private static final Logger log = LoggerFactory.getLogger(XmlParser.class);
48
49     private XmlParser() {
50         // Preventing instantiation of the same.
51     }
52
53     public static Map<String, String> convertToProperties(String s, Set<String> listNameList)
54         throws SvcLogicException {
55
56         checkNotNull(s, "Input should not be null.");
57
58         Handler handler = new Handler(listNameList);
59         try {
60             SAXParserFactory factory = SAXParserFactory.newInstance();
61             SAXParser saxParser = factory.newSAXParser();
62             InputStream in = new ByteArrayInputStream(s.getBytes());
63             saxParser.parse(in, handler);
64         } catch (ParserConfigurationException | IOException | SAXException | NumberFormatException e) {
65             throw new SvcLogicException("Unable to convert XML to properties" + e.getLocalizedMessage(), e);
66         }
67         return handler.getProperties();
68     }
69
70     private static class Handler extends DefaultHandler {
71
72         private Set<String> listNameList;
73
74         private Map<String, String> properties = new HashMap<>();
75
76         public Map<String, String> getProperties() {
77             return properties;
78         }
79
80         public Handler(Set<String> listNameList) {
81             super();
82             this.listNameList = listNameList;
83             if (this.listNameList == null)
84                 this.listNameList = new HashSet<>();
85         }
86
87         StringBuilder currentName = new StringBuilder();
88         StringBuilder currentValue = new StringBuilder();
89
90         @Override
91         public void startElement(String uri, String localName, String qName, Attributes attributes)
92                 throws SAXException {
93             super.startElement(uri, localName, qName, attributes);
94
95             String name = localName;
96             if (name == null || name.trim().length() == 0)
97                 name = qName;
98             int i2 = name.indexOf(':');
99             if (i2 >= 0)
100                 name = name.substring(i2 + 1);
101
102             if (currentName.length() > 0)
103                 currentName.append(Character.toString('.'));
104             currentName.append(name);
105
106             String listName = removeIndexes(currentName.toString());
107
108             if (listNameList.contains(listName)) {
109                 String n = currentName.toString() + "_length";
110                 int len = getInt(properties, n);
111                 properties.put(n, String.valueOf(len + 1));
112                 currentName.append("[").append(len).append("]");
113             }
114         }
115
116         @Override
117         public void endElement(String uri, String localName, String qName) throws SAXException {
118             super.endElement(uri, localName, qName);
119
120             String name = localName;
121             if (name == null || name.trim().length() == 0)
122                 name = qName;
123             int i2 = name.indexOf(':');
124             if (i2 >= 0)
125                 name = name.substring(i2 + 1);
126
127             String s = currentValue.toString().trim();
128             if (s.length() > 0) {
129                 properties.put(currentName.toString(), s);
130
131                 log.info("Added property: {} : {}", currentName, s);
132                 currentValue = new StringBuilder();
133             }
134
135             int i1 = currentName.lastIndexOf("." + name);
136             if (i1 <= 0)
137                 currentName = new StringBuilder();
138             else
139                 currentName = new StringBuilder(currentName.substring(0, i1));
140         }
141
142         @Override
143         public void characters(char[] ch, int start, int length) throws SAXException {
144             super.characters(ch, start, length);
145
146             String value = new String(ch, start, length);
147             currentValue.append(value);
148         }
149
150         private static int getInt(Map<String, String> mm, String name) {
151             String s = mm.get(name);
152             if (s == null)
153                 return 0;
154             return Integer.parseInt(s);
155         }
156
157         private String removeIndexes(String currentName) {
158             StringBuilder b = new StringBuilder();
159             boolean add = true;
160             for (int i = 0; i < currentName.length(); i++) {
161                 char c = currentName.charAt(i);
162                 if (c == '[')
163                     add = false;
164                 else if (c == ']')
165                     add = true;
166                 else if (add)
167                     b.append(Character.toString(c));
168             }
169             return b.toString();
170         }
171     }
172 }