2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.onap.aai.schemagen.genxsd;
22 import org.onap.aai.edges.EdgeIngestor;
23 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
24 import org.onap.aai.nodes.NodeIngestor;
25 import org.onap.aai.setup.SchemaVersion;
26 import org.onap.aai.setup.SchemaVersions;
28 import org.xml.sax.InputSource;
29 import org.xml.sax.SAXException;
31 import javax.xml.XMLConstants;
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
36 import java.io.FileNotFoundException;
37 import java.io.IOException;
38 import java.io.StringReader;
41 public abstract class OxmFileProcessor {
43 public static final String LINE_SEPARATOR = System.getProperty("line.separator");
44 public static final String DOUBLE_LINE_SEPARATOR = System.getProperty("line.separator") + System.getProperty("line.separator");
48 protected Set<String> namespaceFilter;
49 protected File oxmFile;
51 protected SchemaVersion v;
52 protected Document doc = null;
53 protected String apiVersion = null;
54 protected SchemaVersions schemaVersions;
57 protected static int annotationsStartVersion = 9; // minimum version to support annotations in xsd
58 protected static int annotationsMinVersion = 6; // lower versions support annotations in xsd
59 protected static int swaggerSupportStartsVersion = 1; // minimum version to support swagger documentation
60 protected static int swaggerDiffStartVersion = 1; // minimum version to support difference
61 protected static int swaggerMinBasepath = 6; // minimum version to support difference
63 protected Map combinedJavaTypes;
66 protected String apiVersionFmt = null;
67 protected HashMap<String, String> generatedJavaType = new HashMap<String, String>();
68 protected HashMap<String, String> appliedPaths = new HashMap<String, String>();
69 protected NodeList javaTypeNodes = null;
71 protected Map<String,String> javaTypeDefinitions = createJavaTypeDefinitions();
72 private Map<String, String> createJavaTypeDefinitions()
74 StringBuffer aaiInternal = new StringBuffer();
75 StringBuffer nodes = new StringBuffer();
76 Map<String,String> javaTypeDefinitions = new HashMap<String, String>();
77 aaiInternal.append(" aai-internal:\n");
78 aaiInternal.append(" properties:\n");
79 aaiInternal.append(" property-name:\n");
80 aaiInternal.append(" type: string\n");
81 aaiInternal.append(" property-value:\n");
82 aaiInternal.append(" type: string\n");
83 // javaTypeDefinitions.put("aai-internal", aaiInternal.toString());
84 nodes.append(" nodes:\n");
85 nodes.append(" properties:\n");
86 nodes.append(" inventory-item-data:\n");
87 nodes.append(" type: array\n");
88 nodes.append(" items:\n");
89 nodes.append(" $ref: \"#/definitions/inventory-item-data\"\n");
90 javaTypeDefinitions.put("nodes", nodes.toString());
91 return javaTypeDefinitions;
93 static List<String> nodeFilter = createNodeFilter();
94 private static List<String> createNodeFilter()
96 List<String> list = Arrays.asList("search", "actions", "aai-internal", "nodes");
100 public OxmFileProcessor(SchemaVersions schemaVersions, NodeIngestor ni, EdgeIngestor ei){
101 this.schemaVersions = schemaVersions;
108 public void setOxmVersion(File oxmFile, SchemaVersion v) {
109 this.oxmFile = oxmFile;
113 public void setXmlVersion(String xml, SchemaVersion v) {
118 public void setVersion(SchemaVersion v) {
123 public void setNodeIngestor(NodeIngestor ni) {
127 public void setEdgeIngestor(EdgeIngestor ei) {
131 public SchemaVersions getSchemaVersions() {
132 return schemaVersions;
135 public void setSchemaVersions(SchemaVersions schemaVersions) {
136 this.schemaVersions = schemaVersions;
139 protected void init() throws ParserConfigurationException, SAXException, IOException, EdgeRuleNotFoundException {
140 if(this.xml != null || this.oxmFile != null ) {
143 if(this.doc == null) {
144 this.doc = ni.getSchema(v);
146 namespaceFilter = new HashSet<>();
148 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
149 Element bindingElement;
150 NodeList javaTypesNodes;
151 Element javaTypesElement;
153 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
154 throw new SAXException("OXM file error: missing <binding-nodes> in " + oxmFile);
157 bindingElement = (Element) bindingsNodes.item(0);
158 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
159 if ( javaTypesNodes.getLength() < 1 ) {
160 throw new SAXException("OXM file error: missing <binding-nodes><java-types> in " + oxmFile);
162 javaTypesElement = (Element) javaTypesNodes.item(0);
164 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
165 if ( javaTypeNodes.getLength() < 1 ) {
166 throw new SAXException("OXM file error: missing <binding-nodes><java-types><java-type> in " + oxmFile );
170 private void createDocument() throws ParserConfigurationException, SAXException, IOException {
171 DocumentBuilder dBuilder = null;
173 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
174 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
175 dBuilder = dbFactory.newDocumentBuilder();
176 } catch (ParserConfigurationException e) {
181 doc = dBuilder.parse(oxmFile);
183 InputSource isInput = new InputSource(new StringReader(xml));
184 doc = dBuilder.parse(isInput);
186 } catch (SAXException e) {
188 } catch (IOException e) {
193 public abstract String getDocumentHeader();
194 public abstract String process() throws ParserConfigurationException, SAXException, IOException, FileNotFoundException, EdgeRuleNotFoundException ;
196 public String getXMLRootElementName(Element javaTypeElement) {
197 String xmlRootElementName=null;
198 NamedNodeMap attributes;
200 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
201 Element valElement = (Element) valNodes.item(0);
202 attributes = valElement.getAttributes();
203 for ( int i = 0; i < attributes.getLength(); ++i ) {
204 Attr attr = (Attr) attributes.item(i);
205 String attrName = attr.getNodeName();
207 String attrValue = attr.getNodeValue();
208 if ( attrName.equals("name"))
209 xmlRootElementName = attrValue;
211 return xmlRootElementName;
214 public String getXmlRootElementName( String javaTypeName )
216 String attrName, attrValue;
218 Element javaTypeElement;
219 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
220 javaTypeElement = (Element) javaTypeNodes.item(i);
221 NamedNodeMap attributes = javaTypeElement.getAttributes();
222 for ( int j = 0; j < attributes.getLength(); ++j ) {
223 attr = (Attr) attributes.item(j);
224 attrName = attr.getNodeName();
225 attrValue = attr.getNodeValue();
226 if ( attrName.equals("name") && attrValue.equals(javaTypeName)) {
227 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
228 Element valElement = (Element) valNodes.item(0);
229 attributes = valElement.getAttributes();
230 for ( int k = 0; k < attributes.getLength(); ++k ) {
231 attr = (Attr) attributes.item(k);
232 attrName = attr.getNodeName();
234 attrValue = attr.getNodeValue();
235 if ( attrName.equals("name"))
244 public Map getCombinedJavaTypes() {
245 return combinedJavaTypes;
248 public void setCombinedJavaTypes(Map combinedJavaTypes) {
249 this.combinedJavaTypes = combinedJavaTypes;
252 public Element getJavaTypeElementSwagger( String javaTypeName )
255 String attrName, attrValue;
257 Element javaTypeElement;
259 List<Element> combineElementList = new ArrayList<Element>();
260 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
261 javaTypeElement = (Element) javaTypeNodes.item(i);
262 NamedNodeMap attributes = javaTypeElement.getAttributes();
263 for ( int j = 0; j < attributes.getLength(); ++j ) {
264 attr = (Attr) attributes.item(j);
265 attrName = attr.getNodeName();
266 attrValue = attr.getNodeValue();
267 if ( attrName.equals("name") && attrValue.equals(javaTypeName)) {
268 combineElementList.add(javaTypeElement);
272 if ( combineElementList.size() == 0 ) {
273 return (Element) null;
274 } else if ( combineElementList.size() > 1 ) {
275 return combineElements( javaTypeName, combineElementList);
277 return combineElementList.get(0);
280 public boolean versionSupportsSwaggerDiff( String version) {
281 int ver = new Integer(version.substring(1)).intValue();
282 if ( ver >= HTMLfromOXM.swaggerDiffStartVersion ) {
288 public boolean versionSupportsBasePathProperty( String version) {
289 int ver = new Integer(version.substring(1)).intValue();
290 if ( ver <= HTMLfromOXM.swaggerMinBasepath ) {
296 protected void updateParentXmlElements(Element parentElement, NodeList moreXmlElementNodes) {
301 Node refChild = null;
302 // find childNode with attributes and no children, insert children before that node
303 childNodes = parentElement.getChildNodes();
304 if ( childNodes == null || childNodes.getLength() == 0 ) {
305 // should not happen since the base parent was chosen if it had children
309 for ( int i = 0; i < childNodes.getLength(); ++i ) {
310 refChild = childNodes.item(i);
311 if ( refChild.hasAttributes() && !refChild.hasChildNodes()) {
317 for ( int i = 0; i < moreXmlElementNodes.getLength(); ++i ) {
318 xmlElement = (Element)moreXmlElementNodes.item(i);
319 childNode = xmlElement.cloneNode(true);
320 parentElement.insertBefore(childNode, refChild);
324 protected Node getXmlPropertiesNode(Element javaTypeElement ) {
325 NodeList nl = javaTypeElement.getChildNodes();
327 for ( int i = 0; i < nl.getLength(); ++i ) {
329 if ( "xml-properties".equals(child.getNodeName())) {
336 protected Node merge( NodeList nl, Node mergeNode ) {
337 NamedNodeMap nnm = mergeNode.getAttributes();
339 NamedNodeMap childNnm;
341 String mergeName = nnm.getNamedItem("name").getNodeValue();
342 String mergeValue = nnm.getNamedItem("value").getNodeValue();
345 for ( int j = 0; j < nl.getLength(); ++j ) {
346 childNode = nl.item(j);
347 if ( "xml-property".equals(childNode.getNodeName())) {
348 childNnm = childNode.getAttributes();
349 childName = childNnm.getNamedItem("name").getNodeValue();
350 childValue = childNnm.getNamedItem("value").getNodeValue();
351 if ( childName.equals(mergeName)) {
353 // keep, replace or update
354 if ( childValue.contains(mergeValue) ) {
357 if ( mergeValue.contains(childValue) ) {
358 childNnm.getNamedItem("value").setTextContent(mergeValue);
361 childNnm.getNamedItem("value").setTextContent(mergeValue + "," + childValue);
366 childNode = mergeNode.cloneNode(true);
370 protected void mergeXmlProperties(Node useChildProperties, NodeList propertiesToMerge ) {
371 NodeList nl = useChildProperties.getChildNodes();
374 for ( int i = 0; i < propertiesToMerge.getLength(); ++i ) {
375 childNode = propertiesToMerge.item(i);
376 if ( "xml-property".equals(childNode.getNodeName()) ) {
377 newNode = merge(nl, childNode);
378 if ( newNode != null ) {
379 useChildProperties.appendChild(newNode);
386 protected void combineXmlProperties(int useElement, List<Element> combineElementList) {
387 // add or update xml-properties to the referenced element from the combined list
388 Element javaTypeElement = combineElementList.get(useElement);
389 NodeList nl = javaTypeElement.getChildNodes();
390 Node useChildProperties = getXmlPropertiesNode( javaTypeElement);
392 Node childProperties;
393 if ( useChildProperties == null ) {
394 // find xml-properties to clone
395 for ( int i = 0; i < combineElementList.size(); ++i ) {
396 if ( i == useElement ) {
399 childProperties = getXmlPropertiesNode(combineElementList.get(i));
400 if ( childProperties != null ) {
401 useChildProperties = childProperties.cloneNode(true);
402 javaTypeElement.appendChild(useChildProperties);
408 // find other xml-properties
409 for ( int i = 0; i < combineElementList.size(); ++i ) {
410 if ( i == useElement|| ( cloneChild >= 0 && i <= cloneChild )) {
413 childProperties = getXmlPropertiesNode(combineElementList.get(i));
414 if ( childProperties == null ) {
417 cnl = childProperties.getChildNodes();
418 mergeXmlProperties( useChildProperties, cnl);
423 protected Element combineElements( String javaTypeName, List<Element> combineElementList ) {
424 Element javaTypeElement;
425 NodeList parentNodes;
426 Element parentElement = null;
427 NodeList xmlElementNodes;
430 if ( combinedJavaTypes.containsKey( javaTypeName) ) {
431 return combineElementList.get((int)combinedJavaTypes.get(javaTypeName));
433 for ( int i = 0; i < combineElementList.size(); ++i ) {
434 javaTypeElement = combineElementList.get(i);
435 parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
436 if ( parentNodes.getLength() == 0 ) {
439 parentElement = (Element)parentNodes.item(0);
440 xmlElementNodes = parentElement.getElementsByTagName("xml-element");
441 if ( xmlElementNodes.getLength() <= 0 ) {
447 boolean doCombineElements = true;
448 if ( useElement < 0 ) {
450 doCombineElements = false;
451 } else if ( useElement == combineElementList.size() - 1) {
452 doCombineElements = false;
454 if ( doCombineElements ) {
455 // get xml-element from other javaTypeElements
456 Element otherParentElement = null;
457 for ( int i = 0; i < combineElementList.size(); ++i ) {
458 if ( i == useElement ) {
461 javaTypeElement = combineElementList.get(i);
462 parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
463 if ( parentNodes.getLength() == 0 ) {
466 otherParentElement = (Element)parentNodes.item(0);
467 xmlElementNodes = otherParentElement.getElementsByTagName("xml-element");
468 if ( xmlElementNodes.getLength() <= 0 ) {
471 // xml-element that are not present
472 updateParentXmlElements( parentElement, xmlElementNodes);
476 // need to combine xml-properties
477 combineXmlProperties(useElement, combineElementList );
478 combinedJavaTypes.put( javaTypeName, useElement);
479 return combineElementList.get(useElement);