Return-Path: Delivered-To: apmail-xml-axis-dev-archive@xml.apache.org Received: (qmail 96446 invoked by uid 500); 17 Dec 2002 00:01:37 -0000 Mailing-List: contact axis-dev-help@xml.apache.org; run by ezmlm Precedence: bulk Reply-To: axis-dev@xml.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list axis-dev@xml.apache.org Received: (qmail 96437 invoked by uid 500); 17 Dec 2002 00:01:37 -0000 Delivered-To: apmail-xml-axis-cvs@apache.org Date: 17 Dec 2002 00:01:36 -0000 Message-ID: <20021217000136.91163.qmail@icarus.apache.org> From: dims@apache.org To: xml-axis-cvs@apache.org Subject: cvs commit: xml-axis/java/test/wsdl/jaxrpcdynproxy AddressInOut.wsdl AddressSoapBindingImpl.java JAXRPCDynProxyTestCase.java build.xml X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N dims 2002/12/16 16:01:35 Modified: java/src/org/apache/axis/client AxisClientProxy.java Call.java Service.java Added: java/test/wsdl/jaxrpcdynproxy AddressInOut.wsdl AddressSoapBindingImpl.java JAXRPCDynProxyTestCase.java build.xml Log: Fix for Bug 15183 - [Patch] Dynamic proxy client does not handle inout parameters (handlers) from cchabanois@cognicase.fr (C�dric Chabanois) Revision Changes Path 1.4 +123 -4 xml-axis/java/src/org/apache/axis/client/AxisClientProxy.java Index: AxisClientProxy.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/client/AxisClientProxy.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- AxisClientProxy.java 29 Nov 2002 17:17:10 -0000 1.3 +++ AxisClientProxy.java 17 Dec 2002 00:01:35 -0000 1.4 @@ -57,6 +57,15 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; +import java.util.Map; +import java.util.Vector; + +import javax.xml.namespace.QName; +import javax.xml.rpc.holders.Holder; + +import org.apache.axis.description.OperationDesc; +import org.apache.axis.description.ParameterDesc; +import org.apache.axis.utils.JavaUtils; /** * Very simple dynamic proxy InvocationHandler class. This class is @@ -65,20 +74,97 @@ * a SOAP request. * * @author Glen Daniels (gdaniels@macromedia.com) + * @author C�dric Chabanois (cchabanois@ifrance.com) */ public class AxisClientProxy implements InvocationHandler { - Call call; + + private Call call; + private QName portName; /** * Constructor - package access only (should only really get used * in Service.getPort(endpoint, proxyClass). + * Call can be pre-filled from wsdl */ - AxisClientProxy(Call call) + AxisClientProxy(Call call, QName portName) { this.call = call; + this.portName = portName; // can be null + } + + + /** + * Parameters for invoke method are not the same as parameter for Call + * instance : + * - Holders must be converted to their mapped java types + * - only in and inout parameters must be present in call parameters + * + * @param proxyParams proxyParameters + * @return Object[] Call parameters + * @throws JavaUtils.HolderException + */ + private Object[] proxyParams2CallParams(Object[] proxyParams) + throws JavaUtils.HolderException + { + OperationDesc operationDesc = call.getOperation(); + if (operationDesc == null) + { + // we don't know which parameters are IN, OUT or INOUT + // let's suppose they are all in + return proxyParams; + } + + Vector paramsCall = new Vector(); + for (int i = 0; i < proxyParams.length;i++) + { + Object param = proxyParams[i]; + ParameterDesc paramDesc = operationDesc.getParameter(i); + + if (paramDesc.getMode() == ParameterDesc.INOUT) { + paramsCall.add(JavaUtils.getHolderValue((Holder)param)); + } + else + if (paramDesc.getMode() == ParameterDesc.IN) { + paramsCall.add(param); + } + } + return paramsCall.toArray(); } /** + * copy in/out and out parameters (Holder parameters) back to proxyParams + * + * @param proxyParams proxyParameters + */ + private void callOutputParams2proxyParams(Object[] proxyParams) + throws JavaUtils.HolderException + { + OperationDesc operationDesc = call.getOperation(); + if (operationDesc == null) + { + // we don't know which parameters are IN, OUT or INOUT + // let's suppose they are all in + return; + } + + Map outputParams = call.getOutputParams(); + + for (int i = 0; i < operationDesc.getNumParams();i++) + { + Object param = proxyParams[i]; + ParameterDesc paramDesc = operationDesc.getParameter(i); + if ((paramDesc.getMode() == ParameterDesc.INOUT) || + (paramDesc.getMode() == ParameterDesc.OUT)) { + + JavaUtils.setHolderValue((Holder)param, + outputParams.get(paramDesc.getQName())); + } + } + } + + + + /** * Handle a method invocation. */ public Object invoke(Object o, Method method, Object[] objects) @@ -88,8 +174,41 @@ return null; } else { - call.setOperation(call.getPortName(), method.getName()); - return call.invoke(objects); + Object outValue; + Object[] paramsCall; + + if ((call.getTargetEndpointAddress() != null) && + (call.getPortName() != null)) { + // call object has been prefilled : targetEndPoint and portname + // are already set. We complete it with method informations + call.setOperation(method.getName()); + paramsCall = proxyParams2CallParams(objects); + outValue = call.invoke(paramsCall); + } + else if (portName != null) + { + // we only know the portName. Try to complete this information + // from wsdl if available + call.setOperation(portName,method.getName()); + paramsCall = proxyParams2CallParams(objects); + outValue = call.invoke(paramsCall); + } + else + { + // we don't even know the portName (we don't have wsdl) + paramsCall = objects; + outValue = call.invoke(method.getName(), paramsCall); + } + callOutputParams2proxyParams(objects); + return outValue; } + } + + /** + * Returns the current call + * @return call + */ + public Call getCall(){ + return call; } } 1.195 +116 -23 xml-axis/java/src/org/apache/axis/client/Call.java Index: Call.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/client/Call.java,v retrieving revision 1.194 retrieving revision 1.195 diff -u -r1.194 -r1.195 --- Call.java 11 Dec 2002 22:38:09 -0000 1.194 +++ Call.java 17 Dec 2002 00:01:35 -0000 1.195 @@ -2,7 +2,7 @@ * The Apache Software License, Version 1.1 * * - * Copyright (c) 2001 The Apache Software Foundation. All rights +* Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -1146,14 +1146,27 @@ operationName = new QName(opName); } - public void setOperation(QName portName, String opName) { + /** + * Prefill as much info from the WSDL as it can. + * Right now it's SOAPAction, operation qname, parameter types + * and return type of the Web Service. + * + * This methods considers that port name and target endpoint address have + * already been set. This is useful when you want to use the same Call + * instance for several calls on the same Port + * + * Note: Not part of JAX-RPC specification. + * + * @param portName PortName in the WSDL doc to search for + * @param opName Operation(method) that's going to be invoked + */ + public void setOperation(String opName) { if ( service == null ) throw new JAXRPCException( Messages.getMessage("noService04") ); - // Make sure we're making a fresh start. - this.setPortName( portName ); + // remove all settings concerning an operation + // leave portName and targetEndPoint as they are this.setOperationName( opName ); - this.setTargetEndpointAddress( (URL) null ); this.setEncodingStyle( null ); this.setReturnType( null ); this.removeAllParameters(); @@ -1188,26 +1201,9 @@ throw new JAXRPCException( Messages.getMessage("noOperation01", opName) ); - // Get the URL - //////////////////////////////////////////////////////////////////// - List list = port.getExtensibilityElements(); - for ( int i = 0 ; list != null && i < list.size() ; i++ ) { - Object obj = list.get(i); - if ( obj instanceof SOAPAddress ) { - try { - SOAPAddress addr = (SOAPAddress) obj ; - URL url = new URL(addr.getLocationURI()); - this.setTargetEndpointAddress(url); - } - catch(Exception exp) { - throw new JAXRPCException( - Messages.getMessage("cantSetURI00", "" + exp) ); - } - } - } - // Get the SOAPAction //////////////////////////////////////////////////////////////////// + List list = port.getExtensibilityElements(); String opStyle = null; BindingOperation bop = binding.getBindingOperation(opName, null, null); @@ -1360,6 +1356,98 @@ // need to be specified with addParameter calls. parmAndRetReq = false; return; + + } + + + /** + * prefill as much info from the WSDL as it can. + * Right now it's target URL, SOAPAction, Parameter types, + * and return type of the Web Service. + * + * If wsdl is not present, this function set port name and operation name + * and does not modify target endpoint address. + * + * Note: Not part of JAX-RPC specification. + * + * @param portName PortName in the WSDL doc to search for + * @param opName Operation(method) that's going to be invoked + */ + public void setOperation(QName portName, String opName) { + if ( service == null ) + throw new JAXRPCException( Messages.getMessage("noService04") ); + + // Make sure we're making a fresh start. + this.setPortName( portName ); + this.setOperationName( opName ); + this.setEncodingStyle( null ); + this.setReturnType( null ); + this.removeAllParameters(); + + javax.wsdl.Service wsdlService = service.getWSDLService(); + // Nothing to do is the WSDL is not already set. + if(wsdlService == null) + return; + + // we reinitialize target endpoint only if we have wsdl + this.setTargetEndpointAddress( (URL) null ); + + Port port = wsdlService.getPort( portName.getLocalPart() ); + if ( port == null ) + throw new JAXRPCException( Messages.getMessage("noPort00", "" + + portName) ); + + Binding binding = port.getBinding(); + PortType portType = binding.getPortType(); + if ( portType == null ) + throw new JAXRPCException( Messages.getMessage("noPortType00", "" + + portName) ); + + // Get the URL + //////////////////////////////////////////////////////////////////// + List list = port.getExtensibilityElements(); + for ( int i = 0 ; list != null && i < list.size() ; i++ ) { + Object obj = list.get(i); + if ( obj instanceof SOAPAddress ) { + try { + SOAPAddress addr = (SOAPAddress) obj ; + URL url = new URL(addr.getLocationURI()); + this.setTargetEndpointAddress(url); + } + catch(Exception exp) { + throw new JAXRPCException( + Messages.getMessage("cantSetURI00", "" + exp) ); + } + } + } + + // Get the SOAPAction + //////////////////////////////////////////////////////////////////// + String opStyle = null; + BindingOperation bop = binding.getBindingOperation(opName, + null, null); + if ( bop == null ) + throw new JAXRPCException( Messages.getMessage("noOperation02", + opName )); + list = bop.getExtensibilityElements(); + for ( int i = 0 ; list != null && i < list.size() ; i++ ) { + Object obj = list.get(i); + if ( obj instanceof SOAPOperation ) { + SOAPOperation sop = (SOAPOperation) obj ; + opStyle = ((SOAPOperation) obj).getStyle(); + String action = sop.getSoapActionURI(); + if ( action != null ) { + setUseSOAPAction(true); + setSOAPActionURI(action); + } + else { + setUseSOAPAction(false); + setSOAPActionURI(null); + } + break ; + } + } + setOperation(opName); } /** @@ -2539,6 +2627,11 @@ public void setOperation(OperationDesc operation) { this.operation = operation; operationSetManually = true; + } + + public OperationDesc getOperation() + { + return operation; } public void clearOperation() { 1.83 +1 -1 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.82 retrieving revision 1.83 diff -u -r1.82 -r1.83 --- Service.java 19 Nov 2002 22:47:01 -0000 1.82 +++ Service.java 17 Dec 2002 00:01:35 -0000 1.83 @@ -437,7 +437,7 @@ Thread.currentThread().getContextClassLoader(); return (Remote)Proxy.newProxyInstance(classLoader, new Class[] { proxyInterface, javax.xml.rpc.Stub.class }, - new AxisClientProxy(call)); + new AxisClientProxy(call, portName)); } catch (Exception e) { throw new ServiceException(e.toString()); } 1.1 xml-axis/java/test/wsdl/jaxrpcdynproxy/AddressInOut.wsdl Index: AddressInOut.wsdl =================================================================== 1.1 xml-axis/java/test/wsdl/jaxrpcdynproxy/AddressSoapBindingImpl.java Index: AddressSoapBindingImpl.java =================================================================== package test.wsdl.jaxrpcdynproxy; import test.wsdl.jaxrpcdynproxy.holders.AddressBeanHolder; public class AddressSoapBindingImpl implements test.wsdl.jaxrpcdynproxy.AddressService { public String updateAddress(AddressBeanHolder addressBeanHolder, int newPostCode) throws java.rmi.RemoteException { addressBeanHolder.value.setPostcode(newPostCode); return ("Your street : " + addressBeanHolder.value.getStreet() + "\nYour postCode : " + newPostCode); } } 1.1 xml-axis/java/test/wsdl/jaxrpcdynproxy/JAXRPCDynProxyTestCase.java Index: JAXRPCDynProxyTestCase.java =================================================================== package test.wsdl.jaxrpcdynproxy; import javax.xml.namespace.QName; import javax.xml.rpc.Service; import javax.xml.rpc.ServiceFactory; import java.net.URL; import test.wsdl.jaxrpcdynproxy.holders.AddressBeanHolder; import junit.framework.TestCase; import java.net.URL; import java.lang.reflect.Proxy; import org.apache.axis.encoding.TypeMappingRegistry; import org.apache.axis.encoding.TypeMapping; import org.apache.axis.encoding.ser.BeanSerializerFactory; import org.apache.axis.encoding.ser.BeanDeserializerFactory; import org.apache.axis.client.AxisClientProxy; public class JAXRPCDynProxyTestCase extends TestCase { /** * Default constructor for use as service */ public JAXRPCDynProxyTestCase() { super("JAXRPCDynProxyTest"); } public JAXRPCDynProxyTestCase(String name) { super(name); } public void testInOut() throws Exception { URL urlWsdl = new URL("http://localhost:8080/axis/services/AddressInOut?wsdl"); String nameSpaceUri = "http://jaxrpcdynproxy.wsdl.test"; String serviceName = "AddressInOut"; String portName = "AddressInOut"; ServiceFactory serviceFactory = ServiceFactory.newInstance(); Service service = serviceFactory.createService(urlWsdl, new QName(nameSpaceUri, serviceName)); AddressService myProxy = (AddressService) service.getPort(new QName(nameSpaceUri, portName), AddressService.class); AddressBean addressBean = new AddressBean(); addressBean.setStreet("55, rue des Lilas"); AddressBeanHolder addressBeanHolder = new AddressBeanHolder(addressBean); QName qName = new QName("http://jaxrpcdynproxy.wsdl.test", "AddressBean"); AxisClientProxy clientProxy = (AxisClientProxy) Proxy.getInvocationHandler(myProxy); clientProxy.getCall().registerTypeMapping(AddressBean.class, qName, BeanSerializerFactory.class, BeanDeserializerFactory.class, false); myProxy.updateAddress(addressBeanHolder, 75005); addressBean = addressBeanHolder.value; assertEquals("New postcode is not the expected 75005", addressBean.getPostcode(), 75005); } public static void main(String[] args) throws Exception { JAXRPCDynProxyTestCase test = new JAXRPCDynProxyTestCase("test"); test.testInOut(); } } 1.1 xml-axis/java/test/wsdl/jaxrpcdynproxy/build.xml Index: build.xml =================================================================== ]> &properties; &paths; &taskdefs; &taskdefs_post_compile; &targets;