[AAI-191 Amsterdam] Refactor import statements
[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                                 break;
949                         default:
950                                 return null;
951                         }
952                 }
953                 /*
954                 if ( path == null )
955                         System.out.println( "processJavaTypeElementSwagger called with null path for javaTypeName " + javaTypeName);
956                 */
957                 /*
958                 if ( path == null || !(path.contains("cloud-infrastructure")))
959                         switch ( javaTypeName) {
960                          case "Inventory":
961                                 useTag = null;
962                                 break;
963                                 
964                         case "CloudInfrastructure":
965                         case "Search":
966                         case "Actions":
967                         case "ServiceDesignAndCreation":
968                         case "LicenseManagement":
969                         case "Network":
970                                 if ( tag == null )
971                                         useTag = javaTypeName;
972
973                                 break;
974                         default:
975                                         return null;
976                                         
977                         }
978                 */
979                 
980                 if ( !javaTypeName.equals("Inventory") ) {
981                         if ( javaTypeName.equals("AaiInternal"))
982                                 return null;
983                         if ( opId == null )
984                                 useOpId = javaTypeName;
985                         else
986                                 useOpId = opId + javaTypeName;
987                         if ( tag == null )
988                                 useTag = javaTypeName;
989                 }
990                 
991                 /*
992                 if ( javaTypeName.equals("GenericVnf"))
993                         System.out.println( "Processing " + javaTypeName);
994                 else if ( javaTypeName.equals("Service"))
995                                 System.out.println( "Processing " + javaTypeName);
996                 else if ( javaTypeName.equals("SitePair"))
997                         System.out.println( "Processing " + javaTypeName);
998                 */
999                 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
1000
1001                 if ( parentNodes.getLength() == 0 ) {
1002                         //System.out.println( "no java-attributes for java-type " + javaTypeName);
1003                         return "";
1004
1005                 }
1006                 
1007                 NamedNodeMap attributes;
1008                 
1009                 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
1010                 Element valElement = (Element) valNodes.item(0);
1011                 attributes = valElement.getAttributes();
1012                 for ( int i = 0; i < attributes.getLength(); ++i ) {
1013             Attr attr = (Attr) attributes.item(i);
1014             String attrName = attr.getNodeName();
1015
1016             String attrValue = attr.getNodeValue();
1017             //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
1018             if ( attrName.equals("name"))
1019                 xmlRootElementName = attrValue;
1020                 }
1021                 /*
1022                 if ( xmlRootElementName.equals("oam-networks"))
1023                         System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
1024                 */
1025                 //already processed
1026                 /*
1027                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1028                         return null;
1029                 }
1030                 */
1031                 NodeList childNodes;
1032                 Element childElement;
1033                 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
1034                 Element xmlPropElement;
1035                 String pathDescriptionProperty = null;
1036                 
1037                 
1038                 Vector<String> indexedProps = null;
1039                 
1040                 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
1041                 if ( path != null && path.equals("/network/generic-vnfs"))
1042                         System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
1043                 */
1044                 if ( xmlPropNodes.getLength() > 0 ) {
1045
1046                         for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
1047                                 xmlPropElement = (Element)xmlPropNodes.item(i);
1048                                 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
1049                                         continue;
1050                                 childNodes = xmlPropElement.getElementsByTagName("xml-property");
1051                                 
1052                                 if ( childNodes.getLength() > 0 ) {
1053                                         for ( int j = 0; j < childNodes.getLength(); ++j ) {
1054                                                 childElement = (Element)childNodes.item(j);
1055                                                 // get name
1056                                                 int useValue = VALUE_NONE;
1057                                                 attributes = childElement.getAttributes();
1058                                                 for ( int k = 0; k < attributes.getLength(); ++k ) {
1059                                                         Attr attr = (Attr) attributes.item(k);
1060                                                         String attrName = attr.getNodeName();
1061                                                         String attrValue = attr.getNodeValue();
1062                                                         if ( attrName == null || attrValue == null )
1063                                                                 continue;
1064                                                         if ( attrName.equals("name") && attrValue.equals("description")) {
1065                                                                 useValue = VALUE_DESCRIPTION;
1066                                                         }
1067                                                         if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
1068                                                                 pathDescriptionProperty = attrValue;
1069                                                                 //break;
1070                                                                 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1071                                                         }
1072                                                         if ( attrValue.equals("indexedProps")) {
1073                                                                 useValue = VALUE_INDEXED_PROPS;
1074                                                         }
1075                                                         if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
1076                                                                 indexedProps = getIndexedProps( attrValue );
1077                                                         }
1078                                                 }
1079                                         }
1080                                 }
1081                         }
1082                 }
1083                 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
1084
1085                 /*
1086                 if ( javaTypeName.equals("RelationshipList")) {
1087                         System.out.println( "Skipping " + javaTypeName);
1088                         generatedJavaType.put(javaTypeName, null);
1089                         return "";
1090                 }
1091                 */
1092                 
1093                 Element parentElement = (Element)parentNodes.item(0);
1094                 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
1095
1096         
1097                 String attrDescription = null;
1098
1099                 Element xmlElementElement;
1100                 String addType = null;
1101                 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1102                 String elementName = null;
1103                 StringBuffer sbParameters = new StringBuffer();
1104
1105                 StringBuffer sbRequired = new StringBuffer();
1106                 int requiredCnt = 0;
1107                 int propertyCnt = 0;
1108                 StringBuffer sbProperties = new StringBuffer();
1109                 StringBuffer sbIndexedParams = new StringBuffer();
1110
1111                 
1112                 StringTokenizer st;
1113                 if ( xmlRootElementName.equals("inventory"))
1114                         path = "";
1115                 else if ( path == null )
1116                         //path = "/aai/" + apiVersion;
1117                         path = "/" + xmlRootElementName;
1118                 else
1119                         path += "/" + xmlRootElementName;
1120                 st = new StringTokenizer(path, "/");
1121                 /*
1122                 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1123                         System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1124                 */
1125                 boolean genPath = false;
1126                 /*
1127                 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1128                         System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1129                 */
1130                 if ( st.countTokens() > 1 && getItemName == null ) {
1131                         if ( appliedPaths.containsKey(path)) 
1132                                 return null;
1133                         appliedPaths.put(path, null);
1134                         genPath = true;
1135                         if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1136                                 genPath = false;
1137                         }
1138                         if ( path.endsWith("/relationship-list")) {
1139                                 genPath = false;
1140                         }
1141                                         
1142                 }
1143                 
1144                 Vector<String> addTypeV = null;
1145                 if (  xmlElementNodes.getLength() > 0 ) {
1146                         
1147                         for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1148                                 xmlElementElement = (Element)xmlElementNodes.item(i);
1149                                 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1150                                         continue;
1151                                 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1152                                 if ( childNodes.getLength() > 0 ) {
1153                                         childElement = (Element)childNodes.item(0);
1154                                         // get name
1155                                         attributes = childElement.getAttributes();
1156                                         for ( int k = 0; k < attributes.getLength(); ++k ) {
1157                                                 Attr attr = (Attr) attributes.item(k);
1158                                                 String attrName = attr.getNodeName();
1159                                                 String attrValue = attr.getNodeValue();
1160                                                 if ( attrName.equals("name")) {
1161                                                         xmlElementWrapper = attrValue;
1162                                                         //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1163                                                 }
1164                                         }
1165
1166                                 }
1167                                 */
1168                                 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1169                                 attrDescription = null;
1170                                 if ( valNodes.getLength() > 0 ) {
1171                                         for ( int j = 0; j < valNodes.getLength(); ++j ) {
1172                                                 valElement = (Element)valNodes.item(j);
1173                                                 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1174                                                         continue;
1175                                                 childNodes = valElement.getElementsByTagName("xml-property");
1176                                                 if ( childNodes.getLength() > 0 ) {
1177                                                         childElement = (Element)childNodes.item(0);
1178                                                         // get name
1179                                                         attributes = childElement.getAttributes();
1180                                                         attrDescription = null;
1181                                                         boolean useValue = false;
1182                                                         for ( int k = 0; k < attributes.getLength(); ++k ) {
1183                                                                 Attr attr = (Attr) attributes.item(k);
1184                                                                 String attrName = attr.getNodeName();
1185                                                                 String attrValue = attr.getNodeValue();
1186                                                                 if ( attrName.equals("name") && attrValue.equals("description")) {
1187                                                                         useValue = true;
1188                                                                 }
1189                                                                 if ( useValue && attrName.equals("value")) {
1190                                                                         attrDescription = attrValue;
1191                                                                         //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1192                                                                 }
1193                                                         }
1194
1195                                                 }
1196                                         }
1197                                 }
1198                                 
1199                                 attributes = xmlElementElement.getAttributes();
1200                                 addTypeV = null; // vector of 1
1201                                 addType = null;
1202                                 
1203                                 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1204                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
1205                             Attr attr = (Attr) attributes.item(j);
1206                             String attrName = attr.getNodeName();
1207         
1208                             String attrValue = attr.getNodeValue();
1209                             //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1210                             if ( attrName.equals("name")) {
1211                                 elementName = attrValue;
1212
1213                             }
1214                             if ( attrName.equals("type") && getItemName == null ) {
1215                                 elementType = attrValue;
1216                                 if ( attrValue.contains(apiVersionFmt) ) {
1217                                         addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1218                                         if ( addTypeV == null ) 
1219                                                 addTypeV = new Vector<String>();
1220                                         addTypeV.add(addType);
1221                                 }
1222                                         
1223                             }
1224                             if ( attrName.equals("xml-key")) {
1225                                 elementIsKey = attrValue;
1226                                 path += "/{" + elementName + "}";
1227                             }
1228                             if ( attrName.equals("required")) {
1229                                 elementIsRequired = attrValue;
1230                             }
1231                             if ( attrName.equals("container-type")) {
1232                                 elementContainerType = attrValue;
1233                             }   
1234                                 }
1235                 if ( getItemName != null ) {
1236                         if ( getItemName.equals("array") ) {
1237                                 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1238                                         //System.out.println( " returning array " + elementName );
1239                                         return elementName;
1240                                 }
1241                                 
1242                         } else { // not an array check
1243                                 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1244                                         //System.out.println( " returning object " + elementName );
1245                                         return elementName;
1246                                 }
1247                                 
1248                         }
1249                         //System.out.println( " returning null" );
1250                         return null;
1251                 }
1252                                 if ( elementIsRequired != null ) {
1253                                         if ( requiredCnt == 0 )
1254                                                 sbRequired.append("    required:\n");
1255                                         ++requiredCnt;
1256                                         if ( addTypeV != null ) {
1257                                                 for ( int k = 0; k < addTypeV.size(); ++i ) {
1258                                                         sbRequired.append("    - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1259                                                 }
1260                                         } else 
1261                                                 sbRequired.append("    - " + elementName + "\n");
1262
1263                                 }
1264
1265                                 if (  elementIsKey != null )  {
1266                                                                                 sbParameters.append(("        - name: " + elementName + "\n"));
1267                                         sbParameters.append(("          in: path\n"));
1268                                         if ( attrDescription != null && attrDescription.length() > 0 )
1269                                                 sbParameters.append(("          description: " + attrDescription + "\n"));
1270                                         sbParameters.append(("          required: true\n"));
1271                                         if ( elementType.equals("java.lang.String"))
1272                                                 sbParameters.append("          type: string\n");
1273                                         if ( elementType.equals("java.lang.Long")) {
1274                                                 sbParameters.append("          type: integer\n");
1275                                                 sbParameters.append("          format: int64\n");
1276                                         }
1277                                         if ( elementType.equals("java.lang.Integer")) {
1278                                                 sbParameters.append("          type: integer\n");
1279                                                 sbParameters.append("          format: int32\n");
1280                                         }
1281                                         if ( elementType.equals("java.lang.Boolean"))
1282                                                 sbParameters.append("          type: boolean\n");
1283
1284
1285                                 } else if (  indexedProps != null
1286                                                 && indexedProps.contains(elementName ) ) {
1287                                         sbIndexedParams.append(("        - name: " + elementName + "\n"));
1288                                         sbIndexedParams.append(("          in: query\n"));
1289                                         if ( attrDescription != null && attrDescription.length() > 0 )
1290                                                 sbIndexedParams.append(("          description: " + attrDescription + "\n"));
1291                                         sbIndexedParams.append(("          required: false\n"));
1292                                         if ( elementType.equals("java.lang.String"))
1293                                                 sbIndexedParams.append("          type: string\n");
1294                                         if ( elementType.equals("java.lang.Long")) {
1295                                                 sbIndexedParams.append("          type: integer\n");
1296                                                 sbIndexedParams.append("          format: int64\n");
1297                                         }
1298                                         if ( elementType.equals("java.lang.Integer")) {
1299                                                 sbIndexedParams.append("          type: integer\n");
1300                                                 sbIndexedParams.append("          format: int32\n");
1301                                         }
1302                                         if ( elementType.equals("java.lang.Boolean"))
1303                                                 sbIndexedParams.append("          type: boolean\n");
1304                                 }
1305
1306                         /*
1307                         if ( elementName != null && elementName.equals("inventory-item"))
1308                                 System.out.println( "processing inventory-item elementName");
1309                         */
1310                 
1311                         if ( isStandardType(elementType)) {
1312                                 sbProperties.append("      " + elementName + ":\n");
1313                                 ++propertyCnt;
1314                                 sbProperties.append("        type: ");
1315
1316                                 if ( elementType.equals("java.lang.String"))
1317                                         sbProperties.append("string\n");
1318                                 else if ( elementType.equals("java.lang.Long")) {
1319                                         sbProperties.append("integer\n");
1320                                         sbProperties.append("        format: int64\n");
1321                                 }
1322                                 else if ( elementType.equals("java.lang.Integer")){
1323                                         sbProperties.append("integer\n");
1324                                         sbProperties.append("        format: int32\n");
1325                                 }
1326                                 else if ( elementType.equals("java.lang.Boolean"))
1327                                         sbProperties.append("boolean\n");
1328                                 if ( attrDescription != null && attrDescription.length() > 0 )
1329                                         sbProperties.append("        description: " + attrDescription + "\n");
1330                         }
1331
1332                         //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1333
1334                 if ( addTypeV !=  null ) {
1335                         StringBuffer newPathParams = null;
1336                         if ( pathParams != null  ) {
1337                                 newPathParams = new StringBuffer();
1338                                 newPathParams.append(pathParams);
1339                         }
1340                     if ( sbParameters.toString().length() > 0 ) {
1341                                         if ( newPathParams == null )
1342                                                 newPathParams = new StringBuffer();
1343                                         newPathParams.append(sbParameters);
1344                     }
1345                     String newQueryParams = null;
1346                     if ( sbIndexedParams.toString().length() > 0 ) {
1347                         if ( queryParams == null )
1348                                 newQueryParams = sbIndexedParams.toString();
1349                         else
1350                                 newQueryParams = queryParams + sbIndexedParams.toString();
1351                     } else {
1352                         newQueryParams = queryParams;
1353                     }
1354                         for ( int k = 0; k < addTypeV.size(); ++k ) {
1355                                 addType = addTypeV.elementAt(k);
1356                 
1357                                 if ( opId == null || !opId.contains(addType)) {
1358                                         processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1359                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, null,
1360                                                 newPathParams, newQueryParams, validEdges);
1361                                 }
1362                                 // need item name of array
1363                                         String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1364                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
1365                                                                 "array", null, null, null );
1366                                         
1367                                         if ( itemName != null ) {
1368                                                 if ( addType.equals("AaiInternal") ) {
1369                                                         //System.out.println( "addType AaiInternal, skip properties");
1370                                                         
1371                                                 } else if ( getItemName == null) {
1372                                                         ++propertyCnt;
1373                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1374                                                         sbProperties.append("        type: array\n        items:\n");
1375                                                         sbProperties.append("          $ref: \"#/definitions/" + itemName + "\"\n");
1376                                                         if ( attrDescription != null && attrDescription.length() > 0 )
1377                                                                 sbProperties.append("        description: " + attrDescription + "\n");
1378                                                 }
1379                                         } else {
1380                                                 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1381                                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, "other" );
1382                                                 if ( itemName != null ) {
1383                                                 */
1384                                                 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1385                                                         // need properties for getXmlRootElementName(addType)
1386                                                 newPathParams = null;
1387                                                 if ( pathParams != null  ) {
1388                                                         newPathParams = new StringBuffer();
1389                                                         newPathParams.append(pathParams);
1390                                                 }
1391                                             if ( sbParameters.toString().length() > 0 ) {
1392                                                                 if ( newPathParams == null )
1393                                                                         newPathParams = new StringBuffer();
1394                                                                 newPathParams.append(sbParameters);
1395                                             }
1396                                             newQueryParams = null;
1397                                             if ( sbIndexedParams.toString().length() > 0 ) {
1398                                                 if ( queryParams == null )
1399                                                         newQueryParams = sbIndexedParams.toString();
1400                                                 else
1401                                                         newQueryParams = queryParams + sbIndexedParams.toString();
1402                                             } else {
1403                                                 newQueryParams = queryParams;
1404                                             }
1405                                                         processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1406                                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
1407                                                                                 null, newPathParams, newQueryParams, validEdges );
1408                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1409                                                         sbProperties.append("        type: array\n        items:          \n");
1410                                                         sbProperties.append("          $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1411                                                 } else {
1412                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1413                                                         sbProperties.append("        type: object\n");
1414                                                         sbProperties.append("        $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1415                                                 }
1416                                                 if ( attrDescription != null && attrDescription.length() > 0 )
1417                                                         sbProperties.append("        description: " + attrDescription + "\n");
1418                                                 ++propertyCnt;
1419                                                 /*}
1420                                                 else {
1421                                                         System.out.println(" unable to define swagger object for " + addType);
1422                                                 }
1423                                                 */
1424                                         }
1425                                         //if ( getItemName == null) looking for missing properties
1426                                                 //generatedJavaType.put(addType, null);
1427                         }
1428                 }
1429                 }
1430         }       
1431                 if ( genPath ) {
1432                         /*
1433                         if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1434                                 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1435                         */
1436
1437                         if ( !path.endsWith("/relationship") ) {
1438                                 pathSb.append("  " + path + ":\n" );
1439                                 pathSb.append("    get:\n");
1440                                 pathSb.append("      tags:\n");
1441                                 pathSb.append("        - " + tag + "\n");
1442                                 pathSb.append("      summary: returns " + xmlRootElementName + "\n");
1443         
1444                                 pathSb.append("      description: returns " + xmlRootElementName + "\n");
1445                                 pathSb.append("      operationId: get" + useOpId + "\n");
1446                                 pathSb.append("      produces:\n");
1447                                 pathSb.append("        - application/json\n");
1448                                 pathSb.append("        - application/xml\n");
1449                                 
1450                                 pathSb.append("      responses:\n");
1451                                 pathSb.append("        \"200\":\n");
1452                                 pathSb.append("          description: successful operation\n");
1453                                 pathSb.append("          schema:\n");
1454                                 pathSb.append("              $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1455                                 pathSb.append("        \"default\":\n");
1456                                 pathSb.append("          " + responsesUrl);
1457                                 /*
1458                                 pathSb.append("        \"200\":\n");
1459                                 pathSb.append("          description: successful operation\n");
1460                                 pathSb.append("          schema:\n");
1461                                 pathSb.append("              $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1462                                 pathSb.append("        \"404\":\n");
1463                                 pathSb.append("          description: resource was not found\n");
1464                                 pathSb.append("        \"400\":\n");
1465                                 pathSb.append("          description: bad request\n");
1466                                 */
1467                                 if ( path.indexOf('{') > 0 ) {
1468                                 
1469                             if ( sbParameters.toString().length() > 0 ) {
1470                                                 if ( pathParams == null )
1471                                                         pathParams = new StringBuffer();
1472                                                 pathParams.append(sbParameters);
1473                             }
1474                                         if ( pathParams != null) {
1475                                                 pathSb.append("      parameters:\n");
1476                                                 pathSb.append(pathParams);
1477                                         } else
1478                                                 System.out.println( "null pathParams for " + useOpId);
1479                                         if ( sbIndexedParams.toString().length() > 0 ) {
1480                                                 if ( queryParams == null )
1481                                                         queryParams = sbIndexedParams.toString();
1482                                                 else
1483                                                         queryParams = queryParams + sbIndexedParams.toString();
1484                                         }
1485                                         if ( queryParams != null ) {
1486                                                 if ( pathParams == null ) {
1487                                                         pathSb.append("      parameters:\n");
1488                                                 }
1489                                                 pathSb.append(queryParams);
1490                                         }
1491                                 }
1492                         }
1493                         boolean skipPutDelete = false; // no put or delete for "all" 
1494                         if ( !path.endsWith("/relationship") ) {                                
1495                                 if ( !path.endsWith("}") ){
1496                                                 skipPutDelete = true;
1497                                 }
1498                                         
1499                         }
1500                         if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1501                                 // add PUT
1502                                 if ( path.endsWith("/relationship") ) {
1503                                         pathSb.append("  " + path + ":\n" );
1504                                 } 
1505                                 pathSb.append("    put:\n");
1506                                 pathSb.append("      tags:\n");
1507                                 pathSb.append("        - " + tag + "\n");
1508
1509                                 if ( path.endsWith("/relationship") ) {
1510                                         pathSb.append("      summary: see node definition for valid relationships\n");
1511                                 } else {
1512                                         pathSb.append("      summary: create or update an existing " + xmlRootElementName + "\n");
1513                                         pathSb.append("      description: create or update an existing " + xmlRootElementName + "\n");
1514                                 }
1515                                 pathSb.append("      operationId: createOrUpdate" + useOpId + "\n");
1516                                 pathSb.append("      consumes:\n");
1517                                 pathSb.append("        - application/json\n");
1518                                 pathSb.append("        - application/xml\n");                                   
1519                                 pathSb.append("      produces:\n");
1520                                 pathSb.append("        - application/json\n");
1521                                 pathSb.append("        - application/xml\n");
1522                                 pathSb.append("      responses:\n");
1523                                 pathSb.append("        \"default\":\n");
1524                                 pathSb.append("          " + responsesUrl);
1525                                 /*
1526                                 pathSb.append("      responses:\n");
1527                                 pathSb.append("        \"200\":\n");
1528                                 pathSb.append("          description: existing resource has been modified and there is a response buffer\n");                                   
1529                                 pathSb.append("        \"201\":\n");
1530                                 pathSb.append("          description: new resource is created\n");      
1531                                 pathSb.append("        \"202\":\n");
1532                                 pathSb.append("          description: action requested but may have taken other actions as well, which are returned in the response payload\n");                                
1533                                 pathSb.append("        \"204\":\n");
1534                                 pathSb.append("          description: existing resource has been modified and there is no response buffer\n");                          
1535                                 pathSb.append("        \"400\":\n");
1536                                 pathSb.append("          description: Bad Request will be returned if headers are missing\n");
1537                                 pathSb.append("        \"404\":\n");
1538                                 pathSb.append("          description: Not Found will be returned if an unknown URL is used\n");
1539                                 */                                              
1540                                 pathSb.append("      parameters:\n");
1541                                 //pathSb.append("        - in: path\n");
1542                                 pathSb.append(pathParams); // for nesting
1543                                 pathSb.append("        - name: body\n");
1544                                 pathSb.append("          in: body\n");
1545                                 pathSb.append("          description: " + xmlRootElementName + " object that needs to be created or updated\n");
1546                                 pathSb.append("          required: true\n");
1547                                 pathSb.append("          schema:\n");
1548                                 pathSb.append("            $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1549                                 /*
1550                                 if ( queryParams != null ) {
1551                                         pathSb.append(queryParams);
1552                                 }
1553                                 */
1554                                 // add DELETE
1555                                 pathSb.append("    delete:\n");
1556                                 pathSb.append("      tags:\n");
1557                                 pathSb.append("        - " + tag + "\n");
1558                                 pathSb.append("      summary: delete an existing " + xmlRootElementName + "\n");
1559                                 
1560                                 pathSb.append("      description: delete an existing " + xmlRootElementName + "\n");
1561                                 
1562                                 pathSb.append("      operationId: delete" + useOpId + "\n");
1563                                 pathSb.append("      consumes:\n");
1564                                 pathSb.append("        - application/json\n");
1565                                 pathSb.append("        - application/xml\n");                                   
1566                                 pathSb.append("      produces:\n");
1567                                 pathSb.append("        - application/json\n");
1568                                 pathSb.append("        - application/xml\n");
1569                                 pathSb.append("      responses:\n");
1570                                 pathSb.append("        \"default\":\n");
1571                                 pathSb.append("          " + responsesUrl);
1572                                 /*
1573                                 pathSb.append("      responses:\n");
1574                                 pathSb.append("        \"200\":\n");
1575                                 pathSb.append("          description: successful, the response includes an entity describing the status\n");
1576                                 pathSb.append("        \"204\":\n");
1577                                 pathSb.append("          description: successful, action has been enacted but the response does not include an entity\n");
1578                                 pathSb.append("        \"400\":\n");
1579                                 pathSb.append("          description: Bad Request will be returned if headers are missing\n");
1580                                 pathSb.append("        \"404\":\n");
1581                                 pathSb.append("          description: Not Found will be returned if an unknown URL is used\n");
1582                                 */                              
1583                                 pathSb.append("      parameters:\n");
1584                                 //pathSb.append("        - in: path\n");
1585                                 pathSb.append(pathParams); // for nesting
1586                                 if ( !path.endsWith("/relationship") ) {
1587                                         pathSb.append("        - name: resource-version\n");
1588         
1589                                         pathSb.append("          in: query\n");
1590                                         pathSb.append("          description: resource-version for concurrency\n");
1591                                         pathSb.append("          required: true\n");
1592                                         pathSb.append("          type: string\n");
1593                                 }
1594                                 /*
1595                                 if ( queryParams != null ) {
1596                                         pathSb.append(queryParams);
1597                                 }
1598                                 */
1599                         }
1600                         
1601                 }
1602                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1603                         return null;
1604                 }
1605         
1606                 definitionsSb.append("  " + xmlRootElementName + ":\n");
1607                 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1608                 if ( edges.size() > 0 ) {
1609                         StringBuffer sbEdge = new StringBuffer();
1610                         sbEdge.append("      ###### Related Nodes\n");
1611                         for (EdgeDescription ed : edges) { 
1612                                 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1613                                     sbEdge.append("      - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1614                                     sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1615                                     sbEdge.append("\n");
1616                                 }
1617                         }
1618                         for (EdgeDescription ed : edges) { 
1619                                 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1620                                     sbEdge.append("      - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1621                                     sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1622                                     sbEdge.append("\n");
1623                                 }
1624                         }
1625                         validEdges = sbEdge.toString();
1626                 }
1627
1628                 String deleteRule = getDeleteRules(xmlRootElementName);
1629                 // Handle description property.  Might have a description OR valid edges OR both OR neither.
1630                 // Only put a description: tag if there is at least one.
1631                 if (pathDescriptionProperty != null || deleteRule != null || validEdges != null) {
1632                         definitionsSb.append("    description: |\n");      
1633
1634                         if ( pathDescriptionProperty != null ) 
1635                                 definitionsSb.append("      " + pathDescriptionProperty + "\n" );
1636                         if (deleteRule != null) 
1637                                 definitionsSb.append("      ###### Default Delete Scope\n      ").append(deleteRule).append("\n");
1638                         if (validEdges != null) 
1639                                 definitionsSb.append(validEdges);
1640                 }
1641                 
1642                 if ( requiredCnt > 0 )
1643                         definitionsSb.append(sbRequired);
1644                 if ( propertyCnt > 0 ) {
1645                         definitionsSb.append("    properties:\n");
1646                         definitionsSb.append(sbProperties);
1647                 }
1648                 generatedJavaType.put(xmlRootElementName, null);
1649                 return null;
1650         }
1651         
1652         public static String generateSwaggerFromOxmFile( File oxmFile )
1653         {
1654
1655                 StringBuffer sb = new StringBuffer();
1656                 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");
1657                 sb.append("  title: Active and Available Inventory REST API\n");
1658                 sb.append("  license:\n    name: Apache 2.0\n    url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1659                 sb.append("  contact:\n    name:\n    url:\n    email:\n");
1660                 sb.append("host:\nbasePath: /aai/" + apiVersion + "\n");
1661                 sb.append("schemes:\n  - https\npaths:\n");
1662                 /*
1663                 sb.append("responses:\n");
1664                 sb.append("  \"200\":\n");
1665                 sb.append("    description: successful operation\n");
1666                 sb.append("  \"404\":\n");
1667                 sb.append("    description: resource was not found\n");
1668                 sb.append("  \"400\":\n");
1669                 sb.append("    description: bad request\n");
1670                 */
1671                 try {
1672                         versionedClass = getEdgeRulesClass();
1673                     File initialFile = new File("src/main/resources/dbedgerules/DbEdgeRules_" + apiVersion + ".json");
1674                     InputStream is = new FileInputStream(initialFile);
1675
1676                         Scanner scanner = new Scanner(is);
1677                         jsonEdges = scanner.useDelimiter("\\Z").next();
1678                         scanner.close();
1679                         is.close();
1680                         
1681                     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1682                     dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1683                     DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1684                     Document doc = dBuilder.parse(oxmFile);
1685
1686                     NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1687                         Element bindingElement;
1688                         NodeList javaTypesNodes;
1689                         Element javaTypesElement;
1690                         
1691                         Element javaTypeElement;
1692
1693                         
1694                         if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1695                                 System.out.println( "missing <binding-nodes> in " + oxmFile );
1696                                 return null;
1697                         }           
1698                         
1699                         bindingElement = (Element) bindingsNodes.item(0);
1700                         javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1701                         if ( javaTypesNodes.getLength() < 1 ) {
1702                                 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1703                                 return null;
1704                         }
1705                         javaTypesElement = (Element) javaTypesNodes.item(0);
1706
1707                         javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1708                         if ( javaTypeNodes.getLength() < 1 ) {
1709                                 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1710                                 return null;
1711                         }
1712
1713                         String javaTypeName;
1714                         String attrName, attrValue;
1715                         Attr attr;
1716                         StringBuffer pathSb = new StringBuffer();
1717                         
1718                         StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1719                         
1720                         for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1721                                 javaTypeElement = (Element) javaTypeNodes.item(i);
1722                                 NamedNodeMap attributes = javaTypeElement.getAttributes();
1723                                 javaTypeName = null;
1724                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
1725                             attr = (Attr) attributes.item(j);
1726                             attrName = attr.getNodeName();
1727                             attrValue = attr.getNodeValue();
1728                             if ( attrName.equals("name"))
1729                                 javaTypeName = attrValue;
1730                                 }
1731                                 if ( javaTypeName == null ) {
1732                                         System.out.println( "<java-type> has no name attribute in " + oxmFile );
1733                                         return null;
1734                                 }
1735                                 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1736                                         
1737                                         //generatedJavaType.put(javaTypeName, null);
1738                                         //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1739
1740                                         processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1741                                                         definitionsSb, null, null, null, null, null, null, null);
1742                                 }
1743                         }
1744                         sb.append(pathSb);
1745                         //System.out.println( "definitions block\n" + definitionsSb.toString());
1746                         sb.append(definitionsSb.toString());
1747                         //sb.append(definitionsSb);
1748                                 
1749                 } catch (Exception e) {
1750                         e.printStackTrace();
1751                         return null;
1752                 }
1753                 //System.out.println("generated " + sb.toString());
1754                 return sb.toString();
1755         }
1756         
1757         private static NodeList locateXmlProperties(Element element) {
1758                 XPathExpression expr;
1759                 NodeList result = null;
1760                 try {
1761                         expr = xpath.compile("xml-properties");
1762                         if (expr != null) {
1763                                 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1764                                 if (nodeset != null) {
1765                                         NodeList nodes = (NodeList) nodeset;
1766                                         if (nodes != null && nodes.getLength() > 0) {
1767                                                 Element xmlProperty = (Element)nodes.item(0);
1768                                                 result = xmlProperty.getElementsByTagName("xml-property");
1769                                         }
1770                                 }
1771                         }
1772                 } catch (XPathExpressionException e) {
1773                         e.printStackTrace();
1774                 }
1775                 return result;
1776                 
1777         }
1778 }