Author: barrettj Date: Thu Oct 28 19:15:02 2010 New Revision: 1028438 URL: http://svn.apache.org/viewvc?rev=1028438&view=rev Log: D/L/B messages may have an empty body or a body with no element. Add unit test and dispatch operation resolution code for those cases.
Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/client/dispatch/DispatchOperationResolutionDocLitBareTest.java Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java?rev=1028438&r1=1028437&r2=1028438&view=diff ============================================================================== --- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java (original) +++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java Thu Oct 28 19:15:02 2010 @@ -286,35 +286,38 @@ public abstract class BaseDispatch<T> ex QName bodyElementQName) { OperationDescription operationDesc = null; - // This logic mimics the code in SOAPMessageBodyBasedOperationDispatcher.findOperation. We will look for - // the AxisOperation corresponding to the body element name. Note that we are searching for the AxisOperation instead - // of searching through the OperationDescriptions so that we can use the getOperationByMessageElementQName - // for the Doc/Lit/Bare case. Once we have the AxisOperation, we'll use that to find the Operation Description. - AxisService axisService = endpointInterfaceDesc.getEndpointDescription().getAxisService(); - AxisOperation axisOperation = null; - - // Doc/Lit/Wrapped and RPC, the operation name is the first body element qname - axisOperation = axisService.getOperation(new QName(bodyElementQName.getLocalPart())); - - if (axisOperation == null) { - // Doc/Lit/Bare, the first body element qname is the element name contained in the wsdl:message part - axisOperation = axisService.getOperationByMessageElementQName(bodyElementQName); - } - - if (axisOperation == null) { - // Not sure why we wouldn't have found the operation above using just the localPart rather than the full QName used here, - // but this is what SOAPMessageBodyBasedOperationDispatcher.findOperation does. - axisOperation = axisService.getOperation(bodyElementQName); - } - - // If we found an axis operation, then find the operation description that corresponds to it - if (axisOperation != null) { - OperationDescription allOpDescs[] = endpointInterfaceDesc.getDispatchableOperations(); - for (OperationDescription checkOpDesc : allOpDescs ) { - AxisOperation checkAxisOperation = checkOpDesc.getAxisOperation(); - if (checkAxisOperation == axisOperation) { - operationDesc = checkOpDesc; - break; + // If there's no bodyElementQName for us to work with, there's nothing more we can do. + if (bodyElementQName != null) { + // This logic mimics the code in SOAPMessageBodyBasedOperationDispatcher.findOperation. We will look for + // the AxisOperation corresponding to the body element name. Note that we are searching for the AxisOperation instead + // of searching through the OperationDescriptions so that we can use the getOperationByMessageElementQName + // for the Doc/Lit/Bare case. Once we have the AxisOperation, we'll use that to find the Operation Description. + AxisService axisService = endpointInterfaceDesc.getEndpointDescription().getAxisService(); + AxisOperation axisOperation = null; + + // Doc/Lit/Wrapped and RPC, the operation name is the first body element qname + axisOperation = axisService.getOperation(new QName(bodyElementQName.getLocalPart())); + + if (axisOperation == null) { + // Doc/Lit/Bare, the first body element qname is the element name contained in the wsdl:message part + axisOperation = axisService.getOperationByMessageElementQName(bodyElementQName); + } + + if (axisOperation == null) { + // Not sure why we wouldn't have found the operation above using just the localPart rather than the full QName used here, + // but this is what SOAPMessageBodyBasedOperationDispatcher.findOperation does. + axisOperation = axisService.getOperation(bodyElementQName); + } + + // If we found an axis operation, then find the operation description that corresponds to it + if (axisOperation != null) { + OperationDescription allOpDescs[] = endpointInterfaceDesc.getDispatchableOperations(); + for (OperationDescription checkOpDesc : allOpDescs ) { + AxisOperation checkAxisOperation = checkOpDesc.getAxisOperation(); + if (checkAxisOperation == axisOperation) { + operationDesc = checkOpDesc; + break; + } } } } @@ -401,9 +404,17 @@ public abstract class BaseDispatch<T> ex try { SOAPBody soapBody = soapMessage.getSOAPBody(); Node firstElement = soapBody.getFirstChild(); - String ns = firstElement.getNamespaceURI(); - String lp= firstElement.getLocalName(); - bodyElementQName = new QName(ns, lp); + // A Doc/Lit/Bare message may not have a firsElement. The soap:Body element may be empty if there + // are no arguments to the operation. + if (firstElement != null) { + String ns = firstElement.getNamespaceURI(); + String lp= firstElement.getLocalName(); + // A Doc/Lit/Bare message may not have a localPart on the element. That can happen if the first element + // is the argument value and there is no wrapper element surrounding it. + if (lp != null) { + bodyElementQName = new QName(ns, lp); + } + } } catch (SOAPException e) { if (log.isDebugEnabled()) { log.debug("Unabled to get the first body element from the outbound dispatch message", e); Modified: axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/client/dispatch/DispatchOperationResolutionDocLitBareTest.java URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/client/dispatch/DispatchOperationResolutionDocLitBareTest.java?rev=1028438&r1=1028437&r2=1028438&view=diff ============================================================================== --- axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/client/dispatch/DispatchOperationResolutionDocLitBareTest.java (original) +++ axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/client/dispatch/DispatchOperationResolutionDocLitBareTest.java Thu Oct 28 19:15:02 2010 @@ -44,6 +44,23 @@ public class DispatchOperationResolution "<ns1:echoStringInput xmlns:ns1=\"http://org/apache/axis2/jaxws/samples/echo/\">" + "The Bare Necessities" + "</ns1:echoStringInput>"; + + /** + * A Doc/Lit/Bare message could have an empty body if the operation has no arguments. + */ + private static final String echoBodyContent_EmptyBody_MESSAGE = + "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>" + + "</soapenv:Body></soapenv:Envelope>"; + + + /** + * A Doc/Lit/Bare message may not have an element in the Body. + */ + private static final String echoBodyContent_NoLocalPart_MESSAGE = + "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>" + + "NoLocalPart" + + "</soapenv:Body></soapenv:Envelope>"; + public void testOperationResolution() { Service service = Service.create(wsdlDocumentLocation, serviceQName); @@ -62,7 +79,37 @@ public class DispatchOperationResolution assertSame("Wrong operation description returned", expectedOperationDescription, opDesc); } - + + public void testOperationResolution_EmptySoapBody() { + Service service = Service.create(wsdlDocumentLocation, serviceQName); + Dispatch<String> dispatch = service.createDispatch(portQName, String.class, Service.Mode.MESSAGE); + assertNotNull(dispatch); + + String result = dispatch.invoke(echoBodyContent_EmptyBody_MESSAGE); + TestClientInvocationController testController = getInvocationController(); + InvocationContext ic = testController.getInvocationContext(); + MessageContext requestMC = ic.getRequestMessageContext(); + + // Because there is no soap body to process, the runtime won't be able to determine the operation + OperationDescription opDesc = requestMC.getOperationDescription(); + assertNull("OpDesc from request MC should be null", opDesc); + } + + public void testOperationResolution_NoSoapBodyElement() { + Service service = Service.create(wsdlDocumentLocation, serviceQName); + Dispatch<String> dispatch = service.createDispatch(portQName, String.class, Service.Mode.MESSAGE); + assertNotNull(dispatch); + + String result = dispatch.invoke(echoBodyContent_NoLocalPart_MESSAGE); + TestClientInvocationController testController = getInvocationController(); + InvocationContext ic = testController.getInvocationContext(); + MessageContext requestMC = ic.getRequestMessageContext(); + + // Because there is no soap body to process, the runtime won't be able to determine the operation + OperationDescription opDesc = requestMC.getOperationDescription(); + assertNull("OpDesc from request MC should be null", opDesc); + } + //********************************************************************************************* // Utility methods //*********************************************************************************************