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