diff --git a/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java b/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java index 410cf34d..bb3f6584 100644 --- a/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java +++ b/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java @@ -96,34 +96,45 @@ public class AnnotationActionEndpointMapping extends AbstractActionMethodEndpoin 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 getActionUri(address.value(), methodEndpoint); + } + else { + return null; } - return null; } protected URI getResponseAction(Object endpoint, MessageAddressingProperties map) { MethodEndpoint methodEndpoint = (MethodEndpoint) endpoint; Action action = methodEndpoint.getMethod().getAnnotation(Action.class); if (action != null && StringUtils.hasText(action.output())) { - try { - return new URI(action.output()); - } - catch (URISyntaxException e) { - throw new IllegalArgumentException( - "Invalid Action annotation [" + action.value() + "] on [" + methodEndpoint + "]"); - } + return getActionUri(action.output(), methodEndpoint); } else { return super.getResponseAction(endpoint, map); } } + protected URI getFaultAction(Object endpoint, MessageAddressingProperties map) { + MethodEndpoint methodEndpoint = (MethodEndpoint) endpoint; + Action action = methodEndpoint.getMethod().getAnnotation(Action.class); + if (action != null && StringUtils.hasText(action.fault())) { + return getActionUri(action.fault(), methodEndpoint); + } + else { + return super.getResponseAction(endpoint, map); + } + } + + private URI getActionUri(String action, MethodEndpoint methodEndpoint) { + try { + return new URI(action); + } + catch (URISyntaxException e) { + throw new IllegalArgumentException( + "Invalid Action annotation [" + action + "] on [" + methodEndpoint + "]"); + } + } + public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } diff --git a/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/annotation/Action.java b/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/annotation/Action.java index ef39e18f..76c425c9 100644 --- a/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/annotation/Action.java +++ b/core-tiger/src/main/java/org/springframework/ws/soap/addressing/server/annotation/Action.java @@ -40,4 +40,10 @@ public @interface Action { /** Signifies the value for the response WS-Addressing Action header that is provided by the method. */ String output() default ""; + /** + * Signifies the value for the fault response WS-Addressing Action header that is provided by the + * method. + */ + String fault() default ""; + } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractActionEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractActionEndpointMapping.java index 91ba23ae..bc3712ae 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractActionEndpointMapping.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractActionEndpointMapping.java @@ -31,7 +31,8 @@ import org.springframework.ws.soap.addressing.core.MessageAddressingProperties; * implementations. Provides infrastructure for mapping endpoints to actions. *

* By default, this mapping creates a Action for reply messages based on the request message, plus the - * extra {@link #setOutputActionSuffix(String) suffix}. + * extra {@link #setOutputActionSuffix(String) suffix}, and a * By default, this mapping creates a Action + * for reply messages based on the request message, plus the extra {@link #setOutputActionSuffix(String) suffix}. * * @author Arjen Poutsma * @since 1.5.0 @@ -39,26 +40,51 @@ import org.springframework.ws.soap.addressing.core.MessageAddressingProperties; public abstract class AbstractActionEndpointMapping extends AbstractAddressingEndpointMapping implements ApplicationContextAware { - /** The defaults suffix to add to request Action for reply messages. */ + /** The defaults suffix to add to the request Action for reply messages. */ public static final String DEFAULT_OUTPUT_ACTION_SUFFIX = "Response"; + /** The defaults suffix to add to response Action for reply messages. */ + public static final String DEFAULT_FAULT_ACTION_SUFFIX = "Fault"; + // keys are action URIs, values are endpoints private final Map endpointMap = new HashMap(); private String outputActionSuffix = DEFAULT_OUTPUT_ACTION_SUFFIX; + private String faultActionSuffix = DEFAULT_OUTPUT_ACTION_SUFFIX; + private ApplicationContext applicationContext; + /** Returns the suffix to add to request Actions for reply messages. */ + public String getOutputActionSuffix() { + return outputActionSuffix; + } + /** * Sets the suffix to add to request Actions for reply messages. * * @see #DEFAULT_OUTPUT_ACTION_SUFFIX */ public void setOutputActionSuffix(String outputActionSuffix) { - Assert.hasText(outputActionSuffix, "'replyActionSuffix' must not be empty"); + Assert.hasText(outputActionSuffix, "'outputActionSuffix' must not be empty"); this.outputActionSuffix = outputActionSuffix; } + /** Returns the suffix to add to request Actions for reply fault messages. */ + public String getFaultActionSuffix() { + return faultActionSuffix; + } + + /** + * Sets the suffix to add to request Actions for reply fault messages. + * + * @see #DEFAULT_FAULT_ACTION_SUFFIX + */ + public void setFaultActionSuffix(String faultActionSuffix) { + Assert.hasText(faultActionSuffix, "'faultActionSuffix' must not be empty"); + this.faultActionSuffix = faultActionSuffix; + } + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @@ -137,10 +163,21 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn protected URI getResponseAction(Object endpoint, MessageAddressingProperties requestMap) { URI requestAction = requestMap.getAction(); if (requestAction != null) { - return URI.create(requestAction.toString() + outputActionSuffix); + return URI.create(requestAction.toString() + getOutputActionSuffix()); } else { return null; } } + + protected URI getFaultAction(Object endpoint, MessageAddressingProperties requestMap) { + URI requestAction = requestMap.getAction(); + if (requestAction != null) { + return URI.create(requestAction.toString() + getFaultActionSuffix()); + } + else { + return null; + } + } + } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractAddressingEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractAddressingEndpointMapping.java index b299f654..a5006e98 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractAddressingEndpointMapping.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/server/AbstractAddressingEndpointMapping.java @@ -198,11 +198,12 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec AddressingVersion version, MessageAddressingProperties requestMap) { URI responseAction = getResponseAction(endpoint, requestMap); + URI faultAction = getFaultAction(endpoint, requestMap); EndpointInterceptor[] interceptors = new EndpointInterceptor[preInterceptors.length + postInterceptors.length + 1]; System.arraycopy(preInterceptors, 0, interceptors, 0, preInterceptors.length); - AddressingEndpointInterceptor interceptor = - new AddressingEndpointInterceptor(version, messageIdStrategy, messageSenders, responseAction, null); + AddressingEndpointInterceptor interceptor = new AddressingEndpointInterceptor(version, messageIdStrategy, + messageSenders, responseAction, faultAction); interceptors[preInterceptors.length] = interceptor; System.arraycopy(postInterceptors, 0, interceptors, preInterceptors.length + 1, postInterceptors.length); return new SoapEndpointInvocationChain(endpoint, interceptors, actorsOrRoles, isUltimateReceiver); @@ -230,6 +231,24 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec */ protected abstract Object getEndpointInternal(MessageAddressingProperties map); + /** + * Provides the WS-Addressing Action for response messages, given the endpoint, and request Message Addressing + * Properties. + * + * @param endpoint the mapped endpoint + * @param requestMap the MAP for the request + * @return the response Action + */ protected abstract URI getResponseAction(Object endpoint, MessageAddressingProperties requestMap); + /** + * Provides the WS-Addressing Action for response fault messages, given the endpoint, and request Message Addressing + * Properties. + * + * @param endpoint the mapped endpoint + * @param requestMap the MAP for the request + * @return the response Action + */ + protected abstract URI getFaultAction(Object endpoint, MessageAddressingProperties requestMap); + } diff --git a/core/src/main/java/org/springframework/ws/soap/addressing/server/AddressingEndpointInterceptor.java b/core/src/main/java/org/springframework/ws/soap/addressing/server/AddressingEndpointInterceptor.java index a6e8b80f..3ceeaba4 100644 --- a/core/src/main/java/org/springframework/ws/soap/addressing/server/AddressingEndpointInterceptor.java +++ b/core/src/main/java/org/springframework/ws/soap/addressing/server/AddressingEndpointInterceptor.java @@ -104,7 +104,7 @@ class AddressingEndpointInterceptor implements SoapEndpointInterceptor { } SoapMessage reply = (SoapMessage) messageContext.getResponse(); URI replyMessageId = getMessageId(reply); - URI action = !isFault ? replyAction : faultAction; + URI action = isFault ? faultAction : replyAction; MessageAddressingProperties replyMap = requestMap.getReplyProperties(replyEpr, action, replyMessageId); version.addAddressingHeaders(reply, replyMap); if (handleAnonymousAddress(messageContext, replyEpr)) {