zutil/src/zutil/net/ws/WSMethodDef.java

300 lines
9.4 KiB
Java
Raw Normal View History

2015-05-27 13:13:19 +00:00
/*
* The MIT License (MIT)
*
2020-11-22 22:42:02 +01:00
* Copyright (c) 2020 Ziver Koc
2013-05-28 19:29:24 +00:00
*
2011-07-13 17:53:17 +00:00
* 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:
2013-05-28 19:29:24 +00:00
*
2011-07-13 17:53:17 +00:00
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
2013-05-28 19:29:24 +00:00
*
2011-07-13 17:53:17 +00:00
* 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.
2015-05-27 13:13:19 +00:00
*/
2013-05-28 19:29:24 +00:00
2011-02-15 19:37:35 +00:00
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;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
2018-05-27 01:23:21 +02:00
import java.util.Collections;
import java.util.List;
/**
* This is a web service method definition class
2018-05-26 23:04:40 +02:00
*
* @author Ziver
*/
// TODO: Header parameters
public class WSMethodDef {
/**
* The parent web service definition
**/
2018-05-26 23:01:03 +02:00
private WebServiceDef wsDef;
/**
* A list of input parameters
**/
2018-05-26 23:01:03 +02:00
private ArrayList<WSParameterDef> inputs;
/**
* A List of return parameters of the method
**/
2018-05-26 23:01:03 +02:00
private ArrayList<WSParameterDef> outputs;
/**
* A List of exceptions that this method throws
**/
2018-05-26 23:01:03 +02:00
private ArrayList<Class<?>> exceptions;
/**
* The real method that this class represent, can be null if its a remote method
**/
2018-05-26 23:01:03 +02:00
private Method method;
/**
* Documentation of the method
**/
2018-05-26 23:01:03 +02:00
private String doc;
/**
* The namespace of the method
**/
2018-05-26 23:01:03 +02:00
private String namespace;
/**
* The type of request required to execute the method
**/
private WSInterface.RequestType requestType;
/**
* The published name of the method
**/
2018-05-26 23:01:03 +02:00
private String name;
/**
* The endpoint location
**/
private String path;
2018-05-26 23:01:03 +02:00
/**
* @param wsDef is the parent web service defining interface
* @param me is a method in a class that implements WSInterface
2018-05-26 23:01:03 +02:00
*/
protected WSMethodDef(WebServiceDef wsDef, Method me) {
2018-07-05 16:58:02 +02:00
if (!WSInterface.class.isAssignableFrom(me.getDeclaringClass()))
2018-05-26 23:01:03 +02:00
throw new ClassCastException("Declaring class does not implement WSInterface!");
2018-05-26 23:01:03 +02:00
this.wsDef = wsDef;
this.method = me;
this.inputs = new ArrayList<>();
this.outputs = new ArrayList<>();
this.exceptions = new ArrayList<>();
this.name = method.getName();
// Handle documentation and namespace
WSDocumentation docAnnotation = method.getAnnotation(WSDocumentation.class);
if (docAnnotation != null)
doc = docAnnotation.value();
WSNamespace namespaceAnnotation = method.getAnnotation(WSNamespace.class);
if (namespaceAnnotation != null)
namespace = namespaceAnnotation.value();
2018-05-26 23:01:03 +02:00
else
namespace = wsDef.getNamespace() + "?#" + name;
// Hnadle Exceptions
2018-05-27 01:23:21 +02:00
Collections.addAll(exceptions, method.getExceptionTypes());
2018-05-26 23:01:03 +02:00
// Handle input parameter names
2018-05-26 23:01:03 +02:00
Annotation[][] paramAnnotation = method.getParameterAnnotations();
Class<?>[] inputTypes = method.getParameterTypes();
for (int i = 0; i < paramAnnotation.length; i++) {
WSParameterDef param = new WSParameterDef(this);
for (Annotation annotation : paramAnnotation[i]) {
if (annotation instanceof WSInterface.WSParamName) {
2018-05-26 23:01:03 +02:00
WSInterface.WSParamName paramName = (WSInterface.WSParamName) annotation;
param.setName(paramName.value());
param.setOptional(paramName.optional());
2018-05-26 23:01:03 +02:00
}
}
param.setParamClass(inputTypes[i]);
2018-05-26 23:01:03 +02:00
// if no name was found then use default
2018-07-05 16:58:02 +02:00
if (param.getName() == null)
param.setName("args" + i);
2018-05-26 23:01:03 +02:00
inputs.add(param);
2018-05-26 23:01:03 +02:00
}
// Handle return parameter names
WSInterface.WSReturnName returnNameAnnotation = method.getAnnotation(WSInterface.WSReturnName.class);
if (WSReturnObject.class.isAssignableFrom(method.getReturnType())) {
2018-05-26 23:01:03 +02:00
Class<?> retClass = method.getReturnType();
Field[] fields = retClass.getFields();
for (Field field : fields) {
WSParameterDef ret_param = new WSParameterDef(this);
WSReturnObject.WSValueName retValName = field.getAnnotation(WSReturnObject.WSValueName.class);
if (retValName != null)
ret_param.setName(retValName.value());
2018-05-26 23:01:03 +02:00
else
ret_param.setName(field.getName());
ret_param.setParamClass(field.getType());
outputs.add(ret_param);
2018-05-26 23:01:03 +02:00
}
} else if (method.getReturnType() != void.class) {
WSParameterDef ret_param = new WSParameterDef(this);
if (returnNameAnnotation != null)
ret_param.setName(returnNameAnnotation.value());
2018-05-26 23:01:03 +02:00
else
ret_param.setName("return");
ret_param.setParamClass(method.getReturnType());
outputs.add(ret_param);
}
// Handle the request type
WSRequestType requestTypeAnnotation = method.getAnnotation(WSRequestType.class);
if (requestTypeAnnotation != null) {
this.requestType = requestTypeAnnotation.value();
} else {
// Specific request type was not provided, try to figure it out by the method name
if (name.startsWith("get"))
this.requestType = WSInterface.RequestType.HTTP_GET;
if (name.startsWith("post"))
this.requestType = WSInterface.RequestType.HTTP_POST;
if (name.startsWith("put"))
this.requestType = WSInterface.RequestType.HTTP_PUT;
if (name.startsWith("delete"))
this.requestType = WSInterface.RequestType.HTTP_DELETE;
2018-05-26 23:01:03 +02:00
}
// Handle endpoint path
WSPath pathAnnotation = method.getAnnotation(WSPath.class);
if (pathAnnotation != null)
path = pathAnnotation.value();
else
path = this.name;
if (path.startsWith("/"))
path = path.substring(1);
2018-05-26 23:01:03 +02:00
}
/**
* @return the published name of the method
*/
public String getName() {
2018-05-26 23:01:03 +02:00
return name;
}
/**
* @return the path to the WS method endpoint
*/
public String getPath() {
return path;
}
2018-05-26 23:01:03 +02:00
/**
* @return a list of exceptions this method throws
*/
public List<Class<?>> getExceptions() {
2018-05-26 23:01:03 +02:00
return exceptions;
}
/**
* @return a list of input parameters
*/
public List<WSParameterDef> getInputs() {
2018-05-26 23:01:03 +02:00
return inputs;
}
/**
* @return a list of input parameters
*/
public List<WSParameterDef> getOutputs() {
2018-05-26 23:01:03 +02:00
return outputs;
}
/**
* @return documentation of the method if one exists or else null
2018-05-26 23:01:03 +02:00
*/
public String getDocumentation() {
2018-05-26 23:01:03 +02:00
return doc;
}
/**
* @return the type of request needed to execute this method
*/
public WSInterface.RequestType getRequestType() {
return requestType;
}
2018-05-26 23:01:03 +02:00
/**
2018-07-05 16:58:02 +02:00
* @return the namespace or endpoint url of the method
2018-05-26 23:01:03 +02:00
*/
public String getNamespace() {
2018-05-26 23:01:03 +02:00
return namespace;
}
/**
* Invokes a specified method
*
* @param params a vector with arguments
* @param obj the object the method will called on
2018-05-26 23:01:03 +02:00
*/
public Object invoke(Object obj, Object[] params) throws Exception {
return this.method.invoke(obj, params);
2018-05-26 23:01:03 +02:00
}
public String toString() {
2018-05-26 23:01:03 +02:00
StringBuilder tmp = new StringBuilder();
boolean first = true;
2018-05-26 23:01:03 +02:00
tmp.append(name).append("(");
for (WSParameterDef param : inputs) {
2018-07-05 16:58:02 +02:00
if (first)
2018-05-26 23:01:03 +02:00
first = false;
else
tmp.append(" ,");
tmp.append(param.getParamClass().getSimpleName());
tmp.append(" ");
tmp.append(param.getName());
}
tmp.append(") => ");
2018-05-26 23:01:03 +02:00
first = true;
for (WSParameterDef param : outputs) {
2018-07-05 16:58:02 +02:00
if (first)
2018-05-26 23:01:03 +02:00
first = false;
else
tmp.append(" ,");
tmp.append(param.getParamClass().getSimpleName());
tmp.append(" ");
tmp.append(param.getName());
}
return tmp.toString();
}
}