Moved MethodEndpoint functionality to core-tiger module. (Fixed #SWS-20)
This commit is contained in:
30
core-tiger/pom.xml
Normal file
30
core-tiger/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0"?>
|
||||
<project>
|
||||
<parent>
|
||||
<artifactId>spring-ws</artifactId>
|
||||
<groupId>org.springframework.ws</groupId>
|
||||
<version>1.0-m4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-ws-core-tiger</artifactId>
|
||||
<name>Spring WS Core - Java 5</name>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<!-- Spring-WS dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ws</groupId>
|
||||
<artifactId>spring-ws-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -23,9 +23,6 @@ import java.util.Properties;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
@@ -36,6 +33,7 @@ import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.XPathParam;
|
||||
import org.springframework.xml.dom.DomUtils;
|
||||
import org.springframework.xml.namespace.SimpleNamespaceContext;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
@@ -106,7 +104,8 @@ public class XPathParamAnnotationEndpointAdapter extends AbstractMethodEndpointA
|
||||
|
||||
protected void invokeInternal(MessageContext messageContext, MethodEndpoint methodEndpoint) throws Exception {
|
||||
try {
|
||||
Element payloadElement = getMessagePayloadElement(messageContext.getRequest());
|
||||
Element payloadElement =
|
||||
DomUtils.getRootElement(messageContext.getRequest().getPayloadSource(), getTransformerFactory());
|
||||
Object[] args = getMethodArguments(payloadElement, methodEndpoint.getMethod());
|
||||
Object result = methodEndpoint.invoke(args);
|
||||
if (result != null && result instanceof Source) {
|
||||
@@ -126,19 +125,6 @@ public class XPathParamAnnotationEndpointAdapter extends AbstractMethodEndpointA
|
||||
}
|
||||
}
|
||||
|
||||
private Element getMessagePayloadElement(WebServiceMessage message) throws TransformerException {
|
||||
if (message.getPayloadSource() instanceof DOMSource) {
|
||||
DOMSource domSource = (DOMSource) message.getPayloadSource();
|
||||
if (domSource.getNode().getNodeType() == Node.ELEMENT_NODE) {
|
||||
return (Element) domSource.getNode();
|
||||
}
|
||||
}
|
||||
Transformer transformer = createTransformer();
|
||||
DOMResult domResult = new DOMResult();
|
||||
transformer.transform(message.getPayloadSource(), domResult);
|
||||
return (Element) domResult.getNode().getFirstChild();
|
||||
}
|
||||
|
||||
private Object[] getMethodArguments(Element payloadElement, Method method) throws XPathExpressionException {
|
||||
Class[] parameterTypes = method.getParameterTypes();
|
||||
XPath xpath = createXPath();
|
||||
@@ -22,14 +22,14 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationEndpointMapping;
|
||||
import org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationEndpointMapping;
|
||||
import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationMethodEndpointMapping;
|
||||
import org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping;
|
||||
|
||||
/**
|
||||
* Marks a class as an endpoint.
|
||||
* <p/>
|
||||
* Instances of this class are typically picked up by an {@link AbstractAnnotationEndpointMapping} implementation, such
|
||||
* as {@link SoapActionAnnotationEndpointMapping}.
|
||||
* Instances of this class are typically picked up by an {@link AbstractAnnotationMethodEndpointMapping} implementation,
|
||||
* such as {@link SoapActionAnnotationMethodEndpointMapping}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@@ -16,14 +16,23 @@
|
||||
|
||||
package org.springframework.ws.server.endpoint.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an endpoint method as the handler for an incoming request. The annotation value signifies the value for the
|
||||
* request payload root element that is handled by the method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PayloadRootQName {
|
||||
@Documented
|
||||
public @interface PayloadRoot {
|
||||
|
||||
String value();
|
||||
|
||||
@@ -21,15 +21,18 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
/**
|
||||
* Indicates that a method parameter should be bound to an XPath expression. The annotation value signifies the XPath
|
||||
* expression to use. The parameter can be of the following types: <ul> <li><code>boolean</code>, or {@link
|
||||
* Boolean}</li> <li><code>double</code>, or {@link Double}</li> <li>{@link String}</li> <li>{@link
|
||||
* org.w3c.dom.Node}</li> <li>{@link org.w3c.dom.NodeList}</li> </ul>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.server.endpoint.adapter.XPathParamAnnotationEndpointAdapter
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface XPathParam {
|
||||
|
||||
/**
|
||||
* The XPathParam value.
|
||||
*
|
||||
* @return the
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
@@ -26,15 +26,17 @@ import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
* Abstract base for {@link org.springframework.ws.server.EndpointMapping} implementations that map classes tagged with
|
||||
* an annotation. By default the annotation is {@link Endpoint}, but this can be overriden in subclasses.
|
||||
* <p/>
|
||||
* Each bean
|
||||
* The methods of each bean carrying @Endpoint will be registered using {@link #registerMethods(Object)}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public abstract class AbstractAnnotationEndpointMapping extends AbstractMethodEndpointMapping
|
||||
public abstract class AbstractAnnotationMethodEndpointMapping extends AbstractMethodEndpointMapping
|
||||
implements BeanPostProcessor {
|
||||
|
||||
public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
registerMethods(bean);
|
||||
if (getEndpointClass(bean).getAnnotation(getEndpointAnnotationType()) != null) {
|
||||
registerMethods(bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -18,20 +18,34 @@ package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRootQName;
|
||||
import org.springframework.ws.server.EndpointMapping;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
import org.springframework.xml.dom.DomUtils;
|
||||
import org.springframework.xml.namespace.QNameUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
public class PayloadRootQNameMethodEndpointMapping extends AbstractAnnotationEndpointMapping {
|
||||
/**
|
||||
* Implementation of the {@link EndpointMapping} interface that uses the {@link PayloadRoot} annotation to map methods
|
||||
* to request payload root elements.
|
||||
* <p/>
|
||||
* Endpoints typically have the following form:
|
||||
* <pre>
|
||||
* @Endpoint
|
||||
* public class MyEndpoint{
|
||||
* @Payload("{http://springframework.org/spring-ws}Request")
|
||||
* public Source doSomethingWithRequest() {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class PayloadRootAnnotationMethodEndpointMapping extends AbstractAnnotationMethodEndpointMapping {
|
||||
|
||||
private static TransformerFactory transformerFactory;
|
||||
|
||||
@@ -40,22 +54,15 @@ public class PayloadRootQNameMethodEndpointMapping extends AbstractAnnotationEnd
|
||||
}
|
||||
|
||||
protected String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
|
||||
Element payloadElement = getMessagePayloadElement(messageContext.getRequest());
|
||||
Element payloadElement =
|
||||
DomUtils.getRootElement(messageContext.getRequest().getPayloadSource(), transformerFactory);
|
||||
QName qName = QNameUtils.getQNameForNode(payloadElement);
|
||||
return qName != null ? qName.toString() : null;
|
||||
}
|
||||
|
||||
protected String getLookupKeyForMethod(Method method) {
|
||||
PayloadRootQName annotation = AnnotationUtils.getAnnotation(method, PayloadRootQName.class);
|
||||
PayloadRoot annotation = AnnotationUtils.getAnnotation(method, PayloadRoot.class);
|
||||
return annotation != null ? annotation.value() : null;
|
||||
}
|
||||
|
||||
private Element getMessagePayloadElement(WebServiceMessage message) throws TransformerException {
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
DOMResult domResult = new DOMResult();
|
||||
transformer.transform(message.getPayloadSource(), domResult);
|
||||
return (Element) domResult.getNode().getFirstChild();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -16,14 +16,22 @@
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
/**
|
||||
* Marks an endpoint method as the handler for an incoming request. The annotation value signifies the value for the
|
||||
* request SOAPAction header that is handled by the method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SoapAction {
|
||||
|
||||
String value();
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
JDK 1.5+ annotations for Spring-WS SOAP endpoints.
|
||||
</body>
|
||||
</html>
|
||||
@@ -24,35 +24,30 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.EndpointInvocationChain;
|
||||
import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationEndpointMapping;
|
||||
import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationMethodEndpointMapping;
|
||||
import org.springframework.ws.soap.SoapEndpointMapping;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.server.SoapEndpointInvocationChain;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
|
||||
|
||||
/**
|
||||
* Implementation of the <code>EndpointMapping</code> interface to map from <code>SOAPAction</code> headers to endpoint
|
||||
* beans. Supports both mapping to bean instances and mapping to bean names: the latter is required for prototype
|
||||
* handlers.
|
||||
* Implementation of the {@link org.springframework.ws.server.EndpointMapping} interface that uses the {@link
|
||||
* SoapAction} annotation to map methods to the request SOAPAction header.
|
||||
* <p/>
|
||||
* The <code>endpointMap</code> property is suitable for populating the endpoint map with bean references, e.g. via the
|
||||
* map element in XML bean definitions.
|
||||
* <p/>
|
||||
* Mappings to bean names can be set via the <code>mappings</code> property, in a form accepted by the
|
||||
* <code>java.util.Properties</code> class, like as follows:
|
||||
* Endpoints typically have the following form:
|
||||
* <pre>
|
||||
* http://www.springframework.org/spring-ws/samples/airline/BookFlight=bookFlightEndpoint
|
||||
* http://www.springframework.org/spring-ws/samples/airline/GetFlights=getFlightsEndpoint
|
||||
* @Endpoint
|
||||
* public class MyEndpoint{
|
||||
* @SoapAction("http://springframework.org/spring-ws/SoapAction")
|
||||
* public Source doSomethingWithRequest() {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* The syntax is SOAP_ACTION=ENDPOINT_BEAN_NAME.
|
||||
* <p/>
|
||||
* This endpoint mapping does not read from the request message, and therefore is more suitable for message contexts
|
||||
* which directly read from the transport request (such as the <code>AxiomSoapMessageContextFactory</code> with the
|
||||
* <code>payloadCaching</code> disabled).
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class SoapActionAnnotationEndpointMapping extends AbstractAnnotationEndpointMapping
|
||||
public class SoapActionAnnotationMethodEndpointMapping extends AbstractAnnotationMethodEndpointMapping
|
||||
implements SoapEndpointMapping {
|
||||
|
||||
private String[] actorsOrRoles;
|
||||
@@ -19,19 +19,22 @@ package org.springframework.ws.server.endpoint.adapter;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.ws.MockWebServiceMessage;
|
||||
import org.springframework.ws.MockWebServiceMessageFactory;
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.XPathParam;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
import org.springframework.xml.transform.StringSource;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class XPathParamAnnotationEndpointAdapterTest extends TestCase {
|
||||
|
||||
private static final String CONTENTS = "<root><child><text>text</text><number>42.0</number></child></root>";
|
||||
|
||||
private XPathParamAnnotationEndpointAdapter adapter;
|
||||
|
||||
private boolean supportedTypesInvoked = false;
|
||||
@@ -81,22 +84,44 @@ public class XPathParamAnnotationEndpointAdapterTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testInvokeTypes() throws Exception {
|
||||
MockWebServiceMessage request =
|
||||
new MockWebServiceMessage(new ClassPathResource("nonamespaces.xml", getClass()));
|
||||
MessageContext messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
|
||||
MockControl messageControl = MockControl.createControl(WebServiceMessage.class);
|
||||
WebServiceMessage messageMock = (WebServiceMessage) messageControl.getMock();
|
||||
messageControl.expectAndReturn(messageMock.getPayloadSource(), new StringSource(CONTENTS));
|
||||
messageControl.replay();
|
||||
MockControl factoryControl = MockControl.createControl(WebServiceMessageFactory.class);
|
||||
WebServiceMessageFactory factoryMock = (WebServiceMessageFactory) factoryControl.getMock();
|
||||
factoryControl.replay();
|
||||
|
||||
MessageContext messageContext = new DefaultMessageContext(messageMock, factoryMock);
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedTypes",
|
||||
new Class[]{Boolean.TYPE, Double.TYPE, Node.class, NodeList.class, String.class});
|
||||
adapter.invoke(messageContext, endpoint);
|
||||
assertTrue("Method not invoked", supportedTypesInvoked);
|
||||
|
||||
messageControl.verify();
|
||||
factoryControl.verify();
|
||||
|
||||
}
|
||||
|
||||
public void testInvokeSource() throws Exception {
|
||||
MockWebServiceMessage request =
|
||||
new MockWebServiceMessage(new ClassPathResource("nonamespaces.xml", getClass()));
|
||||
MessageContext messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
|
||||
MockControl messageControl = MockControl.createControl(WebServiceMessage.class);
|
||||
WebServiceMessage requestMock = (WebServiceMessage) messageControl.getMock();
|
||||
WebServiceMessage responseMock = (WebServiceMessage) messageControl.getMock();
|
||||
messageControl.expectAndReturn(requestMock.getPayloadSource(), new StringSource(CONTENTS));
|
||||
messageControl.expectAndReturn(responseMock.getPayloadResult(), new StringResult());
|
||||
messageControl.replay();
|
||||
MockControl factoryControl = MockControl.createControl(WebServiceMessageFactory.class);
|
||||
WebServiceMessageFactory factoryMock = (WebServiceMessageFactory) factoryControl.getMock();
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
factoryControl.replay();
|
||||
|
||||
MessageContext messageContext = new DefaultMessageContext(requestMock, factoryMock);
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedSource", new Class[]{String.class});
|
||||
adapter.invoke(messageContext, endpoint);
|
||||
assertTrue("Method not invoked", supportedSourceInvoked);
|
||||
|
||||
messageControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
public void supportedVoid(@XPathParam("/")String param1) {
|
||||
@@ -16,73 +16,41 @@
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
|
||||
/** TestCase for {@link AbstractAnnotationEndpointMapping} */
|
||||
public class AnnotationEndpointMappingTest extends TestCase {
|
||||
public class PayloadRootAnnotationMethodEndpointMappingTest extends TestCase {
|
||||
|
||||
private AbstractAnnotationEndpointMapping mapping;
|
||||
private PayloadRootAnnotationMethodEndpointMapping mapping;
|
||||
|
||||
private StaticApplicationContext applicationContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
applicationContext = new StaticApplicationContext();
|
||||
applicationContext.registerSingleton("mapping", MyAnnotationEndpointMapping.class);
|
||||
applicationContext.registerSingleton("mapping", PayloadRootAnnotationMethodEndpointMapping.class);
|
||||
applicationContext.registerSingleton("endpoint", MyEndpoint.class);
|
||||
applicationContext.registerSingleton("other", OtherBean.class);
|
||||
applicationContext.refresh();
|
||||
mapping = (AbstractAnnotationEndpointMapping) applicationContext.getBean("mapping");
|
||||
mapping = (PayloadRootAnnotationMethodEndpointMapping) applicationContext.getBean("mapping");
|
||||
}
|
||||
|
||||
public void testRegistration() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = mapping.lookupEndpoint("arg");
|
||||
MethodEndpoint endpoint = mapping.lookupEndpoint("{http://springframework.org/spring-ws}Request");
|
||||
assertNotNull("MethodEndpoint not registered", endpoint);
|
||||
MethodEndpoint expected = new MethodEndpoint(applicationContext.getBean("endpoint"), "doIt", new Class[0]);
|
||||
assertEquals("Invalid endpoint registered", expected, endpoint);
|
||||
|
||||
assertNull("Invalid endpoint registered", mapping.lookupEndpoint("arg2"));
|
||||
}
|
||||
|
||||
private static class MyAnnotationEndpointMapping extends AbstractAnnotationEndpointMapping {
|
||||
|
||||
protected String getLookupKeyForMethod(Method method) {
|
||||
MyAnnotation annotation = AnnotationUtils.getAnnotation(method, MyAnnotation.class);
|
||||
if (annotation != null) {
|
||||
return annotation.value();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
|
||||
return "arg";
|
||||
}
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MyAnnotation {
|
||||
|
||||
String value();
|
||||
|
||||
assertNull("Invalid endpoint registered",
|
||||
mapping.lookupEndpoint("{http://springframework.org/spring-ws}Request2"));
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
private static class MyEndpoint {
|
||||
|
||||
@MyAnnotation("arg")
|
||||
@PayloadRoot("{http://springframework.org/spring-ws}Request")
|
||||
public void doIt() {
|
||||
|
||||
}
|
||||
@@ -91,7 +59,7 @@ public class AnnotationEndpointMappingTest extends TestCase {
|
||||
|
||||
private static class OtherBean {
|
||||
|
||||
@MyAnnotation("arg2")
|
||||
@PayloadRoot("{http://springframework.org/spring-ws}Request2")
|
||||
public void doIt() {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.soap.server.endpoint.mapping;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointInvocationChain;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
|
||||
|
||||
public class SoapActionAnnotationMethodEndpointMappingTest extends TestCase {
|
||||
|
||||
private SoapActionAnnotationMethodEndpointMapping mapping;
|
||||
|
||||
private StaticApplicationContext applicationContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
applicationContext = new StaticApplicationContext();
|
||||
applicationContext.registerSingleton("mapping", SoapActionAnnotationMethodEndpointMapping.class);
|
||||
applicationContext.registerSingleton("endpoint", MyEndpoint.class);
|
||||
applicationContext.refresh();
|
||||
mapping = (SoapActionAnnotationMethodEndpointMapping) applicationContext.getBean("mapping");
|
||||
}
|
||||
|
||||
public void testRegistration() throws Exception {
|
||||
MockControl messageControl = MockControl.createControl(SoapMessage.class);
|
||||
SoapMessage requestMock = (SoapMessage) messageControl.getMock();
|
||||
messageControl.expectAndReturn(requestMock.getSoapAction(), "http://springframework.org/spring-ws/SoapAction");
|
||||
messageControl.replay();
|
||||
MockControl factoryControl = MockControl.createControl(WebServiceMessageFactory.class);
|
||||
WebServiceMessageFactory factoryMock = (WebServiceMessageFactory) factoryControl.getMock();
|
||||
factoryControl.replay();
|
||||
MessageContext context = new DefaultMessageContext(requestMock, factoryMock);
|
||||
|
||||
EndpointInvocationChain chain = mapping.getEndpoint(context);
|
||||
assertNotNull("MethodEndpoint not registered", chain);
|
||||
MethodEndpoint expected = new MethodEndpoint(applicationContext.getBean("endpoint"), "doIt", new Class[0]);
|
||||
assertEquals("Invalid endpoint registered", expected, chain.getEndpoint());
|
||||
messageControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
private static class MyEndpoint {
|
||||
|
||||
@SoapAction("http://springframework.org/spring-ws/SoapAction")
|
||||
public void doIt() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
6
core-tiger/src/test/resources/log4j.properties
Normal file
6
core-tiger/src/test/resources/log4j.properties
Normal file
@@ -0,0 +1,6 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
log4j.logger.org.springframework.ws=DEBUG
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-ws</artifactId>
|
||||
<groupId>org.springframework.ws</groupId>
|
||||
@@ -33,6 +34,10 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-mock</artifactId>
|
||||
|
||||
@@ -24,8 +24,8 @@ import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.xml.transform.TransformerObjectSupport;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link EndpointAdapter} implementations that support {@link
|
||||
* org.springframework.ws.server.endpoint.MethodEndpoint}s. Contains template methods for handling method endpoints.
|
||||
* Abstract base class for {@link EndpointAdapter} implementations that support {@link MethodEndpoint}s. Contains
|
||||
* template methods for handling these method endpoints.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@@ -17,13 +17,11 @@
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.xml.dom.DomUtils;
|
||||
import org.springframework.xml.namespace.QNameUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -56,15 +54,10 @@ public class PayloadRootQNameEndpointMapping extends AbstractQNameEndpointMappin
|
||||
}
|
||||
|
||||
protected QName resolveQName(MessageContext messageContext) throws TransformerException {
|
||||
Element payloadElement = getMessagePayloadElement(messageContext.getRequest());
|
||||
Element payloadElement =
|
||||
DomUtils.getRootElement(messageContext.getRequest().getPayloadSource(), transformerFactory);
|
||||
return QNameUtils.getQNameForNode(payloadElement);
|
||||
}
|
||||
|
||||
private Element getMessagePayloadElement(WebServiceMessage message) throws TransformerException {
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
DOMResult domResult = new DOMResult();
|
||||
transformer.transform(message.getPayloadSource(), domResult);
|
||||
return (Element) domResult.getNode().getFirstChild();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.springframework.ws.transport.WebServiceConnection;
|
||||
* Commons HttpClient</a> to execute POST requests.
|
||||
* <p/>
|
||||
* Allows to use a preconfigured HttpClient instance, potentially with authentication, HTTP connection pooling, etc.
|
||||
* Also designed for easy subclassing, customizing specific template methods.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.transport.http.HttpUrlConnectionMessageSender
|
||||
|
||||
1
pom.xml
1
pom.xml
@@ -104,6 +104,7 @@
|
||||
</activation>
|
||||
<modules>
|
||||
<module>oxm-tiger</module>
|
||||
<module>core-tiger</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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.soap.server.endpoint.mapping;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
|
||||
|
||||
public class SoapActionAnnotationEndpointMappingTest extends TestCase {
|
||||
|
||||
private StaticApplicationContext applicationContext;
|
||||
|
||||
private SoapActionAnnotationEndpointMapping mapping;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
applicationContext = new StaticApplicationContext();
|
||||
applicationContext.registerSingleton("mapping", SoapActionAnnotationEndpointMapping.class);
|
||||
applicationContext.registerSingleton("endpoint", MyEndpoint.class);
|
||||
applicationContext.refresh();
|
||||
mapping = (SoapActionAnnotationEndpointMapping) applicationContext.getBean("mapping");
|
||||
}
|
||||
|
||||
public void testIt() {
|
||||
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
private static class MyEndpoint {
|
||||
|
||||
@SoapAction("http://springframework.org/spring-ws/action")
|
||||
public void handleMessage() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@
|
||||
</properties>
|
||||
<body>
|
||||
<release version="1.0-RC1">
|
||||
<action dev="poutsma" type="add" issue="SWS-20">Added MethodEndpoint functionality, invoking methods for
|
||||
incoming requests
|
||||
</action>
|
||||
<action dev="poutsma" type="fix" issue="SWS-105">GZip compression is not enabled</action>
|
||||
<action dev="poutsma" type="update">WebServiceConnection is now container for TransportInputStream and
|
||||
TransportOutputStream, used on both client- and server-side
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.xml.dom;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
|
||||
@@ -36,11 +37,12 @@ public abstract class DomUtils {
|
||||
/**
|
||||
* Returns the root element of the given source, transforming it if necessary.
|
||||
*
|
||||
* @param source the source to get the root element from
|
||||
* @param transformer a transformer
|
||||
* @param source the source to get the root element from
|
||||
* @param transformerFactory a transformer factory, necessary if the given source is not a <code>DOMSource</code>
|
||||
* @return the root element
|
||||
*/
|
||||
public static Element getRootElement(Source source, Transformer transformer) throws TransformerException {
|
||||
public static Element getRootElement(Source source, TransformerFactory transformerFactory)
|
||||
throws TransformerException {
|
||||
if (source instanceof DOMSource) {
|
||||
DOMSource domSource = (DOMSource) source;
|
||||
Node node = domSource.getNode();
|
||||
@@ -55,6 +57,7 @@ public abstract class DomUtils {
|
||||
return document.getDocumentElement();
|
||||
}
|
||||
}
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
DOMResult domResult = new DOMResult();
|
||||
transformer.transform(source, domResult);
|
||||
Document document = (Document) domResult.getNode();
|
||||
|
||||
@@ -34,9 +34,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
*/
|
||||
public abstract class TransformerObjectSupport {
|
||||
|
||||
/**
|
||||
* Logger available to subclasses.
|
||||
*/
|
||||
/** Logger available to subclasses. */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private static TransformerFactory transformerFactory;
|
||||
@@ -45,6 +43,11 @@ public abstract class TransformerObjectSupport {
|
||||
transformerFactory = TransformerFactory.newInstance();
|
||||
}
|
||||
|
||||
/** Returns the <code>TransformerFactory</code>. */
|
||||
protected TransformerFactory getTransformerFactory() {
|
||||
return transformerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>Transformer</code>. Must be called per request, as transformer is not thread-safe.
|
||||
*
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.io.StringReader;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
@@ -34,16 +33,16 @@ import org.xml.sax.InputSource;
|
||||
|
||||
public class DomUtilsTest extends TestCase {
|
||||
|
||||
private Transformer transformer;
|
||||
|
||||
private static final String NAMESPACE = "http://springframework.org/spring-ws";
|
||||
|
||||
private static final String LOCAL_NAME = "Root";
|
||||
|
||||
private static final String XML = "<" + LOCAL_NAME + " xmlns='" + NAMESPACE + "'/>";
|
||||
|
||||
private TransformerFactory transformerFactory;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformerFactory = TransformerFactory.newInstance();
|
||||
}
|
||||
|
||||
public void testGetRootElementDomSource() throws Exception {
|
||||
@@ -67,7 +66,7 @@ public class DomUtilsTest extends TestCase {
|
||||
}
|
||||
|
||||
private void testSource(Source source) throws TransformerException {
|
||||
Element result = DomUtils.getRootElement(source, transformer);
|
||||
Element result = DomUtils.getRootElement(source, transformerFactory);
|
||||
assertNotNull("No result", result);
|
||||
assertEquals("Invalid namespace", NAMESPACE, result.getNamespaceURI());
|
||||
assertEquals("Invalid local name", LOCAL_NAME, result.getLocalName());
|
||||
|
||||
Reference in New Issue
Block a user