c9405264ce1fab9f7032ca8c6bcac440a93494fc
[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.openecomp";
671                 if ( useAnnotationsInXsd ) {
672                         sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/" 
673                                 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
674                                                 + "\n"
675                                                 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" + 
676                                                 "    jaxb:version=\"2.1\" \r\n" + 
677                                                 "    xmlns:annox=\"http://annox.dev.java.net\" \r\n" + 
678                                                 "    jaxb:extensionBindingPrefixes=\"annox\">\n\n");
679                 } else {
680                         sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/" 
681                                         + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n");
682                 }
683
684                 try {
685                     
686                     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
687                     dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
688                     DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
689                     Document doc = dBuilder.parse(oxmFile);
690
691                     NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
692                         Element bindingElement;
693                         NodeList javaTypesNodes;
694                         Element javaTypesElement;
695                         
696                         Element javaTypeElement;
697
698                         
699                         if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
700                                 System.out.println( "missing <binding-nodes> in " + oxmFile );
701                                 return null;
702                         }           
703                         
704                         bindingElement = (Element) bindingsNodes.item(0);
705                         javaTypesNodes = bindingElement.getElementsByTagName("java-types");
706                         if ( javaTypesNodes.getLength() < 1 ) {
707                                 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
708                                 return null;
709                         }
710                         javaTypesElement = (Element) javaTypesNodes.item(0);
711                         javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
712                         if ( javaTypeNodes.getLength() < 1 ) {
713                                 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
714                                 return null;
715                         }
716
717                         String javaTypeName;
718                         String attrName, attrValue;
719                         Attr attr;
720                         for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
721                                 javaTypeElement = (Element) javaTypeNodes.item(i);
722                                 NamedNodeMap attributes = javaTypeElement.getAttributes();
723                                 javaTypeName = null;
724                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
725                             attr = (Attr) attributes.item(j);
726                             attrName = attr.getNodeName();
727                             attrValue = attr.getNodeValue();
728                             if ( attrName.equals("name"))
729                                 javaTypeName = attrValue;
730                                 }
731                                 if ( javaTypeName == null ) {
732                                         System.out.println( "<java-type> has no name attribute in " + oxmFile );
733                                         return null;
734                                 }
735                                 if ("Nodes".equals(javaTypeName)) {
736                                         //System.out.println("skipping Nodes entry (temporary feature)");
737                                         continue;
738                                 }
739                                 if ( !generatedJavaType.containsKey(javaTypeName) ) {
740                                         generatedJavaType.put(javaTypeName, null);
741                                         sb.append(processJavaTypeElement( javaTypeName, javaTypeElement ));
742                                 }
743                         }
744                                 
745                 } catch (Exception e) {
746                         e.printStackTrace();
747                         return null;
748                 }
749                 sb.append("</xs:schema>\n");
750                 return sb.toString();
751         }
752
753         private static boolean isStandardType( String elementType )
754         {
755                 switch ( elementType ) {
756                 case "java.lang.String":
757                 case "java.lang.Long":
758                 case "java.lang.Integer":
759                 case"java.lang.Boolean":
760                         return true;
761                 }
762                 return false;
763         }
764         
765         private static Vector<String> getIndexedProps( String attrValue )
766         {
767                 if ( attrValue == null )
768                         return null;
769                 StringTokenizer st = new StringTokenizer( attrValue, ",");
770                 if ( st.countTokens() ==  0 )
771                         return null;
772                 Vector<String> result = new Vector<String>();
773                 while ( st.hasMoreTokens()) {
774                         result.add(st.nextToken());
775                 }
776                 return result;
777         }
778         
779         /**
780          * Guaranteed to at least return non null but empty collection of edge descriptions
781          * @param nodeName name of the vertex whose edge relationships to return
782          * @return collection of node neighbors based on DbEdgeRules
783         **/
784         private static Collection<EdgeDescription> getEdgeRulesFromJson( String path, boolean skipMatch ) 
785         {
786
787                 ArrayList<EdgeDescription> result = new ArrayList<>();
788                 Iterator<Map<String, Object>> edgeRulesIterator;
789                 try {
790
791                         GenerateXsd x = new GenerateXsd();
792                         
793                         List<Map<String, Object>> inEdges = JsonPath.parse(jsonEdges).read(path);
794                         
795                         edgeRulesIterator = inEdges.iterator();
796                         Map<String, Object> edgeMap;
797                         String fromNode;
798                         String toNode;
799                         String ruleKey;
800                         String direction;
801                         String multiplicity;
802                         String isParent;
803                         String hasDelTarget;
804                         EdgeDescription edgeDes;
805                         
806                         while( edgeRulesIterator.hasNext() ){
807                                 edgeMap = edgeRulesIterator.next();
808                                 fromNode = (String)edgeMap.get("from");
809                                 toNode = (String)edgeMap.get("to");
810                                 if ( skipMatch ) { 
811                                         if ( fromNode.equals(toNode)) {
812                                                 continue;
813                                         }
814                                 }
815                                 edgeDes = x.new EdgeDescription();
816                                 edgeDes.setRuleKey(fromNode + "|" + toNode);
817                                 direction = (String)edgeMap.get("direction");
818                                 edgeDes.setDirection(direction);
819                                 multiplicity = (String)edgeMap.get("multiplicity");
820                                 edgeDes.setMultiplicity(multiplicity);
821                                 isParent = (String)edgeMap.get(EdgeProperty.CONTAINS.toString());
822                                 if ( "${direction}".equals(isParent))  {
823                                         edgeDes.setType(LineageType.PARENT);
824                                 } else {
825                                         edgeDes.setType(LineageType.UNRELATED);
826                                 }
827                                 hasDelTarget = (String)edgeMap.get(EdgeProperty.DELETE_OTHER_V.toString());
828                                 edgeDes.setHasDelTarget(hasDelTarget);
829                                 result.add(edgeDes);
830                                 
831                         }
832                 } catch (Exception ex) {
833                         ex.printStackTrace();
834                 }
835                 return result;
836                 
837         }
838         
839         /**
840          * Guaranteed to at least return non null but empty collection of edge descriptions
841          * @param nodeName name of the vertex whose edge relationships to return
842          * @return collection of node neighbors based on DbEdgeRules
843         **/
844         private static Collection<EdgeDescription> getEdgeRules( String nodeName ) 
845         {               
846                 String fromRulesPath = "$['rules'][?(@['from']=='" + nodeName + "')]";
847                 String toRulesPath = "$['rules'][?(@['to']=='" + nodeName + "')]";
848                 Collection<EdgeDescription> fromEdges = getEdgeRulesFromJson( fromRulesPath, false );
849                 Collection<EdgeDescription> edges = getEdgeRulesFromJson( toRulesPath, true );
850                 edges.addAll(fromEdges);
851                 return edges;
852         }
853         
854         public static String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
855                         StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
856                         String getItemName, StringBuffer pathParams, String queryParams, String validEdges) {
857                 
858                 String xmlRootElementName = null;
859
860                 //Map<String, String> addJavaType = new HashMap<String, String>();
861                 String useTag = null;
862                 String useOpId = null;
863                 
864                 if ( tag != null ) {
865                         switch ( tag ) {
866                         case "Network":
867                         case "ServiceDesignAndCreation":
868                         case "Business":
869                         case "LicenseManagement":
870                         case "CloudInfrastructure":
871                         case "ExternalSystem":
872                                 break;
873                         default:
874                                 return null;
875                         }
876                 }
877                 /*
878                 if ( path == null )
879                         System.out.println( "processJavaTypeElementSwagger called with null path for javaTypeName " + javaTypeName);
880                 */
881                 /*
882                 if ( path == null || !(path.contains("cloud-infrastructure")))
883                         switch ( javaTypeName) {
884                          case "Inventory":
885                                 useTag = null;
886                                 break;
887                                 
888                         case "CloudInfrastructure":
889                         case "Search":
890                         case "Actions":
891                         case "ServiceDesignAndCreation":
892                         case "LicenseManagement":
893                         case "Network":
894                                 if ( tag == null )
895                                         useTag = javaTypeName;
896
897                                 break;
898                         default:
899                                         return null;
900                                         
901                         }
902                 */
903                 
904                 if ( !javaTypeName.equals("Inventory") ) {
905                         if ( javaTypeName.equals("AaiInternal"))
906                                 return null;
907                         if ( opId == null )
908                                 useOpId = javaTypeName;
909                         else
910                                 useOpId = opId + javaTypeName;
911                         if ( tag == null )
912                                 useTag = javaTypeName;
913                 }
914                 
915                 /*
916                 if ( javaTypeName.equals("GenericVnf"))
917                         System.out.println( "Processing " + javaTypeName);
918                 else if ( javaTypeName.equals("Service"))
919                                 System.out.println( "Processing " + javaTypeName);
920                 else if ( javaTypeName.equals("SitePair"))
921                         System.out.println( "Processing " + javaTypeName);
922                 */
923                 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
924
925                 if ( parentNodes.getLength() == 0 ) {
926                         //System.out.println( "no java-attributes for java-type " + javaTypeName);
927                         return "";
928
929                 }
930                 
931                 NamedNodeMap attributes;
932                 
933                 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
934                 Element valElement = (Element) valNodes.item(0);
935                 attributes = valElement.getAttributes();
936                 for ( int i = 0; i < attributes.getLength(); ++i ) {
937             Attr attr = (Attr) attributes.item(i);
938             String attrName = attr.getNodeName();
939
940             String attrValue = attr.getNodeValue();
941             //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
942             if ( attrName.equals("name"))
943                 xmlRootElementName = attrValue;
944                 }
945                 /*
946                 if ( xmlRootElementName.equals("oam-networks"))
947                         System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
948                 */
949                 //already processed
950                 /*
951                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
952                         return null;
953                 }
954                 */
955                 NodeList childNodes;
956                 Element childElement;
957                 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
958                 Element xmlPropElement;
959                 String pathDescriptionProperty = null;
960                 
961                 
962                 Vector<String> indexedProps = null;
963                 
964                 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
965                 if ( path != null && path.equals("/network/generic-vnfs"))
966                         System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
967                 */
968                 if ( xmlPropNodes.getLength() > 0 ) {
969
970                         for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
971                                 xmlPropElement = (Element)xmlPropNodes.item(i);
972                                 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
973                                         continue;
974                                 childNodes = xmlPropElement.getElementsByTagName("xml-property");
975                                 
976                                 if ( childNodes.getLength() > 0 ) {
977                                         for ( int j = 0; j < childNodes.getLength(); ++j ) {
978                                                 childElement = (Element)childNodes.item(j);
979                                                 // get name
980                                                 int useValue = VALUE_NONE;
981                                                 attributes = childElement.getAttributes();
982                                                 for ( int k = 0; k < attributes.getLength(); ++k ) {
983                                                         Attr attr = (Attr) attributes.item(k);
984                                                         String attrName = attr.getNodeName();
985                                                         String attrValue = attr.getNodeValue();
986                                                         if ( attrName == null || attrValue == null )
987                                                                 continue;
988                                                         if ( attrName.equals("name") && attrValue.equals("description")) {
989                                                                 useValue = VALUE_DESCRIPTION;
990                                                         }
991                                                         if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
992                                                                 pathDescriptionProperty = attrValue;
993                                                                 //break;
994                                                                 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
995                                                         }
996                                                         if ( attrValue.equals("indexedProps")) {
997                                                                 useValue = VALUE_INDEXED_PROPS;
998                                                         }
999                                                         if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
1000                                                                 indexedProps = getIndexedProps( attrValue );
1001                                                         }
1002                                                 }
1003                                         }
1004                                 }
1005                         }
1006                 }
1007                 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
1008
1009                 /*
1010                 if ( javaTypeName.equals("RelationshipList")) {
1011                         System.out.println( "Skipping " + javaTypeName);
1012                         generatedJavaType.put(javaTypeName, null);
1013                         return "";
1014                 }
1015                 */
1016                 
1017                 Element parentElement = (Element)parentNodes.item(0);
1018                 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
1019
1020         
1021                 String attrDescription = null;
1022
1023                 Element xmlElementElement;
1024                 String addType = null;
1025                 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1026                 String elementName = null;
1027                 StringBuffer sbParameters = new StringBuffer();
1028
1029                 StringBuffer sbRequired = new StringBuffer();
1030                 int requiredCnt = 0;
1031                 int propertyCnt = 0;
1032                 StringBuffer sbProperties = new StringBuffer();
1033                 StringBuffer sbIndexedParams = new StringBuffer();
1034
1035                 
1036                 StringTokenizer st;
1037                 if ( xmlRootElementName.equals("inventory"))
1038                         path = "";
1039                 else if ( path == null )
1040                         //path = "/aai/" + apiVersion;
1041                         path = "/" + xmlRootElementName;
1042                 else
1043                         path += "/" + xmlRootElementName;
1044                 st = new StringTokenizer(path, "/");
1045                 /*
1046                 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1047                         System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1048                 */
1049                 boolean genPath = false;
1050                 /*
1051                 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1052                         System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1053                 */
1054                 if ( st.countTokens() > 1 && getItemName == null ) {
1055                         if ( appliedPaths.containsKey(path)) 
1056                                 return null;
1057                         appliedPaths.put(path, null);
1058                         genPath = true;
1059                         if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1060                                 genPath = false;
1061                         }
1062                         if ( path.endsWith("/relationship-list")) {
1063                                 genPath = false;
1064                         }
1065                                         
1066                 }
1067                 
1068                 Vector<String> addTypeV = null;
1069                 if (  xmlElementNodes.getLength() > 0 ) {
1070                         
1071                         for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1072                                 xmlElementElement = (Element)xmlElementNodes.item(i);
1073                                 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1074                                         continue;
1075                                 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1076                                 if ( childNodes.getLength() > 0 ) {
1077                                         childElement = (Element)childNodes.item(0);
1078                                         // get name
1079                                         attributes = childElement.getAttributes();
1080                                         for ( int k = 0; k < attributes.getLength(); ++k ) {
1081                                                 Attr attr = (Attr) attributes.item(k);
1082                                                 String attrName = attr.getNodeName();
1083                                                 String attrValue = attr.getNodeValue();
1084                                                 if ( attrName.equals("name")) {
1085                                                         xmlElementWrapper = attrValue;
1086                                                         //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1087                                                 }
1088                                         }
1089
1090                                 }
1091                                 */
1092                                 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1093                                 attrDescription = null;
1094                                 if ( valNodes.getLength() > 0 ) {
1095                                         for ( int j = 0; j < valNodes.getLength(); ++j ) {
1096                                                 valElement = (Element)valNodes.item(j);
1097                                                 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1098                                                         continue;
1099                                                 childNodes = valElement.getElementsByTagName("xml-property");
1100                                                 if ( childNodes.getLength() > 0 ) {
1101                                                         childElement = (Element)childNodes.item(0);
1102                                                         // get name
1103                                                         attributes = childElement.getAttributes();
1104                                                         attrDescription = null;
1105                                                         boolean useValue = false;
1106                                                         for ( int k = 0; k < attributes.getLength(); ++k ) {
1107                                                                 Attr attr = (Attr) attributes.item(k);
1108                                                                 String attrName = attr.getNodeName();
1109                                                                 String attrValue = attr.getNodeValue();
1110                                                                 if ( attrName.equals("name") && attrValue.equals("description")) {
1111                                                                         useValue = true;
1112                                                                 }
1113                                                                 if ( useValue && attrName.equals("value")) {
1114                                                                         attrDescription = attrValue;
1115                                                                         //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1116                                                                 }
1117                                                         }
1118
1119                                                 }
1120                                         }
1121                                 }
1122                                 
1123                                 attributes = xmlElementElement.getAttributes();
1124                                 addTypeV = null; // vector of 1
1125                                 addType = null;
1126                                 
1127                                 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1128                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
1129                             Attr attr = (Attr) attributes.item(j);
1130                             String attrName = attr.getNodeName();
1131         
1132                             String attrValue = attr.getNodeValue();
1133                             //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1134                             if ( attrName.equals("name")) {
1135                                 elementName = attrValue;
1136
1137                             }
1138                             if ( attrName.equals("type") && getItemName == null ) {
1139                                 elementType = attrValue;
1140                                 if ( attrValue.contains(apiVersionFmt) ) {
1141                                         addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1142                                         if ( addTypeV == null ) 
1143                                                 addTypeV = new Vector<String>();
1144                                         addTypeV.add(addType);
1145                                 }
1146                                         
1147                             }
1148                             if ( attrName.equals("xml-key")) {
1149                                 elementIsKey = attrValue;
1150                                 path += "/{" + elementName + "}";
1151                             }
1152                             if ( attrName.equals("required")) {
1153                                 elementIsRequired = attrValue;
1154                             }
1155                             if ( attrName.equals("container-type")) {
1156                                 elementContainerType = attrValue;
1157                             }   
1158                                 }
1159                 if ( getItemName != null ) {
1160                         if ( getItemName.equals("array") ) {
1161                                 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1162                                         //System.out.println( " returning array " + elementName );
1163                                         return elementName;
1164                                 }
1165                                 
1166                         } else { // not an array check
1167                                 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1168                                         //System.out.println( " returning object " + elementName );
1169                                         return elementName;
1170                                 }
1171                                 
1172                         }
1173                         //System.out.println( " returning null" );
1174                         return null;
1175                 }
1176                                 if ( elementIsRequired != null ) {
1177                                         if ( requiredCnt == 0 )
1178                                                 sbRequired.append("    required:\n");
1179                                         ++requiredCnt;
1180                                         if ( addTypeV != null ) {
1181                                                 for ( int k = 0; k < addTypeV.size(); ++i ) {
1182                                                         sbRequired.append("    - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1183                                                 }
1184                                         } else 
1185                                                 sbRequired.append("    - " + elementName + "\n");
1186
1187                                 }
1188
1189                                 if (  elementIsKey != null )  {
1190                                                                                 sbParameters.append(("        - name: " + elementName + "\n"));
1191                                         sbParameters.append(("          in: path\n"));
1192                                         if ( attrDescription != null && attrDescription.length() > 0 )
1193                                                 sbParameters.append(("          description: " + attrDescription + "\n"));
1194                                         sbParameters.append(("          required: true\n"));
1195                                         if ( elementType.equals("java.lang.String"))
1196                                                 sbParameters.append("          type: string\n");
1197                                         if ( elementType.equals("java.lang.Long")) {
1198                                                 sbParameters.append("          type: integer\n");
1199                                                 sbParameters.append("          format: int64\n");
1200                                         }
1201                                         if ( elementType.equals("java.lang.Integer")) {
1202                                                 sbParameters.append("          type: integer\n");
1203                                                 sbParameters.append("          format: int32\n");
1204                                         }
1205                                         if ( elementType.equals("java.lang.Boolean"))
1206                                                 sbParameters.append("          type: boolean\n");
1207
1208
1209                                 } else if (  indexedProps != null
1210                                                 && indexedProps.contains(elementName ) ) {
1211                                         sbIndexedParams.append(("        - name: " + elementName + "\n"));
1212                                         sbIndexedParams.append(("          in: query\n"));
1213                                         if ( attrDescription != null && attrDescription.length() > 0 )
1214                                                 sbIndexedParams.append(("          description: " + attrDescription + "\n"));
1215                                         sbIndexedParams.append(("          required: false\n"));
1216                                         if ( elementType.equals("java.lang.String"))
1217                                                 sbIndexedParams.append("          type: string\n");
1218                                         if ( elementType.equals("java.lang.Long")) {
1219                                                 sbIndexedParams.append("          type: integer\n");
1220                                                 sbIndexedParams.append("          format: int64\n");
1221                                         }
1222                                         if ( elementType.equals("java.lang.Integer")) {
1223                                                 sbIndexedParams.append("          type: integer\n");
1224                                                 sbIndexedParams.append("          format: int32\n");
1225                                         }
1226                                         if ( elementType.equals("java.lang.Boolean"))
1227                                                 sbIndexedParams.append("          type: boolean\n");
1228                                 }
1229
1230                         /*
1231                         if ( elementName != null && elementName.equals("inventory-item"))
1232                                 System.out.println( "processing inventory-item elementName");
1233                         */
1234                 
1235                         if ( isStandardType(elementType)) {
1236                                 sbProperties.append("      " + elementName + ":\n");
1237                                 ++propertyCnt;
1238                                 sbProperties.append("        type: ");
1239
1240                                 if ( elementType.equals("java.lang.String"))
1241                                         sbProperties.append("string\n");
1242                                 else if ( elementType.equals("java.lang.Long")) {
1243                                         sbProperties.append("integer\n");
1244                                         sbProperties.append("        format: int64\n");
1245                                 }
1246                                 else if ( elementType.equals("java.lang.Integer")){
1247                                         sbProperties.append("integer\n");
1248                                         sbProperties.append("        format: int32\n");
1249                                 }
1250                                 else if ( elementType.equals("java.lang.Boolean"))
1251                                         sbProperties.append("boolean\n");
1252                                 if ( attrDescription != null && attrDescription.length() > 0 )
1253                                         sbProperties.append("        description: " + attrDescription + "\n");
1254                         }
1255
1256                         //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1257
1258                 if ( addTypeV !=  null ) {
1259                         StringBuffer newPathParams = null;
1260                         if ( pathParams != null  ) {
1261                                 newPathParams = new StringBuffer();
1262                                 newPathParams.append(pathParams);
1263                         }
1264                     if ( sbParameters.toString().length() > 0 ) {
1265                                         if ( newPathParams == null )
1266                                                 newPathParams = new StringBuffer();
1267                                         newPathParams.append(sbParameters);
1268                     }
1269                     String newQueryParams = null;
1270                     if ( sbIndexedParams.toString().length() > 0 ) {
1271                         if ( queryParams == null )
1272                                 newQueryParams = sbIndexedParams.toString();
1273                         else
1274                                 newQueryParams = queryParams + sbIndexedParams.toString();
1275                     } else {
1276                         newQueryParams = queryParams;
1277                     }
1278                         for ( int k = 0; k < addTypeV.size(); ++k ) {
1279                                 addType = addTypeV.elementAt(k);
1280                 
1281                                 if ( opId == null || !opId.contains(addType)) {
1282                                         processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1283                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, null,
1284                                                 newPathParams, newQueryParams, validEdges);
1285                                 }
1286                                 // need item name of array
1287                                         String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1288                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
1289                                                                 "array", null, null, null );
1290                                         
1291                                         if ( itemName != null ) {
1292                                                 if ( addType.equals("AaiInternal") ) {
1293                                                         //System.out.println( "addType AaiInternal, skip properties");
1294                                                         
1295                                                 } else if ( getItemName == null) {
1296                                                         ++propertyCnt;
1297                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1298                                                         sbProperties.append("        type: array\n        items:\n");
1299                                                         sbProperties.append("          $ref: \"#/definitions/" + itemName + "\"\n");
1300                                                         if ( attrDescription != null && attrDescription.length() > 0 )
1301                                                                 sbProperties.append("        description: " + attrDescription + "\n");
1302                                                 }
1303                                         } else {
1304                                                 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1305                                                         pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, "other" );
1306                                                 if ( itemName != null ) {
1307                                                 */
1308                                                 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1309                                                         // need properties for getXmlRootElementName(addType)
1310                                                 newPathParams = null;
1311                                                 if ( pathParams != null  ) {
1312                                                         newPathParams = new StringBuffer();
1313                                                         newPathParams.append(pathParams);
1314                                                 }
1315                                             if ( sbParameters.toString().length() > 0 ) {
1316                                                                 if ( newPathParams == null )
1317                                                                         newPathParams = new StringBuffer();
1318                                                                 newPathParams.append(sbParameters);
1319                                             }
1320                                             newQueryParams = null;
1321                                             if ( sbIndexedParams.toString().length() > 0 ) {
1322                                                 if ( queryParams == null )
1323                                                         newQueryParams = sbIndexedParams.toString();
1324                                                 else
1325                                                         newQueryParams = queryParams + sbIndexedParams.toString();
1326                                             } else {
1327                                                 newQueryParams = queryParams;
1328                                             }
1329                                                         processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType), 
1330                                                                 pathSb, definitionsSb, path,  tag == null ? useTag : tag, useOpId, 
1331                                                                                 null, newPathParams, newQueryParams, validEdges );
1332                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1333                                                         sbProperties.append("        type: array\n        items:          \n");
1334                                                         sbProperties.append("          $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1335                                                 } else {
1336                                                         sbProperties.append("      " + getXmlRootElementName(addType) + ":\n");
1337                                                         sbProperties.append("        type: object\n");
1338                                                         sbProperties.append("        $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1339                                                 }
1340                                                 if ( attrDescription != null && attrDescription.length() > 0 )
1341                                                         sbProperties.append("        description: " + attrDescription + "\n");
1342                                                 ++propertyCnt;
1343                                                 /*}
1344                                                 else {
1345                                                         System.out.println(" unable to define swagger object for " + addType);
1346                                                 }
1347                                                 */
1348                                         }
1349                                         //if ( getItemName == null) looking for missing properties
1350                                                 //generatedJavaType.put(addType, null);
1351                         }
1352                 }
1353                 }
1354         }       
1355                 if ( genPath ) {
1356                         /*
1357                         if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1358                                 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1359                         */
1360
1361                         if ( !path.endsWith("/relationship") ) {
1362                                 pathSb.append("  " + path + ":\n" );
1363                                 pathSb.append("    get:\n");
1364                                 pathSb.append("      tags:\n");
1365                                 pathSb.append("        - " + tag + "\n");
1366                                 pathSb.append("      summary: returns " + xmlRootElementName + "\n");
1367         
1368                                 pathSb.append("      description: returns " + xmlRootElementName + "\n");
1369                                 pathSb.append("      operationId: get" + useOpId + "\n");
1370                                 pathSb.append("      produces:\n");
1371                                 pathSb.append("        - application/json\n");
1372                                 pathSb.append("        - application/xml\n");
1373                                 
1374                                 pathSb.append("      responses:\n");
1375                                 pathSb.append("        \"200\":\n");
1376                                 pathSb.append("          description: successful operation\n");
1377                                 pathSb.append("          schema:\n");
1378                                 pathSb.append("              $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1379                                 pathSb.append("        \"default\":\n");
1380                                 pathSb.append("          " + responsesUrl);
1381                                 /*
1382                                 pathSb.append("        \"200\":\n");
1383                                 pathSb.append("          description: successful operation\n");
1384                                 pathSb.append("          schema:\n");
1385                                 pathSb.append("              $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1386                                 pathSb.append("        \"404\":\n");
1387                                 pathSb.append("          description: resource was not found\n");
1388                                 pathSb.append("        \"400\":\n");
1389                                 pathSb.append("          description: bad request\n");
1390                                 */
1391                                 if ( path.indexOf('{') > 0 ) {
1392                                 
1393                             if ( sbParameters.toString().length() > 0 ) {
1394                                                 if ( pathParams == null )
1395                                                         pathParams = new StringBuffer();
1396                                                 pathParams.append(sbParameters);
1397                             }
1398                                         if ( pathParams != null) {
1399                                                 pathSb.append("      parameters:\n");
1400                                                 pathSb.append(pathParams);
1401                                         } else
1402                                                 System.out.println( "null pathParams for " + useOpId);
1403                                         if ( sbIndexedParams.toString().length() > 0 ) {
1404                                                 if ( queryParams == null )
1405                                                         queryParams = sbIndexedParams.toString();
1406                                                 else
1407                                                         queryParams = queryParams + sbIndexedParams.toString();
1408                                         }
1409                                         if ( queryParams != null ) {
1410                                                 if ( pathParams == null ) {
1411                                                         pathSb.append("      parameters:\n");
1412                                                 }
1413                                                 pathSb.append(queryParams);
1414                                         }
1415                                 }
1416                         }
1417                         boolean skipPutDelete = false; // no put or delete for "all" 
1418                         if ( !path.endsWith("/relationship") ) {                                
1419                                 if ( !path.endsWith("}") ){
1420                                                 skipPutDelete = true;
1421                                 }
1422                                         
1423                         }
1424                         if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1425                                 // add PUT
1426                                 if ( path.endsWith("/relationship") ) {
1427                                         pathSb.append("  " + path + ":\n" );
1428                                 } 
1429                                 pathSb.append("    put:\n");
1430                                 pathSb.append("      tags:\n");
1431                                 pathSb.append("        - " + tag + "\n");
1432
1433                                 if ( path.endsWith("/relationship") ) {
1434                                         pathSb.append("      summary: see node definition for valid relationships\n");
1435                                 } else {
1436                                         pathSb.append("      summary: create or update an existing " + xmlRootElementName + "\n");
1437                                         pathSb.append("      description: create or update an existing " + xmlRootElementName + "\n");
1438                                 }
1439                                 pathSb.append("      operationId: createOrUpdate" + useOpId + "\n");
1440                                 pathSb.append("      consumes:\n");
1441                                 pathSb.append("        - application/json\n");
1442                                 pathSb.append("        - application/xml\n");                                   
1443                                 pathSb.append("      produces:\n");
1444                                 pathSb.append("        - application/json\n");
1445                                 pathSb.append("        - application/xml\n");
1446                                 pathSb.append("      responses:\n");
1447                                 pathSb.append("        \"default\":\n");
1448                                 pathSb.append("          " + responsesUrl);
1449                                 /*
1450                                 pathSb.append("      responses:\n");
1451                                 pathSb.append("        \"200\":\n");
1452                                 pathSb.append("          description: existing resource has been modified and there is a response buffer\n");                                   
1453                                 pathSb.append("        \"201\":\n");
1454                                 pathSb.append("          description: new resource is created\n");      
1455                                 pathSb.append("        \"202\":\n");
1456                                 pathSb.append("          description: action requested but may have taken other actions as well, which are returned in the response payload\n");                                
1457                                 pathSb.append("        \"204\":\n");
1458                                 pathSb.append("          description: existing resource has been modified and there is no response buffer\n");                          
1459                                 pathSb.append("        \"400\":\n");
1460                                 pathSb.append("          description: Bad Request will be returned if headers are missing\n");
1461                                 pathSb.append("        \"404\":\n");
1462                                 pathSb.append("          description: Not Found will be returned if an unknown URL is used\n");
1463                                 */                                              
1464                                 pathSb.append("      parameters:\n");
1465                                 //pathSb.append("        - in: path\n");
1466                                 pathSb.append(pathParams); // for nesting
1467                                 pathSb.append("        - name: body\n");
1468                                 pathSb.append("          in: body\n");
1469                                 pathSb.append("          description: " + xmlRootElementName + " object that needs to be created or updated\n");
1470                                 pathSb.append("          required: true\n");
1471                                 pathSb.append("          schema:\n");
1472                                 pathSb.append("            $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1473                                 /*
1474                                 if ( queryParams != null ) {
1475                                         pathSb.append(queryParams);
1476                                 }
1477                                 */
1478                                 // add DELETE
1479                                 pathSb.append("    delete:\n");
1480                                 pathSb.append("      tags:\n");
1481                                 pathSb.append("        - " + tag + "\n");
1482                                 pathSb.append("      summary: delete an existing " + xmlRootElementName + "\n");
1483                                 
1484                                 pathSb.append("      description: delete an existing " + xmlRootElementName + "\n");
1485                                 
1486                                 pathSb.append("      operationId: delete" + useOpId + "\n");
1487                                 pathSb.append("      consumes:\n");
1488                                 pathSb.append("        - application/json\n");
1489                                 pathSb.append("        - application/xml\n");                                   
1490                                 pathSb.append("      produces:\n");
1491                                 pathSb.append("        - application/json\n");
1492                                 pathSb.append("        - application/xml\n");
1493                                 pathSb.append("      responses:\n");
1494                                 pathSb.append("        \"default\":\n");
1495                                 pathSb.append("          " + responsesUrl);
1496                                 /*
1497                                 pathSb.append("      responses:\n");
1498                                 pathSb.append("        \"200\":\n");
1499                                 pathSb.append("          description: successful, the response includes an entity describing the status\n");
1500                                 pathSb.append("        \"204\":\n");
1501                                 pathSb.append("          description: successful, action has been enacted but the response does not include an entity\n");
1502                                 pathSb.append("        \"400\":\n");
1503                                 pathSb.append("          description: Bad Request will be returned if headers are missing\n");
1504                                 pathSb.append("        \"404\":\n");
1505                                 pathSb.append("          description: Not Found will be returned if an unknown URL is used\n");
1506                                 */                              
1507                                 pathSb.append("      parameters:\n");
1508                                 //pathSb.append("        - in: path\n");
1509                                 pathSb.append(pathParams); // for nesting
1510                                 if ( !path.endsWith("/relationship") ) {
1511                                         pathSb.append("        - name: resource-version\n");
1512         
1513                                         pathSb.append("          in: query\n");
1514                                         pathSb.append("          description: resource-version for concurrency\n");
1515                                         pathSb.append("          required: true\n");
1516                                         pathSb.append("          type: string\n");
1517                                 }
1518                                 /*
1519                                 if ( queryParams != null ) {
1520                                         pathSb.append(queryParams);
1521                                 }
1522                                 */
1523                         }
1524                         
1525                 }
1526                 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1527                         return null;
1528                 }
1529         
1530                 definitionsSb.append("  " + xmlRootElementName + ":\n");
1531                 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1532                 if ( edges.size() > 0 ) {
1533                         StringBuffer sbEdge = new StringBuffer();
1534                         sbEdge.append("      ###### Related Nodes\n");
1535                         for (EdgeDescription ed : edges) { 
1536                                 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1537                                     sbEdge.append("      - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1538                                     sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1539                                     sbEdge.append("\n");
1540                                 }
1541                         }
1542                         for (EdgeDescription ed : edges) { 
1543                                 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1544                                     sbEdge.append("      - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1545                                     sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1546                                     sbEdge.append("\n");
1547                                 }
1548                         }
1549                         validEdges = sbEdge.toString();
1550                 }
1551
1552                 // Handle description property.  Might have a description OR valid edges OR both OR neither.
1553                 // Only put a description: tag if there is at least one.
1554                 if (pathDescriptionProperty != null || validEdges != null) {
1555                         definitionsSb.append("    description: |\n");      
1556
1557                         if ( pathDescriptionProperty != null ) 
1558                                 definitionsSb.append("      " + pathDescriptionProperty + "\n" );
1559                         if (validEdges != null)
1560                                 definitionsSb.append(validEdges);
1561                 }
1562                 
1563                 if ( requiredCnt > 0 )
1564                         definitionsSb.append(sbRequired);
1565                 if ( propertyCnt > 0 ) {
1566                         definitionsSb.append("    properties:\n");
1567                         definitionsSb.append(sbProperties);
1568                 }
1569                 generatedJavaType.put(xmlRootElementName, null);
1570                 return null;
1571         }
1572         
1573         public static String generateSwaggerFromOxmFile( File oxmFile )
1574         {
1575
1576                 StringBuffer sb = new StringBuffer();
1577                 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");
1578                 sb.append("  title: Active and Available Inventory REST API\n");
1579                 sb.append("  license:\n    name: Apache 2.0\n    url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1580                 sb.append("  contact:\n    name:\n    url:\n    email:\n");
1581                 sb.append("host:\nbasePath: /aai/" + apiVersion + "\n");
1582                 sb.append("schemes:\n  - https\npaths:\n");
1583                 /*
1584                 sb.append("responses:\n");
1585                 sb.append("  \"200\":\n");
1586                 sb.append("    description: successful operation\n");
1587                 sb.append("  \"404\":\n");
1588                 sb.append("    description: resource was not found\n");
1589                 sb.append("  \"400\":\n");
1590                 sb.append("    description: bad request\n");
1591                 */
1592                 try {
1593                     File initialFile = new File("src/main/resources/dbedgerules/DbEdgeRules_" + apiVersion + ".json");
1594                     InputStream is = new FileInputStream(initialFile);
1595
1596                         Scanner scanner = new Scanner(is);
1597                         jsonEdges = scanner.useDelimiter("\\Z").next();
1598                         scanner.close();
1599                         is.close();
1600                         
1601                     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1602                     dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1603                     DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1604                     Document doc = dBuilder.parse(oxmFile);
1605
1606                     NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1607                         Element bindingElement;
1608                         NodeList javaTypesNodes;
1609                         Element javaTypesElement;
1610                         
1611                         Element javaTypeElement;
1612
1613                         
1614                         if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1615                                 System.out.println( "missing <binding-nodes> in " + oxmFile );
1616                                 return null;
1617                         }           
1618                         
1619                         bindingElement = (Element) bindingsNodes.item(0);
1620                         javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1621                         if ( javaTypesNodes.getLength() < 1 ) {
1622                                 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1623                                 return null;
1624                         }
1625                         javaTypesElement = (Element) javaTypesNodes.item(0);
1626
1627                         javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1628                         if ( javaTypeNodes.getLength() < 1 ) {
1629                                 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1630                                 return null;
1631                         }
1632
1633                         String javaTypeName;
1634                         String attrName, attrValue;
1635                         Attr attr;
1636                         StringBuffer pathSb = new StringBuffer();
1637                         
1638                         StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1639                         
1640                         for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1641                                 javaTypeElement = (Element) javaTypeNodes.item(i);
1642                                 NamedNodeMap attributes = javaTypeElement.getAttributes();
1643                                 javaTypeName = null;
1644                                 for ( int j = 0; j < attributes.getLength(); ++j ) {
1645                             attr = (Attr) attributes.item(j);
1646                             attrName = attr.getNodeName();
1647                             attrValue = attr.getNodeValue();
1648                             if ( attrName.equals("name"))
1649                                 javaTypeName = attrValue;
1650                                 }
1651                                 if ( javaTypeName == null ) {
1652                                         System.out.println( "<java-type> has no name attribute in " + oxmFile );
1653                                         return null;
1654                                 }
1655                                 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1656                                         
1657                                         //generatedJavaType.put(javaTypeName, null);
1658                                         //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1659
1660                                         processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1661                                                         definitionsSb, null, null, null, null, null, null, null);
1662                                 }
1663                         }
1664                         sb.append(pathSb);
1665                         //System.out.println( "definitions block\n" + definitionsSb.toString());
1666                         sb.append(definitionsSb.toString());
1667                         //sb.append(definitionsSb);
1668                                 
1669                 } catch (Exception e) {
1670                         e.printStackTrace();
1671                         return null;
1672                 }
1673                 //System.out.println("generated " + sb.toString());
1674                 return sb.toString();
1675         }
1676         
1677         private static NodeList locateXmlProperties(Element element) {
1678                 XPathExpression expr;
1679                 NodeList result = null;
1680                 try {
1681                         expr = xpath.compile("xml-properties");
1682                         if (expr != null) {
1683                                 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1684                                 if (nodeset != null) {
1685                                         NodeList nodes = (NodeList) nodeset;
1686                                         if (nodes.getLength() > 0) {
1687                                                 Element xmlProperty = (Element)nodes.item(0);
1688                                                 result = xmlProperty.getElementsByTagName("xml-property");
1689                                         }
1690                                 }
1691                         }
1692                 } catch (XPathExpressionException e) {
1693                         e.printStackTrace();
1694                 }
1695                 return result;
1696                 
1697         }
1698 }