930e2fb29a7aff70a589373c36dc685aca9b052a
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / util / genxsd / YAMLfromOXM.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.LinkedHashSet;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.SortedSet;
34 import java.util.StringTokenizer;
35 import java.util.TreeMap;
36 import java.util.TreeSet;
37 import java.util.Vector;
38
39 import javax.xml.parsers.ParserConfigurationException;
40
41 import org.apache.commons.lang3.StringUtils;
42 import org.onap.aai.edges.EdgeIngestor;
43 import org.onap.aai.edges.EdgeRule;
44 import org.onap.aai.edges.EdgeRuleQuery;
45 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
46 import org.onap.aai.exceptions.AAIException;
47 import org.onap.aai.setup.SchemaVersion;
48 import org.onap.aai.setup.SchemaVersions;
49 import org.onap.aai.nodes.NodeIngestor;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52 import org.w3c.dom.Element;
53 import org.w3c.dom.NodeList;
54 import org.xml.sax.SAXException;
55 import com.google.common.collect.Multimap;
56
57
58 public class YAMLfromOXM extends OxmFileProcessor {
59         private static final Logger logger = LoggerFactory.getLogger("YAMLfromOXM.class");
60 //      private static StringBuffer totalPathSbAccumulator = new StringBuffer();
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         
68
69         private String basePath;
70         
71         public YAMLfromOXM(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 © 2017-18 AT&T Intellectual Property. All rights reserved.\n\n    Licensed under the Creative Commons License, Attribution 4.0 Intl. (the "License"); 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 "AS IS" 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                 try {
112                         init();
113                 } catch(Exception e) {
114                         logger.error( "Error initializing " + this.getClass());
115                         throw e;
116                 }               
117                 pathSb.append(getDocumentHeader());
118                 StringBuffer definitionsSb = new StringBuffer();
119                 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
120                         XSDElement javaTypeElement = new XSDElement((Element)javaTypeNodes.item(i));
121                         logger.debug("External: "+javaTypeElement.getAttribute("name"));
122                         String javaTypeName = javaTypeElement.name();
123                         if ( javaTypeName == null ) {
124                                 String msg = "Invalid OXM file: <java-type> has no name attribute in " + oxmFile; 
125                                 logger.error(msg);
126                                 throw new AAIException(msg);
127                         }
128                         namespaceFilter.add(getXmlRootElementName(javaTypeName));
129                         //Skip any type that has already been processed(recursion could be the reason)
130                         if ( generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
131                                         continue;
132                         }
133                         processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
134                                 definitionsSb, null, null, null, null, null, null);
135                 }
136                 sb.append(pathSb);
137
138                 sb.append(appendDefinitions());
139                 PutRelationPathSet prp = new PutRelationPathSet(v);
140                 prp.generateRelations(ei);
141                 return sb.toString();
142         }
143         
144         public String appendDefinitions() {
145                 return appendDefinitions(null);
146         }
147         
148         public String appendDefinitions(Set<String> namespaceFilter) {
149                 //append definitions
150                 if ( inventoryDefSb != null ) {
151                         javaTypeDefinitions.put("inventory", inventoryDefSb.toString());
152                 }
153                 StringBuffer sb = new StringBuffer("definitions:\n");
154                 Map<String, String> sortedJavaTypeDefinitions = new TreeMap<String, String>(javaTypeDefinitions);
155                 for (Map.Entry<String, String> entry : sortedJavaTypeDefinitions.entrySet()) {
156 //                  logger.info("Key: "+entry.getKey()+"Value: "+ entry.getValue());
157                     if(namespaceFilter != null && entry.getKey().matches("service-capabilities")) {
158                         for(String tally : namespaceFilter) { logger.debug("Marker: "+tally);}
159                     }
160                         if(namespaceFilter != null && (! namespaceFilter.contains(entry.getKey()))) {
161                                 continue;
162                         }
163                     logger.debug("Key: "+entry.getKey()+"Test: "+ (entry.getKey() == "relationship"));  
164                     if(entry.getKey().matches("relationship")) {
165                             String jb=entry.getValue();
166                         logger.debug("Value: "+jb);
167                             int ndx=jb.indexOf("related-to-property:");
168                             if(ndx > 0) {
169                                 jb=jb.substring(0, ndx);
170                                 jb=jb.replaceAll(" +$", "");
171                             }
172                         logger.debug("Value-after: "+jb);
173                         sb.append(jb);
174                         continue;
175                     }
176                     sb.append(entry.getValue());
177                 }
178                 
179                 sb.append("patchDefinitions:\n");
180                 for (Map.Entry<String, String> entry : sortedJavaTypeDefinitions.entrySet()) {
181                         if(namespaceFilter != null && (! namespaceFilter.contains(entry.getKey()))) {
182                                 continue;
183                         }
184                     String jb=entry.getValue().replaceAll("/definitions/", "/patchDefinitions/");
185                     int ndx=jb.indexOf("relationship-list:");
186                     if(ndx > 0) {
187                         jb=jb.substring(0, ndx);
188                         jb=jb.replaceAll(" +$", "");
189                     }
190                     int ndx1=jb.indexOf("resource-version:");
191                         logger.debug("Key: "+entry.getKey()+" index: " + ndx1);                 
192                         logger.debug("Value: "+jb);                     
193                         if(ndx1 > 0) {
194                             jb=jb.substring(0, ndx1);
195                             jb=jb.replaceAll(" +$", "");
196                     }
197                         logger.debug("Value-after: "+jb);
198                     sb.append(jb);
199                 }
200                     
201                 sb.append("getDefinitions:\n");
202                 for (Map.Entry<String, String> entry : sortedJavaTypeDefinitions.entrySet()) {
203                         if(namespaceFilter != null && (! namespaceFilter.contains(entry.getKey()))) {
204                                 continue;
205                         }
206                     String jb=entry.getValue().replaceAll("/definitions/", "/getDefinitions/");
207                     sb.append(jb);
208                 }
209                 return sb.toString();
210         }
211         
212         private String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
213                         StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
214                         String getItemName, StringBuffer pathParams, String validEdges) {
215                 
216                 String xmlRootElementName = getXMLRootElementName(javaTypeElement);
217                 StringBuilder definitionsLocalSb = new StringBuilder(256);
218                 
219                 String useTag = null;
220                 String useOpId = null;
221                 logger.debug("tag="+tag);
222                 if ( tag != null ) {
223                         switch ( tag ) {
224                         case "Network":
225                         case "ServiceDesignAndCreation":
226                         case "Business":
227                         case "LicenseManagement":
228                         case "CloudInfrastructure":
229                         case "Common":
230                                 break;
231                         default:
232                                 logger.debug("javaTypeName="+javaTypeName);
233                                 return null;
234                         }
235                 }
236                 
237                 if ( !javaTypeName.equals("Inventory") ) {
238                         if ( javaTypeName.equals("AaiInternal"))
239                                 return null;
240                         if ( opId == null )
241                                 useOpId = javaTypeName;
242                         else
243                                 useOpId = opId + javaTypeName;
244                         if ( tag == null )
245                                 useTag = javaTypeName;
246                 }
247                 path = xmlRootElementName.equals("inventory") ? "" : (path == null) ? "/" + xmlRootElementName : path + "/" + xmlRootElementName;
248                 XSDJavaType javaType = new XSDJavaType(javaTypeElement);
249                 if ( getItemName != null) {
250                 if ( getItemName.equals("array") )
251                         return javaType.getArrayType();
252                 else
253                         return javaType.getItemName();
254                 }
255                         
256                 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
257                 if ( parentNodes.getLength() == 0 ) {
258                         logger.debug( "no java-attributes for java-type " + javaTypeName);
259                         return "";
260                 }
261
262                 String pathDescriptionProperty = javaType.getPathDescriptionProperty();
263                 String container = javaType.getContainerProperty();
264                 Vector<String> indexedProps = javaType.getIndexedProps();
265                 Vector<String> containerProps = new Vector<String>();
266                 if(container != null) {
267                         logger.debug("javaTypeName " + javaTypeName + " container:" + container +" indexedProps:"+indexedProps);
268                 }
269                 
270                 Element parentElement = (Element)parentNodes.item(0);
271                 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
272
273                 StringBuffer sbParameters = new StringBuffer();
274                 StringBuffer sbRequired = new StringBuffer();
275                 int requiredCnt = 0;
276                 int propertyCnt = 0;
277                 StringBuffer sbProperties = new StringBuffer();
278                 
279                 if ( appliedPaths.containsKey(path)) 
280                         return null;
281                 
282                 StringTokenizer st = new StringTokenizer(path, "/");
283                 logger.debug("path: " + path + " st? " + st.toString());
284                 if ( st.countTokens() > 1 && getItemName == null ) {
285                         logger.debug("appliedPaths: " + appliedPaths + " containsKey? " + appliedPaths.containsKey(path));
286                         appliedPaths.put(path, xmlRootElementName);
287                 }
288
289                 Vector<String> addTypeV = null;
290                 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
291                                 XSDElement xmlElementElement = new XSDElement((Element)xmlElementNodes.item(i));
292                                 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
293                                         continue;
294                                 String elementDescription=xmlElementElement.getPathDescriptionProperty();
295                                 if(getItemName == null) {
296                                         addTypeV = xmlElementElement.getAddTypes(v.toString());
297                                 }
298                     if ( "true".equals(xmlElementElement.getAttribute("xml-key"))) {
299                         path += "/{" + xmlElementElement.getAttribute("name") + "}";
300                     }
301                     logger.debug("path: " + path);
302                 logger.debug( "xmlElementElement.getAttribute(required):"+xmlElementElement.getAttribute("required") );
303                                 
304                                 if ( ("true").equals(xmlElementElement.getAttribute("required"))) {
305                                         if ( requiredCnt == 0 )
306                                                 sbRequired.append("    required:\n");
307                                         ++requiredCnt;
308                                         if ( addTypeV == null || addTypeV.isEmpty()) {
309                                                 sbRequired.append("    - " + xmlElementElement.getAttribute("name") + "\n");
310                                         } else { 
311                                                 for ( int k = 0; k < addTypeV.size(); ++k ) {
312                                                         sbRequired.append("    - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
313                                                 }
314                                         }
315                                 }
316
317                                 if ( "true".equals(xmlElementElement.getAttribute("xml-key")) )  {
318                                         sbParameters.append(xmlElementElement.getPathParamYAML(elementDescription));
319                                 }
320                                 if (  indexedProps != null
321                                                 && indexedProps.contains(xmlElementElement.getAttribute("name") ) ) {
322                                         containerProps.add(xmlElementElement.getQueryParamYAML());
323                                         GetOperation.addContainerProps(container, containerProps);
324                                 }
325                         if ( xmlElementElement.isStandardType()) {
326                                 sbProperties.append(xmlElementElement.getTypePropertyYAML());
327                                 ++propertyCnt;
328                         }
329                         
330                         StringBuffer newPathParams = new StringBuffer((pathParams == null ? "" : pathParams.toString())+sbParameters.toString()); 
331                 for ( int k = 0; addTypeV != null && k < addTypeV.size(); ++k ) {
332                         String addType = addTypeV.elementAt(k);
333                                 namespaceFilter.add(getXmlRootElementName(addType));
334                                 logger.debug("addType: "+ addType);
335                 
336                         if ( opId == null || !opId.contains(addType)) {
337                                 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
338                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, null,
339                                         newPathParams, validEdges);
340                         }
341                         // need item name of array
342                                 String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
343                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
344                                                         "array", null, null );
345                                         
346                                 if ( itemName != null ) {
347                                         if ( addType.equals("AaiInternal") ) {
348                                                 logger.debug( "addType AaiInternal, skip properties");
349                                                         
350                                         } else if ( getItemName == null) {
351                                                 ++propertyCnt;
352                                                 sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
353                                                 sbProperties.append("        type: array\n        items:\n");
354                                                 sbProperties.append("          $ref: \"#/definitions/" + (itemName == "" ? "inventory-item-data" : itemName) + "\"\n");
355                                                 if ( StringUtils.isNotEmpty(elementDescription) )
356                                                         sbProperties.append("        description: " + elementDescription + "\n");
357                                         }
358                                 } else {
359                                         if ( ("java.util.ArrayList").equals(xmlElementElement.getAttribute("container-type"))) {
360                                                         // need properties for getXmlRootElementName(addType)
361                                                 namespaceFilter.add(getXmlRootElementName(addType));
362                                                 newPathParams = new StringBuffer((pathParams == null ? "" : pathParams.toString())+sbParameters.toString()); 
363                                                 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
364                                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
365                                                                         null, newPathParams, validEdges );
366                                                 sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
367                                                 sbProperties.append("        type: array\n        items:          \n");
368                                                 sbProperties.append("          $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
369                                                 if ( StringUtils.isNotEmpty(elementDescription) )
370                                                         sbProperties.append("        description: " + elementDescription + "\n");
371
372                                         } else {
373                                                 //Make sure certain types added to the filter don't appear
374                                                 if(nodeFilter.contains(getXmlRootElementName(addType))) {
375                                                         ;
376                                                 } else {
377                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
378                                                         sbProperties.append("        type: object\n");
379                                                         sbProperties.append("        $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
380                                                 }
381                                         }
382                                         if ( StringUtils.isNotEmpty(elementDescription) )
383                                                 sbProperties.append("        description: " + elementDescription + "\n");
384                                         ++propertyCnt;
385                                 }
386                 }
387                 }
388                 
389                 if ( sbParameters.toString().length() > 0 ) {
390                         if ( pathParams == null )
391                                 pathParams = new StringBuffer();
392                         pathParams.append(sbParameters);
393                 }
394                 GetOperation get = new GetOperation(useOpId, xmlRootElementName, tag, path,  pathParams == null ? "" : pathParams.toString());
395             pathSb.append(get.toString());
396             logger.debug("opId vs useOpId:"+opId+" vs "+useOpId+" PathParams="+pathParams);
397                 // add PUT
398                 PutOperation put = new PutOperation(useOpId, xmlRootElementName, tag, path, pathParams == null ? "" : pathParams.toString(), this.v);
399                 pathSb.append(put.toString());
400                 // add PATCH
401                 PatchOperation patch = new PatchOperation(useOpId, xmlRootElementName, tag, path, pathParams == null ? "" : pathParams.toString());
402                 pathSb.append(patch.toString());
403                 // add DELETE
404                 DeleteOperation del = new DeleteOperation(useOpId, xmlRootElementName, tag, path, pathParams == null ? "" : pathParams.toString());
405                 pathSb.append(del.toString());
406                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
407                         logger.debug("xmlRootElementName(1)="+xmlRootElementName);
408                         return null;
409                 }
410         
411                 boolean processingInventoryDef = false;
412                 if ( xmlRootElementName.equals("inventory")) {
413                         // inventory properties for each oxm to be concatenated
414                         processingInventoryDef = true;
415                         if ( inventoryDefSb == null ) {
416                                 inventoryDefSb = new StringBuilder();
417                                 definitionsSb.append("  " + xmlRootElementName + ":\n");
418                                 definitionsLocalSb.append("  " + xmlRootElementName + ":\n");
419                                 definitionsLocalSb.append("    properties:\n");
420                         }
421
422                 } else {
423                         definitionsSb.append("  " + xmlRootElementName + ":\n");
424                         definitionsLocalSb.append("  " + xmlRootElementName + ":\n");
425                 }
426 //              Collection<EdgeDescription> edges = edgeRuleSet.getEdgeRules(xmlRootElementName );
427                 DeleteFootnoteSet footnotes = new DeleteFootnoteSet(xmlRootElementName);
428                 StringBuffer sbEdge = new StringBuffer();
429                 LinkedHashSet<String> preventDelete = new LinkedHashSet<String>();
430                 String prevent=null;
431                 String nodeCaption = new String("      ###### Related Nodes\n");
432                 try {
433                         EdgeRuleQuery q = new EdgeRuleQuery.Builder(xmlRootElementName).version(v).fromOnly().build();
434                         Multimap<String, EdgeRule> results = ei.getRules(q);
435                         SortedSet<String> ss=new TreeSet<String>(results.keySet());
436                         sbEdge.append(nodeCaption);
437                         nodeCaption="";
438                         for(String key : ss) {
439                                 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())));} );
440                                 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);} );
441                                 results.get(key).stream().filter((i) -> (i.getFrom().equals(xmlRootElementName) && (! i.isPrivateEdge() && i.getPreventDelete().equals("OUT")))).forEach((i) ->{ preventDelete.add(i.getTo().toUpperCase());} );
442                         }
443                 } catch(Exception e) {
444                         logger.debug("xmlRootElementName: "+xmlRootElementName+"\n"+e);
445                 }
446                 try {
447                         EdgeRuleQuery q1 = new EdgeRuleQuery.Builder(xmlRootElementName).version(v).toOnly().build();
448                         Multimap<String, EdgeRule> results = ei.getRules(q1);
449                         SortedSet<String> ss=new TreeSet<String>(results.keySet());
450                         sbEdge.append(nodeCaption);
451                         for(String key : ss) {
452                                 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);} );
453                                 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())));} );
454                                 results.get(key).stream().filter((i) -> (i.getTo().equals(xmlRootElementName) && (! i.isPrivateEdge() && i.getPreventDelete().equals("IN")))).forEach((i) ->{ preventDelete.add(i.getFrom().toUpperCase());} );
455                         }
456                 } catch(Exception e) {
457                         logger.debug("xmlRootElementName: "+xmlRootElementName+"\n"+e);
458                 }
459                 if(preventDelete.size() > 0) {
460                         prevent = xmlRootElementName.toUpperCase()+" cannot be deleted if related to "+String.join(",",preventDelete);
461                         logger.debug(prevent);
462                 }
463
464                 if(StringUtils.isNotEmpty(prevent)) {
465                         footnotes.add(prevent);
466                 }
467                 if(footnotes.footnotes.size() > 0) {
468                         sbEdge.append(footnotes.toString());
469                 }                       
470                 validEdges = sbEdge.toString();
471
472                 // Handle description property.  Might have a description OR valid edges OR both OR neither.
473                 // Only put a description: tag if there is at least one.
474                 if (StringUtils.isNotEmpty(pathDescriptionProperty) || StringUtils.isNotEmpty(validEdges) ) {
475                         definitionsSb.append("    description: |\n");
476                         definitionsLocalSb.append("    description: |\n");      
477
478                         if ( pathDescriptionProperty != null ) {
479                                 definitionsSb.append("      " + pathDescriptionProperty + "\n" );
480                                 definitionsLocalSb.append("      " + pathDescriptionProperty    + "\n" );
481                         }
482                         definitionsSb.append(validEdges);
483                         definitionsLocalSb.append(validEdges);
484                 }
485                 
486                 if ( requiredCnt > 0 ) {
487                         definitionsSb.append(sbRequired);
488                         definitionsLocalSb.append(sbRequired);
489                 }
490                         
491                 if ( propertyCnt > 0 ) {
492                         definitionsSb.append("    properties:\n");
493                         definitionsSb.append(sbProperties);
494                         if  ( !processingInventoryDef) {
495                                 definitionsLocalSb.append("    properties:\n");
496                         }
497                         definitionsLocalSb.append(sbProperties);
498                 }
499                 try {
500                         namespaceFilter.add(xmlRootElementName);
501                         if ( xmlRootElementName.equals("inventory") ) {
502                                 //will add to javaTypeDefinitions at end 
503                                 inventoryDefSb.append(definitionsLocalSb.toString());
504                         } else {
505                                 javaTypeDefinitions.put(xmlRootElementName, definitionsLocalSb.toString());
506                         }
507                 } catch (Exception e) {
508                         e.printStackTrace();
509                 }
510                 if ( xmlRootElementName.equals("inventory") ) {
511                         logger.trace("skip xmlRootElementName(2)="+xmlRootElementName);
512                         return null;
513                 }               
514                 generatedJavaType.put(xmlRootElementName, null);
515 /*
516                 if( validTag(javaTypeName) && javaTypeName == useTag && tag == null) {
517                         String nameSpaceResult = getDocumentHeader()+pathSb.toString()+appendDefinitions(namespaceFilter);
518                         writeYAMLfile(javaTypeName, nameSpaceResult);
519                         totalPathSbAccumulator.append(pathSb);
520                         pathSb.delete(0, pathSb.length());
521                         namespaceFilter.clear();
522                 }
523 */
524                 logger.trace("xmlRootElementName(2)="+xmlRootElementName);
525                 return null;
526         }
527         
528         private void writeYAMLfile(String outfileName, String fileContent) {
529                 outfileName = (StringUtils.isEmpty(outfileName)) ? "aai_swagger" : outfileName;
530                 outfileName = (outfileName.lastIndexOf(File.separator) == -1) ? yaml_dir + File.separator +outfileName+"_" + v.toString() + "." + generateTypeYAML : outfileName;
531                 File outfile = new File(outfileName);
532                 File parentDir = outfile.getParentFile();
533                 if(parentDir != null && ! parentDir.exists()) 
534                         parentDir.mkdirs();
535                 try {
536                         outfile.createNewFile();
537                 } catch (IOException e) {
538                         logger.error( "Exception creating output file " + outfileName);
539                         e.printStackTrace();
540                 }
541                 BufferedWriter bw = null;
542                 try {
543                         Charset charset = Charset.forName("UTF-8");
544                         Path path = Paths.get(outfileName);
545                         bw = Files.newBufferedWriter(path, charset);
546                         bw.write(fileContent);
547                         if ( bw != null ) {
548                                 bw.close();
549                         }
550                 } catch ( IOException e) {
551                         logger.error( "Exception writing output file " + outfileName);
552                         e.printStackTrace();
553                 } 
554         }
555         
556         public boolean validTag(String tag) {
557                 if(tag != null) {
558                         switch ( tag ) {
559                         case "Network":
560 //                      case "Search":
561 //                      case "Actions":
562                         case "ServiceDesignAndCreation":
563                         case "Business":
564                         case "LicenseManagement":
565                         case "CloudInfrastructure":
566                         case "Common":
567                                 return true;
568                         }
569                 }
570                 return false;
571         }
572
573 }