From a2b6be1f35922a300f6fbd9d717e64d99359050a Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Wed, 14 Sep 2011 20:30:06 +0000 Subject: [PATCH] Improved the Web service classes, needs to be tested RESOLVED - #92 http://bugs.koc.se/view.php?id=92 --- src/zutil/io/StringOutputStream.java | 11 + src/zutil/net/http/soap/SOAPHttpPage.java | 668 +++--------------- src/zutil/net/upnp/services/BrowseRetObj.java | 5 +- .../upnp/services/UPnPContentDirectory.java | 4 +- src/zutil/net/ws/WSInterface.java | 4 +- src/zutil/net/ws/WSMethodDef.java | 125 +++- src/zutil/net/ws/WSObject.java | 77 -- src/zutil/net/ws/WSParameterDef.java | 24 +- ...turnValueList.java => WSReturnObject.java} | 36 +- src/zutil/net/ws/WebServiceDef.java | 45 +- src/zutil/parser/wsdl/WSDLWriter.java | 131 ++-- src/zutil/test/SOAPTest.java | 81 +-- src/zutil/test/UPnPServerTest.java | 7 +- 13 files changed, 401 insertions(+), 817 deletions(-) delete mode 100644 src/zutil/net/ws/WSObject.java rename src/zutil/net/ws/{WSReturnValueList.java => WSReturnObject.java} (76%) diff --git a/src/zutil/io/StringOutputStream.java b/src/zutil/io/StringOutputStream.java index 243592f..4009650 100644 --- a/src/zutil/io/StringOutputStream.java +++ b/src/zutil/io/StringOutputStream.java @@ -55,6 +55,17 @@ public class StringOutputStream extends OutputStream{ buffer.append( new String(b, off, len) ); } + /** + * Same as {@link clear()} + */ + @Override + public void close() { + clear(); + } + + /** + * Clears the String buffer + */ public void clear(){ buffer = new StringBuilder(); } diff --git a/src/zutil/net/http/soap/SOAPHttpPage.java b/src/zutil/net/http/soap/SOAPHttpPage.java index c84f0b1..6193520 100644 --- a/src/zutil/net/http/soap/SOAPHttpPage.java +++ b/src/zutil/net/http/soap/SOAPHttpPage.java @@ -21,44 +21,13 @@ ******************************************************************************/ package zutil.net.http.soap; -import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import javax.wsdl.Binding; -import javax.wsdl.BindingInput; -import javax.wsdl.BindingOperation; -import javax.wsdl.BindingOutput; -import javax.wsdl.Definition; -import javax.wsdl.Fault; -import javax.wsdl.Import; -import javax.wsdl.Input; -import javax.wsdl.Message; -import javax.wsdl.Operation; -import javax.wsdl.Output; -import javax.wsdl.Part; -import javax.wsdl.Port; -import javax.wsdl.PortType; -import javax.wsdl.Service; -import javax.wsdl.WSDLException; -import javax.wsdl.extensions.soap.SOAPAddress; -import javax.wsdl.extensions.soap.SOAPBinding; -import javax.wsdl.extensions.soap.SOAPBody; -import javax.wsdl.extensions.soap.SOAPHeader; -import javax.wsdl.extensions.soap.SOAPOperation; -import javax.wsdl.factory.WSDLFactory; -import javax.wsdl.xml.WSDLWriter; -import javax.xml.namespace.QName; - import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; @@ -68,20 +37,16 @@ import org.dom4j.io.XMLWriter; import org.xml.sax.SAXException; import zutil.converters.Converter; -import zutil.io.StringOutputStream; import zutil.log.LogUtil; import zutil.net.http.HttpPage; import zutil.net.http.HttpPrintStream; import zutil.net.ws.WSInterface; -import zutil.net.ws.WSObject; -import zutil.net.ws.WSReturnValueList; -import zutil.net.ws.WSInterface.WSDocumentation; -import zutil.net.ws.WSInterface.WSParamDocumentation; -import zutil.net.ws.WSObject.WSFieldName; - -import com.ibm.wsdl.extensions.PopulatedExtensionRegistry; -import com.ibm.wsdl.extensions.soap.SOAPConstants; -import com.sun.org.apache.xerces.internal.dom.DocumentImpl; +import zutil.net.ws.WSMethodDef; +import zutil.net.ws.WSParameterDef; +import zutil.net.ws.WSReturnObject; +import zutil.net.ws.WSReturnObject.WSValueName; +import zutil.net.ws.WebServiceDef; +import zutil.parser.wsdl.WSDLWriter; /** * This is an HTTPPage for the HTTPServer that @@ -118,135 +83,20 @@ import com.sun.org.apache.xerces.internal.dom.DocumentImpl; public class SOAPHttpPage implements HttpPage{ public static final Logger logger = LogUtil.getLogger(); - // valid methods for this soap page - private HashMap methods; - // contains an method and the names for the parameters - private class MethodCache{ - String[] paramName; - boolean[] paramOptional; - String[] returnName; - Class[] returnClass; - Method method; - boolean header; - - MethodCache(Method m){ - method = m; - paramName = new String[method.getParameterTypes().length]; - paramOptional = new boolean[method.getParameterTypes().length]; - header = false; - - Class tmp = m.getReturnType(); - if( WSReturnValueList.class.isAssignableFrom( tmp )){ - returnName = new String[ tmp.getFields().length ]; - returnClass = new Class[ tmp.getFields().length ]; - } - else if( !tmp.isAssignableFrom( void.class )){ - returnName = new String[1]; - returnClass = new Class[1]; - } - else{ - returnName = new String[0]; - returnClass = new Class[0]; - } - } - } - // The object that the functions will be invoked from - private WSInterface interf; - // The WSDL document - private Definition wsdl; - // The WSDL Type part - private Document wsdlType; - // the URL to this soap page - private String url; - // Session enabled + /** The object that the functions will be invoked from **/ + private WebServiceDef wsDef; + /** This instance of the web service class is used if session is disabled **/ + private WSInterface ws; + /** The WSDL document **/ + private WSDLWriter wsdl; + /** Session enabled **/ private boolean session_enabled; - public SOAPHttpPage(String url, WSInterface interf) throws WSDLException{ - //if(!SOAPInterface.class.isAssignableFrom(interf) ) - // throw new ClassCastException("Class does not implement SOAPInterface!"); - this.url = url; - this.interf = interf; + public SOAPHttpPage( WebServiceDef wsDef ){ + this.wsDef = wsDef; this.session_enabled = false; - methods = new HashMap(); - for(Method m : interf.getClass().getDeclaredMethods()){ - // check for public methods - if((m.getModifiers() & Modifier.PUBLIC) > 0 && - !m.isAnnotationPresent(WSInterface.WSDisabled.class)){ - MethodCache chasch = new MethodCache(m); - StringBuffer tmp = new StringBuffer(m.getName()+"("); - - // Get the parameter names - Annotation[][] paramAnnotation = m.getParameterAnnotations(); - - for(int i=0; i "); - - // the return parameter name - WSInterface.WSReturnName returnName = m.getAnnotation(WSInterface.WSReturnName.class); - if( WSReturnValueList.class.isAssignableFrom( m.getReturnType() ) ){ - Class retClass = m.getReturnType(); - for(int i=0; i0 ){ - if(returnName != null) chasch.returnName[0] = returnName.value(); - else chasch.returnName[0] = "return"; - chasch.returnClass[0] = m.getReturnType(); - tmp.append(chasch.returnClass[0].getSimpleName()+" "+chasch.returnName[0]); - } - - // SOAP header? - if(m.getAnnotation(WSInterface.WSHeader.class) != null) - chasch.header = true; - - // save in HashMap - logger.info("New SOAP Method Registered: "+tmp); - methods.put(m.getName(), chasch); - } - } - - generateWSDL(); - - if(logger.isLoggable(Level.INFO)){ - try { - // WSDL - StringOutputStream out = new StringOutputStream(); - WSDLFactory factory = WSDLFactory.newInstance(); - WSDLWriter writer = factory.newWSDLWriter(); - writer.writeWSDL(wsdl, out); - logger.info(out.toString()); - // WSDL Type - out.clear(); - OutputFormat format = OutputFormat.createPrettyPrint(); - XMLWriter xmlWriter = new XMLWriter( out, format ); - xmlWriter.write( wsdlType ); - logger.info(out.toString()); - } catch (Exception e) { - e.printStackTrace(); - } - } + wsdl = new WSDLWriter( wsDef ); } /** @@ -260,6 +110,14 @@ public class SOAPHttpPage implements HttpPage{ this.session_enabled = enabled; } + /** + * Sets the web service object to the specified one. + * Only used when session is disabled + */ + public void setObject(WSInterface obj) { + this.ws = obj; + } + public void respond(HttpPrintStream out, Map client_info, @@ -272,13 +130,7 @@ public class SOAPHttpPage implements HttpPage{ out.flush(); if(request.containsKey("wsdl")){ - WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter(); - writer.writeWSDL(wsdl, out); - } - else if(request.containsKey("type")){ - OutputFormat format = OutputFormat.createPrettyPrint(); - XMLWriter writer = new XMLWriter( out, format ); - writer.write( wsdlType ); + wsdl.write( out ); } else{ WSInterface obj = null; @@ -286,12 +138,14 @@ public class SOAPHttpPage implements HttpPage{ if( session.containsKey("SOAPInterface")) obj = (WSInterface)session.get("SOAPInterface"); else{ - obj = interf.getClass().newInstance(); + obj = wsDef.newInstance(); session.put("SOAPInterface", obj); } } else{ - obj = interf; + if( ws == null ) + ws = wsDef.newInstance(); + obj = ws; } Document document = genSOAPResponse( request.get(""), obj); @@ -302,12 +156,14 @@ public class SOAPHttpPage implements HttpPage{ // DEBUG - OutputFormat format2 = OutputFormat.createPrettyPrint(); - System.err.println("********** Request"); - System.err.println(request); - System.out.println("********** Response"); - writer = new XMLWriter( System.out, format2 ); - writer.write( document ); + if( logger.isLoggable(Level.FINEST) ){ + OutputFormat format2 = OutputFormat.createPrettyPrint(); + System.err.println("********** Request"); + System.err.println(request); + System.out.println("********** Response"); + writer = new XMLWriter( System.out, format2 ); + writer.write( document ); + } } } catch (Exception e) { @@ -317,16 +173,18 @@ public class SOAPHttpPage implements HttpPage{ /** * Generates a soap response for the given XML - * @param xml is the XML request - * @return a Document with the response + * + * @param xml is the XML request + * @return a Document with the response */ public Document genSOAPResponse(String xml){ try { - WSInterface o = null; - if(session_enabled) o = interf.getClass().newInstance(); - else o = interf; + WSInterface obj = null; + if( ws == null ) + ws = wsDef.newInstance(); + obj = ws; - return genSOAPResponse(xml, o ); + return genSOAPResponse(xml, obj ); } catch (Exception e) { logger.log(Level.WARNING, "Exception in SOAP generation", e); } @@ -380,8 +238,8 @@ public class SOAPHttpPage implements HttpPage{ /** * Converts an String XML to an Element * - * @param msg is the string XML - * @return the XML root Element + * @param msg is the string XML + * @return the XML root Element */ private Element getXMLRoot(String xml) throws Exception { if(xml != null && !xml.isEmpty()){ @@ -392,50 +250,44 @@ public class SOAPHttpPage implements HttpPage{ } /** - * Takes an XML Element and invokes all the - * Child Elements as methods. + * Takes an XML Element and invokes all the it's child elements as methods. * - * @param obj is the object that the methods will be called from - * @param requestRoot is the Element where the children lies - * @param responseRoot is the root element of the response + * @param obj is the object that the methods will be called from + * @param requestRoot is the Element where the children lies + * @param responseRoot is the root element of the response */ @SuppressWarnings("unchecked") private void prepareInvoke(WSInterface obj, Element requestRoot, Element responseRoot) throws Throwable{ Iterator it = requestRoot.elementIterator(); while( it.hasNext() ){ Element e = it.next(); - if(methods.containsKey(e.getQName().getName())){ - MethodCache m = methods.get(e.getQName().getName()); - Object[] params = new Object[m.paramName.length]; + if( wsDef.hasMethod( e.getQName().getName()) ){ + WSMethodDef m = wsDef.getMethod( e.getQName().getName() ); + Object[] params = new Object[ m.getInputCount() ]; // Get the parameter values - for(int i=0; i0 ){ - WSInterface.WSNamespace namespace = m.method.getAnnotation(WSInterface.WSNamespace.class); + if( m.getOutputCount()>0 ){ Element response = responseRoot.addElement(""); - if( namespace != null ) - response.addNamespace("m", namespace.value()); - else - response.addNamespace("m", url+""+m.method.getName()); - response.setName("m:"+m.method.getName()+"Response"); - if( ret instanceof WSReturnValueList ){ - Field[] f = ret.getClass().getFields(); - for(int i=0; i c){ + public static String getClassSOAPName(Class c){ Class cTmp = getClass(c); if(byte[].class.isAssignableFrom(c)){ return "base64Binary"; } - else if( WSObject.class.isAssignableFrom(cTmp) ){ + else if( WSReturnObject.class.isAssignableFrom(cTmp) ){ return c.getSimpleName(); } else{ @@ -535,343 +367,7 @@ public class SOAPHttpPage implements HttpPage{ } } - //******************************************************** - //********* WSDL Generation ************************* - - /** - * Generates an WSDL document for the class - * - * @throws WSDLException - */ - private void generateWSDL() throws WSDLException{ - ArrayList> types = new ArrayList>(); - - String tns = url+"?wsdl"; - String xsd = "http://www.w3.org/2001/XMLSchema"; - String soap = "http://schemas.xmlsoap.org/wsdl/soap/"; - String wsdln = "http://schemas.xmlsoap.org/wsdl/"; - String td = url+"?type"; - - PopulatedExtensionRegistry extReg = new PopulatedExtensionRegistry(); - WSDLFactory factory = WSDLFactory.newInstance(); - String portTypeName = this.interf.getClass().getSimpleName()+"PortType"; - - wsdl = factory.newDefinition(); - wsdl.setQName(new QName(tns, this.interf.getClass().getSimpleName())); - wsdl.setTargetNamespace(tns); - wsdl.addNamespace("tns", tns); - wsdl.addNamespace("xsd", xsd); - wsdl.addNamespace("soap", soap); - wsdl.addNamespace("wsdl", wsdln); - wsdl.addNamespace("td", td); - - Message exception = wsdl.createMessage(); - exception.setQName(new QName(tns, "exception")); - exception.setUndefined(true); - Part epart = wsdl.createPart(); - epart.setName("message"); - epart.setTypeName(new QName(xsd, "string")); - exception.addPart(epart); - wsdl.addMessage(exception); - - Message empty = wsdl.createMessage(); - empty.setQName(new QName(tns, "empty")); - empty.setUndefined(false); - epart = wsdl.createPart(); - epart.setName("empty"); - epart.setTypeName(new QName(td, "empty")); - empty.addPart(epart); - wsdl.addMessage(empty); - - // Types import - Import imp = wsdl.createImport(); - imp.setNamespaceURI(td); - imp.setLocationURI(td); - wsdl.addImport(imp); - - // PortType - PortType portType = wsdl.createPortType(); - portType.setQName(new QName(tns, portTypeName)); - portType.setUndefined(false); - for(MethodCache m : methods.values()){ - Operation operation = wsdl.createOperation(); - //********* Request Messages - if(m.paramName.length > 0){ - Message msgIn = wsdl.createMessage(); - msgIn.setQName(new QName(tns, m.method.getName()+"Request")); - msgIn.setUndefined(false); - - //***** Documentation - WSParamDocumentation tmpParamDoc = m.method.getAnnotation(WSInterface.WSParamDocumentation.class); - if(tmpParamDoc != null){ - org.w3c.dom.Document xmldoc= new DocumentImpl(); - org.w3c.dom.Element paramDoc = xmldoc.createElement("wsdl:documentation"); - paramDoc.setTextContent(tmpParamDoc.value()); - msgIn.setDocumentationElement(paramDoc); - } - - // Parameters - for(int i=0; i0 ){ - Message msgOut = wsdl.createMessage(); - msgOut.setQName(new QName(tns, m.method.getName()+"Response")); - msgOut.setUndefined(false); - - for( int i=0; i retClass = m.returnClass[i]; - //MultiPrintStream.out.println(m.method.getName()+"=>"+m.returnName[i]+"="+retClass); - - // Parts - Part part = wsdl.createPart(); - part.setName( m.returnName[i] ); - msgOut.addPart(part); - - Class cTmp = getClass( retClass ); - // is an binary array - if(byte[].class.isAssignableFrom( retClass )){ - part.setTypeName(new QName(xsd, "base64Binary")); - } - // is an array? - else if( retClass.isArray()){ - part.setTypeName(new QName(td, - "ArrayOf"+getClassSOAPName( retClass ).replaceAll("[\\[\\]]", ""))); - // add to type generation list - if(!types.contains( retClass )) - types.add( retClass ); - } - else if( WSObject.class.isAssignableFrom(cTmp) ){ - // its an SOAPObject - part.setTypeName(new QName(td, getClassSOAPName( retClass ))); - // add to type generation list - if(!types.contains(cTmp)) - types.add(cTmp); - } - else{// its an Object - part.setTypeName(new QName(xsd, getClassSOAPName( retClass ))); - } - } - - wsdl.addMessage(msgOut); - Output output = wsdl.createOutput(); - output.setMessage(msgOut); - operation.setOutput(output); - } - //************* Exceptions - if(m.method.getExceptionTypes().length <= 0){ - Fault fault = wsdl.createFault(); - fault.setMessage(exception); - operation.addFault(fault); - } - //************* Operations - operation.setName(m.method.getName()); - operation.setUndefined(false); - - //***** Documentation - WSDocumentation tmpDoc = m.method.getAnnotation(WSInterface.WSDocumentation.class); - if(tmpDoc != null){ - // - org.w3c.dom.Document xmldoc= new DocumentImpl(); - org.w3c.dom.Element doc = xmldoc.createElement("wsdl:documentation"); - doc.setTextContent(tmpDoc.value()); - operation.setDocumentationElement(doc); - } - - portType.addOperation(operation); - } - wsdl.addPortType(portType); - - // Binding - Binding binding = wsdl.createBinding(); - binding.setQName(new QName(tns, interf.getClass().getSimpleName()+"Binding")); - binding.setPortType(portType); - binding.setUndefined(false); - - SOAPBinding soapBinding = (SOAPBinding)extReg.createExtension(Binding.class, SOAPConstants.Q_ELEM_SOAP_BINDING); - soapBinding.setStyle("rpc"); - //soapBinding.setRequired(true); - soapBinding.setTransportURI("http://schemas.xmlsoap.org/soap/http"); - binding.addExtensibilityElement(soapBinding); - - for(MethodCache m : methods.values()){ - BindingOperation operation = wsdl.createBindingOperation(); - operation.setName(m.method.getName()); - - SOAPOperation soapOperation = (SOAPOperation)extReg.createExtension(BindingOperation.class, SOAPConstants.Q_ELEM_SOAP_OPERATION); - soapOperation.setSoapActionURI(url+""+m.method.getName()); - operation.addExtensibilityElement(soapOperation); - - // input - BindingInput input = wsdl.createBindingInput(); - // Header - if(m.header){ - SOAPHeader soapHeader = (SOAPHeader)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_HEADER); - soapHeader.setUse("literal"); - soapHeader.setNamespaceURI(url+""+m.method.getName()); - input.addExtensibilityElement(soapHeader); - }// Body - else{ - SOAPBody soapBody = (SOAPBody)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_BODY); - soapBody.setUse("literal"); - soapBody.setNamespaceURI(url+""+m.method.getName()); - input.addExtensibilityElement(soapBody); - } - operation.setBindingInput(input); - - // output - if(!m.method.getReturnType().equals( void.class )){ - BindingOutput output = wsdl.createBindingOutput(); - // Header - if(m.header){ - SOAPHeader soapHeader = (SOAPHeader)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_HEADER); - soapHeader.setUse("literal"); - soapHeader.setNamespaceURI(url+""+m.method.getName()); - output.addExtensibilityElement(soapHeader); - }// Body - else{ - SOAPBody soapBody = (SOAPBody)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_BODY); - soapBody.setUse("literal"); - soapBody.setNamespaceURI(url+""+m.method.getName()); - output.addExtensibilityElement(soapBody); - } - operation.setBindingOutput(output); - } - - binding.addBindingOperation(operation); - } - wsdl.addBinding(binding); - - // Service - Port port = wsdl.createPort(); - port.setName( interf.getClass().getSimpleName()+"Port" ); - port.setBinding(binding); - SOAPAddress addr = (SOAPAddress)extReg.createExtension(Port.class, SOAPConstants.Q_ELEM_SOAP_ADDRESS); - addr.setLocationURI(url); - port.addExtensibilityElement(addr); - - Service ser = wsdl.createService(); - ser.setQName(new QName(tns, interf.getClass().getSimpleName()+"Service")); - ser.addPort(port); - wsdl.addService(ser); - - // generate the complexTypes - generateWSDLType(types); - } - - /** - * This function generates the Type part of the WSDL. - * Should be cabled after generateWSDL has finished. - * - */ - private void generateWSDLType(ArrayList> types){ - wsdlType = DocumentHelper.createDocument(); - Element definitions = wsdlType.addElement( "wsdl:definitions" ); - definitions.addAttribute("targetNamespace", url); - definitions.addNamespace("tns", url+"?type"); - definitions.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); - definitions.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/"); - definitions.addNamespace("SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"); - - Element typeE = definitions.addElement("wsdl:types"); - Element schema = typeE.addElement("xsd:schema"); - schema.addAttribute("targetNamespace", url+"?type"); - - // empty type - Element empty = schema.addElement("xsd:complexType"); - empty.addAttribute("name", "empty"); - empty.addElement("xsd:sequence"); - - for(int n=0; n c = types.get(n); - // Generate Array type - if(c.isArray()){ - Class ctmp = getClass(c); - - Element type = schema.addElement("xsd:complexType"); - type.addAttribute("name", - "ArrayOf"+getClassSOAPName(c).replaceAll("[\\[\\]]", "")); - - /*// .Net can't handle this code - Element complexContent = type.addElement("complexContent"); - - Element restriction = complexContent.addElement("restriction"); - restriction.addAttribute("base", "SOAP-ENC:Array"); - - Element attribute = restriction.addElement("attribute"); - attribute.addAttribute("ref", "SOAP-ENC:arrayType"); - attribute.addAttribute("wsdl:arrayType", "tns:"+getClassSOAPName(c)); - */ - - Element sequence = type.addElement("xsd:sequence"); - - Element element = sequence.addElement("xsd:element"); - element.addAttribute("minOccurs", "0"); - element.addAttribute("maxOccurs", "unbounded"); - element.addAttribute("name", "element"); - element.addAttribute("nillable", "true"); - if(WSObject.class.isAssignableFrom(ctmp)) - element.addAttribute("type", "tns:"+getClassSOAPName(c).replace("[]", "")); - else - element.addAttribute("type", "xsd:"+getClassSOAPName(c).replace("[]", "")); - - if(!types.contains(ctmp)) - types.add(ctmp); - } - // Generate SOAPObject type - else if(WSObject.class.isAssignableFrom(c)){ - Element type = schema.addElement("xsd:complexType"); - type.addAttribute("name", getClassSOAPName(c)); - - Element sequence = type.addElement("xsd:sequence"); - - Field[] fields = c.getFields(); - for(int i=0; i cTmp = getClass(fields[i].getType()); - if(WSObject.class.isAssignableFrom(cTmp)){ - element.addAttribute("type", "tns:"+getClassSOAPName(cTmp)); - if(!types.contains(cTmp)) - types.add(cTmp); - } - else{ - element.addAttribute("type", "xsd:"+getClassSOAPName(fields[i].getType())); - } - // Is the Field optional - if(tmp != null && tmp.optional()) - element.addAttribute("minOccurs", "0"); - } - } - } - } - - private Class getClass(Class c){ + public static Class getClass(Class c){ if(c!=null && c.isArray()){ return getClass(c.getComponentType()); } diff --git a/src/zutil/net/upnp/services/BrowseRetObj.java b/src/zutil/net/upnp/services/BrowseRetObj.java index 3f644bb..4d89ec0 100644 --- a/src/zutil/net/upnp/services/BrowseRetObj.java +++ b/src/zutil/net/upnp/services/BrowseRetObj.java @@ -21,9 +21,10 @@ ******************************************************************************/ package zutil.net.upnp.services; -import zutil.net.ws.WSReturnValueList; +import zutil.net.ws.WSReturnObject; -public class BrowseRetObj extends WSReturnValueList{ + +public class BrowseRetObj extends WSReturnObject{ @WSValueName("Result") public String Result; @WSValueName("NumberReturned") diff --git a/src/zutil/net/upnp/services/UPnPContentDirectory.java b/src/zutil/net/upnp/services/UPnPContentDirectory.java index 0006019..47a3c07 100644 --- a/src/zutil/net/upnp/services/UPnPContentDirectory.java +++ b/src/zutil/net/upnp/services/UPnPContentDirectory.java @@ -33,7 +33,7 @@ import zutil.net.http.HttpPage; import zutil.net.http.HttpPrintStream; import zutil.net.upnp.UPnPService; import zutil.net.ws.WSInterface; -import zutil.net.ws.WSReturnValueList; +import zutil.net.ws.WSReturnObject; /** * Information about a UPNP Service @@ -137,7 +137,7 @@ public class UPnPContentDirectory implements UPnPService, HttpPage, WSInterface } return ret; } - public class BrowseRetObj extends WSReturnValueList{ + public class BrowseRetObj extends WSReturnObject{ @WSValueName("Result") public String Result; @WSValueName("NumberReturned") diff --git a/src/zutil/net/ws/WSInterface.java b/src/zutil/net/ws/WSInterface.java index fdf5241..90f0e11 100644 --- a/src/zutil/net/ws/WSInterface.java +++ b/src/zutil/net/ws/WSInterface.java @@ -121,12 +121,12 @@ public interface WSInterface { public @interface WSHeader { } /** - * Specifies the name space for the method. + * Specifies the name space for method. * * @author Ziver */ @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) + //@Target(ElementType.TYPE) public @interface WSNamespace { String value(); } diff --git a/src/zutil/net/ws/WSMethodDef.java b/src/zutil/net/ws/WSMethodDef.java index fe9be16..51f713d 100644 --- a/src/zutil/net/ws/WSMethodDef.java +++ b/src/zutil/net/ws/WSMethodDef.java @@ -23,14 +23,23 @@ package zutil.net.ws; import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import zutil.net.ws.WSInterface.WSDocumentation; +import zutil.net.ws.WSInterface.WSNamespace; +/** + * This is a web service method definition class + * + * @author Ziver + */ // TODO: Header parameters public class WSMethodDef { + /** The parent web service definition **/ + private WebServiceDef wsDef; /** A list of input parameters **/ private ArrayList inputs; /** A List of return parameters of the method **/ @@ -41,6 +50,8 @@ public class WSMethodDef { private Method method; /** Documentation of the method **/ private String doc; + /** This is the namespace of the method **/ + private String namespace; /** The published name of the method **/ private String name; @@ -49,63 +60,78 @@ public class WSMethodDef { * * @param me is a method in a class that implements WSInterface */ - public WSMethodDef(Method me) { - if(!WSInterface.class.isAssignableFrom(me.getDeclaringClass()) ) + protected WSMethodDef( WebServiceDef wsDef, Method me) { + if( !WSInterface.class.isAssignableFrom(me.getDeclaringClass()) ) throw new ClassCastException("Declaring class does not implement WSInterface!"); + this.wsDef = wsDef; method = me; inputs = new ArrayList(); outputs = new ArrayList(); exceptions = new ArrayList>(); name = method.getName(); - //***** Documentation - WSDocumentation tmpDoc = method.getAnnotation(WSInterface.WSDocumentation.class); + //***** Documentation & Namespace + WSDocumentation tmpDoc = method.getAnnotation( WSDocumentation.class ); if(tmpDoc != null){ doc = tmpDoc.value(); } + WSNamespace tmpSpace = method.getAnnotation( WSNamespace.class ); + if( tmpSpace != null ) + namespace = tmpSpace.value(); + else + namespace = wsDef.getNamespace()+"?#"+name; + //***** Exceptions for( Class exc : method.getExceptionTypes() ){ exceptions.add( exc ); } + //********* Get the input parameter names ********** Annotation[][] paramAnnotation = method.getParameterAnnotations(); - + Class[] inputTypes = method.getParameterTypes(); + for(int i=0; i retClass = method.getReturnType(); Field[] fields = retClass.getFields(); + for(int i=0; i "); first = true; @@ -187,9 +258,9 @@ public class WSMethodDef { first = false; else tmp.append(" ,"); - tmp.append(param.paramClass.getSimpleName()); + tmp.append(param.getParamClass().getSimpleName()); tmp.append(" "); - tmp.append(param.name); + tmp.append(param.getName()); } return tmp.toString(); } diff --git a/src/zutil/net/ws/WSObject.java b/src/zutil/net/ws/WSObject.java deleted file mode 100644 index f301bec..0000000 --- a/src/zutil/net/ws/WSObject.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Ziver Koc - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ -package zutil.net.ws; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This class is used as an return Object for a web service. - * If an class implements this interface then it can return - * multiple values through the SOAPInterface. Example: - *
- * 	private static class TestObject implements WSObject{
- *		@SOAPFieldName("name")
- *		public String name;
- *		@SOAPFieldName("lastname")
- *		public String lastname;
- *
- *		public TestObject(String n, String l){
- *			name = n;
- *			lastname = l;
- *		}
- *	}
- * 
- * - * @author Ziver - * - */ -public interface WSObject{ - /** - * Specifies the name of a field. - * The fields that are available in the service should - * be declared public. - * - * @author Ziver - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface WSFieldName { - String value(); - boolean optional() default false; - } - - /** - * This generates an documentation tag in the - * WSDL for the object type - * - * @author Ziver - */ - /* - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface WSDLDocumentation { - String value(); - }*/ -} diff --git a/src/zutil/net/ws/WSParameterDef.java b/src/zutil/net/ws/WSParameterDef.java index 2dc32e1..d5ae742 100644 --- a/src/zutil/net/ws/WSParameterDef.java +++ b/src/zutil/net/ws/WSParameterDef.java @@ -21,18 +21,30 @@ ******************************************************************************/ package zutil.net.ws; +/** + * This is a web service parameter definition class + * + * @author Ziver + */ public class WSParameterDef{ + /** The parent method **/ + private WSMethodDef mDef; /** The class type of the parameter **/ - protected Class paramClass; + private Class paramClass; /** The web service name of the parameter **/ - protected String name; + private String name; /** Developer documentation **/ - protected String doc; + private String doc; /** If this parameter is optional **/ - protected boolean optional; + private boolean optional; /** Is it an header parameter **/ //boolean header; + protected WSParameterDef( WSMethodDef mDef ){ + this.mDef = mDef; + this.optional = false; + } + public Class getParamClass() { return paramClass; @@ -61,4 +73,8 @@ public class WSParameterDef{ protected void setOptional(boolean optional) { this.optional = optional; } + + public WSMethodDef getMethod(){ + return mDef; + } } diff --git a/src/zutil/net/ws/WSReturnValueList.java b/src/zutil/net/ws/WSReturnObject.java similarity index 76% rename from src/zutil/net/ws/WSReturnValueList.java rename to src/zutil/net/ws/WSReturnObject.java index cdaf108..3ac8bd7 100644 --- a/src/zutil/net/ws/WSReturnValueList.java +++ b/src/zutil/net/ws/WSReturnObject.java @@ -28,16 +28,29 @@ import java.lang.annotation.Target; import java.lang.reflect.Field; /** - * This interface is for returning multiple object. - * All the public fields in the class that implements - * this class will be set as return values. And the - * implementing class will be transparent. + * This class is used as an return Object for a web service. + * If an class implements this interface then it can return + * multiple values through the WSInterface. And the + * implementing class will be transparent. Example: + * + *
+ * 	private static class TestObject implements WSReturnObject{
+ *		@WSValueName("name")
+ *		public String name;
+ *		@WSValueName("lastname")
+ *		public String lastname;
+ *
+ *		public TestObject(String n, String l){
+ *			name = n;
+ *			lastname = l;
+ *		}
+ *	}
+ * 
* * @author Ziver * */ -public class WSReturnValueList { - +public class WSReturnObject{ /** * Method comments for the WSDL. * These comments are put in the operation part of the WSDL @@ -49,15 +62,6 @@ public class WSReturnValueList { String value(); } - /** - * Disables publication of the given field. - * - * @author Ziver - */ - /*@Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public @interface SOAPDisabledValue { }*/ - /** * Annotation that assigns a name to the return value * to the field. @@ -68,6 +72,7 @@ public class WSReturnValueList { @Target(ElementType.FIELD) public @interface WSValueName { String value(); + boolean optional() default false; } @@ -75,4 +80,3 @@ public class WSReturnValueList { return field.get(this); } } - diff --git a/src/zutil/net/ws/WebServiceDef.java b/src/zutil/net/ws/WebServiceDef.java index 8f97208..67e2163 100644 --- a/src/zutil/net/ws/WebServiceDef.java +++ b/src/zutil/net/ws/WebServiceDef.java @@ -27,31 +27,35 @@ import java.util.Collection; import java.util.HashMap; import java.util.Set; -import javax.wsdl.WSDLException; - +/** + * Defines a web service from a class implementing the {@link zutil.net.ws.WSInterface} + * + * @author Ziver + */ public class WebServiceDef { /** A map of methods in this Service **/ private HashMap methods; - /** URL of the Service **/ - //private String url; /** Namespace of the service **/ - //private String namespace; + private String namespace; /** Name of the web service **/ private String name; /** This is the WSInterface class **/ private Class intf; - public WebServiceDef(Class intf) throws WSDLException{ + public WebServiceDef(Class intf){ this.intf = intf; methods = new HashMap(); name = intf.getSimpleName(); + if( intf.getAnnotation( WSInterface.WSNamespace.class ) != null ) + this.namespace = intf.getAnnotation( WSInterface.WSNamespace.class ).value(); + for(Method m : intf.getDeclaredMethods()){ // check for public methods if((m.getModifiers() & Modifier.PUBLIC) > 0 && !m.isAnnotationPresent(WSInterface.WSDisabled.class)){ - WSMethodDef method = new WSMethodDef(m); + WSMethodDef method = new WSMethodDef(this, m); methods.put(method.getName(), method); } } @@ -71,6 +75,22 @@ public class WebServiceDef { return name; } + /** + * @param name is the name of the method + * @return if there is a method by the given name + */ + public boolean hasMethod( String name ){ + return methods.containsKey( name ); + } + + /** + * @param name is the name of the method + * @return the method or null if there is no such method + */ + public WSMethodDef getMethod( String name ){ + return methods.get( name ); + } + /** * @return a Set of all the method names */ @@ -84,4 +104,15 @@ public class WebServiceDef { public Collection getMethods(){ return methods.values(); } + + /** + * @return the namespace of this web service ( usually the URL of the service ) + */ + public String getNamespace(){ + return namespace; + } + + public WSInterface newInstance() throws InstantiationException, IllegalAccessException { + return intf.newInstance(); + } } diff --git a/src/zutil/parser/wsdl/WSDLWriter.java b/src/zutil/parser/wsdl/WSDLWriter.java index 07350bb..85bd106 100644 --- a/src/zutil/parser/wsdl/WSDLWriter.java +++ b/src/zutil/parser/wsdl/WSDLWriter.java @@ -21,10 +21,11 @@ ******************************************************************************/ package zutil.parser.wsdl; +import java.io.IOException; import java.io.OutputStream; +import java.io.PrintStream; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.logging.Logger; import javax.wsdl.Binding; import javax.wsdl.BindingInput; @@ -57,39 +58,71 @@ import com.ibm.wsdl.extensions.PopulatedExtensionRegistry; import com.ibm.wsdl.extensions.soap.SOAPConstants; import com.sun.org.apache.xerces.internal.dom.DocumentImpl; -import zutil.log.LogUtil; +import zutil.io.StringOutputStream; import zutil.net.ws.WSMethodDef; -import zutil.net.ws.WSObject; import zutil.net.ws.WSParameterDef; +import zutil.net.ws.WSReturnObject; +import zutil.net.ws.WSReturnObject.WSValueName; import zutil.net.ws.WebServiceDef; -import zutil.net.ws.WSObject.WSFieldName; public class WSDLWriter{ - private static final Logger logger = LogUtil.getLogger(); private WebServiceDef ws; - private StringBuilder cache; - private OutputStream out; - + private String cache; + private String soapURL; - public void write(WebServiceDef object) { - // TODO Auto-generated method stub + public WSDLWriter( WebServiceDef ws ){ + this.ws = ws; + try { + Definition wsdl = generateWSDL( ); + + StringOutputStream out = new StringOutputStream(); + + javax.wsdl.xml.WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter(); + writer.writeWSDL(wsdl, out); + + //OutputFormat format = OutputFormat.createPrettyPrint(); + //XMLWriter writer = new XMLWriter( out, format ); + //writer.write( wsdlType ); + + this.cache = out.toString(); + out.close(); + } catch (WSDLException e) { + e.printStackTrace(); + } } + + /** + * @param binding adds this binding to the WSDL generation + */ + public void setSOAPAddress( String url ){ + this.soapURL = url; + } + + + + public void write( PrintStream out ) { + out.print( cache ); + } + + public void write( OutputStream out ) throws IOException { + out.write( cache.getBytes() ); + } /** * Generates an WSDL document for the class * * @throws WSDLException */ - private void generateWSDL(String url) throws WSDLException{ + private Definition generateWSDL( ) throws WSDLException { ArrayList> types = new ArrayList>(); - String tns = url+"?wsdl"; + String tns = ws.getNamespace()+"?wsdl"; String xsd = "http://www.w3.org/2001/XMLSchema"; String soap = "http://schemas.xmlsoap.org/wsdl/soap/"; String wsdln = "http://schemas.xmlsoap.org/wsdl/"; - String td = url+"?type"; + String td = ws.getNamespace()+"?type"; PopulatedExtensionRegistry extReg = new PopulatedExtensionRegistry(); WSDLFactory factory = WSDLFactory.newInstance(); @@ -132,10 +165,10 @@ public class WSDLWriter{ PortType portType = wsdl.createPortType(); portType.setQName(new QName(tns, portTypeName)); portType.setUndefined(false); - for(WSMethodDef method : ws.getMethods()){ + for( WSMethodDef method : ws.getMethods() ){ Operation operation = wsdl.createOperation(); //********* Request Messages - if(method.inputCount() > 0){ + if( method.getInputCount() > 0 ){ Message msgIn = wsdl.createMessage(); msgIn.setQName(new QName(tns, method.getName()+"Request")); msgIn.setUndefined(false); @@ -149,10 +182,10 @@ public class WSDLWriter{ } // Parameters - for(WSParameterDef param : method.getInputs()){ + for( WSParameterDef param : method.getInputs() ){ // Parts Part part = wsdl.createPart(); - part.setName(param.getName()); + part.setName( param.getName() ); part.setTypeName(new QName( xsd, getClassSOAPName( param.getParamClass() ))); if( param.isOptional() ) @@ -170,7 +203,7 @@ public class WSDLWriter{ operation.setInput(input); } //********** Response Message - if( method.outputCount() > 0 ){ + if( method.getOutputCount() > 0 ){ Message msgOut = wsdl.createMessage(); msgOut.setQName(new QName(tns, method.getName()+"Response")); msgOut.setUndefined(false); @@ -195,7 +228,7 @@ public class WSDLWriter{ if(!types.contains( paramClass )) types.add( paramClass ); } - else if( WSObject.class.isAssignableFrom(valueClass) ){ + else if( WSReturnObject.class.isAssignableFrom(valueClass) ){ // its an SOAPObject part.setTypeName(new QName(td, getClassSOAPName( paramClass ))); // add to type generation list @@ -252,42 +285,30 @@ public class WSDLWriter{ operation.setName(method.getName()); SOAPOperation soapOperation = (SOAPOperation)extReg.createExtension(BindingOperation.class, SOAPConstants.Q_ELEM_SOAP_OPERATION); - soapOperation.setSoapActionURI(url+""+method.getName()); + soapOperation.setSoapActionURI(method.getNamespace()); operation.addExtensibilityElement(soapOperation); - // input + //********************************* input BindingInput input = wsdl.createBindingInput(); // TODO: Header - /*if(m.header){ - SOAPHeader soapHeader = (SOAPHeader)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_HEADER); - soapHeader.setUse("literal"); - soapHeader.setNamespaceURI(url+""+method.getName()); - input.addExtensibilityElement(soapHeader); - }*/ // Body //else{ SOAPBody soapBody = (SOAPBody)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_BODY); soapBody.setUse("literal"); - soapBody.setNamespaceURI(url+""+method.getName()); + soapBody.setNamespaceURI(method.getNamespace()); input.addExtensibilityElement(soapBody); //} operation.setBindingInput(input); - // output - if( method.outputCount() > 0 ){ + //********************************** output + if( method.getOutputCount() > 0 ){ BindingOutput output = wsdl.createBindingOutput(); // TODO: Header - /*if(m.header){ - SOAPHeader soapHeaderBind = (SOAPHeader)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_HEADER); - soapHeaderBind("literal"); - soapHeaderBind(url+""+method.getName()); - output.addExtensibilityElement(soapHeaderBind); - }*/ // Body //else{ SOAPBody soapBodyBind = (SOAPBody)extReg.createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_BODY); soapBodyBind.setUse("literal"); - soapBodyBind.setNamespaceURI(url+""+method.getName()); + soapBodyBind.setNamespaceURI(method.getNamespace()); output.addExtensibilityElement(soapBodyBind); //} operation.setBindingOutput(output); @@ -297,12 +318,12 @@ public class WSDLWriter{ } wsdl.addBinding(binding); - // Service + //******************* Service Port port = wsdl.createPort(); port.setName( ws.getName()+"Port" ); port.setBinding(binding); SOAPAddress addr = (SOAPAddress)extReg.createExtension(Port.class, SOAPConstants.Q_ELEM_SOAP_ADDRESS); - addr.setLocationURI(url); + addr.setLocationURI( soapURL ); port.addExtensibilityElement(addr); Service ser = wsdl.createService(); @@ -311,7 +332,8 @@ public class WSDLWriter{ wsdl.addService(ser); // generate the complexTypes - generateWSDLType(url, types); + generateWSDLType(types); + return wsdl; } /** @@ -319,18 +341,18 @@ public class WSDLWriter{ * Should be cabled after generateWSDL has finished. * */ - private void generateWSDLType(String url, ArrayList> types){ + private void generateWSDLType(ArrayList> types){ Document wsdlType = DocumentHelper.createDocument(); Element definitions = wsdlType.addElement( "wsdl:definitions" ); - definitions.addAttribute("targetNamespace", url); - definitions.addNamespace("tns", url+"?type"); + definitions.addAttribute("targetNamespace", ws.getNamespace()); + definitions.addNamespace("tns", ws.getNamespace()+"?type"); definitions.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); definitions.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/"); definitions.addNamespace("SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"); Element typeE = definitions.addElement("wsdl:types"); Element schema = typeE.addElement("xsd:schema"); - schema.addAttribute("targetNamespace", url+"?type"); + schema.addAttribute("targetNamespace", ws.getNamespace()+"?type"); // empty type Element empty = schema.addElement("xsd:complexType"); @@ -354,7 +376,7 @@ public class WSDLWriter{ element.addAttribute("maxOccurs", "unbounded"); element.addAttribute("name", "element"); element.addAttribute("nillable", "true"); - if(WSObject.class.isAssignableFrom(ctmp)) + if( WSReturnObject.class.isAssignableFrom(ctmp) ) element.addAttribute("type", "tns:"+getClassSOAPName(c).replace("[]", "")); else element.addAttribute("type", "xsd:"+getClassSOAPName(c).replace("[]", "")); @@ -363,7 +385,7 @@ public class WSDLWriter{ types.add(ctmp); } // Generate SOAPObject type - else if(WSObject.class.isAssignableFrom(c)){ + else if(WSReturnObject.class.isAssignableFrom(c)){ Element type = schema.addElement("xsd:complexType"); type.addAttribute("name", getClassSOAPName(c)); @@ -371,7 +393,7 @@ public class WSDLWriter{ Field[] fields = c.getFields(); for(int i=0; i cTmp = getClass(fields[i].getType()); - if(WSObject.class.isAssignableFrom(cTmp)){ + if( WSReturnObject.class.isAssignableFrom(cTmp) ){ element.addAttribute("type", "tns:"+getClassSOAPName(cTmp)); if(!types.contains(cTmp)) types.add(cTmp); @@ -397,6 +419,11 @@ public class WSDLWriter{ } } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // TODO: FIX THESE ARE DUPLICATES FROM SOAPHttpPage + /////////////////////////////////////////////////////////////////////////////////////////////// + private Class getClass(Class c){ if(c!=null && c.isArray()){ return getClass(c.getComponentType()); @@ -406,17 +433,17 @@ public class WSDLWriter{ private String getClassSOAPName(Class c){ Class cTmp = getClass(c); - if(byte[].class.isAssignableFrom(c)){ + if( byte[].class.isAssignableFrom(c) ){ return "base64Binary"; } - else if( WSObject.class.isAssignableFrom(cTmp) ){ + else if( WSReturnObject.class.isAssignableFrom(cTmp) ){ return c.getSimpleName(); } else{ String ret = c.getSimpleName().toLowerCase(); - if(cTmp == Integer.class) ret = ret.replaceAll("integer", "int"); - else if(cTmp == Character.class)ret = ret.replaceAll("character", "char"); + if( cTmp == Integer.class ) ret = ret.replaceAll("integer", "int"); + else if( cTmp == Character.class ) ret = ret.replaceAll("character", "char"); return ret; } diff --git a/src/zutil/test/SOAPTest.java b/src/zutil/test/SOAPTest.java index 98b1c79..63ef640 100644 --- a/src/zutil/test/SOAPTest.java +++ b/src/zutil/test/SOAPTest.java @@ -21,16 +21,16 @@ ******************************************************************************/ package zutil.test; -import javax.wsdl.WSDLException; - import org.dom4j.Document; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import zutil.net.http.soap.SOAPHttpPage; import zutil.net.ws.WSInterface; -import zutil.net.ws.WSObject; -import zutil.net.ws.WSReturnValueList; +import zutil.net.ws.WSInterface.*; +import zutil.net.ws.WSReturnObject; +import zutil.net.ws.WebServiceDef; +import zutil.parser.wsdl.WSDLWriter; public class SOAPTest { @@ -42,64 +42,65 @@ public class SOAPTest { } public SOAPTest(){ - try { - SOAPHttpPage soap = new SOAPHttpPage("http://test.se:8080/", new SOAPTestClass()); - - // Response - try { - Document document = soap.genSOAPResponse( - "" + - "\n" + - " \n" + - //" \n" + - //" IBM\n" + - //" \n" + - //" \n" + - //" 66\n" + - //" \n" + - " \n" + - " IBM\n" + - " \n" + - " \n" + - ""); - System.out.println( "****************** RESPONSE *********************" ); + WebServiceDef wsDef = new WebServiceDef( SOAPTestClass.class ); + SOAPHttpPage soap = new SOAPHttpPage( wsDef ); + + WSDLWriter wsdl = new WSDLWriter( wsDef ); + wsdl.write(System.out); + + // Response + try { + Document document = soap.genSOAPResponse( + "" + + "\n" + + " \n" + + //" \n" + + //" IBM\n" + + //" \n" + + //" \n" + + //" 66\n" + + //" \n" + + " \n" + + " IBM\n" + + " \n" + + " \n" + + ""); + System.out.println( "****************** RESPONSE *********************" ); - OutputFormat format = OutputFormat.createPrettyPrint(); - XMLWriter writer = new XMLWriter( System.out, format ); - writer.write( document ); + 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) { + System.out.println(); + } catch (Exception e) { e.printStackTrace(); } } - public class SOAPTestClass3 implements WSObject{ + public static class SOAPTestClass3 extends WSReturnObject{ public String lol = "lol11"; public String lol2 = "lol22"; } - public class SOAPTestClass2 implements WSObject{ - @WSFieldName(value="lolz", optional=true) + public static class SOAPTestClass2 extends WSReturnObject{ + @WSValueName(value="lolz") public String lol = "lol1"; - @WSFieldName("lolx") + @WSValueName("lolx") public String lol2 = "lol2"; public byte[] b = new byte[]{0x12, 0x23}; public SOAPTestClass3 l = new SOAPTestClass3(); } - public class SOAPTestRetClass extends WSReturnValueList{ + public static class SOAPTestRetClass extends WSReturnObject{ @WSValueName("retTest") public String lol = "lol1"; public String lol2 = "lol2"; } - public class SOAPTestClass implements WSInterface{ + @WSNamespace("http://test.se:8080/") + public static class SOAPTestClass implements WSInterface{ public SOAPTestClass(){} - + @WSHeader() @WSDocumentation("hello") public void pubZ( diff --git a/src/zutil/test/UPnPServerTest.java b/src/zutil/test/UPnPServerTest.java index 611ea11..e6cbdb4 100644 --- a/src/zutil/test/UPnPServerTest.java +++ b/src/zutil/test/UPnPServerTest.java @@ -32,6 +32,7 @@ import zutil.net.http.soap.SOAPHttpPage; import zutil.net.ssdp.SSDPServer; import zutil.net.upnp.UPnPMediaServer; import zutil.net.upnp.services.UPnPContentDirectory; +import zutil.net.ws.WebServiceDef; public class UPnPServerTest { @@ -40,13 +41,15 @@ public class UPnPServerTest { MultiPrintStream.out.println("UPNP Server running"); UPnPContentDirectory cds = new UPnPContentDirectory(new File("C:\\Users\\Ziver\\Desktop\\lan")); + WebServiceDef ws = new WebServiceDef( UPnPContentDirectory.class ); HttpServer http = new HttpServer("http://192.168.0.60/", 8080); //http.setDefaultPage(upnp); http.setPage("/RootDesc", upnp ); http.setPage("/SCP/ContentDir", cds ); - SOAPHttpPage soap = new SOAPHttpPage("Action/ContentDir", cds); - soap.enableSession(false); + SOAPHttpPage soap = new SOAPHttpPage(ws); + soap.setObject( cds ); + soap.enableSession( false ); http.setPage("/Action/ContentDir", soap ); http.start(); MultiPrintStream.out.println("HTTP Server running");