5abd8f4850432b04e022f4b66677749422ec8d2d
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / util / genxsd / NodesYAMLfromOXM.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.onap.aai.util.genxsd;
21
22 import java.io.BufferedWriter;
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.nio.charset.Charset;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.nio.file.Paths;
30 import java.util.HashMap;
31 import java.util.LinkedHashSet;
32 import java.util.Map;
33 import java.util.Set;
34 import java.util.SortedSet;
35 import java.util.StringTokenizer;
36 import java.util.TreeMap;
37 import java.util.TreeSet;
38 import java.util.Vector;
39
40 import javax.xml.parsers.ParserConfigurationException;
41
42 import org.apache.commons.lang3.StringUtils;
43 import org.onap.aai.edges.EdgeIngestor;
44 import org.onap.aai.edges.EdgeRule;
45 import org.onap.aai.edges.EdgeRuleQuery;
46 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
47 import org.onap.aai.exceptions.AAIException;
48 import org.onap.aai.setup.SchemaVersion;
49 import org.onap.aai.setup.SchemaVersions;
50 import org.onap.aai.nodes.NodeIngestor;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53 import org.w3c.dom.Element;
54 import org.w3c.dom.NodeList;
55 import org.xml.sax.SAXException;
56
57 import com.google.common.collect.Multimap;
58
59 public class NodesYAMLfromOXM extends OxmFileProcessor {
60         private static final Logger logger = LoggerFactory.getLogger("GenerateXsd.class");
61         private static final String root = "../aai-schema/src/main/resources";
62         private static final String autoGenRoot = "aai-schema/src/main/resources";
63         private static final String generateTypeYAML = "yaml";
64         private static final String normalStartDir = "aai-core";
65         private static final String yaml_dir = (((System.getProperty("user.dir") != null) && (!System.getProperty("user.dir").contains(normalStartDir))) ? autoGenRoot : root) + "/aai_swagger_yaml";
66         private StringBuilder inventoryDefSb = null;    
67         private Map<String,String> operationDefinitions = new HashMap<>();
68
69         private String basePath;
70
71         public NodesYAMLfromOXM(String basePath, SchemaVersions schemaVersions, NodeIngestor ni, EdgeIngestor ei){
72                 super(schemaVersions, ni,ei);
73                 this.basePath = basePath;
74         }
75         public void setOxmVersion(File oxmFile, SchemaVersion v) {
76                 super.setOxmVersion(oxmFile, v);
77         }
78         public void setXmlVersion(String xml, SchemaVersion v){
79                 super.setXmlVersion(xml, v);
80         }
81         
82         public void setVersion(SchemaVersion v) {
83                 super.setVersion(v);
84         }
85
86         @Override
87         public String getDocumentHeader() {
88                 StringBuffer sb = new StringBuffer();
89                 sb.append("swagger: \"2.0\"\ninfo:\n  ");
90                 sb.append("description: |");
91         if ( versionSupportsSwaggerDiff(v.toString())) {
92             sb.append("\n\n    [Differences versus the previous schema version]("+"apidocs/aai_swagger_" + v.toString() + ".diff)");
93         }
94                 sb.append("\n\n    Copyright &copy; 2017-18 AT&amp;T Intellectual Property. All rights reserved.\n\n    Licensed under the Creative Commons License, Attribution 4.0 Intl. (the &quot;License&quot;); you may not use this documentation except in compliance with the License.\n\n    You may obtain a copy of the License at\n\n    (https://creativecommons.org/licenses/by/4.0/)\n\n    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n\n    This document is best viewed with Firefox or Chrome. Nodes can be found by appending /#/definitions/node-type-to-find to the path to this document. Edge definitions can be found with the node definitions.\n  version: \"" + v.toString() +"\"\n");
95                 sb.append("  title: Active and Available Inventory REST API\n");
96                 sb.append("  license:\n    name: Apache 2.0\n    url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
97                 sb.append("  contact:\n    name:\n    url:\n    email:\n");
98                 sb.append("host:\nbasePath: " + basePath + "/" + v.toString() + "\n");
99                 sb.append("schemes:\n  - https\npaths:\n");
100                 return sb.toString();
101         }
102         
103         protected void init() throws ParserConfigurationException, SAXException, IOException, AAIException, FileNotFoundException, EdgeRuleNotFoundException {
104                 super.init();
105         }
106
107         @Override
108         public String process() throws ParserConfigurationException, SAXException, IOException, AAIException, FileNotFoundException, EdgeRuleNotFoundException {
109                 StringBuffer sb = new StringBuffer();
110                 StringBuffer pathSb = new StringBuffer();
111                 NodeGetOperation.resetContainers();
112                 try {
113                         init();
114                 } catch(Exception e) {
115                         logger.error( "Error initializing " + this.getClass());
116                         throw e;
117                 }
118                 pathSb.append(getDocumentHeader());
119                 StringBuffer definitionsSb = new StringBuffer();
120                 Element elem;
121                 String javaTypeName;
122                 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
123                         elem = (Element)javaTypeNodes.item(i);
124                         javaTypeName = elem.getAttribute("name");
125                         if ( !"Inventory".equals(javaTypeName ) ) {
126                                 if ( generatedJavaType.containsKey(javaTypeName) ) {
127                                         continue;
128                                 }
129                                 // will combine all matching java-types
130                                 elem = getJavaTypeElementSwagger(javaTypeName );
131                         }                       
132                         
133                         XSDElement javaTypeElement = new XSDElement(elem);
134                                         
135                         logger.debug("External: "+javaTypeElement.getAttribute("name")+"/"+getXmlRootElementName(javaTypeName));
136                         if ( javaTypeName == null ) {
137                                 String msg = "Invalid OXM file: <java-type> has no name attribute in " + oxmFile; 
138                                 logger.error(msg);
139                                 throw new AAIException(msg);
140                         }
141                         namespaceFilter.add(getXmlRootElementName(javaTypeName));
142                         processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
143                                 definitionsSb, null, null, null, null, null, null);
144                 }
145                 sb.append(pathSb);
146 //              sb.append(getDocumentHeader());
147 //              sb.append(totalPathSbAccumulator);
148                 sb.append(appendOperations());
149                 sb.append(appendDefinitions());
150                 PutRelationPathSet prp = new PutRelationPathSet(v);
151                 prp.generateRelations(ei);
152                 return sb.toString();
153         }
154         
155         public String appendDefinitions() {
156                 return appendDefinitions(null);
157         }
158         
159         public String appendDefinitions(Set<String> namespaceFilter) {
160                 if ( inventoryDefSb != null ) {
161                         javaTypeDefinitions.put("inventory", inventoryDefSb.toString());
162                 }                       
163                 StringBuffer sb = new StringBuffer("definitions:\n");
164                 Map<String, String> sortedJavaTypeDefinitions = new TreeMap<>(javaTypeDefinitions);
165
166                 for (Map.Entry<String, String> entry : sortedJavaTypeDefinitions.entrySet()) {
167                         if(namespaceFilter != null && (! namespaceFilter.contains(entry.getKey()))) {
168                                 continue;
169                         }
170                     sb.append(entry.getValue());
171                 }
172                 return sb.toString();
173         }
174         
175         private String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
176                         StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
177                         String getItemName, StringBuffer pathParams, String validEdges) {
178                 
179                 String xmlRootElementName = getXMLRootElementName(javaTypeElement);
180                 StringBuilder definitionsLocalSb = new StringBuilder(256);
181                 
182                 String useTag = null;
183                 String useOpId = null;
184                 logger.debug("tag="+tag);
185
186                 if(tag != null && (! validTag(tag))) {
187                         logger.debug("tag="+tag+"; javaTypeName="+javaTypeName);
188                         return null;
189                 }               
190                 if ( !javaTypeName.equals("Inventory") ) {
191                         if ( javaTypeName.equals("AaiInternal"))
192                                 return null;
193                         if ( opId == null )
194                                 useOpId = javaTypeName;
195                         else
196                                 useOpId = opId + javaTypeName;
197                         if ( tag == null )
198                                 useTag = javaTypeName;
199                 }
200
201                 path = xmlRootElementName.equals("inventory") ? "" : (path == null) ? "/" + xmlRootElementName : path + "/" + xmlRootElementName;
202                 XSDJavaType javaType = new XSDJavaType(javaTypeElement);
203                 if ( getItemName != null) {
204                 if ( getItemName.equals("array") )
205                         return javaType.getArrayType();
206                 else
207                         return javaType.getItemName();
208                 }
209                         
210                 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
211                 if ( parentNodes.getLength() == 0 ) {
212                         logger.debug( "no java-attributes for java-type " + javaTypeName);
213                         return "";
214                 }
215
216                 String pathDescriptionProperty = javaType.getPathDescriptionProperty();
217                 String container = javaType.getContainerProperty();
218                 Vector<String> indexedProps = javaType.getIndexedProps();
219                 Vector<String> containerProps = new Vector<String>();
220                 if(container != null) {
221                         logger.debug("javaTypeName " + javaTypeName + " container:" + container +" indexedProps:"+indexedProps);
222                 }
223                 
224                 Element parentElement = (Element)parentNodes.item(0);
225                 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
226
227                 StringBuffer sbParameters = new StringBuffer();
228                 StringBuffer sbRequired = new StringBuffer();
229                 int requiredCnt = 0;
230                 int propertyCnt = 0;
231                 StringBuffer sbProperties = new StringBuffer();
232                 
233                 if ( appliedPaths.containsKey(path)) 
234                         return null;
235                 
236                 StringTokenizer st = new StringTokenizer(path, "/");
237                 logger.debug("path: " + path + " st? " + st.toString());
238                 if ( st.countTokens() > 1 && getItemName == null ) {
239                         logger.debug("appliedPaths: " + appliedPaths + " containsKey? " + appliedPaths.containsKey(path));
240                         appliedPaths.put(path, xmlRootElementName);
241                 }
242                 Vector<String> addTypeV = null;
243                 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
244                                 XSDElement xmlElementElement = new XSDElement((Element)xmlElementNodes.item(i));
245                                 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
246                                         continue;
247                                 String elementDescription=xmlElementElement.getPathDescriptionProperty();
248                                 if(getItemName == null) {
249                                         addTypeV = xmlElementElement.getAddTypes(v.toString());
250                                 }
251                     if ( "true".equals(xmlElementElement.getAttribute("xml-key"))) {
252                         path += "/{" + xmlElementElement.getAttribute("name") + "}";
253                     }
254                     logger.debug("path: " + path);
255                 logger.debug( "xmlElementElement.getAttribute(required):"+xmlElementElement.getAttribute("required") );
256                                 
257                                 if ( ("true").equals(xmlElementElement.getAttribute("required"))) {
258                                         if ( requiredCnt == 0 )
259                                                 sbRequired.append("    required:\n");
260                                         ++requiredCnt;
261                                         if ( addTypeV == null || addTypeV.isEmpty()) {
262                                                 sbRequired.append("    - " + xmlElementElement.getAttribute("name") + "\n");
263                                         } else { 
264                                                 for ( int k = 0; k < addTypeV.size(); ++k ) {
265                                                         sbRequired.append("    - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
266                                                 }
267                                         }
268                                 }
269
270                                 if ( "true".equals(xmlElementElement.getAttribute("xml-key")) )  {
271                                         sbParameters.append(xmlElementElement.getPathParamYAML(elementDescription));
272                                 }
273                                 if (  indexedProps != null
274                                                 && indexedProps.contains(xmlElementElement.getAttribute("name") ) ) {
275                                         containerProps.add(xmlElementElement.getQueryParamYAML(elementDescription));
276                                         NodeGetOperation.addContainerProps(container, containerProps);
277                                 } else if ( indexedProps == null || indexedProps.isEmpty() && "true".equals(xmlElementElement.getAttribute("required")) ){
278                                         // no indexedProps and element is required, also considered using xml-key in this case
279                                         containerProps.add(xmlElementElement.getPathParamYAMLRqd(elementDescription, false));
280                                         NodeGetOperation.addContainerProps(container, containerProps);
281                                 }
282                         if ( xmlElementElement.isStandardType()) {
283                                 sbProperties.append(xmlElementElement.getTypePropertyYAML());
284                                 ++propertyCnt;
285                         }
286                         
287 //                      StringBuffer newPathParams = new StringBuffer((pathParams == null ? "" : pathParams.toString())+sbParameters.toString()); //cp8128 don't append the pathParams to sbParameters so that child nodes don't contain the parameters from parent
288                         StringBuffer newPathParams = new StringBuffer(sbParameters.toString());
289                 for ( int k = 0; addTypeV != null && k < addTypeV.size(); ++k ) {
290                         String addType = addTypeV.elementAt(k);
291                                 namespaceFilter.add(getXmlRootElementName(addType));
292                         if ( opId == null || !opId.contains(addType)) {
293                                 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
294                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, null,
295                                         newPathParams, validEdges);
296                         }
297                         // need item name of array
298                                 String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
299                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
300                                                         "array", null, null);
301                                         
302                                 if ( itemName != null ) {
303                                         if ( addType.equals("AaiInternal") ) {
304                                                 logger.debug( "addType AaiInternal, skip properties");
305                                                         
306                                         } else if ( getItemName == null) {
307                                                 ++propertyCnt;
308                                                 sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
309                                                 sbProperties.append("        type: array\n        items:\n");
310                                                 sbProperties.append("          $ref: \"#/definitions/" + (itemName == "" ? "aai-internal" : itemName) + "\"\n");
311                                                 if ( StringUtils.isNotEmpty(elementDescription) )
312                                                         sbProperties.append("        description: " + elementDescription + "\n");
313                                         }
314                                 } else {
315                                         if ( ("java.util.ArrayList").equals(xmlElementElement.getAttribute("container-type"))) {
316                                                         // need properties for getXmlRootElementName(addType)
317                                                 namespaceFilter.add(getXmlRootElementName(addType));
318                                                 if(getXmlRootElementName(addType).equals("service-capabilities"))
319                                                 {
320                                                         logger.info("arrays: "+ getXmlRootElementName(addType));
321                                                 }                                               
322 //                                              newPathParams = new StringBuffer((pathParams == null ? "" : pathParams.toString())+sbParameters.toString()); //cp8128 - change this to not append pathParameters. Just use sbParameters
323                                                 newPathParams = new StringBuffer(sbParameters.toString());
324                                                 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
325                                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
326                                                                         null, newPathParams, validEdges);
327                                                 sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
328                                                 sbProperties.append("        type: array\n        items:          \n");
329                                                 sbProperties.append("          $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
330                                                 if ( StringUtils.isNotEmpty(elementDescription) )
331                                                         sbProperties.append("        description: " + elementDescription + "\n");
332
333                                         } else {
334                                                 //Make sure certain types added to the filter don't appear
335                                                 if (nodeFilter.contains(getXmlRootElementName(addType))) {
336                                                         ;
337                                                 } else {
338                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
339                                                         sbProperties.append("        type: object\n");
340                                                         sbProperties.append("        $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
341                                                 }
342                                         }
343                                         if ( StringUtils.isNotEmpty(elementDescription) )
344                                                 sbProperties.append("        description: " + elementDescription + "\n");
345                                         ++propertyCnt;
346                                 }
347                 }
348                 }
349                 
350                 if ( sbParameters.toString().length() > 0 ) {
351                         if ( pathParams == null )
352                                 pathParams = new StringBuffer();
353                         pathParams.append(sbParameters);
354                 }
355                 if (indexedProps.isEmpty() && containerProps.isEmpty()){
356                         NodeGetOperation get = new NodeGetOperation(useOpId, xmlRootElementName, tag, path, null);
357                         String operation = get.toString();
358                         if(StringUtils.isNotEmpty(operation)) {
359                                 operationDefinitions.put(xmlRootElementName, operation);
360                         }                       
361                 } else {
362                         NodeGetOperation get = new NodeGetOperation(useOpId, xmlRootElementName, tag, path,  pathParams == null ? "" : pathParams.toString());
363                         String operation = get.toString();
364                         if(StringUtils.isNotEmpty(operation)) {
365                                 operationDefinitions.put(xmlRootElementName, operation);
366                         }                       
367                 }
368             logger.debug("opId vs useOpId:"+opId+" vs "+useOpId+" PathParams="+pathParams);
369                 // add PUT
370                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
371                         logger.debug("xmlRootElementName(1)="+xmlRootElementName);
372                         return null;
373                 }
374                 boolean processingInventoryDef = false;
375                 if ( xmlRootElementName.equals("inventory")) {
376                         // inventory properties for each oxm to be concatenated
377                         processingInventoryDef = true;
378                         if ( inventoryDefSb == null ) {
379                                 inventoryDefSb = new StringBuilder();
380                                 definitionsSb.append("  " + xmlRootElementName + ":\n");
381                                 definitionsLocalSb.append("  " + xmlRootElementName + ":\n");
382                                 definitionsLocalSb.append("    properties:\n");
383                         }
384
385                 } else {
386                         definitionsSb.append("  " + xmlRootElementName + ":\n");
387                         definitionsLocalSb.append("  " + xmlRootElementName + ":\n");
388                 }
389                 DeleteFootnoteSet footnotes = new DeleteFootnoteSet(xmlRootElementName);
390                 StringBuffer sbEdge = new StringBuffer();
391                 LinkedHashSet<String> preventDelete = new LinkedHashSet<String>();
392                 String prevent=null;
393                 String nodeCaption = new String("      ###### Related Nodes\n");
394                 try {
395                         EdgeRuleQuery q = new EdgeRuleQuery.Builder(xmlRootElementName).version(v).fromOnly().build();
396                         Multimap<String, EdgeRule> results = ei.getRules(q);
397                         SortedSet<String> ss=new TreeSet<>(results.keySet());
398                         sbEdge.append(nodeCaption);
399                         nodeCaption="";
400                         for(String key : ss) {
401                                 results.get(key).stream().filter((i) -> (i.getFrom().equals(xmlRootElementName) && (! i.isPrivateEdge()))).forEach((i) ->{ logger.info(new String(new StringBuffer("      - TO ").append(i.getTo()).append(i.getDirection().toString()).append(i.getContains())));} );
402                                 results.get(key).stream().filter((i) -> (i.getFrom().equals(xmlRootElementName) && (! i.isPrivateEdge()))).forEach((i) ->{ sbEdge.append("      - TO "+i.getTo()); EdgeDescription ed = new EdgeDescription(i);  String footnote = ed.getAlsoDeleteFootnote(xmlRootElementName); sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName)+footnote+"\n"); if(StringUtils.isNotEmpty(footnote)) footnotes.add(footnote);} );
403                                 results.get(key).stream().filter((i) -> (i.getFrom().equals(xmlRootElementName) && (! i.isPrivateEdge() && i.getPreventDelete().equals("OUT")))).forEach((i) ->{ preventDelete.add(i.getTo().toUpperCase());} );
404                         }
405                 } catch(Exception e) {
406                         logger.debug("xmlRootElementName: "+xmlRootElementName+"\n"+e);
407                 }
408                 try {
409                         EdgeRuleQuery q1 = new EdgeRuleQuery.Builder(xmlRootElementName).version(v).toOnly().build();
410                         Multimap<String, EdgeRule> results = ei.getRules(q1);
411                         SortedSet<String> ss=new TreeSet<String>(results.keySet());
412                         sbEdge.append(nodeCaption);
413                         for(String key : ss) {
414                                 results.get(key).stream().filter((i) -> (i.getTo().equals(xmlRootElementName) && (! i.isPrivateEdge()))).forEach((i) ->{ sbEdge.append("      - FROM "+i.getFrom()); EdgeDescription ed = new EdgeDescription(i);  String footnote = ed.getAlsoDeleteFootnote(xmlRootElementName); sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName)+footnote+"\n"); if(StringUtils.isNotEmpty(footnote)) footnotes.add(footnote);} );
415                                 results.get(key).stream().filter((i) -> (i.getTo().equals(xmlRootElementName) && (! i.isPrivateEdge()))).forEach((i) ->{ logger.info(new String(new StringBuffer("      - FROM ").append(i.getFrom()).append(i.getDirection().toString()).append(i.getContains())));} );
416                                 results.get(key).stream().filter((i) -> (i.getTo().equals(xmlRootElementName) && (! i.isPrivateEdge() && i.getPreventDelete().equals("IN")))).forEach((i) ->{ preventDelete.add(i.getFrom().toUpperCase());} );
417                         }
418                 } catch(Exception e) {
419                         logger.debug("xmlRootElementName: "+xmlRootElementName+"\n"+e);
420                 }
421                 if(preventDelete.size() > 0) {
422                         prevent = xmlRootElementName.toUpperCase()+" cannot be deleted if related to "+String.join(",",preventDelete);
423                         logger.debug(prevent);
424                 }
425
426                 if(StringUtils.isNotEmpty(prevent)) {
427                         footnotes.add(prevent);
428                 }
429                 if(footnotes.footnotes.size() > 0) {
430                         sbEdge.append(footnotes.toString());
431                 }                       
432                 validEdges = sbEdge.toString();
433
434                 // Handle description property.  Might have a description OR valid edges OR both OR neither.
435                 // Only put a description: tag if there is at least one.
436                 if (StringUtils.isNotEmpty(pathDescriptionProperty) || StringUtils.isNotEmpty(validEdges) ) {
437                         definitionsSb.append("    description: |\n");
438                         definitionsLocalSb.append("    description: |\n");      
439
440                         if ( pathDescriptionProperty != null ) {
441                                 definitionsSb.append("      " + pathDescriptionProperty + "\n" );
442                                 definitionsLocalSb.append("      " + pathDescriptionProperty    + "\n" );
443                         }
444                         definitionsSb.append(validEdges);
445                         definitionsLocalSb.append(validEdges);
446                 }
447                 
448                 if ( requiredCnt > 0 ) {
449                         definitionsSb.append(sbRequired);
450                         definitionsLocalSb.append(sbRequired);
451                 }
452                         
453                 if ( propertyCnt > 0 ) {
454                         definitionsSb.append("    properties:\n");
455                         definitionsSb.append(sbProperties);
456                         if  ( !processingInventoryDef) {
457                                 definitionsLocalSb.append("    properties:\n");
458                         }
459                         definitionsLocalSb.append(sbProperties);
460                 }
461                 try {
462                         namespaceFilter.add(xmlRootElementName);
463                         if ( xmlRootElementName.equals("inventory") ) {
464                                 //will add to javaTypeDefinitions at end 
465                                 inventoryDefSb.append(definitionsLocalSb.toString());
466                         } else {
467                                 javaTypeDefinitions.put(xmlRootElementName, definitionsLocalSb.toString());
468                         }
469                 } catch (Exception e) {
470                         e.printStackTrace();
471                 }
472                 if ( xmlRootElementName.equals("inventory") ) {
473                         logger.trace("skip xmlRootElementName(2)="+xmlRootElementName);
474                         return null;
475                 }
476                 generatedJavaType.put(xmlRootElementName, null);
477                 //Write operations by Namespace(tagName)
478 /*
479                 if( validTag(javaTypeName) && javaTypeName == useTag && tag == null) {
480                         writeYAMLfile("nodes_"+javaTypeName, getDocumentHeader()+pathSb.toString()+appendDefinitions(namespaceFilter));
481                         totalPathSbAccumulator.append(pathSb);
482                         pathSb.delete(0, pathSb.length());
483                         namespaceFilter.clear();
484                 }
485 */
486                 logger.debug("xmlRootElementName(2)="+xmlRootElementName);
487                 return null;
488         }
489         
490         private void writeYAMLfile(String outfileName, String fileContent) {
491                 outfileName = (StringUtils.isEmpty(outfileName)) ? "aai_swagger" : outfileName;
492                 outfileName = (outfileName.lastIndexOf(File.separator) == -1) ? yaml_dir + File.separator +outfileName+"_" + v.toString() + "." + generateTypeYAML : outfileName;
493                 File outfile = new File(outfileName);
494                 File parentDir = outfile.getParentFile();
495                 if(parentDir != null && ! parentDir.exists()) 
496                         parentDir.mkdirs();
497                 try {
498                         outfile.createNewFile();
499                 } catch (IOException e) {
500                         logger.error( "Exception creating output file " + outfileName);
501                         e.printStackTrace();
502                 }
503                 Path path = Paths.get(outfileName);
504                 Charset charset = Charset.forName("UTF-8");
505                 try(BufferedWriter bw = Files.newBufferedWriter(path, charset);) {
506                         bw.write(fileContent);
507                         if ( bw != null ) {
508                                 bw.close();
509                         }
510                 } catch ( IOException e) {
511                         logger.error( "Exception writing output file " + outfileName);
512                         e.printStackTrace();
513                 } 
514         }
515         
516         public boolean validTag(String tag) {
517                 if(tag != null) {
518                         switch ( tag ) {
519                         case "Network":
520                         case "Search":
521                         case "Actions":
522                         case "ServiceDesignAndCreation":
523                         case "Business":
524                         case "LicenseManagement":
525                         case "CloudInfrastructure":
526                                 return true;
527                         }
528                 }
529                 return false;
530         }
531         
532         public String appendOperations() {
533                 //append definitions
534                 StringBuffer sb = new StringBuffer();
535                 Map<String, String> sortedOperationDefinitions = new TreeMap<String, String>(operationDefinitions);
536                 for (Map.Entry<String, String> entry : sortedOperationDefinitions.entrySet()) {
537                     sb.append(entry.getValue());
538                 }
539                 return sb.toString();
540         }
541 }
542