butek 02/05/21 08:43:02 Modified: java/src/org/apache/axis/client Service.java java/src/org/apache/axis/wsdl/toJava JavaServiceImplWriter.java Added: java/src/org/apache/axis/utils WSDLUtils.java java/test/dynamic PackageTests.java ServiceGetPort.java Log: I've added a bit of JAX-RPC implementation. JAX-RPC says getPort can return either a generated stub or a dynamic proxy. We just returned the dyamic proxy. But sometimes we have enough info to return a generated stub, if it's available. So now we try to return the generated stub where we can and, if it fails, only then return the dynamic proxy. This change needed a utility-like method that was in JavaServiceImplWriter: getAddressFromPort. This method doesn't quite fit into any utility class we have, so I created a new one - WSDLUtils - for WSDL4J utility methods. A fair bit of what's in the Java writers COULD be put into this class, but for now getAddressFromPort is the only thing in there. I've also written a simple test to make sure the generated stub is returned when it's available. Revision Changes Path 1.53 +56 -9 xml-axis/java/src/org/apache/axis/client/Service.java Index: Service.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/client/Service.java,v retrieving revision 1.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- Service.java 17 May 2002 19:09:34 -0000 1.52 +++ Service.java 21 May 2002 15:43:02 -0000 1.53 @@ -60,6 +60,7 @@ import org.apache.axis.EngineConfiguration; import org.apache.axis.configuration.DefaultEngineConfigurationFactory; import org.apache.axis.utils.JavaUtils; +import org.apache.axis.utils.WSDLUtils; import org.apache.axis.utils.XMLUtils; import org.w3c.dom.Document; @@ -81,14 +82,16 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.net.URL; import java.rmi.Remote; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.Map; -import java.lang.reflect.Proxy; /** * Axis' JAXRPC Dynamic Invoation Interface implementation of the Service @@ -279,23 +282,67 @@ } /** - * Not implemented yet + * Return either an instance of a generated stub, if it can be + * found, or a dynamic proxy for the given proxy interface. * - * @param portName ... - * @param proxyInterface ... - * @return java.rmi.Remote ... + * @param portName The name of the service port + * @param proxyInterface The Remote object returned by this + * method will also implement the given proxyInterface + * @return java.rmi.Remote The stub implementation. * @throws ServiceException If there's an error */ public Remote getPort(QName portName, Class proxyInterface) throws ServiceException { - return getPort(null, portName, proxyInterface); + // First, try to find a generated stub. If that + // returns null, then find a dynamic stub. + Remote stub = getGeneratedStub(portName, proxyInterface); + return stub != null ? stub : getPort(null, portName, proxyInterface); } /** - * Not implemented yet + * With the proxyInterface and the service's portName, we have + * ALMOST enough info to find a generated stub. The generated + * stub is named after the binding, which we can get from the + * service's port. This binding is likely in the same namespace + * (ie, package) that the proxyInterface is in. So try to find + * and instantiate <proxyInterfacePackage>.<bindingName>Stub. + * If it doesn't exist, return null. + */ + private Remote getGeneratedStub(QName portName, Class proxyInterface) { + try { + String pkg = proxyInterface.getName(); + pkg = pkg.substring(0, pkg.lastIndexOf('.')); + Port port = wsdlService.getPort(portName.getLocalPart()); + String binding = port.getBinding().getQName().getLocalPart(); + ClassLoader classLoader = + Thread.currentThread().getContextClassLoader(); + Class stubClass = classLoader.loadClass( + pkg + "." + binding + "Stub"); + if (proxyInterface.isAssignableFrom(stubClass)) { + Class[] formalArgs = {javax.xml.rpc.Service.class}; + Object[] actualArgs = {this}; + Constructor ctor = stubClass.getConstructor(formalArgs); + Stub stub = (Stub) ctor.newInstance(actualArgs); + stub._setProperty( + Stub.ENDPOINT_ADDRESS_PROPERTY, + WSDLUtils.getAddressFromPort(port)); + return (Remote) stub; + } + else { + return null; + } + } + catch (Throwable t) { + return null; + } + } // getGeneratedStub + + /** + * Return a dynamic proxy for the given proxy interface. * - * @param proxyInterface ... - * @return java.rmi.Remote ... + * @param proxyInterface The Remote object returned by this + * method will also implement the given proxyInterface + * @return java.rmi.Remote The stub implementation * @throws ServiceException If there's an error */ public Remote getPort(Class proxyInterface) throws ServiceException { 1.25 +24 -253 xml-axis/java/src/org/apache/axis/utils/WSDLUtils.java 1.14 +2 -23 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaServiceImplWriter.java Index: JavaServiceImplWriter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaServiceImplWriter.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- JavaServiceImplWriter.java 17 May 2002 19:09:33 -0000 1.13 +++ JavaServiceImplWriter.java 21 May 2002 15:43:02 -0000 1.14 @@ -60,8 +60,6 @@ import java.net.URL; import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Vector; @@ -69,9 +67,8 @@ import javax.wsdl.Port; import javax.wsdl.Service; -import javax.wsdl.extensions.soap.SOAPAddress; - import org.apache.axis.utils.JavaUtils; +import org.apache.axis.utils.WSDLUtils; import org.apache.axis.utils.XMLUtils; import org.apache.axis.wsdl.symbolTable.BindingEntry; @@ -169,14 +166,13 @@ } // Get endpoint address and validate it - String address = getAddressFromPort(p); + String address = WSDLUtils.getAddressFromPort(p); if (address == null) { // now what? throw new IOException(JavaUtils.getMessage("emitFail02", portName, className)); } try { -// URL ep = new URL(address); new URL(address); } catch (MalformedURLException e) { @@ -259,22 +255,5 @@ pw.println("}"); pw.close(); } // writeFileBody - - /** - * Return the endpoint address from a <soap:address location="..."> tag - */ - private String getAddressFromPort(Port p) { - // Get the endpoint for a port - List extensibilityList = p.getExtensibilityElements(); - for (ListIterator li = extensibilityList.listIterator(); li.hasNext();) { - Object obj = li.next(); - if (obj instanceof SOAPAddress) { - return XMLUtils.xmlEncodeString( - ((SOAPAddress) obj).getLocationURI()); - } - } - // didn't find it - return null; - } // getAddressFromPort } // class JavaServiceImplWriter 1.1 xml-axis/java/test/dynamic/PackageTests.java Index: PackageTests.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Axis" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package test.dynamic; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test package for faults * * @author Mark Roder <[EMAIL PROTECTED]> */ public class PackageTests extends TestCase { public PackageTests(String name) { super(name); } public static Test suite() throws Exception { TestSuite suite = new TestSuite(); suite.addTestSuite(ServiceGetPort.class); return suite; } } 1.1 xml-axis/java/test/dynamic/ServiceGetPort.java Index: ServiceGetPort.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Axis" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package test.dynamic; import java.net.URL; import java.rmi.Remote; import javax.xml.rpc.namespace.QName; import javax.xml.rpc.Service; import javax.xml.rpc.ServiceFactory; import junit.framework.TestCase; import samples.addr.AddressBook; import samples.addr.AddressBookSOAPBindingStub; /** * This class tests Fault deserialization. * * @author Sam Ruby ([EMAIL PROTECTED]) */ public class ServiceGetPort extends TestCase { public ServiceGetPort(String name) { super(name); } // ctor public void testGetGeneratedStub() throws Exception { Service service = ServiceFactory.newInstance().createService( new URL("file:samples/addr/AddressBook.wsdl"), new QName("urn:AddressFetcher2", "AddressBookService")); QName portName = new QName("urn:AddressFetcher2", "AddressBook"); Remote stub = service.getPort(portName, AddressBook.class); assertTrue("Stub should be an instance of AddressBookSOAPBindingStub; instead, it is " + stub.getClass().getName(), stub instanceof AddressBookSOAPBindingStub); } // testGetGeneratedStub }