diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/AbstractActionMethodEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/addressing/AbstractActionMethodEndpointMapping.java deleted file mode 100644 index 5d3c559e..00000000 --- a/core/src/main/java/org/springframework/ws/soap/addressing/AbstractActionMethodEndpointMapping.java +++ /dev/null @@ -1,78 +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.reflect.Method; -import java.net.URI; - -import org.springframework.aop.support.AopUtils; -import org.springframework.core.JdkVersion; -import org.springframework.util.Assert; -import org.springframework.ws.server.endpoint.MethodEndpoint; - -/** - * @author Arjen Poutsma - * @since 1.5.0 - */ -public abstract class AbstractActionMethodEndpointMapping extends AbstractActionEndpointMapping { - - /** - * Helper method that registers the methods of the given bean. This method iterates over the methods of the bean, - * and calls {@link #getActionForMethod(Method)} for each. If this returns a URI, the method is registered using - * {@link #registerEndpoint(URI, Object)}. - * - * @see #getActionForMethod (java.lang.reflect.Method) - */ - protected void registerMethods(Object endpoint) { - Assert.notNull(endpoint, "'endpoint' must not be null"); - Method[] methods = getEndpointClass(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 the action URI for the given method. Returns null if the method is not to be registered, - * which is the default. - * - * @param method the method - * @return the action URI, or null if the method is not to be registered - */ - protected URI getActionForMethod(Method method) { - return null; - } - - /** - * Return the class or interface to use for method reflection. - *

- * Default implementation delegates to {@link AopUtils#getTargetClass(Object)}. - * - * @param endpoint the bean instance (might be an AOP proxy) - * @return the bean class to expose - */ - protected Class getEndpointClass(Object endpoint) { - return AopUtils.getTargetClass(endpoint); - } - -} diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/EndpointReference.java b/core/src/main/java/org/springframework/ws/soap/addressing/core/EndpointReference.java similarity index 95% rename from core/src/main/java/org/springframework/ws/soap/addressing/EndpointReference.java rename to core/src/main/java/org/springframework/ws/soap/addressing/core/EndpointReference.java index 0470620c..9d9eb2e9 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/EndpointReference.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/core/EndpointReference.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ws.soap.addressing; +package org.springframework.ws.soap.addressing.core; import java.net.URI; import java.util.Collections; @@ -54,11 +54,11 @@ public final class EndpointReference { /** * Creates a new instance of the {@link EndpointReference} class with the given address, reference properties, and - * reference paramters. + * reference parameters. * * @param address the endpoint address * @param referenceProperties the reference properties, as a list of {@link Node} - * @param referenceProperties the reference parameters, as a list of {@link Node} + * @param referenceParameters the reference parameters, as a list of {@link Node} */ public EndpointReference(URI address, List referenceProperties, List referenceParameters) { Assert.notNull(address, "address must not be null"); diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/MessageAddressingProperties.java b/core/src/main/java/org/springframework/ws/soap/addressing/core/MessageAddressingProperties.java similarity index 81% rename from core/src/main/java/org/springframework/ws/soap/addressing/MessageAddressingProperties.java rename to core/src/main/java/org/springframework/ws/soap/addressing/core/MessageAddressingProperties.java index 3b6aa23d..6853205f 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/MessageAddressingProperties.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/core/MessageAddressingProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ws.soap.addressing; +package org.springframework.ws.soap.addressing.core; import java.net.URI; import java.util.Collections; @@ -76,6 +76,14 @@ public final class MessageAddressingProperties { this.referenceParameters = Collections.EMPTY_LIST; } + /** + * Constructs a new {@link MessageAddressingProperties} that forms a reply to the given EPR. + * + * @param epr the endpoint reference to create a reply for + * @param action the value of the action property + * @param messageId the value of the message id property + * @param relatesTo the value of the relates to property + */ private MessageAddressingProperties(EndpointReference epr, URI action, URI messageId, URI relatesTo) { this.to = epr.getAddress(); this.action = action; @@ -134,36 +142,25 @@ public final class MessageAddressingProperties { } /** - * Indicates whether is {@link MessageAddressingProperties} is valid, i.e. whether all required elements are - * listed. - *

- * Returns true if the to and action properties have been set, and - if a reply or fault endpoint has - * been set - also checks for the message id. + * Creates a {@link MessageAddressingProperties} that can be used for creating a reply to the given {@link + * EndpointReference}. The {@link #getTo() destination} property will be populated with the {@link + * EndpointReference#getAddress() address} of the given EPR, and the {@link #getRelatesTo() relationship} property + * will be set to the {@link #getMessageId() message id} property of this instance. the action is specified, the + * + * @param epr the endpoint reference to create a reply to + * @param action the action */ - public boolean isValid() { - if (to == null) { - return false; - } - if (action == null) { - return false; - } - if (replyTo != null || faultTo != null) { - return messageId != null; - } - return true; - } - public MessageAddressingProperties getReplyProperties(EndpointReference epr, URI action, URI messageId) { return new MessageAddressingProperties(epr, action, messageId, this.messageId); } /** - * Indicates whether is {@link MessageAddressingProperties} has all required properties. Returns true - * if the destination and action properties have been set, and if a reply or fault endpoint has been set, also - * checks for the message id. + * Indicates whether is {@link MessageAddressingProperties} has all required properties. + * + * @return true if the to and action properties have been set, and - if a reply or fault endpoint has + * been set - also checks for the message id */ public boolean hasRequiredProperties() { - // TODO: make sure this is handled according to the spec if (to == null) { return false; } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/core/package.html b/core/src/main/java/org/springframework/ws/soap/addressing/core/package.html new file mode 100644 index 00000000..c9432d84 --- /dev/null +++ b/core/src/main/java/org/springframework/ws/soap/addressing/core/package.html @@ -0,0 +1,6 @@ + + +Core package for WS-Addressing support. Contains the EndpointReference and +MessageAddressingProperties classes. + + diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/messageid/MessageIdStrategy.java b/core/src/main/java/org/springframework/ws/soap/addressing/messageid/MessageIdStrategy.java index 23c3e02e..afb1ce02 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/messageid/MessageIdStrategy.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/messageid/MessageIdStrategy.java @@ -18,7 +18,7 @@ package org.springframework.ws.soap.addressing.messageid; import java.net.URI; -import org.springframework.ws.context.MessageContext; +import org.springframework.ws.soap.SoapMessage; /** * Strategy interface that encapsulates the creation and validation of WS-Addressing MessageIDs. @@ -37,11 +37,11 @@ public interface MessageIdStrategy { boolean isDuplicate(URI messageId); /** - * Returns a new WS-Addressing MessageID for the {@link MessageContext#getResponse() response} in the - * given message context. + * Returns a new WS-Addressing MessageID for the given {@link SoapMessage}. * + * @param message the message to create an id for * @return the new message id */ - URI newMessageId(MessageContext messageContext); + URI newMessageId(SoapMessage message); } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/messageid/RandomGuidMessageIdStrategy.java b/core/src/main/java/org/springframework/ws/soap/addressing/messageid/RandomGuidMessageIdStrategy.java index 69f3e93a..03b41e94 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/messageid/RandomGuidMessageIdStrategy.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/messageid/RandomGuidMessageIdStrategy.java @@ -18,7 +18,7 @@ package org.springframework.ws.soap.addressing.messageid; import java.net.URI; -import org.springframework.ws.context.MessageContext; +import org.springframework.ws.soap.SoapMessage; /** * Implementation of the {@link MessageIdStrategy} interface that uses a {@link RandomGuid} to generate a Message Id. @@ -46,7 +46,7 @@ public class RandomGuidMessageIdStrategy implements MessageIdStrategy { return false; } - public URI newMessageId(MessageContext messageContext) { + public URI newMessageId(SoapMessage message) { return URI.create(PREFIX + new RandomGuid(secure).toString()); } } \ No newline at end of file diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdStrategy.java b/core/src/main/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdStrategy.java index 69aef428..a57c4494 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdStrategy.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdStrategy.java @@ -19,7 +19,7 @@ package org.springframework.ws.soap.addressing.messageid; import java.net.URI; import java.util.UUID; -import org.springframework.ws.context.MessageContext; +import org.springframework.ws.soap.SoapMessage; /** * Implementation of the {@link MessageIdStrategy} interface that uses a {@link UUID} to generate a Message Id. The UUID @@ -39,7 +39,7 @@ public class UuidMessageIdStrategy implements MessageIdStrategy { return false; } - public URI newMessageId(MessageContext messageContext) { + public URI newMessageId(SoapMessage message) { return URI.create(PREFIX + UUID.randomUUID().toString()); } } \ No newline at end of file diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/AbstractActionEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractActionEndpointMapping.java similarity index 75% rename from core/src/main/java/org/springframework/ws/soap/addressing/AbstractActionEndpointMapping.java rename to core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractActionEndpointMapping.java index e19c9a8c..19078ea6 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/AbstractActionEndpointMapping.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractActionEndpointMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ws.soap.addressing; +package org.springframework.ws.soap.addressing.server; import java.net.URI; import java.util.HashMap; @@ -24,8 +24,12 @@ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.util.Assert; +import org.springframework.ws.soap.addressing.core.MessageAddressingProperties; /** + * Abstract base class for WS-Addressing Action-mapped {@link org.springframework.ws.server.EndpointMapping} + * implementations. Provides infrastructure for mapping endpoints to actions. + * * @author Arjen Poutsma * @since 1.5.0 */ @@ -37,6 +41,31 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn private ApplicationContext applicationContext; + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + protected final Object getEndpointInternal(MessageAddressingProperties map) { + Object endpoint = lookupEndpoint(map.getAction()); + if (endpoint != null) { + URI endpointAddress = getEndpointAddress(endpoint); + if (endpointAddress == null || endpointAddress.equals(map.getTo())) { + return endpoint; + } + } + return null; + } + + /** + * Returns the address property of the given endpoint. The value of this property should match the {@link + * MessageAddressingProperties#getTo() destination} of incoming messages. May return null to ignore + * the destination. + * + * @param endpoint the endpoint to return the address for + * @return the endpoint address; or null to ignore the destination property + */ + protected abstract URI getEndpointAddress(Object endpoint); + /** * Looks up an endpoint instance for the given action. All keys are tried in order. * @@ -47,10 +76,6 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn return endpointMap.get(action); } - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - /** * Register the specified endpoint for the given action URI. * @@ -87,11 +112,5 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn } } - protected final Object getEndpointInternal(MessageAddressingProperties map) { - return getEndpointInternal(map.getTo(), map.getAction()); - } - - protected abstract Object getEndpointInternal(URI to, URI action); - } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/AbstractAddressingEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractAddressingEndpointMapping.java similarity index 79% rename from core/src/main/java/org/springframework/ws/soap/addressing/AbstractAddressingEndpointMapping.java rename to core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractAddressingEndpointMapping.java index a0f0ca86..9bf7bf66 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/AbstractAddressingEndpointMapping.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractAddressingEndpointMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ws.soap.addressing; +package org.springframework.ws.soap.addressing.server; import java.net.URI; import java.util.Arrays; @@ -31,16 +31,36 @@ import org.springframework.ws.server.EndpointMapping; import org.springframework.ws.soap.SoapHeader; import org.springframework.ws.soap.SoapHeaderElement; import org.springframework.ws.soap.SoapMessage; +import org.springframework.ws.soap.addressing.core.MessageAddressingProperties; import org.springframework.ws.soap.addressing.messageid.MessageIdStrategy; import org.springframework.ws.soap.addressing.messageid.RandomGuidMessageIdStrategy; import org.springframework.ws.soap.addressing.messageid.UuidMessageIdStrategy; +import org.springframework.ws.soap.addressing.version.WsAddressing200408; +import org.springframework.ws.soap.addressing.version.WsAddressing200605; +import org.springframework.ws.soap.addressing.version.WsAddressingVersion; import org.springframework.ws.soap.server.SoapEndpointInvocationChain; import org.springframework.ws.soap.server.SoapEndpointMapping; import org.springframework.ws.transport.WebServiceMessageSender; import org.springframework.xml.transform.TransformerObjectSupport; /** - * Abstract base class for {@link EndpointMapping} implementations that implement WS-Addressing. + * Abstract base class for {@link EndpointMapping} implementations that handle WS-Addressing. Besides the normal {@link + * SoapEndpointMapping} properties, this mapping has a {@link #setVersions(WsAddressingVersion[]) versions} property, + * which defines the WS-Addressing specifications supported. By default, these are {@link WsAddressing200408} and {@link + * WsAddressing200605}. + *

+ * The {@link #setMessageIdStrategy(MessageIdStrategy) messageIdStrategy} property defines the strategy to use for + * creating reply MessageIDs. By default, this is the {@link UuidMessageIdStrategy} on Java 5 and higher, + * and the {@link RandomGuidMessageIdStrategy} on Java 1.4. + *

+ * The {@link #setMessageSenders(WebServiceMessageSender[]) messageSenders} are used to send out-of-band reply messages. + * If a request messages defines a non-anonymous reply address, these senders will be used to send the message. + *

+ * This mapping (and all subclasses) uses an implicit WS-Addressing {@link EndpointInterceptor}, which is added in every + * {@link EndpointInvocationChain} produced. As such, this mapping does not have the standard interceptors + * property, but rather a {@link #setPreInterceptors(EndpointInterceptor[]) preInterceptors} and {@link + * #setPostInterceptors(EndpointInterceptor[]) postInterceptors} property, which are added before and after the implicit + * WS-Addressing interceptor, respectively. * * @author Arjen Poutsma * @since 1.5.0 @@ -54,7 +74,7 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec private MessageIdStrategy messageIdStrategy; - private WebServiceMessageSender[] messageSenders; + private WebServiceMessageSender[] messageSenders = new WebServiceMessageSender[0]; private WsAddressingVersion[] versions; @@ -115,16 +135,18 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec } /** - * Sets the message id provider used for creating WS-Addressing MessageIds. + * Sets the message id strategy used for creating WS-Addressing MessageIds. *

* By default, the {@link UuidMessageIdStrategy} is used on Java 5 and higher, and the {@link * RandomGuidMessageIdStrategy} on Java 1.4. */ - public final void setMessageIdProvider(MessageIdStrategy messageIdStrategy) { + public final void setMessageIdStrategy(MessageIdStrategy messageIdStrategy) { + Assert.notNull(messageIdStrategy, "'messageIdStrategy' must not be null"); this.messageIdStrategy = messageIdStrategy; } public final void setMessageSenders(WebServiceMessageSender[] messageSenders) { + Assert.notNull(messageSenders, "'messageSenders' must not be null"); this.messageSenders = messageSenders; } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/SimpleActionEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/addressing/server/SimpleActionEndpointMapping.java similarity index 86% rename from core/src/main/java/org/springframework/ws/soap/addressing/SimpleActionEndpointMapping.java rename to core/src/main/java/org/springframework/ws/soap/addressing/server/SimpleActionEndpointMapping.java index da6602d4..b56526eb 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/SimpleActionEndpointMapping.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/server/SimpleActionEndpointMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ws.soap.addressing; +package org.springframework.ws.soap.addressing.server; import java.net.URI; import java.net.URISyntaxException; @@ -41,12 +41,12 @@ import org.springframework.beans.BeansException; * The syntax is WS_ADDRESSING_ACTION=ENDPOINT_BEAN_NAME. *

* If set, the {@link #setAddress(URI) address} property should be equal to the {@link - * MessageAddressingProperties#getTo() destination} property of the incominging message. As such, it can be used to - * create multiple Endpoint References, by defining multiple SimpleActionEndpointMapping bean definitions - * with different addressproperty values. + * org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination} property of the + * incominging message. As such, it can be used to create multiple Endpoint References, by defining multiple + * SimpleActionEndpointMapping bean definitions with different address property values. * * @author Arjen Poutsma - * @see MessageAddressingProperties#getAction() + * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getAction() * @since 1.5.0 */ public class SimpleActionEndpointMapping extends AbstractActionEndpointMapping { @@ -93,7 +93,8 @@ public class SimpleActionEndpointMapping extends AbstractActionEndpointMapping { /** * Set the address property. If set, value of this property is compared to the {@link - * MessageAddressingProperties#getTo() destination} property of the incominging message. + * org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination} property of the + * incominging message. * * @param address the address URI */ @@ -106,14 +107,6 @@ public class SimpleActionEndpointMapping extends AbstractActionEndpointMapping { registerEndpoints(actionMap); } - protected Object getEndpointInternal(URI to, URI action) { - // MAP address much match the defined EPR address - if (address != null && !address.equals(to)) { - return null; - } - return lookupEndpoint(action); - } - /** * Register all endpoints specified in the action map. * @@ -139,4 +132,7 @@ public class SimpleActionEndpointMapping extends AbstractActionEndpointMapping { } } + protected URI getEndpointAddress(Object endpoint) { + return address; + } } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/server/package.html b/core/src/main/java/org/springframework/ws/soap/addressing/server/package.html new file mode 100644 index 00000000..80021d7b --- /dev/null +++ b/core/src/main/java/org/springframework/ws/soap/addressing/server/package.html @@ -0,0 +1,5 @@ + + +Contains servers-side WS-Addressing support, in the form of EndpointMappings. + + diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/version/package.html b/core/src/main/java/org/springframework/ws/soap/addressing/version/package.html new file mode 100644 index 00000000..6b9220b2 --- /dev/null +++ b/core/src/main/java/org/springframework/ws/soap/addressing/version/package.html @@ -0,0 +1,5 @@ + + +Contains abstractions over various versions of the WS-Addressing specification. + + \ No newline at end of file diff --git a/core/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingTestCase.java b/core/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingTestCase.java index 7e39844b..48f4dd46 100644 --- a/core/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingTestCase.java +++ b/core/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingTestCase.java @@ -33,7 +33,7 @@ public abstract class AbstractWsAddressingTestCase extends XMLTestCase { protected SaajSoapMessage loadSaajMessage(String fileName) throws SOAPException, IOException { MimeHeaders mimeHeaders = new MimeHeaders(); mimeHeaders.addHeader("Content-Type", " application/soap+xml"); - InputStream is = getClass().getResourceAsStream(fileName); + InputStream is = AbstractWsAddressingTestCase.class.getResourceAsStream(fileName); assertNotNull("Could not load " + fileName, is); try { return new SaajSoapMessage(messageFactory.createMessage(mimeHeaders, is));