Refactoring of WSDLWriter

This commit is contained in:
Ziver Koc 2014-02-23 14:28:40 +00:00
parent eb2b67ec5d
commit 52fee71c30
6 changed files with 301 additions and 115 deletions

View file

@ -35,7 +35,6 @@ import zutil.net.http.HttpPage;
import zutil.net.http.HttpPrintStream; import zutil.net.http.HttpPrintStream;
import zutil.net.ws.*; import zutil.net.ws.*;
import zutil.net.ws.WSReturnObject.WSValueName; import zutil.net.ws.WSReturnObject.WSValueName;
import zutil.parser.wsdl.WSDLWriter;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -82,16 +81,12 @@ public class SOAPHttpPage implements HttpPage{
private WebServiceDef wsDef; private WebServiceDef wsDef;
/** This instance of the web service class is used if session is disabled **/ /** This instance of the web service class is used if session is disabled **/
private WSInterface ws; private WSInterface ws;
/** The WSDL document **/
private WSDLWriter wsdl;
/** Session enabled **/ /** Session enabled **/
private boolean session_enabled; private boolean session_enabled;
public SOAPHttpPage( WebServiceDef wsDef ){ public SOAPHttpPage( WebServiceDef wsDef ){
this.wsDef = wsDef; this.wsDef = wsDef;
this.session_enabled = false; this.session_enabled = false;
wsdl = new WSDLWriter( wsDef );
} }
/** /**
@ -124,43 +119,37 @@ public class SOAPHttpPage implements HttpPage{
out.setHeader("Content-Type", "text/xml"); out.setHeader("Content-Type", "text/xml");
out.flush(); out.flush();
if(request.containsKey("wsdl")){ WSInterface obj = null;
wsdl.write( out ); if(session_enabled){
} if( session.containsKey("SOAPInterface"))
else{ obj = (WSInterface)session.get("SOAPInterface");
WSInterface obj = null; else{
if(session_enabled){ obj = wsDef.newInstance();
if( session.containsKey("SOAPInterface")) session.put("SOAPInterface", obj);
obj = (WSInterface)session.get("SOAPInterface"); }
else{ }
obj = wsDef.newInstance(); else{
session.put("SOAPInterface", obj); if( ws == null )
} ws = wsDef.newInstance();
} obj = ws;
else{ }
if( ws == null )
ws = wsDef.newInstance(); Document document = genSOAPResponse( request.get(""), obj);
obj = ws;
} OutputFormat format = OutputFormat.createCompactFormat();
XMLWriter writer = new XMLWriter( out, format );
Document document = genSOAPResponse( request.get(""), obj); writer.write( document );
OutputFormat format = OutputFormat.createCompactFormat();
XMLWriter writer = new XMLWriter( out, format ); // DEBUG
writer.write( document ); if( logger.isLoggable(Level.FINEST) ){
OutputFormat format2 = OutputFormat.createPrettyPrint();
System.err.println("********** Request");
// DEBUG System.err.println(request);
if( logger.isLoggable(Level.FINEST) ){ System.out.println("********** Response");
OutputFormat format2 = OutputFormat.createPrettyPrint(); writer = new XMLWriter( System.out, format2 );
System.err.println("********** Request"); writer.write( document );
System.err.println(request); }
System.out.println("********** Response");
writer = new XMLWriter( System.out, format2 );
writer.write( document );
}
}
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.WARNING, "Unhandled request", e); logger.log(Level.WARNING, "Unhandled request", e);
} }
@ -299,57 +288,57 @@ public class SOAPHttpPage implements HttpPage{
/** /**
* Generates an return XML Element. This function can * Generates an return XML Element. This function can
* handle return values as XML Elements, WSReturnObject and the * 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 ret is the object that is the return value * @param retObj is the object that is the return value
* @param ename is the name of the parent Element * @param ename is the name of the parent Element
*/ */
private void generateReturnXML(Element root, Object ret, String ename) throws IllegalArgumentException, IllegalAccessException{ private void generateReturnXML(Element root, Object retObj, String ename) throws IllegalArgumentException, IllegalAccessException{
if(ret == null) return; if(retObj == null) return;
if(byte[].class.isAssignableFrom(ret.getClass())){ if(byte[].class.isAssignableFrom(retObj.getClass())){
Element valueE = root.addElement( ename ); Element valueE = root.addElement( ename );
valueE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass())); valueE.addAttribute("type", "xsd:"+ getSOAPClassName(retObj.getClass()));
String tmp = new sun.misc.BASE64Encoder().encode((byte[])ret); String tmp = new sun.misc.BASE64Encoder().encode((byte[])retObj);
tmp = tmp.replaceAll("\\s", ""); tmp = tmp.replaceAll("\\s", "");
valueE.setText(tmp); valueE.setText(tmp);
} }
// return an array // return an array
else if(ret.getClass().isArray()){ else if(retObj.getClass().isArray()){
Element array = root.addElement( (ename.equals("element") ? "Array" : ename) ); Element array = root.addElement( (ename.equals("element") ? "Array" : ename) );
String arrayType = "xsd:"+getClassSOAPName(ret.getClass()); String arrayType = "xsd:"+ getSOAPClassName(retObj.getClass());
arrayType = arrayType.replaceFirst("\\[\\]", "["+Array.getLength(ret)+"]"); arrayType = arrayType.replaceFirst("\\[\\]", "["+Array.getLength(retObj)+"]");
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(ret) ;i++){ for(int i=0; i<Array.getLength(retObj) ;i++){
generateReturnXML(array, Array.get(ret, i), "element"); generateReturnXML(array, Array.get(retObj, i), "element");
} }
} }
else{ else{
Element objectE = root.addElement( ename ); Element objectE = root.addElement( ename );
if(ret instanceof Element) if(retObj instanceof Element)
objectE.add( (Element)ret ); objectE.add( (Element)retObj );
else if(ret instanceof WSReturnObject){ else if(retObj instanceof WSReturnObject){
Field[] fields = ret.getClass().getFields(); Field[] fields = retObj.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(ret), name); generateReturnXML(objectE, fields[i].get(retObj), name);
} }
} }
else { else {
objectE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass())); objectE.addAttribute("type", "xsd:"+ getSOAPClassName(retObj.getClass()));
objectE.addText( ""+ret ); objectE.addText( ""+retObj );
} }
} }
} }
public static String getClassSOAPName(Class<?> c){ public 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";

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2014 Ziver
*
* 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.zutil.net.ws.rest;
import zutil.net.http.HttpPage;
import zutil.net.http.HttpPrintStream;
import java.util.Map;
/**
* User: Ziver
*/
public class RestHttpPage implements HttpPage {
@Override
public void respond(HttpPrintStream out,
Map<String, String> client_info,
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request) {
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014 Ziver
*
* 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.parser.wsdl;
import zutil.net.http.HttpPage;
import zutil.net.http.HttpPrintStream;
import zutil.net.ws.WebServiceDef;
import java.util.Map;
/**
* User: Ziver
*/
public class WSDLHttpPage implements HttpPage {
/** The WSDL document **/
private WSDLWriter wsdl;
public WSDLHttpPage( WebServiceDef wsDef ){
wsdl = new WSDLWriter( wsDef );
}
public void respond(HttpPrintStream out,
Map<String, String> client_info,
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request) {
out.setHeader("Content-Type", "text/xml");
wsdl.write( out );
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014 Ziver
*
* 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.parser.wsdl;
import org.dom4j.Element;
import zutil.net.ws.WSMethodDef;
/**
* This interface defines a WSDL Service type.
*
* User: Ziver
*/
public abstract class WSDLService {
/** The URL of this service **/
private String url;
public WSDLService(String url){
this.url = url;
}
public String getServiceAddress(){
return url;
}
public abstract String getServiceType();
public abstract void generateBinding(Element definitions);
public abstract void generateOperation(Element definitions, WSMethodDef method);
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2014 Ziver
*
* 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.parser.wsdl;
import org.dom4j.Element;
import zutil.net.ws.WSMethodDef;
/**
* User: Ziver
*/
public class WSDLServiceSOAP extends WSDLService{
public WSDLServiceSOAP(String url){
super(url);
}
@Override
public String getServiceType() { return "soap"; }
@Override
public void generateBinding(Element definitions) {
// definitions -> binding -> soap:binding
Element soap_binding = definitions.addElement("soap:binding");
soap_binding.addAttribute("style", "rpc");
soap_binding.addAttribute("transport", "http://schemas.xmlsoap.org/soap/http");
}
@Override
public void generateOperation(Element definitions, WSMethodDef method) {
// definitions -> binding -> operation
Element operation = definitions.addElement("wsdl:operation");
operation.addAttribute("name", method.getName());
// definitions -> binding -> operation -> soap:operation
Element soap_operation = operation.addElement("soap:operation");
soap_operation.addAttribute("soapAction", method.getNamespace());
//*************************** Input
// definitions -> binding -> operation -> input
Element input = operation.addElement("wsdl:input");
// definitions -> binding -> operation -> input -> body
Element input_body = input.addElement("soap:body");
input_body.addAttribute("use", "literal");
input_body.addAttribute("namespace", method.getNamespace());
//*************************** output
if( method.getOutputCount() > 0 ){
// definitions -> binding -> operation -> output
Element output = operation.addElement("wsdl:output");
// definitions -> binding -> operation -> input -> body
Element output_body = output.addElement("soap:body");
output_body.addAttribute("use", "literal");
output_body.addAttribute("namespace", method.getNamespace());
}
}
}

View file

@ -22,19 +22,11 @@
package zutil.parser.wsdl; package zutil.parser.wsdl;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.io.OutputFormat; import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter; import org.dom4j.io.XMLWriter;
import zutil.io.StringOutputStream; import zutil.io.StringOutputStream;
import zutil.net.ws.WSMethodDef; import zutil.net.ws.WSMethodDef;
import zutil.net.ws.WSParameterDef; import zutil.net.ws.WSParameterDef;
@ -42,16 +34,33 @@ import zutil.net.ws.WSReturnObject;
import zutil.net.ws.WSReturnObject.WSValueName; import zutil.net.ws.WSReturnObject.WSValueName;
import zutil.net.ws.WebServiceDef; import zutil.net.ws.WebServiceDef;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.ArrayList;
public class WSDLWriter{ public class WSDLWriter{
/** Current Web service definition ***/
private WebServiceDef ws; private WebServiceDef ws;
/** Cache of generated WSDL **/
private String cache; private String cache;
/** A list of services **/
private ArrayList<WSDLService> services;
public WSDLWriter( WebServiceDef ws ){ public WSDLWriter( WebServiceDef ws ){
this.services = new ArrayList<WSDLService>();
this.ws = ws; this.ws = ws;
} }
/**
* Add a service to be published with the WSDL
*/
public void addService(WSDLService serv){
cache = null;
services.add(serv);
}
public void write( PrintStream out ) { public void write( PrintStream out ) {
out.print(generate()); out.print(generate());
@ -223,47 +232,15 @@ public class WSDLWriter{
binding.addAttribute("name", ws.getName()+"Binding"); binding.addAttribute("name", ws.getName()+"Binding");
binding.addAttribute("type", "tns:"+ws.getName()+"PortType"); binding.addAttribute("type", "tns:"+ws.getName()+"PortType");
generateSOAPOBinding(binding); for(WSDLService serv : services){
serv.generateBinding(binding);
for(WSMethodDef method : ws.getMethods()){ for(WSMethodDef method : ws.getMethods()){
generateSOAPOperation(binding, method); serv.generateOperation(binding, method);
} }
}
} }
private void generateSOAPOBinding(Element definitions){
// definitions -> binding -> soap:binding
Element soap_binding = definitions.addElement("soap:binding");
soap_binding.addAttribute("style", "rpc");
soap_binding.addAttribute("transport", "http://schemas.xmlsoap.org/soap/http");
}
private void generateSOAPOperation(Element definitions, WSMethodDef method){
// definitions -> binding -> operation
Element operation = definitions.addElement("wsdl:operation");
operation.addAttribute("name", method.getName());
// definitions -> binding -> operation -> soap:operation
Element soap_operation = operation.addElement("soap:operation");
soap_operation.addAttribute("soapAction", method.getNamespace());
//*************************** Input
// definitions -> binding -> operation -> input
Element input = operation.addElement("wsdl:input");
// definitions -> binding -> operation -> input -> body
Element input_body = input.addElement("soap:body");
input_body.addAttribute("use", "literal");
input_body.addAttribute("namespace", method.getNamespace());
//*************************** output
if( method.getOutputCount() > 0 ){
// definitions -> binding -> operation -> output
Element output = operation.addElement("wsdl:output");
// definitions -> binding -> operation -> input -> body
Element output_body = output.addElement("soap:body");
output_body.addAttribute("use", "literal");
output_body.addAttribute("namespace", method.getNamespace());
}
}
private void generateService(Element parent){ private void generateService(Element parent){
// definitions -> service // definitions -> service
@ -275,9 +252,11 @@ public class WSDLWriter{
port.addAttribute("name", ws.getName()+"Port"); port.addAttribute("name", ws.getName()+"Port");
port.addAttribute("binding", "tns:"+ws.getName()+"Binding"); port.addAttribute("binding", "tns:"+ws.getName()+"Binding");
// definitions -> service-> port -> address for(WSDLService serv : services){
Element address = port.addElement("soap:address"); // definitions -> service-> port -> address
address.addAttribute("location", null); Element address = port.addElement(serv.getServiceType()+":address");
address.addAttribute("location", serv.getServiceAddress());
}
} }
/** /**