You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2011/09/01 13:33:33 UTC
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/...
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());
+ }
}