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