diff --git a/src/zutil/net/ws/WSMethodDef.java b/src/zutil/net/ws/WSMethodDef.java index 6518b39..e6e11e2 100755 --- a/src/zutil/net/ws/WSMethodDef.java +++ b/src/zutil/net/ws/WSMethodDef.java @@ -181,16 +181,16 @@ public class WSMethodDef { } else { // Specific request type was not provided, try to figure it out by the method name - if (name.startsWith("get")) - this.requestType = WSInterface.RequestType.GET; if (name.startsWith("post")) this.requestType = WSInterface.RequestType.POST; - if (name.startsWith("put")) + else if (name.startsWith("put")) this.requestType = WSInterface.RequestType.PUT; - if (name.startsWith("delete")) + else if (name.startsWith("delete")) this.requestType = WSInterface.RequestType.DELETE; - if (name.startsWith("patch")) + else if (name.startsWith("patch")) this.requestType = WSInterface.RequestType.PATCH; + else + this.requestType = WSInterface.RequestType.GET; } // Handle endpoint path @@ -201,8 +201,8 @@ public class WSMethodDef { else path = this.name; - if (path.startsWith("/")) - path = path.substring(1); + if (!path.startsWith("/")) + path = '/' + path; } /** diff --git a/src/zutil/net/ws/openapi/OpenAPIWriter.java b/src/zutil/net/ws/openapi/OpenAPIWriter.java index 1302866..84fe631 100644 --- a/src/zutil/net/ws/openapi/OpenAPIWriter.java +++ b/src/zutil/net/ws/openapi/OpenAPIWriter.java @@ -12,7 +12,9 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.Writer; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.logging.Logger; /** @@ -58,12 +60,14 @@ public class OpenAPIWriter { public String write() { if (cache == null) { + Map> schemas = new HashMap<>(); + DataNode root = new DataNode(DataNode.DataType.Map); root.set("openapi", OPENAPI_VERSION); root.set("info", generateInfo()); root.set("servers", generateServers()); - root.set("paths", generatePaths()); - root.set("components", generateComponents()); + root.set("paths", generatePaths(schemas)); + root.set("components", generateComponents(schemas)); this.cache = JSONWriter.toString(root); } @@ -74,12 +78,12 @@ public class OpenAPIWriter { DataNode infoRoot = new DataNode(DataNode.DataType.Map); infoRoot.set("title", ws.getName()); infoRoot.set("description", ws.getDocumentation()); + infoRoot.set("version", ""); // Not implemented properties // "termsOfService": xxx, // "contact": {"name": xxx,"url": xxx,"email": xxx}, // "license": {"name": xxx, "url": xxx}, - // "version": xxx return infoRoot; } @@ -87,30 +91,28 @@ public class OpenAPIWriter { DataNode serversRoot = new DataNode(DataNode.DataType.List); for (ServerData data : servers) { - DataNode serverNode = new DataNode(DataNode.DataType.Map); + DataNode serverNode = serversRoot.add(DataNode.DataType.Map); serverNode.set("url", data.url); serverNode.set("description", data.description); - serversRoot.add(serverNode); } return serversRoot; } - private DataNode generatePaths() { + private DataNode generatePaths(Map> schemas) { DataNode pathsRoot = new DataNode(DataNode.DataType.Map); for (WSMethodDef methodDef : ws.getMethods()) { - DataNode pathNode = new DataNode(DataNode.DataType.Map); + DataNode pathNode = pathsRoot.set(methodDef.getPath(), DataNode.DataType.Map); - DataNode typeNode = new DataNode(DataNode.DataType.Map); + DataNode typeNode = pathNode.set(methodDef.getRequestType().toString().toLowerCase(), DataNode.DataType.Map); typeNode.set("description", methodDef.getDocumentation()); - pathNode.set(methodDef.getRequestType().toString().toLowerCase(), typeNode); // -------------------------------------------- // Inputs // -------------------------------------------- - DataNode parameterNode = new DataNode(DataNode.DataType.Map); + DataNode parameterNode = typeNode.set("parameters", DataNode.DataType.Map); for (WSParameterDef parameterDef : methodDef.getInputs()) { parameterNode.set("name", parameterDef.getName()); parameterNode.set("description", parameterDef.getDocumentation()); @@ -119,29 +121,27 @@ public class OpenAPIWriter { parameterNode.set("schema", ""); } - typeNode.set("parameters", parameterNode); // -------------------------------------------- // Outputs // -------------------------------------------- - DataNode responseNode = new DataNode(DataNode.DataType.Map); - for (WSParameterDef parameterDef : methodDef.getOutputs()) { - parameterNode.set("name", parameterDef.getName()); - parameterNode.set("description", parameterDef.getDocumentation()); - parameterNode.set("in", "query"); - parameterNode.set("required", parameterDef.isOptional()); + DataNode responseNode = typeNode.set("responses", DataNode.DataType.Map); + DataNode schemaNode = responseNode.set("200", DataNode.DataType.Map) + .set("content", DataNode.DataType.Map) + .set("application/json", DataNode.DataType.Map) + .set("schema", DataNode.DataType.Map); - parameterNode.set("schema", ""); - } - typeNode.set("responses", responseNode); + String retName = methodDef.getName() + "Return"; + schemas.put("retName", methodDef.getOutputs()); + schemaNode.set("$ref", "#/components/schemas/" + retName); } return pathsRoot; } - private DataNode generateComponents() { + private DataNode generateComponents(Map> schemas) { DataNode componentsRoot = new DataNode(DataNode.DataType.Map); DataNode schemasNode = new DataNode(DataNode.DataType.Map); componentsRoot.set("schemas", schemasNode); diff --git a/src/zutil/net/ws/wsdl/WSDLWriter.java b/src/zutil/net/ws/wsdl/WSDLWriter.java index 51fd216..2d946ac 100644 --- a/src/zutil/net/ws/wsdl/WSDLWriter.java +++ b/src/zutil/net/ws/wsdl/WSDLWriter.java @@ -313,7 +313,9 @@ public class WSDLWriter { empty.addAttribute("name", "empty"); empty.addElement("xsd:sequence"); - for (Class c : types) { + for (int i=0; i c = types.get(i); + // Generate Array type if (c.isArray()) { Class ctmp = ClassUtil.getArrayClass(c); @@ -344,26 +346,26 @@ public class WSDLWriter { Element sequence = type.addElement("xsd:sequence"); Field[] fields = c.getFields(); - for (int i = 0; i < fields.length; i++) { - WSInterface.WSParamName tmp = fields[i].getAnnotation(WSInterface.WSParamName.class); + for (int j=0; j cTmp = ClassUtil.getArrayClass(fields[i].getType()); + Class cTmp = ClassUtil.getArrayClass(fields[j].getType()); if (WSReturnObject.class.isAssignableFrom(cTmp)) { element.addAttribute("type", "tns:" + SOAPHttpPage.getSOAPClassName(cTmp)); if (!types.contains(cTmp)) types.add(cTmp); } else { - element.addAttribute("type", "xsd:" + SOAPHttpPage.getSOAPClassName(fields[i].getType())); + element.addAttribute("type", "xsd:" + SOAPHttpPage.getSOAPClassName(fields[j].getType())); } // Is the Field optional diff --git a/src/zutil/parser/DataNode.java b/src/zutil/parser/DataNode.java index e86ae15..87c469d 100644 --- a/src/zutil/parser/DataNode.java +++ b/src/zutil/parser/DataNode.java @@ -182,7 +182,19 @@ public class DataNode implements Iterable { } /** - * Adds a node to the Map + * Creates a new node and adds it to the list. + * + * @param type the type of the new DataNode + * @return a newly created DataNode + */ + public DataNode add(DataType type) { + DataNode newNode = new DataNode(type); + list.add(newNode); + return newNode; + } + + /** + * Adds a node to the Map with the provided value */ public void set(String key, DataNode node) { map.put(key, node); @@ -208,6 +220,20 @@ public class DataNode implements Iterable { map.put(key, new DataNode(value)); } + /** + * Creates a new node and adds it to the specified key. + * + * @param key the key where the new DataNode should be assigned + * @param type the type of the new DataNode + * @return a newly created DataNode + */ + public DataNode set(String key, DataType type) { + DataNode newNode = new DataNode(type); + map.put(key, newNode); + return newNode; + } + + /** * Sets the value of the node * diff --git a/test/zutil/net/ws/openapi/OpenAPIWriterTest.java b/test/zutil/net/ws/openapi/OpenAPIWriterTest.java new file mode 100644 index 0000000..8efff8e --- /dev/null +++ b/test/zutil/net/ws/openapi/OpenAPIWriterTest.java @@ -0,0 +1,42 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.net.ws.openapi; + +import org.junit.Test; +import zutil.net.ws.WebServiceDef; +import zutil.net.ws.soap.SOAPTest; + +import static org.junit.Assert.assertEquals; + +public class OpenAPIWriterTest { + + @Test + public void basicTest() { + OpenAPIWriter writer = new OpenAPIWriter(new WebServiceDef(SOAPTest.MainSOAPClass.class)); + writer.addServer("example.com", "Main Server"); + + assertEquals("", writer.write()); + } +} \ No newline at end of file diff --git a/test/zutil/net/ws/soap/SOAPTest.java b/test/zutil/net/ws/soap/SOAPTest.java index 089eb45..421c35b 100755 --- a/test/zutil/net/ws/soap/SOAPTest.java +++ b/test/zutil/net/ws/soap/SOAPTest.java @@ -29,6 +29,7 @@ import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import zutil.net.ws.WSInterface; import zutil.net.ws.WSInterface.WSNamespace; +import zutil.net.ws.WSInterface.WSParamName; import zutil.net.ws.WSReturnObject; import zutil.net.ws.WebServiceDef; import zutil.net.ws.wsdl.WSDLWriter; @@ -36,7 +37,11 @@ import zutil.net.ws.wsdl.WSDLWriter; // TODO: Convert to JUnit public class SOAPTest { - /************************* TEST CASES ************************/ + + // ---------------------------------------------------- + // TEST CASES + // ---------------------------------------------------- + public static void main(String[] args){ WebServiceDef wsDef = new WebServiceDef( MainSOAPClass.class ); SOAPHttpPage soap = new SOAPHttpPage( wsDef ); @@ -75,12 +80,15 @@ public class SOAPTest { } } - /************************* TEST CLASSES ************************/ + // ---------------------------------------------------- + // TEST CLASSES + // ---------------------------------------------------- + @SuppressWarnings("unused") public static class SpecialReturnClass extends WSReturnObject{ - @WSValueName(value="otherValue1") + @WSParamName("otherValue1") public String param1 = "otherValue1"; - @WSValueName("otherName2") + @WSParamName("otherName2") public String param2 = "otherValue2"; public byte[] b = new byte[]{0x12, 0x23}; public InnerClass inner = new InnerClass(); @@ -94,7 +102,7 @@ public class SOAPTest { @SuppressWarnings("unused") public static class SimpleReturnClass extends WSReturnObject{ - @WSValueName("otherParam1") + @WSParamName("otherParam1") public String param1 = "param1"; public String param2 = "param2"; } diff --git a/test/zutil/net/ws/wsdl/WSDLWriterTest.java b/test/zutil/net/ws/wsdl/WSDLWriterTest.java new file mode 100644 index 0000000..1078378 --- /dev/null +++ b/test/zutil/net/ws/wsdl/WSDLWriterTest.java @@ -0,0 +1,175 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.net.ws.wsdl; + +import org.junit.Test; +import zutil.net.ws.WebServiceDef; +import zutil.net.ws.soap.SOAPTest; + +import static org.junit.Assert.assertEquals; + +public class WSDLWriterTest { + + @Test + public void basicTest() { + WSDLWriter writer = new WSDLWriter(new WebServiceDef(SOAPTest.MainSOAPClass.class)); + writer.addService(new WSDLServiceSOAP("example.com")); + + assertEquals("\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Documentation of method exceptionMethod()\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n", + writer.write()); + } +} \ No newline at end of file