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