diff --git a/sandbox/pom.xml b/sandbox/pom.xml
index 4f32ce46..3cdd6c0a 100644
--- a/sandbox/pom.xml
+++ b/sandbox/pom.xml
@@ -9,6 +9,18 @@
spring-ws-sandbox
jar
Spring WS Sandbox
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.5
+ 1.5
+
+
+
+
@@ -61,6 +73,23 @@
mail
provided
+
+ javax.jbi
+ jbi
+ 1.0
+ provided
+
+
+ javax.xml.ws
+ jaxws-api
+ 2.1
+
+
+ javax.xml.bind
+ jaxb-api
+
+
+
com.sun.xml.messaging.saaj
diff --git a/sandbox/src/main/java/org/springframework/ws/jaxws/JaxWsProviderEndpointAdapter.java b/sandbox/src/main/java/org/springframework/ws/jaxws/JaxWsProviderEndpointAdapter.java
new file mode 100644
index 00000000..00547d71
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/jaxws/JaxWsProviderEndpointAdapter.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.jaxws;
+
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.ws.Provider;
+import javax.xml.ws.Service;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceProvider;
+
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.context.MessageContext;
+import org.springframework.ws.server.EndpointAdapter;
+import org.springframework.ws.soap.saaj.SaajSoapMessage;
+import org.springframework.xml.transform.TransformerObjectSupport;
+
+/**
+ * Adapter to use a JAX-WS {@link Provider} as the endpoint for a EndpointInvocationChain. Supports both
+ * message and payload providers.
+ *
+ * @author Arjen Poutsma
+ */
+public class JaxWsProviderEndpointAdapter extends TransformerObjectSupport implements EndpointAdapter {
+
+ public boolean supports(Object endpoint) {
+ return endpoint.getClass().getAnnotation(WebServiceProvider.class) != null && endpoint instanceof Provider;
+ }
+
+ public void invoke(MessageContext messageContext, Object endpoint) throws Exception {
+ ServiceMode serviceMode = endpoint.getClass().getAnnotation(ServiceMode.class);
+ if (serviceMode == null || Service.Mode.PAYLOAD.equals(serviceMode.value())) {
+ invokeSourceProvider(messageContext, (Provider) endpoint);
+ }
+ else if (Service.Mode.MESSAGE.equals(serviceMode.value())) {
+ Provider provider = (Provider) endpoint;
+ invokeMessageProvider(messageContext, provider);
+ }
+ }
+
+ private void invokeSourceProvider(MessageContext messageContext, Provider provider)
+ throws TransformerException {
+ Source requestSource = messageContext.getRequest().getPayloadSource();
+ Source responseSource = provider.invoke(requestSource);
+ if (responseSource != null) {
+ WebServiceMessage response = messageContext.getResponse();
+ Transformer transformer = createTransformer();
+ transformer.transform(responseSource, response.getPayloadResult());
+ }
+ }
+
+ private void invokeMessageProvider(MessageContext messageContext, Provider provider) {
+ if (!(messageContext.getRequest() instanceof SaajSoapMessage)) {
+ throw new IllegalArgumentException("JaxWsProviderEndpointAdapter requires a SaajSoapMessage. " +
+ "Use a SaajSoapMessageFactory to create the SOAP messages.");
+ }
+ SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest();
+ SOAPMessage saajRequest = request.getSaajMessage();
+ SOAPMessage saajResponse = provider.invoke(saajRequest);
+ if (saajResponse != null) {
+ SaajSoapMessage response = (SaajSoapMessage) messageContext.getResponse();
+ response.setSaajMessage(saajResponse);
+ }
+ }
+}
diff --git a/sandbox/src/test/java/org/springframework/ws/jaxws/JaxWsProviderEndpointAdapterTest.java b/sandbox/src/test/java/org/springframework/ws/jaxws/JaxWsProviderEndpointAdapterTest.java
new file mode 100644
index 00000000..3c0040b8
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/jaxws/JaxWsProviderEndpointAdapterTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.jaxws;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.Source;
+import javax.xml.ws.Provider;
+import javax.xml.ws.Service;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceProvider;
+
+import junit.framework.TestCase;
+import org.springframework.ws.MockWebServiceMessage;
+import org.springframework.ws.MockWebServiceMessageFactory;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.context.DefaultMessageContext;
+import org.springframework.ws.context.MessageContext;
+import org.springframework.ws.soap.saaj.SaajSoapMessage;
+import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
+
+public class JaxWsProviderEndpointAdapterTest extends TestCase {
+
+ private JaxWsProviderEndpointAdapter adapter;
+
+ protected void setUp() throws Exception {
+ adapter = new JaxWsProviderEndpointAdapter();
+ }
+
+ public void testSupports() throws Exception {
+ MyMessageProvider messageProvider = new MyMessageProvider();
+ assertTrue("Does not support message provider", adapter.supports(messageProvider));
+ MySourceProvider sourceProvider = new MySourceProvider();
+ assertTrue("Does not support source provider", adapter.supports(sourceProvider));
+ MyDefaultProvider defaultProvider = new MyDefaultProvider();
+ assertTrue("Does not support source provider", adapter.supports(defaultProvider));
+ }
+
+ public void testInvokeMessageProvider() throws Exception {
+ MyMessageProvider provider = new MyMessageProvider();
+ MessageContext messageContext =
+ new DefaultMessageContext(new SaajSoapMessageFactory(MessageFactory.newInstance()));
+ adapter.invoke(messageContext, provider);
+ assertTrue("No response", messageContext.hasResponse());
+ SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest();
+ SaajSoapMessage response = (SaajSoapMessage) messageContext.getResponse();
+ assertEquals("Invalid response", request.getSaajMessage(), response.getSaajMessage());
+ }
+
+ public void testInvokeSourceProvider() throws Exception {
+ MySourceProvider provider = new MySourceProvider();
+ WebServiceMessage request = new MockWebServiceMessage("");
+ MessageContext messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
+ adapter.invoke(messageContext, provider);
+ assertTrue("No response", messageContext.hasResponse());
+ }
+
+ public void testInvokeDefaultProvider() throws Exception {
+ MyDefaultProvider provider = new MyDefaultProvider();
+ WebServiceMessage request = new MockWebServiceMessage("");
+ MessageContext messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
+ adapter.invoke(messageContext, provider);
+ assertTrue("No response", messageContext.hasResponse());
+ }
+
+ @WebServiceProvider
+ @ServiceMode(Service.Mode.MESSAGE)
+ private static class MyMessageProvider implements Provider {
+
+ public SOAPMessage invoke(SOAPMessage request) {
+ return request;
+ }
+ }
+
+ @WebServiceProvider
+ @ServiceMode(value = Service.Mode.PAYLOAD)
+ private static class MySourceProvider implements Provider {
+
+ public Source invoke(Source request) {
+ return request;
+ }
+ }
+
+ @WebServiceProvider
+ private static class MyDefaultProvider implements Provider {
+
+ public Source invoke(Source request) {
+ return request;
+ }
+ }
+
+
+}