Merged WSNamespace into WSPath

This commit is contained in:
Ziver Koc 2021-03-02 21:01:55 +01:00
parent bb8d6a93b4
commit fd7f197a17
10 changed files with 77 additions and 103 deletions

View file

@ -128,14 +128,6 @@ public interface WSInterface {
@Target(ElementType.METHOD)
@interface WSHeader {}
/**
* Specifies the name space for the method.
*/
@Retention(RetentionPolicy.RUNTIME)
@interface WSNamespace {
String value();
}
/**
* Specifies the request type.
*/
@ -146,10 +138,10 @@ public interface WSInterface {
}
/**
* Sets a specific URL path for the method overriding the auto generated path.
* Sets a specific URL path for the method overriding the auto generated path. This will also be used as the namespace.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Target({ElementType.TYPE, ElementType.METHOD})
@interface WSPath {
String value();
}

View file

@ -25,7 +25,6 @@
package zutil.net.ws;
import zutil.net.ws.WSInterface.WSDocumentation;
import zutil.net.ws.WSInterface.WSNamespace;
import zutil.net.ws.WSInterface.WSPath;
import zutil.net.ws.WSInterface.WSRequestType;
@ -50,11 +49,11 @@ public class WSMethodDef {
/**
* A list of input parameters
**/
private ArrayList<WSParameterDef> inputs;
private ArrayList<WSParameterDef> inputs = new ArrayList<>();
/**
* A List of return parameters of the method
**/
private ArrayList<WSParameterDef> outputs;
private ArrayList<WSParameterDef> outputs = new ArrayList<>();
/**
* The object type of output object
**/
@ -62,7 +61,7 @@ public class WSMethodDef {
/**
* A List of exceptions that this method throws
**/
private ArrayList<Class<?>> exceptions;
private ArrayList<Class<?>> exceptions = new ArrayList<>();
/**
* The real method that this class represent, can be null if its a remote method
**/
@ -72,9 +71,9 @@ public class WSMethodDef {
**/
private String doc;
/**
* The namespace of the method
* The URL path of the method
**/
private String namespace;
private String path;
/**
* The type of request required to execute the method
**/
@ -83,38 +82,34 @@ public class WSMethodDef {
* The published name of the method
**/
private String name;
/**
* The endpoint location
**/
private String path;
/**
* @param wsDef is the parent web service defining interface
* @param me is a method in a class that implements WSInterface
* @param wsDef is the parent web service defining interface
* @param method is a method in a class that implements WSInterface
*/
protected WSMethodDef(WebServiceDef wsDef, Method me) {
if (!WSInterface.class.isAssignableFrom(me.getDeclaringClass()))
protected WSMethodDef(WebServiceDef wsDef, Method method) {
if (!WSInterface.class.isAssignableFrom(method.getDeclaringClass()))
throw new ClassCastException("Declaring class does not implement WSInterface!");
this.wsDef = wsDef;
this.method = me;
this.inputs = new ArrayList<>();
this.outputs = new ArrayList<>();
this.exceptions = new ArrayList<>();
this.method = method;
this.name = method.getName();
// Handle documentation and namespace
WSDocumentation docAnnotation = method.getAnnotation(WSDocumentation.class);
WSDocumentation docAnnotation = this.method.getAnnotation(WSDocumentation.class);
if (docAnnotation != null)
doc = docAnnotation.value();
WSNamespace namespaceAnnotation = method.getAnnotation(WSNamespace.class);
WSPath namespaceAnnotation = this.method.getAnnotation(WSPath.class);
if (namespaceAnnotation != null)
namespace = namespaceAnnotation.value();
path = namespaceAnnotation.value();
else
namespace = wsDef.getNamespace() + "?#" + name;
path = name;
if (path.startsWith("/"))
path = path.substring(1);
// ------------------------------------------------
// Handle inputs
@ -137,7 +132,7 @@ public class WSMethodDef {
// Handle outputs
// ------------------------------------------------
this.outputClass = method.getReturnType();
this.outputClass = this.method.getReturnType();
if (WSReturnObject.class.isAssignableFrom(outputClass)) {
Field[] fields = outputClass.getFields();
@ -150,8 +145,8 @@ public class WSMethodDef {
outputs.add(ret_param);
}
} else if (outputClass != void.class) {
WSInterface.WSReturnName returnNameAnnotation = method.getAnnotation(WSInterface.WSReturnName.class);
WSParameterDef ret_param = new WSParameterDef(this, method.getReturnType(), new Annotation[]{returnNameAnnotation});
WSInterface.WSReturnName returnNameAnnotation = this.method.getAnnotation(WSInterface.WSReturnName.class);
WSParameterDef ret_param = new WSParameterDef(this, this.method.getReturnType(), new Annotation[]{returnNameAnnotation});
if (ret_param.getName() == null)
ret_param.setName("return");
@ -163,13 +158,13 @@ public class WSMethodDef {
// Handle Exceptions
// ------------------------------------------------
Collections.addAll(exceptions, method.getExceptionTypes());
Collections.addAll(exceptions, this.method.getExceptionTypes());
// ------------------------------------------------
// Handle the request type
// ------------------------------------------------
WSRequestType requestTypeAnnotation = method.getAnnotation(WSRequestType.class);
WSRequestType requestTypeAnnotation = this.method.getAnnotation(WSRequestType.class);
if (requestTypeAnnotation != null) {
this.requestType = requestTypeAnnotation.value();
} else {
@ -186,19 +181,6 @@ public class WSMethodDef {
else
this.requestType = WSInterface.RequestType.GET;
}
// ------------------------------------------------
// Handle endpoint path
// ------------------------------------------------
WSPath pathAnnotation = method.getAnnotation(WSPath.class);
if (pathAnnotation != null)
path = pathAnnotation.value();
else
path = this.name;
if (!path.startsWith("/"))
path = '/' + path;
}
/**
@ -212,7 +194,7 @@ public class WSMethodDef {
* @return the path to the WS method endpoint
*/
public String getPath() {
return path;
return wsDef.getPath() + "/" + path;
}
/**
@ -257,19 +239,12 @@ public class WSMethodDef {
return requestType;
}
/**
* @return the namespace or endpoint url of the method
*/
public String getNamespace() {
return namespace;
}
/**
* Invokes a specified method
*
* @param params a vector with arguments
* @param obj the object the method will called on
* @param params a vector with arguments
* @param obj the object the method will called on
*/
public Object invoke(Object obj, Object[] params) throws Exception {
return this.method.invoke(obj, params);

View file

@ -38,24 +38,27 @@ import java.util.Set;
public class WebServiceDef {
/** This is the WSInterface class **/
private Class<? extends WSInterface> intf;
/** Namespace of the service **/
private String namespace;
/** Name of the web service **/
private String name;
/** Path or namespace of the service **/
private String path = "";
/** Human readable description of the service **/
private String documentation = "";
/** A map of methods in this Service **/
private HashMap<String,WSMethodDef> methods = new HashMap<>();
public WebServiceDef(Class<? extends WSInterface> intf){
this.intf = intf;
name = intf.getSimpleName();
WSInterface.WSNamespace namespaceAnnotation = intf.getAnnotation(WSInterface.WSNamespace.class);
if (namespaceAnnotation != null)
this.namespace = namespaceAnnotation.value();
WSInterface.WSPath pathAnnotation = intf.getAnnotation(WSInterface.WSPath.class);
if (pathAnnotation != null) {
this.path = pathAnnotation.value();
if (path.endsWith("/")) // remove last backslash
path = path.substring(0, path.length()-1);
}
WSInterface.WSDocumentation documentationAnnotation = intf.getAnnotation(WSInterface.WSDocumentation.class);
if (documentationAnnotation != null)
@ -63,14 +66,14 @@ public class WebServiceDef {
for(Method m : intf.getDeclaredMethods()){
// Check for public methods
if ((m.getModifiers() & Modifier.PUBLIC) > 0 &&
!m.isAnnotationPresent(WSInterface.WSIgnore.class)){
if ((m.getModifiers() & Modifier.PUBLIC) > 0 && !m.isAnnotationPresent(WSInterface.WSIgnore.class)){
WSMethodDef method = new WSMethodDef(this, m);
methods.put(method.getName(), method);
}
}
}
/**
* @return the class that defines this web service
*/
@ -93,16 +96,16 @@ public class WebServiceDef {
}
/**
* @param name is the name of the method
* @return if there is a method by the given name
* @param name is the name of the method
* @return if there is a method by the given name
*/
public boolean hasMethod( String name ){
return methods.containsKey( name );
}
/**
* @param name is the name of the method
* @return the method or null if there is no such method
* @param name is the name of the method
* @return the method or null if there is no such method
*/
public WSMethodDef getMethod( String name ){
return methods.get( name );
@ -125,8 +128,8 @@ public class WebServiceDef {
/**
* @return the namespace of this web service ( usually the URL of the service )
*/
public String getNamespace(){
return namespace;
public String getPath(){
return path;
}
public WSInterface newInstance() throws InstantiationException, IllegalAccessException {

View file

@ -107,7 +107,7 @@ public class SOAPClientInvocationHandler implements InvocationHandler {
Element body = envelope.addElement("soap:Body");
Element method = body.addElement("");
method.addNamespace("m", methodDef.getNamespace());
method.addNamespace("m", methodDef.getPath());
method.setName("m:" + methodDef.getName() + "Request");
List<WSParameterDef> outputParamDefs = methodDef.getOutputs();

View file

@ -291,7 +291,7 @@ public class SOAPHttpPage implements HttpPage{
// generate response XML
if (outputParamDefs.size() > 0) {
Element response = responseRoot.addElement("");
response.addNamespace("m", methodDef.getNamespace() );
response.addNamespace("m", methodDef.getPath() );
response.setName("m:" + methodDef.getName() + "Response");
if (outputParams instanceof WSReturnObject) {

View file

@ -56,7 +56,7 @@ public class WSDLServiceSOAP extends WSDLService{
// definitions -> binding -> operation -> soap:operation
Element soap_operation = operation.addElement("soap:operation");
soap_operation.addAttribute("soapAction", method.getNamespace());
soap_operation.addAttribute("soapAction", method.getPath());
// ------------------------------------------------
// Input
@ -67,7 +67,7 @@ public class WSDLServiceSOAP extends WSDLService{
// definitions -> binding -> operation -> input -> body
Element input_body = input.addElement("soap:body");
input_body.addAttribute("use", "literal");
input_body.addAttribute("namespace", method.getNamespace());
input_body.addAttribute("namespace", method.getPath());
// ------------------------------------------------
// Output
@ -79,7 +79,7 @@ public class WSDLServiceSOAP extends WSDLService{
// definitions -> binding -> operation -> input -> body
Element output_body = output.addElement("soap:body");
output_body.addAttribute("use", "literal");
output_body.addAttribute("namespace", method.getNamespace());
output_body.addAttribute("namespace", method.getPath());
}
}
}

View file

@ -107,8 +107,8 @@ public class WSDLWriter {
definitions.addNamespace("http", "http://schemas.xmlsoap.org/wsdl/http/");
definitions.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
definitions.addNamespace("soap-enc", "http://schemas.xmlsoap.org/soap/encoding/");
definitions.addNamespace("tns", ws.getNamespace() + "?type");
definitions.addAttribute("targetNamespace", ws.getNamespace());
definitions.addNamespace("tns", ws.getPath() + "/type");
definitions.addAttribute("targetNamespace", ws.getPath());
generateType(definitions);
generateMessages(definitions);
@ -306,7 +306,7 @@ public class WSDLWriter {
// definitions -> types
Element typeE = definitions.addElement("wsdl:types");
Element schema = typeE.addElement("xsd:schema");
schema.addAttribute("targetNamespace", ws.getNamespace() + "?type");
schema.addAttribute("targetNamespace", ws.getPath() + "/type");
// empty type
Element empty = schema.addElement("xsd:complexType");
@ -316,7 +316,10 @@ public class WSDLWriter {
for (int i=0; i<types.size(); i++) {
Class<?> c = types.get(i);
// --------------------------------------------
// Generate Array type
// --------------------------------------------
if (c.isArray()) {
Class<?> ctmp = ClassUtil.getArrayClass(c);
@ -338,7 +341,11 @@ public class WSDLWriter {
if (!types.contains(ctmp))
types.add(ctmp);
}
// --------------------------------------------
// Generate SOAPObject type
// --------------------------------------------
else if (WSReturnObject.class.isAssignableFrom(c)) {
Element type = schema.addElement("xsd:complexType");
type.addAttribute("name", SOAPHttpPage.getSOAPClassName(c));

View file

@ -24,13 +24,10 @@
package zutil.net.ws.rest;
import org.junit.Test;
import zutil.net.ws.WSInterface;
import zutil.net.ws.WebServiceDef;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@ -42,7 +39,7 @@ public class RESTClientTest {
public interface OpenWeartherMap extends WSInterface {
@WSNamespace("")
@WSPath("")
int weather(@WSParamName("q") String city);
}

View file

@ -28,7 +28,7 @@ import org.dom4j.Document;
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.WSPath;
import zutil.net.ws.WSInterface.WSParamName;
import zutil.net.ws.WSReturnObject;
import zutil.net.ws.WebServiceDef;
@ -85,7 +85,7 @@ public class SOAPTest {
// ----------------------------------------------------
@SuppressWarnings("unused")
@WSNamespace("http://test.se:8080/")
@WSPath("http://test.se:8080/")
public static class MainSOAPClass implements WSInterface{
public MainSOAPClass(){}

View file

@ -39,9 +39,9 @@ public class WSDLWriterTest {
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"\n" +
"<wsdl:definitions xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap-enc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tns=\"http://test.se:8080/?type\" targetNamespace=\"http://test.se:8080/\">\n" +
"<wsdl:definitions xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap-enc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tns=\"http://test.se:8080/type\" targetNamespace=\"http://test.se:8080\">\n" +
" <wsdl:types>\n" +
" <xsd:schema targetNamespace=\"http://test.se:8080/?type\">\n" +
" <xsd:schema targetNamespace=\"http://test.se:8080/type\">\n" +
" <xsd:complexType name=\"empty\">\n" +
" <xsd:sequence/>\n" +
" </xsd:complexType>\n" +
@ -125,42 +125,42 @@ public class WSDLWriterTest {
" <wsdl:binding name=\"MainSOAPClassBinding\" type=\"tns:MainSOAPClassPortType\">\n" +
" <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n" +
" <wsdl:operation name=\"stringArrayMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#stringArrayMethod\"/>\n" +
" <soap:operation soapAction=\"http://test.se:8080/stringArrayMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#stringArrayMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/stringArrayMethod\"/>\n" +
" </wsdl:input>\n" +
" <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#stringArrayMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/stringArrayMethod\"/>\n" +
" </wsdl:output>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"simpleReturnClassMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" +
" <soap:operation soapAction=\"http://test.se:8080/simpleReturnClassMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/simpleReturnClassMethod\"/>\n" +
" </wsdl:input>\n" +
" <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/simpleReturnClassMethod\"/>\n" +
" </wsdl:output>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"exceptionMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#exceptionMethod\"/>\n" +
" <soap:operation soapAction=\"http://test.se:8080/exceptionMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#exceptionMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/exceptionMethod\"/>\n" +
" </wsdl:input>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"specialReturnMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#specialReturnMethod\"/>\n" +
" <soap:operation soapAction=\"http://test.se:8080/specialReturnMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#specialReturnMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/specialReturnMethod\"/>\n" +
" </wsdl:input>\n" +
" <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#specialReturnMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/specialReturnMethod\"/>\n" +
" </wsdl:output>\n" +
" </wsdl:operation>\n" +
" <wsdl:operation name=\"voidMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#voidMethod\"/>\n" +
" <soap:operation soapAction=\"http://test.se:8080/voidMethod\"/>\n" +
" <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#voidMethod\"/>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/voidMethod\"/>\n" +
" </wsdl:input>\n" +
" </wsdl:operation>\n" +
" </wsdl:binding>\n" +