- Split out WS-Addressing to multiple packages (SWS-84)
- Javadoc
This commit is contained in:
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008 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.addressing;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.soap.addressing.annotation.Action;
|
||||
import org.springframework.ws.soap.addressing.annotation.Address;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class AnnotationActionMethodEndpointMapping extends AbstractActionMethodEndpointMapping
|
||||
implements BeanPostProcessor {
|
||||
|
||||
/** Returns the 'endpoint' annotation type. Default is {@link Endpoint}. */
|
||||
protected Class<? extends Annotation> getEndpointAnnotationType() {
|
||||
return Endpoint.class;
|
||||
}
|
||||
|
||||
public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public final Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (getEndpointClass(bean).getAnnotation(getEndpointAnnotationType()) != null) {
|
||||
registerMethods(bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
protected URI getActionForMethod(Method method) {
|
||||
Action action = method.getAnnotation(Action.class);
|
||||
if (action != null) {
|
||||
try {
|
||||
return new URI(action.value());
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object getEndpointInternal(URI to, URI action) {
|
||||
MethodEndpoint methodEndpoint = (MethodEndpoint) lookupEndpoint(action);
|
||||
if (methodEndpoint != null) {
|
||||
// respect the Address annotation, if set
|
||||
Class endpointClass = methodEndpoint.getMethod().getDeclaringClass();
|
||||
Address address = AnnotationUtils.findAnnotation(endpointClass, Address.class);
|
||||
if (address != null && StringUtils.hasText(address.value())) {
|
||||
try {
|
||||
URI addressUri = new URI(address.value());
|
||||
if (to.equals(addressUri)) {
|
||||
return methodEndpoint;
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Address annotation [" + address.value() + "] on [" + endpointClass + "]");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// address not set
|
||||
return methodEndpoint;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -37,10 +37,4 @@ public @interface Action {
|
||||
/** Signifies the value for the request WS-Addressing <code>Action</code> header that is handled by the method. */
|
||||
String value();
|
||||
|
||||
/**
|
||||
* Explicit value of the WS-Addressing <code>Action</code> message addressing property for the <code>output</code>
|
||||
* message of the operation.
|
||||
*/
|
||||
String output() default "";
|
||||
|
||||
}
|
||||
|
||||
@@ -24,11 +24,8 @@ import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an endpoint with a WS-Addressing <code>Address</code>. If this annotation is applied, the {@link #value()} is
|
||||
* compared to the {@link org.springframework.ws.soap.addressing.MessageAddressingProperties#getTo() destination}
|
||||
* compared to the {@link org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination}
|
||||
* property of the incominging message.
|
||||
* <p/>
|
||||
* as the handler for an incoming request. The annotation value signifies the value for the request WS-Addressing
|
||||
* <code>Action</code> header that is handled by the method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.5.0
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2008 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.addressing.server;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.JdkVersion;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.soap.addressing.annotation.Action;
|
||||
import org.springframework.ws.soap.addressing.annotation.Address;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link org.springframework.ws.server.EndpointMapping} interface that uses the {@link Action}
|
||||
* annotation to map methods to a WS-Addressing <code>Action</code> header.
|
||||
* <p/>
|
||||
* Endpoints typically have the following form:
|
||||
* <pre>
|
||||
* @Endpoint
|
||||
* @Address("mailto:joe@fabrikam123.example")
|
||||
* public class MyEndpoint{
|
||||
* @Action("http://fabrikam123.example/mail/Delete")
|
||||
* public Source doSomethingWithRequest() {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* If set, the {@link @Address} annotation on the endpoint class should be equal to the {@link
|
||||
* org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination} property of the
|
||||
* incominging message.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see Action
|
||||
* @see Address
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class AnnotationActionEndpointMapping extends AbstractActionEndpointMapping implements BeanPostProcessor {
|
||||
|
||||
/** Returns the 'endpoint' annotation type. Default is {@link Endpoint}. */
|
||||
protected Class<? extends Annotation> getEndpointAnnotationType() {
|
||||
return Endpoint.class;
|
||||
}
|
||||
|
||||
public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public final Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (AopUtils.getTargetClass(bean).getAnnotation(getEndpointAnnotationType()) != null) {
|
||||
registerMethods(bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that registers the methods of the given bean. This method iterates over the methods of the bean,
|
||||
* and calls {@link #getActionForMethod(java.lang.reflect.Method)} for each. If this returns a URI, the method is
|
||||
* registered using {@link #registerEndpoint(java.net.URI, Object)}.
|
||||
*
|
||||
* @see #getActionForMethod (java.lang.reflect.Method)
|
||||
*/
|
||||
protected void registerMethods(Object endpoint) {
|
||||
Assert.notNull(endpoint, "'endpoint' must not be null");
|
||||
Method[] methods = AopUtils.getTargetClass(endpoint).getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (JdkVersion.isAtLeastJava15() && methods[i].isSynthetic() ||
|
||||
methods[i].getDeclaringClass().equals(Object.class)) {
|
||||
continue;
|
||||
}
|
||||
URI action = getActionForMethod(methods[i]);
|
||||
if (action != null) {
|
||||
registerEndpoint(action, new MethodEndpoint(endpoint, methods[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the action value for the specified method. Default implementation looks for the {@link Action} annotation
|
||||
* value.
|
||||
*/
|
||||
protected URI getActionForMethod(Method method) {
|
||||
Action action = method.getAnnotation(Action.class);
|
||||
if (action != null && StringUtils.hasText(action.value())) {
|
||||
try {
|
||||
return new URI(action.value());
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address property of the given {@link MethodEndpoint}, by looking for the {@link Address} annotation.
|
||||
* The value of this property should match the {@link org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo()
|
||||
* destination} of incoming messages. Returns <code>null</code> if the anotation is not present, thus ignoring the
|
||||
* destination property.
|
||||
*
|
||||
* @param endpoint the method endpoint to return the address for
|
||||
* @return the endpoint address; or <code>null</code> to ignore the destination property
|
||||
*/
|
||||
protected URI getEndpointAddress(Object endpoint) {
|
||||
MethodEndpoint methodEndpoint = (MethodEndpoint) endpoint;
|
||||
Class endpointClass = methodEndpoint.getMethod().getDeclaringClass();
|
||||
Address address = AnnotationUtils.findAnnotation(endpointClass, Address.class);
|
||||
if (address != null && StringUtils.hasText(address.value())) {
|
||||
try {
|
||||
return new URI(address.value());
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Address annotation [" + address.value() + "] on [" + endpointClass + "]");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.addressing;
|
||||
package org.springframework.ws.soap.addressing.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.MimeHeaders;
|
||||
import javax.xml.soap.SOAPConstants;
|
||||
import javax.xml.soap.SOAPException;
|
||||
|
||||
import org.custommonkey.xmlunit.XMLTestCase;
|
||||
import org.custommonkey.xmlunit.XMLUnit;
|
||||
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
@@ -30,16 +37,20 @@ import org.springframework.ws.soap.addressing.annotation.Address;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessage;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
|
||||
|
||||
public class AnnotationActionMethodEndpointMappingTest extends AbstractWsAddressingTestCase {
|
||||
public class AnnotationActionMethodEndpointMappingTest extends XMLTestCase {
|
||||
|
||||
private StaticApplicationContext applicationContext;
|
||||
|
||||
private AnnotationActionMethodEndpointMapping mapping;
|
||||
private AnnotationActionEndpointMapping mapping;
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
private MessageFactory messageFactory;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
|
||||
XMLUnit.setIgnoreWhitespace(true);
|
||||
applicationContext = new StaticApplicationContext();
|
||||
applicationContext.registerSingleton("mapping", AnnotationActionMethodEndpointMapping.class);
|
||||
mapping = (AnnotationActionMethodEndpointMapping) applicationContext.getBean("mapping");
|
||||
applicationContext.registerSingleton("mapping", AnnotationActionEndpointMapping.class);
|
||||
mapping = (AnnotationActionEndpointMapping) applicationContext.getBean("mapping");
|
||||
}
|
||||
|
||||
public void testNoAddress() throws Exception {
|
||||
@@ -65,8 +76,17 @@ public class AnnotationActionMethodEndpointMappingTest extends AbstractWsAddress
|
||||
}
|
||||
|
||||
private MessageContext createMessageContext() throws SOAPException, IOException {
|
||||
SaajSoapMessage message = loadSaajMessage("200408/valid.xml");
|
||||
return new DefaultMessageContext(message, new SaajSoapMessageFactory(messageFactory));
|
||||
MimeHeaders mimeHeaders = new MimeHeaders();
|
||||
mimeHeaders.addHeader("Content-Type", " application/soap+xml");
|
||||
InputStream is = getClass().getResourceAsStream("valid.xml");
|
||||
assertNotNull("Could not load valid.xml", is);
|
||||
try {
|
||||
SaajSoapMessage message = new SaajSoapMessage(messageFactory.createMessage(mimeHeaders, is));
|
||||
return new DefaultMessageContext(message, new SaajSoapMessageFactory(messageFactory));
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
@@ -0,0 +1,17 @@
|
||||
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:f123="http://www.fabrikam123.example/svc53">
|
||||
<S:Header>
|
||||
<wsa:MessageID>uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff</wsa:MessageID>
|
||||
<wsa:ReplyTo>
|
||||
<wsa:Address>http://example.com/business/client1</wsa:Address>
|
||||
</wsa:ReplyTo>
|
||||
<wsa:To S:mustUnderstand="true">mailto:joe@fabrikam123.example</wsa:To>
|
||||
<wsa:Action>http://fabrikam123.example/mail/Delete</wsa:Action>
|
||||
</S:Header>
|
||||
<S:Body>
|
||||
<f123:Delete>
|
||||
<maxCount>42</maxCount>
|
||||
</f123:Delete>
|
||||
</S:Body>
|
||||
</S:Envelope>
|
||||
Reference in New Issue
Block a user