2 * ============LICENSE_START=======================================================
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
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=========================================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 package org.onap.aai.util;
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;
30 import javax.xml.XMLConstants;
31 import javax.xml.parsers.DocumentBuilder;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import javax.xml.xpath.*;
35 import java.nio.charset.Charset;
36 import java.nio.file.Files;
37 import java.nio.file.Path;
38 import java.nio.file.Paths;
43 public class GenerateXsd {
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;
52 static Map<String, String> generatedJavaType;
53 static Map<String, String> appliedPaths;
54 static NodeList javaTypeNodes;
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;
61 private static final String generateTypeXSD = "xsd";
62 private static final String generateTypeYAML = "yaml";
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";
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
71 private static XPath xpath = XPathFactory.newInstance().newXPath();
74 private enum LineageType {
75 PARENT, CHILD, UNRELATED;
77 private class EdgeDescription {
79 private String ruleKey;
80 private LineageType type = LineageType.UNRELATED;
81 private String direction;
82 private String multiplicity;
83 private boolean hasDelTarget = false;
85 public String getRuleKey() {
88 public String getMultiplicity() {
91 public String getDirection() {
94 public void setRuleKey(String val) {
97 public void setType(LineageType val) {
100 public void setDirection(String val) {
101 this.direction = val;
103 public void setMultiplicity(String val) {
104 this.multiplicity=val;
106 public void setHasDelTarget(String val) {
107 hasDelTarget = Boolean.parseBoolean(val);
110 public String getRelationshipDescription(String fromTo, String otherNodeName) {
114 if ("FROM".equals(fromTo)) {
115 if ("OUT".equals(direction)) {
116 if (LineageType.PARENT == type) {
117 result = " (is composed of "+otherNodeName;
121 if (LineageType.CHILD == type) {
122 result = " (comprises "+otherNodeName;
124 else if (LineageType.PARENT == type) {
125 result = " (comprises "+otherNodeName;
129 if ("OUT".equals(direction)) {
130 if (LineageType.PARENT == type) {
131 result = " (comprises "+otherNodeName;
134 if (LineageType.PARENT == type) {
135 result = " (is composed of "+otherNodeName;
140 // if (type != null) {
141 // if (LineageType.PARENT.equals(type) && "FROM".equals(fromTo)) {
142 // if ("OUT".equals(direction)) {
143 // result = " (is composed of "+otherNodeName;
145 // result = " (comprises "+otherNodeName;
148 // result = " (comprises " + otherNodeName;
149 // // if (!(multiplicity.startsWith("One"))) {
150 // // System.err.println("Surprised to find multiplicity "+multiplicity+" with comprises for "+ruleKey);
154 if ("TO".equals(fromTo)) {
155 if (result.length() == 0) result = result + " (";
156 else result = result + ", ";
158 result = result + mapMultiplicity(fromTo);
159 if (hasDelTarget) result = result + ", will delete target node";
162 if (result.length() > 0) result = result + ")";
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;
174 // result = switchMultiplicity(multiplicity);
177 // if (direction.equals("OUT")) {
178 // result = multiplicity;
180 // result = switchMultiplicity(multiplicity);
186 // private String switchMultiplicity(String val) throws IllegalArgumentException
188 // String result = null;
195 // result = "One2Many";
198 // result = "Many2One";
201 // throw new IllegalArgumentException("Multiplicity cannot be "+val);
203 // System.out.println("Switched Multiplicity from "+val+" to "+result);
208 private static boolean validVersion(String versionToGen) {
210 if ("ALL".equalsIgnoreCase(versionToGen)) {
214 for (Version v : Version.values()) {
215 if (v.name().equals(versionToGen)) {
223 private static boolean versionUsesAnnotations( String version) {
224 if (new Integer(version.substring(1)).intValue() >= annotationsStartVersion ) {
230 private static boolean versionSupportsSwagger( String version) {
231 if (new Integer(version.substring(1)).intValue() >= swaggerSupportStartsVersion ) {
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;
244 if ( !fileTypeToGen.equals( generateTypeXSD ) && !fileTypeToGen.equals( generateTypeYAML )) {
245 System.err.println("Invalid gen_type passed. " + fileTypeToGen);
250 if ( versionToGen == null ) {
251 System.err.println("Version is required, ie v<n> or ALL.");
255 responsesUrl = System.getProperty("yamlresponses_url");
256 String responsesLabel = System.getProperty("yamlresponses_label");
257 List<Version> versionsToGen = new ArrayList<>();
260 if (!"ALL".equalsIgnoreCase(versionToGen) && !versionToGen.matches("v\\d+") && !validVersion(versionToGen)) {
261 System.err.println("Invalid version passed. " + versionToGen);
265 if ("ALL".equalsIgnoreCase(versionToGen)) {
266 versionsToGen = Arrays.asList(Version.values());
267 Collections.sort(versionsToGen);
268 Collections.reverse(versionsToGen);
270 versionsToGen.add(Version.valueOf(versionToGen));
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" );
279 responsesUrl = "description: "+ responsesLabel+ "(" + responsesUrl + ").\n";
281 String oxmPath = root + "/oxm/";
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);
304 outfile = new File(outfileName);
305 File parentDir = outfile.getParentFile();
306 if(! parentDir.exists())
310 outfile.createNewFile();
311 } catch (IOException e) {
312 System.out.println( "Exception creating output file " + outfileName);
315 BufferedWriter bw = null;
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);
329 System.out.println( "GeneratedXSD successful, saved in " + outfileName);
335 public static String processJavaTypeElement( String javaTypeName, Element javaTypeElement) {
337 String xmlRootElementName = null;
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);
347 NamedNodeMap attributes;
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();
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;
362 if ( javaTypeName.equals("RelationshipList")) {
363 System.out.println( "Skipping " + javaTypeName);
364 generatedJavaType.put(javaTypeName, null);
369 Element parentElement = (Element)parentNodes.item(0);
370 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
372 Element childElement;
373 String xmlElementWrapper;
375 Element xmlElementElement;
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, " ");
388 sb1.append(" </xs:annotation>\r\n");
390 System.out.println("no properties found for: " + xmlRootElementName);
392 sb1.append(" <xs:sequence>\n");
393 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
395 xmlElementElement = (Element)xmlElementNodes.item(i);
396 childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
398 xmlElementWrapper = null;
399 if ( childNodes.getLength() > 0 ) {
400 childElement = (Element)childNodes.item(0);
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);
414 attributes = xmlElementElement.getAttributes();
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();
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;
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) ));
440 if ( attrName.equals("xml-key")) {
441 elementIsKey = attrValue;
443 if ( attrName.equals("required")) {
444 elementIsRequired = attrValue;
446 if ( attrName.equals("container-type")) {
447 elementContainerType = attrValue;
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\"");
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");
464 System.out.println("no properties found for: " + xmlElementWrapper);
466 sb1.append(" <xs:sequence>\n");
469 if ("Nodes".equals(addType)) {
470 //System.out.println ("Skipping nodes, temporary testing");
473 if ( addType != null ) {
474 //sb1.append(" <xs:element ref=\"tns:" + elementName +"\"");
475 sb1.append(" <xs:element ref=\"tns:" + getXmlRootElementName(addType) +"\"");
477 sb1.append(" <xs:element name=\"" + elementName +"\"");
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\"");
493 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
494 sb1.append(" maxOccurs=\"unbounded\"");
496 properties = GenerateXsd.locateXmlProperties(xmlElementElement);
497 if (properties != null || elementIsKey != null) {
499 if ( useAnnotationsInXsd ) {
500 sb1.append(" <xs:annotation>\r\n");
501 insertAnnotation(properties, elementIsKey != null, "field", sb1, " ");
502 sb1.append(" </xs:annotation>\r\n");
504 if (xmlElementWrapper== null) {
505 sb1.append(" </xs:element>\n");
510 if ( xmlElementWrapper != null ) {
511 sb1.append(" </xs:sequence>\n");
512 sb1.append(" </xs:complexType>\n");
513 sb1.append(" </xs:element>\n");
517 if ( xmlRootElementName.equals("notify") ||
518 xmlRootElementName.equals("relationship") ||
519 xmlRootElementName.equals("relationship-data") ||
520 xmlRootElementName.equals("related-to-property") )
522 sb1.append(" <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n");
524 sb1.append(" </xs:sequence>\n");
525 sb1.append(" </xs:complexType>\n");
526 sb1.append(" </xs:element>\n");
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();
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;
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();
555 return sb.toString();
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<>();
566 metadata.add("isKey=true");
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")) {
575 } else if (name.equals("extends")) {
576 name = "extendsFrom";
578 metadata.add(name + "=\"" + value.replaceAll("&", "&") + "\"");
579 //System.out.println("property name: " + name);
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");
591 private static Element getJavaTypeElement( String javaTypeName )
594 String attrName, attrValue;
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;
608 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
609 return (Element) null;
612 private static Element getJavaTypeElementSwagger( String javaTypeName )
615 String attrName, attrValue;
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;
629 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
630 return (Element) null;
632 private static String getXmlRootElementName( String javaTypeName )
635 String attrName, attrValue;
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();
653 attrValue = attr.getNodeValue();
654 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
655 if ( attrName.equals("name"))
661 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
666 public static String processOxmFile( File oxmFile, Version v )
668 StringBuilder sb = new StringBuilder();
669 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
670 String namespace = "org.onap";
671 if (v.compareTo(Version.v11) < 0 || v.compareTo(Version.v12) < 0) {
672 namespace = "org.openecomp";
674 if ( useAnnotationsInXsd ) {
675 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
676 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
678 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" +
679 " jaxb:version=\"2.1\" \r\n" +
680 " xmlns:annox=\"http://annox.dev.java.net\" \r\n" +
681 " jaxb:extensionBindingPrefixes=\"annox\">\n\n");
683 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
684 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n");
689 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
690 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
691 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
692 Document doc = dBuilder.parse(oxmFile);
694 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
695 Element bindingElement;
696 NodeList javaTypesNodes;
697 Element javaTypesElement;
699 Element javaTypeElement;
702 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
703 System.out.println( "missing <binding-nodes> in " + oxmFile );
707 bindingElement = (Element) bindingsNodes.item(0);
708 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
709 if ( javaTypesNodes.getLength() < 1 ) {
710 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
713 javaTypesElement = (Element) javaTypesNodes.item(0);
714 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
715 if ( javaTypeNodes.getLength() < 1 ) {
716 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
721 String attrName, attrValue;
723 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
724 javaTypeElement = (Element) javaTypeNodes.item(i);
725 NamedNodeMap attributes = javaTypeElement.getAttributes();
727 for ( int j = 0; j < attributes.getLength(); ++j ) {
728 attr = (Attr) attributes.item(j);
729 attrName = attr.getNodeName();
730 attrValue = attr.getNodeValue();
731 if ( attrName.equals("name"))
732 javaTypeName = attrValue;
734 if ( javaTypeName == null ) {
735 System.out.println( "<java-type> has no name attribute in " + oxmFile );
738 if ("Nodes".equals(javaTypeName)) {
739 //System.out.println("skipping Nodes entry (temporary feature)");
742 if ( !generatedJavaType.containsKey(javaTypeName) ) {
743 generatedJavaType.put(javaTypeName, null);
744 sb.append(processJavaTypeElement( javaTypeName, javaTypeElement ));
748 } catch (Exception e) {
752 sb.append("</xs:schema>\n");
753 return sb.toString();
756 private static boolean isStandardType( String elementType )
758 switch ( elementType ) {
759 case "java.lang.String":
760 case "java.lang.Long":
761 case "java.lang.Integer":
762 case"java.lang.Boolean":
768 private static Vector<String> getIndexedProps( String attrValue )
770 if ( attrValue == null )
772 StringTokenizer st = new StringTokenizer( attrValue, ",");
773 if ( st.countTokens() == 0 )
775 Vector<String> result = new Vector<String>();
776 while ( st.hasMoreTokens()) {
777 result.add(st.nextToken());
783 * Guaranteed to at least return non null but empty collection of edge descriptions
784 * @param nodeName name of the vertex whose edge relationships to return
785 * @return collection of node neighbors based on DbEdgeRules
787 private static Collection<EdgeDescription> getEdgeRulesFromJson( String path, boolean skipMatch )
790 ArrayList<EdgeDescription> result = new ArrayList<>();
791 Iterator<Map<String, Object>> edgeRulesIterator;
794 GenerateXsd x = new GenerateXsd();
796 List<Map<String, Object>> inEdges = JsonPath.parse(jsonEdges).read(path);
798 edgeRulesIterator = inEdges.iterator();
799 Map<String, Object> edgeMap;
807 EdgeDescription edgeDes;
809 while( edgeRulesIterator.hasNext() ){
810 edgeMap = edgeRulesIterator.next();
811 fromNode = (String)edgeMap.get("from");
812 toNode = (String)edgeMap.get("to");
814 if ( fromNode.equals(toNode)) {
818 edgeDes = x.new EdgeDescription();
819 edgeDes.setRuleKey(fromNode + "|" + toNode);
820 direction = (String)edgeMap.get("direction");
821 edgeDes.setDirection(direction);
822 multiplicity = (String)edgeMap.get("multiplicity");
823 edgeDes.setMultiplicity(multiplicity);
824 isParent = (String)edgeMap.get(EdgeProperty.CONTAINS.toString());
825 if ( "${direction}".equals(isParent)) {
826 edgeDes.setType(LineageType.PARENT);
828 edgeDes.setType(LineageType.UNRELATED);
830 hasDelTarget = (String)edgeMap.get(EdgeProperty.DELETE_OTHER_V.toString());
831 edgeDes.setHasDelTarget(hasDelTarget);
835 } catch (Exception ex) {
836 ex.printStackTrace();
843 * Guaranteed to at least return non null but empty collection of edge descriptions
844 * @param nodeName name of the vertex whose edge relationships to return
845 * @return collection of node neighbors based on DbEdgeRules
847 private static Collection<EdgeDescription> getEdgeRules( String nodeName )
849 String fromRulesPath = "$['rules'][?(@['from']=='" + nodeName + "')]";
850 String toRulesPath = "$['rules'][?(@['to']=='" + nodeName + "')]";
851 Collection<EdgeDescription> fromEdges = getEdgeRulesFromJson( fromRulesPath, false );
852 Collection<EdgeDescription> edges = getEdgeRulesFromJson( toRulesPath, true );
853 edges.addAll(fromEdges);
857 public static String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
858 StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
859 String getItemName, StringBuffer pathParams, String queryParams, String validEdges) {
861 String xmlRootElementName = null;
863 //Map<String, String> addJavaType = new HashMap<String, String>();
864 String useTag = null;
865 String useOpId = null;
870 case "ServiceDesignAndCreation":
872 case "LicenseManagement":
873 case "CloudInfrastructure":
874 case "ExternalSystem":
882 System.out.println( "processJavaTypeElementSwagger called with null path for javaTypeName " + javaTypeName);
885 if ( path == null || !(path.contains("cloud-infrastructure")))
886 switch ( javaTypeName) {
891 case "CloudInfrastructure":
894 case "ServiceDesignAndCreation":
895 case "LicenseManagement":
898 useTag = javaTypeName;
907 if ( !javaTypeName.equals("Inventory") ) {
908 if ( javaTypeName.equals("AaiInternal"))
911 useOpId = javaTypeName;
913 useOpId = opId + javaTypeName;
915 useTag = javaTypeName;
919 if ( javaTypeName.equals("GenericVnf"))
920 System.out.println( "Processing " + javaTypeName);
921 else if ( javaTypeName.equals("Service"))
922 System.out.println( "Processing " + javaTypeName);
923 else if ( javaTypeName.equals("SitePair"))
924 System.out.println( "Processing " + javaTypeName);
926 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
928 if ( parentNodes.getLength() == 0 ) {
929 //System.out.println( "no java-attributes for java-type " + javaTypeName);
934 NamedNodeMap attributes;
936 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
937 Element valElement = (Element) valNodes.item(0);
938 attributes = valElement.getAttributes();
939 for ( int i = 0; i < attributes.getLength(); ++i ) {
940 Attr attr = (Attr) attributes.item(i);
941 String attrName = attr.getNodeName();
943 String attrValue = attr.getNodeValue();
944 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
945 if ( attrName.equals("name"))
946 xmlRootElementName = attrValue;
949 if ( xmlRootElementName.equals("oam-networks"))
950 System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
954 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
959 Element childElement;
960 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
961 Element xmlPropElement;
962 String pathDescriptionProperty = null;
965 Vector<String> indexedProps = null;
967 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
968 if ( path != null && path.equals("/network/generic-vnfs"))
969 System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
971 if ( xmlPropNodes.getLength() > 0 ) {
973 for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
974 xmlPropElement = (Element)xmlPropNodes.item(i);
975 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
977 childNodes = xmlPropElement.getElementsByTagName("xml-property");
979 if ( childNodes.getLength() > 0 ) {
980 for ( int j = 0; j < childNodes.getLength(); ++j ) {
981 childElement = (Element)childNodes.item(j);
983 int useValue = VALUE_NONE;
984 attributes = childElement.getAttributes();
985 for ( int k = 0; k < attributes.getLength(); ++k ) {
986 Attr attr = (Attr) attributes.item(k);
987 String attrName = attr.getNodeName();
988 String attrValue = attr.getNodeValue();
989 if ( attrName == null || attrValue == null )
991 if ( attrName.equals("name") && attrValue.equals("description")) {
992 useValue = VALUE_DESCRIPTION;
994 if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
995 pathDescriptionProperty = attrValue;
997 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
999 if ( attrValue.equals("indexedProps")) {
1000 useValue = VALUE_INDEXED_PROPS;
1002 if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
1003 indexedProps = getIndexedProps( attrValue );
1010 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
1013 if ( javaTypeName.equals("RelationshipList")) {
1014 System.out.println( "Skipping " + javaTypeName);
1015 generatedJavaType.put(javaTypeName, null);
1020 Element parentElement = (Element)parentNodes.item(0);
1021 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
1024 String attrDescription = null;
1026 Element xmlElementElement;
1027 String addType = null;
1028 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1029 String elementName = null;
1030 StringBuffer sbParameters = new StringBuffer();
1032 StringBuffer sbRequired = new StringBuffer();
1033 int requiredCnt = 0;
1034 int propertyCnt = 0;
1035 StringBuffer sbProperties = new StringBuffer();
1036 StringBuffer sbIndexedParams = new StringBuffer();
1040 if ( xmlRootElementName.equals("inventory"))
1042 else if ( path == null )
1043 //path = "/aai/" + apiVersion;
1044 path = "/" + xmlRootElementName;
1046 path += "/" + xmlRootElementName;
1047 st = new StringTokenizer(path, "/");
1049 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1050 System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1052 boolean genPath = false;
1054 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1055 System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1057 if ( st.countTokens() > 1 && getItemName == null ) {
1058 if ( appliedPaths.containsKey(path))
1060 appliedPaths.put(path, null);
1062 if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1065 if ( path.endsWith("/relationship-list")) {
1071 Vector<String> addTypeV = null;
1072 if ( xmlElementNodes.getLength() > 0 ) {
1074 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1075 xmlElementElement = (Element)xmlElementNodes.item(i);
1076 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1078 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1079 if ( childNodes.getLength() > 0 ) {
1080 childElement = (Element)childNodes.item(0);
1082 attributes = childElement.getAttributes();
1083 for ( int k = 0; k < attributes.getLength(); ++k ) {
1084 Attr attr = (Attr) attributes.item(k);
1085 String attrName = attr.getNodeName();
1086 String attrValue = attr.getNodeValue();
1087 if ( attrName.equals("name")) {
1088 xmlElementWrapper = attrValue;
1089 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1095 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1096 attrDescription = null;
1097 if ( valNodes.getLength() > 0 ) {
1098 for ( int j = 0; j < valNodes.getLength(); ++j ) {
1099 valElement = (Element)valNodes.item(j);
1100 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1102 childNodes = valElement.getElementsByTagName("xml-property");
1103 if ( childNodes.getLength() > 0 ) {
1104 childElement = (Element)childNodes.item(0);
1106 attributes = childElement.getAttributes();
1107 attrDescription = null;
1108 boolean useValue = false;
1109 for ( int k = 0; k < attributes.getLength(); ++k ) {
1110 Attr attr = (Attr) attributes.item(k);
1111 String attrName = attr.getNodeName();
1112 String attrValue = attr.getNodeValue();
1113 if ( attrName.equals("name") && attrValue.equals("description")) {
1116 if ( useValue && attrName.equals("value")) {
1117 attrDescription = attrValue;
1118 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1126 attributes = xmlElementElement.getAttributes();
1127 addTypeV = null; // vector of 1
1130 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1131 for ( int j = 0; j < attributes.getLength(); ++j ) {
1132 Attr attr = (Attr) attributes.item(j);
1133 String attrName = attr.getNodeName();
1135 String attrValue = attr.getNodeValue();
1136 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1137 if ( attrName.equals("name")) {
1138 elementName = attrValue;
1141 if ( attrName.equals("type") && getItemName == null ) {
1142 elementType = attrValue;
1143 if ( attrValue.contains(apiVersionFmt) ) {
1144 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1145 if ( addTypeV == null )
1146 addTypeV = new Vector<String>();
1147 addTypeV.add(addType);
1151 if ( attrName.equals("xml-key")) {
1152 elementIsKey = attrValue;
1153 path += "/{" + elementName + "}";
1155 if ( attrName.equals("required")) {
1156 elementIsRequired = attrValue;
1158 if ( attrName.equals("container-type")) {
1159 elementContainerType = attrValue;
1162 if ( getItemName != null ) {
1163 if ( getItemName.equals("array") ) {
1164 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1165 //System.out.println( " returning array " + elementName );
1169 } else { // not an array check
1170 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1171 //System.out.println( " returning object " + elementName );
1176 //System.out.println( " returning null" );
1179 if ( elementIsRequired != null ) {
1180 if ( requiredCnt == 0 )
1181 sbRequired.append(" required:\n");
1183 if ( addTypeV != null ) {
1184 for ( int k = 0; k < addTypeV.size(); ++i ) {
1185 sbRequired.append(" - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1188 sbRequired.append(" - " + elementName + "\n");
1192 if ( elementIsKey != null ) {
1193 sbParameters.append((" - name: " + elementName + "\n"));
1194 sbParameters.append((" in: path\n"));
1195 if ( attrDescription != null && attrDescription.length() > 0 )
1196 sbParameters.append((" description: " + attrDescription + "\n"));
1197 sbParameters.append((" required: true\n"));
1198 if ( elementType.equals("java.lang.String"))
1199 sbParameters.append(" type: string\n");
1200 if ( elementType.equals("java.lang.Long")) {
1201 sbParameters.append(" type: integer\n");
1202 sbParameters.append(" format: int64\n");
1204 if ( elementType.equals("java.lang.Integer")) {
1205 sbParameters.append(" type: integer\n");
1206 sbParameters.append(" format: int32\n");
1208 if ( elementType.equals("java.lang.Boolean"))
1209 sbParameters.append(" type: boolean\n");
1212 } else if ( indexedProps != null
1213 && indexedProps.contains(elementName ) ) {
1214 sbIndexedParams.append((" - name: " + elementName + "\n"));
1215 sbIndexedParams.append((" in: query\n"));
1216 if ( attrDescription != null && attrDescription.length() > 0 )
1217 sbIndexedParams.append((" description: " + attrDescription + "\n"));
1218 sbIndexedParams.append((" required: false\n"));
1219 if ( elementType.equals("java.lang.String"))
1220 sbIndexedParams.append(" type: string\n");
1221 if ( elementType.equals("java.lang.Long")) {
1222 sbIndexedParams.append(" type: integer\n");
1223 sbIndexedParams.append(" format: int64\n");
1225 if ( elementType.equals("java.lang.Integer")) {
1226 sbIndexedParams.append(" type: integer\n");
1227 sbIndexedParams.append(" format: int32\n");
1229 if ( elementType.equals("java.lang.Boolean"))
1230 sbIndexedParams.append(" type: boolean\n");
1234 if ( elementName != null && elementName.equals("inventory-item"))
1235 System.out.println( "processing inventory-item elementName");
1238 if ( isStandardType(elementType)) {
1239 sbProperties.append(" " + elementName + ":\n");
1241 sbProperties.append(" type: ");
1243 if ( elementType.equals("java.lang.String"))
1244 sbProperties.append("string\n");
1245 else if ( elementType.equals("java.lang.Long")) {
1246 sbProperties.append("integer\n");
1247 sbProperties.append(" format: int64\n");
1249 else if ( elementType.equals("java.lang.Integer")){
1250 sbProperties.append("integer\n");
1251 sbProperties.append(" format: int32\n");
1253 else if ( elementType.equals("java.lang.Boolean"))
1254 sbProperties.append("boolean\n");
1255 if ( attrDescription != null && attrDescription.length() > 0 )
1256 sbProperties.append(" description: " + attrDescription + "\n");
1259 //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1261 if ( addTypeV != null ) {
1262 StringBuffer newPathParams = null;
1263 if ( pathParams != null ) {
1264 newPathParams = new StringBuffer();
1265 newPathParams.append(pathParams);
1267 if ( sbParameters.toString().length() > 0 ) {
1268 if ( newPathParams == null )
1269 newPathParams = new StringBuffer();
1270 newPathParams.append(sbParameters);
1272 String newQueryParams = null;
1273 if ( sbIndexedParams.toString().length() > 0 ) {
1274 if ( queryParams == null )
1275 newQueryParams = sbIndexedParams.toString();
1277 newQueryParams = queryParams + sbIndexedParams.toString();
1279 newQueryParams = queryParams;
1281 for ( int k = 0; k < addTypeV.size(); ++k ) {
1282 addType = addTypeV.elementAt(k);
1284 if ( opId == null || !opId.contains(addType)) {
1285 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1286 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, null,
1287 newPathParams, newQueryParams, validEdges);
1289 // need item name of array
1290 String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1291 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1292 "array", null, null, null );
1294 if ( itemName != null ) {
1295 if ( addType.equals("AaiInternal") ) {
1296 //System.out.println( "addType AaiInternal, skip properties");
1298 } else if ( getItemName == null) {
1300 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1301 sbProperties.append(" type: array\n items:\n");
1302 sbProperties.append(" $ref: \"#/definitions/" + itemName + "\"\n");
1303 if ( attrDescription != null && attrDescription.length() > 0 )
1304 sbProperties.append(" description: " + attrDescription + "\n");
1307 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1308 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, "other" );
1309 if ( itemName != null ) {
1311 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1312 // need properties for getXmlRootElementName(addType)
1313 newPathParams = null;
1314 if ( pathParams != null ) {
1315 newPathParams = new StringBuffer();
1316 newPathParams.append(pathParams);
1318 if ( sbParameters.toString().length() > 0 ) {
1319 if ( newPathParams == null )
1320 newPathParams = new StringBuffer();
1321 newPathParams.append(sbParameters);
1323 newQueryParams = null;
1324 if ( sbIndexedParams.toString().length() > 0 ) {
1325 if ( queryParams == null )
1326 newQueryParams = sbIndexedParams.toString();
1328 newQueryParams = queryParams + sbIndexedParams.toString();
1330 newQueryParams = queryParams;
1332 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1333 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1334 null, newPathParams, newQueryParams, validEdges );
1335 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1336 sbProperties.append(" type: array\n items: \n");
1337 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1339 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1340 sbProperties.append(" type: object\n");
1341 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1343 if ( attrDescription != null && attrDescription.length() > 0 )
1344 sbProperties.append(" description: " + attrDescription + "\n");
1348 System.out.println(" unable to define swagger object for " + addType);
1352 //if ( getItemName == null) looking for missing properties
1353 //generatedJavaType.put(addType, null);
1360 if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1361 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1364 if ( !path.endsWith("/relationship") ) {
1365 pathSb.append(" " + path + ":\n" );
1366 pathSb.append(" get:\n");
1367 pathSb.append(" tags:\n");
1368 pathSb.append(" - " + tag + "\n");
1369 pathSb.append(" summary: returns " + xmlRootElementName + "\n");
1371 pathSb.append(" description: returns " + xmlRootElementName + "\n");
1372 pathSb.append(" operationId: get" + useOpId + "\n");
1373 pathSb.append(" produces:\n");
1374 pathSb.append(" - application/json\n");
1375 pathSb.append(" - application/xml\n");
1377 pathSb.append(" responses:\n");
1378 pathSb.append(" \"200\":\n");
1379 pathSb.append(" description: successful operation\n");
1380 pathSb.append(" schema:\n");
1381 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1382 pathSb.append(" \"default\":\n");
1383 pathSb.append(" " + responsesUrl);
1385 pathSb.append(" \"200\":\n");
1386 pathSb.append(" description: successful operation\n");
1387 pathSb.append(" schema:\n");
1388 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1389 pathSb.append(" \"404\":\n");
1390 pathSb.append(" description: resource was not found\n");
1391 pathSb.append(" \"400\":\n");
1392 pathSb.append(" description: bad request\n");
1394 if ( path.indexOf('{') > 0 ) {
1396 if ( sbParameters.toString().length() > 0 ) {
1397 if ( pathParams == null )
1398 pathParams = new StringBuffer();
1399 pathParams.append(sbParameters);
1401 if ( pathParams != null) {
1402 pathSb.append(" parameters:\n");
1403 pathSb.append(pathParams);
1405 System.out.println( "null pathParams for " + useOpId);
1406 if ( sbIndexedParams.toString().length() > 0 ) {
1407 if ( queryParams == null )
1408 queryParams = sbIndexedParams.toString();
1410 queryParams = queryParams + sbIndexedParams.toString();
1412 if ( queryParams != null ) {
1413 if ( pathParams == null ) {
1414 pathSb.append(" parameters:\n");
1416 pathSb.append(queryParams);
1420 boolean skipPutDelete = false; // no put or delete for "all"
1421 if ( !path.endsWith("/relationship") ) {
1422 if ( !path.endsWith("}") ){
1423 skipPutDelete = true;
1427 if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1429 if ( path.endsWith("/relationship") ) {
1430 pathSb.append(" " + path + ":\n" );
1432 pathSb.append(" put:\n");
1433 pathSb.append(" tags:\n");
1434 pathSb.append(" - " + tag + "\n");
1436 if ( path.endsWith("/relationship") ) {
1437 pathSb.append(" summary: see node definition for valid relationships\n");
1439 pathSb.append(" summary: create or update an existing " + xmlRootElementName + "\n");
1440 pathSb.append(" description: create or update an existing " + xmlRootElementName + "\n");
1442 pathSb.append(" operationId: createOrUpdate" + useOpId + "\n");
1443 pathSb.append(" consumes:\n");
1444 pathSb.append(" - application/json\n");
1445 pathSb.append(" - application/xml\n");
1446 pathSb.append(" produces:\n");
1447 pathSb.append(" - application/json\n");
1448 pathSb.append(" - application/xml\n");
1449 pathSb.append(" responses:\n");
1450 pathSb.append(" \"default\":\n");
1451 pathSb.append(" " + responsesUrl);
1453 pathSb.append(" responses:\n");
1454 pathSb.append(" \"200\":\n");
1455 pathSb.append(" description: existing resource has been modified and there is a response buffer\n");
1456 pathSb.append(" \"201\":\n");
1457 pathSb.append(" description: new resource is created\n");
1458 pathSb.append(" \"202\":\n");
1459 pathSb.append(" description: action requested but may have taken other actions as well, which are returned in the response payload\n");
1460 pathSb.append(" \"204\":\n");
1461 pathSb.append(" description: existing resource has been modified and there is no response buffer\n");
1462 pathSb.append(" \"400\":\n");
1463 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1464 pathSb.append(" \"404\":\n");
1465 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1467 pathSb.append(" parameters:\n");
1468 //pathSb.append(" - in: path\n");
1469 pathSb.append(pathParams); // for nesting
1470 pathSb.append(" - name: body\n");
1471 pathSb.append(" in: body\n");
1472 pathSb.append(" description: " + xmlRootElementName + " object that needs to be created or updated\n");
1473 pathSb.append(" required: true\n");
1474 pathSb.append(" schema:\n");
1475 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1477 if ( queryParams != null ) {
1478 pathSb.append(queryParams);
1482 pathSb.append(" delete:\n");
1483 pathSb.append(" tags:\n");
1484 pathSb.append(" - " + tag + "\n");
1485 pathSb.append(" summary: delete an existing " + xmlRootElementName + "\n");
1487 pathSb.append(" description: delete an existing " + xmlRootElementName + "\n");
1489 pathSb.append(" operationId: delete" + useOpId + "\n");
1490 pathSb.append(" consumes:\n");
1491 pathSb.append(" - application/json\n");
1492 pathSb.append(" - application/xml\n");
1493 pathSb.append(" produces:\n");
1494 pathSb.append(" - application/json\n");
1495 pathSb.append(" - application/xml\n");
1496 pathSb.append(" responses:\n");
1497 pathSb.append(" \"default\":\n");
1498 pathSb.append(" " + responsesUrl);
1500 pathSb.append(" responses:\n");
1501 pathSb.append(" \"200\":\n");
1502 pathSb.append(" description: successful, the response includes an entity describing the status\n");
1503 pathSb.append(" \"204\":\n");
1504 pathSb.append(" description: successful, action has been enacted but the response does not include an entity\n");
1505 pathSb.append(" \"400\":\n");
1506 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1507 pathSb.append(" \"404\":\n");
1508 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1510 pathSb.append(" parameters:\n");
1511 //pathSb.append(" - in: path\n");
1512 pathSb.append(pathParams); // for nesting
1513 if ( !path.endsWith("/relationship") ) {
1514 pathSb.append(" - name: resource-version\n");
1516 pathSb.append(" in: query\n");
1517 pathSb.append(" description: resource-version for concurrency\n");
1518 pathSb.append(" required: true\n");
1519 pathSb.append(" type: string\n");
1522 if ( queryParams != null ) {
1523 pathSb.append(queryParams);
1529 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1533 definitionsSb.append(" " + xmlRootElementName + ":\n");
1534 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1535 if ( edges.size() > 0 ) {
1536 StringBuffer sbEdge = new StringBuffer();
1537 sbEdge.append(" ###### Related Nodes\n");
1538 for (EdgeDescription ed : edges) {
1539 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1540 sbEdge.append(" - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1541 sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1542 sbEdge.append("\n");
1545 for (EdgeDescription ed : edges) {
1546 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1547 sbEdge.append(" - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1548 sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1549 sbEdge.append("\n");
1552 validEdges = sbEdge.toString();
1555 // Handle description property. Might have a description OR valid edges OR both OR neither.
1556 // Only put a description: tag if there is at least one.
1557 if (pathDescriptionProperty != null || validEdges != null) {
1558 definitionsSb.append(" description: |\n");
1560 if ( pathDescriptionProperty != null )
1561 definitionsSb.append(" " + pathDescriptionProperty + "\n" );
1562 if (validEdges != null)
1563 definitionsSb.append(validEdges);
1566 if ( requiredCnt > 0 )
1567 definitionsSb.append(sbRequired);
1568 if ( propertyCnt > 0 ) {
1569 definitionsSb.append(" properties:\n");
1570 definitionsSb.append(sbProperties);
1572 generatedJavaType.put(xmlRootElementName, null);
1576 public static String generateSwaggerFromOxmFile( File oxmFile )
1579 StringBuffer sb = new StringBuffer();
1580 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");
1581 sb.append(" title: Active and Available Inventory REST API\n");
1582 sb.append(" license:\n name: Apache 2.0\n url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1583 sb.append(" contact:\n name:\n url:\n email:\n");
1584 sb.append("host:\nbasePath: /aai/" + apiVersion + "\n");
1585 sb.append("schemes:\n - https\npaths:\n");
1587 sb.append("responses:\n");
1588 sb.append(" \"200\":\n");
1589 sb.append(" description: successful operation\n");
1590 sb.append(" \"404\":\n");
1591 sb.append(" description: resource was not found\n");
1592 sb.append(" \"400\":\n");
1593 sb.append(" description: bad request\n");
1596 File initialFile = new File("src/main/resources/dbedgerules/DbEdgeRules_" + apiVersion + ".json");
1597 InputStream is = new FileInputStream(initialFile);
1599 Scanner scanner = new Scanner(is);
1600 jsonEdges = scanner.useDelimiter("\\Z").next();
1604 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1605 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1606 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1607 Document doc = dBuilder.parse(oxmFile);
1609 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1610 Element bindingElement;
1611 NodeList javaTypesNodes;
1612 Element javaTypesElement;
1614 Element javaTypeElement;
1617 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1618 System.out.println( "missing <binding-nodes> in " + oxmFile );
1622 bindingElement = (Element) bindingsNodes.item(0);
1623 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1624 if ( javaTypesNodes.getLength() < 1 ) {
1625 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1628 javaTypesElement = (Element) javaTypesNodes.item(0);
1630 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1631 if ( javaTypeNodes.getLength() < 1 ) {
1632 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1636 String javaTypeName;
1637 String attrName, attrValue;
1639 StringBuffer pathSb = new StringBuffer();
1641 StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1643 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1644 javaTypeElement = (Element) javaTypeNodes.item(i);
1645 NamedNodeMap attributes = javaTypeElement.getAttributes();
1646 javaTypeName = null;
1647 for ( int j = 0; j < attributes.getLength(); ++j ) {
1648 attr = (Attr) attributes.item(j);
1649 attrName = attr.getNodeName();
1650 attrValue = attr.getNodeValue();
1651 if ( attrName.equals("name"))
1652 javaTypeName = attrValue;
1654 if ( javaTypeName == null ) {
1655 System.out.println( "<java-type> has no name attribute in " + oxmFile );
1658 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1660 //generatedJavaType.put(javaTypeName, null);
1661 //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1663 processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1664 definitionsSb, null, null, null, null, null, null, null);
1668 //System.out.println( "definitions block\n" + definitionsSb.toString());
1669 sb.append(definitionsSb.toString());
1670 //sb.append(definitionsSb);
1672 } catch (Exception e) {
1673 e.printStackTrace();
1676 //System.out.println("generated " + sb.toString());
1677 return sb.toString();
1680 private static NodeList locateXmlProperties(Element element) {
1681 XPathExpression expr;
1682 NodeList result = null;
1684 expr = xpath.compile("xml-properties");
1686 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1687 if (nodeset != null) {
1688 NodeList nodes = (NodeList) nodeset;
1689 if (nodes.getLength() > 0) {
1690 Element xmlProperty = (Element)nodes.item(0);
1691 result = xmlProperty.getElementsByTagName("xml-property");
1695 } catch (XPathExpressionException e) {
1696 e.printStackTrace();