Improved the Web service classes, needs to be tested

RESOLVED - #92 
http://bugs.koc.se/view.php?id=92
This commit is contained in:
Ziver Koc 2011-09-14 20:30:06 +00:00
parent 09b671bda7
commit a2b6be1f35
13 changed files with 401 additions and 817 deletions

View file

@ -121,12 +121,12 @@ public interface WSInterface {
public @interface WSHeader { }
/**
* Specifies the name space for the method.
* Specifies the name space for method.
*
* @author Ziver
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//@Target(ElementType.TYPE)
public @interface WSNamespace {
String value();
}

View file

@ -23,14 +23,23 @@ package zutil.net.ws;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import zutil.net.ws.WSInterface.WSDocumentation;
import zutil.net.ws.WSInterface.WSNamespace;
/**
* This is a web service method definition class
*
* @author Ziver
*/
// TODO: Header parameters
public class WSMethodDef {
/** The parent web service definition **/
private WebServiceDef wsDef;
/** A list of input parameters **/
private ArrayList<WSParameterDef> inputs;
/** A List of return parameters of the method **/
@ -41,6 +50,8 @@ public class WSMethodDef {
private Method method;
/** Documentation of the method **/
private String doc;
/** This is the namespace of the method **/
private String namespace;
/** The published name of the method **/
private String name;
@ -49,63 +60,78 @@ public class WSMethodDef {
*
* @param me is a method in a class that implements WSInterface
*/
public WSMethodDef(Method me) {
if(!WSInterface.class.isAssignableFrom(me.getDeclaringClass()) )
protected WSMethodDef( WebServiceDef wsDef, Method me) {
if( !WSInterface.class.isAssignableFrom(me.getDeclaringClass()) )
throw new ClassCastException("Declaring class does not implement WSInterface!");
this.wsDef = wsDef;
method = me;
inputs = new ArrayList<WSParameterDef>();
outputs = new ArrayList<WSParameterDef>();
exceptions = new ArrayList<Class<?>>();
name = method.getName();
//***** Documentation
WSDocumentation tmpDoc = method.getAnnotation(WSInterface.WSDocumentation.class);
//***** Documentation & Namespace
WSDocumentation tmpDoc = method.getAnnotation( WSDocumentation.class );
if(tmpDoc != null){
doc = tmpDoc.value();
}
WSNamespace tmpSpace = method.getAnnotation( WSNamespace.class );
if( tmpSpace != null )
namespace = tmpSpace.value();
else
namespace = wsDef.getNamespace()+"?#"+name;
//***** Exceptions
for( Class<?> exc : method.getExceptionTypes() ){
exceptions.add( exc );
}
//********* Get the input parameter names **********
Annotation[][] paramAnnotation = method.getParameterAnnotations();
Class<?>[] inputTypes = method.getParameterTypes();
for(int i=0; i<paramAnnotation.length ;i++){
WSParameterDef param = new WSParameterDef();
WSParameterDef param = new WSParameterDef( this );
for(Annotation annotation : paramAnnotation[i]){
if(annotation instanceof WSInterface.WSParamName){
WSInterface.WSParamName paramName = (WSInterface.WSParamName) annotation;
param.name = paramName.value();
param.optional = paramName.optional();
param.setName( paramName.value() );
param.setOptional( paramName.optional() );
}
}
param.setParamClass( inputTypes[i] );
// if no name was found then use default
if(param.name == null)
param.name = "args"+i;
if(param.getName() == null)
param.setName( "args"+i );
inputs.add( param );
}
//******** The return parameter name ************
WSInterface.WSReturnName returnName = method.getAnnotation(WSInterface.WSReturnName.class);
if( WSReturnValueList.class.isAssignableFrom( method.getReturnType() ) ){
if( WSReturnObject.class.isAssignableFrom( method.getReturnType() ) ){
Class<?> retClass = method.getReturnType();
Field[] fields = retClass.getFields();
for(int i=0; i<fields.length ;i++){
WSParameterDef ret_param = new WSParameterDef();
WSReturnValueList.WSValueName retValName = fields[i]
.getAnnotation( WSReturnValueList.WSValueName.class );
if(retValName != null) ret_param.name = retValName.value();
else ret_param.name = fields[i].getName();
ret_param.paramClass = fields[i].getType();
WSParameterDef ret_param = new WSParameterDef( this );
WSReturnObject.WSValueName retValName = fields[i]
.getAnnotation( WSReturnObject.WSValueName.class );
if(retValName != null)
ret_param.setName( retValName.value() );
else
ret_param.setName( fields[i].getName() );
ret_param.setParamClass( fields[i].getType() );
outputs.add( ret_param );
}
}
else{
WSParameterDef ret_param = new WSParameterDef();
if(returnName != null) ret_param.name = returnName.value();
else ret_param.name = "return";
ret_param.paramClass = method.getReturnType();
WSParameterDef ret_param = new WSParameterDef( this );
if(returnName != null)
ret_param.setName(returnName.value());
else
ret_param.setName("return");
ret_param.setParamClass( method.getReturnType() );
outputs.add( ret_param );
}
}
@ -134,7 +160,7 @@ public class WSMethodDef {
/**
* @return the number of parameters for this method
*/
public int inputCount(){
public int getInputCount(){
return inputs.size();
}
@ -145,10 +171,18 @@ public class WSMethodDef {
return inputs;
}
/**
* @param index is a index
* @return a {@link WSParameterDef} object in the given index
*/
public WSParameterDef getInput( int index ){
return inputs.get( index );
}
/**
* @return the number of parameters for this method
*/
public int outputCount(){
public int getOutputCount(){
return outputs.size();
}
@ -159,6 +193,14 @@ public class WSMethodDef {
return outputs;
}
/**
* @param index is a index
* @return a {@link WSParameterDef} object in the given index
*/
public WSParameterDef getOutput( int index ){
return outputs.get( index );
}
/**
* @return Documentation of the method if one exists or else null
*/
@ -166,6 +208,35 @@ public class WSMethodDef {
return doc;
}
/**
* @return the namespace of the method
*/
public String getNamespace(){
return namespace;
}
public WebServiceDef getWebService(){
return wsDef;
}
/**
* Invokes a specified method
*
* @param obj the object the method will called on
* @param params a vector with arguments
*/
public Object invoke(Object obj, Object[] params) throws Throwable{
try {
return this.method.invoke(obj, params );
} catch (IllegalArgumentException e) {
throw e;
} catch (IllegalAccessException e) {
throw e;
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
public String toString(){
StringBuilder tmp = new StringBuilder();
@ -176,9 +247,9 @@ public class WSMethodDef {
first = false;
else
tmp.append(" ,");
tmp.append(param.paramClass.getSimpleName());
tmp.append(param.getParamClass().getSimpleName());
tmp.append(" ");
tmp.append(param.name);
tmp.append(param.getName());
}
tmp.append(") => ");
first = true;
@ -187,9 +258,9 @@ public class WSMethodDef {
first = false;
else
tmp.append(" ,");
tmp.append(param.paramClass.getSimpleName());
tmp.append(param.getParamClass().getSimpleName());
tmp.append(" ");
tmp.append(param.name);
tmp.append(param.getName());
}
return tmp.toString();
}

View file

@ -1,77 +0,0 @@
/*******************************************************************************
* Copyright (c) 2011 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;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This class is used as an return Object for a web service.
* If an class implements this interface then it can return
* multiple values through the SOAPInterface. Example:
* <pre>
* private static class TestObject implements WSObject{
* @SOAPFieldName("name")
* public String name;
* @SOAPFieldName("lastname")
* public String lastname;
*
* public TestObject(String n, String l){
* name = n;
* lastname = l;
* }
* }
* </pre>
*
* @author Ziver
*
*/
public interface WSObject{
/**
* Specifies the name of a field.
* The fields that are available in the service should
* be declared public.
*
* @author Ziver
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface WSFieldName {
String value();
boolean optional() default false;
}
/**
* This generates an documentation tag in the
* WSDL for the object type
*
* @author Ziver
*/
/*
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WSDLDocumentation {
String value();
}*/
}

View file

@ -21,18 +21,30 @@
******************************************************************************/
package zutil.net.ws;
/**
* This is a web service parameter definition class
*
* @author Ziver
*/
public class WSParameterDef{
/** The parent method **/
private WSMethodDef mDef;
/** The class type of the parameter **/
protected Class<?> paramClass;
private Class<?> paramClass;
/** The web service name of the parameter **/
protected String name;
private String name;
/** Developer documentation **/
protected String doc;
private String doc;
/** If this parameter is optional **/
protected boolean optional;
private boolean optional;
/** Is it an header parameter **/
//boolean header;
protected WSParameterDef( WSMethodDef mDef ){
this.mDef = mDef;
this.optional = false;
}
public Class<?> getParamClass() {
return paramClass;
@ -61,4 +73,8 @@ public class WSParameterDef{
protected void setOptional(boolean optional) {
this.optional = optional;
}
public WSMethodDef getMethod(){
return mDef;
}
}

View file

@ -28,16 +28,29 @@ import java.lang.annotation.Target;
import java.lang.reflect.Field;
/**
* This interface is for returning multiple object.
* All the public fields in the class that implements
* this class will be set as return values. And the
* implementing class will be transparent.
* This class is used as an return Object for a web service.
* If an class implements this interface then it can return
* multiple values through the WSInterface. And the
* implementing class will be transparent. Example:
*
* <pre>
* private static class TestObject implements WSReturnObject{
* @WSValueName("name")
* public String name;
* @WSValueName("lastname")
* public String lastname;
*
* public TestObject(String n, String l){
* name = n;
* lastname = l;
* }
* }
* </pre>
*
* @author Ziver
*
*/
public class WSReturnValueList {
public class WSReturnObject{
/**
* Method comments for the WSDL.
* These comments are put in the operation part of the WSDL
@ -49,15 +62,6 @@ public class WSReturnValueList {
String value();
}
/**
* Disables publication of the given field.
*
* @author Ziver
*/
/*@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SOAPDisabledValue { }*/
/**
* Annotation that assigns a name to the return value
* to the field.
@ -68,6 +72,7 @@ public class WSReturnValueList {
@Target(ElementType.FIELD)
public @interface WSValueName {
String value();
boolean optional() default false;
}
@ -75,4 +80,3 @@ public class WSReturnValueList {
return field.get(this);
}
}

View file

@ -27,31 +27,35 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import javax.wsdl.WSDLException;
/**
* Defines a web service from a class implementing the {@link zutil.net.ws.WSInterface}
*
* @author Ziver
*/
public class WebServiceDef {
/** A map of methods in this Service **/
private HashMap<String,WSMethodDef> methods;
/** URL of the Service **/
//private String url;
/** Namespace of the service **/
//private String namespace;
private String namespace;
/** Name of the web service **/
private String name;
/** This is the WSInterface class **/
private Class<? extends WSInterface> intf;
public WebServiceDef(Class<? extends WSInterface> intf) throws WSDLException{
public WebServiceDef(Class<? extends WSInterface> intf){
this.intf = intf;
methods = new HashMap<String,WSMethodDef>();
name = intf.getSimpleName();
if( intf.getAnnotation( WSInterface.WSNamespace.class ) != null )
this.namespace = intf.getAnnotation( WSInterface.WSNamespace.class ).value();
for(Method m : intf.getDeclaredMethods()){
// check for public methods
if((m.getModifiers() & Modifier.PUBLIC) > 0 &&
!m.isAnnotationPresent(WSInterface.WSDisabled.class)){
WSMethodDef method = new WSMethodDef(m);
WSMethodDef method = new WSMethodDef(this, m);
methods.put(method.getName(), method);
}
}
@ -71,6 +75,22 @@ public class WebServiceDef {
return 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
*/
public WSMethodDef getMethod( String name ){
return methods.get( name );
}
/**
* @return a Set of all the method names
*/
@ -84,4 +104,15 @@ public class WebServiceDef {
public Collection<WSMethodDef> getMethods(){
return methods.values();
}
/**
* @return the namespace of this web service ( usually the URL of the service )
*/
public String getNamespace(){
return namespace;
}
public WSInterface newInstance() throws InstantiationException, IllegalAccessException {
return intf.newInstance();
}
}