diff --git a/core-tiger/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionAnnotationMethodEndpointMapping.java b/core-tiger/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionAnnotationMethodEndpointMapping.java index bc087619..a8efbc0b 100644 --- a/core-tiger/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionAnnotationMethodEndpointMapping.java +++ b/core-tiger/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionAnnotationMethodEndpointMapping.java @@ -24,9 +24,9 @@ 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.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.SoapEndpointMapping; import org.springframework.ws.soap.server.endpoint.annotation.SoapAction; /** diff --git a/core/src/main/java/org/springframework/ws/server/EndpointInterceptor.java b/core/src/main/java/org/springframework/ws/server/EndpointInterceptor.java index 50ea2a9d..a64fca77 100644 --- a/core/src/main/java/org/springframework/ws/server/EndpointInterceptor.java +++ b/core/src/main/java/org/springframework/ws/server/EndpointInterceptor.java @@ -23,14 +23,15 @@ import org.springframework.ws.context.MessageContext; * existing or custom interceptors for certain groups of endpoints, to add common preprocessing behavior without needing * to modify each endpoint implementation. *
- * AEndpointInterceptor gets called before the appropriate EndpointAdapter triggers the
- * invocation of the endpoint itself. This mechanism can be used for a large field of preprocessing aspects, e.g. for
- * authorization checks, or message header checks. Its main purpose is to allow for factoring out repetitive endpoint
- * code.
+ * A EndpointInterceptor gets called before the appropriate {@link EndpointAdapter} triggers the invocation
+ * of the endpoint itself. This mechanism can be used for a large field of preprocessing aspects, e.g. for authorization
+ * checks, or message header checks. Its main purpose is to allow for factoring out repetitive endpoint code.
*
- * Typically an interceptor chain is defined per EndpointMapping bean, sharing its granularity. To be able
- * to apply a certain interceptor chain to a group of handlers, one needs to map the desired handlers via one
- * EndpointMapping bean.
+ * Typically an interceptor chain is defined per {@link EndpointMapping} bean, sharing its granularity. To be able to
+ * apply a certain interceptor chain to a group of handlers, one needs to map the desired handlers via one
+ * EndpointMapping bean.The interceptors themselves are defined as beans in the application context,
+ * referenced by the mapping bean definition via its interceptors property (in XML: a <list> of
+ * <ref>).
*
* @author Arjen Poutsma
* @see EndpointInvocationChain#getInterceptors()
@@ -40,23 +41,57 @@ import org.springframework.ws.context.MessageContext;
public interface EndpointInterceptor {
/**
- * Processes the incoming request message.
+ * Processes the incoming request message. Called after {@link EndpointMapping} determined an appropriate endpoint
+ * object, but before {@link EndpointAdapter} invokes the endpoint.
+ *
+ * {@link MessageDispatcher} processes an endpoint in an invocation chain, consisting of any number of interceptors,
+ * with the endpoint itself at the end. With this method, each interceptor can decide to abort the chain, typically
+ * creating a custom response.
*
* @param messageContext contains the incoming request message
* @param endpoint chosen endpoint to invoke
* @return true to continue processing of the request interceptor chain; false to indicate
- * blocking of the request handler chain, without invoking the endpoint
+ * blocking of the request endpoint chain, without invoking the endpoint
+ * @throws Exception in case of errors
+ * @see org.springframework.ws.context.MessageContext#getRequest()
*/
boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception;
/**
- * Processes the outgoing response message.
+ * Processes the outgoing response message. Called after {@link EndpointAdapter} actually invoked the endpoint. Can
+ * manipulate the response, if any, by adding new headers, etc.
+ *
+ * {@link MessageDispatcher} processes an endpoint in an invocation chain, consisting of any number of interceptors,
+ * with the endpoint itself at the end. With this method, each interceptor can post-process an invocation, getting
+ * applied in inverse order of the execution chain.
+ *
+ * Note: Will only be called if this interceptor's {@link #handleRequest} method has successfully completed.
*
* @param messageContext contains both request and response messages
* @param endpoint chosen endpoint to invoke
* @return true to continue processing of the reponse interceptor chain; false to indicate
- * blocking of the response handler chain.
+ * blocking of the response endpoint chain.
+ * @throws Exception in case of errors
+ * @see org.springframework.ws.context.MessageContext#getRequest()
+ * @see org.springframework.ws.context.MessageContext#hasResponse()
+ * @see org.springframework.ws.context.MessageContext#getResponse()
*/
boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception;
+ /**
+ * Processes the outgoing response fault. Called after {@link EndpointAdapter} actually invoked the endpoint. Can
+ * manipulate the response, if any, by adding new headers, etc.
+ *
+ * {@link MessageDispatcher} processes an endpoint in an invocation chain, consisting of any number of interceptors,
+ * with the endpoint itself at the end. With this method, each interceptor can post-process an invocation, getting
+ * applied in inverse order of the execution chain.
+ *
+ * Note: Will only be called if this interceptor's {@link #handleRequest} method has successfully completed.
+ *
+ * @param messageContext contains both request and response messages, the response should contains a Fault
+ * @param endpoint chosen endpoint to invoke
+ * @return true to continue processing of the reponse interceptor chain; false to indicate
+ * blocking of the response handler chain.
+ */
+ boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception;
}
diff --git a/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java b/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java
index c315bd59..f4adb1ef 100644
--- a/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java
+++ b/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java
@@ -179,7 +179,7 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
return;
}
// Apply handleRequest of registered interceptors
- if (!ObjectUtils.isEmpty(mappedEndpoint.getInterceptors())) {
+ if (mappedEndpoint.getInterceptors() != null) {
for (int i = 0; i < mappedEndpoint.getInterceptors().length; i++) {
EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
interceptorIndex = i;
@@ -303,15 +303,21 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa
* @param messageContext the message context, whose request and response are filled
* @see EndpointInterceptor#handleResponse(MessageContext,Object)
*/
- protected void triggerHandleResponse(EndpointInvocationChain mappedEndpoint,
- int interceptorIndex,
- MessageContext messageContext) throws Exception {
+ private void triggerHandleResponse(EndpointInvocationChain mappedEndpoint,
+ int interceptorIndex,
+ MessageContext messageContext) throws Exception {
if (mappedEndpoint != null && messageContext.hasResponse() &&
!ObjectUtils.isEmpty(mappedEndpoint.getInterceptors())) {
boolean resume = true;
+ boolean hasFault = messageContext.getResponse().hasFault();
for (int i = interceptorIndex; resume && i >= 0; i--) {
EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
- resume = interceptor.handleResponse(messageContext, mappedEndpoint.getEndpoint());
+ if (!hasFault) {
+ resume = interceptor.handleResponse(messageContext, mappedEndpoint.getEndpoint());
+ }
+ else {
+ resume = interceptor.handleFault(messageContext, mappedEndpoint.getEndpoint());
+ }
}
}
}
diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractLoggingInterceptor.java b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractLoggingInterceptor.java
index ba259ee3..4950dce9 100644
--- a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractLoggingInterceptor.java
+++ b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractLoggingInterceptor.java
@@ -42,16 +42,12 @@ public abstract class AbstractLoggingInterceptor extends TransformerObjectSuppor
private boolean logResponse = true;
- /**
- * Indicates whether the request should be logged. Default is true.
- */
+ /** Indicates whether the request should be logged. Default is true. */
public final void setLogRequest(boolean logRequest) {
this.logRequest = logRequest;
}
- /**
- * Indicates whether the response should be logged. Default is true.
- */
+ /** Indicates whether the response should be logged. Default is true. */
public final void setLogResponse(boolean logResponse) {
this.logResponse = logResponse;
}
@@ -86,6 +82,11 @@ public abstract class AbstractLoggingInterceptor extends TransformerObjectSuppor
return true;
}
+ /** Does nothing by default. Faults are not logged. */
+ public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
+ return true;
+ }
+
private Transformer createNonIndentingTransformer() throws TransformerConfigurationException {
Transformer transformer = createTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/AbstractValidatingInterceptor.java b/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/AbstractValidatingInterceptor.java
index 2140cf42..a08798b1 100644
--- a/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/AbstractValidatingInterceptor.java
+++ b/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/AbstractValidatingInterceptor.java
@@ -111,6 +111,18 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
this.validateResponse = validateResponse;
}
+ public void afterPropertiesSet() throws Exception {
+ Assert.notEmpty(schemas, "setting either the schema or schemas property is required");
+ Assert.hasLength(schemaLanguage, "schemaLanguage is required");
+ for (int i = 0; i < schemas.length; i++) {
+ Assert.isTrue(schemas[i].exists(), "schema [" + schemas[i] + "] does not exist");
+ }
+ if (logger.isInfoEnabled()) {
+ logger.info("Validating using " + StringUtils.arrayToCommaDelimitedString(schemas));
+ }
+ validator = XmlValidatorFactory.createValidator(schemas, schemaLanguage);
+ }
+
/**
* Validates the request message in the given message context. Validation only occurs if
* validateRequest is set to true, which is the default.
@@ -196,16 +208,9 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
return false;
}
- public void afterPropertiesSet() throws Exception {
- Assert.notEmpty(schemas, "setting either the schema or schemas property is required");
- Assert.hasLength(schemaLanguage, "schemaLanguage is required");
- for (int i = 0; i < schemas.length; i++) {
- Assert.isTrue(schemas[i].exists(), "schema [" + schemas[i] + "] does not exist");
- }
- if (logger.isInfoEnabled()) {
- logger.info("Validating using " + StringUtils.arrayToCommaDelimitedString(schemas));
- }
- validator = XmlValidatorFactory.createValidator(schemas, schemaLanguage);
+ /** Does nothing by default. Faults are not validated. */
+ public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
+ return true;
}
/**
diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java b/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java
index 5c665b41..ff9e2092 100644
--- a/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java
+++ b/core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java
@@ -56,16 +56,12 @@ public class PayloadTransformingInterceptor implements EndpointInterceptor, Init
private Templates responseTemplates;
- /**
- * Sets the XSLT stylesheet to use for transforming incoming request.
- */
+ /** Sets the XSLT stylesheet to use for transforming incoming request. */
public void setRequestXslt(Resource requestXslt) {
this.requestXslt = requestXslt;
}
- /**
- * Sets the XSLT stylesheet to use for transforming outgoing responses.
- */
+ /** Sets the XSLT stylesheet to use for transforming outgoing responses. */
public void setResponseXslt(Resource responseXslt) {
this.responseXslt = responseXslt;
}
@@ -106,6 +102,11 @@ public class PayloadTransformingInterceptor implements EndpointInterceptor, Init
return true;
}
+ /** Does nothing by default. Faults are not transformed. */
+ public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
+ return true;
+ }
+
public void afterPropertiesSet() throws Exception {
if (requestXslt == null && responseXslt == null) {
throw new IllegalArgumentException("Setting either 'requestXslt' or 'responseXslt' is required");
diff --git a/core/src/main/java/org/springframework/ws/soap/SoapElement.java b/core/src/main/java/org/springframework/ws/soap/SoapElement.java
index ace3ccb5..87cfb582 100644
--- a/core/src/main/java/org/springframework/ws/soap/SoapElement.java
+++ b/core/src/main/java/org/springframework/ws/soap/SoapElement.java
@@ -51,6 +51,13 @@ public interface SoapElement {
*/
void addAttribute(QName name, String value);
+ /**
+ * Removes the attribute with the specified name.
+ *
+ * @param name the qualified name of the attribute to remove
+ */
+ void removeAttribute(QName name);
+
/**
* Returns the value of the attribute with the specified qualified name.
*
@@ -66,5 +73,4 @@ public interface SoapElement {
*/
Iterator getAllAttibutes();
-
}
diff --git a/core/src/main/java/org/springframework/ws/soap/SoapHeader.java b/core/src/main/java/org/springframework/ws/soap/SoapHeader.java
index cb37982c..e4237a16 100644
--- a/core/src/main/java/org/springframework/ws/soap/SoapHeader.java
+++ b/core/src/main/java/org/springframework/ws/soap/SoapHeader.java
@@ -69,13 +69,4 @@ public interface SoapHeader extends SoapElement {
*/
Iterator examineAllHeaderElements() throws SoapHeaderException;
- /**
- * Returns an Iterator over all the SoapHeaderElements with the specified header.
- *
- * @param name the qualified name of header elements to look for
- * @return an iterator over all the header elements
- * @throws SoapHeaderException if the header cannot be returned
- * @see SoapHeaderElement
- */
- Iterator examineHeaderElements(QName name) throws SoapHeaderException;
}
diff --git a/core/src/main/java/org/springframework/ws/soap/SoapHeaderElement.java b/core/src/main/java/org/springframework/ws/soap/SoapHeaderElement.java
index 0cc5fbf5..465b1379 100644
--- a/core/src/main/java/org/springframework/ws/soap/SoapHeaderElement.java
+++ b/core/src/main/java/org/springframework/ws/soap/SoapHeaderElement.java
@@ -59,9 +59,20 @@ public interface SoapHeaderElement extends SoapElement {
*/
void setMustUnderstand(boolean mustUnderstand) throws SoapHeaderException;
- /**
- * Returns a Result that allows for writing to the contents of the header element.
- */
+ /** Returns a Result that allows for writing to the contents of the header element. */
Result getResult() throws SoapHeaderException;
+ /**
+ * Returns the text content of this header element, if any.
+ *
+ * @return the text content of this header element
+ */
+ String getText();
+
+ /**
+ * Sets the text content of this header element.
+ *
+ * @param content the new text content of this header element
+ */
+ void setText(String content);
}
diff --git a/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapElement.java b/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapElement.java
index ec09dfae..1333e0ce 100644
--- a/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapElement.java
+++ b/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapElement.java
@@ -79,6 +79,18 @@ class AxiomSoapElement implements SoapElement {
}
}
+ public void removeAttribute(QName name) {
+ try {
+ OMAttribute attribute = getAxiomElement().getAttribute(name);
+ if (attribute != null) {
+ getAxiomElement().removeAttribute(attribute);
+ }
+ }
+ catch (OMException ex) {
+ throw new AxiomSoapElementException(ex);
+ }
+ }
+
public final String getAttributeValue(QName name) {
try {
return getAxiomElement().getAttributeValue(name);
diff --git a/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapHeaderElement.java b/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapHeaderElement.java
index 5fd0cad9..6d4f565e 100644
--- a/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapHeaderElement.java
+++ b/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapHeaderElement.java
@@ -57,6 +57,14 @@ class AxiomSoapHeaderElement extends AxiomSoapElement implements SoapHeaderEleme
}
+ public String getText() {
+ return getAxiomHeaderBlock().getText();
+ }
+
+ public void setText(String content) {
+ getAxiomHeaderBlock().setText(content);
+ }
+
protected SOAPHeaderBlock getAxiomHeaderBlock() {
return (SOAPHeaderBlock) getAxiomElement();
}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj11Implementation.java b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj11Implementation.java
index 06b3c04e..eda9887d 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj11Implementation.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj11Implementation.java
@@ -81,11 +81,24 @@ public class Saaj11Implementation implements SaajImplementation {
return new SAXResult(new SaajContentHandler(element));
}
+ public String getText(SOAPElement element) {
+ return element.getValue();
+ }
+
+ public void setText(SOAPElement element, String content) throws SOAPException {
+ element.addTextNode(content);
+ }
+
public void addAttribute(SOAPElement element, QName name, String value) throws SOAPException {
Name attributeName = SaajUtils.toName(name, element);
element.addAttribute(attributeName, value);
}
+ public void removeAttribute(SOAPElement element, QName name) throws SOAPException {
+ Name attributeName = SaajUtils.toName(name, element);
+ element.removeAttribute(attributeName);
+ }
+
public String getAttributeValue(SOAPElement element, QName name) throws SOAPException {
Name attributeName = SaajUtils.toName(name, element);
return element.getAttributeValue(attributeName);
@@ -100,11 +113,6 @@ public class Saaj11Implementation implements SaajImplementation {
return results.iterator();
}
- public Iterator getChildElements(SOAPElement element, QName name) throws SOAPException {
- Name childName = SaajUtils.toName(name, element);
- return element.getChildElements(childName);
- }
-
public QName getFaultCode(SOAPFault fault) {
String code = fault.getFaultCode();
int idx = code.indexOf(':');
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj12Implementation.java b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj12Implementation.java
index a1f09f3e..f38862cb 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj12Implementation.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj12Implementation.java
@@ -109,6 +109,11 @@ public class Saaj12Implementation implements SaajImplementation {
element.addAttribute(attributeName, value);
}
+ public void removeAttribute(SOAPElement element, QName name) throws SOAPException {
+ Name attributeName = SaajUtils.toName(name, element);
+ element.removeAttribute(attributeName);
+ }
+
public String getAttributeValue(SOAPElement element, QName name) throws SOAPException {
Name attributeName = SaajUtils.toName(name, element);
return element.getAttributeValue(attributeName);
@@ -123,9 +128,12 @@ public class Saaj12Implementation implements SaajImplementation {
return results.iterator();
}
- public Iterator getChildElements(SOAPElement element, QName name) throws SOAPException {
- Name childName = SaajUtils.toName(name, element);
- return element.getChildElements(childName);
+ public String getText(SOAPElement element) {
+ return element.getValue();
+ }
+
+ public void setText(SOAPElement element, String content) {
+ element.setValue(content);
}
public SOAPEnvelope getEnvelope(SOAPMessage message) throws SOAPException {
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj13Implementation.java b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj13Implementation.java
index 07f08c71..48f83156 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj13Implementation.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj13Implementation.java
@@ -139,10 +139,22 @@ public class Saaj13Implementation implements SaajImplementation {
return new DOMResult(element);
}
+ public String getText(SOAPElement element) {
+ return element.getValue();
+ }
+
+ public void setText(SOAPElement element, String content) {
+ element.setValue(content);
+ }
+
public void addAttribute(SOAPElement element, QName name, String value) throws SOAPException {
element.addAttribute(name, value);
}
+ public void removeAttribute(SOAPElement element, QName name) throws SOAPException {
+ element.removeAttribute(name);
+ }
+
public String getAttributeValue(SOAPElement element, QName name) throws SOAPException {
return element.getAttributeValue(name);
}
@@ -151,10 +163,6 @@ public class Saaj13Implementation implements SaajImplementation {
return element.getAllAttributesAsQNames();
}
- public Iterator getChildElements(SOAPElement element, QName name) throws SOAPException {
- return element.getChildElements(name);
- }
-
public SOAPEnvelope getEnvelope(SOAPMessage message) throws SOAPException {
return message.getSOAPPart().getEnvelope();
}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajImplementation.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajImplementation.java
index e13f3975..db1a7a26 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/SaajImplementation.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajImplementation.java
@@ -53,18 +53,24 @@ public interface SaajImplementation {
/** Returns the writable Result of the given element. */
Result getResult(SOAPElement element);
+ /** Returns the text of the given element */
+ String getText(SOAPElement element);
+
+ /** Returns the text of the given element */
+ void setText(SOAPElement element, String content) throws SOAPException;
+
/** Adds an attribute to the specified element. */
void addAttribute(SOAPElement element, QName name, String value) throws SOAPException;
+ /** Removes an attribute from the specified element. */
+ void removeAttribute(SOAPElement element, QName name) throws SOAPException;
+
/** Returns the attribute value * */
String getAttributeValue(SOAPElement element, QName name) throws SOAPException;
/** Returns all attributes as an iterator of QNames. * */
Iterator getAllAttibutes(SOAPElement element);
- /** Returns an iterator over the child elements with the given name. */
- Iterator getChildElements(SOAPElement element, QName name) throws SOAPException;
-
/** Returns the envelope of the given message. */
SOAPEnvelope getEnvelope(SOAPMessage message) throws SOAPException;
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapElement.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapElement.java
index 1f67bdbd..2aefd1dc 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapElement.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapElement.java
@@ -57,6 +57,15 @@ class SaajSoapElement implements SoapElement {
}
}
+ public void removeAttribute(QName name) {
+ try {
+ getImplementation().removeAttribute(element, name);
+ }
+ catch (SOAPException ex) {
+ throw new SaajSoapElementException(ex);
+ }
+ }
+
public String getAttributeValue(QName name) {
try {
return getImplementation().getAttributeValue(element, name);
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeader.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeader.java
index 77c31e9a..620358f1 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeader.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeader.java
@@ -44,16 +44,6 @@ class SaajSoapHeader extends SaajSoapElement implements SoapHeader {
return new SaajSoapHeaderElementIterator(iterator);
}
- public Iterator examineHeaderElements(QName name) throws SoapHeaderException {
- try {
- Iterator iterator = getImplementation().getChildElements(getSaajHeader(), name);
- return new SaajSoapHeaderElementIterator(iterator);
- }
- catch (SOAPException ex) {
- throw new SaajSoapHeaderException(ex);
- }
- }
-
public Iterator examineMustUnderstandHeaderElements(String actorOrRole) throws SoapHeaderException {
Iterator iterator = getImplementation().examineMustUnderstandHeaderElements(getSaajHeader(), actorOrRole);
return new SaajSoapHeaderElementIterator(iterator);
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeaderElement.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeaderElement.java
index 6e9760d4..bf8fc973 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeaderElement.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeaderElement.java
@@ -16,6 +16,7 @@
package org.springframework.ws.soap.saaj;
+import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.transform.Result;
@@ -54,6 +55,19 @@ class SaajSoapHeaderElement extends SaajSoapElement implements SoapHeaderElement
getImplementation().setMustUnderstand(getSaajHeaderElement(), mustUnderstand);
}
+ public String getText() {
+ return getImplementation().getText(getSaajHeaderElement());
+ }
+
+ public void setText(String content) {
+ try {
+ getImplementation().setText(getSaajHeaderElement(), content);
+ }
+ catch (SOAPException ex) {
+ throw new SaajSoapHeaderException(ex);
+ }
+ }
+
protected SOAPHeaderElement getSaajHeaderElement() {
return (SOAPHeaderElement) getSaajElement();
}
diff --git a/core/src/main/java/org/springframework/ws/soap/SoapEndpointInterceptor.java b/core/src/main/java/org/springframework/ws/soap/server/SoapEndpointInterceptor.java
similarity index 64%
rename from core/src/main/java/org/springframework/ws/soap/SoapEndpointInterceptor.java
rename to core/src/main/java/org/springframework/ws/soap/server/SoapEndpointInterceptor.java
index ebc0b892..4491516f 100644
--- a/core/src/main/java/org/springframework/ws/soap/SoapEndpointInterceptor.java
+++ b/core/src/main/java/org/springframework/ws/soap/server/SoapEndpointInterceptor.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package org.springframework.ws.soap;
+package org.springframework.ws.soap.server;
-import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
+import org.springframework.ws.soap.SoapHeaderElement;
/**
* SOAP-specific extension of the EndpointInterceptor interface. Allows for handling of SOAP faults, which
@@ -27,17 +27,6 @@ import org.springframework.ws.server.EndpointInterceptor;
*/
public interface SoapEndpointInterceptor extends EndpointInterceptor {
- /**
- * Processes the fault. Both request and response of the message context should be filled; the body of the response
- * message contains the fault.
- *
- * @param messageContext contains both request and response messages, the response should contains a SOAP Fault
- * @param endpoint chosen endpoint to invoke
- * @return true to continue processing of the reponse interceptor chain; false to indicate
- * blocking of the response handler chain.
- */
- boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception;
-
/**
* Given a SoapHeaderElement, return whether or not this SoapEndpointInterceptor
* understands it.
diff --git a/core/src/main/java/org/springframework/ws/soap/SoapEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/server/SoapEndpointMapping.java
similarity index 81%
rename from core/src/main/java/org/springframework/ws/soap/SoapEndpointMapping.java
rename to core/src/main/java/org/springframework/ws/soap/server/SoapEndpointMapping.java
index a6b6f6fc..0d4ead82 100644
--- a/core/src/main/java/org/springframework/ws/soap/SoapEndpointMapping.java
+++ b/core/src/main/java/org/springframework/ws/soap/server/SoapEndpointMapping.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.ws.soap;
+package org.springframework.ws.soap.server;
import org.springframework.ws.server.EndpointMapping;
@@ -30,14 +30,10 @@ import org.springframework.ws.server.EndpointMapping;
*/
public interface SoapEndpointMapping extends EndpointMapping {
- /**
- * Sets a single SOAP actor/actorOrRole to apply to all endpoints mapped by the delegate endpoint mapping.
- */
+ /** Sets a single SOAP actor/actorOrRole to apply to all endpoints mapped by the delegate endpoint mapping. */
void setActorOrRole(String actorOrRole);
- /**
- * Sets the array of SOAP actors/actorsOrRoles to apply to all endpoints mapped by the delegate endpoint mapping.
- */
+ /** Sets the array of SOAP actors/actorsOrRoles to apply to all endpoints mapped by the delegate endpoint mapping. */
void setActorsOrRoles(String[] actorsOrRoles);
}
diff --git a/core/src/main/java/org/springframework/ws/soap/server/SoapMessageDispatcher.java b/core/src/main/java/org/springframework/ws/soap/server/SoapMessageDispatcher.java
index 2dd18110..a21993b2 100644
--- a/core/src/main/java/org/springframework/ws/soap/server/SoapMessageDispatcher.java
+++ b/core/src/main/java/org/springframework/ws/soap/server/SoapMessageDispatcher.java
@@ -22,14 +22,12 @@ import java.util.List;
import java.util.Locale;
import javax.xml.namespace.QName;
-import org.springframework.util.ObjectUtils;
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.MessageDispatcher;
import org.springframework.ws.soap.SoapBody;
-import org.springframework.ws.soap.SoapEndpointInterceptor;
import org.springframework.ws.soap.SoapFault;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapHeaderElement;
@@ -43,13 +41,11 @@ import org.springframework.ws.soap.soap12.Soap12Header;
*
* @author Arjen Poutsma
* @see org.springframework.ws.soap.SoapMessage
- * @see org.springframework.ws.soap.SoapEndpointInterceptor
+ * @see SoapEndpointInterceptor
*/
public class SoapMessageDispatcher extends MessageDispatcher {
- /**
- * Default message used when creating a SOAP MustUnderstand fault.
- */
+ /** Default message used when creating a SOAP MustUnderstand fault. */
public static final String DEFAULT_MUST_UNDERSTAND_FAULT =
"One or more mandatory SOAP header blocks not understood";
@@ -130,7 +126,7 @@ public class SoapMessageDispatcher extends MessageDispatcher {
* SoapEndpointInterceptor. If they are, returns true. If they are not, a SOAP fault is
* created, and false is returned.
*
- * @see org.springframework.ws.soap.SoapEndpointInterceptor#understands(org.springframework.ws.soap.SoapHeaderElement)
+ * @see SoapEndpointInterceptor#understands(org.springframework.ws.soap.SoapHeaderElement)
*/
private boolean handleRequestForRole(EndpointInvocationChain mappedEndpoint,
MessageContext messageContext,
@@ -180,41 +176,4 @@ public class SoapMessageDispatcher extends MessageDispatcher {
return false;
}
}
-
- /**
- * Trigger handleResponse or handleFault on the mapped EndpointInterceptors. Will just invoke said method on all
- * interceptors whose handleRequest invocation returned true, in addition to the last interceptor who
- * returned false.
- *
- * @param mappedEndpoint the mapped EndpointInvocationChain
- * @param interceptorIndex index of last interceptor that was called
- * @param messageContext the message context, whose request and response are filled
- * @see org.springframework.ws.server.EndpointInterceptor#handleResponse(org.springframework.ws.context.MessageContext,
- *Object)
- */
- protected void triggerHandleResponse(EndpointInvocationChain mappedEndpoint,
- int interceptorIndex,
- MessageContext messageContext) throws Exception {
- if (mappedEndpoint != null && messageContext.hasResponse() &&
- !ObjectUtils.isEmpty(mappedEndpoint.getInterceptors())) {
- boolean hasFault = false;
- if (messageContext.getResponse() instanceof SoapMessage) {
- SoapMessage soapResponse = (SoapMessage) messageContext.getResponse();
- hasFault = soapResponse.getSoapBody().hasFault();
- }
- boolean resume = true;
- for (int i = interceptorIndex; resume && i >= 0; i--) {
- EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
- if (hasFault) {
- if (interceptor instanceof SoapEndpointInterceptor) {
- SoapEndpointInterceptor soapEndpointInterceptor = (SoapEndpointInterceptor) interceptor;
- resume = soapEndpointInterceptor.handleFault(messageContext, mappedEndpoint.getEndpoint());
- }
- }
- else {
- resume = interceptor.handleResponse(messageContext, mappedEndpoint.getEndpoint());
- }
- }
- }
- }
}
diff --git a/core/src/main/java/org/springframework/ws/soap/server/endpoint/interceptor/SoapEnvelopeLoggingInterceptor.java b/core/src/main/java/org/springframework/ws/soap/server/endpoint/interceptor/SoapEnvelopeLoggingInterceptor.java
index 41ea567b..033d354e 100644
--- a/core/src/main/java/org/springframework/ws/soap/server/endpoint/interceptor/SoapEnvelopeLoggingInterceptor.java
+++ b/core/src/main/java/org/springframework/ws/soap/server/endpoint/interceptor/SoapEnvelopeLoggingInterceptor.java
@@ -21,9 +21,9 @@ import javax.xml.transform.Source;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.AbstractLoggingInterceptor;
-import org.springframework.ws.soap.SoapEndpointInterceptor;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
+import org.springframework.ws.soap.server.SoapEndpointInterceptor;
/**
* SOAP-specific EndpointInterceptor that logs the complete request and response envelope of
@@ -39,9 +39,7 @@ public class SoapEnvelopeLoggingInterceptor extends AbstractLoggingInterceptor i
private boolean logFault = true;
- /**
- * Indicates whether a SOAP Fault should be logged. Default is true.
- */
+ /** Indicates whether a SOAP Fault should be logged. Default is true. */
public void setLogFault(boolean logFault) {
this.logFault = logFault;
}
diff --git a/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/DelegatingSoapEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/DelegatingSoapEndpointMapping.java
index 60acae3b..f6c0da41 100644
--- a/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/DelegatingSoapEndpointMapping.java
+++ b/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/DelegatingSoapEndpointMapping.java
@@ -21,8 +21,8 @@ import org.springframework.util.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInvocationChain;
import org.springframework.ws.server.EndpointMapping;
-import org.springframework.ws.soap.SoapEndpointMapping;
import org.springframework.ws.soap.server.SoapEndpointInvocationChain;
+import org.springframework.ws.soap.server.SoapEndpointMapping;
/**
* EndpointMapping implement that adds SOAP actors or roles to a delegate endpoint. Delegates to another
@@ -46,9 +46,7 @@ public class DelegatingSoapEndpointMapping implements InitializingBean, SoapEndp
private String[] actorsOrRoles;
- /**
- * Sets the delegate EndpointMapping to resolve the endpoint with.
- */
+ /** Sets the delegate EndpointMapping to resolve the endpoint with. */
public void setDelegate(EndpointMapping delegate) {
this.delegate = delegate;
}
diff --git a/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionEndpointMapping.java b/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionEndpointMapping.java
index 2bca365c..939c340a 100644
--- a/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionEndpointMapping.java
+++ b/core/src/main/java/org/springframework/ws/soap/server/endpoint/mapping/SoapActionEndpointMapping.java
@@ -22,10 +22,10 @@ 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.AbstractMapBasedEndpointMapping;
-import org.springframework.ws.soap.SoapEndpointMapping;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
import org.springframework.ws.soap.server.SoapEndpointInvocationChain;
+import org.springframework.ws.soap.server.SoapEndpointMapping;
/**
* Implementation of the EndpointMapping interface to map from SOAPAction headers to endpoint
diff --git a/core/src/test/java/org/springframework/ws/server/MessageDispatcherTest.java b/core/src/test/java/org/springframework/ws/server/MessageDispatcherTest.java
index 7af3934b..107bbf20 100644
--- a/core/src/test/java/org/springframework/ws/server/MessageDispatcherTest.java
+++ b/core/src/test/java/org/springframework/ws/server/MessageDispatcherTest.java
@@ -307,6 +307,47 @@ public class MessageDispatcherTest extends TestCase {
factoryControl.verify();
}
+ public void testFaultFlow() throws Exception {
+ MockControl adapterControl = MockControl.createControl(EndpointAdapter.class);
+ EndpointAdapter adapterMock = (EndpointAdapter) adapterControl.getMock();
+ dispatcher.setEndpointAdapters(Collections.singletonList(adapterMock));
+
+ Object endpoint = new Object();
+ adapterControl.expectAndReturn(adapterMock.supports(endpoint), true);
+
+ MockControl mappingControl = MockControl.createControl(EndpointMapping.class);
+ EndpointMapping mappingMock = (EndpointMapping) mappingControl.getMock();
+ dispatcher.setEndpointMappings(Collections.singletonList(mappingMock));
+
+ MockControl interceptorControl = MockControl.createStrictControl(EndpointInterceptor.class);
+ EndpointInterceptor interceptorMock = (EndpointInterceptor) interceptorControl.getMock();
+
+ interceptorControl.expectAndReturn(interceptorMock.handleRequest(messageContext, endpoint), true);
+ adapterMock.invoke(messageContext, endpoint);
+ interceptorControl.expectAndReturn(interceptorMock.handleFault(messageContext, endpoint), true);
+
+ EndpointInvocationChain chain =
+ new EndpointInvocationChain(endpoint, new EndpointInterceptor[]{interceptorMock});
+
+ mappingControl.expectAndReturn(mappingMock.getEndpoint(messageContext), chain);
+ MockWebServiceMessage response = new MockWebServiceMessage();
+ response.setFault(true);
+ factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), response);
+
+ mappingControl.replay();
+ interceptorControl.replay();
+ adapterControl.replay();
+ factoryControl.replay();
+ // response required for interceptor invocation
+ messageContext.getResponse();
+ dispatcher.dispatch(messageContext);
+
+ mappingControl.verify();
+ interceptorControl.verify();
+ adapterControl.verify();
+ factoryControl.verify();
+ }
+
public void testNoEndpointFound() throws Exception {
dispatcher.setEndpointMappings(Collections.EMPTY_LIST);
try {
diff --git a/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java b/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java
index b884ddce..f7dd1843 100644
--- a/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java
+++ b/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java
@@ -94,17 +94,6 @@ public abstract class AbstractSoapHeaderTestCase extends AbstractSoapElementTest
assertHeaderElementEqual(headerElement, content);
}
- public void testExamineHeaderElements() throws Exception {
- QName qName = new QName("http://www.springframework.org", "localName", "spring");
- soapHeader.addHeaderElement(qName);
- Iterator iterator = soapHeader.examineHeaderElements(qName);
- assertNotNull("No Iterator returned", iterator);
- assertTrue("header element iterator has no elements", iterator.hasNext());
- SoapHeaderElement headerElement = (SoapHeaderElement) iterator.next();
- assertNotNull("No SoapHeaderElement returned", headerElement);
- assertEquals("Invalid qName for element", qName, headerElement.getName());
- }
-
protected void assertHeaderElementEqual(SoapHeaderElement headerElement, String expected) throws Exception {
StringResult result = new StringResult();
transformer.transform(headerElement.getSource(), result);
diff --git a/core/src/test/java/org/springframework/ws/soap/server/SoapMessageDispatcherTest.java b/core/src/test/java/org/springframework/ws/soap/server/SoapMessageDispatcherTest.java
index 459c6947..8f425263 100644
--- a/core/src/test/java/org/springframework/ws/soap/server/SoapMessageDispatcherTest.java
+++ b/core/src/test/java/org/springframework/ws/soap/server/SoapMessageDispatcherTest.java
@@ -29,7 +29,6 @@ import org.easymock.MockControl;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapBody;
-import org.springframework.ws.soap.SoapEndpointInterceptor;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
diff --git a/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java b/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java
index 0cc62b05..c197b851 100644
--- a/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java
+++ b/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java
@@ -24,9 +24,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapBody;
-import org.springframework.ws.soap.SoapEndpointInterceptor;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
+import org.springframework.ws.soap.server.SoapEndpointInterceptor;
/**
* Interceptor base class for interceptors that handle WS-Security.
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index e9c21107..4002a8bf 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -6,6 +6,9 @@