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