Moved from javasisst to Reflection Proxy
This commit is contained in:
parent
ad970e3317
commit
431d238c19
10 changed files with 288 additions and 229 deletions
BIN
Zutil.jar
BIN
Zutil.jar
Binary file not shown.
Binary file not shown.
73
src/zutil/net/ws/WSClientFactory.java
Executable file
73
src/zutil/net/ws/WSClientFactory.java
Executable file
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 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 zutil.log.LogUtil;
|
||||||
|
import zutil.net.ws.soap.SOAPClientInvocationHandler;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an factory that generates clients for an unspecified web services
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
public class WSClientFactory {
|
||||||
|
private static Logger logger = LogUtil.getLogger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public static <T> T createClient(Class<T> intf, InvocationHandler handler){
|
||||||
|
if( !WSInterface.class.isAssignableFrom( intf )){
|
||||||
|
throw new ClassCastException("The Web Service class is not a subclass of WSInterface!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class proxyClass = Proxy.getProxyClass(
|
||||||
|
WSClientFactory.class.getClassLoader(),
|
||||||
|
new Class[]{intf});
|
||||||
|
Constructor<T> constructor = proxyClass.getConstructor(
|
||||||
|
new Class[]{InvocationHandler.class});
|
||||||
|
T obj = constructor.newInstance(
|
||||||
|
new Object[]{handler});
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
} catch (Exception e){
|
||||||
|
logger.log(Level.SEVERE, null, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
src/zutil/net/ws/rest/RestHttpPage.java
Normal file → Executable file
35
src/zutil/net/ws/rest/RestHttpPage.java
Normal file → Executable file
|
|
@ -25,14 +25,15 @@
|
||||||
package zutil.net.ws.rest;
|
package zutil.net.ws.rest;
|
||||||
|
|
||||||
import zutil.converters.Converter;
|
import zutil.converters.Converter;
|
||||||
|
import zutil.io.StringOutputStream;
|
||||||
import zutil.net.http.HttpHeaderParser;
|
import zutil.net.http.HttpHeaderParser;
|
||||||
import zutil.net.http.HttpPage;
|
import zutil.net.http.HttpPage;
|
||||||
import zutil.net.http.HttpPrintStream;
|
import zutil.net.http.HttpPrintStream;
|
||||||
import zutil.net.ws.WSInterface;
|
import zutil.net.ws.*;
|
||||||
import zutil.net.ws.WSMethodDef;
|
import zutil.parser.json.JSONObjectOutputStream;
|
||||||
import zutil.net.ws.WSParameterDef;
|
|
||||||
import zutil.net.ws.WebServiceDef;
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,13 +58,33 @@ public class RestHttpPage implements HttpPage {
|
||||||
HttpHeaderParser client_info,
|
HttpHeaderParser client_info,
|
||||||
Map<String, Object> session,
|
Map<String, Object> session,
|
||||||
Map<String, String> cookie,
|
Map<String, String> cookie,
|
||||||
Map<String, String> request) {
|
Map<String, String> request) throws IOException {
|
||||||
execute(request);
|
try {
|
||||||
|
out.println(
|
||||||
|
execute(client_info.getRequestURL(), request));
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
throw new IOException(throwable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void execute(Map<String, String> input){
|
private String execute(String targetMethod, Map<String, String> input) throws Throwable {
|
||||||
|
if( wsDef.hasMethod(targetMethod) ){
|
||||||
|
// Parse request
|
||||||
|
WSMethodDef m = wsDef.getMethod(targetMethod);
|
||||||
|
Object[] params = prepareInputParams(m, input);
|
||||||
|
|
||||||
|
// Invoke
|
||||||
|
Object ret = m.invoke(ws, params);
|
||||||
|
|
||||||
|
// Generate Response
|
||||||
|
StringOutputStream dummyOut = new StringOutputStream();
|
||||||
|
JSONObjectOutputStream out = new JSONObjectOutputStream(dummyOut);
|
||||||
|
out.writeObject(ret);
|
||||||
|
out.close();
|
||||||
|
return dummyOut.toString();
|
||||||
|
}
|
||||||
|
return "{error: \"Unknown target: "+targetMethod+"\"}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] prepareInputParams(WSMethodDef method, Map<String, String> input){
|
private Object[] prepareInputParams(WSMethodDef method, Map<String, String> input){
|
||||||
|
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015 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.soap;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an abstract client that will do generic requests to a
|
|
||||||
* SOAP Web service
|
|
||||||
*
|
|
||||||
* @author Ziver
|
|
||||||
*/
|
|
||||||
public class SOAPAbstractClient {
|
|
||||||
/** Web address of the web service */
|
|
||||||
protected String url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a request to the target web service
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Object request(String methodName, HashMap<String,Object> input){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
114
src/zutil/net/ws/soap/SOAPClientFactory.java
Normal file → Executable file
114
src/zutil/net/ws/soap/SOAPClientFactory.java
Normal file → Executable file
|
|
@ -24,15 +24,15 @@
|
||||||
|
|
||||||
package zutil.net.ws.soap;
|
package zutil.net.ws.soap;
|
||||||
|
|
||||||
import javassist.*;
|
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.ws.WSClientFactory;
|
||||||
import zutil.net.ws.WSInterface;
|
import zutil.net.ws.WSInterface;
|
||||||
import zutil.net.ws.WSMethodDef;
|
|
||||||
import zutil.net.ws.WSParameterDef;
|
|
||||||
import zutil.net.ws.WebServiceDef;
|
import zutil.net.ws.WebServiceDef;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.List;
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -51,11 +51,8 @@ public class SOAPClientFactory {
|
||||||
* @return a client Object
|
* @return a client Object
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T getClient(Class<T> intf) throws InstantiationException, IllegalAccessException, CannotCompileException, NotFoundException{
|
public static <T> T createClient(Class<T> intf){
|
||||||
if( !WSInterface.class.isAssignableFrom( intf )){
|
return createClient( intf, new WebServiceDef((Class<? extends WSInterface>)intf) );
|
||||||
throw new ClassCastException("The Web Service class is not a subclass of WSInterface!");
|
|
||||||
}
|
|
||||||
return getClient( intf, new WebServiceDef((Class<? extends WSInterface>)intf) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -66,102 +63,9 @@ public class SOAPClientFactory {
|
||||||
* @param wsDef is the web service definition of the intf parameter
|
* @param wsDef is the web service definition of the intf parameter
|
||||||
* @return a client Object
|
* @return a client Object
|
||||||
*/
|
*/
|
||||||
public static <T> T getClient(Class<T> intf, WebServiceDef wsDef) throws InstantiationException, IllegalAccessException, CannotCompileException, NotFoundException{
|
public static <T> T createClient(Class<T> intf, WebServiceDef wsDef){
|
||||||
if( !WSInterface.class.isAssignableFrom( intf )){
|
T obj = WSClientFactory.createClient(intf, new SOAPClientInvocationHandler());
|
||||||
throw new ClassCastException("The Web Service class is not a subclass of WSInterface!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the class
|
|
||||||
ClassPool pool = ClassPool.getDefault();
|
|
||||||
CtClass intfClass = pool.get( intf.getName() );
|
|
||||||
CtClass cc = pool.makeClass(intf.getName()+"Impl_"+ (int)(Math.random()*10000));
|
|
||||||
|
|
||||||
// Is intf an interface
|
|
||||||
if( intf.isInterface() ){
|
|
||||||
cc.addInterface( intfClass );
|
|
||||||
}
|
|
||||||
// or a class
|
|
||||||
else{
|
|
||||||
cc.setSuperclass( intfClass );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the logger class
|
|
||||||
CtField logger = CtField.make(
|
|
||||||
"private static "+Logger.class.getName()+" logger = "+LogUtil.class.getName()+".getLogger();",
|
|
||||||
cc);
|
|
||||||
cc.addField(logger);
|
|
||||||
|
|
||||||
// Generate the methods
|
|
||||||
for(WSMethodDef methodDef : wsDef.getMethods()){
|
|
||||||
// Create method
|
|
||||||
CtMethod method = CtNewMethod.make(
|
|
||||||
getOutputClass(methodDef.getOutputs()), // Return type
|
|
||||||
methodDef.getName(), // Method name
|
|
||||||
getParameterClasses(methodDef.getInputs()), // Parameters
|
|
||||||
new CtClass[]{pool.get( SOAPException.class.getName() )}, // Exceptions
|
|
||||||
generateCodeBody(methodDef), // Code Body
|
|
||||||
cc); // Class
|
|
||||||
cc.addMethod(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initiate the class
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Class<T> c = cc.toClass();
|
|
||||||
T obj = c.newInstance();
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a generic method code body that calls the SOAPAbstractClient class
|
|
||||||
*/
|
|
||||||
private static String generateCodeBody(WSMethodDef m) {
|
|
||||||
logger.finer("Generating method "+m.getName()+"(...)");
|
|
||||||
|
|
||||||
StringBuilder body = new StringBuilder("{\n");
|
|
||||||
// Logging
|
|
||||||
body.append( "logger.fine(\"Executing method: "+m.getName()+"(...)\");\n" );
|
|
||||||
|
|
||||||
// Generate parameter list
|
|
||||||
body.append( HashMap.class.getName()+"<String,Object> params = new "+HashMap.class.getName()+"<String,Object>();\n" );
|
|
||||||
for(WSParameterDef param : m.getInputs()){
|
|
||||||
body.append( "params.put(\""+param.getName()+"\", "+param.getName()+");\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call SOAPAbstractClient class
|
|
||||||
if(m.getOutputCount() > 0) // non void function
|
|
||||||
body.append( "return " );
|
|
||||||
body.append( SOAPAbstractClient.class.getName()+".request(\""+m.getName()+"\", params);\n" );
|
|
||||||
|
|
||||||
body.append("}");
|
|
||||||
logger.finest("###################### BODY #########################");
|
|
||||||
logger.finest(body.toString());
|
|
||||||
logger.finest("#######################################################");
|
|
||||||
return body.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CtClass getParameterClass(WSParameterDef param) throws NotFoundException{
|
|
||||||
return ClassPool.getDefault().get( param.getClass().getName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CtClass[] getParameterClasses(List<WSParameterDef> params) throws NotFoundException{
|
|
||||||
CtClass[] c = new CtClass[params.size()];
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for(WSParameterDef param : params){
|
|
||||||
c[i++] = getParameterClass(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CtClass getOutputClass(List<WSParameterDef> params) throws NotFoundException{
|
|
||||||
if(params.isEmpty()){
|
|
||||||
return CtClass.voidType;
|
|
||||||
}
|
|
||||||
else if(params.size() == 1){
|
|
||||||
return ClassPool.getDefault().get( params.get(0).getClass().getName() );
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown return type");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
105
src/zutil/net/ws/soap/SOAPClientInvocationHandler.java
Executable file
105
src/zutil/net/ws/soap/SOAPClientInvocationHandler.java
Executable file
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 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.soap;
|
||||||
|
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.DocumentHelper;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.http.HttpClient;
|
||||||
|
import zutil.net.http.HttpHeaderParser;
|
||||||
|
import zutil.net.ws.WSInterface;
|
||||||
|
import zutil.net.ws.WSMethodDef;
|
||||||
|
import zutil.net.ws.WSParameterDef;
|
||||||
|
import zutil.net.ws.WebServiceDef;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an abstract client that will do generic requests to a
|
||||||
|
* SOAP Web service
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
public class SOAPClientInvocationHandler implements InvocationHandler {
|
||||||
|
private static Logger logger = LogUtil.getLogger();
|
||||||
|
|
||||||
|
private WebServiceDef wsDef;
|
||||||
|
/** Web address of the web service */
|
||||||
|
protected String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes a request to the target web service
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
HttpClient request = HttpClient.POST();
|
||||||
|
|
||||||
|
HttpHeaderParser response = request.send();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Document genSOAPRequest(WSInterface obj, String targetMethod, Object[] args){
|
||||||
|
Document document = DocumentHelper.createDocument();
|
||||||
|
Element envelope = document.addElement("soap:Envelope");
|
||||||
|
WSMethodDef methodDef = wsDef.getMethod( targetMethod );
|
||||||
|
try {
|
||||||
|
envelope.addNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
|
||||||
|
envelope.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
|
||||||
|
envelope.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
|
||||||
|
|
||||||
|
Element body = envelope.addElement( "soap:Body" );
|
||||||
|
Element method = body.addElement("");
|
||||||
|
method.addNamespace("m", methodDef.getNamespace() );
|
||||||
|
method.setName("m:"+methodDef.getName()+"Request");
|
||||||
|
for(int i=0; i<methodDef.getOutputCount() ;i++){
|
||||||
|
WSParameterDef param = methodDef.getOutput( i );
|
||||||
|
SOAPHttpPage.generateSOAPXMLForObj(method, args[i] , param.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.SEVERE, "Exception in SOAP generation", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object parseSOAPResponse(String xml){
|
||||||
|
try {
|
||||||
|
Element response = SOAPHttpPage.getXMLRoot(xml);
|
||||||
|
// TODO:
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
logger.log(Level.SEVERE, "Unable to parse SOAP response", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/zutil/net/ws/soap/SOAPHttpPage.java
Normal file → Executable file
62
src/zutil/net/ws/soap/SOAPHttpPage.java
Normal file → Executable file
|
|
@ -228,7 +228,7 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
* @param xml is the string XML
|
* @param xml is the string XML
|
||||||
* @return the XML root Element
|
* @return the XML root Element
|
||||||
*/
|
*/
|
||||||
private Element getXMLRoot(String xml) throws Exception {
|
protected static Element getXMLRoot(String xml) throws DocumentException {
|
||||||
if(xml != null && !xml.isEmpty()){
|
if(xml != null && !xml.isEmpty()){
|
||||||
Document document = DocumentHelper.parseText(xml);
|
Document document = DocumentHelper.parseText(xml);
|
||||||
return document.getRootElement();
|
return document.getRootElement();
|
||||||
|
|
@ -275,73 +275,77 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
Field[] f = ret.getClass().getFields();
|
Field[] f = ret.getClass().getFields();
|
||||||
for(int i=0; i<m.getOutputCount() ;i++){
|
for(int i=0; i<m.getOutputCount() ;i++){
|
||||||
WSParameterDef param = m.getOutput( i );
|
WSParameterDef param = m.getOutput( i );
|
||||||
generateReturnXML(response,((WSReturnObject)ret).getValue(f[i]) , param.getName());
|
generateSOAPXMLForObj(response,((WSReturnObject)ret).getValue(f[i]) , param.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
generateReturnXML(response, ret, m.getOutput(0).getName());
|
generateSOAPXMLForObj(response, ret, m.getOutput(0).getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
throw new Exception("No such method: "+e.getQName().getName()+"!");
|
throw new NoSuchMethodException("Unable to find method: "+e.getQName().getName()+"!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a return XML Element. This function can
|
* Generates a XML Element for a given Object. This method can
|
||||||
* handle return values as XML Elements, WSReturnObject and
|
* handle return values as XML Elements, WSReturnObject and
|
||||||
* Java basic data types.
|
* Java basic data types.
|
||||||
*
|
*
|
||||||
* @param root is the parent Element
|
* @param root is the parent Element
|
||||||
* @param retObj is the object that is the return value
|
* @param obj is the object that is the return value
|
||||||
* @param ename is the name of the parent Element
|
* @param elementName is the name of the parent Element
|
||||||
*/
|
*/
|
||||||
private void generateReturnXML(Element root, Object retObj, String ename) throws IllegalArgumentException, IllegalAccessException{
|
protected static void generateSOAPXMLForObj(Element root, Object obj, String elementName) throws IllegalArgumentException, IllegalAccessException{
|
||||||
if(retObj == null) return;
|
if(obj == null) return;
|
||||||
if(byte[].class.isAssignableFrom(retObj.getClass())){
|
if(byte[].class.isAssignableFrom(obj.getClass())){
|
||||||
Element valueE = root.addElement( ename );
|
Element valueE = root.addElement( elementName );
|
||||||
valueE.addAttribute("type", "xsd:"+ getSOAPClassName(retObj.getClass()));
|
valueE.addAttribute("type", "xsd:"+ getSOAPClassName(obj.getClass()));
|
||||||
String tmp = new sun.misc.BASE64Encoder().encode((byte[])retObj);
|
String tmp = new sun.misc.BASE64Encoder().encode((byte[])obj);
|
||||||
tmp = tmp.replaceAll("\\s", "");
|
tmp = tmp.replaceAll("\\s", "");
|
||||||
valueE.setText(tmp);
|
valueE.setText(tmp);
|
||||||
}
|
}
|
||||||
// return an array
|
// return an array
|
||||||
else if(retObj.getClass().isArray()){
|
else if(obj.getClass().isArray()){
|
||||||
Element array = root.addElement( (ename.equals("element") ? "Array" : ename) );
|
Element array = root.addElement( (elementName.equals("element") ? "Array" : elementName) );
|
||||||
String arrayType = "xsd:"+ getSOAPClassName(retObj.getClass());
|
String arrayType = "xsd:"+ getSOAPClassName(obj.getClass());
|
||||||
arrayType = arrayType.replaceFirst("\\[\\]", "["+Array.getLength(retObj)+"]");
|
arrayType = arrayType.replaceFirst("\\[\\]", "["+Array.getLength(obj)+"]");
|
||||||
|
|
||||||
array.addAttribute("type", "soap:Array");
|
array.addAttribute("type", "soap:Array");
|
||||||
array.addAttribute("soap:arrayType", arrayType);
|
array.addAttribute("soap:arrayType", arrayType);
|
||||||
for(int i=0; i<Array.getLength(retObj) ;i++){
|
for(int i=0; i<Array.getLength(obj) ;i++){
|
||||||
generateReturnXML(array, Array.get(retObj, i), "element");
|
generateSOAPXMLForObj(array, Array.get(obj, i), "element");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Element objectE = root.addElement( ename );
|
Element objectE = root.addElement( elementName );
|
||||||
if(retObj instanceof Element)
|
if(obj instanceof Element)
|
||||||
objectE.add( (Element)retObj );
|
objectE.add( (Element)obj );
|
||||||
else if(retObj instanceof WSReturnObject){
|
else if(obj instanceof WSReturnObject){
|
||||||
Field[] fields = retObj.getClass().getFields();
|
Field[] fields = obj.getClass().getFields();
|
||||||
for(int i=0; i<fields.length ;i++){
|
for(int i=0; i<fields.length ;i++){
|
||||||
WSValueName tmp = fields[i].getAnnotation( WSValueName.class );
|
WSValueName tmp = fields[i].getAnnotation( WSValueName.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;
|
||||||
generateReturnXML(objectE, fields[i].get(retObj), name);
|
generateSOAPXMLForObj(objectE, fields[i].get(obj), name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
objectE.addAttribute("type", "xsd:"+ getSOAPClassName(retObj.getClass()));
|
objectE.addAttribute("type", "xsd:"+ getSOAPClassName(obj.getClass()));
|
||||||
objectE.addText( ""+retObj );
|
objectE.addText( ""+obj );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getSOAPClassName(Class<?> c){
|
protected static String getSOAPClassName(Class<?> c){
|
||||||
Class<?> cTmp = getClass(c);
|
Class<?> cTmp = getClass(c);
|
||||||
if(byte[].class.isAssignableFrom(c)){
|
if(byte[].class.isAssignableFrom(c)){
|
||||||
return "base64Binary";
|
return "base64Binary";
|
||||||
|
|
@ -359,7 +363,7 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?> getClass(Class<?> c){
|
protected static Class<?> getClass(Class<?> c){
|
||||||
if(c!=null && c.isArray()){
|
if(c!=null && c.isArray()){
|
||||||
return getClass(c.getComponentType());
|
return getClass(c.getComponentType());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
test/zutil/test/SOAPClientTest.java
Normal file → Executable file
6
test/zutil/test/SOAPClientTest.java
Normal file → Executable file
|
|
@ -23,8 +23,6 @@
|
||||||
*/
|
*/
|
||||||
package zutil.test;
|
package zutil.test;
|
||||||
|
|
||||||
import javassist.CannotCompileException;
|
|
||||||
import javassist.NotFoundException;
|
|
||||||
import zutil.log.CompactLogFormatter;
|
import zutil.log.CompactLogFormatter;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
import zutil.net.ws.WSInterface;
|
import zutil.net.ws.WSInterface;
|
||||||
|
|
@ -34,11 +32,11 @@ import java.util.logging.Level;
|
||||||
|
|
||||||
public class SOAPClientTest {
|
public class SOAPClientTest {
|
||||||
|
|
||||||
public static void main(String[] args) throws InstantiationException, IllegalAccessException, CannotCompileException, NotFoundException{
|
public static void main(String[] args) throws InstantiationException, IllegalAccessException{
|
||||||
LogUtil.setGlobalLevel(Level.ALL);
|
LogUtil.setGlobalLevel(Level.ALL);
|
||||||
LogUtil.setFormatter("", new CompactLogFormatter());
|
LogUtil.setFormatter("", new CompactLogFormatter());
|
||||||
|
|
||||||
TestClient intf = SOAPClientFactory.getClient(TestClient.class);
|
TestClient intf = SOAPClientFactory.createClient(TestClient.class);
|
||||||
intf.m();
|
intf.m();
|
||||||
intf.c();
|
intf.c();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
test/zutil/test/SOAPTest.java
Normal file → Executable file
23
test/zutil/test/SOAPTest.java
Normal file → Executable file
|
|
@ -26,6 +26,7 @@ package zutil.test;
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
import org.dom4j.io.OutputFormat;
|
import org.dom4j.io.OutputFormat;
|
||||||
import org.dom4j.io.XMLWriter;
|
import org.dom4j.io.XMLWriter;
|
||||||
|
import zutil.net.nio.message.type.SystemMessage;
|
||||||
import zutil.net.ws.WSInterface;
|
import zutil.net.ws.WSInterface;
|
||||||
import zutil.net.ws.WSInterface.WSNamespace;
|
import zutil.net.ws.WSInterface.WSNamespace;
|
||||||
import zutil.net.ws.WSReturnObject;
|
import zutil.net.ws.WSReturnObject;
|
||||||
|
|
@ -44,17 +45,14 @@ public class SOAPTest {
|
||||||
WebServiceDef wsDef = new WebServiceDef( MainSOAPClass.class );
|
WebServiceDef wsDef = new WebServiceDef( MainSOAPClass.class );
|
||||||
SOAPHttpPage soap = new SOAPHttpPage( wsDef );
|
SOAPHttpPage soap = new SOAPHttpPage( wsDef );
|
||||||
|
|
||||||
|
System.out.println( "****************** WSDL *********************" );
|
||||||
WSDLWriter wsdl = new WSDLWriter( wsDef );
|
WSDLWriter wsdl = new WSDLWriter( wsDef );
|
||||||
wsdl.write(System.out);
|
wsdl.write(System.out);
|
||||||
System.out.println( "****************** new *********************" );
|
|
||||||
WSDLWriter wsdl2 = new WSDLWriter( wsDef );
|
|
||||||
wsdl2.write(System.out);
|
|
||||||
|
|
||||||
// Response
|
// Response
|
||||||
try {
|
try {
|
||||||
System.out.println( "****************** LOG *********************" );
|
System.out.println( "\n****************** REQUEST *********************" );
|
||||||
Document document = soap.genSOAPResponse(
|
String request = "<?xml version=\"1.0\"?>\n" +
|
||||||
"<?xml version=\"1.0\"?>" +
|
|
||||||
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
|
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
|
||||||
" <soap:Body xmlns:m=\"http://www.example.org/stock\">\n" +
|
" <soap:Body xmlns:m=\"http://www.example.org/stock\">\n" +
|
||||||
" <m:stringArrayMethod>\n" +
|
" <m:stringArrayMethod>\n" +
|
||||||
|
|
@ -65,8 +63,11 @@ public class SOAPTest {
|
||||||
" <m:byte>IBM</m:byte>\n" +
|
" <m:byte>IBM</m:byte>\n" +
|
||||||
" </m:simpleReturnClassMethod>\n" +
|
" </m:simpleReturnClassMethod>\n" +
|
||||||
" </soap:Body>\n" +
|
" </soap:Body>\n" +
|
||||||
"</soap:Envelope>");
|
"</soap:Envelope>";
|
||||||
System.out.println( "****************** RESPONSE *********************" );
|
System.out.println(request);
|
||||||
|
System.out.println( "\n****************** EXECUTION *********************" );
|
||||||
|
Document document = soap.genSOAPResponse(request);
|
||||||
|
System.out.println( "\n****************** RESPONSE *********************" );
|
||||||
|
|
||||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||||
XMLWriter writer = new XMLWriter( System.out, format );
|
XMLWriter writer = new XMLWriter( System.out, format );
|
||||||
|
|
@ -112,7 +113,7 @@ public class SOAPTest {
|
||||||
public void exceptionMethod(
|
public void exceptionMethod(
|
||||||
@WSParamName(value="otherParam1", optional=true) int param1,
|
@WSParamName(value="otherParam1", optional=true) int param1,
|
||||||
@WSParamName(value="otherParam2", optional=true) int param2) throws Exception{
|
@WSParamName(value="otherParam2", optional=true) int param2) throws Exception{
|
||||||
System.out.println("Executing method: exceptionMethod()");
|
System.out.println("Executing method: exceptionMethod(int param1="+param1+", int param2="+param2+",)");
|
||||||
throw new Exception("This is an Exception");
|
throw new Exception("This is an Exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +121,7 @@ public class SOAPTest {
|
||||||
@WSParamDocumentation("Documentation of stringArrayMethod()")
|
@WSParamDocumentation("Documentation of stringArrayMethod()")
|
||||||
public String[][] stringArrayMethod (
|
public String[][] stringArrayMethod (
|
||||||
@WSParamName("StringName") String str) throws Exception{
|
@WSParamName("StringName") String str) throws Exception{
|
||||||
System.out.println("Executing method: stringArrayMethod()");
|
System.out.println("Executing method: stringArrayMethod(String str='"+str+"')");
|
||||||
return new String[][]{{"test","test2"},{"test3","test4"}};
|
return new String[][]{{"test","test2"},{"test3","test4"}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,7 +129,7 @@ public class SOAPTest {
|
||||||
@WSParamDocumentation("Documentation of specialReturnMethod()")
|
@WSParamDocumentation("Documentation of specialReturnMethod()")
|
||||||
public SpecialReturnClass[] specialReturnMethod (
|
public SpecialReturnClass[] specialReturnMethod (
|
||||||
@WSParamName("StringName2") String str) throws Exception{
|
@WSParamName("StringName2") String str) throws Exception{
|
||||||
System.out.println("Executing method: specialReturnMethod()");
|
System.out.println("Executing method: specialReturnMethod(String str='"+str+"')");
|
||||||
return new SpecialReturnClass[]{new SpecialReturnClass(), new SpecialReturnClass()};
|
return new SpecialReturnClass[]{new SpecialReturnClass(), new SpecialReturnClass()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue