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.openecomp";
671 if ( useAnnotationsInXsd ) {
672 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
673 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
675 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" +
676 " jaxb:version=\"2.1\" \r\n" +
677 " xmlns:annox=\"http://annox.dev.java.net\" \r\n" +
678 " jaxb:extensionBindingPrefixes=\"annox\">\n\n");
680 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
681 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n");
686 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
687 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
688 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
689 Document doc = dBuilder.parse(oxmFile);
691 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
692 Element bindingElement;
693 NodeList javaTypesNodes;
694 Element javaTypesElement;
696 Element javaTypeElement;
699 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
700 System.out.println( "missing <binding-nodes> in " + oxmFile );
704 bindingElement = (Element) bindingsNodes.item(0);
705 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
706 if ( javaTypesNodes.getLength() < 1 ) {
707 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
710 javaTypesElement = (Element) javaTypesNodes.item(0);
711 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
712 if ( javaTypeNodes.getLength() < 1 ) {
713 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
718 String attrName, attrValue;
720 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
721 javaTypeElement = (Element) javaTypeNodes.item(i);
722 NamedNodeMap attributes = javaTypeElement.getAttributes();
724 for ( int j = 0; j < attributes.getLength(); ++j ) {
725 attr = (Attr) attributes.item(j);
726 attrName = attr.getNodeName();
727 attrValue = attr.getNodeValue();
728 if ( attrName.equals("name"))
729 javaTypeName = attrValue;
731 if ( javaTypeName == null ) {
732 System.out.println( "<java-type> has no name attribute in " + oxmFile );
735 if ("Nodes".equals(javaTypeName)) {
736 //System.out.println("skipping Nodes entry (temporary feature)");
739 if ( !generatedJavaType.containsKey(javaTypeName) ) {
740 generatedJavaType.put(javaTypeName, null);
741 sb.append(processJavaTypeElement( javaTypeName, javaTypeElement ));
745 } catch (Exception e) {
749 sb.append("</xs:schema>\n");
750 return sb.toString();
753 private static boolean isStandardType( String elementType )
755 switch ( elementType ) {
756 case "java.lang.String":
757 case "java.lang.Long":
758 case "java.lang.Integer":
759 case"java.lang.Boolean":
765 private static Vector<String> getIndexedProps( String attrValue )
767 if ( attrValue == null )
769 StringTokenizer st = new StringTokenizer( attrValue, ",");
770 if ( st.countTokens() == 0 )
772 Vector<String> result = new Vector<String>();
773 while ( st.hasMoreTokens()) {
774 result.add(st.nextToken());
780 * Guaranteed to at least return non null but empty collection of edge descriptions
781 * @param nodeName name of the vertex whose edge relationships to return
782 * @return collection of node neighbors based on DbEdgeRules
784 private static Collection<EdgeDescription> getEdgeRulesFromJson( String path, boolean skipMatch )
787 ArrayList<EdgeDescription> result = new ArrayList<>();
788 Iterator<Map<String, Object>> edgeRulesIterator;
791 GenerateXsd x = new GenerateXsd();
793 List<Map<String, Object>> inEdges = JsonPath.parse(jsonEdges).read(path);
795 edgeRulesIterator = inEdges.iterator();
796 Map<String, Object> edgeMap;
804 EdgeDescription edgeDes;
806 while( edgeRulesIterator.hasNext() ){
807 edgeMap = edgeRulesIterator.next();
808 fromNode = (String)edgeMap.get("from");
809 toNode = (String)edgeMap.get("to");
811 if ( fromNode.equals(toNode)) {
815 edgeDes = x.new EdgeDescription();
816 edgeDes.setRuleKey(fromNode + "|" + toNode);
817 direction = (String)edgeMap.get("direction");
818 edgeDes.setDirection(direction);
819 multiplicity = (String)edgeMap.get("multiplicity");
820 edgeDes.setMultiplicity(multiplicity);
821 isParent = (String)edgeMap.get(EdgeProperty.CONTAINS.toString());
822 if ( "${direction}".equals(isParent)) {
823 edgeDes.setType(LineageType.PARENT);
825 edgeDes.setType(LineageType.UNRELATED);
827 hasDelTarget = (String)edgeMap.get(EdgeProperty.DELETE_OTHER_V.toString());
828 edgeDes.setHasDelTarget(hasDelTarget);
832 } catch (Exception ex) {
833 ex.printStackTrace();
840 * Guaranteed to at least return non null but empty collection of edge descriptions
841 * @param nodeName name of the vertex whose edge relationships to return
842 * @return collection of node neighbors based on DbEdgeRules
844 private static Collection<EdgeDescription> getEdgeRules( String nodeName )
846 String fromRulesPath = "$['rules'][?(@['from']=='" + nodeName + "')]";
847 String toRulesPath = "$['rules'][?(@['to']=='" + nodeName + "')]";
848 Collection<EdgeDescription> fromEdges = getEdgeRulesFromJson( fromRulesPath, false );
849 Collection<EdgeDescription> edges = getEdgeRulesFromJson( toRulesPath, true );
850 edges.addAll(fromEdges);
854 public static String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
855 StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
856 String getItemName, StringBuffer pathParams, String queryParams, String validEdges) {
858 String xmlRootElementName = null;
860 //Map<String, String> addJavaType = new HashMap<String, String>();
861 String useTag = null;
862 String useOpId = null;
867 case "ServiceDesignAndCreation":
869 case "LicenseManagement":
870 case "CloudInfrastructure":
871 case "ExternalSystem":
879 System.out.println( "processJavaTypeElementSwagger called with null path for javaTypeName " + javaTypeName);
882 if ( path == null || !(path.contains("cloud-infrastructure")))
883 switch ( javaTypeName) {
888 case "CloudInfrastructure":
891 case "ServiceDesignAndCreation":
892 case "LicenseManagement":
895 useTag = javaTypeName;
904 if ( !javaTypeName.equals("Inventory") ) {
905 if ( javaTypeName.equals("AaiInternal"))
908 useOpId = javaTypeName;
910 useOpId = opId + javaTypeName;
912 useTag = javaTypeName;
916 if ( javaTypeName.equals("GenericVnf"))
917 System.out.println( "Processing " + javaTypeName);
918 else if ( javaTypeName.equals("Service"))
919 System.out.println( "Processing " + javaTypeName);
920 else if ( javaTypeName.equals("SitePair"))
921 System.out.println( "Processing " + javaTypeName);
923 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
925 if ( parentNodes.getLength() == 0 ) {
926 //System.out.println( "no java-attributes for java-type " + javaTypeName);
931 NamedNodeMap attributes;
933 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
934 Element valElement = (Element) valNodes.item(0);
935 attributes = valElement.getAttributes();
936 for ( int i = 0; i < attributes.getLength(); ++i ) {
937 Attr attr = (Attr) attributes.item(i);
938 String attrName = attr.getNodeName();
940 String attrValue = attr.getNodeValue();
941 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
942 if ( attrName.equals("name"))
943 xmlRootElementName = attrValue;
946 if ( xmlRootElementName.equals("oam-networks"))
947 System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
951 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
956 Element childElement;
957 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
958 Element xmlPropElement;
959 String pathDescriptionProperty = null;
962 Vector<String> indexedProps = null;
964 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
965 if ( path != null && path.equals("/network/generic-vnfs"))
966 System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
968 if ( xmlPropNodes.getLength() > 0 ) {
970 for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
971 xmlPropElement = (Element)xmlPropNodes.item(i);
972 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
974 childNodes = xmlPropElement.getElementsByTagName("xml-property");
976 if ( childNodes.getLength() > 0 ) {
977 for ( int j = 0; j < childNodes.getLength(); ++j ) {
978 childElement = (Element)childNodes.item(j);
980 int useValue = VALUE_NONE;
981 attributes = childElement.getAttributes();
982 for ( int k = 0; k < attributes.getLength(); ++k ) {
983 Attr attr = (Attr) attributes.item(k);
984 String attrName = attr.getNodeName();
985 String attrValue = attr.getNodeValue();
986 if ( attrName == null || attrValue == null )
988 if ( attrName.equals("name") && attrValue.equals("description")) {
989 useValue = VALUE_DESCRIPTION;
991 if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
992 pathDescriptionProperty = attrValue;
994 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
996 if ( attrValue.equals("indexedProps")) {
997 useValue = VALUE_INDEXED_PROPS;
999 if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
1000 indexedProps = getIndexedProps( attrValue );
1007 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
1010 if ( javaTypeName.equals("RelationshipList")) {
1011 System.out.println( "Skipping " + javaTypeName);
1012 generatedJavaType.put(javaTypeName, null);
1017 Element parentElement = (Element)parentNodes.item(0);
1018 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
1021 String attrDescription = null;
1023 Element xmlElementElement;
1024 String addType = null;
1025 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1026 String elementName = null;
1027 StringBuffer sbParameters = new StringBuffer();
1029 StringBuffer sbRequired = new StringBuffer();
1030 int requiredCnt = 0;
1031 int propertyCnt = 0;
1032 StringBuffer sbProperties = new StringBuffer();
1033 StringBuffer sbIndexedParams = new StringBuffer();
1037 if ( xmlRootElementName.equals("inventory"))
1039 else if ( path == null )
1040 //path = "/aai/" + apiVersion;
1041 path = "/" + xmlRootElementName;
1043 path += "/" + xmlRootElementName;
1044 st = new StringTokenizer(path, "/");
1046 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1047 System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1049 boolean genPath = false;
1051 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1052 System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1054 if ( st.countTokens() > 1 && getItemName == null ) {
1055 if ( appliedPaths.containsKey(path))
1057 appliedPaths.put(path, null);
1059 if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1062 if ( path.endsWith("/relationship-list")) {
1068 Vector<String> addTypeV = null;
1069 if ( xmlElementNodes.getLength() > 0 ) {
1071 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1072 xmlElementElement = (Element)xmlElementNodes.item(i);
1073 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1075 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1076 if ( childNodes.getLength() > 0 ) {
1077 childElement = (Element)childNodes.item(0);
1079 attributes = childElement.getAttributes();
1080 for ( int k = 0; k < attributes.getLength(); ++k ) {
1081 Attr attr = (Attr) attributes.item(k);
1082 String attrName = attr.getNodeName();
1083 String attrValue = attr.getNodeValue();
1084 if ( attrName.equals("name")) {
1085 xmlElementWrapper = attrValue;
1086 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1092 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1093 attrDescription = null;
1094 if ( valNodes.getLength() > 0 ) {
1095 for ( int j = 0; j < valNodes.getLength(); ++j ) {
1096 valElement = (Element)valNodes.item(j);
1097 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1099 childNodes = valElement.getElementsByTagName("xml-property");
1100 if ( childNodes.getLength() > 0 ) {
1101 childElement = (Element)childNodes.item(0);
1103 attributes = childElement.getAttributes();
1104 attrDescription = null;
1105 boolean useValue = false;
1106 for ( int k = 0; k < attributes.getLength(); ++k ) {
1107 Attr attr = (Attr) attributes.item(k);
1108 String attrName = attr.getNodeName();
1109 String attrValue = attr.getNodeValue();
1110 if ( attrName.equals("name") && attrValue.equals("description")) {
1113 if ( useValue && attrName.equals("value")) {
1114 attrDescription = attrValue;
1115 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1123 attributes = xmlElementElement.getAttributes();
1124 addTypeV = null; // vector of 1
1127 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1128 for ( int j = 0; j < attributes.getLength(); ++j ) {
1129 Attr attr = (Attr) attributes.item(j);
1130 String attrName = attr.getNodeName();
1132 String attrValue = attr.getNodeValue();
1133 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1134 if ( attrName.equals("name")) {
1135 elementName = attrValue;
1138 if ( attrName.equals("type") && getItemName == null ) {
1139 elementType = attrValue;
1140 if ( attrValue.contains(apiVersionFmt) ) {
1141 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1142 if ( addTypeV == null )
1143 addTypeV = new Vector<String>();
1144 addTypeV.add(addType);
1148 if ( attrName.equals("xml-key")) {
1149 elementIsKey = attrValue;
1150 path += "/{" + elementName + "}";
1152 if ( attrName.equals("required")) {
1153 elementIsRequired = attrValue;
1155 if ( attrName.equals("container-type")) {
1156 elementContainerType = attrValue;
1159 if ( getItemName != null ) {
1160 if ( getItemName.equals("array") ) {
1161 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1162 //System.out.println( " returning array " + elementName );
1166 } else { // not an array check
1167 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1168 //System.out.println( " returning object " + elementName );
1173 //System.out.println( " returning null" );
1176 if ( elementIsRequired != null ) {
1177 if ( requiredCnt == 0 )
1178 sbRequired.append(" required:\n");
1180 if ( addTypeV != null ) {
1181 for ( int k = 0; k < addTypeV.size(); ++i ) {
1182 sbRequired.append(" - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1185 sbRequired.append(" - " + elementName + "\n");
1189 if ( elementIsKey != null ) {
1190 sbParameters.append((" - name: " + elementName + "\n"));
1191 sbParameters.append((" in: path\n"));
1192 if ( attrDescription != null && attrDescription.length() > 0 )
1193 sbParameters.append((" description: " + attrDescription + "\n"));
1194 sbParameters.append((" required: true\n"));
1195 if ( elementType.equals("java.lang.String"))
1196 sbParameters.append(" type: string\n");
1197 if ( elementType.equals("java.lang.Long")) {
1198 sbParameters.append(" type: integer\n");
1199 sbParameters.append(" format: int64\n");
1201 if ( elementType.equals("java.lang.Integer")) {
1202 sbParameters.append(" type: integer\n");
1203 sbParameters.append(" format: int32\n");
1205 if ( elementType.equals("java.lang.Boolean"))
1206 sbParameters.append(" type: boolean\n");
1209 } else if ( indexedProps != null
1210 && indexedProps.contains(elementName ) ) {
1211 sbIndexedParams.append((" - name: " + elementName + "\n"));
1212 sbIndexedParams.append((" in: query\n"));
1213 if ( attrDescription != null && attrDescription.length() > 0 )
1214 sbIndexedParams.append((" description: " + attrDescription + "\n"));
1215 sbIndexedParams.append((" required: false\n"));
1216 if ( elementType.equals("java.lang.String"))
1217 sbIndexedParams.append(" type: string\n");
1218 if ( elementType.equals("java.lang.Long")) {
1219 sbIndexedParams.append(" type: integer\n");
1220 sbIndexedParams.append(" format: int64\n");
1222 if ( elementType.equals("java.lang.Integer")) {
1223 sbIndexedParams.append(" type: integer\n");
1224 sbIndexedParams.append(" format: int32\n");
1226 if ( elementType.equals("java.lang.Boolean"))
1227 sbIndexedParams.append(" type: boolean\n");
1231 if ( elementName != null && elementName.equals("inventory-item"))
1232 System.out.println( "processing inventory-item elementName");
1235 if ( isStandardType(elementType)) {
1236 sbProperties.append(" " + elementName + ":\n");
1238 sbProperties.append(" type: ");
1240 if ( elementType.equals("java.lang.String"))
1241 sbProperties.append("string\n");
1242 else if ( elementType.equals("java.lang.Long")) {
1243 sbProperties.append("integer\n");
1244 sbProperties.append(" format: int64\n");
1246 else if ( elementType.equals("java.lang.Integer")){
1247 sbProperties.append("integer\n");
1248 sbProperties.append(" format: int32\n");
1250 else if ( elementType.equals("java.lang.Boolean"))
1251 sbProperties.append("boolean\n");
1252 if ( attrDescription != null && attrDescription.length() > 0 )
1253 sbProperties.append(" description: " + attrDescription + "\n");
1256 //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1258 if ( addTypeV != null ) {
1259 StringBuffer newPathParams = null;
1260 if ( pathParams != null ) {
1261 newPathParams = new StringBuffer();
1262 newPathParams.append(pathParams);
1264 if ( sbParameters.toString().length() > 0 ) {
1265 if ( newPathParams == null )
1266 newPathParams = new StringBuffer();
1267 newPathParams.append(sbParameters);
1269 String newQueryParams = null;
1270 if ( sbIndexedParams.toString().length() > 0 ) {
1271 if ( queryParams == null )
1272 newQueryParams = sbIndexedParams.toString();
1274 newQueryParams = queryParams + sbIndexedParams.toString();
1276 newQueryParams = queryParams;
1278 for ( int k = 0; k < addTypeV.size(); ++k ) {
1279 addType = addTypeV.elementAt(k);
1281 if ( opId == null || !opId.contains(addType)) {
1282 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1283 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, null,
1284 newPathParams, newQueryParams, validEdges);
1286 // need item name of array
1287 String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1288 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1289 "array", null, null, null );
1291 if ( itemName != null ) {
1292 if ( addType.equals("AaiInternal") ) {
1293 //System.out.println( "addType AaiInternal, skip properties");
1295 } else if ( getItemName == null) {
1297 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1298 sbProperties.append(" type: array\n items:\n");
1299 sbProperties.append(" $ref: \"#/definitions/" + itemName + "\"\n");
1300 if ( attrDescription != null && attrDescription.length() > 0 )
1301 sbProperties.append(" description: " + attrDescription + "\n");
1304 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1305 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, "other" );
1306 if ( itemName != null ) {
1308 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1309 // need properties for getXmlRootElementName(addType)
1310 newPathParams = null;
1311 if ( pathParams != null ) {
1312 newPathParams = new StringBuffer();
1313 newPathParams.append(pathParams);
1315 if ( sbParameters.toString().length() > 0 ) {
1316 if ( newPathParams == null )
1317 newPathParams = new StringBuffer();
1318 newPathParams.append(sbParameters);
1320 newQueryParams = null;
1321 if ( sbIndexedParams.toString().length() > 0 ) {
1322 if ( queryParams == null )
1323 newQueryParams = sbIndexedParams.toString();
1325 newQueryParams = queryParams + sbIndexedParams.toString();
1327 newQueryParams = queryParams;
1329 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1330 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1331 null, newPathParams, newQueryParams, validEdges );
1332 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1333 sbProperties.append(" type: array\n items: \n");
1334 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1336 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1337 sbProperties.append(" type: object\n");
1338 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1340 if ( attrDescription != null && attrDescription.length() > 0 )
1341 sbProperties.append(" description: " + attrDescription + "\n");
1345 System.out.println(" unable to define swagger object for " + addType);
1349 //if ( getItemName == null) looking for missing properties
1350 //generatedJavaType.put(addType, null);
1357 if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1358 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1361 if ( !path.endsWith("/relationship") ) {
1362 pathSb.append(" " + path + ":\n" );
1363 pathSb.append(" get:\n");
1364 pathSb.append(" tags:\n");
1365 pathSb.append(" - " + tag + "\n");
1366 pathSb.append(" summary: returns " + xmlRootElementName + "\n");
1368 pathSb.append(" description: returns " + xmlRootElementName + "\n");
1369 pathSb.append(" operationId: get" + useOpId + "\n");
1370 pathSb.append(" produces:\n");
1371 pathSb.append(" - application/json\n");
1372 pathSb.append(" - application/xml\n");
1374 pathSb.append(" responses:\n");
1375 pathSb.append(" \"200\":\n");
1376 pathSb.append(" description: successful operation\n");
1377 pathSb.append(" schema:\n");
1378 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1379 pathSb.append(" \"default\":\n");
1380 pathSb.append(" " + responsesUrl);
1382 pathSb.append(" \"200\":\n");
1383 pathSb.append(" description: successful operation\n");
1384 pathSb.append(" schema:\n");
1385 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1386 pathSb.append(" \"404\":\n");
1387 pathSb.append(" description: resource was not found\n");
1388 pathSb.append(" \"400\":\n");
1389 pathSb.append(" description: bad request\n");
1391 if ( path.indexOf('{') > 0 ) {
1393 if ( sbParameters.toString().length() > 0 ) {
1394 if ( pathParams == null )
1395 pathParams = new StringBuffer();
1396 pathParams.append(sbParameters);
1398 if ( pathParams != null) {
1399 pathSb.append(" parameters:\n");
1400 pathSb.append(pathParams);
1402 System.out.println( "null pathParams for " + useOpId);
1403 if ( sbIndexedParams.toString().length() > 0 ) {
1404 if ( queryParams == null )
1405 queryParams = sbIndexedParams.toString();
1407 queryParams = queryParams + sbIndexedParams.toString();
1409 if ( queryParams != null ) {
1410 if ( pathParams == null ) {
1411 pathSb.append(" parameters:\n");
1413 pathSb.append(queryParams);
1417 boolean skipPutDelete = false; // no put or delete for "all"
1418 if ( !path.endsWith("/relationship") ) {
1419 if ( !path.endsWith("}") ){
1420 skipPutDelete = true;
1424 if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1426 if ( path.endsWith("/relationship") ) {
1427 pathSb.append(" " + path + ":\n" );
1429 pathSb.append(" put:\n");
1430 pathSb.append(" tags:\n");
1431 pathSb.append(" - " + tag + "\n");
1433 if ( path.endsWith("/relationship") ) {
1434 pathSb.append(" summary: see node definition for valid relationships\n");
1436 pathSb.append(" summary: create or update an existing " + xmlRootElementName + "\n");
1437 pathSb.append(" description: create or update an existing " + xmlRootElementName + "\n");
1439 pathSb.append(" operationId: createOrUpdate" + useOpId + "\n");
1440 pathSb.append(" consumes:\n");
1441 pathSb.append(" - application/json\n");
1442 pathSb.append(" - application/xml\n");
1443 pathSb.append(" produces:\n");
1444 pathSb.append(" - application/json\n");
1445 pathSb.append(" - application/xml\n");
1446 pathSb.append(" responses:\n");
1447 pathSb.append(" \"default\":\n");
1448 pathSb.append(" " + responsesUrl);
1450 pathSb.append(" responses:\n");
1451 pathSb.append(" \"200\":\n");
1452 pathSb.append(" description: existing resource has been modified and there is a response buffer\n");
1453 pathSb.append(" \"201\":\n");
1454 pathSb.append(" description: new resource is created\n");
1455 pathSb.append(" \"202\":\n");
1456 pathSb.append(" description: action requested but may have taken other actions as well, which are returned in the response payload\n");
1457 pathSb.append(" \"204\":\n");
1458 pathSb.append(" description: existing resource has been modified and there is no response buffer\n");
1459 pathSb.append(" \"400\":\n");
1460 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1461 pathSb.append(" \"404\":\n");
1462 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1464 pathSb.append(" parameters:\n");
1465 //pathSb.append(" - in: path\n");
1466 pathSb.append(pathParams); // for nesting
1467 pathSb.append(" - name: body\n");
1468 pathSb.append(" in: body\n");
1469 pathSb.append(" description: " + xmlRootElementName + " object that needs to be created or updated\n");
1470 pathSb.append(" required: true\n");
1471 pathSb.append(" schema:\n");
1472 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1474 if ( queryParams != null ) {
1475 pathSb.append(queryParams);
1479 pathSb.append(" delete:\n");
1480 pathSb.append(" tags:\n");
1481 pathSb.append(" - " + tag + "\n");
1482 pathSb.append(" summary: delete an existing " + xmlRootElementName + "\n");
1484 pathSb.append(" description: delete an existing " + xmlRootElementName + "\n");
1486 pathSb.append(" operationId: delete" + useOpId + "\n");
1487 pathSb.append(" consumes:\n");
1488 pathSb.append(" - application/json\n");
1489 pathSb.append(" - application/xml\n");
1490 pathSb.append(" produces:\n");
1491 pathSb.append(" - application/json\n");
1492 pathSb.append(" - application/xml\n");
1493 pathSb.append(" responses:\n");
1494 pathSb.append(" \"default\":\n");
1495 pathSb.append(" " + responsesUrl);
1497 pathSb.append(" responses:\n");
1498 pathSb.append(" \"200\":\n");
1499 pathSb.append(" description: successful, the response includes an entity describing the status\n");
1500 pathSb.append(" \"204\":\n");
1501 pathSb.append(" description: successful, action has been enacted but the response does not include an entity\n");
1502 pathSb.append(" \"400\":\n");
1503 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1504 pathSb.append(" \"404\":\n");
1505 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1507 pathSb.append(" parameters:\n");
1508 //pathSb.append(" - in: path\n");
1509 pathSb.append(pathParams); // for nesting
1510 if ( !path.endsWith("/relationship") ) {
1511 pathSb.append(" - name: resource-version\n");
1513 pathSb.append(" in: query\n");
1514 pathSb.append(" description: resource-version for concurrency\n");
1515 pathSb.append(" required: true\n");
1516 pathSb.append(" type: string\n");
1519 if ( queryParams != null ) {
1520 pathSb.append(queryParams);
1526 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1530 definitionsSb.append(" " + xmlRootElementName + ":\n");
1531 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1532 if ( edges.size() > 0 ) {
1533 StringBuffer sbEdge = new StringBuffer();
1534 sbEdge.append(" ###### Related Nodes\n");
1535 for (EdgeDescription ed : edges) {
1536 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1537 sbEdge.append(" - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1538 sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1539 sbEdge.append("\n");
1542 for (EdgeDescription ed : edges) {
1543 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1544 sbEdge.append(" - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1545 sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1546 sbEdge.append("\n");
1549 validEdges = sbEdge.toString();
1552 // Handle description property. Might have a description OR valid edges OR both OR neither.
1553 // Only put a description: tag if there is at least one.
1554 if (pathDescriptionProperty != null || validEdges != null) {
1555 definitionsSb.append(" description: |\n");
1557 if ( pathDescriptionProperty != null )
1558 definitionsSb.append(" " + pathDescriptionProperty + "\n" );
1559 if (validEdges != null)
1560 definitionsSb.append(validEdges);
1563 if ( requiredCnt > 0 )
1564 definitionsSb.append(sbRequired);
1565 if ( propertyCnt > 0 ) {
1566 definitionsSb.append(" properties:\n");
1567 definitionsSb.append(sbProperties);
1569 generatedJavaType.put(xmlRootElementName, null);
1573 public static String generateSwaggerFromOxmFile( File oxmFile )
1576 StringBuffer sb = new StringBuffer();
1577 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");
1578 sb.append(" title: Active and Available Inventory REST API\n");
1579 sb.append(" license:\n name: Apache 2.0\n url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1580 sb.append(" contact:\n name:\n url:\n email:\n");
1581 sb.append("host:\nbasePath: /aai/" + apiVersion + "\n");
1582 sb.append("schemes:\n - https\npaths:\n");
1584 sb.append("responses:\n");
1585 sb.append(" \"200\":\n");
1586 sb.append(" description: successful operation\n");
1587 sb.append(" \"404\":\n");
1588 sb.append(" description: resource was not found\n");
1589 sb.append(" \"400\":\n");
1590 sb.append(" description: bad request\n");
1593 File initialFile = new File("src/main/resources/dbedgerules/DbEdgeRules_" + apiVersion + ".json");
1594 InputStream is = new FileInputStream(initialFile);
1596 Scanner scanner = new Scanner(is);
1597 jsonEdges = scanner.useDelimiter("\\Z").next();
1601 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1602 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1603 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1604 Document doc = dBuilder.parse(oxmFile);
1606 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1607 Element bindingElement;
1608 NodeList javaTypesNodes;
1609 Element javaTypesElement;
1611 Element javaTypeElement;
1614 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1615 System.out.println( "missing <binding-nodes> in " + oxmFile );
1619 bindingElement = (Element) bindingsNodes.item(0);
1620 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1621 if ( javaTypesNodes.getLength() < 1 ) {
1622 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1625 javaTypesElement = (Element) javaTypesNodes.item(0);
1627 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1628 if ( javaTypeNodes.getLength() < 1 ) {
1629 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1633 String javaTypeName;
1634 String attrName, attrValue;
1636 StringBuffer pathSb = new StringBuffer();
1638 StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1640 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1641 javaTypeElement = (Element) javaTypeNodes.item(i);
1642 NamedNodeMap attributes = javaTypeElement.getAttributes();
1643 javaTypeName = null;
1644 for ( int j = 0; j < attributes.getLength(); ++j ) {
1645 attr = (Attr) attributes.item(j);
1646 attrName = attr.getNodeName();
1647 attrValue = attr.getNodeValue();
1648 if ( attrName.equals("name"))
1649 javaTypeName = attrValue;
1651 if ( javaTypeName == null ) {
1652 System.out.println( "<java-type> has no name attribute in " + oxmFile );
1655 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1657 //generatedJavaType.put(javaTypeName, null);
1658 //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1660 processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1661 definitionsSb, null, null, null, null, null, null, null);
1665 //System.out.println( "definitions block\n" + definitionsSb.toString());
1666 sb.append(definitionsSb.toString());
1667 //sb.append(definitionsSb);
1669 } catch (Exception e) {
1670 e.printStackTrace();
1673 //System.out.println("generated " + sb.toString());
1674 return sb.toString();
1677 private static NodeList locateXmlProperties(Element element) {
1678 XPathExpression expr;
1679 NodeList result = null;
1681 expr = xpath.compile("xml-properties");
1683 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1684 if (nodeset != null) {
1685 NodeList nodes = (NodeList) nodeset;
1686 if (nodes.getLength() > 0) {
1687 Element xmlProperty = (Element)nodes.item(0);
1688 result = xmlProperty.getElementsByTagName("xml-property");
1692 } catch (XPathExpressionException e) {
1693 e.printStackTrace();