Added specific webService class and changed from Multiprintstream to java.logger.Logger

This commit is contained in:
Ziver Koc 2010-08-13 22:36:08 +00:00
parent 3d4b05c697
commit 19b5b822a9
11 changed files with 464 additions and 279 deletions

View file

@ -0,0 +1,78 @@
package zutil.network.http.soap;
import javax.wsdl.WSDLException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
import zutil.network.ws.WSInterface;
import zutil.network.ws.WSMethodDef;
import zutil.network.ws.WebServiceDef;
/**
* This is an factory that generates clients for web services
*
* @author Ziver
*/
public class SOAPClientFactory {
/**
* Generates a Client Object for the web service.
*
* @param <T> is the class of the web service definition
* @param intf is the class of the web service definition
* @return a client Object
*/
@SuppressWarnings("unchecked")
public static <T> T getClient(Class<T> intf) throws InstantiationException, IllegalAccessException, CannotCompileException, NotFoundException, WSDLException{
if( !WSInterface.class.isAssignableFrom( intf )){
throw new ClassCastException("The Web Service class is not a subclass of WSInterface!");
}
return getClient( intf, new WebServiceDef((Class<? extends WSInterface>)intf) );
}
/**
* Generates a Client Object for the web service.
*
* @param <T> is the class of the web service definition
* @param intf is the class of the web service definition
* @param wsDef is the web service definition of the intf parameter
* @return a client Object
*/
@SuppressWarnings("unchecked")
public static <T> T getClient(Class<T> intf, WebServiceDef wsDef) throws InstantiationException, IllegalAccessException, CannotCompileException, NotFoundException{
if( !WSInterface.class.isAssignableFrom( intf )){
throw new ClassCastException("The Web Service class is not a subclass of WSInterface!");
}
// Generate the class
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(intf.getName()+"Impl_"+Math.random());
CtClass intfClass = pool.get( intf.getName() );
// Is intf an interface
if( intf.isInterface() ){
cc.addInterface( intfClass );
}
// or a class
else{
cc.setSuperclass( intfClass );
}
// Generate the methods
for(WSMethodDef methodDef : wsDef.getMethods()){
CtMethod method = CtNewMethod.make("public int m(int i){}", cc);
method.insertBefore("System.out.println(\"Hello.say():\");");
}
// Initiate the class
Class<T> c = cc.toClass();
T obj = c.newInstance();
return obj;
}
}

View file

@ -6,10 +6,10 @@ package zutil.network.http.soap;
* *
* @author Ziver * @author Ziver
*/ */
public class SOAPClientException extends Exception{ public class SOAPException extends Exception{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public SOAPClientException(String string) { public SOAPException(String string) {
super(string); super(string);
} }
} }

View file

@ -1,6 +1,5 @@
package zutil.network.http.soap; package zutil.network.http.soap;
import java.io.IOException;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -11,6 +10,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.wsdl.Binding; import javax.wsdl.Binding;
import javax.wsdl.BindingInput; import javax.wsdl.BindingInput;
@ -45,12 +46,17 @@ import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter; import org.dom4j.io.XMLWriter;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import zutil.MultiPrintStream; import zutil.converters.Converter;
import zutil.io.StringOutputStream;
import zutil.log.LogUtil;
import zutil.network.http.HttpPage; import zutil.network.http.HttpPage;
import zutil.network.http.HttpPrintStream; import zutil.network.http.HttpPrintStream;
import zutil.network.http.soap.SOAPInterface.WSDLDocumentation; import zutil.network.ws.WSInterface;
import zutil.network.http.soap.SOAPInterface.WSDLParamDocumentation; import zutil.network.ws.WSObject;
import zutil.network.http.soap.SOAPObject.SOAPFieldName; import zutil.network.ws.WSReturnValueList;
import zutil.network.ws.WSInterface.WSDocumentation;
import zutil.network.ws.WSInterface.WSParamDocumentation;
import zutil.network.ws.WSObject.WSFieldName;
import com.ibm.wsdl.extensions.PopulatedExtensionRegistry; import com.ibm.wsdl.extensions.PopulatedExtensionRegistry;
import com.ibm.wsdl.extensions.soap.SOAPConstants; import com.ibm.wsdl.extensions.soap.SOAPConstants;
@ -89,6 +95,8 @@ import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
* @author Ziver * @author Ziver
*/ */
public class SOAPHttpPage implements HttpPage{ public class SOAPHttpPage implements HttpPage{
public static final Logger logger = LogUtil.getLogger();
// valid methods for this soap page // valid methods for this soap page
private HashMap<String, MethodCache> methods; private HashMap<String, MethodCache> methods;
// contains an method and the names for the parameters // contains an method and the names for the parameters
@ -107,7 +115,7 @@ public class SOAPHttpPage implements HttpPage{
header = false; header = false;
Class<?> tmp = m.getReturnType(); Class<?> tmp = m.getReturnType();
if( SOAPReturnValueList.class.isAssignableFrom( tmp )){ if( WSReturnValueList.class.isAssignableFrom( tmp )){
returnName = new String[ tmp.getFields().length ]; returnName = new String[ tmp.getFields().length ];
returnClass = new Class<?>[ tmp.getFields().length ]; returnClass = new Class<?>[ tmp.getFields().length ];
} }
@ -122,7 +130,7 @@ public class SOAPHttpPage implements HttpPage{
} }
} }
// The object that the functions will be invoked from // The object that the functions will be invoked from
private SOAPInterface interf; private WSInterface interf;
// The WSDL document // The WSDL document
private Definition wsdl; private Definition wsdl;
// The WSDL Type part // The WSDL Type part
@ -132,7 +140,7 @@ public class SOAPHttpPage implements HttpPage{
// Session enabled // Session enabled
private boolean session_enabled; private boolean session_enabled;
public SOAPHttpPage(String url, SOAPInterface interf) throws WSDLException{ public SOAPHttpPage(String url, WSInterface interf) throws WSDLException{
//if(!SOAPInterface.class.isAssignableFrom(interf) ) //if(!SOAPInterface.class.isAssignableFrom(interf) )
// throw new ClassCastException("Class does not implement SOAPInterface!"); // throw new ClassCastException("Class does not implement SOAPInterface!");
this.url = url; this.url = url;
@ -143,7 +151,7 @@ public class SOAPHttpPage implements HttpPage{
for(Method m : interf.getClass().getDeclaredMethods()){ for(Method m : interf.getClass().getDeclaredMethods()){
// check for public methods // check for public methods
if((m.getModifiers() & Modifier.PUBLIC) > 0 && if((m.getModifiers() & Modifier.PUBLIC) > 0 &&
!m.isAnnotationPresent(SOAPInterface.SOAPDisabled.class)){ !m.isAnnotationPresent(WSInterface.WSDisabled.class)){
MethodCache chasch = new MethodCache(m); MethodCache chasch = new MethodCache(m);
StringBuffer tmp = new StringBuffer(m.getName()+"("); StringBuffer tmp = new StringBuffer(m.getName()+"(");
@ -152,8 +160,8 @@ public class SOAPHttpPage implements HttpPage{
for(int i=0; i<paramAnnotation.length ;i++){ for(int i=0; i<paramAnnotation.length ;i++){
for(Annotation annotation : paramAnnotation[i]){ for(Annotation annotation : paramAnnotation[i]){
if(annotation instanceof SOAPInterface.SOAPParamName){ if(annotation instanceof WSInterface.WSParamName){
SOAPInterface.SOAPParamName paramName = (SOAPInterface.SOAPParamName) annotation; WSInterface.WSParamName paramName = (WSInterface.WSParamName) annotation;
chasch.paramName[i] = paramName.value(); chasch.paramName[i] = paramName.value();
chasch.paramOptional[i] = paramName.optional(); chasch.paramOptional[i] = paramName.optional();
} }
@ -168,13 +176,13 @@ public class SOAPHttpPage implements HttpPage{
tmp.append(") => "); tmp.append(") => ");
// the return parameter name // the return parameter name
SOAPInterface.SOAPReturnName returnName = m.getAnnotation(SOAPInterface.SOAPReturnName.class); WSInterface.WSReturnName returnName = m.getAnnotation(WSInterface.WSReturnName.class);
if( SOAPReturnValueList.class.isAssignableFrom( m.getReturnType() ) ){ if( WSReturnValueList.class.isAssignableFrom( m.getReturnType() ) ){
Class<?> retClass = m.getReturnType(); Class<?> retClass = m.getReturnType();
for(int i=0; i<retClass.getFields().length ;i++){ for(int i=0; i<retClass.getFields().length ;i++){
if(i!=0) tmp.append(", "); if(i!=0) tmp.append(", ");
SOAPReturnValueList.SOAPValueName retValName = retClass.getFields()[i] WSReturnValueList.WSValueName retValName = retClass.getFields()[i]
.getAnnotation( SOAPReturnValueList.SOAPValueName.class ); .getAnnotation( WSReturnValueList.WSValueName.class );
if(retValName != null) chasch.returnName[i] = retValName.value(); if(retValName != null) chasch.returnName[i] = retValName.value();
else chasch.returnName[i] = retClass.getFields()[i].getName(); else chasch.returnName[i] = retClass.getFields()[i].getName();
chasch.returnClass[i] = retClass.getFields()[i].getType(); chasch.returnClass[i] = retClass.getFields()[i].getType();
@ -189,31 +197,34 @@ public class SOAPHttpPage implements HttpPage{
} }
// SOAP header? // SOAP header?
if(m.getAnnotation(SOAPInterface.SOAPHeader.class) != null) if(m.getAnnotation(WSInterface.WSHeader.class) != null)
chasch.header = true; chasch.header = true;
// save in HashMap // save in HashMap
MultiPrintStream.out.println("New SOAP Method Registered: "+tmp); logger.info("New SOAP Method Registered: "+tmp);
methods.put(m.getName(), chasch); methods.put(m.getName(), chasch);
} }
} }
generateWSDL(); generateWSDL();
try { if(logger.isLoggable(Level.INFO)){
// WSDL try {
MultiPrintStream.out.println(); // WSDL
WSDLFactory factory = WSDLFactory.newInstance(); StringOutputStream out = new StringOutputStream();
WSDLWriter writer = factory.newWSDLWriter(); WSDLFactory factory = WSDLFactory.newInstance();
writer.writeWSDL(wsdl, MultiPrintStream.out); WSDLWriter writer = factory.newWSDLWriter();
MultiPrintStream.out.println(); writer.writeWSDL(wsdl, out);
// WSDL Type logger.info(out.toString());
OutputFormat format = OutputFormat.createPrettyPrint(); // WSDL Type
XMLWriter xmlWriter = new XMLWriter( MultiPrintStream.out, format ); out.clear();
xmlWriter.write( wsdlType ); OutputFormat format = OutputFormat.createPrettyPrint();
MultiPrintStream.out.println(); XMLWriter xmlWriter = new XMLWriter( out, format );
} catch (Exception e) { xmlWriter.write( wsdlType );
e.printStackTrace(); logger.info(out.toString());
} catch (Exception e) {
e.printStackTrace();
}
} }
} }
@ -249,10 +260,10 @@ public class SOAPHttpPage implements HttpPage{
writer.write( wsdlType ); writer.write( wsdlType );
} }
else{ else{
SOAPInterface obj = null; WSInterface obj = null;
if(session_enabled){ if(session_enabled){
if( session.containsKey("SOAPInterface")) if( session.containsKey("SOAPInterface"))
obj = (SOAPInterface)session.get("SOAPInterface"); obj = (WSInterface)session.get("SOAPInterface");
else{ else{
obj = interf.getClass().newInstance(); obj = interf.getClass().newInstance();
session.put("SOAPInterface", obj); session.put("SOAPInterface", obj);
@ -279,7 +290,7 @@ public class SOAPHttpPage implements HttpPage{
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(MultiPrintStream.out); logger.log(Level.WARNING, "Unhandled request", e);
} }
} }
@ -290,18 +301,18 @@ public class SOAPHttpPage implements HttpPage{
*/ */
public Document genSOAPResponse(String xml){ public Document genSOAPResponse(String xml){
try { try {
SOAPInterface o = null; WSInterface o = null;
if(session_enabled) o = interf.getClass().newInstance(); if(session_enabled) o = interf.getClass().newInstance();
else o = interf; else o = interf;
return genSOAPResponse(xml, o ); return genSOAPResponse(xml, o );
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(MultiPrintStream.out); logger.log(Level.WARNING, "Exception in SOAP generation", e);
} }
return null; return null;
} }
protected Document genSOAPResponse(String xml, SOAPInterface obj){ protected Document genSOAPResponse(String xml, WSInterface obj){
Document document = DocumentHelper.createDocument(); Document document = DocumentHelper.createDocument();
Element envelope = document.addElement("soap:Envelope"); Element envelope = document.addElement("soap:Envelope");
try { try {
@ -327,7 +338,7 @@ public class SOAPHttpPage implements HttpPage{
body.clearContent(); body.clearContent();
Element fault = body.addElement("soap:Fault"); Element fault = body.addElement("soap:Fault");
// The fault source // The fault source
if(e instanceof SOAPClientException || e instanceof SAXException || e instanceof DocumentException) if(e instanceof SOAPException || e instanceof SAXException || e instanceof DocumentException)
fault.addElement("faultcode").setText( "soap:Client" ); fault.addElement("faultcode").setText( "soap:Client" );
else else
fault.addElement("faultcode").setText( "soap:Server" ); fault.addElement("faultcode").setText( "soap:Server" );
@ -336,10 +347,10 @@ public class SOAPHttpPage implements HttpPage{
fault.addElement("faultstring").setText( ""+e.getClass().getSimpleName() ); fault.addElement("faultstring").setText( ""+e.getClass().getSimpleName() );
else else
fault.addElement("faultstring").setText( ""+e.getMessage() ); fault.addElement("faultstring").setText( ""+e.getMessage() );
e.printStackTrace(MultiPrintStream.out); logger.log(Level.WARNING, "Caught exception from SOAP Class", e);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(MultiPrintStream.out); logger.log(Level.WARNING, "Exception in SOAP generation", e);
} }
return document; return document;
@ -368,7 +379,7 @@ public class SOAPHttpPage implements HttpPage{
* @param responseRoot is the root element of the response * @param responseRoot is the root element of the response
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void prepareInvoke(SOAPInterface obj, Element requestRoot, Element responseRoot) throws Throwable{ private void prepareInvoke(WSInterface obj, Element requestRoot, Element responseRoot) throws Throwable{
Iterator<Element> it = requestRoot.elementIterator(); Iterator<Element> it = requestRoot.elementIterator();
while( it.hasNext() ){ while( it.hasNext() ){
Element e = it.next(); Element e = it.next();
@ -379,7 +390,7 @@ public class SOAPHttpPage implements HttpPage{
// Get the parameter values // Get the parameter values
for(int i=0; i<m.paramName.length ;i++){ for(int i=0; i<m.paramName.length ;i++){
if(e.element(m.paramName[i]) != null) if(e.element(m.paramName[i]) != null)
params[i] = convertToClass( params[i] = Converter.fromString(
e.element(m.paramName[i]).getTextTrim(), e.element(m.paramName[i]).getTextTrim(),
m.method.getParameterTypes()[i]); m.method.getParameterTypes()[i]);
} }
@ -389,17 +400,17 @@ public class SOAPHttpPage implements HttpPage{
// generate response XML // generate response XML
if( m.returnClass.length>0 ){ if( m.returnClass.length>0 ){
SOAPInterface.SOAPNameSpace namespace = m.method.getAnnotation(SOAPInterface.SOAPNameSpace.class); WSInterface.WSNamespace namespace = m.method.getAnnotation(WSInterface.WSNamespace.class);
Element response = responseRoot.addElement(""); Element response = responseRoot.addElement("");
if( namespace != null ) if( namespace != null )
response.addNamespace("m", namespace.value()); response.addNamespace("m", namespace.value());
else else
response.addNamespace("m", url+""+m.method.getName()); response.addNamespace("m", url+""+m.method.getName());
response.setName("m:"+m.method.getName()+"Response"); response.setName("m:"+m.method.getName()+"Response");
if( ret instanceof SOAPReturnValueList ){ if( ret instanceof WSReturnValueList ){
Field[] f = ret.getClass().getFields(); Field[] f = ret.getClass().getFields();
for(int i=0; i<m.returnName.length ;i++ ){ for(int i=0; i<m.returnName.length ;i++ ){
generateReturnXML(response,((SOAPReturnValueList)ret).getValue(f[i]) , m.returnName[i], m); generateReturnXML(response,((WSReturnValueList)ret).getValue(f[i]) , m.returnName[i], m);
} }
} }
else{ else{
@ -412,31 +423,6 @@ public class SOAPHttpPage implements HttpPage{
} }
} }
} }
/**
* Converts an given String to a specified class
*/
protected Object convertToClass(String data, Class<?> c) throws IOException{
if(data == null || data.isEmpty())
return null;
if( c == String.class) return data;
else if(c == Integer.class) return Integer.parseInt(data);
else if(c == int.class) return Integer.parseInt(data);
else if(c == Long.class) return Long.parseLong(data);
else if(c == long.class) return Long.parseLong(data);
else if(c == Float.class) return Float.parseFloat(data);
else if(c == float.class) return Float.parseFloat(data);
else if(c == Double.class) return Double.parseDouble(data);
else if(c == double.class) return Double.parseDouble(data);
else if(c == Boolean.class) return Boolean.parseBoolean(data);
else if(c == boolean.class) return Boolean.parseBoolean(data);
else if(c == Byte.class) return Byte.parseByte(data);
else if(c == byte.class) return Byte.parseByte(data);
else if(byte[].class.isAssignableFrom(c))
return new sun.misc.BASE64Decoder().decodeBuffer(data);
return null;
}
/** /**
* Invokes a specified method * Invokes a specified method
@ -449,7 +435,7 @@ public class SOAPHttpPage implements HttpPage{
try { try {
return m.invoke(obj, params ); return m.invoke(obj, params );
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new SOAPClientException("Arguments missing for "+m.getName()+"!"); throw new SOAPException("Arguments missing for "+m.getName()+"!");
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw e; throw e;
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
@ -492,10 +478,10 @@ public class SOAPHttpPage implements HttpPage{
Element objectE = root.addElement( ename ); //getClassSOAPName(ret.getClass()) Element objectE = root.addElement( ename ); //getClassSOAPName(ret.getClass())
if(ret instanceof Element) if(ret instanceof Element)
objectE.add( (Element)ret ); objectE.add( (Element)ret );
else if(ret instanceof SOAPObject){ else if(ret instanceof WSObject){
Field[] fields = ret.getClass().getFields(); Field[] fields = ret.getClass().getFields();
for(int i=0; i<fields.length ;i++){ for(int i=0; i<fields.length ;i++){
SOAPFieldName tmp = fields[i].getAnnotation(SOAPObject.SOAPFieldName.class); WSFieldName tmp = fields[i].getAnnotation(WSObject.WSFieldName.class);
String name; String name;
if(tmp != null) name = tmp.value(); if(tmp != null) name = tmp.value();
else name = "field"+i; else name = "field"+i;
@ -515,7 +501,7 @@ public class SOAPHttpPage implements HttpPage{
if(byte[].class.isAssignableFrom(c)){ if(byte[].class.isAssignableFrom(c)){
return "base64Binary"; return "base64Binary";
} }
else if( SOAPObject.class.isAssignableFrom(cTmp) ){ else if( WSObject.class.isAssignableFrom(cTmp) ){
return c.getSimpleName(); return c.getSimpleName();
} }
else{ else{
@ -595,7 +581,7 @@ public class SOAPHttpPage implements HttpPage{
msgIn.setUndefined(false); msgIn.setUndefined(false);
//***** Documentation //***** Documentation
WSDLParamDocumentation tmpParamDoc = m.method.getAnnotation(SOAPInterface.WSDLParamDocumentation.class); WSParamDocumentation tmpParamDoc = m.method.getAnnotation(WSInterface.WSParamDocumentation.class);
if(tmpParamDoc != null){ if(tmpParamDoc != null){
org.w3c.dom.Document xmldoc= new DocumentImpl(); org.w3c.dom.Document xmldoc= new DocumentImpl();
org.w3c.dom.Element paramDoc = xmldoc.createElement("wsdl:documentation"); org.w3c.dom.Element paramDoc = xmldoc.createElement("wsdl:documentation");
@ -652,7 +638,7 @@ public class SOAPHttpPage implements HttpPage{
if(!types.contains( retClass )) if(!types.contains( retClass ))
types.add( retClass ); types.add( retClass );
} }
else if( SOAPObject.class.isAssignableFrom(cTmp) ){ else if( WSObject.class.isAssignableFrom(cTmp) ){
// its an SOAPObject // its an SOAPObject
part.setTypeName(new QName(td, getClassSOAPName( retClass ))); part.setTypeName(new QName(td, getClassSOAPName( retClass )));
// add to type generation list // add to type generation list
@ -680,7 +666,7 @@ public class SOAPHttpPage implements HttpPage{
operation.setUndefined(false); operation.setUndefined(false);
//***** Documentation //***** Documentation
WSDLDocumentation tmpDoc = m.method.getAnnotation(SOAPInterface.WSDLDocumentation.class); WSDocumentation tmpDoc = m.method.getAnnotation(WSInterface.WSDocumentation.class);
if(tmpDoc != null){ if(tmpDoc != null){
// <!-- example --> // <!-- example -->
org.w3c.dom.Document xmldoc= new DocumentImpl(); org.w3c.dom.Document xmldoc= new DocumentImpl();
@ -821,7 +807,7 @@ public class SOAPHttpPage implements HttpPage{
element.addAttribute("maxOccurs", "unbounded"); element.addAttribute("maxOccurs", "unbounded");
element.addAttribute("name", "element"); element.addAttribute("name", "element");
element.addAttribute("nillable", "true"); element.addAttribute("nillable", "true");
if(SOAPObject.class.isAssignableFrom(ctmp)) if(WSObject.class.isAssignableFrom(ctmp))
element.addAttribute("type", "tns:"+getClassSOAPName(c).replace("[]", "")); element.addAttribute("type", "tns:"+getClassSOAPName(c).replace("[]", ""));
else else
element.addAttribute("type", "xsd:"+getClassSOAPName(c).replace("[]", "")); element.addAttribute("type", "xsd:"+getClassSOAPName(c).replace("[]", ""));
@ -830,7 +816,7 @@ public class SOAPHttpPage implements HttpPage{
types.add(ctmp); types.add(ctmp);
} }
// Generate SOAPObject type // Generate SOAPObject type
else if(SOAPObject.class.isAssignableFrom(c)){ else if(WSObject.class.isAssignableFrom(c)){
Element type = schema.addElement("xsd:complexType"); Element type = schema.addElement("xsd:complexType");
type.addAttribute("name", getClassSOAPName(c)); type.addAttribute("name", getClassSOAPName(c));
@ -838,7 +824,7 @@ public class SOAPHttpPage implements HttpPage{
Field[] fields = c.getFields(); Field[] fields = c.getFields();
for(int i=0; i<fields.length ;i++){ for(int i=0; i<fields.length ;i++){
SOAPFieldName tmp = fields[i].getAnnotation(SOAPObject.SOAPFieldName.class); WSFieldName tmp = fields[i].getAnnotation(WSObject.WSFieldName.class);
String name; String name;
if(tmp != null) name = tmp.value(); if(tmp != null) name = tmp.value();
else name = "field"+i; else name = "field"+i;
@ -848,7 +834,7 @@ public class SOAPHttpPage implements HttpPage{
// Check if the object is an SOAPObject // Check if the object is an SOAPObject
Class<?> cTmp = getClass(fields[i].getType()); Class<?> cTmp = getClass(fields[i].getType());
if(SOAPObject.class.isAssignableFrom(cTmp)){ if(WSObject.class.isAssignableFrom(cTmp)){
element.addAttribute("type", "tns:"+getClassSOAPName(cTmp)); element.addAttribute("type", "tns:"+getClassSOAPName(cTmp));
if(!types.contains(cTmp)) if(!types.contains(cTmp))
types.add(cTmp); types.add(cTmp);

View file

@ -1,51 +0,0 @@
package zutil.network.http.soap;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 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.
*
* @author Ziver
*
*/
public interface SOAPReturnObjectList {
/**
* Method comments for the WSDL.
* These comments are put in the operation part of the WSDL
*
* @author Ziver
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface WSDLDocumentation{
String value();
}
/**
* Disables SOAP 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.
*
* @author Ziver
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SOAPValueName {
String value();
}
}

View file

@ -1,111 +0,0 @@
package zutil.network.http.soap;
import javax.wsdl.WSDLException;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class SOAPTest {
//*******************************************************************************************
//**************************** TEST *********************************************************
public static void main(String[] args){
try {
SOAPHttpPage soap = new SOAPHttpPage("http://test.se:8080/", new SOAPTestClass());
// Response
try {
Document document = soap.genSOAPResponse(
"<?xml version=\"1.0\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <soap:Body xmlns:m=\"http://www.example.org/stock\">\n" +
//" <m:pubA>\n" +
//" <m:Ztring>IBM</m:Ztring>\n" +
//" </m:pubA>\n" +
//" <m:pubZ>\n" +
//" <m:olle>66</m:olle>\n" +
//" </m:pubZ>\n" +
" <m:pubB>\n" +
" <m:byte>IBM</m:byte>\n" +
" </m:pubB>\n" +
" </soap:Body>\n" +
"</soap:Envelope>");
System.out.println( "****************** RESPONSE *********************" );
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter( System.out, format );
writer.write( document );
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
} catch (WSDLException e) {
e.printStackTrace();
}
}
}
class SOAPTestClass3 implements SOAPObject{
public String lol = "lol11";
public String lol2 = "lol22";
}
class SOAPTestClass2 implements SOAPObject{
@SOAPFieldName(value="lolz", optional=true)
public String lol = "lol1";
@SOAPFieldName("lolx")
public String lol2 = "lol2";
public byte[] b = new byte[]{0x12, 0x23};
public SOAPTestClass3 l = new SOAPTestClass3();
}
class SOAPTestRetClass implements SOAPReturnObjectList{
@SOAPValueName("retTest")
public String lol = "lol1";
public String lol2 = "lol2";
}
class SOAPTestClass implements SOAPInterface{
public SOAPTestClass(){}
@SOAPHeader()
@WSDLDocumentation("hello")
public void pubZ(
@SOAPParamName(value="olle", optional=true) int lol,
@SOAPParamName(value="olle2", optional=true) int lol2) throws Exception{
//System.out.println("Param: "+lol);
throw new Exception("Ziver is the fizle");
}
@SOAPReturnName("param")
@WSDLParamDocumentation("null is the shizzle")
public String[][] pubA (
@SOAPParamName("Ztring") String lol) throws Exception{
//System.out.println("ParamZ: "+lol);
return new String[][]{{"test","test2"},{"test3","test4"}};
}
@SOAPReturnName("zivarray")
@WSDLParamDocumentation("null is the shizzle")
public SOAPTestClass2[] pubX (
@SOAPParamName("Ztring") String lol) throws Exception{
return new SOAPTestClass2[]{new SOAPTestClass2(), new SOAPTestClass2()};
}
@SOAPReturnName("zivarray")
@WSDLParamDocumentation("null is the shizzle")
public SOAPTestRetClass pubB (
@SOAPParamName("byte") String lol) throws Exception{
SOAPTestRetClass tmp = new SOAPTestRetClass();
tmp.lol = "test";
tmp.lol2 = "test2";
return tmp;
}
@SOAPDisabled()
public void privaZ(){ }
protected void protZ(){ }
}

View file

@ -1,31 +1,30 @@
package zutil.network.http.soap; package zutil.network.ws;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* *
* Specifies SOAP parameters names an other things. * Specifies web service parameter names and other things.
* Example: * Example:
* <pre> * <pre>
* private static class Test implements SOAPInterface{ * private static class Test implements WSInterface{
* public Test(){} * public Test(){}
* *
* @SOAPHeader() * @WSDocumentation("blabla")
* @WSDLDocumentation("blabla")
* @WSDLParamDocumentation("olle = an variable?") * @WSDLParamDocumentation("olle = an variable?")
* public void pubZ( * public void pubZ(
* @SOAPParamName("olle") int lol) * @WSParamName("olle") int lol)
* throws Exception{ * throws Exception{
* .... * ....
* } * }
* *
* @SOAPReturnName("param") * @WSReturnName("param")
* public String pubA( * public String pubA(
* @SOAPParamName(value="lol", optional=true) String lol) * @WSParamName(value="lol", optional=true) String lol)
* throws Exception{ * throws Exception{
* .... * ....
* } * }
* *
* @SOAPDisabled() * @WSDisabled()
* public void privaZ(....){ * public void privaZ(....){
* ... * ...
* } * }
@ -34,7 +33,7 @@ import java.lang.annotation.*;
* </pre> * </pre>
* @author Ziver * @author Ziver
*/ */
public interface SOAPInterface { public interface WSInterface {
/** /**
* Annotation that assigns a name to an parameters * Annotation that assigns a name to an parameters
* in an method. * in an method.
@ -43,7 +42,7 @@ public interface SOAPInterface {
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER) @Target(ElementType.PARAMETER)
public @interface SOAPParamName { public @interface WSParamName {
String value(); String value();
boolean optional() default false; boolean optional() default false;
} }
@ -56,29 +55,30 @@ public interface SOAPInterface {
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
public @interface SOAPReturnName { public @interface WSReturnName {
String value(); String value();
} }
/** /**
* Disables SOAP publication of the given method * Disables publication of the given method
* *
* @author Ziver * @author Ziver
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
public @interface SOAPDisabled { } public @interface WSDisabled { }
/** /**
* Method comments for the WSDL. * Method or Parameter comments for the WSDL.
* These comments are put in the operation part of the WSDL * These comments are put in the message part of the WSDL
* *
* @author Ziver * @author Ziver
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface WSDLDocumentation{ public @interface WSDocumentation{
String value(); String value();
} }
/** /**
* Parameter comments for the WSDL. * Parameter comments for the WSDL.
* These comments are put in the message part of the WSDL * These comments are put in the message part of the WSDL
@ -86,27 +86,27 @@ public interface SOAPInterface {
* @author Ziver * @author Ziver
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface WSDLParamDocumentation{ public @interface WSParamDocumentation{
String value(); String value();
} }
/** /**
* This method will be used in the header of the soap. * This method will be used in the header.
* *
* @author Ziver * @author Ziver
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
public @interface SOAPHeader { } public @interface WSHeader { }
/** /**
* Specifies the namespace for the method. * Specifies the name space for the method.
* *
* @author Ziver * @author Ziver
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
public @interface SOAPNameSpace { public @interface WSNamespace {
String value(); String value();
} }
} }

View file

@ -0,0 +1,175 @@
package zutil.network.ws;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import zutil.network.ws.WSInterface.WSDocumentation;
// TODO: Header parameters
public class WSMethodDef {
/** A list of input parameters **/
private ArrayList<WSParameterDef> inputs;
/** A List of return parameters of the method **/
private ArrayList<WSParameterDef> outputs;
/** A List of exceptions that this method throws **/
private ArrayList<Class<?>> exceptions;
/** The real method that this class represent, can be null if its a remote method **/
private Method method;
/** Documentation of the method **/
private String doc;
/** The published name of the method **/
private String name;
/**
*
* @param me is a method in a class that implements WSInterface
*/
public WSMethodDef(Method me) {
if(!WSInterface.class.isAssignableFrom(me.getDeclaringClass()) )
throw new ClassCastException("Declaring class does not implement WSInterface!");
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);
if(tmpDoc != null){
doc = tmpDoc.value();
}
//***** Exceptions
for( Class<?> exc : method.getExceptionTypes() ){
exceptions.add( exc );
}
//********* Get the input parameter names **********
Annotation[][] paramAnnotation = method.getParameterAnnotations();
for(int i=0; i<paramAnnotation.length ;i++){
WSParameterDef param = new WSParameterDef();
for(Annotation annotation : paramAnnotation[i]){
if(annotation instanceof WSInterface.WSParamName){
WSInterface.WSParamName paramName = (WSInterface.WSParamName) annotation;
param.name = paramName.value();
param.optional = paramName.optional();
}
}
// if no name was found then use default
if(param.name == null)
param.name = "args"+i;
inputs.add( param );
}
//******** The return parameter name ************
WSInterface.WSReturnName returnName = method.getAnnotation(WSInterface.WSReturnName.class);
if( WSReturnValueList.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();
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();
outputs.add( ret_param );
}
}
/**
* @return the published name of the method
*/
public String getName(){
return name;
}
/**
* @return the number of exceptions this method throws
*/
public int exceptionCount(){
return exceptions.size();
}
/**
* @return a list of exceptions this method throws
*/
public List<Class<?>> getExceptions(){
return exceptions;
}
/**
* @return the number of parameters for this method
*/
public int inputCount(){
return inputs.size();
}
/**
* @return a list of input parameters
*/
public List<WSParameterDef> getInputs(){
return inputs;
}
/**
* @return the number of parameters for this method
*/
public int outputCount(){
return outputs.size();
}
/**
* @return a list of input parameters
*/
public List<WSParameterDef> getOutputs(){
return outputs;
}
/**
* @return Documentation of the method if one exists or else null
*/
public String getDocumentation(){
return doc;
}
public String toString(){
StringBuilder tmp = new StringBuilder();
boolean first = true;
tmp.append(name).append("(");
for(WSParameterDef param : inputs){
if(first)
first = false;
else
tmp.append(" ,");
tmp.append(param.paramClass.getSimpleName());
tmp.append(" ");
tmp.append(param.name);
}
tmp.append(") => ");
first = true;
for(WSParameterDef param : outputs){
if(first)
first = false;
else
tmp.append(" ,");
tmp.append(param.paramClass.getSimpleName());
tmp.append(" ");
tmp.append(param.name);
}
return tmp.toString();
}
}

View file

@ -1,4 +1,4 @@
package zutil.network.http.soap; package zutil.network.ws;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -6,11 +6,11 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* This class is used as an return Object for SOAP. * This class is used as an return Object for a web service.
* If an class implements this interface then it can return * If an class implements this interface then it can return
* multiple values through the SOAPInterface. Example: * multiple values through the SOAPInterface. Example:
* <pre> * <pre>
* private static class TestObject implements SOAPObject{ * private static class TestObject implements WSObject{
* @SOAPFieldName("name") * @SOAPFieldName("name")
* public String name; * public String name;
* @SOAPFieldName("lastname") * @SOAPFieldName("lastname")
@ -26,17 +26,17 @@ import java.lang.annotation.Target;
* @author Ziver * @author Ziver
* *
*/ */
public interface SOAPObject{ public interface WSObject{
/** /**
* Specifies the SOAP name of an field. * Specifies the name of a field.
* The fields that are available for SOAP should * The fields that are available in the service should
* be declared public. * be declared public.
* *
* @author Ziver * @author Ziver
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
public @interface SOAPFieldName { public @interface WSFieldName {
String value(); String value();
boolean optional() default false; boolean optional() default false;
} }

View file

@ -0,0 +1,42 @@
package zutil.network.ws;
public class WSParameterDef{
/** The class type of the parameter **/
protected Class<?> paramClass;
/** The web service name of the parameter **/
protected String name;
/** Developer documentation **/
protected String doc;
/** If this parameter is optional **/
protected boolean optional;
/** Is it an header parameter **/
//boolean header;
public Class<?> getParamClass() {
return paramClass;
}
protected void setParamClass(Class<?> paramClass) {
this.paramClass = paramClass;
}
public String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
public String getDoc() {
return doc;
}
protected void setDoc(String doc) {
this.doc = doc;
}
public boolean isOptional() {
return optional;
}
protected void setOptional(boolean optional) {
this.optional = optional;
}
}

View file

@ -1,4 +1,4 @@
package zutil.network.http.soap; package zutil.network.ws;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -15,7 +15,7 @@ import java.lang.reflect.Field;
* @author Ziver * @author Ziver
* *
*/ */
public class SOAPReturnValueList { public class WSReturnValueList {
/** /**
* Method comments for the WSDL. * Method comments for the WSDL.
@ -29,7 +29,7 @@ public class SOAPReturnValueList {
} }
/** /**
* Disables SOAP publication of the given field. * Disables publication of the given field.
* *
* @author Ziver * @author Ziver
*/ */
@ -45,12 +45,12 @@ public class SOAPReturnValueList {
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
public @interface SOAPValueName { public @interface WSValueName {
String value(); String value();
} }
protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException{ public Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException{
return field.get(this); return field.get(this);
} }
} }

View file

@ -0,0 +1,66 @@
package zutil.network.ws;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import javax.wsdl.WSDLException;
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;
/** 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{
this.intf = intf;
methods = new HashMap<String,WSMethodDef>();
name = intf.getSimpleName();
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);
methods.put(method.getName(), method);
}
}
}
/**
* @return the class that defines this web service
*/
public Class<? extends WSInterface> getWSClass(){
return intf;
}
/**
* @return the name of the Service (usually the class name of the WSInterface)
*/
public String getName(){
return name;
}
/**
* @return a Set of all the method names
*/
public Set<String> getMethodNames(){
return methods.keySet();
}
/**
* @return all the methods
*/
public Collection<WSMethodDef> getMethods(){
return methods.values();
}
}