2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.aai.util;
23 import com.google.common.base.Joiner;
24 import com.jayway.jsonpath.JsonPath;
25 import org.openecomp.aai.introspection.Version;
26 import org.openecomp.aai.serialization.db.EdgeProperty;
29 import javax.xml.XMLConstants;
30 import javax.xml.parsers.DocumentBuilder;
31 import javax.xml.parsers.DocumentBuilderFactory;
32 import javax.xml.xpath.*;
34 import java.nio.charset.Charset;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
42 public class GenerateXsd {
44 static String apiVersion = null;
45 static String apiVersionFmt = null;
46 static boolean useAnnotationsInXsd = false;
47 static String responsesUrl = null;
48 static String responsesLabel = null;
49 static String jsonEdges = null;
51 static Map<String, String> generatedJavaType;
52 static Map<String, String> appliedPaths;
53 static NodeList javaTypeNodes;
56 public static final int VALUE_NONE = 0;
57 public static final int VALUE_DESCRIPTION = 1;
58 public static final int VALUE_INDEXED_PROPS = 2;
60 private static final String generateTypeXSD = "xsd";
61 private static final String generateTypeYAML = "yaml";
63 private static final String root = "../aai-schema/src/main/resources";
64 private static final String xsd_dir = root + "/aai_schema";
65 private static final String yaml_dir = root + "/aai_swagger_yaml";
67 private static int annotationsStartVersion = 9; // minimum version to support annotations in xsd
68 private static int swaggerSupportStartsVersion = 7; // minimum version to support swagger documentation
70 private static XPath xpath = XPathFactory.newInstance().newXPath();
73 private enum LineageType {
74 PARENT, CHILD, UNRELATED;
76 private class EdgeDescription {
78 private String ruleKey;
79 private LineageType type = LineageType.UNRELATED;
80 private String direction;
81 private String multiplicity;
82 private boolean hasDelTarget = false;
84 public String getRuleKey() {
87 public String getMultiplicity() {
90 public String getDirection() {
93 public void setRuleKey(String val) {
96 public void setType(LineageType val) {
99 public void setDirection(String val) {
100 this.direction = val;
102 public void setMultiplicity(String val) {
103 this.multiplicity=val;
105 public void setHasDelTarget(String val) {
106 hasDelTarget = Boolean.parseBoolean(val);
109 public String getRelationshipDescription(String fromTo, String otherNodeName) {
113 if ("FROM".equals(fromTo)) {
114 if ("OUT".equals(direction)) {
115 if (LineageType.PARENT == type) {
116 result = " (is composed of "+otherNodeName;
120 if (LineageType.CHILD == type) {
121 result = " (comprises "+otherNodeName;
123 else if (LineageType.PARENT == type) {
124 result = " (comprises "+otherNodeName;
128 if ("OUT".equals(direction)) {
129 if (LineageType.PARENT == type) {
130 result = " (comprises "+otherNodeName;
133 if (LineageType.PARENT == type) {
134 result = " (is composed of "+otherNodeName;
139 // if (type != null) {
140 // if (LineageType.PARENT.equals(type) && "FROM".equals(fromTo)) {
141 // if ("OUT".equals(direction)) {
142 // result = " (is composed of "+otherNodeName;
144 // result = " (comprises "+otherNodeName;
147 // result = " (comprises " + otherNodeName;
148 // // if (!(multiplicity.startsWith("One"))) {
149 // // System.err.println("Surprised to find multiplicity "+multiplicity+" with comprises for "+ruleKey);
153 if ("TO".equals(fromTo)) {
154 if (result.length() == 0) result = result + " (";
155 else result = result + ", ";
157 result = result + mapMultiplicity(fromTo);
158 if (hasDelTarget) result = result + ", will delete target node";
161 if (result.length() > 0) result = result + ")";
166 private String mapMultiplicity(String fromTo) {
167 String result = multiplicity;
168 // Below logic works if an IN switches multiplicity, which it doesn't today.
169 // if ("TO".equals(fromTo)) {
170 // if (direction.equals("OUT")) {
171 // result = multiplicity;
173 // result = switchMultiplicity(multiplicity);
176 // if (direction.equals("OUT")) {
177 // result = multiplicity;
179 // result = switchMultiplicity(multiplicity);
185 // private String switchMultiplicity(String val) throws IllegalArgumentException
187 // String result = null;
194 // result = "One2Many";
197 // result = "Many2One";
200 // throw new IllegalArgumentException("Multiplicity cannot be "+val);
202 // System.out.println("Switched Multiplicity from "+val+" to "+result);
207 private static boolean validVersion(String versionToGen) {
209 if ("ALL".equalsIgnoreCase(versionToGen)) {
213 for (Version v : Version.values()) {
214 if (v.name().equals(versionToGen)) {
222 private static boolean versionUsesAnnotations( String version) {
223 if (new Integer(version.substring(1)).intValue() >= annotationsStartVersion ) {
229 private static boolean versionSupportsSwagger( String version) {
230 if (new Integer(version.substring(1)).intValue() >= swaggerSupportStartsVersion ) {
236 public static void main(String[] args) throws IOException {
237 String versionToGen = System.getProperty("gen_version").toLowerCase();
238 String fileTypeToGen = System.getProperty("gen_type").toLowerCase();
239 if ( fileTypeToGen == null ) {
240 fileTypeToGen = generateTypeXSD;
243 if ( !fileTypeToGen.equals( generateTypeXSD ) && !fileTypeToGen.equals( generateTypeYAML )) {
244 System.err.println("Invalid gen_type passed. " + fileTypeToGen);
249 if ( versionToGen == null ) {
250 System.err.println("Version is required, ie v<n> or ALL.");
254 responsesUrl = System.getProperty("yamlresponses_url");
255 String responsesLabel = System.getProperty("yamlresponses_label");
256 List<Version> versionsToGen = new ArrayList<>();
259 if (!"ALL".equalsIgnoreCase(versionToGen) && !versionToGen.matches("v\\d+") && !validVersion(versionToGen)) {
260 System.err.println("Invalid version passed. " + versionToGen);
264 if ("ALL".equalsIgnoreCase(versionToGen)) {
265 versionsToGen = Arrays.asList(Version.values());
266 Collections.sort(versionsToGen);
267 Collections.reverse(versionsToGen);
269 versionsToGen.add(Version.valueOf(versionToGen));
272 if ( fileTypeToGen.equals(generateTypeYAML) ) {
273 if ( responsesUrl == null || responsesUrl.length() < 1
274 || responsesLabel == null || responsesLabel.length() < 1 ) {
275 System.err.println("generating swagger yaml file requires yamlresponses_url and yamlresponses_label properties" );
278 responsesUrl = "description: "+ responsesLabel+ "(" + responsesUrl + ").\n";
280 String oxmPath = root + "/oxm/";
286 for (Version v : versionsToGen) {
287 apiVersion = v.toString();
288 System.out.println("Generating " + apiVersion + " " + fileTypeToGen);
289 File oxm_file = new File(oxmPath + "aai_oxm_" + apiVersion + ".xml");
290 apiVersionFmt = "." + apiVersion + ".";
291 generatedJavaType = new HashMap<String, String>();
292 appliedPaths = new HashMap<String, String>();
293 if ( fileTypeToGen.equals(generateTypeXSD) ) {
294 useAnnotationsInXsd = versionUsesAnnotations(apiVersion);
295 outfileName = xsd_dir + "/aai_schema_" + apiVersion + "." + generateTypeXSD;
296 fileContent = processOxmFile(oxm_file, v);
297 } else if ( versionSupportsSwagger(apiVersion )) {
298 outfileName = yaml_dir + "/aai_swagger_" + apiVersion + "." + generateTypeYAML;
299 fileContent = generateSwaggerFromOxmFile( oxm_file);
303 outfile = new File(outfileName);
304 File parentDir = outfile.getParentFile();
305 if(! parentDir.exists())
309 outfile.createNewFile();
310 } catch (IOException e) {
311 System.out.println( "Exception creating output file " + outfileName);
314 BufferedWriter bw = null;
316 Charset charset = Charset.forName("UTF-8");
317 Path path = Paths.get(outfileName);
318 bw = Files.newBufferedWriter(path, charset);
319 bw.write(fileContent);
320 } catch ( IOException e) {
321 System.out.println( "Exception writing output file " + outfileName);
328 System.out.println( "GeneratedXSD successful, saved in " + outfileName);
334 public static String processJavaTypeElement( String javaTypeName, Element javaTypeElement) {
336 String xmlRootElementName = null;
338 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
339 StringBuffer sb = new StringBuffer();
340 if ( parentNodes.getLength() == 0 ) {
341 //System.out.println( "no java-attributes for java-type " + javaTypeName);
346 NamedNodeMap attributes;
348 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
349 Element valElement = (Element) valNodes.item(0);
350 attributes = valElement.getAttributes();
351 for ( int i = 0; i < attributes.getLength(); ++i ) {
352 Attr attr = (Attr) attributes.item(i);
353 String attrName = attr.getNodeName();
355 String attrValue = attr.getNodeValue();
356 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
357 if ( attrName.equals("name"))
358 xmlRootElementName = attrValue;
361 if ( javaTypeName.equals("RelationshipList")) {
362 System.out.println( "Skipping " + javaTypeName);
363 generatedJavaType.put(javaTypeName, null);
368 Element parentElement = (Element)parentNodes.item(0);
369 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
371 Element childElement;
372 String xmlElementWrapper;
374 Element xmlElementElement;
376 String elementName, elementType, elementIsKey, elementIsRequired, elementContainerType;
377 StringBuffer sb1 = new StringBuffer();
378 if ( xmlElementNodes.getLength() > 0 ) {
379 sb1.append(" <xs:element name=\"" + xmlRootElementName + "\">\n");
380 sb1.append(" <xs:complexType>\n");
381 NodeList properties = GenerateXsd.locateXmlProperties(javaTypeElement);
382 if (properties != null && useAnnotationsInXsd) {
383 //System.out.println("properties found for: " + xmlRootElementName);
384 sb1.append(" <xs:annotation>\r\n");
385 insertAnnotation(properties, false, "class", sb1, " ");
387 sb1.append(" </xs:annotation>\r\n");
389 System.out.println("no properties found for: " + xmlRootElementName);
391 sb1.append(" <xs:sequence>\n");
392 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
394 xmlElementElement = (Element)xmlElementNodes.item(i);
395 childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
397 xmlElementWrapper = null;
398 if ( childNodes.getLength() > 0 ) {
399 childElement = (Element)childNodes.item(0);
401 attributes = childElement.getAttributes();
402 for ( int k = 0; k < attributes.getLength(); ++k ) {
403 Attr attr = (Attr) attributes.item(k);
404 String attrName = attr.getNodeName();
405 String attrValue = attr.getNodeValue();
406 if ( attrName.equals("name")) {
407 xmlElementWrapper = attrValue;
408 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
413 attributes = xmlElementElement.getAttributes();
417 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
418 for ( int j = 0; j < attributes.getLength(); ++j ) {
419 Attr attr = (Attr) attributes.item(j);
420 String attrName = attr.getNodeName();
422 String attrValue = attr.getNodeValue();
423 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
424 if ( attrName.equals("name")) {
425 elementName = attrValue;
427 if ( attrName.equals("type")) {
428 elementType = attrValue;
429 if ( attrValue.contains(apiVersionFmt) ) {
430 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
431 if ( !generatedJavaType.containsKey(addType) ) {
432 generatedJavaType.put(addType, attrValue);
433 sb.append(processJavaTypeElement( addType, getJavaTypeElement(addType) ));
439 if ( attrName.equals("xml-key")) {
440 elementIsKey = attrValue;
442 if ( attrName.equals("required")) {
443 elementIsRequired = attrValue;
445 if ( attrName.equals("container-type")) {
446 elementContainerType = attrValue;
450 if ( xmlElementWrapper != null ) {
451 sb1.append(" <xs:element name=\"" + xmlElementWrapper +"\"");
452 if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) {
453 sb1.append(" minOccurs=\"0\"");
456 sb1.append(" <xs:complexType>\n");
457 properties = GenerateXsd.locateXmlProperties(javaTypeElement);
458 if (properties != null && useAnnotationsInXsd) {
459 sb1.append(" <xs:annotation>\r\n");
460 insertAnnotation(properties, false, "class", sb1, " ");
461 sb1.append(" </xs:annotation>\r\n");
463 System.out.println("no properties found for: " + xmlElementWrapper);
465 sb1.append(" <xs:sequence>\n");
468 if ("Nodes".equals(addType)) {
469 //System.out.println ("Skipping nodes, temporary testing");
472 if ( addType != null ) {
473 //sb1.append(" <xs:element ref=\"tns:" + elementName +"\"");
474 sb1.append(" <xs:element ref=\"tns:" + getXmlRootElementName(addType) +"\"");
476 sb1.append(" <xs:element name=\"" + elementName +"\"");
478 if ( elementType.equals("java.lang.String"))
479 sb1.append(" type=\"xs:string\"");
480 //if ( elementType.equals("java.lang.String"))
481 //sb1.append(" type=\"xs:string\"");
482 if ( elementType.equals("java.lang.Long"))
483 sb1.append(" type=\"xs:unsignedInt\"");
484 if ( elementType.equals("java.lang.Integer"))
485 sb1.append(" type=\"xs:int\"");
486 if ( elementType.equals("java.lang.Boolean"))
487 sb1.append(" type=\"xs:boolean\"");
488 //if ( elementIsRequired != null && elementIsRequired.equals("true")||addType != null) {
489 if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) {
490 sb1.append(" minOccurs=\"0\"");
492 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
493 sb1.append(" maxOccurs=\"unbounded\"");
495 properties = GenerateXsd.locateXmlProperties(xmlElementElement);
496 if (properties != null || elementIsKey != null) {
498 if ( useAnnotationsInXsd ) {
499 sb1.append(" <xs:annotation>\r\n");
500 insertAnnotation(properties, elementIsKey != null, "field", sb1, " ");
501 sb1.append(" </xs:annotation>\r\n");
503 if (xmlElementWrapper== null) {
504 sb1.append(" </xs:element>\n");
509 if ( xmlElementWrapper != null ) {
510 sb1.append(" </xs:sequence>\n");
511 sb1.append(" </xs:complexType>\n");
512 sb1.append(" </xs:element>\n");
516 if ( xmlRootElementName.equals("notify") ||
517 xmlRootElementName.equals("relationship") ||
518 xmlRootElementName.equals("relationship-data") ||
519 xmlRootElementName.equals("related-to-property") )
521 sb1.append(" <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n");
523 sb1.append(" </xs:sequence>\n");
524 sb1.append(" </xs:complexType>\n");
525 sb1.append(" </xs:element>\n");
528 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
529 Element valElement = (Element) valNodes.item(0);
530 attributes = valElement.getAttributes();
531 for ( int i = 0; i < attributes.getLength(); ++i ) {
532 Attr attr = (Attr) attributes.item(i);
533 String attrName = attr.getNodeName();
535 String attrValue = attr.getNodeValue();
536 System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
537 if ( attrValue.equals("name"))
538 xmlRootElementName = attrValue;
542 if ( xmlElementNodes.getLength() < 1 ) {
543 sb.append(" <xs:element name=\"" + xmlRootElementName + "\">\n");
544 sb.append(" <xs:complexType>\n");
545 sb.append(" <xs:sequence/>\n");
546 sb.append(" </xs:complexType>\n");
547 sb.append(" </xs:element>\n");
548 generatedJavaType.put(javaTypeName, null);
549 return sb.toString();
554 return sb.toString();
557 private static void insertAnnotation(NodeList items, boolean isKey, String target, StringBuffer sb1, String indentation) {
558 if (items != null || isKey) {
559 List<String> metadata = new ArrayList<>();
565 metadata.add("isKey=true");
568 for (int i = 0; i < items.getLength(); i++) {
569 item = (Element)items.item(i);
570 name = item.getAttribute("name");
571 value = item.getAttribute("value");
572 if (name.equals("abstract")) {
574 } else if (name.equals("extends")) {
575 name = "extendsFrom";
577 metadata.add(name + "=\"" + value.replaceAll("&", "&") + "\"");
578 //System.out.println("property name: " + name);
583 indentation + " <xs:appinfo>\r\n" +
584 indentation + " <annox:annotate target=\""+target+"\">@org.openecomp.aai.annotations.Metadata(" + Joiner.on(",").join(metadata) + ")</annox:annotate>\r\n" +
585 indentation + " </xs:appinfo>\r\n");
590 private static Element getJavaTypeElement( String javaTypeName )
593 String attrName, attrValue;
595 Element javaTypeElement;
596 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
597 javaTypeElement = (Element) javaTypeNodes.item(i);
598 NamedNodeMap attributes = javaTypeElement.getAttributes();
599 for ( int j = 0; j < attributes.getLength(); ++j ) {
600 attr = (Attr) attributes.item(j);
601 attrName = attr.getNodeName();
602 attrValue = attr.getNodeValue();
603 if ( attrName.equals("name") && attrValue.equals(javaTypeName))
604 return javaTypeElement;
607 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
608 return (Element) null;
611 private static Element getJavaTypeElementSwagger( String javaTypeName )
614 String attrName, attrValue;
616 Element javaTypeElement;
617 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
618 javaTypeElement = (Element) javaTypeNodes.item(i);
619 NamedNodeMap attributes = javaTypeElement.getAttributes();
620 for ( int j = 0; j < attributes.getLength(); ++j ) {
621 attr = (Attr) attributes.item(j);
622 attrName = attr.getNodeName();
623 attrValue = attr.getNodeValue();
624 if ( attrName.equals("name") && attrValue.equals(javaTypeName))
625 return javaTypeElement;
628 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
629 return (Element) null;
631 private static String getXmlRootElementName( String javaTypeName )
634 String attrName, attrValue;
636 Element javaTypeElement;
637 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
638 javaTypeElement = (Element) javaTypeNodes.item(i);
639 NamedNodeMap attributes = javaTypeElement.getAttributes();
640 for ( int j = 0; j < attributes.getLength(); ++j ) {
641 attr = (Attr) attributes.item(j);
642 attrName = attr.getNodeName();
643 attrValue = attr.getNodeValue();
644 if ( attrName.equals("name") && attrValue.equals(javaTypeName)) {
645 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
646 Element valElement = (Element) valNodes.item(0);
647 attributes = valElement.getAttributes();
648 for ( int k = 0; k < attributes.getLength(); ++k ) {
649 attr = (Attr) attributes.item(k);
650 attrName = attr.getNodeName();
652 attrValue = attr.getNodeValue();
653 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
654 if ( attrName.equals("name"))
660 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
665 public static String processOxmFile( File oxmFile, Version v )
667 StringBuilder sb = new StringBuilder();
668 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
669 String namespace = "org.openecomp";
670 if ( useAnnotationsInXsd ) {
671 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
672 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
674 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" +
675 " jaxb:version=\"2.1\" \r\n" +
676 " xmlns:annox=\"http://annox.dev.java.net\" \r\n" +
677 " jaxb:extensionBindingPrefixes=\"annox\">\n\n");
679 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
680 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n");
685 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
686 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
687 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
688 Document doc = dBuilder.parse(oxmFile);
690 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
691 Element bindingElement;
692 NodeList javaTypesNodes;
693 Element javaTypesElement;
695 Element javaTypeElement;
698 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
699 System.out.println( "missing <binding-nodes> in " + oxmFile );
703 bindingElement = (Element) bindingsNodes.item(0);
704 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
705 if ( javaTypesNodes.getLength() < 1 ) {
706 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
709 javaTypesElement = (Element) javaTypesNodes.item(0);
710 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
711 if ( javaTypeNodes.getLength() < 1 ) {
712 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
717 String attrName, attrValue;
719 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
720 javaTypeElement = (Element) javaTypeNodes.item(i);
721 NamedNodeMap attributes = javaTypeElement.getAttributes();
723 for ( int j = 0; j < attributes.getLength(); ++j ) {
724 attr = (Attr) attributes.item(j);
725 attrName = attr.getNodeName();
726 attrValue = attr.getNodeValue();
727 if ( attrName.equals("name"))
728 javaTypeName = attrValue;
730 if ( javaTypeName == null ) {
731 System.out.println( "<java-type> has no name attribute in " + oxmFile );
734 if ("Nodes".equals(javaTypeName)) {
735 //System.out.println("skipping Nodes entry (temporary feature)");
738 if ( !generatedJavaType.containsKey(javaTypeName) ) {
739 generatedJavaType.put(javaTypeName, null);
740 sb.append(processJavaTypeElement( javaTypeName, javaTypeElement ));
744 } catch (Exception e) {
748 sb.append("</xs:schema>\n");
749 return sb.toString();
752 private static boolean isStandardType( String elementType )
754 switch ( elementType ) {
755 case "java.lang.String":
756 case "java.lang.Long":
757 case "java.lang.Integer":
758 case"java.lang.Boolean":
764 private static Vector<String> getIndexedProps( String attrValue )
766 if ( attrValue == null )
768 StringTokenizer st = new StringTokenizer( attrValue, ",");
769 if ( st.countTokens() == 0 )
771 Vector<String> result = new Vector<String>();
772 while ( st.hasMoreTokens()) {
773 result.add(st.nextToken());
779 * Guaranteed to at least return non null but empty collection of edge descriptions
780 * @param nodeName name of the vertex whose edge relationships to return
781 * @return collection of node neighbors based on DbEdgeRules
783 private static Collection<EdgeDescription> getEdgeRulesFromJson( String path, boolean skipMatch )
786 ArrayList<EdgeDescription> result = new ArrayList<>();
787 Iterator<Map<String, Object>> edgeRulesIterator;
790 GenerateXsd x = new GenerateXsd();
792 List<Map<String, Object>> inEdges = JsonPath.parse(jsonEdges).read(path);
794 edgeRulesIterator = inEdges.iterator();
795 Map<String, Object> edgeMap;
803 EdgeDescription edgeDes;
805 while( edgeRulesIterator.hasNext() ){
806 edgeMap = edgeRulesIterator.next();
807 fromNode = (String)edgeMap.get("from");
808 toNode = (String)edgeMap.get("to");
810 if ( fromNode.equals(toNode)) {
814 edgeDes = x.new EdgeDescription();
815 edgeDes.setRuleKey(fromNode + "|" + toNode);
816 direction = (String)edgeMap.get("direction");
817 edgeDes.setDirection(direction);
818 multiplicity = (String)edgeMap.get("multiplicity");
819 edgeDes.setMultiplicity(multiplicity);
820 isParent = (String)edgeMap.get(EdgeProperty.CONTAINS.toString());
821 if ( "${direction}".equals(isParent)) {
822 edgeDes.setType(LineageType.PARENT);
824 edgeDes.setType(LineageType.UNRELATED);
826 hasDelTarget = (String)edgeMap.get(EdgeProperty.DELETE_OTHER_V.toString());
827 edgeDes.setHasDelTarget(hasDelTarget);
831 } catch (Exception ex) {
832 ex.printStackTrace();
839 * Guaranteed to at least return non null but empty collection of edge descriptions
840 * @param nodeName name of the vertex whose edge relationships to return
841 * @return collection of node neighbors based on DbEdgeRules
843 private static Collection<EdgeDescription> getEdgeRules( String nodeName )
845 String fromRulesPath = "$['rules'][?(@['from']=='" + nodeName + "')]";
846 String toRulesPath = "$['rules'][?(@['to']=='" + nodeName + "')]";
847 Collection<EdgeDescription> fromEdges = getEdgeRulesFromJson( fromRulesPath, false );
848 Collection<EdgeDescription> edges = getEdgeRulesFromJson( toRulesPath, true );
849 edges.addAll(fromEdges);
853 public static String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
854 StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
855 String getItemName, StringBuffer pathParams, String queryParams, String validEdges) {
857 String xmlRootElementName = null;
859 //Map<String, String> addJavaType = new HashMap<String, String>();
860 String useTag = null;
861 String useOpId = null;
866 case "ServiceDesignAndCreation":
868 case "LicenseManagement":
869 case "CloudInfrastructure":
870 case "ExternalSystem":
878 System.out.println( "processJavaTypeElementSwagger called with null path for javaTypeName " + javaTypeName);
881 if ( path == null || !(path.contains("cloud-infrastructure")))
882 switch ( javaTypeName) {
887 case "CloudInfrastructure":
890 case "ServiceDesignAndCreation":
891 case "LicenseManagement":
894 useTag = javaTypeName;
903 if ( !javaTypeName.equals("Inventory") ) {
904 if ( javaTypeName.equals("AaiInternal"))
907 useOpId = javaTypeName;
909 useOpId = opId + javaTypeName;
911 useTag = javaTypeName;
915 if ( javaTypeName.equals("GenericVnf"))
916 System.out.println( "Processing " + javaTypeName);
917 else if ( javaTypeName.equals("Service"))
918 System.out.println( "Processing " + javaTypeName);
919 else if ( javaTypeName.equals("SitePair"))
920 System.out.println( "Processing " + javaTypeName);
922 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
924 if ( parentNodes.getLength() == 0 ) {
925 //System.out.println( "no java-attributes for java-type " + javaTypeName);
930 NamedNodeMap attributes;
932 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
933 Element valElement = (Element) valNodes.item(0);
934 attributes = valElement.getAttributes();
935 for ( int i = 0; i < attributes.getLength(); ++i ) {
936 Attr attr = (Attr) attributes.item(i);
937 String attrName = attr.getNodeName();
939 String attrValue = attr.getNodeValue();
940 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
941 if ( attrName.equals("name"))
942 xmlRootElementName = attrValue;
945 if ( xmlRootElementName.equals("oam-networks"))
946 System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
950 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
955 Element childElement;
956 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
957 Element xmlPropElement;
958 String pathDescriptionProperty = null;
961 Vector<String> indexedProps = null;
963 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
964 if ( path != null && path.equals("/network/generic-vnfs"))
965 System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
967 if ( xmlPropNodes.getLength() > 0 ) {
969 for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
970 xmlPropElement = (Element)xmlPropNodes.item(i);
971 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
973 childNodes = xmlPropElement.getElementsByTagName("xml-property");
975 if ( childNodes.getLength() > 0 ) {
976 for ( int j = 0; j < childNodes.getLength(); ++j ) {
977 childElement = (Element)childNodes.item(j);
979 int useValue = VALUE_NONE;
980 attributes = childElement.getAttributes();
981 for ( int k = 0; k < attributes.getLength(); ++k ) {
982 Attr attr = (Attr) attributes.item(k);
983 String attrName = attr.getNodeName();
984 String attrValue = attr.getNodeValue();
985 if ( attrName == null || attrValue == null )
987 if ( attrName.equals("name") && attrValue.equals("description")) {
988 useValue = VALUE_DESCRIPTION;
990 if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
991 pathDescriptionProperty = attrValue;
993 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
995 if ( attrValue.equals("indexedProps")) {
996 useValue = VALUE_INDEXED_PROPS;
998 if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
999 indexedProps = getIndexedProps( attrValue );
1006 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
1009 if ( javaTypeName.equals("RelationshipList")) {
1010 System.out.println( "Skipping " + javaTypeName);
1011 generatedJavaType.put(javaTypeName, null);
1016 Element parentElement = (Element)parentNodes.item(0);
1017 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
1020 String attrDescription = null;
1022 Element xmlElementElement;
1023 String addType = null;
1024 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1025 String elementName = null;
1026 StringBuffer sbParameters = new StringBuffer();
1028 StringBuffer sbRequired = new StringBuffer();
1029 int requiredCnt = 0;
1030 int propertyCnt = 0;
1031 StringBuffer sbProperties = new StringBuffer();
1032 StringBuffer sbIndexedParams = new StringBuffer();
1036 if ( xmlRootElementName.equals("inventory"))
1038 else if ( path == null )
1039 //path = "/aai/" + apiVersion;
1040 path = "/" + xmlRootElementName;
1042 path += "/" + xmlRootElementName;
1043 st = new StringTokenizer(path, "/");
1045 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1046 System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1048 boolean genPath = false;
1050 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1051 System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1053 if ( st.countTokens() > 1 && getItemName == null ) {
1054 if ( appliedPaths.containsKey(path))
1056 appliedPaths.put(path, null);
1058 if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1061 if ( path.endsWith("/relationship-list")) {
1067 Vector<String> addTypeV = null;
1068 if ( xmlElementNodes.getLength() > 0 ) {
1070 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1071 xmlElementElement = (Element)xmlElementNodes.item(i);
1072 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1074 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1075 if ( childNodes.getLength() > 0 ) {
1076 childElement = (Element)childNodes.item(0);
1078 attributes = childElement.getAttributes();
1079 for ( int k = 0; k < attributes.getLength(); ++k ) {
1080 Attr attr = (Attr) attributes.item(k);
1081 String attrName = attr.getNodeName();
1082 String attrValue = attr.getNodeValue();
1083 if ( attrName.equals("name")) {
1084 xmlElementWrapper = attrValue;
1085 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1091 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1092 attrDescription = null;
1093 if ( valNodes.getLength() > 0 ) {
1094 for ( int j = 0; j < valNodes.getLength(); ++j ) {
1095 valElement = (Element)valNodes.item(j);
1096 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1098 childNodes = valElement.getElementsByTagName("xml-property");
1099 if ( childNodes.getLength() > 0 ) {
1100 childElement = (Element)childNodes.item(0);
1102 attributes = childElement.getAttributes();
1103 attrDescription = null;
1104 boolean useValue = false;
1105 for ( int k = 0; k < attributes.getLength(); ++k ) {
1106 Attr attr = (Attr) attributes.item(k);
1107 String attrName = attr.getNodeName();
1108 String attrValue = attr.getNodeValue();
1109 if ( attrName.equals("name") && attrValue.equals("description")) {
1112 if ( useValue && attrName.equals("value")) {
1113 attrDescription = attrValue;
1114 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1122 attributes = xmlElementElement.getAttributes();
1123 addTypeV = null; // vector of 1
1126 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1127 for ( int j = 0; j < attributes.getLength(); ++j ) {
1128 Attr attr = (Attr) attributes.item(j);
1129 String attrName = attr.getNodeName();
1131 String attrValue = attr.getNodeValue();
1132 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1133 if ( attrName.equals("name")) {
1134 elementName = attrValue;
1137 if ( attrName.equals("type") && getItemName == null ) {
1138 elementType = attrValue;
1139 if ( attrValue.contains(apiVersionFmt) ) {
1140 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1141 if ( addTypeV == null )
1142 addTypeV = new Vector<String>();
1143 addTypeV.add(addType);
1147 if ( attrName.equals("xml-key")) {
1148 elementIsKey = attrValue;
1149 path += "/{" + elementName + "}";
1151 if ( attrName.equals("required")) {
1152 elementIsRequired = attrValue;
1154 if ( attrName.equals("container-type")) {
1155 elementContainerType = attrValue;
1158 if ( getItemName != null ) {
1159 if ( getItemName.equals("array") ) {
1160 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1161 //System.out.println( " returning array " + elementName );
1165 } else { // not an array check
1166 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1167 //System.out.println( " returning object " + elementName );
1172 //System.out.println( " returning null" );
1175 if ( elementIsRequired != null ) {
1176 if ( requiredCnt == 0 )
1177 sbRequired.append(" required:\n");
1179 if ( addTypeV != null ) {
1180 for ( int k = 0; k < addTypeV.size(); ++i ) {
1181 sbRequired.append(" - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1184 sbRequired.append(" - " + elementName + "\n");
1188 if ( elementIsKey != null ) {
1189 sbParameters.append((" - name: " + elementName + "\n"));
1190 sbParameters.append((" in: path\n"));
1191 if ( attrDescription != null && attrDescription.length() > 0 )
1192 sbParameters.append((" description: " + attrDescription + "\n"));
1193 sbParameters.append((" required: true\n"));
1194 if ( elementType.equals("java.lang.String"))
1195 sbParameters.append(" type: string\n");
1196 if ( elementType.equals("java.lang.Long")) {
1197 sbParameters.append(" type: integer\n");
1198 sbParameters.append(" format: int64\n");
1200 if ( elementType.equals("java.lang.Integer")) {
1201 sbParameters.append(" type: integer\n");
1202 sbParameters.append(" format: int32\n");
1204 if ( elementType.equals("java.lang.Boolean"))
1205 sbParameters.append(" type: boolean\n");
1208 } else if ( indexedProps != null
1209 && indexedProps.contains(elementName ) ) {
1210 sbIndexedParams.append((" - name: " + elementName + "\n"));
1211 sbIndexedParams.append((" in: query\n"));
1212 if ( attrDescription != null && attrDescription.length() > 0 )
1213 sbIndexedParams.append((" description: " + attrDescription + "\n"));
1214 sbIndexedParams.append((" required: false\n"));
1215 if ( elementType.equals("java.lang.String"))
1216 sbIndexedParams.append(" type: string\n");
1217 if ( elementType.equals("java.lang.Long")) {
1218 sbIndexedParams.append(" type: integer\n");
1219 sbIndexedParams.append(" format: int64\n");
1221 if ( elementType.equals("java.lang.Integer")) {
1222 sbIndexedParams.append(" type: integer\n");
1223 sbIndexedParams.append(" format: int32\n");
1225 if ( elementType.equals("java.lang.Boolean"))
1226 sbIndexedParams.append(" type: boolean\n");
1230 if ( elementName != null && elementName.equals("inventory-item"))
1231 System.out.println( "processing inventory-item elementName");
1234 if ( isStandardType(elementType)) {
1235 sbProperties.append(" " + elementName + ":\n");
1237 sbProperties.append(" type: ");
1239 if ( elementType.equals("java.lang.String"))
1240 sbProperties.append("string\n");
1241 else if ( elementType.equals("java.lang.Long")) {
1242 sbProperties.append("integer\n");
1243 sbProperties.append(" format: int64\n");
1245 else if ( elementType.equals("java.lang.Integer")){
1246 sbProperties.append("integer\n");
1247 sbProperties.append(" format: int32\n");
1249 else if ( elementType.equals("java.lang.Boolean"))
1250 sbProperties.append("boolean\n");
1251 if ( attrDescription != null && attrDescription.length() > 0 )
1252 sbProperties.append(" description: " + attrDescription + "\n");
1255 //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1257 if ( addTypeV != null ) {
1258 StringBuffer newPathParams = null;
1259 if ( pathParams != null ) {
1260 newPathParams = new StringBuffer();
1261 newPathParams.append(pathParams);
1263 if ( sbParameters.toString().length() > 0 ) {
1264 if ( newPathParams == null )
1265 newPathParams = new StringBuffer();
1266 newPathParams.append(sbParameters);
1268 String newQueryParams = null;
1269 if ( sbIndexedParams.toString().length() > 0 ) {
1270 if ( queryParams == null )
1271 newQueryParams = sbIndexedParams.toString();
1273 newQueryParams = queryParams + sbIndexedParams.toString();
1275 newQueryParams = queryParams;
1277 for ( int k = 0; k < addTypeV.size(); ++k ) {
1278 addType = addTypeV.elementAt(k);
1280 if ( opId == null || !opId.contains(addType)) {
1281 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1282 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, null,
1283 newPathParams, newQueryParams, validEdges);
1285 // need item name of array
1286 String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1287 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1288 "array", null, null, null );
1290 if ( itemName != null ) {
1291 if ( addType.equals("AaiInternal") ) {
1292 //System.out.println( "addType AaiInternal, skip properties");
1294 } else if ( getItemName == null) {
1296 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1297 sbProperties.append(" type: array\n items:\n");
1298 sbProperties.append(" $ref: \"#/definitions/" + itemName + "\"\n");
1299 if ( attrDescription != null && attrDescription.length() > 0 )
1300 sbProperties.append(" description: " + attrDescription + "\n");
1303 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1304 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, "other" );
1305 if ( itemName != null ) {
1307 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1308 // need properties for getXmlRootElementName(addType)
1309 newPathParams = null;
1310 if ( pathParams != null ) {
1311 newPathParams = new StringBuffer();
1312 newPathParams.append(pathParams);
1314 if ( sbParameters.toString().length() > 0 ) {
1315 if ( newPathParams == null )
1316 newPathParams = new StringBuffer();
1317 newPathParams.append(sbParameters);
1319 newQueryParams = null;
1320 if ( sbIndexedParams.toString().length() > 0 ) {
1321 if ( queryParams == null )
1322 newQueryParams = sbIndexedParams.toString();
1324 newQueryParams = queryParams + sbIndexedParams.toString();
1326 newQueryParams = queryParams;
1328 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1329 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1330 null, newPathParams, newQueryParams, validEdges );
1331 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1332 sbProperties.append(" type: array\n items: \n");
1333 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1335 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1336 sbProperties.append(" type: object\n");
1337 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1339 if ( attrDescription != null && attrDescription.length() > 0 )
1340 sbProperties.append(" description: " + attrDescription + "\n");
1344 System.out.println(" unable to define swagger object for " + addType);
1348 //if ( getItemName == null) looking for missing properties
1349 //generatedJavaType.put(addType, null);
1356 if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1357 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1360 if ( !path.endsWith("/relationship") ) {
1361 pathSb.append(" " + path + ":\n" );
1362 pathSb.append(" get:\n");
1363 pathSb.append(" tags:\n");
1364 pathSb.append(" - " + tag + "\n");
1365 pathSb.append(" summary: returns " + xmlRootElementName + "\n");
1367 pathSb.append(" description: returns " + xmlRootElementName + "\n");
1368 pathSb.append(" operationId: get" + useOpId + "\n");
1369 pathSb.append(" produces:\n");
1370 pathSb.append(" - application/json\n");
1371 pathSb.append(" - application/xml\n");
1373 pathSb.append(" responses:\n");
1374 pathSb.append(" \"200\":\n");
1375 pathSb.append(" description: successful operation\n");
1376 pathSb.append(" schema:\n");
1377 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1378 pathSb.append(" \"default\":\n");
1379 pathSb.append(" " + responsesUrl);
1381 pathSb.append(" \"200\":\n");
1382 pathSb.append(" description: successful operation\n");
1383 pathSb.append(" schema:\n");
1384 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1385 pathSb.append(" \"404\":\n");
1386 pathSb.append(" description: resource was not found\n");
1387 pathSb.append(" \"400\":\n");
1388 pathSb.append(" description: bad request\n");
1390 if ( path.indexOf('{') > 0 ) {
1392 if ( sbParameters.toString().length() > 0 ) {
1393 if ( pathParams == null )
1394 pathParams = new StringBuffer();
1395 pathParams.append(sbParameters);
1397 if ( pathParams != null) {
1398 pathSb.append(" parameters:\n");
1399 pathSb.append(pathParams);
1401 System.out.println( "null pathParams for " + useOpId);
1402 if ( sbIndexedParams.toString().length() > 0 ) {
1403 if ( queryParams == null )
1404 queryParams = sbIndexedParams.toString();
1406 queryParams = queryParams + sbIndexedParams.toString();
1408 if ( queryParams != null ) {
1409 if ( pathParams == null ) {
1410 pathSb.append(" parameters:\n");
1412 pathSb.append(queryParams);
1416 boolean skipPutDelete = false; // no put or delete for "all"
1417 if ( !path.endsWith("/relationship") ) {
1418 if ( !path.endsWith("}") ){
1419 skipPutDelete = true;
1423 if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1425 if ( path.endsWith("/relationship") ) {
1426 pathSb.append(" " + path + ":\n" );
1428 pathSb.append(" put:\n");
1429 pathSb.append(" tags:\n");
1430 pathSb.append(" - " + tag + "\n");
1432 if ( path.endsWith("/relationship") ) {
1433 pathSb.append(" summary: see node definition for valid relationships\n");
1435 pathSb.append(" summary: create or update an existing " + xmlRootElementName + "\n");
1436 pathSb.append(" description: create or update an existing " + xmlRootElementName + "\n");
1438 pathSb.append(" operationId: createOrUpdate" + useOpId + "\n");
1439 pathSb.append(" consumes:\n");
1440 pathSb.append(" - application/json\n");
1441 pathSb.append(" - application/xml\n");
1442 pathSb.append(" produces:\n");
1443 pathSb.append(" - application/json\n");
1444 pathSb.append(" - application/xml\n");
1445 pathSb.append(" responses:\n");
1446 pathSb.append(" \"default\":\n");
1447 pathSb.append(" " + responsesUrl);
1449 pathSb.append(" responses:\n");
1450 pathSb.append(" \"200\":\n");
1451 pathSb.append(" description: existing resource has been modified and there is a response buffer\n");
1452 pathSb.append(" \"201\":\n");
1453 pathSb.append(" description: new resource is created\n");
1454 pathSb.append(" \"202\":\n");
1455 pathSb.append(" description: action requested but may have taken other actions as well, which are returned in the response payload\n");
1456 pathSb.append(" \"204\":\n");
1457 pathSb.append(" description: existing resource has been modified and there is no response buffer\n");
1458 pathSb.append(" \"400\":\n");
1459 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1460 pathSb.append(" \"404\":\n");
1461 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1463 pathSb.append(" parameters:\n");
1464 //pathSb.append(" - in: path\n");
1465 pathSb.append(pathParams); // for nesting
1466 pathSb.append(" - name: body\n");
1467 pathSb.append(" in: body\n");
1468 pathSb.append(" description: " + xmlRootElementName + " object that needs to be created or updated\n");
1469 pathSb.append(" required: true\n");
1470 pathSb.append(" schema:\n");
1471 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1473 if ( queryParams != null ) {
1474 pathSb.append(queryParams);
1478 pathSb.append(" delete:\n");
1479 pathSb.append(" tags:\n");
1480 pathSb.append(" - " + tag + "\n");
1481 pathSb.append(" summary: delete an existing " + xmlRootElementName + "\n");
1483 pathSb.append(" description: delete an existing " + xmlRootElementName + "\n");
1485 pathSb.append(" operationId: delete" + useOpId + "\n");
1486 pathSb.append(" consumes:\n");
1487 pathSb.append(" - application/json\n");
1488 pathSb.append(" - application/xml\n");
1489 pathSb.append(" produces:\n");
1490 pathSb.append(" - application/json\n");
1491 pathSb.append(" - application/xml\n");
1492 pathSb.append(" responses:\n");
1493 pathSb.append(" \"default\":\n");
1494 pathSb.append(" " + responsesUrl);
1496 pathSb.append(" responses:\n");
1497 pathSb.append(" \"200\":\n");
1498 pathSb.append(" description: successful, the response includes an entity describing the status\n");
1499 pathSb.append(" \"204\":\n");
1500 pathSb.append(" description: successful, action has been enacted but the response does not include an entity\n");
1501 pathSb.append(" \"400\":\n");
1502 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1503 pathSb.append(" \"404\":\n");
1504 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1506 pathSb.append(" parameters:\n");
1507 //pathSb.append(" - in: path\n");
1508 pathSb.append(pathParams); // for nesting
1509 if ( !path.endsWith("/relationship") ) {
1510 pathSb.append(" - name: resource-version\n");
1512 pathSb.append(" in: query\n");
1513 pathSb.append(" description: resource-version for concurrency\n");
1514 pathSb.append(" required: true\n");
1515 pathSb.append(" type: string\n");
1518 if ( queryParams != null ) {
1519 pathSb.append(queryParams);
1525 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1529 definitionsSb.append(" " + xmlRootElementName + ":\n");
1530 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1531 if ( edges.size() > 0 ) {
1532 StringBuffer sbEdge = new StringBuffer();
1533 sbEdge.append(" ###### Related Nodes\n");
1534 for (EdgeDescription ed : edges) {
1535 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1536 sbEdge.append(" - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1537 sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1538 sbEdge.append("\n");
1541 for (EdgeDescription ed : edges) {
1542 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1543 sbEdge.append(" - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1544 sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1545 sbEdge.append("\n");
1548 validEdges = sbEdge.toString();
1551 // Handle description property. Might have a description OR valid edges OR both OR neither.
1552 // Only put a description: tag if there is at least one.
1553 if (pathDescriptionProperty != null || validEdges != null) {
1554 definitionsSb.append(" description: |\n");
1556 if ( pathDescriptionProperty != null )
1557 definitionsSb.append(" " + pathDescriptionProperty + "\n" );
1558 if (validEdges != null)
1559 definitionsSb.append(validEdges);
1562 if ( requiredCnt > 0 )
1563 definitionsSb.append(sbRequired);
1564 if ( propertyCnt > 0 ) {
1565 definitionsSb.append(" properties:\n");
1566 definitionsSb.append(sbProperties);
1568 generatedJavaType.put(xmlRootElementName, null);
1572 public static String generateSwaggerFromOxmFile( File oxmFile )
1575 StringBuffer sb = new StringBuffer();
1576 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");
1577 sb.append(" title: Active and Available Inventory REST API\n");
1578 sb.append(" license:\n name: Apache 2.0\n url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1579 sb.append(" contact:\n name:\n url:\n email:\n");
1580 sb.append("host:\nbasePath: /aai/" + apiVersion + "\n");
1581 sb.append("schemes:\n - https\npaths:\n");
1583 sb.append("responses:\n");
1584 sb.append(" \"200\":\n");
1585 sb.append(" description: successful operation\n");
1586 sb.append(" \"404\":\n");
1587 sb.append(" description: resource was not found\n");
1588 sb.append(" \"400\":\n");
1589 sb.append(" description: bad request\n");
1592 File initialFile = new File("src/main/resources/dbedgerules/DbEdgeRules_" + apiVersion + ".json");
1593 InputStream is = new FileInputStream(initialFile);
1595 Scanner scanner = new Scanner(is);
1596 jsonEdges = scanner.useDelimiter("\\Z").next();
1600 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1601 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1602 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1603 Document doc = dBuilder.parse(oxmFile);
1605 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1606 Element bindingElement;
1607 NodeList javaTypesNodes;
1608 Element javaTypesElement;
1610 Element javaTypeElement;
1613 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1614 System.out.println( "missing <binding-nodes> in " + oxmFile );
1618 bindingElement = (Element) bindingsNodes.item(0);
1619 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1620 if ( javaTypesNodes.getLength() < 1 ) {
1621 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1624 javaTypesElement = (Element) javaTypesNodes.item(0);
1626 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1627 if ( javaTypeNodes.getLength() < 1 ) {
1628 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1632 String javaTypeName;
1633 String attrName, attrValue;
1635 StringBuffer pathSb = new StringBuffer();
1637 StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1639 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1640 javaTypeElement = (Element) javaTypeNodes.item(i);
1641 NamedNodeMap attributes = javaTypeElement.getAttributes();
1642 javaTypeName = null;
1643 for ( int j = 0; j < attributes.getLength(); ++j ) {
1644 attr = (Attr) attributes.item(j);
1645 attrName = attr.getNodeName();
1646 attrValue = attr.getNodeValue();
1647 if ( attrName.equals("name"))
1648 javaTypeName = attrValue;
1650 if ( javaTypeName == null ) {
1651 System.out.println( "<java-type> has no name attribute in " + oxmFile );
1654 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1656 //generatedJavaType.put(javaTypeName, null);
1657 //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1659 processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1660 definitionsSb, null, null, null, null, null, null, null);
1664 //System.out.println( "definitions block\n" + definitionsSb.toString());
1665 sb.append(definitionsSb.toString());
1666 //sb.append(definitionsSb);
1668 } catch (Exception e) {
1669 e.printStackTrace();
1672 //System.out.println("generated " + sb.toString());
1673 return sb.toString();
1676 private static NodeList locateXmlProperties(Element element) {
1677 XPathExpression expr;
1678 NodeList result = null;
1680 expr = xpath.compile("xml-properties");
1682 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1683 if (nodeset != null) {
1684 NodeList nodes = (NodeList) nodeset;
1685 if (nodes.getLength() > 0) {
1686 Element xmlProperty = (Element)nodes.item(0);
1687 result = xmlProperty.getElementsByTagName("xml-property");
1691 } catch (XPathExpressionException e) {
1692 e.printStackTrace();