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();