[AAI-12] Add the swagger documentation for onap
[aai/aai-common.git] / aai-core / src / main / java / org / openecomp / aai / util / GenerateXsd.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.openecomp.aai
4  * ================================================================================
5  * Copyright (C) 2017 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
21 package org.openecomp.aai.util;
22
23 import java.io.BufferedWriter;
24 import java.io.File;
25 import java.io.FileWriter;
26 import java.io.IOException;
27 import java.lang.reflect.Field;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.StringTokenizer;
37 import java.util.Vector;
38
39 import javax.xml.XMLConstants;
40 import javax.xml.bind.JAXBContext;
41 import javax.xml.bind.JAXBException;
42 import javax.xml.bind.SchemaOutputResolver;
43 import javax.xml.parsers.DocumentBuilder;
44 import javax.xml.parsers.DocumentBuilderFactory;
45 import javax.xml.transform.Result;
46 import javax.xml.transform.stream.StreamResult;
47 import javax.xml.xpath.XPath;
48 import javax.xml.xpath.XPathConstants;
49 import javax.xml.xpath.XPathExpression;
50 import javax.xml.xpath.XPathExpressionException;
51 import javax.xml.xpath.XPathFactory;
52
53 import org.w3c.dom.Attr;
54 import org.w3c.dom.Document;
55 import org.w3c.dom.Element;
56 import org.w3c.dom.NamedNodeMap;
57 import org.w3c.dom.NodeList;
58
59 import org.openecomp.aai.dbmodel.DbEdgeRules;
60 import org.openecomp.aai.db.props.AAIProperties;
61 import org.openecomp.aai.introspection.Version;
62 import com.google.common.base.Joiner;
63 import com.google.common.collect.Multimap;
64
65
66 public class GenerateXsd {
67         static String apiVersion = null;
68         static String apiVersionFmt = null;
69         static boolean useAnnotationsInXsd = false;
70         static String responsesUrl = null;
71         static String responsesLabel = null;
72         //static Map<String, String> generatedJavaType = new HashMap<String, String>();
73         //static Map<String, String> appliedPaths = new HashMap<String, String>();
74         static Map<String, String> generatedJavaType;
75         static Map<String, String> appliedPaths;
76         static NodeList javaTypeNodes;
77         static Class<?> versionedClass;
78
79         
80         public static final int VALUE_NONE = 0;
81         public static final int VALUE_DESCRIPTION = 1;
82         public static final int VALUE_INDEXED_PROPS = 2;
83         
84         private static final String generateTypeXSD = "xsd";
85         private static final String generateTypeYAML = "yaml";
86         
87         private static final String root = "../aai-schema/src/main/resources";
88         private static final String xsd_dir = root + "/aai_schema";
89         private static final String yaml_dir = root + "/aai_swagger_yaml";
90         
91         private static int annotationsStartVersion = 9; // minimum version to support annotations in xsd
92         private static int swaggerSupportStartsVersion = 7; // minimum version to support swagger documentation
93         
94         private static XPath xpath = XPathFactory.newInstance().newXPath();
95         
96
97         private enum LineageType {
98                 PARENT, CHILD, UNRELATED;
99         }
100         private class EdgeDescription {
101                 
102                 private String ruleKey;
103                 private LineageType type = LineageType.UNRELATED;
104                 private String direction;
105                 private String multiplicity;
106                 private boolean hasDelTarget = false;
107
108                 public String getRuleKey() {
109                         return ruleKey;
110                 }
111                 public String getMultiplicity() {
112                         return multiplicity;
113                 }
114                 public String getDirection() {
115                         return direction;
116                 }
117                 public void setRuleKey(String val) {
118                         this.ruleKey=val;
119                 }
120                 public void setType(LineageType val) {
121                         this.type=val;
122                 }
123                 public void setDirection(String val) {
124                         this.direction = val;
125                 }
126                 public void setMultiplicity(String val) {
127                         this.multiplicity=val;
128                 }
129                 public void setHasDelTarget(String val) {
130                         hasDelTarget = Boolean.parseBoolean(val);
131                 }
132
133                 public String getRelationshipDescription(String fromTo, String otherNodeName) {
134                         
135                         String result = "";             
136
137                         if ("FROM".equals(fromTo)) {
138                                 if ("OUT".equals(direction)) {
139                                         if (LineageType.PARENT == type) {
140                                                 result = " (is composed of "+otherNodeName;
141                                         } 
142                                 } 
143                                 else {
144                                         if (LineageType.CHILD == type) {
145                                                 result = " (comprises "+otherNodeName;
146                                         } 
147                                         else if (LineageType.PARENT == type) {
148                                                 result = " (comprises "+otherNodeName;
149                                         }
150                                 }
151                         } else {
152                                 if ("OUT".equals(direction)) {
153                                         if (LineageType.PARENT == type) {
154                                                 result = " (comprises "+otherNodeName;
155                                         } 
156                                 } else {
157                                         if (LineageType.PARENT == type) {
158                                                 result = " (is composed of "+otherNodeName;
159                                         }
160                                 }
161                         }
162
163 //                      if (type != null) {
164 //                              if (LineageType.PARENT.equals(type) && "FROM".equals(fromTo)) {
165 //                                      if ("OUT".equals(direction)) {
166 //                                              result = " (is composed of "+otherNodeName;
167 //                                      } else {
168 //                                              result = " (comprises "+otherNodeName;
169 //                                      }
170 //                              } else {
171 //                                      result = " (comprises " + otherNodeName;
172 //                                      //                                      if (!(multiplicity.startsWith("One"))) {
173 //                                      //                                              System.err.println("Surprised to find multiplicity "+multiplicity+" with comprises for "+ruleKey);
174 //                                      //                                      }
175 //                              }
176 //                      }
177                         if ("TO".equals(fromTo)) {
178                                 if (result.length() == 0) result = result + " (";
179                                 else result = result + ", ";
180
181                                 result = result + mapMultiplicity(fromTo);
182                                 if (hasDelTarget) result = result + ", will delete target node";
183                         }
184
185                         if (result.length() > 0) result = result + ")";
186                         
187                         return result;
188                 }
189
190                 private String mapMultiplicity(String fromTo) {
191                         String result = multiplicity;
192 // Below logic works if an IN switches multiplicity, which it doesn't today.
193 //                      if ("TO".equals(fromTo)) {
194 //                              if (direction.equals("OUT")) {
195 //                                      result = multiplicity;
196 //                              } else {
197 //                                      result = switchMultiplicity(multiplicity);
198 //                              }
199 //                      } else {
200 //                              if (direction.equals("OUT")) {
201 //                                      result = multiplicity;
202 //                              } else {
203 //                                      result = switchMultiplicity(multiplicity);
204 //                              }
205 //                      } 
206                         return result;
207                 }
208
209 //              private String switchMultiplicity(String val) throws IllegalArgumentException
210 //              {
211 //                      String result = null;
212 //                      switch (val) {
213 //                      case "Many2Many":
214 //                      case "One2One":
215 //                              result = val;
216 //                              break;
217 //                      case "Many2One":
218 //                              result = "One2Many";
219 //                              break;
220 //                      case "One2Many":
221 //                              result = "Many2One";
222 //                              break;
223 //                      default:
224 //                              throw new IllegalArgumentException("Multiplicity cannot be "+val);
225 //                      }
226 //                      System.out.println("Switched Multiplicity from "+val+" to "+result);
227 //                      return result;
228 //              }
229         }
230         
231         private static boolean validVersion(String versionToGen) {
232                 
233                 if ("ALL".equalsIgnoreCase(versionToGen)) {
234                         return true;
235                 }
236                 
237                 for (Version v : Version.values()) {
238                 if (v.name().equals(versionToGen)) {
239                     return true;
240                 }
241             }
242
243             return false;
244         }
245         
246         private static boolean versionUsesAnnotations( String version) {
247                 if (new Integer(version.substring(1)).intValue() >= annotationsStartVersion ) {
248                         return true;
249                 }
250                 return false;
251         }
252         
253         private static boolean versionSupportsSwagger( String version) {
254                 if (new Integer(version.substring(1)).intValue() >= swaggerSupportStartsVersion ) {
255                         return true;
256                 }
257                 return false;
258         }
259         
260         public static void main(String[] args) throws IOException {
261                 String versionToGen = System.getProperty("gen_version").toLowerCase();
262                 String fileTypeToGen = System.getProperty("gen_type").toLowerCase();
263                 if ( fileTypeToGen == null ) {
264                         fileTypeToGen = generateTypeXSD;
265                 }
266                 
267                 if ( !fileTypeToGen.equals( generateTypeXSD ) && !fileTypeToGen.equals( generateTypeYAML )) {
268                         System.err.println("Invalid gen_type passed. " + fileTypeToGen);
269                         System.exit(1);
270                 }
271                 
272                 
273                 if ( versionToGen == null ) {
274                         System.err.println("Version is required, ie v<n> or ALL.");
275                         System.exit(1);                 
276                 }
277                 
278                 responsesUrl = System.getProperty("yamlresponses_url");
279                 String responsesLabel = System.getProperty("yamlresponses_label");
280                 List<Version> versionsToGen = new ArrayList<>();
281
282                 
283                 if (!"ALL".equalsIgnoreCase(versionToGen) && !versionToGen.matches("v\\d+") && !validVersion(versionToGen)) {
284                         System.err.println("Invalid version passed. " + versionToGen);
285                         System.exit(1);
286                 }
287                 
288                 if ("ALL".equalsIgnoreCase(versionToGen)) {
289                         versionsToGen = Arrays.asList(Version.values());
290                         Collections.sort(versionsToGen);
291                         Collections.reverse(versionsToGen);
292                 } else {
293                         versionsToGen.add(Version.valueOf(versionToGen));
294                 }
295
296                 if ( fileTypeToGen.equals(generateTypeYAML) ) {
297                         if ( responsesUrl == null || responsesUrl.length() < 1 
298                                         || responsesLabel == null || responsesLabel.length() < 1 ) {
299                                 System.err.println("generating swagger yaml file requires yamlresponses_url and yamlresponses_label properties" );
300                                 System.exit(1);
301                         }
302                         responsesUrl = "description: "+ responsesLabel+ "(" + responsesUrl + ").\n";
303                 }
304                 String oxmPath = root + "/oxm/";
305         
306                 String outfileName;
307                 File outfile;
308                 String fileContent;
309                 
310                 for (Version v : versionsToGen) {
311                         apiVersion = v.toString();
312                         System.out.println("Generating " + apiVersion + " " + fileTypeToGen);
313                         File oxm_file = new File(oxmPath + "aai_oxm_" + apiVersion + ".xml");
314                         apiVersionFmt = "." + apiVersion + ".";
315                         generatedJavaType = new HashMap<String, String>();
316                         appliedPaths = new HashMap<String, String>();
317                         if ( fileTypeToGen.equals(generateTypeXSD) ) {
318                                 useAnnotationsInXsd = versionUsesAnnotations(apiVersion);
319                                 outfileName = xsd_dir + "/aai_schema_" + apiVersion + "." + generateTypeXSD;
320                                 fileContent = processOxmFile( oxm_file);
321                         } else if ( versionSupportsSwagger(apiVersion )) {
322                                 outfileName = yaml_dir + "/aai_swagger_" + apiVersion + "." + generateTypeYAML;
323                                 fileContent = generateSwaggerFromOxmFile( oxm_file);
324                         } else {
325                                 continue;
326                         }
327                         outfile = new File(outfileName);
328                         File parentDir = outfile.getParentFile();
329                         if(! parentDir.exists()) 
330                               parentDir.mkdirs();
331                 
332                     try {
333                         outfile.createNewFile();
334                     } catch (IOException e) {
335                         System.out.println( "Exception creating output file " + outfileName);
336                         e.printStackTrace();
337                     }
338                 try {
339                         FileWriter fw = new FileWriter(outfile.getAbsoluteFile());
340                         BufferedWriter bw = new BufferedWriter(fw);
341                         bw.write(fileContent);
342                         bw.close();
343
344                 } catch ( IOException e) {
345                         System.out.println( "Exception writing output file " + outfileName);
346                         e.printStackTrace();
347                 }
348                         System.out.println( "GeneratedXSD successful, saved in " + outfileName);
349                 }
350                 
351         }
352
353
354         public static String processJavaTypeElement( String javaTypeName, Element javaTypeElement) {
355                 
356                 String xmlRootElementName = null;
357
358                 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
359                 StringBuffer sb = new StringBuffer();
360                 if ( parentNodes.getLength() == 0 ) {
361                         //System.out.println( "no java-attributes for java-type " + javaTypeName);
362                         return "";
363
364                 }
365                 
366                 NamedNodeMap attributes;
367                 
368                 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
369                 Element valElement = (Element) valNodes.item(0);
370                 attributes = valElement.getAttributes();
371                 for ( int i = 0; i < attributes.getLength(); ++i ) {
372             Attr attr = (Attr) attributes.item(i);
373             String attrName = attr.getNodeName();
374
375             String attrValue = attr.getNodeValue();
376             //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
377             if ( attrName.equals("name"))
378                 xmlRootElementName = attrValue;
379                 }
380                 /*
381                 if ( javaTypeName.equals("RelationshipList")) {
382                         System.out.println( "Skipping " + javaTypeName);
383                         generatedJavaType.put(javaTypeName, null);
384                         return "";
385                 }
386                 */
387                 
388                 Element parentElement = (Element)parentNodes.item(0);
389                 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
390                 NodeList childNodes;
391                 Element childElement;
392                 String xmlElementWrapper;
393
394                 Element xmlElementElement;
395                 String addType;
396                 String elementName, elementType, elementIsKey, elementIsRequired, elementContainerType;
397                 StringBuffer sb1 = new StringBuffer();
398                 if ( xmlElementNodes.getLength() > 0 ) {
399                         sb1.append("  <xs:element name=\"" + xmlRootElementName + "\">\n");
400                         sb1.append("    <xs:complexType>\n");
401                         NodeList properties = GenerateXsd.locateXmlProperties(javaTypeElement);
402                         if (properties != null && useAnnotationsInXsd) {
403                                 //System.out.println("properties found for: " + xmlRootElementName);
404                                 sb1.append("      <xs:annotation>\r\n");
405                                 insertAnnotation(properties, false, "class", sb1, "      ");
406                                 
407                                 sb1.append("      </xs:annotation>\r\n");
408                         } /*else {
409                                 System.out.println("no properties found for: " + xmlRootElementName);
410                         }*/
411                         sb1.append("      <xs:sequence>\n");
412                         for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
413                                 
414                                 xmlElementElement = (Element)xmlElementNodes.item(i);
415                                 childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
416                                 
417                                 xmlElementWrapper = null;
418                                 if ( childNodes.getLength() > 0 ) {
419                                         childElement = (Element)childNodes.item(0);
420                                         // get name
421                                         attributes = childElement.getAttributes();
422                                         for ( int k = 0; k < attributes.getLength(); ++k ) {
423                                                 Attr attr = (Attr) attributes.item(k);
424                                                 String attrName = attr.getNodeName();
425                                                 String attrValue = attr.getNodeValue();
426                                                 if ( attrName.equals("name")) {
427                                                         xmlElementWrapper = attrValue;
428                                                         //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
429                                                 }
430                                         }
431
432                                 }
433                                 attributes = xmlElementElement.getAttributes();
434                                 addType = null;
435         
436          
437                                 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
438                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
439                             Attr attr = (Attr) attributes.item(j);
440                             String attrName = attr.getNodeName();
441         
442                             String attrValue = attr.getNodeValue();
443                             //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
444                             if ( attrName.equals("name")) {
445                                 elementName = attrValue;
446                             }
447                             if ( attrName.equals("type")) {
448                                 elementType = attrValue;
449                                 if ( attrValue.contains(apiVersionFmt) ) {
450                                         addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
451                                         if ( !generatedJavaType.containsKey(addType) ) {
452                                                 generatedJavaType.put(addType, attrValue);
453                                                 sb.append(processJavaTypeElement( addType, getJavaTypeElement(addType) ));      
454                                         }
455                                 }
456                                         
457                             }
458
459                             if ( attrName.equals("xml-key")) {
460                                 elementIsKey = attrValue;
461                             }
462                             if ( attrName.equals("required")) {
463                                 elementIsRequired = attrValue;
464                             }
465                             if ( attrName.equals("container-type")) {
466                                 elementContainerType = attrValue;
467                             }   
468                                 }
469         
470                                 if ( xmlElementWrapper != null ) {
471                                         sb1.append("        <xs:element name=\"" + xmlElementWrapper +"\"");
472                                         if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) { 
473                                                 sb1.append(" minOccurs=\"0\""); 
474                                         } 
475                                         sb1.append(">\n");
476                                         sb1.append("          <xs:complexType>\n");
477                                         properties = GenerateXsd.locateXmlProperties(javaTypeElement);
478                                         if (properties != null && useAnnotationsInXsd) {
479                                                 sb1.append("            <xs:annotation>\r\n");
480                                                 insertAnnotation(properties, false, "class", sb1, "            ");
481                                                 sb1.append("            </xs:annotation>\r\n");
482                                         } /*else {
483                                                 System.out.println("no properties found for: " + xmlElementWrapper);
484                                         }*/
485                                         sb1.append("            <xs:sequence>\n");
486                                         sb1.append("      ");
487                                 }
488                 if ("Nodes".equals(addType)) {
489                         //System.out.println ("Skipping nodes, temporary testing");
490                         continue;
491                 }
492                                 if ( addType != null ) {
493                                         //sb1.append("        <xs:element ref=\"tns:" + elementName +"\"");
494                                         sb1.append("        <xs:element ref=\"tns:" + getXmlRootElementName(addType) +"\"");
495                                 } else {
496                                         sb1.append("        <xs:element name=\"" + elementName +"\"");
497                                 }
498                                 if ( elementType.equals("java.lang.String"))
499                                         sb1.append(" type=\"xs:string\"");
500                                 //if ( elementType.equals("java.lang.String"))
501                                         //sb1.append(" type=\"xs:string\"");
502                                 if ( elementType.equals("java.lang.Long"))
503                                         sb1.append(" type=\"xs:unsignedInt\"");
504                                 if ( elementType.equals("java.lang.Integer"))
505                                         sb1.append(" type=\"xs:int\"");
506                                 if ( elementType.equals("java.lang.Boolean"))
507                                         sb1.append(" type=\"xs:boolean\"");
508                                 //if ( elementIsRequired != null && elementIsRequired.equals("true")||addType != null) {
509                                 if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) { 
510                                         sb1.append(" minOccurs=\"0\"");
511                                 } 
512                                 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
513                                         sb1.append(" maxOccurs=\"unbounded\"");
514                                 }
515                                 properties = GenerateXsd.locateXmlProperties(xmlElementElement);
516                                 if (properties != null || elementIsKey != null) {
517                                         sb1.append(">\n");
518                                         if ( useAnnotationsInXsd ) {
519                                                 sb1.append("          <xs:annotation>\r\n");
520                                                 insertAnnotation(properties, elementIsKey != null, "field", sb1, "          ");
521                                                 sb1.append("          </xs:annotation>\r\n");
522                                         }
523                                         if (xmlElementWrapper== null) {
524                                                 sb1.append("        </xs:element>\n");
525                                         }
526                                 } else {
527                                         sb1.append("/>\n");
528                                 }
529                                 if ( xmlElementWrapper != null ) {
530                                         sb1.append("            </xs:sequence>\n");
531                                         sb1.append("          </xs:complexType>\n");
532                                         sb1.append("        </xs:element>\n");
533                                 }
534                         }
535                         /*
536                 if (  xmlRootElementName.equals("notify") ||
537                         xmlRootElementName.equals("relationship") ||
538                         xmlRootElementName.equals("relationship-data") ||
539                         xmlRootElementName.equals("related-to-property") )
540                         
541                         sb1.append("        <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n");
542                 */      
543                 sb1.append("      </xs:sequence>\n");
544                 sb1.append("    </xs:complexType>\n");
545                 sb1.append("  </xs:element>\n");
546                 }
547                 /*
548                 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
549                 Element valElement = (Element) valNodes.item(0);
550                 attributes = valElement.getAttributes();
551                 for ( int i = 0; i < attributes.getLength(); ++i ) {
552             Attr attr = (Attr) attributes.item(i);
553             String attrName = attr.getNodeName();
554
555             String attrValue = attr.getNodeValue();
556             System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
557             if ( attrValue.equals("name"))
558                 xmlRootElementName = attrValue;
559                 }
560                 */
561                 
562                 if ( xmlElementNodes.getLength() < 1 ) {
563                         sb.append("  <xs:element name=\"" + xmlRootElementName + "\">\n");
564                         sb.append("    <xs:complexType>\n");
565                         sb.append("      <xs:sequence/>\n");
566                         sb.append("    </xs:complexType>\n");
567                         sb.append("  </xs:element>\n");
568                         generatedJavaType.put(javaTypeName, null);
569                         return sb.toString();                   
570                 }
571                 
572                 sb.append( sb1 );
573
574                 return sb.toString();
575         }
576         
577         private static void insertAnnotation(NodeList items, boolean isKey, String target, StringBuffer sb1, String indentation) {
578                 if (items != null || isKey) {
579                         List<String> metadata = new ArrayList<>();
580                         
581                         String name = "";
582                         String value = "";
583                         Element item = null;
584                         if (isKey) {
585                                 metadata.add("isKey=true");
586                         }
587                         if (items != null) {
588                                 for (int i = 0; i < items.getLength(); i++) {
589                                         item = (Element)items.item(i);
590                                         name = item.getAttribute("name");
591                                         value = item.getAttribute("value");
592                                         if (name.equals("abstract")) {
593                                                 name = "isAbstract";
594                                         } else if (name.equals("extends")) {
595                                                 name = "extendsFrom";
596                                         }
597                                         metadata.add(name + "=\"" + value.replaceAll("&",  "&amp;") + "\"");
598                                         //System.out.println("property name: " + name);
599         
600                                 }
601                         }
602                         sb1.append(
603                                         indentation + "  <xs:appinfo>\r\n" + 
604                                                         indentation + "    <annox:annotate target=\""+target+"\">@org.openecomp.aai.annotations.Metadata(" + Joiner.on(",").join(metadata) + ")</annox:annotate>\r\n" + 
605                                                         indentation + "  </xs:appinfo>\r\n");
606                 }
607
608         }
609
610         private static Element getJavaTypeElement( String javaTypeName )
611         {
612                 
613                 String attrName, attrValue;
614                 Attr attr;
615                 Element javaTypeElement;
616                 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
617                         javaTypeElement = (Element) javaTypeNodes.item(i);
618                         NamedNodeMap attributes = javaTypeElement.getAttributes();
619                         for ( int j = 0; j < attributes.getLength(); ++j ) {
620                     attr = (Attr) attributes.item(j);
621                     attrName = attr.getNodeName();
622                     attrValue = attr.getNodeValue();
623                     if ( attrName.equals("name") && attrValue.equals(javaTypeName))
624                         return javaTypeElement;
625                         }
626                 }
627                 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
628                 return (Element) null;
629         }
630         
631         private static Element getJavaTypeElementSwagger( String javaTypeName )
632         {
633                 
634                 String attrName, attrValue;
635                 Attr attr;
636                 Element javaTypeElement;
637                 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
638                         javaTypeElement = (Element) javaTypeNodes.item(i);
639                         NamedNodeMap attributes = javaTypeElement.getAttributes();
640                         for ( int j = 0; j < attributes.getLength(); ++j ) {
641                     attr = (Attr) attributes.item(j);
642                     attrName = attr.getNodeName();
643                     attrValue = attr.getNodeValue();
644                     if ( attrName.equals("name") && attrValue.equals(javaTypeName))
645                         return javaTypeElement;
646                         }
647                 }
648                 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
649                 return (Element) null;
650         }
651         private static String getXmlRootElementName( String javaTypeName )
652         {
653                 
654                 String attrName, attrValue;
655                 Attr attr;
656                 Element javaTypeElement;
657                 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
658                         javaTypeElement = (Element) javaTypeNodes.item(i);
659                         NamedNodeMap attributes = javaTypeElement.getAttributes();
660                         for ( int j = 0; j < attributes.getLength(); ++j ) {
661                     attr = (Attr) attributes.item(j);
662                     attrName = attr.getNodeName();
663                     attrValue = attr.getNodeValue();
664                     if ( attrName.equals("name") && attrValue.equals(javaTypeName)) {
665                                 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
666                                 Element valElement = (Element) valNodes.item(0);
667                                 attributes = valElement.getAttributes();
668                                 for ( int k = 0; k < attributes.getLength(); ++k ) {
669                             attr = (Attr) attributes.item(k);
670                             attrName = attr.getNodeName();
671
672                             attrValue = attr.getNodeValue();
673                             //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
674                             if ( attrName.equals("name"))
675                                 return (attrValue);
676                                 }
677                     }
678                         }
679                 }
680                 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
681                 return null;
682         }       
683         
684         
685         public static String processOxmFile( File oxmFile )
686         {
687                 StringBuffer sb = new StringBuffer();
688                 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
689                 String namespace = "org.openecomp";
690                 if ( useAnnotationsInXsd ) {
691                         sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/" 
692                                 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
693                                                 + "\n"
694                                                 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" + 
695                                                 "    jaxb:version=\"2.1\" \r\n" + 
696                                                 "    xmlns:annox=\"http://annox.dev.java.net\" \r\n" + 
697                                                 "    jaxb:extensionBindingPrefixes=\"annox\">\n\n");
698                 } else {
699                         sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/" 
700                                         + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n");
701                 }
702
703                 try {
704                     
705                     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
706                     dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
707                     DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
708                     Document doc = dBuilder.parse(oxmFile);
709
710                     NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
711                         Element bindingElement;
712                         NodeList javaTypesNodes;
713                         Element javaTypesElement;
714                         
715                         Element javaTypeElement;
716
717                         
718                         if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
719                                 System.out.println( "missing <binding-nodes> in " + oxmFile );
720                                 return null;
721                         }           
722                         
723                         bindingElement = (Element) bindingsNodes.item(0);
724                         javaTypesNodes = bindingElement.getElementsByTagName("java-types");
725                         if ( javaTypesNodes.getLength() < 1 ) {
726                                 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
727                                 return null;
728                         }
729                         javaTypesElement = (Element) javaTypesNodes.item(0);
730                         javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
731                         if ( javaTypeNodes.getLength() < 1 ) {
732                                 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
733                                 return null;
734                         }
735
736                         String javaTypeName;
737                         String attrName, attrValue;
738                         Attr attr;
739                         for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
740                                 javaTypeElement = (Element) javaTypeNodes.item(i);
741                                 NamedNodeMap attributes = javaTypeElement.getAttributes();
742                                 javaTypeName = null;
743                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
744                             attr = (Attr) attributes.item(j);
745                             attrName = attr.getNodeName();
746                             attrValue = attr.getNodeValue();
747                             if ( attrName.equals("name"))
748                                 javaTypeName = attrValue;
749                                 }
750                                 if ( javaTypeName == null ) {
751                                         System.out.println( "<java-type> has no name attribute in " + oxmFile );
752                                         return null;
753                                 }
754                                 if ("Nodes".equals(javaTypeName)) {
755                                         //System.out.println("skipping Nodes entry (temporary feature)");
756                                         continue;
757                                 }
758                                 if ( !generatedJavaType.containsKey(javaTypeName) ) {
759                                         generatedJavaType.put(javaTypeName, null);
760                                         sb.append(processJavaTypeElement( javaTypeName, javaTypeElement ));
761                                 }
762                         }
763                                 
764                 } catch (Exception e) {
765                         e.printStackTrace();
766                         return null;
767                 }
768                 sb.append("</xs:schema>\n");
769                 return sb.toString();
770         }
771
772         private static boolean isStandardType( String elementType )
773         {
774                 switch ( elementType ) {
775                 case "java.lang.String":
776                 case "java.lang.Long":
777                 case "java.lang.Integer":
778                 case"java.lang.Boolean":
779                         return true;
780                 }
781                 return false;
782         }
783         
784         private static Vector<String> getIndexedProps( String attrValue )
785         {
786                 if ( attrValue == null )
787                         return null;
788                 StringTokenizer st = new StringTokenizer( attrValue, ",");
789                 if ( st.countTokens() ==  0 )
790                         return null;
791                 Vector<String> result = new Vector<String>();
792                 while ( st.hasMoreTokens()) {
793                         result.add(st.nextToken());
794                 }
795                 return result;
796         }
797         
798         private static Class<?> getEdgeRulesClass() throws ClassNotFoundException {
799                 Class<?> result = null;
800                 
801                 // If a class matching the apiVersion exists, we are generating documentation for a prior release
802                 // Otherwise, we're generated documentation for the current release.
803                 try {
804                         result = Class.forName("org.openecomp.aai.dbmodel." + apiVersion +".gen.DbEdgeRules");
805                 } catch (ClassNotFoundException  ex) {
806                         result = Class.forName("org.openecomp.aai.dbmodel.DbEdgeRules");
807                 }
808                 return result;
809         }
810         
811         /**
812          * Guaranteed to at least return non null but empty collection of edge descriptions
813          * @param nodeName name of the vertex whose edge relationships to return
814          * @return collection of node neighbors based on DbEdgeRules
815          */
816         private static Collection<EdgeDescription> getEdgeRules( String nodeName ) 
817         {
818
819                 ArrayList<EdgeDescription> result = new ArrayList<>();
820                 Iterator<String> edgeRulesIterator;
821
822                 try {
823
824                         Field mapfield = versionedClass.getField("EdgeRules");
825                         Object map = mapfield.get(null);
826                         if (map instanceof Multimap<?,?>) {
827                                 edgeRulesIterator = ((Multimap<String,String>) map).keySet().iterator();
828                         } else {
829                                 throw new NoSuchFieldException ("Didn't get back the multimap field expected");
830                         }
831                         GenerateXsd x = new GenerateXsd();
832
833                         while( edgeRulesIterator.hasNext() ){
834                                 String ruleKey = edgeRulesIterator.next();
835                                 if ( ruleKey.startsWith(nodeName + "|" ) ||
836                                                 ruleKey.endsWith("|" + nodeName)) {
837                                         Collection <String> edRuleColl = DbEdgeRules.EdgeRules.get(ruleKey);
838                                         Iterator <String> ruleItr = edRuleColl.iterator();
839                                         while( ruleItr.hasNext() ){             
840                                                 EdgeDescription edgeDes = x.new EdgeDescription();
841                                                 edgeDes.setRuleKey(ruleKey);
842                                                 String fullRuleString = ruleItr.next();
843                                                 String[] toks = fullRuleString.split(",");
844                                                 if (toks != null) {
845                                                         if (toks.length > 1) {
846                                                                 edgeDes.setDirection(toks[1]);
847                                                         }
848                                                         if (toks.length > 2) {
849                                                                 edgeDes.setMultiplicity(toks[2]);
850                                                         }
851                                                         if (toks.length > 3) {
852                                                                 if (toks[3].equals("true")) 
853                                                                         edgeDes.setType(LineageType.PARENT);
854                                                                 else if (toks[3].equals("parent")) 
855                                                                         edgeDes.setType(LineageType.PARENT);
856                                                                 else if (toks[3].equals("child")) 
857                                                                         edgeDes.setType(LineageType.CHILD);
858                                                                 else 
859                                                                         edgeDes.setType(LineageType.UNRELATED);
860                                                         }
861                                                         if (toks.length > 5) {
862                                                                 edgeDes.setHasDelTarget(toks[5]);;
863                                                         }
864                                                 }
865
866                                                 //System.out.println( "nodeName " + nodeName + " ruleKey "  + ruleKey + " ruleString " + fullRuleString);
867                                                 //result.add(ruleKey + "-" + fullRuleString);
868                                                 result.add(edgeDes);
869                                         }
870                                 }
871                         }
872                 } catch (Exception ex) {
873                         ex.printStackTrace();
874                 }
875                 return result;
876         }
877         
878         /**
879          * Finds the default delete scope from DBEdgeRules
880          * @param nodeName name of vertex whose delete scope to return
881          * @return default delete scope of the input nodeName, null if none.
882          */
883         private static String getDeleteRules( String nodeName )
884         {
885                 String result = null;
886                 Iterator<String> delRulesIterator;
887
888                 try {
889
890                         Field mapfield = versionedClass.getField("DefaultDeleteScope");
891                         Object map = mapfield.get(null);
892                         if (map instanceof Multimap<?,?>) {
893                                 delRulesIterator = ((Multimap<String,String>) map).keySet().iterator();
894                         } else {
895                                 throw new NoSuchFieldException ("Didn't get back the multimap field expected");
896                         }
897
898                         while( delRulesIterator.hasNext() ){
899                                 String ruleKey = delRulesIterator.next();
900                                 if ( ruleKey.equals(nodeName)) {
901                                         Collection <String> deRuleColl = DbEdgeRules.DefaultDeleteScope.get(ruleKey);
902                                         Iterator <String> ruleItr = deRuleColl.iterator();
903                                         if( ruleItr.hasNext() ){                
904                                                 result = ruleItr.next();
905                                         }
906                                 }
907                         }
908
909                 } catch (Exception ex) {
910                         ex.printStackTrace();
911                 }
912                 return result;
913         }
914         
915         public static String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement, 
916                         StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
917                         String getItemName, StringBuffer pathParams, String queryParams, String validEdges) {
918                 
919                 String xmlRootElementName = null;
920
921                 //Map<String, String> addJavaType = new HashMap<String, String>();
922                 String useTag = null;
923                 String useOpId = null;
924                 
925                 if ( tag != null ) {
926                         switch ( tag ) {
927                         case "Network":
928                         case "ServiceDesignAndCreation":
929                         case "Business":
930                         case "LicenseManagement":
931                         case "CloudInfrastructure":
932                                 break;
933                         default:
934                                 return null;
935                         }
936                 }
937                 /*
938                 if ( path == null )
939                         System.out.println( "processJavaTypeElementSwagger called with null path for javaTypeName " + javaTypeName);
940                 */
941                 /*
942                 if ( path == null || !(path.contains("cloud-infrastructure")))
943                         switch ( javaTypeName) {
944                          case "Inventory":
945                                 useTag = null;
946                                 break;
947                                 
948                         case "CloudInfrastructure":
949                         case "Search":
950                         case "Actions":
951                         case "ServiceDesignAndCreation":
952                         case "LicenseManagement":
953                         case "Network":
954                                 if ( tag == null )
955                                         useTag = javaTypeName;
956
957                                 break;
958                         default:
959                                         return null;
960                                         
961                         }
962                 */
963                 
964                 if ( !javaTypeName.equals("Inventory") ) {
965                         if ( javaTypeName.equals("AaiInternal"))
966                                 return null;
967                         if ( opId == null )
968                                 useOpId = javaTypeName;
969                         else
970                                 useOpId = opId + javaTypeName;
971                         if ( tag == null )
972                                 useTag = javaTypeName;
973                 }
974                 
975                 /*
976                 if ( javaTypeName.equals("GenericVnf"))
977                         System.out.println( "Processing " + javaTypeName);
978                 else if ( javaTypeName.equals("Service"))
979                                 System.out.println( "Processing " + javaTypeName);
980                 else if ( javaTypeName.equals("SitePair"))
981                         System.out.println( "Processing " + javaTypeName);
982                 */
983                 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
984
985                 if ( parentNodes.getLength() == 0 ) {
986                         //System.out.println( "no java-attributes for java-type " + javaTypeName);
987                         return "";
988
989                 }
990                 
991                 NamedNodeMap attributes;
992                 
993                 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
994                 Element valElement = (Element) valNodes.item(0);
995                 attributes = valElement.getAttributes();
996                 for ( int i = 0; i < attributes.getLength(); ++i ) {
997             Attr attr = (Attr) attributes.item(i);
998             String attrName = attr.getNodeName();
999
1000             String attrValue = attr.getNodeValue();
1001             //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
1002             if ( attrName.equals("name"))
1003                 xmlRootElementName = attrValue;
1004                 }
1005                 /*
1006                 if ( xmlRootElementName.equals("oam-networks"))
1007                         System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
1008                 */
1009                 //already processed
1010                 /*
1011                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1012                         return null;
1013                 }
1014                 */
1015                 NodeList childNodes;
1016                 Element childElement;
1017                 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
1018                 Element xmlPropElement;
1019                 String pathDescriptionProperty = null;
1020                 
1021                 
1022                 Vector<String> indexedProps = null;
1023                 
1024                 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
1025                 if ( path != null && path.equals("/network/generic-vnfs"))
1026                         System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
1027                 */
1028                 if ( xmlPropNodes.getLength() > 0 ) {
1029
1030                         for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
1031                                 xmlPropElement = (Element)xmlPropNodes.item(i);
1032                                 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
1033                                         continue;
1034                                 childNodes = xmlPropElement.getElementsByTagName("xml-property");
1035                                 
1036                                 if ( childNodes.getLength() > 0 ) {
1037                                         for ( int j = 0; j < childNodes.getLength(); ++j ) {
1038                                                 childElement = (Element)childNodes.item(j);
1039                                                 // get name
1040                                                 int useValue = VALUE_NONE;
1041                                                 attributes = childElement.getAttributes();
1042                                                 for ( int k = 0; k < attributes.getLength(); ++k ) {
1043                                                         Attr attr = (Attr) attributes.item(k);
1044                                                         String attrName = attr.getNodeName();
1045                                                         String attrValue = attr.getNodeValue();
1046                                                         if ( attrName == null || attrValue == null )
1047                                                                 continue;
1048                                                         if ( attrName.equals("name") && attrValue.equals("description")) {
1049                                                                 useValue = VALUE_DESCRIPTION;
1050                                                         }
1051                                                         if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
1052                                                                 pathDescriptionProperty = attrValue;
1053                                                                 //break;
1054                                                                 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1055                                                         }
1056                                                         if ( attrValue.equals("indexedProps")) {
1057                                                                 useValue = VALUE_INDEXED_PROPS;
1058                                                         }
1059                                                         if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
1060                                                                 indexedProps = getIndexedProps( attrValue );
1061                                                         }
1062                                                 }
1063                                         }
1064                                 }
1065                         }
1066                 }
1067                 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
1068
1069                 /*
1070                 if ( javaTypeName.equals("RelationshipList")) {
1071                         System.out.println( "Skipping " + javaTypeName);
1072                         generatedJavaType.put(javaTypeName, null);
1073                         return "";
1074                 }
1075                 */
1076                 
1077                 Element parentElement = (Element)parentNodes.item(0);
1078                 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
1079
1080         
1081                 String attrDescription = null;
1082
1083                 Element xmlElementElement;
1084                 String addType = null;
1085                 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1086                 String elementName = null;
1087                 StringBuffer sbParameters = new StringBuffer();
1088
1089                 StringBuffer sbRequired = new StringBuffer();
1090                 int requiredCnt = 0;
1091                 int propertyCnt = 0;
1092                 StringBuffer sbProperties = new StringBuffer();
1093                 StringBuffer sbIndexedParams = new StringBuffer();
1094
1095                 
1096                 StringTokenizer st;
1097                 if ( xmlRootElementName.equals("inventory"))
1098                         path = "";
1099                 else if ( path == null )
1100                         //path = "/aai/" + apiVersion;
1101                         path = "/" + xmlRootElementName;
1102                 else
1103                         path += "/" + xmlRootElementName;
1104                 st = new StringTokenizer(path, "/");
1105                 /*
1106                 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1107                         System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1108                 */
1109                 boolean genPath = false;
1110                 /*
1111                 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1112                         System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1113                 */
1114                 if ( st.countTokens() > 1 && getItemName == null ) {
1115                         if ( appliedPaths.containsKey(path)) 
1116                                 return null;
1117                         appliedPaths.put(path, null);
1118                         genPath = true;
1119                         if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1120                                 genPath = false;
1121                         }
1122                         if ( path.endsWith("/relationship-list")) {
1123                                 genPath = false;
1124                         }
1125                                         
1126                 }
1127                 
1128                 Vector<String> addTypeV = null;
1129                 if (  xmlElementNodes.getLength() > 0 ) {
1130                         
1131                         for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1132                                 xmlElementElement = (Element)xmlElementNodes.item(i);
1133                                 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1134                                         continue;
1135                                 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1136                                 if ( childNodes.getLength() > 0 ) {
1137                                         childElement = (Element)childNodes.item(0);
1138                                         // get name
1139                                         attributes = childElement.getAttributes();
1140                                         for ( int k = 0; k < attributes.getLength(); ++k ) {
1141                                                 Attr attr = (Attr) attributes.item(k);
1142                                                 String attrName = attr.getNodeName();
1143                                                 String attrValue = attr.getNodeValue();
1144                                                 if ( attrName.equals("name")) {
1145                                                         xmlElementWrapper = attrValue;
1146                                                         //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1147                                                 }
1148                                         }
1149
1150                                 }
1151                                 */
1152                                 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1153                                 attrDescription = null;
1154                                 if ( valNodes.getLength() > 0 ) {
1155                                         for ( int j = 0; j < valNodes.getLength(); ++j ) {
1156                                                 valElement = (Element)valNodes.item(j);
1157                                                 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1158                                                         continue;
1159                                                 childNodes = valElement.getElementsByTagName("xml-property");
1160                                                 if ( childNodes.getLength() > 0 ) {
1161                                                         childElement = (Element)childNodes.item(0);
1162                                                         // get name
1163                                                         attributes = childElement.getAttributes();
1164                                                         attrDescription = null;
1165                                                         boolean useValue = false;
1166                                                         for ( int k = 0; k < attributes.getLength(); ++k ) {
1167                                                                 Attr attr = (Attr) attributes.item(k);
1168                                                                 String attrName = attr.getNodeName();
1169                                                                 String attrValue = attr.getNodeValue();
1170                                                                 if ( attrName.equals("name") && attrValue.equals("description")) {
1171                                                                         useValue = true;
1172                                                                 }
1173                                                                 if ( useValue && attrName.equals("value")) {
1174                                                                         attrDescription = attrValue;
1175                                                                         //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1176                                                                 }
1177                                                         }
1178
1179                                                 }
1180                                         }
1181                                 }
1182                                 
1183                                 attributes = xmlElementElement.getAttributes();
1184                                 addTypeV = null; // vector of 1
1185                                 addType = null;
1186                                 
1187                                 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1188                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
1189                             Attr attr = (Attr) attributes.item(j);
1190                             String attrName = attr.getNodeName();
1191         
1192                             String attrValue = attr.getNodeValue();
1193                             //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1194                             if ( attrName.equals("name")) {
1195                                 elementName = attrValue;
1196
1197                             }
1198                             if ( attrName.equals("type") && getItemName == null ) {
1199                                 elementType = attrValue;
1200                                 if ( attrValue.contains(apiVersionFmt) ) {
1201                                         addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1202                                         if ( addTypeV == null ) 
1203                                                 addTypeV = new Vector<String>();
1204                                         addTypeV.add(addType);
1205                                 }
1206                                         
1207                             }
1208                             if ( attrName.equals("xml-key")) {
1209                                 elementIsKey = attrValue;
1210                                 path += "/{" + elementName + "}";
1211                             }
1212                             if ( attrName.equals("required")) {
1213                                 elementIsRequired = attrValue;
1214                             }
1215                             if ( attrName.equals("container-type")) {
1216                                 elementContainerType = attrValue;
1217                             }   
1218                                 }
1219                 if ( getItemName != null ) {
1220                         if ( getItemName.equals("array") ) {
1221                                 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1222                                         //System.out.println( " returning array " + elementName );
1223                                         return elementName;
1224                                 }
1225                                 
1226                         } else { // not an array check
1227                                 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1228                                         //System.out.println( " returning object " + elementName );
1229                                         return elementName;
1230                                 }
1231                                 
1232                         }
1233                         //System.out.println( " returning null" );
1234                         return null;
1235                 }
1236                                 if ( elementIsRequired != null ) {
1237                                         if ( requiredCnt == 0 )
1238                                                 sbRequired.append("    required:\n");
1239                                         ++requiredCnt;
1240                                         if ( addTypeV != null ) {
1241                                                 for ( int k = 0; k < addTypeV.size(); ++i ) {
1242                                                         sbRequired.append("    - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1243                                                 }
1244                                         } else 
1245                                                 sbRequired.append("    - " + elementName + "\n");
1246
1247                                 }
1248
1249                                 if (  elementIsKey != null )  {
1250                                                                                 sbParameters.append(("        - name: " + elementName + "\n"));
1251                                         sbParameters.append(("          in: path\n"));
1252                                         if ( attrDescription != null && attrDescription.length() > 0 )
1253                                                 sbParameters.append(("          description: " + attrDescription + "\n"));
1254                                         sbParameters.append(("          required: true\n"));
1255                                         if ( elementType.equals("java.lang.String"))
1256                                                 sbParameters.append("          type: string\n");
1257                                         if ( elementType.equals("java.lang.Long")) {
1258                                                 sbParameters.append("          type: integer\n");
1259                                                 sbParameters.append("          format: int64\n");
1260                                         }
1261                                         if ( elementType.equals("java.lang.Integer")) {
1262                                                 sbParameters.append("          type: integer\n");
1263                                                 sbParameters.append("          format: int32\n");
1264                                         }
1265                                         if ( elementType.equals("java.lang.Boolean"))
1266                                                 sbParameters.append("          type: boolean\n");
1267
1268
1269                                 } else if (  indexedProps != null
1270                                                 && indexedProps.contains(elementName ) ) {
1271                                         sbIndexedParams.append(("        - name: " + elementName + "\n"));
1272                                         sbIndexedParams.append(("          in: query\n"));
1273                                         if ( attrDescription != null && attrDescription.length() > 0 )
1274                                                 sbIndexedParams.append(("          description: " + attrDescription + "\n"));
1275                                         sbIndexedParams.append(("          required: false\n"));
1276                                         if ( elementType.equals("java.lang.String"))
1277                                                 sbIndexedParams.append("          type: string\n");
1278                                         if ( elementType.equals("java.lang.Long")) {
1279                                                 sbIndexedParams.append("          type: integer\n");
1280                                                 sbIndexedParams.append("          format: int64\n");
1281                                         }
1282                                         if ( elementType.equals("java.lang.Integer")) {
1283                                                 sbIndexedParams.append("          type: integer\n");
1284                                                 sbIndexedParams.append("          format: int32\n");
1285                                         }
1286                                         if ( elementType.equals("java.lang.Boolean"))
1287                                                 sbIndexedParams.append("          type: boolean\n");
1288                                 }
1289
1290                         /*
1291                         if ( elementName != null && elementName.equals("inventory-item"))
1292                                 System.out.println( "processing inventory-item elementName");
1293                         */
1294                 
1295                         if ( isStandardType(elementType)) {
1296                                 sbProperties.append("      " + elementName + ":\n");
1297                                 ++propertyCnt;
1298                                 sbProperties.append("        type: ");
1299
1300                                 if ( elementType.equals("java.lang.String"))
1301                                         sbProperties.append("string\n");
1302                                 else if ( elementType.equals("java.lang.Long")) {
1303                                         sbProperties.append("integer\n");
1304                                         sbProperties.append("        format: int64\n");
1305                                 }
1306                                 else if ( elementType.equals("java.lang.Integer")){
1307                                         sbProperties.append("integer\n");
1308                                         sbProperties.append("        format: int32\n");
1309                                 }
1310                                 else if ( elementType.equals("java.lang.Boolean"))
1311                                         sbProperties.append("boolean\n");
1312                                 if ( attrDescription != null && attrDescription.length() > 0 )
1313                                         sbProperties.append("        description: " + attrDescription + "\n");
1314                         }
1315
1316                         //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1317
1318                 if ( addTypeV !=  null ) {
1319                         StringBuffer newPathParams = null;
1320                         if ( pathParams != null  ) {
1321                                 newPathParams = new StringBuffer();
1322                                 newPathParams.append(pathParams);
1323                         }
1324                     if ( sbParameters.toString().length() > 0 ) {
1325                                         if ( newPathParams == null )
1326                                                 newPathParams = new StringBuffer();
1327                                         newPathParams.append(sbParameters);
1328                     }
1329                     String newQueryParams = null;
1330                     if ( sbIndexedParams.toString().length() > 0 ) {
1331                         if ( queryParams == null )
1332                                 newQueryParams = sbIndexedParams.toString();
1333                         else
1334                                 newQueryParams = queryParams + sbIndexedParams.toString();
1335                     } else {
1336                         newQueryParams = queryParams;
1337                     }
1338                         for ( int k = 0; k < addTypeV.size(); ++k ) {
1339                                 addType = addTypeV.elementAt(k);
1340                 
1341                                 if ( opId == null || !opId.contains(addType)) {
1342                                         processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1343                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, null,
1344                                                 newPathParams, newQueryParams, validEdges);
1345                                 }
1346                                 // need item name of array
1347                                         String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1348                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
1349                                                                 "array", null, null, null );
1350                                         
1351                                         if ( itemName != null ) {
1352                                                 if ( addType.equals("AaiInternal") ) {
1353                                                         //System.out.println( "addType AaiInternal, skip properties");
1354                                                         
1355                                                 } else if ( getItemName == null) {
1356                                                         ++propertyCnt;
1357                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1358                                                         sbProperties.append("        type: array\n        items:\n");
1359                                                         sbProperties.append("          $ref: \"#/definitions/" + itemName + "\"\n");
1360                                                         if ( attrDescription != null && attrDescription.length() > 0 )
1361                                                                 sbProperties.append("        description: " + attrDescription + "\n");
1362                                                 }
1363                                         } else {
1364                                                 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1365                                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, "other" );
1366                                                 if ( itemName != null ) {
1367                                                 */
1368                                                 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1369                                                         // need properties for getXmlRootElementName(addType)
1370                                                 newPathParams = null;
1371                                                 if ( pathParams != null  ) {
1372                                                         newPathParams = new StringBuffer();
1373                                                         newPathParams.append(pathParams);
1374                                                 }
1375                                             if ( sbParameters.toString().length() > 0 ) {
1376                                                                 if ( newPathParams == null )
1377                                                                         newPathParams = new StringBuffer();
1378                                                                 newPathParams.append(sbParameters);
1379                                             }
1380                                             newQueryParams = null;
1381                                             if ( sbIndexedParams.toString().length() > 0 ) {
1382                                                 if ( queryParams == null )
1383                                                         newQueryParams = sbIndexedParams.toString();
1384                                                 else
1385                                                         newQueryParams = queryParams + sbIndexedParams.toString();
1386                                             } else {
1387                                                 newQueryParams = queryParams;
1388                                             }
1389                                                         processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1390                                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
1391                                                                                 null, newPathParams, newQueryParams, validEdges );
1392                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1393                                                         sbProperties.append("        type: array\n        items:          \n");
1394                                                         sbProperties.append("          $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1395                                                 } else {
1396                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1397                                                         sbProperties.append("        type: object\n");
1398                                                         sbProperties.append("        $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1399                                                 }
1400                                                 if ( attrDescription != null && attrDescription.length() > 0 )
1401                                                         sbProperties.append("        description: " + attrDescription + "\n");
1402                                                 ++propertyCnt;
1403                                                 /*}
1404                                                 else {
1405                                                         System.out.println(" unable to define swagger object for " + addType);
1406                                                 }
1407                                                 */
1408                                         }
1409                                         //if ( getItemName == null) looking for missing properties
1410                                                 //generatedJavaType.put(addType, null);
1411                         }
1412                 }
1413                 }
1414         }       
1415                 if ( genPath ) {
1416                         /*
1417                         if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1418                                 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1419                         */
1420
1421                         if ( !path.endsWith("/relationship") ) {
1422                                 pathSb.append("  " + path + ":\n" );
1423                                 pathSb.append("    get:\n");
1424                                 pathSb.append("      tags:\n");
1425                                 pathSb.append("        - " + tag + "\n");
1426                                 pathSb.append("      summary: returns " + xmlRootElementName + "\n");
1427         
1428                                 pathSb.append("      description: returns " + xmlRootElementName + "\n");
1429                                 pathSb.append("      operationId: get" + useOpId + "\n");
1430                                 pathSb.append("      produces:\n");
1431                                 pathSb.append("        - application/json\n");
1432                                 pathSb.append("        - application/xml\n");
1433                                 
1434                                 pathSb.append("      responses:\n");
1435                                 pathSb.append("        \"200\":\n");
1436                                 pathSb.append("          description: successful operation\n");
1437                                 pathSb.append("          schema:\n");
1438                                 pathSb.append("              $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1439                                 pathSb.append("        \"default\":\n");
1440                                 pathSb.append("          " + responsesUrl);
1441                                 /*
1442                                 pathSb.append("        \"200\":\n");
1443                                 pathSb.append("          description: successful operation\n");
1444                                 pathSb.append("          schema:\n");
1445                                 pathSb.append("              $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1446                                 pathSb.append("        \"404\":\n");
1447                                 pathSb.append("          description: resource was not found\n");
1448                                 pathSb.append("        \"400\":\n");
1449                                 pathSb.append("          description: bad request\n");
1450                                 */
1451                                 if ( path.indexOf('{') > 0 ) {
1452                                 
1453                             if ( sbParameters.toString().length() > 0 ) {
1454                                                 if ( pathParams == null )
1455                                                         pathParams = new StringBuffer();
1456                                                 pathParams.append(sbParameters);
1457                             }
1458                                         if ( pathParams != null) {
1459                                                 pathSb.append("      parameters:\n");
1460                                                 pathSb.append(pathParams);
1461                                         } else
1462                                                 System.out.println( "null pathParams for " + useOpId);
1463                                         if ( sbIndexedParams.toString().length() > 0 ) {
1464                                                 if ( queryParams == null )
1465                                                         queryParams = sbIndexedParams.toString();
1466                                                 else
1467                                                         queryParams = queryParams + sbIndexedParams.toString();
1468                                         }
1469                                         if ( queryParams != null ) {
1470                                                 if ( pathParams == null ) {
1471                                                         pathSb.append("      parameters:\n");
1472                                                 }
1473                                                 pathSb.append(queryParams);
1474                                         }
1475                                 }
1476                         }
1477                         boolean skipPutDelete = false; // no put or delete for "all" 
1478                         if ( !path.endsWith("/relationship") ) {                                
1479                                 if ( !path.endsWith("}") ){
1480                                                 skipPutDelete = true;
1481                                 }
1482                                         
1483                         }
1484                         if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1485                                 // add PUT
1486                                 if ( path.endsWith("/relationship") ) {
1487                                         pathSb.append("  " + path + ":\n" );
1488                                 } 
1489                                 pathSb.append("    put:\n");
1490                                 pathSb.append("      tags:\n");
1491                                 pathSb.append("        - " + tag + "\n");
1492
1493                                 if ( path.endsWith("/relationship") ) {
1494                                         pathSb.append("      summary: see node definition for valid relationships\n");
1495                                 } else {
1496                                         pathSb.append("      summary: create or update an existing " + xmlRootElementName + "\n");
1497                                         pathSb.append("      description: create or update an existing " + xmlRootElementName + "\n");
1498                                 }
1499                                 pathSb.append("      operationId: createOrUpdate" + useOpId + "\n");
1500                                 pathSb.append("      consumes:\n");
1501                                 pathSb.append("        - application/json\n");
1502                                 pathSb.append("        - application/xml\n");                                   
1503                                 pathSb.append("      produces:\n");
1504                                 pathSb.append("        - application/json\n");
1505                                 pathSb.append("        - application/xml\n");
1506                                 pathSb.append("      responses:\n");
1507                                 pathSb.append("        \"default\":\n");
1508                                 pathSb.append("          " + responsesUrl);
1509                                 /*
1510                                 pathSb.append("      responses:\n");
1511                                 pathSb.append("        \"200\":\n");
1512                                 pathSb.append("          description: existing resource has been modified and there is a response buffer\n");                                   
1513                                 pathSb.append("        \"201\":\n");
1514                                 pathSb.append("          description: new resource is created\n");      
1515                                 pathSb.append("        \"202\":\n");
1516                                 pathSb.append("          description: action requested but may have taken other actions as well, which are returned in the response payload\n");                                
1517                                 pathSb.append("        \"204\":\n");
1518                                 pathSb.append("          description: existing resource has been modified and there is no response buffer\n");                          
1519                                 pathSb.append("        \"400\":\n");
1520                                 pathSb.append("          description: Bad Request will be returned if headers are missing\n");
1521                                 pathSb.append("        \"404\":\n");
1522                                 pathSb.append("          description: Not Found will be returned if an unknown URL is used\n");
1523                                 */                                              
1524                                 pathSb.append("      parameters:\n");
1525                                 //pathSb.append("        - in: path\n");
1526                                 pathSb.append(pathParams); // for nesting
1527                                 pathSb.append("        - name: body\n");
1528                                 pathSb.append("          in: body\n");
1529                                 pathSb.append("          description: " + xmlRootElementName + " object that needs to be created or updated\n");
1530                                 pathSb.append("          required: true\n");
1531                                 pathSb.append("          schema:\n");
1532                                 pathSb.append("            $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1533                                 /*
1534                                 if ( queryParams != null ) {
1535                                         pathSb.append(queryParams);
1536                                 }
1537                                 */
1538                                 // add DELETE
1539                                 pathSb.append("    delete:\n");
1540                                 pathSb.append("      tags:\n");
1541                                 pathSb.append("        - " + tag + "\n");
1542                                 pathSb.append("      summary: delete an existing " + xmlRootElementName + "\n");
1543                                 
1544                                 pathSb.append("      description: delete an existing " + xmlRootElementName + "\n");
1545                                 
1546                                 pathSb.append("      operationId: delete" + useOpId + "\n");
1547                                 pathSb.append("      consumes:\n");
1548                                 pathSb.append("        - application/json\n");
1549                                 pathSb.append("        - application/xml\n");                                   
1550                                 pathSb.append("      produces:\n");
1551                                 pathSb.append("        - application/json\n");
1552                                 pathSb.append("        - application/xml\n");
1553                                 pathSb.append("      responses:\n");
1554                                 pathSb.append("        \"default\":\n");
1555                                 pathSb.append("          " + responsesUrl);
1556                                 /*
1557                                 pathSb.append("      responses:\n");
1558                                 pathSb.append("        \"200\":\n");
1559                                 pathSb.append("          description: successful, the response includes an entity describing the status\n");
1560                                 pathSb.append("        \"204\":\n");
1561                                 pathSb.append("          description: successful, action has been enacted but the response does not include an entity\n");
1562                                 pathSb.append("        \"400\":\n");
1563                                 pathSb.append("          description: Bad Request will be returned if headers are missing\n");
1564                                 pathSb.append("        \"404\":\n");
1565                                 pathSb.append("          description: Not Found will be returned if an unknown URL is used\n");
1566                                 */                              
1567                                 pathSb.append("      parameters:\n");
1568                                 //pathSb.append("        - in: path\n");
1569                                 pathSb.append(pathParams); // for nesting
1570                                 if ( !path.endsWith("/relationship") ) {
1571                                         pathSb.append("        - name: resource-version\n");
1572         
1573                                         pathSb.append("          in: query\n");
1574                                         pathSb.append("          description: resource-version for concurrency\n");
1575                                         pathSb.append("          required: true\n");
1576                                         pathSb.append("          type: string\n");
1577                                 }
1578                                 /*
1579                                 if ( queryParams != null ) {
1580                                         pathSb.append(queryParams);
1581                                 }
1582                                 */
1583                         }
1584                         
1585                 }
1586                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1587                         return null;
1588                 }
1589         
1590                 definitionsSb.append("  " + xmlRootElementName + ":\n");
1591                 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1592                 if ( edges.size() > 0 ) {
1593                         StringBuffer sbEdge = new StringBuffer();
1594                         sbEdge.append("      ###### Related Nodes\n");
1595                         for (EdgeDescription ed : edges) { 
1596                                 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1597                                     sbEdge.append("      - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1598                                     sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1599                                     sbEdge.append("\n");
1600                                 }
1601                         }
1602                         for (EdgeDescription ed : edges) { 
1603                                 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1604                                     sbEdge.append("      - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1605                                     sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1606                                     sbEdge.append("\n");
1607                                 }
1608                         }
1609                         validEdges = sbEdge.toString();
1610                 }
1611
1612                 String deleteRule = getDeleteRules(xmlRootElementName);
1613                 // Handle description property.  Might have a description OR valid edges OR both OR neither.
1614                 // Only put a description: tag if there is at least one.
1615                 if (pathDescriptionProperty != null || deleteRule != null || validEdges != null) {
1616                         definitionsSb.append("    description: |\n");      
1617
1618                         if ( pathDescriptionProperty != null ) 
1619                                 definitionsSb.append("      " + pathDescriptionProperty + "\n" );
1620                         if (deleteRule != null) 
1621                                 definitionsSb.append("      ###### Default Delete Scope\n      ").append(deleteRule).append("\n");
1622                         if (validEdges != null) 
1623                                 definitionsSb.append(validEdges);
1624                 }
1625                 
1626                 if ( requiredCnt > 0 )
1627                         definitionsSb.append(sbRequired);
1628                 if ( propertyCnt > 0 ) {
1629                         definitionsSb.append("    properties:\n");
1630                         definitionsSb.append(sbProperties);
1631                 }
1632                 generatedJavaType.put(xmlRootElementName, null);
1633                 return null;
1634         }
1635         
1636         public static String generateSwaggerFromOxmFile( File oxmFile )
1637         {
1638
1639                 StringBuffer sb = new StringBuffer();
1640                 sb.append("swagger: \"2.0\"\ninfo:\n  description: |\n    Copyright &copy; 2017 AT&amp;T Intellectual Property. All rights reserved.\n\n    Licensed under the Creative Commons License, Attribution 4.0 Intl. (the &quot;License&quot;); you may not use this documentation except in compliance with the License.\n\n    You may obtain a copy of the License at\n\n    (https://creativecommons.org/licenses/by/4.0/)\n\n    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n\n    ECOMP and OpenECOMP are trademarks and service marks of AT&amp;T Intellectual Property.\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: \"" + apiVersion +"\"\n");
1641                 sb.append("  title: Active and Available Inventory REST API\n");
1642                 sb.append("  license:\n    name: Apache 2.0\n    url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1643                 sb.append("  contact:\n    name:\n    url:\n    email:\n");
1644                 sb.append("host:\nbasePath: /aai/" + apiVersion + "\n");
1645                 sb.append("schemes:\n  - https\npaths:\n");
1646                 /*
1647                 sb.append("responses:\n");
1648                 sb.append("  \"200\":\n");
1649                 sb.append("    description: successful operation\n");
1650                 sb.append("  \"404\":\n");
1651                 sb.append("    description: resource was not found\n");
1652                 sb.append("  \"400\":\n");
1653                 sb.append("    description: bad request\n");
1654                 */
1655                 try {
1656                         
1657                         versionedClass = getEdgeRulesClass();
1658                     
1659                     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1660                     dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1661                     DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1662                     Document doc = dBuilder.parse(oxmFile);
1663
1664                     NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1665                         Element bindingElement;
1666                         NodeList javaTypesNodes;
1667                         Element javaTypesElement;
1668                         
1669                         Element javaTypeElement;
1670
1671                         
1672                         if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1673                                 System.out.println( "missing <binding-nodes> in " + oxmFile );
1674                                 return null;
1675                         }           
1676                         
1677                         bindingElement = (Element) bindingsNodes.item(0);
1678                         javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1679                         if ( javaTypesNodes.getLength() < 1 ) {
1680                                 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1681                                 return null;
1682                         }
1683                         javaTypesElement = (Element) javaTypesNodes.item(0);
1684
1685                         javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1686                         if ( javaTypeNodes.getLength() < 1 ) {
1687                                 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1688                                 return null;
1689                         }
1690
1691                         String javaTypeName;
1692                         String attrName, attrValue;
1693                         Attr attr;
1694                         StringBuffer pathSb = new StringBuffer();
1695                         
1696                         StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1697                         
1698                         for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1699                                 javaTypeElement = (Element) javaTypeNodes.item(i);
1700                                 NamedNodeMap attributes = javaTypeElement.getAttributes();
1701                                 javaTypeName = null;
1702                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
1703                             attr = (Attr) attributes.item(j);
1704                             attrName = attr.getNodeName();
1705                             attrValue = attr.getNodeValue();
1706                             if ( attrName.equals("name"))
1707                                 javaTypeName = attrValue;
1708                                 }
1709                                 if ( javaTypeName == null ) {
1710                                         System.out.println( "<java-type> has no name attribute in " + oxmFile );
1711                                         return null;
1712                                 }
1713                                 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1714                                         
1715                                         //generatedJavaType.put(javaTypeName, null);
1716                                         //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1717
1718                                         processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1719                                                         definitionsSb, null, null, null, null, null, null, null);
1720                                 }
1721                         }
1722                         sb.append(pathSb);
1723                         //System.out.println( "definitions block\n" + definitionsSb.toString());
1724                         sb.append(definitionsSb.toString());
1725                         //sb.append(definitionsSb);
1726                                 
1727                 } catch (Exception e) {
1728                         e.printStackTrace();
1729                         return null;
1730                 }
1731                 //System.out.println("generated " + sb.toString());
1732                 return sb.toString();
1733         }
1734         
1735         private static NodeList locateXmlProperties(Element element) {
1736                 XPathExpression expr;
1737                 NodeList result = null;
1738                 try {
1739                         expr = xpath.compile("xml-properties");
1740                         if (expr != null) {
1741                                 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1742                                 if (nodeset != null) {
1743                                         NodeList nodes = (NodeList) nodeset;
1744                                         if (nodes != null && nodes.getLength() > 0) {
1745                                                 Element xmlProperty = (Element)nodes.item(0);
1746                                                 result = xmlProperty.getElementsByTagName("xml-property");
1747                                         }
1748                                 }
1749                         }
1750                 } catch (XPathExpressionException e) {
1751                         e.printStackTrace();
1752                 }
1753                 return result;
1754                 
1755         }
1756 }