2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.aai.util;
23 import java.io.BufferedWriter;
25 import java.io.FileWriter;
26 import java.io.IOException;
27 import java.lang.reflect.Field;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.HashMap;
31 import java.util.Iterator;
32 import java.util.List;
34 import java.util.StringTokenizer;
35 import java.util.Vector;
37 import javax.xml.XMLConstants;
38 import javax.xml.bind.JAXBContext;
39 import javax.xml.bind.JAXBException;
40 import javax.xml.bind.SchemaOutputResolver;
41 import javax.xml.parsers.DocumentBuilder;
42 import javax.xml.parsers.DocumentBuilderFactory;
43 import javax.xml.transform.Result;
44 import javax.xml.transform.stream.StreamResult;
45 import javax.xml.xpath.XPath;
46 import javax.xml.xpath.XPathConstants;
47 import javax.xml.xpath.XPathExpression;
48 import javax.xml.xpath.XPathExpressionException;
49 import javax.xml.xpath.XPathFactory;
51 import org.w3c.dom.Attr;
52 import org.w3c.dom.Document;
53 import org.w3c.dom.Element;
54 import org.w3c.dom.NamedNodeMap;
55 import org.w3c.dom.NodeList;
57 import org.openecomp.aai.dbmodel.DbEdgeRules;
58 import com.google.common.base.Joiner;
59 import com.google.common.collect.Multimap;
62 public class GenerateXsd {
63 static String apiVersion = null;
64 static String apiVersionFmt = null;
65 static String responsesUrl = null;
66 static String responsesLabel = null;
67 static Map<String, String> generatedJavaType = new HashMap<String, String>();
68 static Map<String, String> appliedPaths = new HashMap<String, String>();
69 static NodeList javaTypeNodes;
70 static Class<?> versionedClass;
73 public static final int VALUE_NONE = 0;
74 public static final int VALUE_DESCRIPTION = 1;
75 public static final int VALUE_INDEXED_PROPS = 2;
77 private static XPath xpath = XPathFactory.newInstance().newXPath();
80 private enum LineageType {
81 PARENT, CHILD, UNRELATED;
83 private class EdgeDescription {
85 private String ruleKey;
86 private LineageType type = LineageType.UNRELATED;
87 private String direction;
88 private String multiplicity;
89 private boolean hasDelTarget = false;
91 public String getRuleKey() {
94 public String getMultiplicity() {
97 public String getDirection() {
100 public void setRuleKey(String val) {
103 public void setType(LineageType val) {
106 public void setDirection(String val) {
107 this.direction = val;
109 public void setMultiplicity(String val) {
110 this.multiplicity=val;
112 public void setHasDelTarget(String val) {
113 hasDelTarget = Boolean.parseBoolean(val);
116 public String getRelationshipDescription(String fromTo, String otherNodeName) {
120 if ("FROM".equals(fromTo)) {
121 if ("OUT".equals(direction)) {
122 if (LineageType.PARENT == type) {
123 result = " (is composed of "+otherNodeName;
127 if (LineageType.CHILD == type) {
128 result = " (comprises "+otherNodeName;
130 else if (LineageType.PARENT == type) {
131 result = " (comprises "+otherNodeName;
135 if ("OUT".equals(direction)) {
136 if (LineageType.PARENT == type) {
137 result = " (comprises "+otherNodeName;
140 if (LineageType.PARENT == type) {
141 result = " (is composed of "+otherNodeName;
146 // if (type != null) {
147 // if (LineageType.PARENT.equals(type) && "FROM".equals(fromTo)) {
148 // if ("OUT".equals(direction)) {
149 // result = " (is composed of "+otherNodeName;
151 // result = " (comprises "+otherNodeName;
154 // result = " (comprises " + otherNodeName;
155 // // if (!(multiplicity.startsWith("One"))) {
156 // // System.err.println("Surprised to find multiplicity "+multiplicity+" with comprises for "+ruleKey);
160 if ("TO".equals(fromTo)) {
161 if (result.length() == 0) result = result + " (";
162 else result = result + ", ";
164 result = result + mapMultiplicity(fromTo);
165 if (hasDelTarget) result = result + ", will delete target node";
168 if (result.length() > 0) result = result + ")";
173 private String mapMultiplicity(String fromTo) {
174 String result = multiplicity;
175 // Below logic works if an IN switches multiplicity, which it doesn't today.
176 // if ("TO".equals(fromTo)) {
177 // if (direction.equals("OUT")) {
178 // result = multiplicity;
180 // result = switchMultiplicity(multiplicity);
183 // if (direction.equals("OUT")) {
184 // result = multiplicity;
186 // result = switchMultiplicity(multiplicity);
192 // private String switchMultiplicity(String val) throws IllegalArgumentException
194 // String result = null;
201 // result = "One2Many";
204 // result = "Many2One";
207 // throw new IllegalArgumentException("Multiplicity cannot be "+val);
209 // System.out.println("Switched Multiplicity from "+val+" to "+result);
214 public static void main(String[] args) throws IOException {
216 if (args.length > 0) {
217 if (args[0] != null) {
218 apiVersion = args[0];
221 boolean genDoc = false;
222 if ( args.length > 1 ) {
224 int index = args[1].indexOf("|");
226 responsesUrl = args[1].substring(0, index);
227 responsesLabel = args[1].substring(index+1);
228 //System.out.println( "response URL " + responsesUrl);
229 //System.out.println( "response label " + responsesLabel);
230 responsesUrl = "description: "+ responsesLabel + "(" +
231 responsesUrl + ").\n";
232 //System.out.println( "operation described with " + responsesUrl);
237 String oxmPath = null;
238 if ( apiVersion == null ) {
239 // to run from eclipse, set these env, e.g. v7, \sources\aai\aaimastergit\bundleconfig-local\etc\oxm\
240 String envRev= System.getenv("OXM_REV");
241 if ( envRev != null )
245 oxmPath = System.getenv("OXM_PATH");
248 outfileName = "c:\\temp\\aai.yaml";
250 outfileName = "c:\\temp\\aai_schema.xsd";
251 if ( apiVersion != null ) { // generate from oxm
252 apiVersionFmt = "." + apiVersion + ".";
253 if ( oxmPath == null ) {
254 oxmPath = AAIConstants.AAI_HOME_ETC_OXM + AAIConstants.AAI_FILESEP;
255 //oxmPath = "\\sources\\aai\\aaimastergit\\bundleconfig-local\\etc\\oxm\\";
258 File oxm_file = new File(oxmPath + "aai_oxm_" + apiVersion + ".xml");
262 xsd = generateSwaggerFromOxmFile( oxm_file);
263 outfile =new File(outfileName);
265 xsd = processOxmFile( oxm_file);
266 outfile =new File(outfileName);
271 outfile.createNewFile();
272 } catch (IOException e) {
273 System.out.println( "Exception creating output file " + outfileName);
277 FileWriter fw = new FileWriter(outfile.getAbsoluteFile());
278 BufferedWriter bw = new BufferedWriter(fw);
282 } catch ( IOException e) {
283 System.out.println( "Exception writing output file " + outfileName);
286 System.out.println( "GeneratedXSD successful, saved in " + outfileName);
290 JAXBContext jaxbContext = null;
292 jaxbContext = JAXBContext.newInstance(org.openecomp.aai.domain.yang.Vce.class);
293 } catch (JAXBException e) {
297 SchemaOutputResolver sor = new MySchemaOutputResolver();
298 jaxbContext.generateSchema(sor);
302 public static class MySchemaOutputResolver extends SchemaOutputResolver {
304 public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException {
305 File file = new File("c:\\temp\\aai_schema.xsd");
306 StreamResult result = new StreamResult(file);
307 result.setSystemId(file.toURI().toURL().toString());
313 public static String processJavaTypeElement( String javaTypeName, Element javaTypeElement) {
315 String xmlRootElementName = null;
317 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
318 StringBuffer sb = new StringBuffer();
319 if ( parentNodes.getLength() == 0 ) {
320 System.out.println( "no java-attributes for java-type " + javaTypeName);
325 NamedNodeMap attributes;
327 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
328 Element valElement = (Element) valNodes.item(0);
329 attributes = valElement.getAttributes();
330 for ( int i = 0; i < attributes.getLength(); ++i ) {
331 Attr attr = (Attr) attributes.item(i);
332 String attrName = attr.getNodeName();
334 String attrValue = attr.getNodeValue();
335 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
336 if ( attrName.equals("name"))
337 xmlRootElementName = attrValue;
340 if ( javaTypeName.equals("RelationshipList")) {
341 System.out.println( "Skipping " + javaTypeName);
342 generatedJavaType.put(javaTypeName, null);
347 Element parentElement = (Element)parentNodes.item(0);
348 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
350 Element childElement;
351 String xmlElementWrapper;
353 Element xmlElementElement;
355 String elementName, elementType, elementIsKey, elementIsRequired, elementContainerType;
356 StringBuffer sb1 = new StringBuffer();
357 if ( xmlElementNodes.getLength() > 0 ) {
358 sb1.append(" <xs:element name=\"" + xmlRootElementName + "\">\n");
359 sb1.append(" <xs:complexType>\n");
360 NodeList properties = GenerateXsd.locateXmlProperties(javaTypeElement);
361 if (properties != null) {
362 System.out.println("properties found for: " + xmlRootElementName);
363 sb1.append(" <xs:annotation>\r\n");
364 insertAnnotation(properties, false, "class", sb1, " ");
366 sb1.append(" </xs:annotation>\r\n");
368 System.out.println("no properties found for: " + xmlRootElementName);
370 sb1.append(" <xs:sequence>\n");
371 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
373 xmlElementElement = (Element)xmlElementNodes.item(i);
374 childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
376 xmlElementWrapper = null;
377 if ( childNodes.getLength() > 0 ) {
378 childElement = (Element)childNodes.item(0);
380 attributes = childElement.getAttributes();
381 for ( int k = 0; k < attributes.getLength(); ++k ) {
382 Attr attr = (Attr) attributes.item(k);
383 String attrName = attr.getNodeName();
384 String attrValue = attr.getNodeValue();
385 if ( attrName.equals("name")) {
386 xmlElementWrapper = attrValue;
387 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
392 attributes = xmlElementElement.getAttributes();
396 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
397 for ( int j = 0; j < attributes.getLength(); ++j ) {
398 Attr attr = (Attr) attributes.item(j);
399 String attrName = attr.getNodeName();
401 String attrValue = attr.getNodeValue();
402 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
403 if ( attrName.equals("name")) {
404 elementName = attrValue;
406 if ( attrName.equals("type")) {
407 elementType = attrValue;
408 if ( attrValue.contains(apiVersionFmt) ) {
409 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
410 if ( !generatedJavaType.containsKey(addType) ) {
411 generatedJavaType.put(addType, attrValue);
412 sb.append(processJavaTypeElement( addType, getJavaTypeElement(addType) ));
418 if ( attrName.equals("xml-key")) {
419 elementIsKey = attrValue;
421 if ( attrName.equals("required")) {
422 elementIsRequired = attrValue;
424 if ( attrName.equals("container-type")) {
425 elementContainerType = attrValue;
429 if ( xmlElementWrapper != null ) {
430 sb1.append(" <xs:element name=\"" + xmlElementWrapper +"\"");
431 if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) {
432 sb1.append(" minOccurs=\"0\"");
435 sb1.append(" <xs:complexType>\n");
436 properties = GenerateXsd.locateXmlProperties(javaTypeElement);
437 if (properties != null) {
438 sb1.append(" <xs:annotation>\r\n");
439 insertAnnotation(properties, false, "class", sb1, " ");
440 sb1.append(" </xs:annotation>\r\n");
442 System.out.println("no properties found for: " + xmlElementWrapper);
444 sb1.append(" <xs:sequence>\n");
447 if ("Nodes".equals(addType)) {
448 System.out.println ("Skipping nodes, temporary testing");
451 if ( addType != null ) {
452 //sb1.append(" <xs:element ref=\"tns:" + elementName +"\"");
453 sb1.append(" <xs:element ref=\"tns:" + getXmlRootElementName(addType) +"\"");
455 sb1.append(" <xs:element name=\"" + elementName +"\"");
457 if ( elementType.equals("java.lang.String"))
458 sb1.append(" type=\"xs:string\"");
459 //if ( elementType.equals("java.lang.String"))
460 //sb1.append(" type=\"xs:string\"");
461 if ( elementType.equals("java.lang.Long"))
462 sb1.append(" type=\"xs:unsignedInt\"");
463 if ( elementType.equals("java.lang.Integer"))
464 sb1.append(" type=\"xs:int\"");
465 if ( elementType.equals("java.lang.Boolean"))
466 sb1.append(" type=\"xs:boolean\"");
467 //if ( elementIsRequired != null && elementIsRequired.equals("true")||addType != null) {
468 if ( elementIsRequired == null || !elementIsRequired.equals("true")||addType != null) {
469 sb1.append(" minOccurs=\"0\"");
471 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
472 sb1.append(" maxOccurs=\"unbounded\"");
474 properties = GenerateXsd.locateXmlProperties(xmlElementElement);
475 if (properties != null || elementIsKey != null) {
477 sb1.append(" <xs:annotation>\r\n");
478 insertAnnotation(properties, elementIsKey != null, "field", sb1, " ");
479 sb1.append(" </xs:annotation>\r\n");
481 if (xmlElementWrapper== null) {
482 sb1.append(" </xs:element>\n");
487 if ( xmlElementWrapper != null ) {
488 sb1.append(" </xs:sequence>\n");
489 sb1.append(" </xs:complexType>\n");
490 sb1.append(" </xs:element>\n");
494 if ( xmlRootElementName.equals("notify") ||
495 xmlRootElementName.equals("relationship") ||
496 xmlRootElementName.equals("relationship-data") ||
497 xmlRootElementName.equals("related-to-property") )
499 sb1.append(" <xs:any namespace=\"##other\" processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n");
501 sb1.append(" </xs:sequence>\n");
502 sb1.append(" </xs:complexType>\n");
503 sb1.append(" </xs:element>\n");
506 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
507 Element valElement = (Element) valNodes.item(0);
508 attributes = valElement.getAttributes();
509 for ( int i = 0; i < attributes.getLength(); ++i ) {
510 Attr attr = (Attr) attributes.item(i);
511 String attrName = attr.getNodeName();
513 String attrValue = attr.getNodeValue();
514 System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
515 if ( attrValue.equals("name"))
516 xmlRootElementName = attrValue;
520 if ( xmlElementNodes.getLength() < 1 ) {
521 sb.append(" <xs:element name=\"" + xmlRootElementName + "\">\n");
522 sb.append(" <xs:complexType>\n");
523 sb.append(" <xs:sequence/>\n");
524 sb.append(" </xs:complexType>\n");
525 sb.append(" </xs:element>\n");
526 generatedJavaType.put(javaTypeName, null);
527 return sb.toString();
532 return sb.toString();
535 private static void insertAnnotation(NodeList items, boolean isKey, String target, StringBuffer sb1, String indentation) {
536 if (items != null || isKey) {
537 List<String> metadata = new ArrayList<>();
543 metadata.add("isKey=true");
546 for (int i = 0; i < items.getLength(); i++) {
547 item = (Element)items.item(i);
548 name = item.getAttribute("name");
549 value = item.getAttribute("value");
550 if (name.equals("abstract")) {
552 } else if (name.equals("extends")) {
553 name = "extendsFrom";
555 metadata.add(name + "=\"" + value.replaceAll("&", "&") + "\"");
556 System.out.println("property name: " + name);
561 indentation + " <xs:appinfo>\r\n" +
562 indentation + " <annox:annotate target=\""+target+"\">@org.openecomp.aai.annotations.Metadata(" + Joiner.on(",").join(metadata) + ")</annox:annotate>\r\n" +
563 indentation + " </xs:appinfo>\r\n");
568 private static Element getJavaTypeElement( String javaTypeName )
571 String attrName, attrValue;
573 Element javaTypeElement;
574 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
575 javaTypeElement = (Element) javaTypeNodes.item(i);
576 NamedNodeMap attributes = javaTypeElement.getAttributes();
577 for ( int j = 0; j < attributes.getLength(); ++j ) {
578 attr = (Attr) attributes.item(j);
579 attrName = attr.getNodeName();
580 attrValue = attr.getNodeValue();
581 if ( attrName.equals("name") && attrValue.equals(javaTypeName))
582 return javaTypeElement;
585 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
586 return (Element) null;
589 private static Element getJavaTypeElementSwagger( String javaTypeName )
592 String attrName, attrValue;
594 Element javaTypeElement;
595 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
596 javaTypeElement = (Element) javaTypeNodes.item(i);
597 NamedNodeMap attributes = javaTypeElement.getAttributes();
598 for ( int j = 0; j < attributes.getLength(); ++j ) {
599 attr = (Attr) attributes.item(j);
600 attrName = attr.getNodeName();
601 attrValue = attr.getNodeValue();
602 if ( attrName.equals("name") && attrValue.equals(javaTypeName))
603 return javaTypeElement;
606 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
607 return (Element) null;
609 private static String getXmlRootElementName( String javaTypeName )
612 String attrName, attrValue;
614 Element javaTypeElement;
615 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
616 javaTypeElement = (Element) javaTypeNodes.item(i);
617 NamedNodeMap attributes = javaTypeElement.getAttributes();
618 for ( int j = 0; j < attributes.getLength(); ++j ) {
619 attr = (Attr) attributes.item(j);
620 attrName = attr.getNodeName();
621 attrValue = attr.getNodeValue();
622 if ( attrName.equals("name") && attrValue.equals(javaTypeName)) {
623 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
624 Element valElement = (Element) valNodes.item(0);
625 attributes = valElement.getAttributes();
626 for ( int k = 0; k < attributes.getLength(); ++k ) {
627 attr = (Attr) attributes.item(k);
628 attrName = attr.getNodeName();
630 attrValue = attr.getNodeValue();
631 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
632 if ( attrName.equals("name"))
638 System.out.println( "oxm file format error, missing java-type " + javaTypeName);
643 public static String processOxmFile( File oxmFile )
645 StringBuffer sb = new StringBuffer();
646 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
647 String namespace = "org.openecomp";
648 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
649 + apiVersion + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + apiVersion + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
651 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" +
652 " jaxb:version=\"2.1\" \r\n" +
653 " xmlns:annox=\"http://annox.dev.java.net\" \r\n" +
654 " jaxb:extensionBindingPrefixes=\"annox\">\n\n");
658 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
659 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
660 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
661 Document doc = dBuilder.parse(oxmFile);
663 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
664 Element bindingElement;
665 NodeList javaTypesNodes;
666 Element javaTypesElement;
668 Element javaTypeElement;
671 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
672 System.out.println( "missing <binding-nodes> in " + oxmFile );
676 bindingElement = (Element) bindingsNodes.item(0);
677 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
678 if ( javaTypesNodes.getLength() < 1 ) {
679 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
682 javaTypesElement = (Element) javaTypesNodes.item(0);
683 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
684 if ( javaTypeNodes.getLength() < 1 ) {
685 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
690 String attrName, attrValue;
692 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
693 javaTypeElement = (Element) javaTypeNodes.item(i);
694 NamedNodeMap attributes = javaTypeElement.getAttributes();
696 for ( int j = 0; j < attributes.getLength(); ++j ) {
697 attr = (Attr) attributes.item(j);
698 attrName = attr.getNodeName();
699 attrValue = attr.getNodeValue();
700 if ( attrName.equals("name"))
701 javaTypeName = attrValue;
703 if ( javaTypeName == null ) {
704 System.out.println( "<java-type> has no name attribute in " + oxmFile );
707 if ("Nodes".equals(javaTypeName)) {
708 System.out.println("skipping Nodes entry (temporary feature)");
711 if ( !generatedJavaType.containsKey(javaTypeName) ) {
712 generatedJavaType.put(javaTypeName, null);
713 sb.append(processJavaTypeElement( javaTypeName, javaTypeElement ));
717 } catch (Exception e) {
721 sb.append("</xs:schema>\n");
722 return sb.toString();
725 private static boolean isStandardType( String elementType )
727 switch ( elementType ) {
728 case "java.lang.String":
729 case "java.lang.Long":
730 case "java.lang.Integer":
731 case"java.lang.Boolean":
737 private static Vector<String> getIndexedProps( String attrValue )
739 if ( attrValue == null )
741 StringTokenizer st = new StringTokenizer( attrValue, ",");
742 if ( st.countTokens() == 0 )
744 Vector<String> result = new Vector<String>();
745 while ( st.hasMoreTokens()) {
746 result.add(st.nextToken());
751 private static Class<?> getEdgeRulesClass() throws ClassNotFoundException {
752 Class<?> result = null;
754 // If a class matching the apiVersion exists, we are generating documentation for a prior release
755 // Otherwise, we're generated documentation for the current release.
757 result = Class.forName("org.openecomp.aai.dbmodel." + apiVersion +".gen.DbEdgeRules");
758 } catch (ClassNotFoundException ex) {
759 result = Class.forName("org.openecomp.aai.dbmodel.DbEdgeRules");
765 * Guaranteed to at least return non null but empty collection of edge descriptions
766 * @param nodeName name of the vertex whose edge relationships to return
767 * @return collection of node neighbors based on DbEdgeRules
769 private static Collection<EdgeDescription> getEdgeRules( String nodeName )
772 ArrayList<EdgeDescription> result = new ArrayList<>();
773 Iterator<String> edgeRulesIterator;
777 Field mapfield = versionedClass.getField("EdgeRules");
778 Object map = mapfield.get(null);
779 if (map instanceof Multimap<?,?>) {
780 edgeRulesIterator = ((Multimap<String,String>) map).keySet().iterator();
782 throw new NoSuchFieldException ("Didn't get back the multimap field expected");
784 GenerateXsd x = new GenerateXsd();
786 while( edgeRulesIterator.hasNext() ){
787 String ruleKey = edgeRulesIterator.next();
788 if ( ruleKey.startsWith(nodeName + "|" ) ||
789 ruleKey.endsWith("|" + nodeName)) {
790 Collection <String> edRuleColl = DbEdgeRules.EdgeRules.get(ruleKey);
791 Iterator <String> ruleItr = edRuleColl.iterator();
792 while( ruleItr.hasNext() ){
793 EdgeDescription edgeDes = x.new EdgeDescription();
794 edgeDes.setRuleKey(ruleKey);
795 String fullRuleString = ruleItr.next();
796 String[] toks = fullRuleString.split(",");
798 if (toks.length > 1) {
799 edgeDes.setDirection(toks[1]);
801 if (toks.length > 2) {
802 edgeDes.setMultiplicity(toks[2]);
804 if (toks.length > 3) {
805 if (toks[3].equals("true"))
806 edgeDes.setType(LineageType.PARENT);
807 else if (toks[3].equals("parent"))
808 edgeDes.setType(LineageType.PARENT);
809 else if (toks[3].equals("child"))
810 edgeDes.setType(LineageType.CHILD);
812 edgeDes.setType(LineageType.UNRELATED);
814 if (toks.length > 5) {
815 edgeDes.setHasDelTarget(toks[5]);;
819 //System.out.println( "nodeName " + nodeName + " ruleKey " + ruleKey + " ruleString " + fullRuleString);
820 //result.add(ruleKey + "-" + fullRuleString);
825 } catch (Exception ex) {
826 ex.printStackTrace();
832 * Finds the default delete scope from DBEdgeRules
833 * @param nodeName name of vertex whose delete scope to return
834 * @return default delete scope of the input nodeName, null if none.
836 private static String getDeleteRules( String nodeName )
838 String result = null;
839 Iterator<String> delRulesIterator;
843 Field mapfield = versionedClass.getField("DefaultDeleteScope");
844 Object map = mapfield.get(null);
845 if (map instanceof Multimap<?,?>) {
846 delRulesIterator = ((Multimap<String,String>) map).keySet().iterator();
848 throw new NoSuchFieldException ("Didn't get back the multimap field expected");
851 while( delRulesIterator.hasNext() ){
852 String ruleKey = delRulesIterator.next();
853 if ( ruleKey.equals(nodeName)) {
854 Collection <String> deRuleColl = DbEdgeRules.DefaultDeleteScope.get(ruleKey);
855 Iterator <String> ruleItr = deRuleColl.iterator();
856 if( ruleItr.hasNext() ){
857 result = ruleItr.next();
862 } catch (Exception ex) {
863 ex.printStackTrace();
868 public static String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
869 StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
870 String getItemName, StringBuffer pathParams, String queryParams, String validEdges) {
872 String xmlRootElementName = null;
874 //Map<String, String> addJavaType = new HashMap<String, String>();
875 String useTag = null;
876 String useOpId = null;
881 case "ServiceDesignAndCreation":
883 case "CloudInfrastructure":
890 if ( !javaTypeName.equals("Inventory") ) {
891 if ( javaTypeName.equals("AaiInternal"))
894 useOpId = javaTypeName;
896 useOpId = opId + javaTypeName;
898 useTag = javaTypeName;
901 NodeList parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
903 if ( parentNodes.getLength() == 0 ) {
904 System.out.println( "no java-attributes for java-type " + javaTypeName);
909 NamedNodeMap attributes;
911 NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
912 Element valElement = (Element) valNodes.item(0);
913 attributes = valElement.getAttributes();
914 for ( int i = 0; i < attributes.getLength(); ++i ) {
915 Attr attr = (Attr) attributes.item(i);
916 String attrName = attr.getNodeName();
918 String attrValue = attr.getNodeValue();
919 //System.out.println("Found xml-root-element attribute: " + attrName + " with value: " + attrValue);
920 if ( attrName.equals("name"))
921 xmlRootElementName = attrValue;
924 if ( xmlRootElementName.equals("oam-networks"))
925 System.out.println( "xmlRootElement oam-networks with getItemData [" + getItemName + "]");
929 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
934 Element childElement;
935 NodeList xmlPropNodes = javaTypeElement.getElementsByTagName("xml-properties");
936 Element xmlPropElement;
937 String pathDescriptionProperty = null;
940 Vector<String> indexedProps = null;
942 /*System.out.println( "javaTypeName " + javaTypeName + " has xml-properties length " + xmlPropNodes.getLength());
943 if ( path != null && path.equals("/network/generic-vnfs"))
944 System.out.println("path is " + "/network/generic-vnfs with getItemName " + getItemName);
946 if ( xmlPropNodes.getLength() > 0 ) {
948 for ( int i = 0; i < xmlPropNodes.getLength(); ++i ) {
949 xmlPropElement = (Element)xmlPropNodes.item(i);
950 if ( !xmlPropElement.getParentNode().isSameNode(javaTypeElement))
952 childNodes = xmlPropElement.getElementsByTagName("xml-property");
954 if ( childNodes.getLength() > 0 ) {
955 for ( int j = 0; j < childNodes.getLength(); ++j ) {
956 childElement = (Element)childNodes.item(j);
958 int useValue = VALUE_NONE;
959 attributes = childElement.getAttributes();
960 for ( int k = 0; k < attributes.getLength(); ++k ) {
961 Attr attr = (Attr) attributes.item(k);
962 String attrName = attr.getNodeName();
963 String attrValue = attr.getNodeValue();
964 if ( attrName == null || attrValue == null )
966 if ( attrName.equals("name") && attrValue.equals("description")) {
967 useValue = VALUE_DESCRIPTION;
969 if ( useValue == VALUE_DESCRIPTION && attrName.equals("value")) {
970 pathDescriptionProperty = attrValue;
972 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
974 if ( attrValue.equals("indexedProps")) {
975 useValue = VALUE_INDEXED_PROPS;
977 if ( useValue == VALUE_INDEXED_PROPS && attrName.equals("value")) {
978 indexedProps = getIndexedProps( attrValue );
985 //System.out.println("javaTypeName " + javaTypeName + " description " + pathDescriptionProperty);
988 if ( javaTypeName.equals("RelationshipList")) {
989 System.out.println( "Skipping " + javaTypeName);
990 generatedJavaType.put(javaTypeName, null);
995 Element parentElement = (Element)parentNodes.item(0);
996 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
999 String attrDescription = null;
1001 Element xmlElementElement;
1002 String addType = null;
1003 String elementType = null, elementIsKey = null, elementIsRequired, elementContainerType = null;
1004 String elementName = null;
1005 StringBuffer sbParameters = new StringBuffer();
1007 StringBuffer sbRequired = new StringBuffer();
1008 int requiredCnt = 0;
1009 int propertyCnt = 0;
1010 StringBuffer sbProperties = new StringBuffer();
1011 StringBuffer sbIndexedParams = new StringBuffer();
1015 if ( xmlRootElementName.equals("inventory"))
1017 else if ( path == null )
1018 //path = "/aai/" + apiVersion;
1019 path = "/" + xmlRootElementName;
1021 path += "/" + xmlRootElementName;
1022 st = new StringTokenizer(path, "/");
1024 if ( path.equals("/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription"))
1025 System.out.println("processing path /business/customers/customer/{global-customer-id}/service-subscriptions with tag " + tag);
1027 boolean genPath = false;
1029 if ( path != null && path.equals("/network/generic-vnfs/generic-vnf"))
1030 System.out.println("path is " + "/network/generic-vnfs/generic-vnf");
1032 if ( st.countTokens() > 1 && getItemName == null ) {
1033 if ( appliedPaths.containsKey(path))
1035 appliedPaths.put(path, null);
1037 if ( path.contains("/relationship/") ) { // filter paths with relationship-list
1040 if ( path.endsWith("/relationship-list")) {
1046 Vector<String> addTypeV = null;
1047 if ( xmlElementNodes.getLength() > 0 ) {
1049 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
1050 xmlElementElement = (Element)xmlElementNodes.item(i);
1051 if ( !xmlElementElement.getParentNode().isSameNode(parentElement))
1053 /*childNodes = xmlElementElement.getElementsByTagName("xml-element-wrapper");
1054 if ( childNodes.getLength() > 0 ) {
1055 childElement = (Element)childNodes.item(0);
1057 attributes = childElement.getAttributes();
1058 for ( int k = 0; k < attributes.getLength(); ++k ) {
1059 Attr attr = (Attr) attributes.item(k);
1060 String attrName = attr.getNodeName();
1061 String attrValue = attr.getNodeValue();
1062 if ( attrName.equals("name")) {
1063 xmlElementWrapper = attrValue;
1064 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1070 valNodes = xmlElementElement.getElementsByTagName("xml-properties");
1071 attrDescription = null;
1072 if ( valNodes.getLength() > 0 ) {
1073 for ( int j = 0; j < valNodes.getLength(); ++j ) {
1074 valElement = (Element)valNodes.item(j);
1075 if ( !valElement.getParentNode().isSameNode(xmlElementElement))
1077 childNodes = valElement.getElementsByTagName("xml-property");
1078 if ( childNodes.getLength() > 0 ) {
1079 childElement = (Element)childNodes.item(0);
1081 attributes = childElement.getAttributes();
1082 attrDescription = null;
1083 boolean useValue = false;
1084 for ( int k = 0; k < attributes.getLength(); ++k ) {
1085 Attr attr = (Attr) attributes.item(k);
1086 String attrName = attr.getNodeName();
1087 String attrValue = attr.getNodeValue();
1088 if ( attrName.equals("name") && attrValue.equals("description")) {
1091 if ( useValue && attrName.equals("value")) {
1092 attrDescription = attrValue;
1093 //System.out.println("found xml-element-wrapper " + xmlElementWrapper);
1101 attributes = xmlElementElement.getAttributes();
1102 addTypeV = null; // vector of 1
1105 elementName = elementType = elementIsKey = elementIsRequired = elementContainerType = null;
1106 for ( int j = 0; j < attributes.getLength(); ++j ) {
1107 Attr attr = (Attr) attributes.item(j);
1108 String attrName = attr.getNodeName();
1110 String attrValue = attr.getNodeValue();
1111 //System.out.println("For " + xmlRootElementName + " Found xml-element attribute: " + attrName + " with value: " + attrValue);
1112 if ( attrName.equals("name")) {
1113 elementName = attrValue;
1116 if ( attrName.equals("type") && getItemName == null ) {
1117 elementType = attrValue;
1118 if ( attrValue.contains(apiVersionFmt) ) {
1119 addType = attrValue.substring(attrValue.lastIndexOf('.')+1);
1120 if ( addTypeV == null )
1121 addTypeV = new Vector<String>();
1122 addTypeV.add(addType);
1126 if ( attrName.equals("xml-key")) {
1127 elementIsKey = attrValue;
1128 path += "/{" + elementName + "}";
1130 if ( attrName.equals("required")) {
1131 elementIsRequired = attrValue;
1133 if ( attrName.equals("container-type")) {
1134 elementContainerType = attrValue;
1137 if ( getItemName != null ) {
1138 if ( getItemName.equals("array") ) {
1139 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1140 //System.out.println( " returning array " + elementName );
1144 } else { // not an array check
1145 if ( elementContainerType == null || !elementContainerType.equals("java.util.ArrayList")) {
1146 //System.out.println( " returning object " + elementName );
1151 //System.out.println( " returning null" );
1154 if ( elementIsRequired != null ) {
1155 if ( requiredCnt == 0 )
1156 sbRequired.append(" required:\n");
1158 if ( addTypeV != null ) {
1159 for ( int k = 0; k < addTypeV.size(); ++i ) {
1160 sbRequired.append(" - " + getXmlRootElementName(addTypeV.elementAt(k)) + ":\n");
1163 sbRequired.append(" - " + elementName + "\n");
1167 if ( elementIsKey != null ) {
1168 sbParameters.append((" - name: " + elementName + "\n"));
1169 sbParameters.append((" in: path\n"));
1170 if ( attrDescription != null && attrDescription.length() > 0 )
1171 sbParameters.append((" description: " + attrDescription + "\n"));
1172 sbParameters.append((" required: true\n"));
1173 if ( elementType.equals("java.lang.String"))
1174 sbParameters.append(" type: string\n");
1175 if ( elementType.equals("java.lang.Long")) {
1176 sbParameters.append(" type: integer\n");
1177 sbParameters.append(" format: int64\n");
1179 if ( elementType.equals("java.lang.Integer")) {
1180 sbParameters.append(" type: integer\n");
1181 sbParameters.append(" format: int32\n");
1183 if ( elementType.equals("java.lang.Boolean"))
1184 sbParameters.append(" type: boolean\n");
1187 } else if ( indexedProps != null
1188 && indexedProps.contains(elementName ) ) {
1189 sbIndexedParams.append((" - name: " + elementName + "\n"));
1190 sbIndexedParams.append((" in: query\n"));
1191 if ( attrDescription != null && attrDescription.length() > 0 )
1192 sbIndexedParams.append((" description: " + attrDescription + "\n"));
1193 sbIndexedParams.append((" required: false\n"));
1194 if ( elementType.equals("java.lang.String"))
1195 sbIndexedParams.append(" type: string\n");
1196 if ( elementType.equals("java.lang.Long")) {
1197 sbIndexedParams.append(" type: integer\n");
1198 sbIndexedParams.append(" format: int64\n");
1200 if ( elementType.equals("java.lang.Integer")) {
1201 sbIndexedParams.append(" type: integer\n");
1202 sbIndexedParams.append(" format: int32\n");
1204 if ( elementType.equals("java.lang.Boolean"))
1205 sbIndexedParams.append(" type: boolean\n");
1209 if ( elementName != null && elementName.equals("inventory-item"))
1210 System.out.println( "processing inventory-item elementName");
1213 if ( isStandardType(elementType)) {
1214 sbProperties.append(" " + elementName + ":\n");
1216 sbProperties.append(" type: ");
1218 if ( elementType.equals("java.lang.String"))
1219 sbProperties.append("string\n");
1220 else if ( elementType.equals("java.lang.Long")) {
1221 sbProperties.append("integer\n");
1222 sbProperties.append(" format: int64\n");
1224 else if ( elementType.equals("java.lang.Integer")){
1225 sbProperties.append("integer\n");
1226 sbProperties.append(" format: int32\n");
1228 else if ( elementType.equals("java.lang.Boolean"))
1229 sbProperties.append("boolean\n");
1230 if ( attrDescription != null && attrDescription.length() > 0 )
1231 sbProperties.append(" description: " + attrDescription + "\n");
1234 //if ( addType != null && elementContainerType != null && elementContainerType.equals("java.util.ArrayList") ) {
1236 if ( addTypeV != null ) {
1237 StringBuffer newPathParams = null;
1238 if ( pathParams != null ) {
1239 newPathParams = new StringBuffer();
1240 newPathParams.append(pathParams);
1242 if ( sbParameters.toString().length() > 0 ) {
1243 if ( newPathParams == null )
1244 newPathParams = new StringBuffer();
1245 newPathParams.append(sbParameters);
1247 String newQueryParams = null;
1248 if ( sbIndexedParams.toString().length() > 0 ) {
1249 if ( queryParams == null )
1250 newQueryParams = sbIndexedParams.toString();
1252 newQueryParams = queryParams + sbIndexedParams.toString();
1254 newQueryParams = queryParams;
1256 for ( int k = 0; k < addTypeV.size(); ++k ) {
1257 addType = addTypeV.elementAt(k);
1259 if ( opId == null || !opId.contains(addType)) {
1260 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1261 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, null,
1262 newPathParams, newQueryParams, validEdges);
1264 // need item name of array
1265 String itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1266 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1267 "array", null, null, null );
1269 if ( itemName != null ) {
1270 if ( addType.equals("AaiInternal") ) {
1271 //System.out.println( "addType AaiInternal, skip properties");
1273 } else if ( getItemName == null) {
1275 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1276 sbProperties.append(" type: array\n items:\n");
1277 sbProperties.append(" $ref: \"#/definitions/" + itemName + "\"\n");
1278 if ( attrDescription != null && attrDescription.length() > 0 )
1279 sbProperties.append(" description: " + attrDescription + "\n");
1282 /*itemName = processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1283 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId, "other" );
1284 if ( itemName != null ) {
1286 if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
1287 // need properties for getXmlRootElementName(addType)
1288 newPathParams = null;
1289 if ( pathParams != null ) {
1290 newPathParams = new StringBuffer();
1291 newPathParams.append(pathParams);
1293 if ( sbParameters.toString().length() > 0 ) {
1294 if ( newPathParams == null )
1295 newPathParams = new StringBuffer();
1296 newPathParams.append(sbParameters);
1298 newQueryParams = null;
1299 if ( sbIndexedParams.toString().length() > 0 ) {
1300 if ( queryParams == null )
1301 newQueryParams = sbIndexedParams.toString();
1303 newQueryParams = queryParams + sbIndexedParams.toString();
1305 newQueryParams = queryParams;
1307 processJavaTypeElementSwagger( addType, getJavaTypeElementSwagger(addType),
1308 pathSb, definitionsSb, path, tag == null ? useTag : tag, useOpId,
1309 null, newPathParams, newQueryParams, validEdges );
1310 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1311 sbProperties.append(" type: array\n items: \n");
1312 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1314 sbProperties.append(" " + getXmlRootElementName(addType) + ":\n");
1315 sbProperties.append(" type: object\n");
1316 sbProperties.append(" $ref: \"#/definitions/" + getXmlRootElementName(addType) + "\"\n");
1318 if ( attrDescription != null && attrDescription.length() > 0 )
1319 sbProperties.append(" description: " + attrDescription + "\n");
1323 System.out.println(" unable to define swagger object for " + addType);
1327 //if ( getItemName == null) looking for missing properties
1328 //generatedJavaType.put(addType, null);
1335 if ( useOpId.equals("CloudInfrastructureComplexesComplexCtagPools"))
1336 System.out.println( "adding path CloudInfrastructureComplexesComplexCtagPools");
1339 if ( !path.endsWith("/relationship") ) {
1340 pathSb.append(" " + path + ":\n" );
1341 pathSb.append(" get:\n");
1342 pathSb.append(" tags:\n");
1343 pathSb.append(" - " + tag + "\n");
1344 pathSb.append(" summary: returns " + xmlRootElementName + "\n");
1346 pathSb.append(" description: returns " + xmlRootElementName + "\n");
1347 pathSb.append(" operationId: get" + useOpId + "\n");
1348 pathSb.append(" produces:\n");
1349 pathSb.append(" - application/json\n");
1350 pathSb.append(" - application/xml\n");
1352 pathSb.append(" responses:\n");
1353 pathSb.append(" \"200\":\n");
1354 pathSb.append(" description: successful operation\n");
1355 pathSb.append(" schema:\n");
1356 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1357 pathSb.append(" \"default\":\n");
1358 pathSb.append(" " + responsesUrl);
1360 pathSb.append(" \"200\":\n");
1361 pathSb.append(" description: successful operation\n");
1362 pathSb.append(" schema:\n");
1363 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1364 pathSb.append(" \"404\":\n");
1365 pathSb.append(" description: resource was not found\n");
1366 pathSb.append(" \"400\":\n");
1367 pathSb.append(" description: bad request\n");
1369 if ( path.indexOf('{') > 0 ) {
1371 if ( sbParameters.toString().length() > 0 ) {
1372 if ( pathParams == null )
1373 pathParams = new StringBuffer();
1374 pathParams.append(sbParameters);
1376 if ( pathParams != null) {
1377 pathSb.append(" parameters:\n");
1378 pathSb.append(pathParams);
1380 System.out.println( "null pathParams for " + useOpId);
1381 if ( sbIndexedParams.toString().length() > 0 ) {
1382 if ( queryParams == null )
1383 queryParams = sbIndexedParams.toString();
1385 queryParams = queryParams + sbIndexedParams.toString();
1387 if ( queryParams != null ) {
1388 if ( pathParams == null ) {
1389 pathSb.append(" parameters:\n");
1391 pathSb.append(queryParams);
1395 boolean skipPutDelete = false; // no put or delete for "all"
1396 if ( !path.endsWith("/relationship") ) {
1397 if ( !path.endsWith("}") ){
1398 skipPutDelete = true;
1402 if ( path.indexOf('{') > 0 && !opId.startsWith("Search") &&!skipPutDelete) {
1404 if ( path.endsWith("/relationship") ) {
1405 pathSb.append(" " + path + ":\n" );
1407 pathSb.append(" put:\n");
1408 pathSb.append(" tags:\n");
1409 pathSb.append(" - " + tag + "\n");
1411 if ( path.endsWith("/relationship") ) {
1412 pathSb.append(" summary: see node definition for valid relationships\n");
1414 pathSb.append(" summary: create or update an existing " + xmlRootElementName + "\n");
1415 pathSb.append(" description: create or update an existing " + xmlRootElementName + "\n");
1417 pathSb.append(" operationId: createOrUpdate" + useOpId + "\n");
1418 pathSb.append(" consumes:\n");
1419 pathSb.append(" - application/json\n");
1420 pathSb.append(" - application/xml\n");
1421 pathSb.append(" produces:\n");
1422 pathSb.append(" - application/json\n");
1423 pathSb.append(" - application/xml\n");
1424 pathSb.append(" responses:\n");
1425 pathSb.append(" \"default\":\n");
1426 pathSb.append(" " + responsesUrl);
1428 pathSb.append(" responses:\n");
1429 pathSb.append(" \"200\":\n");
1430 pathSb.append(" description: existing resource has been modified and there is a response buffer\n");
1431 pathSb.append(" \"201\":\n");
1432 pathSb.append(" description: new resource is created\n");
1433 pathSb.append(" \"202\":\n");
1434 pathSb.append(" description: action requested but may have taken other actions as well, which are returned in the response payload\n");
1435 pathSb.append(" \"204\":\n");
1436 pathSb.append(" description: existing resource has been modified and there is no response buffer\n");
1437 pathSb.append(" \"400\":\n");
1438 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1439 pathSb.append(" \"404\":\n");
1440 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1442 pathSb.append(" parameters:\n");
1443 //pathSb.append(" - in: path\n");
1444 pathSb.append(pathParams); // for nesting
1445 pathSb.append(" - name: body\n");
1446 pathSb.append(" in: body\n");
1447 pathSb.append(" description: " + xmlRootElementName + " object that needs to be created or updated\n");
1448 pathSb.append(" required: true\n");
1449 pathSb.append(" schema:\n");
1450 pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
1452 if ( queryParams != null ) {
1453 pathSb.append(queryParams);
1457 pathSb.append(" delete:\n");
1458 pathSb.append(" tags:\n");
1459 pathSb.append(" - " + tag + "\n");
1460 pathSb.append(" summary: delete an existing " + xmlRootElementName + "\n");
1462 pathSb.append(" description: delete an existing " + xmlRootElementName + "\n");
1464 pathSb.append(" operationId: delete" + useOpId + "\n");
1465 pathSb.append(" consumes:\n");
1466 pathSb.append(" - application/json\n");
1467 pathSb.append(" - application/xml\n");
1468 pathSb.append(" produces:\n");
1469 pathSb.append(" - application/json\n");
1470 pathSb.append(" - application/xml\n");
1471 pathSb.append(" responses:\n");
1472 pathSb.append(" \"default\":\n");
1473 pathSb.append(" " + responsesUrl);
1475 pathSb.append(" responses:\n");
1476 pathSb.append(" \"200\":\n");
1477 pathSb.append(" description: successful, the response includes an entity describing the status\n");
1478 pathSb.append(" \"204\":\n");
1479 pathSb.append(" description: successful, action has been enacted but the response does not include an entity\n");
1480 pathSb.append(" \"400\":\n");
1481 pathSb.append(" description: Bad Request will be returned if headers are missing\n");
1482 pathSb.append(" \"404\":\n");
1483 pathSb.append(" description: Not Found will be returned if an unknown URL is used\n");
1485 pathSb.append(" parameters:\n");
1486 //pathSb.append(" - in: path\n");
1487 pathSb.append(pathParams); // for nesting
1488 if ( !path.endsWith("/relationship") ) {
1489 pathSb.append(" - name: resource-version\n");
1491 pathSb.append(" in: query\n");
1492 pathSb.append(" description: resource-version for concurrency\n");
1493 pathSb.append(" required: true\n");
1494 pathSb.append(" type: string\n");
1497 if ( queryParams != null ) {
1498 pathSb.append(queryParams);
1504 if ( generatedJavaType.containsKey(xmlRootElementName) ) {
1508 definitionsSb.append(" " + xmlRootElementName + ":\n");
1509 Collection<EdgeDescription> edges = getEdgeRules(xmlRootElementName );
1510 if ( edges.size() > 0 ) {
1511 StringBuffer sbEdge = new StringBuffer();
1512 sbEdge.append(" ###### Related Nodes\n");
1513 for (EdgeDescription ed : edges) {
1514 if ( ed.getRuleKey().startsWith(xmlRootElementName)) {
1515 sbEdge.append(" - TO ").append(ed.getRuleKey().substring(ed.getRuleKey().indexOf("|")+1));
1516 sbEdge.append(ed.getRelationshipDescription("TO", xmlRootElementName));
1517 sbEdge.append("\n");
1520 for (EdgeDescription ed : edges) {
1521 if ( ed.getRuleKey().endsWith(xmlRootElementName)) {
1522 sbEdge.append(" - FROM ").append(ed.getRuleKey().substring(0, ed.getRuleKey().indexOf("|")));
1523 sbEdge.append(ed.getRelationshipDescription("FROM", xmlRootElementName));
1524 sbEdge.append("\n");
1527 validEdges = sbEdge.toString();
1530 String deleteRule = getDeleteRules(xmlRootElementName);
1531 // Handle description property. Might have a description OR valid edges OR both OR neither.
1532 // Only put a description: tag if there is at least one.
1533 if (pathDescriptionProperty != null || deleteRule != null || validEdges != null) {
1534 definitionsSb.append(" description: |\n");
1536 if ( pathDescriptionProperty != null )
1537 definitionsSb.append(" " + pathDescriptionProperty + "\n" );
1538 if (deleteRule != null)
1539 definitionsSb.append(" ###### Default Delete Scope\n ").append(deleteRule).append("\n");
1540 if (validEdges != null)
1541 definitionsSb.append(validEdges);
1544 if ( requiredCnt > 0 )
1545 definitionsSb.append(sbRequired);
1546 if ( propertyCnt > 0 ) {
1547 definitionsSb.append(" properties:\n");
1548 definitionsSb.append(sbProperties);
1550 generatedJavaType.put(xmlRootElementName, null);
1554 public static String generateSwaggerFromOxmFile( File oxmFile )
1557 StringBuffer sb = new StringBuffer();
1558 sb.append("swagger: \"2.0\"\ninfo:\n description:\n A&AI REST API\n version: \"" + apiVersion +"\"\n");
1559 sb.append(" title: Active and Available Inventory REST API\n");
1560 sb.append(" license:\n name: Apache 2.0\n url: http://www.apache.org/licenses/LICENSE-2.0.html\n");
1561 sb.append("schemes:\n - https\npaths:\n");
1563 sb.append("responses:\n");
1564 sb.append(" \"200\":\n");
1565 sb.append(" description: successful operation\n");
1566 sb.append(" \"404\":\n");
1567 sb.append(" description: resource was not found\n");
1568 sb.append(" \"400\":\n");
1569 sb.append(" description: bad request\n");
1573 versionedClass = getEdgeRulesClass();
1575 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
1576 dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
1577 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
1578 Document doc = dBuilder.parse(oxmFile);
1580 NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
1581 Element bindingElement;
1582 NodeList javaTypesNodes;
1583 Element javaTypesElement;
1585 Element javaTypeElement;
1588 if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
1589 System.out.println( "missing <binding-nodes> in " + oxmFile );
1593 bindingElement = (Element) bindingsNodes.item(0);
1594 javaTypesNodes = bindingElement.getElementsByTagName("java-types");
1595 if ( javaTypesNodes.getLength() < 1 ) {
1596 System.out.println( "missing <binding-nodes><java-types> in " + oxmFile );
1599 javaTypesElement = (Element) javaTypesNodes.item(0);
1601 javaTypeNodes = javaTypesElement.getElementsByTagName("java-type");
1602 if ( javaTypeNodes.getLength() < 1 ) {
1603 System.out.println( "missing <binding-nodes><java-types><java-type> in " + oxmFile );
1607 String javaTypeName;
1608 String attrName, attrValue;
1610 StringBuffer pathSb = new StringBuffer();
1612 StringBuffer definitionsSb = new StringBuffer("definitions:\n");
1614 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
1615 javaTypeElement = (Element) javaTypeNodes.item(i);
1616 NamedNodeMap attributes = javaTypeElement.getAttributes();
1617 javaTypeName = null;
1618 for ( int j = 0; j < attributes.getLength(); ++j ) {
1619 attr = (Attr) attributes.item(j);
1620 attrName = attr.getNodeName();
1621 attrValue = attr.getNodeValue();
1622 if ( attrName.equals("name"))
1623 javaTypeName = attrValue;
1625 if ( javaTypeName == null ) {
1626 System.out.println( "<java-type> has no name attribute in " + oxmFile );
1629 if ( !generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)) ) {
1631 //generatedJavaType.put(javaTypeName, null);
1632 //if ( javaTypeName.equals("search")||javaTypeName.equals("actions"))
1634 processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
1635 definitionsSb, null, null, null, null, null, null, null);
1639 //System.out.println( "definitions block\n" + definitionsSb.toString());
1640 sb.append(definitionsSb.toString());
1641 //sb.append(definitionsSb);
1643 } catch (Exception e) {
1644 e.printStackTrace();
1647 //System.out.println("generated " + sb.toString());
1648 return sb.toString();
1651 private static NodeList locateXmlProperties(Element element) {
1652 XPathExpression expr;
1653 NodeList result = null;
1655 expr = xpath.compile("xml-properties");
1657 Object nodeset = expr.evaluate(element, XPathConstants.NODESET);
1658 if (nodeset != null) {
1659 NodeList nodes = (NodeList) nodeset;
1660 if (nodes != null && nodes.getLength() > 0) {
1661 Element xmlProperty = (Element)nodes.item(0);
1662 result = xmlProperty.getElementsByTagName("xml-property");
1666 } catch (XPathExpressionException e) {
1667 e.printStackTrace();