2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.aai.util;
23 import java.io.BufferedWriter;
25 import java.io.FileWriter;
26 import java.io.IOException;
27 import java.lang.reflect.Field;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.Collections;
34 import java.util.List;
36 import java.util.StringTokenizer;
37 import java.util.Vector;
39 import javax.xml.XMLConstants;
40 import javax.xml.bind.JAXBContext;
41 import javax.xml.bind.JAXBException;
42 import javax.xml.bind.SchemaOutputResolver;
43 import javax.xml.parsers.DocumentBuilder;
44 import javax.xml.parsers.DocumentBuilderFactory;
45 import javax.xml.transform.Result;
46 import javax.xml.transform.stream.StreamResult;
47 import javax.xml.xpath.XPath;
48 import javax.xml.xpath.XPathConstants;
49 import javax.xml.xpath.XPathExpression;
50 import javax.xml.xpath.XPathExpressionException;
51 import javax.xml.xpath.XPathFactory;
53 import org.w3c.dom.Attr;
54 import org.w3c.dom.Document;
55 import org.w3c.dom.Element;
56 import org.w3c.dom.NamedNodeMap;
57 import org.w3c.dom.NodeList;
59 import org.openecomp.aai.dbmodel.DbEdgeRules;
60 import org.openecomp.aai.db.props.AAIProperties;
61 import org.openecomp.aai.introspection.Version;
62 import com.google.common.base.Joiner;
63 import com.google.common.collect.Multimap;
66 public class GenerateXsd {
67 static String apiVersion = null;
68 static String apiVersionFmt = null;
69 static boolean useAnnotationsInXsd = false;
70 static String responsesUrl = null;
71 static String responsesLabel = null;
72 //static Map<String, String> generatedJavaType = new HashMap<String, String>();
73 //static Map<String, String> appliedPaths = new HashMap<String, String>();
74 static Map<String, String> generatedJavaType;
75 static Map<String, String> appliedPaths;
76 static NodeList javaTypeNodes;
77 static Class<?> versionedClass;
80 public static final int VALUE_NONE = 0;
81 public static final int VALUE_DESCRIPTION = 1;
82 public static final int VALUE_INDEXED_PROPS = 2;
84 private static final String generateTypeXSD = "xsd";
85 private static final String generateTypeYAML = "yaml";
87 private static final String root = "../aai-schema/src/main/resources";
88 private static final String xsd_dir = root + "/aai_schema";
89 private static final String yaml_dir = root + "/aai_swagger_yaml";
91 private static int annotationsStartVersion = 9; // minimum version to support annotations in xsd
92 private static int swaggerSupportStartsVersion = 7; // minimum version to support swagger documentation
94 private static XPath xpath = XPathFactory.newInstance().newXPath();
97 private enum LineageType {
98 PARENT, CHILD, UNRELATED;
100 private class EdgeDescription {
102 private String ruleKey;
103 private LineageType type = LineageType.UNRELATED;
104 private String direction;
105 private String multiplicity;
106 private boolean hasDelTarget = false;
108 public String getRuleKey() {
111 public String getMultiplicity() {
114 public String getDirection() {
117 public void setRuleKey(String val) {
120 public void setType(LineageType val) {
123 public void setDirection(String val) {
124 this.direction = val;
126 public void setMultiplicity(String val) {
127 this.multiplicity=val;
129 public void setHasDelTarget(String val) {
130 hasDelTarget = Boolean.parseBoolean(val);
133 public String getRelationshipDescription(String fromTo, String otherNodeName) {
137 if ("FROM".equals(fromTo)) {
138 if ("OUT".equals(direction)) {
139 if (LineageType.PARENT == type) {
140 result = " (is composed of "+otherNodeName;
144 if (LineageType.CHILD == type) {
145 result = " (comprises "+otherNodeName;
147 else if (LineageType.PARENT == type) {
148 result = " (comprises "+otherNodeName;
152 if ("OUT".equals(direction)) {
153 if (LineageType.PARENT == type) {
154 result = " (comprises "+otherNodeName;
157 if (LineageType.PARENT == type) {
158 result = " (is composed of "+otherNodeName;
163 // if (type != null) {
164 // if (LineageType.PARENT.equals(type) && "FROM".equals(fromTo)) {
165 // if ("OUT".equals(direction)) {
166 // result = " (is composed of "+otherNodeName;
168 // result = " (comprises "+otherNodeName;
171 // result = " (comprises " + otherNodeName;
172 // // if (!(multiplicity.startsWith("One"))) {
173 // // System.err.println("Surprised to find multiplicity "+multiplicity+" with comprises for "+ruleKey);
177 if ("TO".equals(fromTo)) {
178 if (result.length() == 0) result = result + " (";
179 else result = result + ", ";
181 result = result + mapMultiplicity(fromTo);
182 if (hasDelTarget) result = result + ", will delete target node";
185 if (result.length() > 0) result = result + ")";
190 private String mapMultiplicity(String fromTo) {
191 String result = multiplicity;
192 // Below logic works if an IN switches multiplicity, which it doesn't today.
193 // if ("TO".equals(fromTo)) {
194 // if (direction.equals("OUT")) {
195 // result = multiplicity;
197 // result = switchMultiplicity(multiplicity);
200 // if (direction.equals("OUT")) {
201 // result = multiplicity;
203 // result = switchMultiplicity(multiplicity);
209 // private String switchMultiplicity(String val) throws IllegalArgumentException
211 // String result = null;
218 // result = "One2Many";
221 // result = "Many2One";
224 // throw new IllegalArgumentException("Multiplicity cannot be "+val);
226 // System.out.println("Switched Multiplicity from "+val+" to "+result);
231 private static boolean validVersion(String versionToGen) {
233 if ("ALL".equalsIgnoreCase(versionToGen)) {
237 for (Version v : Version.values()) {
238 if (v.name().equals(versionToGen)) {
246 private static boolean versionUsesAnnotations( String version) {
247 if (new Integer(version.substring(1)).intValue() >= annotationsStartVersion ) {
253 private static boolean versionSupportsSwagger( String version) {
254 if (new Integer(version.substring(1)).intValue() >= swaggerSupportStartsVersion ) {
260 public static void main(String[] args) throws IOException {
261 String versionToGen = System.getProperty("gen_version").toLowerCase();
262 String fileTypeToGen = System.getProperty("gen_type").toLowerCase();
263 if ( fileTypeToGen == null ) {
264 fileTypeToGen = generateTypeXSD;
267 if ( !fileTypeToGen.equals( generateTypeXSD ) && !fileTypeToGen.equals( generateTypeYAML )) {
268 System.err.println("Invalid gen_type passed. " + fileTypeToGen);
273 if ( versionToGen == null ) {
274 System.err.println("Version is required, ie v<n> or ALL.");
278 responsesUrl = System.getProperty("yamlresponses_url");
279 String responsesLabel = System.getProperty("yamlresponses_label");
280 List<Version> versionsToGen = new ArrayList<>();
283 if (!"ALL".equalsIgnoreCase(versionToGen) && !versionToGen.matches("v\\d+") && !validVersion(versionToGen)) {
284 System.err.println("Invalid version passed. " + versionToGen);
288 if ("ALL".equalsIgnoreCase(versionToGen)) {
289 versionsToGen = Arrays.asList(Version.values());
290 Collections.sort(versionsToGen);
291 Collections.reverse(versionsToGen);
293 versionsToGen.add(Version.valueOf(versionToGen));
296 if ( fileTypeToGen.equals(generateTypeYAML) ) {
297 if ( responsesUrl == null || responsesUrl.length() < 1
298 || responsesLabel == null || responsesLabel.length() < 1 ) {
299 System.err.println("generating swagger yaml file requires yamlresponses_url and yamlresponses_label properties" );
302 responsesUrl = "description: "+ responsesLabel+ "(" + responsesUrl + ").\n";
304 String oxmPath = root + "/oxm/";
310 for (Version v : versionsToGen) {
311 apiVersion = v.toString();
312 System.out.println("Generating " + apiVersion + " " + fileTypeToGen);
313 File oxm_file = new File(oxmPath + "aai_oxm_" + apiVersion + ".xml");
314 apiVersionFmt = "." + apiVersion + ".";
315 generatedJavaType = new HashMap<String, String>();
316 appliedPaths = new HashMap<String, String>();
317 if ( fileTypeToGen.equals(generateTypeXSD) ) {
318 useAnnotationsInXsd = versionUsesAnnotations(apiVersion);
319 outfileName = xsd_dir + "/aai_schema_" + apiVersion + "." + generateTypeXSD;
320 fileContent = processOxmFile( oxm_file);
321 } else if ( versionSupportsSwagger(apiVersion )) {
322 outfileName = yaml_dir + "/aai_swagger_" + apiVersion + "." + generateTypeYAML;
323 fileContent = generateSwaggerFromOxmFile( oxm_file);
327 outfile = new File(outfileName);
328 File parentDir = outfile.getParentFile();
329 if(! parentDir.exists())
333 outfile.createNewFile();
334 } catch (IOException e) {
335 System.out.println( "Exception creating output file " + outfileName);
339 FileWriter fw = new FileWriter(outfile.getAbsoluteFile());
340 BufferedWriter bw = new BufferedWriter(fw);
341 bw.write(fileContent);
344 } catch ( IOException e) {
345 System.out.println( "Exception writing output file " + outfileName);
348 System.out.println( "GeneratedXSD successful, saved in " + outfileName);
354 public static String processJavaTypeElement( String javaTypeName, Element javaTypeElement) {
356 String xmlRootElementName = null;
358 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
359 StringBuffer sb = new StringBuffer();
360 if ( parentNodes.getLength() == 0 ) {
361 //System.out.println( "no java-attributes for java-type " + javaTypeName);
366 NamedNodeMap attributes;
368 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
369 Element valElement = (Element) valNodes.item(0);
370 attributes = valElement.getAttributes();
371 for ( int i = 0; i < attributes.getLength(); ++i ) {
372 Attr attr = (Attr) attributes.item(i);
373 String attrName = attr.getNodeName();
375 String attrValue = attr.getNodeValue();
376 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
377 if ( attrName.equals("name"))
378 xmlRootElementName = attrValue;
381 if ( javaTypeName.equals("RelationshipList")) {
382 System.out.println( "Skipping " + javaTypeName);
383 generatedJavaType.put(javaTypeName, null);
388 Element parentElement = (Element)parentNodes.item(0);
389 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
391 Element childElement;
392 String xmlElementWrapper;
394 Element xmlElementElement;
396 String elementName, elementType, elementIsKey, elementIsRequired, elementContainerType;
397 StringBuffer sb1 = new StringBuffer();
398 if ( xmlElementNodes.getLength() > 0 ) {
399 sb1.append(" <xs:element name=\"" + xmlRootElementName + "\">\n");
400 sb1.append(" <xs:complexType>\n");
401 NodeList properties = GenerateXsd.locateXmlProperties(javaTypeElement);
402 if (properties != null && useAnnotationsInXsd) {
403 //System.out.println("properties found for: " + xmlRootElementName);
404 sb1.append(" <xs:annotation>\r\n");
405 insertAnnotation(properties, false, "class", sb1, " ");
407 sb1.append(" </xs:annotation>\r\n");
409 System.out.println("no properties found for: " + xmlRootElementName);
411 sb1.append(" <xs:sequence>\n");
412 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
414 xmlElementElement = (Element)xmlElementNodes.item(i);
415 childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
417 xmlElementWrapper = null;
418 if ( childNodes.getLength() > 0 ) {
419 childElement = (Element)childNodes.item(0);
421 attributes = childElement.getAttributes();
422 for ( int k = 0; k < attributes.getLength(); ++k ) {
423 Attr attr = (Attr) attributes.item(k);
424 String attrName = attr.getNodeName();
425 String attrValue = attr.getNodeValue();
426 if ( attrName.equals("name")) {
427 xmlElementWrapper = attrValue;
428 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
433 attributes = xmlElementElement.getAttributes();
437 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
438 for ( int j = 0; j < attributes.getLength(); ++j ) {
439 Attr attr = (Attr) attributes.item(j);
440 String attrName = attr.getNodeName();
442 String attrValue = attr.getNodeValue();
443 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
444 if ( attrName.equals("name")) {
445 elementName = attrValue;
447 if ( attrName.equals("type")) {
448 elementType = attrValue;
449 if ( attrValue.contains(apiVersionFmt) ) {
450 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
451 if ( !generatedJavaType.containsKey(addType) ) {
452 generatedJavaType.put(addType, attrValue);
453 sb.append(processJavaTypeElement( addType, getJavaTypeElement(addType) ));
459 if ( attrName.equals("xml-key")) {
460 elementIsKey = attrValue;
462 if ( attrName.equals("required")) {
463 elementIsRequired = attrValue;
465 if ( attrName.equals("container-type")) {
466 elementContainerType = attrValue;
470 if ( xmlElementWrapper != null ) {
471 sb1.append(" <xs:element name=\"" + xmlElementWrapper +"\"");
472 if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) {
473 sb1.append(" minOccurs=\"0\"");
476 sb1.append(" <xs:complexType>\n");
477 properties = GenerateXsd.locateXmlProperties(javaTypeElement);
478 if (properties != null && useAnnotationsInXsd) {
479 sb1.append(" <xs:annotation>\r\n");
480 insertAnnotation(properties, false, "class", sb1, " ");
481 sb1.append(" </xs:annotation>\r\n");
483 System.out.println("no properties found for: " + xmlElementWrapper);
485 sb1.append(" <xs:sequence>\n");
488 if ("Nodes".equals(addType)) {
489 //System.out.println ("Skipping nodes, temporary testing");
492 if ( addType != null ) {
493 //sb1.append(" <xs:element ref=\"tns:" + elementName +"\"");
494 sb1.append(" <xs:element ref=\"tns:" + getXmlRootElementName(addType) +"\"");
496 sb1.append(" <xs:element name=\"" + elementName +"\"");
498 if ( elementType.equals("java.lang.String"))
499 sb1.append(" type=\"xs:string\"");
500 //if ( elementType.equals("java.lang.String"))
501 //sb1.append(" type=\"xs:string\"");
502 if ( elementType.equals("java.lang.Long"))
503 sb1.append(" type=\"xs:unsignedInt\"");
504 if ( elementType.equals("java.lang.Integer"))
505 sb1.append(" type=\"xs:int\"");
506 if ( elementType.equals("java.lang.Boolean"))
507 sb1.append(" type=\"xs:boolean\"");
508 //if ( elementIsRequired != null && elementIsRequired.equals("true")||addType != null) {
509 if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) {
510 sb1.append(" minOccurs=\"0\"");
512 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
513 sb1.append(" maxOccurs=\"unbounded\"");
515 properties = GenerateXsd.locateXmlProperties(xmlElementElement);
516 if (properties != null || elementIsKey != null) {
518 if ( useAnnotationsInXsd ) {
519 sb1.append(" <xs:annotation>\r\n");
520 insertAnnotation(properties, elementIsKey != null, "field", sb1, " ");
521 sb1.append(" </xs:annotation>\r\n");
523 if (xmlElementWrapper== null) {
524 sb1.append(" </xs:element>\n");
529 if ( xmlElementWrapper != null ) {
530 sb1.append(" </xs:sequence>\n");
531 sb1.append(" </xs:complexType>\n");
532 sb1.append(" </xs:element>\n");
536 if ( xmlRootElementName.equals("notify") ||
537 xmlRootElementName.equals("relationship") ||
538 xmlRootElementName.equals("relationship-data") ||
539 xmlRootElementName.equals("related-to-property") )
541 sb1.append(" <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n");
543 sb1.append(" </xs:sequence>\n");
544 sb1.append(" </xs:complexType>\n");
545 sb1.append(" </xs:element>\n");
548 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
549 Element valElement = (Element) valNodes.item(0);
550 attributes = valElement.getAttributes();
551 for ( int i = 0; i < attributes.getLength(); ++i ) {
552 Attr attr = (Attr) attributes.item(i);
553 String attrName = attr.getNodeName();
555 String attrValue = attr.getNodeValue();
556 System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
557 if ( attrValue.equals("name"))
558 xmlRootElementName = attrValue;
562 if ( xmlElementNodes.getLength() < 1 ) {
563 sb.append(" <xs:element name=\"" + xmlRootElementName + "\">\n");
564 sb.append(" <xs:complexType>\n");
565 sb.append(" <xs:sequence/>\n");
566 sb.append(" </xs:complexType>\n");
567 sb.append(" </xs:element>\n");
568 generatedJavaType.put(javaTypeName, null);
569 return sb.toString();
574 return sb.toString();
577 private static void insertAnnotation(NodeList items, boolean isKey, String target, StringBuffer sb1, String indentation) {
578 if (items != null || isKey) {
579 List<String> metadata = new ArrayList<>();
585 metadata.add("isKey=true");
588 for (int i = 0; i < items.getLength(); i++) {
589 item = (Element)items.item(i);
590 name = item.getAttribute("name");
591 value = item.getAttribute("value");
592 if (name.equals("abstract")) {
594 } else if (name.equals("extends")) {
595 name = "extendsFrom";
597 metadata.add(name + "=\"" + value.replaceAll("&", "&") + "\"");
598 //System.out.println("property name: " + name);
603 indentation + " <xs:appinfo>\r\n" +
604 indentation + " <annox:annotate target=\""+target+"\">@org.openecomp.aai.annotations.Metadata(" + Joiner.on(",").join(metadata) + ")</annox:annotate>\r\n" +
605 indentation + " </xs:appinfo>\r\n");
610 private static Element getJavaTypeElement( String javaTypeName )
613 String attrName, attrValue;
615 Element javaTypeElement;
616 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
617 javaTypeElement = (Element) javaTypeNodes.item(i);
618 NamedNodeMap attributes = javaTypeElement.getAttributes();
619 for ( int j = 0; j < attributes.getLength(); ++j ) {
620 attr = (Attr) attributes.item(j);
621 attrName = attr.getNodeName();
622 attrValue = attr.getNodeValue();
623 if ( attrName.equals("name") && attrValue.equals(javaTypeName))
624 return javaTypeElement;
627 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
628 return (Element) null;
631 private static Element getJavaTypeElementSwagger( String javaTypeName )
634 String attrName, attrValue;
636 Element javaTypeElement;
637 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
638 javaTypeElement = (Element) javaTypeNodes.item(i);
639 NamedNodeMap attributes = javaTypeElement.getAttributes();
640 for ( int j = 0; j < attributes.getLength(); ++j ) {
641 attr = (Attr) attributes.item(j);
642 attrName = attr.getNodeName();
643 attrValue = attr.getNodeValue();
644 if ( attrName.equals("name") && attrValue.equals(javaTypeName))
645 return javaTypeElement;
648 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
649 return (Element) null;
651 private static String getXmlRootElementName( String javaTypeName )
654 String attrName, attrValue;
656 Element javaTypeElement;
657 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
658 javaTypeElement = (Element) javaTypeNodes.item(i);
659 NamedNodeMap attributes = javaTypeElement.getAttributes();
660 for ( int j = 0; j < attributes.getLength(); ++j ) {
661 attr = (Attr) attributes.item(j);
662 attrName = attr.getNodeName();
663 attrValue = attr.getNodeValue();
664 if ( attrName.equals("name") && attrValue.equals(javaTypeName)) {
665 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
666 Element valElement = (Element) valNodes.item(0);
667 attributes = valElement.getAttributes();
668 for ( int k = 0; k < attributes.getLength(); ++k ) {
669 attr = (Attr) attributes.item(k);
670 attrName = attr.getNodeName();
672 attrValue = attr.getNodeValue();
673 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
674 if ( attrName.equals("name"))
680 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
685 public static String processOxmFile( File oxmFile )
687 StringBuffer sb = new StringBuffer();
688 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
689 String namespace = "org.openecomp";
690 if ( useAnnotationsInXsd ) {
691 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
692 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
694 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" +
695 " jaxb:version=\"2.1\" \r\n" +
696 " xmlns:annox=\"http://annox.dev.java.net\" \r\n" +
697 " jaxb:extensionBindingPrefixes=\"annox\">\n\n");
699 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
700 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n");
705 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
706 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
707 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
708 Document doc = dBuilder.parse(oxmFile);
710 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
711 Element bindingElement;
712 NodeList javaTypesNodes;
713 Element javaTypesElement;
715 Element javaTypeElement;
718 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
719 System.out.println( "missing <binding-nodes> in " + oxmFile );
723 bindingElement = (Element) bindingsNodes.item(0);
724 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
725 if ( javaTypesNodes.getLength() < 1 ) {
726 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
729 javaTypesElement = (Element) javaTypesNodes.item(0);
730 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
731 if ( javaTypeNodes.getLength() < 1 ) {
732 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
737 String attrName, attrValue;
739 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
740 javaTypeElement = (Element) javaTypeNodes.item(i);
741 NamedNodeMap attributes = javaTypeElement.getAttributes();
743 for ( int j = 0; j < attributes.getLength(); ++j ) {
744 attr = (Attr) attributes.item(j);
745 attrName = attr.getNodeName();
746 attrValue = attr.getNodeValue();
747 if ( attrName.equals("name"))
748 javaTypeName = attrValue;
750 if ( javaTypeName == null ) {
751 System.out.println( "<java-type> has no name attribute in " + oxmFile );
754 if ("Nodes".equals(javaTypeName)) {
755 //System.out.println("skipping Nodes entry (temporary feature)");
758 if ( !generatedJavaType.containsKey(javaTypeName) ) {
759 generatedJavaType.put(javaTypeName, null);
760 sb.append(processJavaTypeElement( javaTypeName, javaTypeElement ));
764 } catch (Exception e) {
768 sb.append("</xs:schema>\n");
769 return sb.toString();
772 private static boolean isStandardType( String elementType )
774 switch ( elementType ) {
775 case "java.lang.String":
776 case "java.lang.Long":
777 case "java.lang.Integer":
778 case"java.lang.Boolean":
784 private static Vector<String> getIndexedProps( String attrValue )
786 if ( attrValue == null )
788 StringTokenizer st = new StringTokenizer( attrValue, ",");
789 if ( st.countTokens() == 0 )
791 Vector<String> result = new Vector<String>();
792 while ( st.hasMoreTokens()) {
793 result.add(st.nextToken());
798 private static Class<?> getEdgeRulesClass() throws ClassNotFoundException {
799 Class<?> result = null;
801 // If a class matching the apiVersion exists, we are generating documentation for a prior release
802 // Otherwise, we're generated documentation for the current release.
804 result = Class.forName("org.openecomp.aai.dbmodel." + apiVersion +".gen.DbEdgeRules");
805 } catch (ClassNotFoundException ex) {
806 result = Class.forName("org.openecomp.aai.dbmodel.DbEdgeRules");
812 * Guaranteed to at least return non null but empty collection of edge descriptions
813 * @param nodeName name of the vertex whose edge relationships to return
814 * @return collection of node neighbors based on DbEdgeRules
816 private static Collection<EdgeDescription> getEdgeRules( String nodeName )
819 ArrayList<EdgeDescription> result = new ArrayList<>();
820 Iterator<String> edgeRulesIterator;
824 Field mapfield = versionedClass.getField("EdgeRules");
825 Object map = mapfield.get(null);
826 if (map instanceof Multimap<?,?>) {
827 edgeRulesIterator = ((Multimap<String,String>) map).keySet().iterator();
829 throw new NoSuchFieldException ("Didn't get back the multimap field expected");
831 GenerateXsd x = new GenerateXsd();
833 while( edgeRulesIterator.hasNext() ){
834 String ruleKey = edgeRulesIterator.next();
835 if ( ruleKey.startsWith(nodeName + "|" ) ||
836 ruleKey.endsWith("|" + nodeName)) {
837 Collection <String> edRuleColl = DbEdgeRules.EdgeRules.get(ruleKey);
838 Iterator <String> ruleItr = edRuleColl.iterator();
839 while( ruleItr.hasNext() ){
840 EdgeDescription edgeDes = x.new EdgeDescription();
841 edgeDes.setRuleKey(ruleKey);
842 String fullRuleString = ruleItr.next();
843 String[] toks = fullRuleString.split(",");
845 if (toks.length > 1) {
846 edgeDes.setDirection(toks[1]);
848 if (toks.length > 2) {
849 edgeDes.setMultiplicity(toks[2]);
851 if (toks.length > 3) {
852 if (toks[3].equals("true"))
853 edgeDes.setType(LineageType.PARENT);
854 else if (toks[3].equals("parent"))
855 edgeDes.setType(LineageType.PARENT);
856 else if (toks[3].equals("child"))
857 edgeDes.setType(LineageType.CHILD);
859 edgeDes.setType(LineageType.UNRELATED);
861 if (toks.length > 5) {
862 edgeDes.setHasDelTarget(toks[5]);;
866 //System.out.println( "nodeName " + nodeName + " ruleKey " + ruleKey + " ruleString " + fullRuleString);
867 //result.add(ruleKey + "-" + fullRuleString);
872 } catch (Exception ex) {
873 ex.printStackTrace();
879 * Finds the default delete scope from DBEdgeRules
880 * @param nodeName name of vertex whose delete scope to return
881 * @return default delete scope of the input nodeName, null if none.
883 private static String getDeleteRules( String nodeName )
885 String result = null;
886 Iterator<String> delRulesIterator;
890 Field mapfield = versionedClass.getField("DefaultDeleteScope");
891 Object map = mapfield.get(null);
892 if (map instanceof Multimap<?,?>) {
893 delRulesIterator = ((Multimap<String,String>) map).keySet().iterator();
895 throw new NoSuchFieldException ("Didn't get back the multimap field expected");
898 while( delRulesIterator.hasNext() ){
899 String ruleKey = delRulesIterator.next();
900 if ( ruleKey.equals(nodeName)) {
901 Collection <String> deRuleColl = DbEdgeRules.DefaultDeleteScope.get(ruleKey);
902 Iterator <String> ruleItr = deRuleColl.iterator();
903 if( ruleItr.hasNext() ){
904 result = ruleItr.next();
909 } catch (Exception ex) {
910 ex.printStackTrace();
915 public static String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
916 StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
917 String getItemName, StringBuffer pathParams, String queryParams, String validEdges) {
919 String xmlRootElementName = null;
921 //Map<String, String> addJavaType = new HashMap<String, String>();
922 String useTag = null;
923 String useOpId = null;
928 case "ServiceDesignAndCreation":
930 case "LicenseManagement":
931 case "CloudInfrastructure":
939 System.out.println( "processJavaTypeElementSwagger called with null path for javaTypeName " + javaTypeName);
942 if ( path == null || !(path.contains("cloud-infrastructure")))
943 switch ( javaTypeName) {
948 case "CloudInfrastructure":
951 case "ServiceDesignAndCreation":
952 case "LicenseManagement":
955 useTag = javaTypeName;
964 if ( !javaTypeName.equals("Inventory") ) {
965 if ( javaTypeName.equals("AaiInternal"))
968 useOpId = javaTypeName;
970 useOpId = opId + javaTypeName;
972 useTag = javaTypeName;
976 if ( javaTypeName.equals("GenericVnf"))
977 System.out.println( "Processing " + javaTypeName);
978 else if ( javaTypeName.equals("Service"))
979 System.out.println( "Processing " + javaTypeName);
980 else if ( javaTypeName.equals("SitePair"))
981 System.out.println( "Processing " + javaTypeName);
983 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
985 if ( parentNodes.getLength() == 0 ) {
986 //System.out.println( "no java-attributes for java-type " + javaTypeName);
991 NamedNodeMap attributes;
993 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
994 Element valElement = (Element) valNodes.item(0);
995 attributes = valElement.getAttributes();
996 for ( int i = 0; i < attributes.getLength(); ++i ) {
997 Attr attr = (Attr) attributes.item(i);
998 String attrName = attr.getNodeName();
1000 String attrValue = attr.getNodeValue();
1001 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
1002 if ( attrName.equals("name"))
1003 xmlRootElementName = attrValue;
1006 if ( xmlRootElementName.equals("oam-networks"))
1007 System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
1011 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1015 NodeList childNodes;
1016 Element childElement;
1017 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
1018 Element xmlPropElement;
1019 String pathDescriptionProperty = null;
1022 Vector<String> indexedProps = null;
1024 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
1025 if ( path != null && path.equals("/network/generic-vnfs"))
1026 System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
1028 if ( xmlPropNodes.getLength() > 0 ) {
1030 for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
1031 xmlPropElement = (Element)xmlPropNodes.item(i);
1032 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
1034 childNodes = xmlPropElement.getElementsByTagName("xml-property");
1036 if ( childNodes.getLength() > 0 ) {
1037 for ( int j = 0; j < childNodes.getLength(); ++j ) {
1038 childElement = (Element)childNodes.item(j);
1040 int useValue = VALUE_NONE;
1041 attributes = childElement.getAttributes();
1042 for ( int k = 0; k < attributes.getLength(); ++k ) {
1043 Attr attr = (Attr) attributes.item(k);
1044 String attrName = attr.getNodeName();
1045 String attrValue = attr.getNodeValue();
1046 if ( attrName == null || attrValue == null )
1048 if ( attrName.equals("name") && attrValue.equals("description")) {
1049 useValue = VALUE_DESCRIPTION;
1051 if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
1052 pathDescriptionProperty = attrValue;
1054 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1056 if ( attrValue.equals("indexedProps")) {
1057 useValue = VALUE_INDEXED_PROPS;
1059 if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
1060 indexedProps = getIndexedProps( attrValue );
1067 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
1070 if ( javaTypeName.equals("RelationshipList")) {
1071 System.out.println( "Skipping " + javaTypeName);
1072 generatedJavaType.put(javaTypeName, null);
1077 Element parentElement = (Element)parentNodes.item(0);
1078 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
1081 String attrDescription = null;
1083 Element xmlElementElement;
1084 String addType = null;
1085 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1086 String elementName = null;
1087 StringBuffer sbParameters = new StringBuffer();
1089 StringBuffer sbRequired = new StringBuffer();
1090 int requiredCnt = 0;
1091 int propertyCnt = 0;
1092 StringBuffer sbProperties = new StringBuffer();
1093 StringBuffer sbIndexedParams = new StringBuffer();
1097 if ( xmlRootElementName.equals("inventory"))
1099 else if ( path == null )
1100 //path = "/aai/" + apiVersion;
1101 path = "/" + xmlRootElementName;
1103 path += "/" + xmlRootElementName;
1104 st = new StringTokenizer(path, "/");
1106 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1107 System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1109 boolean genPath = false;
1111 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1112 System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1114 if ( st.countTokens() > 1 && getItemName == null ) {
1115 if ( appliedPaths.containsKey(path))
1117 appliedPaths.put(path, null);
1119 if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1122 if ( path.endsWith("/relationship-list")) {
1128 Vector<String> addTypeV = null;
1129 if ( xmlElementNodes.getLength() > 0 ) {
1131 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1132 xmlElementElement = (Element)xmlElementNodes.item(i);
1133 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1135 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1136 if ( childNodes.getLength() > 0 ) {
1137 childElement = (Element)childNodes.item(0);
1139 attributes = childElement.getAttributes();
1140 for ( int k = 0; k < attributes.getLength(); ++k ) {
1141 Attr attr = (Attr) attributes.item(k);
1142 String attrName = attr.getNodeName();
1143 String attrValue = attr.getNodeValue();
1144 if ( attrName.equals("name")) {
1145 xmlElementWrapper = attrValue;
1146 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1152 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1153 attrDescription = null;
1154 if ( valNodes.getLength() > 0 ) {
1155 for ( int j = 0; j < valNodes.getLength(); ++j ) {
1156 valElement = (Element)valNodes.item(j);
1157 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1159 childNodes = valElement.getElementsByTagName("xml-property");
1160 if ( childNodes.getLength() > 0 ) {
1161 childElement = (Element)childNodes.item(0);
1163 attributes = childElement.getAttributes();
1164 attrDescription = null;
1165 boolean useValue = false;
1166 for ( int k = 0; k < attributes.getLength(); ++k ) {
1167 Attr attr = (Attr) attributes.item(k);
1168 String attrName = attr.getNodeName();
1169 String attrValue = attr.getNodeValue();
1170 if ( attrName.equals("name") && attrValue.equals("description")) {
1173 if ( useValue && attrName.equals("value")) {
1174 attrDescription = attrValue;
1175 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1183 attributes = xmlElementElement.getAttributes();
1184 addTypeV = null; // vector of 1
1187 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1188 for ( int j = 0; j < attributes.getLength(); ++j ) {
1189 Attr attr = (Attr) attributes.item(j);
1190 String attrName = attr.getNodeName();
1192 String attrValue = attr.getNodeValue();
1193 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1194 if ( attrName.equals("name")) {
1195 elementName = attrValue;
1198 if ( attrName.equals("type") && getItemName == null ) {
1199 elementType = attrValue;
1200 if ( attrValue.contains(apiVersionFmt) ) {
1201 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1202 if ( addTypeV == null )
1203 addTypeV = new Vector<String>();
1204 addTypeV.add(addType);
1208 if ( attrName.equals("xml-key")) {
1209 elementIsKey = attrValue;
1210 path += "/{" + elementName + "}";
1212 if ( attrName.equals("required")) {
1213 elementIsRequired = attrValue;
1215 if ( attrName.equals("container-type")) {
1216 elementContainerType = attrValue;
1219 if ( getItemName != null ) {
1220 if ( getItemName.equals("array") ) {
1221 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1222 //System.out.println( " returning array " + elementName );
1226 } else { // not an array check
1227 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1228 //System.out.println( " returning object " + elementName );
1233 //System.out.println( " returning null" );
1236 if ( elementIsRequired != null ) {
1237 if ( requiredCnt == 0 )
1238 sbRequired.append(" required:\n");
1240 if ( addTypeV != null ) {
1241 for ( int k = 0; k < addTypeV.size(); ++i ) {
1242 sbRequired.append(" - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1245 sbRequired.append(" - " + elementName + "\n");
1249 if ( elementIsKey != null ) {
1250 sbParameters.append((" - name: " + elementName + "\n"));
1251 sbParameters.append((" in: path\n"));
1252 if ( attrDescription != null && attrDescription.length() > 0 )
1253 sbParameters.append((" description: " + attrDescription + "\n"));
1254 sbParameters.append((" required: true\n"));
1255 if ( elementType.equals("java.lang.String"))
1256 sbParameters.append(" type: string\n");
1257 if ( elementType.equals("java.lang.Long")) {
1258 sbParameters.append(" type: integer\n");
1259 sbParameters.append(" format: int64\n");
1261 if ( elementType.equals("java.lang.Integer")) {
1262 sbParameters.append(" type: integer\n");
1263 sbParameters.append(" format: int32\n");
1265 if ( elementType.equals("java.lang.Boolean"))
1266 sbParameters.append(" type: boolean\n");
1269 } else if ( indexedProps != null
1270 && indexedProps.contains(elementName ) ) {
1271 sbIndexedParams.append((" - name: " + elementName + "\n"));
1272 sbIndexedParams.append((" in: query\n"));
1273 if ( attrDescription != null && attrDescription.length() > 0 )
1274 sbIndexedParams.append((" description: " + attrDescription + "\n"));
1275 sbIndexedParams.append((" required: false\n"));
1276 if ( elementType.equals("java.lang.String"))
1277 sbIndexedParams.append(" type: string\n");
1278 if ( elementType.equals("java.lang.Long")) {
1279 sbIndexedParams.append(" type: integer\n");
1280 sbIndexedParams.append(" format: int64\n");
1282 if ( elementType.equals("java.lang.Integer")) {
1283 sbIndexedParams.append(" type: integer\n");
1284 sbIndexedParams.append(" format: int32\n");
1286 if ( elementType.equals("java.lang.Boolean"))
1287 sbIndexedParams.append(" type: boolean\n");
1291 if ( elementName != null && elementName.equals("inventory-item"))
1292 System.out.println( "processing inventory-item elementName");
1295 if ( isStandardType(elementType)) {
1296 sbProperties.append(" " + elementName + ":\n");
1298 sbProperties.append(" type: ");
1300 if ( elementType.equals("java.lang.String"))
1301 sbProperties.append("string\n");
1302 else if ( elementType.equals("java.lang.Long")) {
1303 sbProperties.append("integer\n");
1304 sbProperties.append(" format: int64\n");
1306 else if ( elementType.equals("java.lang.Integer")){
1307 sbProperties.append("integer\n");
1308 sbProperties.append(" format: int32\n");
1310 else if ( elementType.equals("java.lang.Boolean"))
1311 sbProperties.append("boolean\n");
1312 if ( attrDescription != null && attrDescription.length() > 0 )
1313 sbProperties.append(" description: " + attrDescription + "\n");
1316 //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1318 if ( addTypeV != null ) {
1319 StringBuffer newPathParams = null;
1320 if ( pathParams != null ) {
1321 newPathParams = new StringBuffer();
1322 newPathParams.append(pathParams);
1324 if ( sbParameters.toString().length() > 0 ) {
1325 if ( newPathParams == null )
1326 newPathParams = new StringBuffer();
1327 newPathParams.append(sbParameters);
1329 String newQueryParams = null;
1330 if ( sbIndexedParams.toString().length() > 0 ) {
1331 if ( queryParams == null )
1332 newQueryParams = sbIndexedParams.toString();
1334 newQueryParams = queryParams + sbIndexedParams.toString();
1336 newQueryParams = queryParams;
1338 for ( int k = 0; k < addTypeV.size(); ++k ) {
1339 addType = addTypeV.elementAt(k);
1341 if ( opId == null || !opId.contains(addType)) {
1342 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1343 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, null,
1344 newPathParams, newQueryParams, validEdges);
1346 // need item name of array
1347 String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1348 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1349 "array", null, null, null );
1351 if ( itemName != null ) {
1352 if ( addType.equals("AaiInternal") ) {
1353 //System.out.println( "addType AaiInternal, skip properties");
1355 } else if ( getItemName == null) {
1357 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1358 sbProperties.append(" type: array\n items:\n");
1359 sbProperties.append(" $ref: \"#/definitions/" + itemName + "\"\n");
1360 if ( attrDescription != null && attrDescription.length() > 0 )
1361 sbProperties.append(" description: " + attrDescription + "\n");
1364 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1365 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, "other" );
1366 if ( itemName != null ) {
1368 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1369 // need properties for getXmlRootElementName(addType)
1370 newPathParams = null;
1371 if ( pathParams != null ) {
1372 newPathParams = new StringBuffer();
1373 newPathParams.append(pathParams);
1375 if ( sbParameters.toString().length() > 0 ) {
1376 if ( newPathParams == null )
1377 newPathParams = new StringBuffer();
1378 newPathParams.append(sbParameters);
1380 newQueryParams = null;
1381 if ( sbIndexedParams.toString().length() > 0 ) {
1382 if ( queryParams == null )
1383 newQueryParams = sbIndexedParams.toString();
1385 newQueryParams = queryParams + sbIndexedParams.toString();
1387 newQueryParams = queryParams;
1389 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1390 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1391 null, newPathParams, newQueryParams, validEdges );
1392 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1393 sbProperties.append(" type: array\n items: \n");
1394 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1396 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1397 sbProperties.append(" type: object\n");
1398 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1400 if ( attrDescription != null && attrDescription.length() > 0 )
1401 sbProperties.append(" description: " + attrDescription + "\n");
1405 System.out.println(" unable to define swagger object for " + addType);
1409 //if ( getItemName == null) looking for missing properties
1410 //generatedJavaType.put(addType, null);
1417 if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1418 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1421 if ( !path.endsWith("/relationship") ) {
1422 pathSb.append(" " + path + ":\n" );
1423 pathSb.append(" get:\n");
1424 pathSb.append(" tags:\n");
1425 pathSb.append(" - " + tag + "\n");
1426 pathSb.append(" summary: returns " + xmlRootElementName + "\n");
1428 pathSb.append(" description: returns " + xmlRootElementName + "\n");
1429 pathSb.append(" operationId: get" + useOpId + "\n");
1430 pathSb.append(" produces:\n");
1431 pathSb.append(" - application/json\n");
1432 pathSb.append(" - application/xml\n");
1434 pathSb.append(" responses:\n");
1435 pathSb.append(" \"200\":\n");
1436 pathSb.append(" description: successful operation\n");
1437 pathSb.append(" schema:\n");
1438 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1439 pathSb.append(" \"default\":\n");
1440 pathSb.append(" " + responsesUrl);
1442 pathSb.append(" \"200\":\n");
1443 pathSb.append(" description: successful operation\n");
1444 pathSb.append(" schema:\n");
1445 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1446 pathSb.append(" \"404\":\n");
1447 pathSb.append(" description: resource was not found\n");
1448 pathSb.append(" \"400\":\n");
1449 pathSb.append(" description: bad request\n");
1451 if ( path.indexOf('{') > 0 ) {
1453 if ( sbParameters.toString().length() > 0 ) {
1454 if ( pathParams == null )
1455 pathParams = new StringBuffer();
1456 pathParams.append(sbParameters);
1458 if ( pathParams != null) {
1459 pathSb.append(" parameters:\n");
1460 pathSb.append(pathParams);
1462 System.out.println( "null pathParams for " + useOpId);
1463 if ( sbIndexedParams.toString().length() > 0 ) {
1464 if ( queryParams == null )
1465 queryParams = sbIndexedParams.toString();
1467 queryParams = queryParams + sbIndexedParams.toString();
1469 if ( queryParams != null ) {
1470 if ( pathParams == null ) {
1471 pathSb.append(" parameters:\n");
1473 pathSb.append(queryParams);
1477 boolean skipPutDelete = false; // no put or delete for "all"
1478 if ( !path.endsWith("/relationship") ) {
1479 if ( !path.endsWith("}") ){
1480 skipPutDelete = true;
1484 if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1486 if ( path.endsWith("/relationship") ) {
1487 pathSb.append(" " + path + ":\n" );
1489 pathSb.append(" put:\n");
1490 pathSb.append(" tags:\n");
1491 pathSb.append(" - " + tag + "\n");
1493 if ( path.endsWith("/relationship") ) {
1494 pathSb.append(" summary: see node definition for valid relationships\n");
1496 pathSb.append(" summary: create or update an existing " + xmlRootElementName + "\n");
1497 pathSb.append(" description: create or update an existing " + xmlRootElementName + "\n");
1499 pathSb.append(" operationId: createOrUpdate" + useOpId + "\n");
1500 pathSb.append(" consumes:\n");
1501 pathSb.append(" - application/json\n");
1502 pathSb.append(" - application/xml\n");
1503 pathSb.append(" produces:\n");
1504 pathSb.append(" - application/json\n");
1505 pathSb.append(" - application/xml\n");
1506 pathSb.append(" responses:\n");
1507 pathSb.append(" \"default\":\n");
1508 pathSb.append(" " + responsesUrl);
1510 pathSb.append(" responses:\n");
1511 pathSb.append(" \"200\":\n");
1512 pathSb.append(" description: existing resource has been modified and there is a response buffer\n");
1513 pathSb.append(" \"201\":\n");
1514 pathSb.append(" description: new resource is created\n");
1515 pathSb.append(" \"202\":\n");
1516 pathSb.append(" description: action requested but may have taken other actions as well, which are returned in the response payload\n");
1517 pathSb.append(" \"204\":\n");
1518 pathSb.append(" description: existing resource has been modified and there is no response buffer\n");
1519 pathSb.append(" \"400\":\n");
1520 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1521 pathSb.append(" \"404\":\n");
1522 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1524 pathSb.append(" parameters:\n");
1525 //pathSb.append(" - in: path\n");
1526 pathSb.append(pathParams); // for nesting
1527 pathSb.append(" - name: body\n");
1528 pathSb.append(" in: body\n");
1529 pathSb.append(" description: " + xmlRootElementName + " object that needs to be created or updated\n");
1530 pathSb.append(" required: true\n");
1531 pathSb.append(" schema:\n");
1532 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1534 if ( queryParams != null ) {
1535 pathSb.append(queryParams);
1539 pathSb.append(" delete:\n");
1540 pathSb.append(" tags:\n");
1541 pathSb.append(" - " + tag + "\n");
1542 pathSb.append(" summary: delete an existing " + xmlRootElementName + "\n");
1544 pathSb.append(" description: delete an existing " + xmlRootElementName + "\n");
1546 pathSb.append(" operationId: delete" + useOpId + "\n");
1547 pathSb.append(" consumes:\n");
1548 pathSb.append(" - application/json\n");
1549 pathSb.append(" - application/xml\n");
1550 pathSb.append(" produces:\n");
1551 pathSb.append(" - application/json\n");
1552 pathSb.append(" - application/xml\n");
1553 pathSb.append(" responses:\n");
1554 pathSb.append(" \"default\":\n");
1555 pathSb.append(" " + responsesUrl);
1557 pathSb.append(" responses:\n");
1558 pathSb.append(" \"200\":\n");
1559 pathSb.append(" description: successful, the response includes an entity describing the status\n");
1560 pathSb.append(" \"204\":\n");
1561 pathSb.append(" description: successful, action has been enacted but the response does not include an entity\n");
1562 pathSb.append(" \"400\":\n");
1563 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1564 pathSb.append(" \"404\":\n");
1565 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1567 pathSb.append(" parameters:\n");
1568 //pathSb.append(" - in: path\n");
1569 pathSb.append(pathParams); // for nesting
1570 if ( !path.endsWith("/relationship") ) {
1571 pathSb.append(" - name: resource-version\n");
1573 pathSb.append(" in: query\n");
1574 pathSb.append(" description: resource-version for concurrency\n");
1575 pathSb.append(" required: true\n");
1576 pathSb.append(" type: string\n");
1579 if ( queryParams != null ) {
1580 pathSb.append(queryParams);
1586 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1590 definitionsSb.append(" " + xmlRootElementName + ":\n");
1591 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1592 if ( edges.size() > 0 ) {
1593 StringBuffer sbEdge = new StringBuffer();
1594 sbEdge.append(" ###### Related Nodes\n");
1595 for (EdgeDescription ed : edges) {
1596 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1597 sbEdge.append(" - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1598 sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1599 sbEdge.append("\n");
1602 for (EdgeDescription ed : edges) {
1603 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1604 sbEdge.append(" - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1605 sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1606 sbEdge.append("\n");
1609 validEdges = sbEdge.toString();
1612 String deleteRule = getDeleteRules(xmlRootElementName);
1613 // Handle description property. Might have a description OR valid edges OR both OR neither.
1614 // Only put a description: tag if there is at least one.
1615 if (pathDescriptionProperty != null || deleteRule != null || validEdges != null) {
1616 definitionsSb.append(" description: |\n");
1618 if ( pathDescriptionProperty != null )
1619 definitionsSb.append(" " + pathDescriptionProperty + "\n" );
1620 if (deleteRule != null)
1621 definitionsSb.append(" ###### Default Delete Scope\n ").append(deleteRule).append("\n");
1622 if (validEdges != null)
1623 definitionsSb.append(validEdges);
1626 if ( requiredCnt > 0 )
1627 definitionsSb.append(sbRequired);
1628 if ( propertyCnt > 0 ) {
1629 definitionsSb.append(" properties:\n");
1630 definitionsSb.append(sbProperties);
1632 generatedJavaType.put(xmlRootElementName, null);
1636 public static String generateSwaggerFromOxmFile( File oxmFile )
1639 StringBuffer sb = new StringBuffer();
1640 sb.append("swagger: \"2.0\"\ninfo:\n description: |\n Copyright © 2017 AT&T Intellectual Property. All rights reserved.\n\n Licensed under the Creative Commons License, Attribution 4.0 Intl. (the "License"); 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 "AS IS" 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&T Intellectual Property.\n\n This document is best viewed with Firefox or Chrome. Nodes can be found by appending /#/definitions/node-type-to-find to the path to this document. Edge definitions can be found with the node definitions.\n version: \"" + apiVersion +"\"\n");
1641 sb.append(" title: Active and Available Inventory REST API\n");
1642 sb.append(" license:\n name: Apache 2.0\n url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1643 sb.append(" contact:\n name:\n url:\n email:\n");
1644 sb.append("host:\nbasePath: /aai/" + apiVersion + "\n");
1645 sb.append("schemes:\n - https\npaths:\n");
1647 sb.append("responses:\n");
1648 sb.append(" \"200\":\n");
1649 sb.append(" description: successful operation\n");
1650 sb.append(" \"404\":\n");
1651 sb.append(" description: resource was not found\n");
1652 sb.append(" \"400\":\n");
1653 sb.append(" description: bad request\n");
1657 versionedClass = getEdgeRulesClass();
1659 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1660 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1661 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1662 Document doc = dBuilder.parse(oxmFile);
1664 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1665 Element bindingElement;
1666 NodeList javaTypesNodes;
1667 Element javaTypesElement;
1669 Element javaTypeElement;
1672 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1673 System.out.println( "missing <binding-nodes> in " + oxmFile );
1677 bindingElement = (Element) bindingsNodes.item(0);
1678 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1679 if ( javaTypesNodes.getLength() < 1 ) {
1680 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1683 javaTypesElement = (Element) javaTypesNodes.item(0);
1685 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1686 if ( javaTypeNodes.getLength() < 1 ) {
1687 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1691 String javaTypeName;
1692 String attrName, attrValue;
1694 StringBuffer pathSb = new StringBuffer();
1696 StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1698 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1699 javaTypeElement = (Element) javaTypeNodes.item(i);
1700 NamedNodeMap attributes = javaTypeElement.getAttributes();
1701 javaTypeName = null;
1702 for ( int j = 0; j < attributes.getLength(); ++j ) {
1703 attr = (Attr) attributes.item(j);
1704 attrName = attr.getNodeName();
1705 attrValue = attr.getNodeValue();
1706 if ( attrName.equals("name"))
1707 javaTypeName = attrValue;
1709 if ( javaTypeName == null ) {
1710 System.out.println( "<java-type> has no name attribute in " + oxmFile );
1713 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1715 //generatedJavaType.put(javaTypeName, null);
1716 //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1718 processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1719 definitionsSb, null, null, null, null, null, null, null);
1723 //System.out.println( "definitions block\n" + definitionsSb.toString());
1724 sb.append(definitionsSb.toString());
1725 //sb.append(definitionsSb);
1727 } catch (Exception e) {
1728 e.printStackTrace();
1731 //System.out.println("generated " + sb.toString());
1732 return sb.toString();
1735 private static NodeList locateXmlProperties(Element element) {
1736 XPathExpression expr;
1737 NodeList result = null;
1739 expr = xpath.compile("xml-properties");
1741 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1742 if (nodeset != null) {
1743 NodeList nodes = (NodeList) nodeset;
1744 if (nodes != null && nodes.getLength() > 0) {
1745 Element xmlProperty = (Element)nodes.item(0);
1746 result = xmlProperty.getElementsByTagName("xml-property");
1750 } catch (XPathExpressionException e) {
1751 e.printStackTrace();