Moved MethodEndpoint functionality to core-tiger module. (Fixed #SWS-20)

This commit is contained in:
Arjen Poutsma
2007-04-11 13:21:04 +00:00
parent f07ea88b35
commit 68347ecdd2
28 changed files with 264 additions and 192 deletions

30
core-tiger/pom.xml Normal file
View 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>

View File

@@ -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();

View File

@@ -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
*/

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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>
* &#64;Endpoint
* public class MyEndpoint{
* &#64;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();
}
}

View File

@@ -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();

View File

@@ -0,0 +1,5 @@
<html>
<body>
JDK 1.5+ annotations for Spring-WS SOAP endpoints.
</body>
</html>

View File

@@ -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
* &#64;Endpoint
* public class MyEndpoint{
* &#64;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;

View File

@@ -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) {

View File

@@ -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() {
}

View File

@@ -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() {
}
}
}

View 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

View File

@@ -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>

View File

@@ -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
*/

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -104,6 +104,7 @@
</activation>
<modules>
<module>oxm-tiger</module>
<module>core-tiger</module>
</modules>
</profile>
<profile>

View File

@@ -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() {
}
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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.
*

View File

@@ -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());