camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jans...@apache.org
Subject svn commit: r1164021 - in /camel/branches/camel-2.8.x: ./ components/camel-soap/ components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/ components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ components/camel-soap/src/...
Date Thu, 01 Sep 2011 11:33:33 GMT
Author: janstey
Date: Thu Sep  1 11:33:33 2011
New Revision: 1164021

URL: http://svn.apache.org/viewvc?rev=1164021&view=rev
Log:
Merged revisions 1152170 via svnmerge from 
https://svn.apache.org/repos/asf/camel/trunk

........
  r1152170 | ningjiang | 2011-07-29 08:54:31 -0230 (Fri, 29 Jul 2011) | 1 line
  
  CAMEL-3968 Add support for multiple parameters
........

Added:
    camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/MultiPartClientMarshalTest.java
      - copied unchanged from r1152170, camel/trunk/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/MultiPartClientMarshalTest.java
    camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/MultiPartCustomerServiceImpl.java
      - copied unchanged from r1152170, camel/trunk/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/MultiPartCustomerServiceImpl.java
    camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/MultiPartCxfServerTest.java
      - copied unchanged from r1152170, camel/trunk/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/MultiPartCxfServerTest.java
    camel/branches/camel-2.8.x/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCustomerService.wsdl
      - copied unchanged from r1152170, camel/trunk/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCustomerService.wsdl
    camel/branches/camel-2.8.x/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCxfServerTest-context.xml
      - copied unchanged from r1152170, camel/trunk/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCxfServerTest-context.xml
Modified:
    camel/branches/camel-2.8.x/   (props changed)
    camel/branches/camel-2.8.x/components/camel-soap/pom.xml
    camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
    camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/MethodInfo.java
    camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java
    camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/converter/soap/name/ServiceInterfaceStrategyTest.java

Propchange: camel/branches/camel-2.8.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 11:33:33 2011
@@ -1 +1 @@
-/camel/trunk:1150651,1151054,1155230,1156108,1156260,1156524,1157348,1157798,1157831,1157878,1158153,1159171,1159174,1159457,1159460,1159606,1159867,1160547,1160637,1161010,1161082,1161524,1162309,1162395
+/camel/trunk:1150651,1151054,1152170,1155230,1156108,1156260,1156524,1157348,1157798,1157831,1157878,1158153,1159171,1159174,1159457,1159460,1159606,1159867,1160547,1160637,1161010,1161082,1161524,1162309,1162395

Propchange: camel/branches/camel-2.8.x/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: camel/branches/camel-2.8.x/components/camel-soap/pom.xml
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-soap/pom.xml?rev=1164021&r1=1164020&r2=1164021&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-soap/pom.xml (original)
+++ camel/branches/camel-2.8.x/components/camel-soap/pom.xml Thu Sep  1 11:33:33 2011
@@ -97,6 +97,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-saxon</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
             <scope>test</scope>
@@ -182,13 +187,23 @@
                                         <bindingFile>
                                             ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/binding.xml
                                         </bindingFile>
-                                    </bindingFiles>
+                                    </bindingFiles>                               
    
                                 </wsdlOption>
                                 <wsdlOption>
                                     <wsdl>
                                         ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/CustomerService2.wsdl
                                     </wsdl>
                                 </wsdlOption>
+                                <wsdlOption>
+                                    <wsdl>
+                                        ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCustomerService.wsdl
+                                    </wsdl>
+                                    <bindingFiles>
+                                        <bindingFile>
+                                            ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/binding.xml
+                                        </bindingFile>
+                                    </bindingFiles>
+                                </wsdlOption>
                             </wsdlOptions>
                         </configuration>
                         <goals>

Modified: camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java?rev=1164021&r1=1164020&r2=1164021&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
(original)
+++ camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
Thu Sep  1 11:33:33 2011
@@ -19,11 +19,14 @@ package org.apache.camel.dataformat.soap
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.jws.WebMethod;
+import javax.jws.WebParam;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
@@ -39,10 +42,14 @@ import org.apache.camel.converter.jaxb.J
 import org.apache.camel.dataformat.soap.name.ElementNameStrategy;
 import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
 import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.xmlsoap.schemas.soap.envelope.Body;
 import org.xmlsoap.schemas.soap.envelope.Detail;
 import org.xmlsoap.schemas.soap.envelope.Envelope;
 import org.xmlsoap.schemas.soap.envelope.Fault;
+import org.xmlsoap.schemas.soap.envelope.Header;
 import org.xmlsoap.schemas.soap.envelope.ObjectFactory;
 
 /**
@@ -52,13 +59,20 @@ import org.xmlsoap.schemas.soap.envelope
  * not be extracted from JAXB.
  */
 public class SoapJaxbDataFormat extends JaxbDataFormat {
+
+    public static final String SOAP_UNMARSHALLED_HEADER_LIST = "org.apache.camel.dataformat.soap.UNMARSHALLED_HEADER_LIST";
+    
     private static final String SOAP_PACKAGE_NAME = Envelope.class.getPackage().getName();
 
     private static final QName FAULT_CODE_SERVER = new QName("http://www.w3.org/2003/05/soap-envelope",
"Receiver");
-
+    
+    protected final transient Logger log = LoggerFactory.getLogger(getClass());
+    
     private ElementNameStrategy elementNameStrategy;
 
     private String elementNameStrategyRef;
+    
+    private boolean ignoreUnmarshalledHeaders;
 
     /**
      * Remember to set the context path when using this constructor
@@ -99,6 +113,18 @@ public class SoapJaxbDataFormat extends 
                     + ElementNameStrategy.class.getName());
         }
     }
+    
+    public void setIgnoreUnmarshalledHeaders(boolean ignoreHeaders) {
+        this.ignoreUnmarshalledHeaders = ignoreHeaders;
+    }
+    
+    /**
+     * Indicates whether header content that has been unmarshalled should be placed into
a message
+     * header on the exchange
+     */
+    private boolean isIgnoreUnmarshalledHeaders() {
+        return ignoreUnmarshalledHeaders;
+    }
 
     protected void checkElementNameStrategy(Exchange exchange) {
         if (elementNameStrategy == null) {
@@ -118,11 +144,11 @@ public class SoapJaxbDataFormat extends 
     }
 
     /**
-     * Marshal inputObject to SOAP xml. If the exchange or message has an
+     * Marshal inputObjects to SOAP xml. If the exchange or message has an
      * EXCEPTION_CAUGTH property or header then instead of the object the
      * exception is marshaled.
      * 
-     * To determine the name of the top level xml elment the elementNameStrategy
+     * To determine the name of the top level xml elements the elementNameStrategy
      * is used.
      */
     public void marshal(Exchange exchange, final Object inputObject, OutputStream stream)
throws IOException {
@@ -136,20 +162,34 @@ public class SoapJaxbDataFormat extends 
                 soapAction = webMethod.action();
             }
         }
+                
         Body body = new Body();
+        Header header = new Header();
 
         Throwable exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
         if (exception == null) {
             exception = exchange.getIn().getHeader(Exchange.EXCEPTION_CAUGHT, Throwable.class);
         }
-        final JAXBElement<?> content;
+        
+        final List<JAXBElement<?>> bodyContent;
+        List<JAXBElement<?>> headerContent = new ArrayList<JAXBElement<?>>();
         if (exception != null) {
-            content = createFaultFromException(exception);
+            bodyContent = new ArrayList<JAXBElement<?>>();
+            bodyContent.add(createFaultFromException(exception));
         } else {
-            content = createBodyContentFromObject(inputObject, soapAction);
+            bodyContent = createContentFromObject(inputObject, soapAction, headerContent);
+        }
+       
+        for (JAXBElement<?> elem : bodyContent) {
+            body.getAny().add(elem);
+        }
+        for (JAXBElement<?> elem : headerContent) {
+            header.getAny().add(elem);
         }
-        body.getAny().add(content);
         Envelope envelope = new Envelope();
+        if (headerContent.size() > 0) {
+            envelope.setHeader(header);
+        }
         envelope.setBody(body);
         JAXBElement<Envelope> envelopeEl = new ObjectFactory().createEnvelope(envelope);
         super.marshal(exchange, envelopeEl, stream);
@@ -168,35 +208,106 @@ public class SoapJaxbDataFormat extends 
      *            for name resolution
      * @param classResolver
      *            for name resolution
+     * @param headerElements
+     *            in/out parameter used to capture header content if present
+     *            
      * @return JAXBElement for the body content
      */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    private JAXBElement<?> createBodyContentFromObject(final Object inputObject, String
soapAction) {
-        Object paramObject;
+    private List<JAXBElement<?>> createContentFromObject(final Object inputObject,
String soapAction,
+                                                         List<JAXBElement<?>>
headerElements) {
+        List<Object> bodyParts = new ArrayList<Object>();
+        List<Object> headerParts = new ArrayList<Object>();
         if (inputObject instanceof BeanInvocation) {
-            BeanInvocation bi = (BeanInvocation) inputObject;
-            if (bi.getArgs() == null || bi.getArgs().length == 0) {
-                paramObject = null;
-            } else if (bi.getArgs().length == 1) {
-                paramObject = bi.getArgs()[0];
+            BeanInvocation bi = (BeanInvocation)inputObject;
+            Annotation[][] annotations = bi.getMethod().getParameterAnnotations();
+
+            List<WebParam> webParams = new ArrayList<WebParam>();
+            for (int i = 0; i < annotations.length; i++) {
+                Annotation[] singleParameterAnnotations = annotations[i];
+                for (int j = 0; j < singleParameterAnnotations.length; j++) {
+                    Annotation annotation = singleParameterAnnotations[j];
+                    if (annotation instanceof WebParam) {
+                        webParams.add((WebParam)annotation);
+                    }
+                }
+            }
+
+            if (webParams.size() > 0) {
+                if (webParams.size() == bi.getArgs().length) {
+                    int index = -1;
+                    for (Object o : bi.getArgs()) {
+                        if (webParams.get(++index).header()) {
+                            headerParts.add(o);
+                        } else {
+                            bodyParts.add(o);
+                        }
+                    }
+                } else {
+                    throw new RuntimeCamelException(
+                                                    "The number of bean invocation parameters
does not "
+                                                        + "match the number of parameters
annotated with @WebParam for the method [ "
+                                                        + bi.getMethod().getName() + "].");
+                }
             } else {
-                throw new RuntimeCamelException("SoapDataFormat does not work with " 
-                        + "Beaninvocations that contain more than 1 parameter");        
       
+                // try to map all objects for the body
+                for (Object o : bi.getArgs()) {
+                    bodyParts.add(o);
+                }
             }
+
         } else {
-            paramObject = inputObject;
+            bodyParts.add(inputObject);
         }
-        if (paramObject == null) {
-            return null;
+
+        List<JAXBElement<?>> bodyElements = new ArrayList<JAXBElement<?>>();
+        for (Object bodyObj : bodyParts) {
+            QName name = elementNameStrategy.findQNameForSoapActionOrType(soapAction, bodyObj.getClass());
+            if (name == null) {
+                log.warn("Could not find QName for class " + bodyObj.getClass().getName());
+                continue;
+            } else {
+                bodyElements.add(getElement(bodyObj, name));
+            }
         }
-        QName name = elementNameStrategy.findQNameForSoapActionOrType(soapAction, paramObject.getClass());
-        if (name == null) {
-            // This can happen if a method has no parameter or return type
-            return null;
+
+        for (Object headerObj : headerParts) {
+            QName name = elementNameStrategy.findQNameForSoapActionOrType(soapAction, headerObj.getClass());
+            if (name == null) {
+                log.warn("Could not find QName for class " + headerObj.getClass().getName());
+                continue;
+            } else {
+                JAXBElement<?> headerElem = getElement(headerObj, name);
+                if (null != headerElem) {
+                    headerElements.add(headerElem);
+                }
+            }
         }
-        return new JAXBElement(name, paramObject.getClass(), paramObject);
-    }
 
+        return bodyElements;
+    }
+    
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private JAXBElement<?> getElement(Object fromObj, QName name) {
+       
+        Object value = null;
+        
+        // In the case of a parameter, the class of the value of the holder class
+        // is used for the mapping rather than the holder class itself.
+        
+        if (fromObj instanceof javax.xml.ws.Holder) {
+            javax.xml.ws.Holder holder = (javax.xml.ws.Holder) fromObj;
+            value = holder.value;
+            if (null == value) {
+                return null;
+            }
+        } else {
+            value = fromObj;
+        }
+        
+        return new JAXBElement(name, value.getClass(), value);
+    }
+    
+    
     /**
      * Creates a SOAP fault from the exception and populates the message as well
      * as the detail. The detail object is read from the method getFaultInfo of
@@ -257,6 +368,24 @@ public class SoapJaxbDataFormat extends 
             throw new RuntimeCamelException("Expected Soap Envelope but got " + rootObject.getClass());
         }
         Envelope envelope = (Envelope) rootObject;
+        
+        Header header = envelope.getHeader();
+        if (header != null) {
+            List<Object> returnHeaders;
+            List<Object> anyHeaderElements = envelope.getHeader().getAny();
+            if (null != anyHeaderElements && !(isIgnoreUnmarshalledHeaders())) {
+                if (isIgnoreJAXBElement()) {
+                    returnHeaders = new ArrayList<Object>();
+                    for (Object headerEl : anyHeaderElements) {
+                        returnHeaders.add(JAXBIntrospector.getValue(headerEl));
+                    }  
+                } else {
+                    returnHeaders = anyHeaderElements;
+                }
+                exchange.getOut().setHeader(SoapJaxbDataFormat.SOAP_UNMARSHALLED_HEADER_LIST,
returnHeaders);
+            }
+        }
+        
         List<Object> anyElement = envelope.getBody().getAny();
         if (anyElement.size() == 0) {
             // No parameter so return null

Modified: camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/MethodInfo.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/MethodInfo.java?rev=1164021&r1=1164020&r2=1164021&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/MethodInfo.java
(original)
+++ camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/MethodInfo.java
Thu Sep  1 11:33:33 2011
@@ -16,29 +16,41 @@
  */
 package org.apache.camel.dataformat.soap.name;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
- * Value object to hold information about a method in a JAX-WS service interface
+ * Value object to hold information about a method in a JAX-WS service interface.
+ * Method can have many parameters in the signature, but only one response object.
  */
 public final class MethodInfo {
     private String name;
     private String soapAction;
-    private TypeInfo in;
+    private TypeInfo[] in;
     private TypeInfo out;
+    
+    // map of type name to qname
+    private Map<String, TypeInfo> inTypeMap;
 
     /**
      * Initialize 
      * 
      * @param name method name
      * @param soapAction
-     * @param in input parameter (document style so only one parameter)
-     * @param out return type
+     * @param in input parameters
+     * @param out return types
      */
-    public MethodInfo(String name, String soapAction, TypeInfo in, TypeInfo out) {
+    public MethodInfo(String name, String soapAction, TypeInfo[] in, TypeInfo out) {
         super();
         this.name = name;
         this.soapAction = soapAction;
         this.in = in;
         this.out = out;
+        
+        this.inTypeMap = new HashMap<String, TypeInfo>();
+        for (int i = 0; i < in.length; i++) {
+            inTypeMap.put(in[i].getTypeName(), in[i]);
+        }
     }
 
     public String getName() {
@@ -49,12 +61,16 @@ public final class MethodInfo {
         return soapAction;
     }
 
-    public TypeInfo getIn() {
+    public TypeInfo[] getIn() {
         return in;
     }
 
     public TypeInfo getOut() {
         return out;
     }
-
+     
+    public TypeInfo getIn(String typeName) {
+        return this.inTypeMap.get(typeName);
+    }
+    
 }

Modified: camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java?rev=1164021&r1=1164020&r2=1164021&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java
(original)
+++ camel/branches/camel-2.8.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java
Thu Sep  1 11:33:33 2011
@@ -18,7 +18,10 @@ package org.apache.camel.dataformat.soap
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import javax.jws.WebMethod;
@@ -64,7 +67,8 @@ public class ServiceInterfaceStrategy im
     private TypeInfo getOutInfo(Method method) {
         ResponseWrapper respWrap = method.getAnnotation(ResponseWrapper.class);
         if (respWrap != null && respWrap.className() != null) {
-            return new TypeInfo(respWrap.className(), new QName(respWrap.targetNamespace(),
respWrap.localName()));
+            return new TypeInfo(respWrap.className(), 
+                    new QName(respWrap.targetNamespace(), respWrap.localName()));
         }
         Class<?> returnType = method.getReturnType();
         if (Void.TYPE.equals(returnType)) {
@@ -79,33 +83,57 @@ public class ServiceInterfaceStrategy im
                     + " is not annotated with WebParam. This is not yet supported");
             }
         }
-        
     }
 
-    private TypeInfo getInInfo(Method method) {
+    @SuppressWarnings("rawtypes")
+    private List<TypeInfo> getInInfo(Method method) {
+        List<TypeInfo> typeInfos = new ArrayList<TypeInfo>();
         RequestWrapper requestWrapper = method.getAnnotation(RequestWrapper.class);
+
+        // parameter types are returned in declaration order
         Class<?>[] types = method.getParameterTypes();
         if (types.length == 0) {
-            return new TypeInfo(null, null);
+            typeInfos.add(new TypeInfo(null, null));
+            return typeInfos;
         }
         if (requestWrapper != null && requestWrapper.className() != null) {
-            return new TypeInfo(requestWrapper.className(), new QName(requestWrapper.targetNamespace(),
-                    requestWrapper.localName()));
-        }
-        if (types.length == 1) {
-            Annotation[] firstParamAnnotations = method.getParameterAnnotations()[0];
-            for (Annotation annotation : firstParamAnnotations) {
-                if (annotation instanceof WebParam) {
-                    WebParam webParam = (WebParam) annotation;
-                    return new TypeInfo(types[0].getName(), new QName(webParam.targetNamespace(),
webParam.name()));
+            typeInfos.add(new TypeInfo(requestWrapper.className(), 
+                    new QName(requestWrapper.targetNamespace(), requestWrapper.localName())));
+            return typeInfos;
+        }
+                      
+        // annotations are returned in declaration order
+        Annotation[][] annotations = method.getParameterAnnotations();
+
+        List<WebParam> webParams = new ArrayList<WebParam>();
+
+        for (int i = 0; i < annotations.length; i++) {
+            Annotation[] singleParameterAnnotations = annotations[i];
+            for (int j = 0; j < singleParameterAnnotations.length; j++) {
+                Annotation annotation = singleParameterAnnotations[j];
+                if (annotation instanceof WebParam) {                   
+                    webParams.add((WebParam) annotation);
                 }
             }
-            throw new IllegalArgumentException("Parameter of method " + method.getName()
-                    + " is not annotated with WebParam. This is not yet supported");
         }
-        throw new IllegalArgumentException("Method " + method.getName()
-                + " has more than one parameter and no request wrapper. This is not yet supported");
+        
+        if (webParams.size() != types.length) {
+            throw new IllegalArgumentException(
+                    "The number of @WebParam annotations for Method " + method.getName()
+                     + " does not match the number of parameters. This is not supported.");
+        }
+
+        Iterator<WebParam> webParamIter = webParams.iterator();
+        int paramCounter = -1;
+        while (webParamIter.hasNext()) {   
+            WebParam webParam = webParamIter.next();        
+            typeInfos.add(new TypeInfo(types[++paramCounter].getName(),
+                    new QName(webParam.targetNamespace(), webParam.name())));
+        }
+
+        return typeInfos;
     }
+    
 
     /**
      * Determines how the parameter object of the service method will be named
@@ -115,24 +143,35 @@ public class ServiceInterfaceStrategy im
      * @param method
      */
     private MethodInfo analyzeMethod(Method method) {
-        TypeInfo inInfo = getInInfo(method);
+        List<TypeInfo> inInfos = getInInfo(method);
         TypeInfo outInfo = getOutInfo(method);
         WebMethod webMethod = method.getAnnotation(WebMethod.class);
         String soapAction = (webMethod != null) ? webMethod.action() : null;
-        return new MethodInfo(method.getName(), soapAction, inInfo, outInfo);
+        return new MethodInfo(method.getName(), soapAction, 
+                inInfos.toArray(new TypeInfo[inInfos.size()]), outInfo);
     }
 
     private void analyzeServiceInterface(Class<?> serviceInterface) {
         Method[] methods = serviceInterface.getMethods();
         for (Method method : methods) {
             MethodInfo info = analyzeMethod(method);
-            if (info.getIn() != null) {
-                inTypeNameToQName.put(info.getIn().getTypeName(), info.getIn().getElName());
+            for (int i = 0; i < info.getIn().length; i++) {
+                TypeInfo ti = info.getIn()[i];
+                if (inTypeNameToQName.containsKey(ti.getTypeName())
+                    && (!(ti.getTypeName().equals("javax.xml.ws.Holder")))
+                    && (!(inTypeNameToQName.get(ti.getTypeName()).equals(ti.getElName()))))
{
+                    throw new RuntimeCamelException("Ambiguous parameter mapping. The type
[ "
+                                                    + ti.getTypeName()
+                                                    + " ] is already mapped to a QName in
this context.");
+                }
+                inTypeNameToQName.put(ti.getTypeName(), ti.getElName());
             }
             if (info.getSoapAction() != null && !"".equals(info.getSoapAction()))
{
                 soapActionToMethodInfo.put(info.getSoapAction(), info);
             }
+
             outTypeNameToQName.put(info.getOut().getTypeName(), info.getOut().getElName());
+
             addExceptions(method);
         }
     }
@@ -162,7 +201,11 @@ public class ServiceInterfaceStrategy im
         MethodInfo info = soapActionToMethodInfo.get(soapAction);
         if (info != null) {
             if (isClient) {
-                return info.getIn().getElName();
+                if (type != null) {
+                    return info.getIn(type.getName()).getElName();
+                } else {
+                    return null;
+                }
             } else {
                 return info.getOut().getElName();
             }
@@ -179,8 +222,9 @@ public class ServiceInterfaceStrategy im
             try {
                 qName = fallBackStrategy.findQNameForSoapActionOrType(soapAction, type);
             } catch (Exception e) {
-                String msg = "No method found that matches the given SoapAction " + soapAction
+ " or that has an "
-                        + (isClient ? "input" : "output") + " of type " + type.getName();
+                String msg = "No method found that matches the given SoapAction " + soapAction
+                             + " or that has an " + (isClient ? "input" : "output") + " of
type "
+                             + type.getName();
                 throw new RuntimeCamelException(msg, e);
             }
         }

Modified: camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/converter/soap/name/ServiceInterfaceStrategyTest.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/converter/soap/name/ServiceInterfaceStrategyTest.java?rev=1164021&r1=1164020&r2=1164021&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/converter/soap/name/ServiceInterfaceStrategyTest.java
(original)
+++ camel/branches/camel-2.8.x/components/camel-soap/src/test/java/org/apache/camel/converter/soap/name/ServiceInterfaceStrategyTest.java
Thu Sep  1 11:33:33 2011
@@ -18,40 +18,42 @@ package org.apache.camel.converter.soap.
 
 import javax.xml.namespace.QName;
 
-import junit.framework.Assert;
 
 import com.example.customerservice.CustomerService;
 import com.example.customerservice.GetCustomersByName;
 import com.example.customerservice.GetCustomersByNameResponse;
+import com.example.customerservice.multipart.MultiPartCustomerService;
 
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
+import org.junit.Assert;
 import org.junit.Test;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ServiceInterfaceStrategyTest {
+public class ServiceInterfaceStrategyTest extends Assert {
     private static final Logger LOG = LoggerFactory.getLogger(ServiceInterfaceStrategyTest.class);
 
     @Test
     public void testServiceInterfaceStrategyWithClient() {
         ServiceInterfaceStrategy strategy = new ServiceInterfaceStrategy(CustomerService.class,
true);
         QName elName = strategy.findQNameForSoapActionOrType("", GetCustomersByName.class);
-        Assert.assertEquals("http://customerservice.example.com/", elName.getNamespaceURI());
-        Assert.assertEquals("getCustomersByName", elName.getLocalPart());
+        assertEquals("http://customerservice.example.com/", elName.getNamespaceURI());
+        assertEquals("getCustomersByName", elName.getLocalPart());
 
         QName elName2 = strategy.findQNameForSoapActionOrType("getCustomersByName", GetCustomersByName.class);
-        Assert.assertEquals("http://customerservice.example.com/", elName2.getNamespaceURI());
-        Assert.assertEquals("getCustomersByName", elName2.getLocalPart());
+        assertEquals("http://customerservice.example.com/", elName2.getNamespaceURI());
+        assertEquals("getCustomersByName", elName2.getLocalPart());
 
         // Tests the case where the soap action is found but the in type is null
         QName elName3 = strategy.findQNameForSoapActionOrType("http://customerservice.example.com/getAllCustomers",
                 null);
-        Assert.assertNull(elName3);
+        assertNull(elName3);
 
         try {
             elName = strategy.findQNameForSoapActionOrType("test", Class.class);
-            Assert.fail();
+            fail();
         } catch (RuntimeCamelException e) {
             LOG.debug("Caught expected message: " + e.getMessage());
         }
@@ -63,20 +65,20 @@ public class ServiceInterfaceStrategyTes
 
         // Tests the case where the action is not found but the type is
         QName elName = strategy.findQNameForSoapActionOrType("", GetCustomersByNameResponse.class);
-        Assert.assertEquals("http://customerservice.example.com/", elName.getNamespaceURI());
-        Assert.assertEquals("getCustomersByNameResponse", elName.getLocalPart());
+        assertEquals("http://customerservice.example.com/", elName.getNamespaceURI());
+        assertEquals("getCustomersByNameResponse", elName.getLocalPart());
 
         // Tests the case where the soap action is found
         QName elName2 = strategy.findQNameForSoapActionOrType("http://customerservice.example.com/getCustomersByName",
                 GetCustomersByName.class);
-        Assert.assertEquals("http://customerservice.example.com/", elName2.getNamespaceURI());
-        Assert.assertEquals("getCustomersByNameResponse", elName2.getLocalPart());
+        assertEquals("http://customerservice.example.com/", elName2.getNamespaceURI());
+        assertEquals("getCustomersByNameResponse", elName2.getLocalPart());
 
         // this tests the case that the soap action as well as the type are not
         // found
         try {
             elName = strategy.findQNameForSoapActionOrType("test", Class.class);
-            Assert.fail();
+            fail();
         } catch (RuntimeCamelException e) {
             LOG.debug("Caught expected message: " + e.getMessage());
         }
@@ -92,7 +94,7 @@ public class ServiceInterfaceStrategyTes
 
         try {
             elName = strategy.findQNameForSoapActionOrType("test", Class.class);
-            Assert.fail();
+            fail();
         } catch (RuntimeCamelException e) {
             LOG.debug("Caught expected message: " + e.getMessage());
         }
@@ -102,9 +104,24 @@ public class ServiceInterfaceStrategyTes
     public void testWithNonWebservice() {
         try {
             new ServiceInterfaceStrategy(Object.class, true);
-            Assert.fail("Should throw an exception for a class that is no webservice");
+            fail("Should throw an exception for a class that is no webservice");
         } catch (IllegalArgumentException e) {
             LOG.debug("Caught expected message: " + e.getMessage());
         }
     }
+    
+    @Test
+    public void testMultiPart() {
+        ServiceInterfaceStrategy strategy = new ServiceInterfaceStrategy(MultiPartCustomerService.class,
true);
+        QName custNameQName = strategy.findQNameForSoapActionOrType("http://multipart.customerservice.example.com/getCustomersByName",
+                                                                    com.example.customerservice.multipart.GetCustomersByName.class);
+        QName custTypeQName = strategy.findQNameForSoapActionOrType("http://multipart.customerservice.example.com/getCustomersByName",
+                                                                    com.example.customerservice.multipart.Product.class);
+        
+        assertEquals("http://multipart.customerservice.example.com/", custNameQName.getNamespaceURI());
+        assertEquals("getCustomersByName", custNameQName.getLocalPart());
+
+        assertEquals("http://multipart.customerservice.example.com/", custTypeQName.getNamespaceURI());
+        assertEquals("product", custTypeQName.getLocalPart());
+    }
 }



Mime
View raw message