diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/AbstractWsAddressingMapping.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/AbstractWsAddressingMapping.java new file mode 100644 index 00000000..fd488a8f --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/AbstractWsAddressingMapping.java @@ -0,0 +1,118 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.addressing; + +import javax.xml.transform.TransformerException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.core.JdkVersion; +import org.springframework.util.Assert; +import org.springframework.ws.context.MessageContext; +import org.springframework.ws.server.EndpointInterceptor; +import org.springframework.ws.server.EndpointInvocationChain; +import org.springframework.ws.soap.SoapMessage; +import org.springframework.ws.soap.addressing.messageid.MessageIdProvider; +import org.springframework.ws.soap.addressing.messageid.UidMessageIdProvider; +import org.springframework.ws.soap.addressing.messageid.UuidMessageIdProvider; +import org.springframework.ws.soap.server.SoapEndpointInvocationChain; +import org.springframework.ws.soap.server.SoapEndpointMapping; +import org.springframework.xml.transform.TransformerObjectSupport; + +/** @author Arjen Poutsma */ +public abstract class AbstractWsAddressingMapping extends TransformerObjectSupport implements SoapEndpointMapping { + + protected final Log logger = LogFactory.getLog(getClass()); + + private String[] actorsOrRoles; + + private MessageIdProvider messageIdProvider; + + private AddressingHelper[] helpers = new AddressingHelper[]{new AddressingHelper(new WsAddressing200408())}; + + private EndpointInterceptor[] preInterceptors; + + private EndpointInterceptor[] postInterceptors; + + private static final Object MISSING_HEADER_ENDPOINT = new Object(); + + /** Protected constructor */ + protected AbstractWsAddressingMapping() { + if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_15) { + messageIdProvider = new UuidMessageIdProvider(); + } + else { + messageIdProvider = new UidMessageIdProvider(); + } + } + + public final void setActorOrRole(String actorOrRole) { + Assert.notNull(actorOrRole, "actorOrRole must not be null"); + actorsOrRoles = new String[]{actorOrRole}; + } + + public final void setActorsOrRoles(String[] actorsOrRoles) { + Assert.notEmpty(actorsOrRoles, "actorsOrRoles must not be empty"); + this.actorsOrRoles = actorsOrRoles; + } + + /** + * Sets the message id provider used for creating WS-Addressing MessageIds. By default, the {@link + * UuidMessageIdProvider} is used on Java 5 and higher, and the {@link UidMessageIdProvider} on Java 1.4 and lower. + */ + public final void setMessageIdProvider(MessageIdProvider messageIdProvider) { + this.messageIdProvider = messageIdProvider; + } + + public final void setVersions(WsAddressingVersion[] versions) { + Assert.notEmpty(versions, "specifications must not be empty"); + helpers = new AddressingHelper[versions.length]; + for (int i = 0; i < versions.length; i++) { + helpers[i] = new AddressingHelper(versions[i]); + } + } + + public final EndpointInvocationChain getEndpoint(MessageContext messageContext) throws TransformerException { + Assert.isTrue(messageContext.getResponse() instanceof SoapMessage, + "WsAddressingMapping requires a SoapMessage request"); + SoapMessage request = (SoapMessage) messageContext.getRequest(); + for (int i = 0; i < helpers.length; i++) { + if (!helpers[i].supports(request)) { + continue; + } + MessageAddressingProperties map = helpers[i].getMessageAddressingProperties(request); + Object endpoint; + if (map.isValid()) { + endpoint = getEndpointInternal(map); + } + else { + // Set a 'fake' endpoint, so that the invocation will continue, but result in a MissingHeader fault + // returned by the interceptor + endpoint = MISSING_HEADER_ENDPOINT; + } + if (endpoint == null) { + return null; + } + return new SoapEndpointInvocationChain(endpoint, null, actorsOrRoles); + } + return null; + } + + protected abstract Object getEndpointInternal(MessageAddressingProperties map); + + +} diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/AddressingHelper.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/AddressingHelper.java new file mode 100644 index 00000000..654e6bf6 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/AddressingHelper.java @@ -0,0 +1,222 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.addressing; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Properties; +import javax.xml.namespace.QName; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; + +import org.springframework.util.StringUtils; +import org.springframework.ws.soap.SoapFault; +import org.springframework.ws.soap.SoapHeader; +import org.springframework.ws.soap.SoapHeaderElement; +import org.springframework.ws.soap.SoapMessage; +import org.springframework.ws.soap.soap11.Soap11Body; +import org.springframework.ws.soap.soap12.Soap12Body; +import org.springframework.ws.soap.soap12.Soap12Fault; +import org.springframework.xml.transform.TransformerObjectSupport; +import org.springframework.xml.xpath.XPathExpression; +import org.springframework.xml.xpath.XPathExpressionFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** @author Arjen Poutsma */ +class AddressingHelper extends TransformerObjectSupport { + + private final WsAddressingVersion version; + + private final XPathExpression toExpression; + + private XPathExpression actionExpression; + + private XPathExpression messageIdExpression; + + private XPathExpression fromExpression; + + private XPathExpression replyToExpression; + + private XPathExpression faultToExpression; + + private XPathExpression addressExpression; + + private XPathExpression referencePropertiesExpression; + + private XPathExpression referenceParametersExpression; + + public AddressingHelper(WsAddressingVersion version) { + this.version = version; + Properties namespaces = new Properties(); + namespaces.setProperty(version.getNamespacePrefix(), version.getNamespaceUri()); + toExpression = createNormalizedExpression(version.getToName(), namespaces); + actionExpression = createNormalizedExpression(version.getActionName(), namespaces); + messageIdExpression = createNormalizedExpression(version.getMessageIdName(), namespaces); + fromExpression = createExpression(version.getFromName(), namespaces); + replyToExpression = createExpression(version.getReplyToName(), namespaces); + faultToExpression = createExpression(version.getFaultToName(), namespaces); + addressExpression = createNormalizedExpression(version.getAddressName(), namespaces); + if (version.getReferencePropertiesName() != null) { + referencePropertiesExpression = createChildrenExpression(version.getReferencePropertiesName(), namespaces); + } + if (version.getReferenceParametersName() != null) { + referenceParametersExpression = createChildrenExpression(version.getReferenceParametersName(), namespaces); + } + } + + private XPathExpression createExpression(QName name, Properties namespaces) { + String expression = name.getPrefix() + ":" + name.getLocalPart(); + return XPathExpressionFactory.createXPathExpression(expression, namespaces); + } + + private XPathExpression createNormalizedExpression(QName name, Properties namespaces) { + String expression = "normalize-space(" + name.getPrefix() + ":" + name.getLocalPart() + ")"; + return XPathExpressionFactory.createXPathExpression(expression, namespaces); + } + + private XPathExpression createChildrenExpression(QName name, Properties namespaces) { + String expression = name.getPrefix() + ":" + name.getLocalPart() + "/*"; + return XPathExpressionFactory.createXPathExpression(expression, namespaces); + } + + public MessageAddressingProperties getMessageAddressingProperties(SoapMessage message) throws TransformerException { + Element headerElement = getSoapHeaderElement(message); + String to = toExpression.evaluateAsString(headerElement); + EndpointReference from = getEndpointReference(fromExpression.evaluateAsNode(headerElement)); + EndpointReference replyTo = getEndpointReference(replyToExpression.evaluateAsNode(headerElement)); + EndpointReference faultTo = getEndpointReference(faultToExpression.evaluateAsNode(headerElement)); + String action = actionExpression.evaluateAsString(headerElement); + String messageId = messageIdExpression.evaluateAsString(headerElement); + return new MessageAddressingProperties(to, from, replyTo, faultTo, action, messageId); + } + + /** Given a ReplyTo, FaultTo, or From node, returns an endpoint reference. */ + private EndpointReference getEndpointReference(Node node) { + if (node == null) { + return null; + } + String address = addressExpression.evaluateAsString(node); + if (!StringUtils.hasLength(address)) { + return null; + } + List referenceProperties = referencePropertiesExpression != null ? + referencePropertiesExpression.evaluateAsNodeList(node) : Collections.EMPTY_LIST; + List referenceParameters = referenceParametersExpression != null ? + referenceParametersExpression.evaluateAsNodeList(node) : Collections.EMPTY_LIST; + return new EndpointReference(address, referenceProperties, referenceParameters); + } + + public SoapFault addMessageHeaderRequiredFault(SoapMessage message) { + return addAddressingFault(message, version.getMessageHeaderRequiredName(), + version.getMessageHeaderRequiredText()); + } + + public SoapFault addDestinationUnreachableFault(SoapMessage message) { + return addAddressingFault(message, version.getDestinationUnreachableName(), + version.getDestinationUnreachableText()); + } + + public SoapFault addActionNotSupportedFault(SoapMessage message, String action) { + return addAddressingFault(message, version.getActionNotSupportedName(), + version.getActionNotSupportedText(action)); + } + + private SoapFault addAddressingFault(SoapMessage message, QName subcode, String reason) { + if (message.getSoapBody() instanceof Soap11Body) { + Soap11Body soapBody = (Soap11Body) message.getSoapBody(); + return soapBody.addFault(subcode, reason, Locale.ENGLISH); + } + else { + Soap12Body soapBody = (Soap12Body) message.getSoapBody(); + Soap12Fault soapFault = (Soap12Fault) soapBody.addClientOrSenderFault(reason, Locale.ENGLISH); + soapFault.addFaultSubcode(subcode); + return soapFault; + } + } + + private Element getSoapHeaderElement(SoapMessage message) throws TransformerException { + SoapHeader header = message.getSoapHeader(); + if (header.getSource() instanceof DOMSource) { + DOMSource domSource = (DOMSource) header.getSource(); + if (domSource.getNode() != null && domSource.getNode().getNodeType() == Node.ELEMENT_NODE) { + return (Element) domSource.getNode(); + } + } + Transformer transformer = createTransformer(); + DOMResult domResult = new DOMResult(); + transformer.transform(message.getSoapHeader().getSource(), domResult); + Document document = (Document) domResult.getNode(); + return document.getDocumentElement(); + } + + public boolean hasNoneAddress(EndpointReference reference) { + String none = version.getNoneUri(); + return none != null && none.equals(reference.getAddress()); + } + + public boolean hasAnonymousAddress(EndpointReference reference) { + String anonymous = version.getAnonymousUri(); + return anonymous != null && anonymous.equals(reference.getAddress()); + } + + public void addAddressingHeaders(SoapMessage response, MessageAddressingProperties map) + throws TransformerException { + SoapHeader header = response.getSoapHeader(); + SoapHeaderElement messageId = header.addHeaderElement(version.getMessageIdName()); + messageId.setText(map.getMessageId()); + SoapHeaderElement relatesTo = header.addHeaderElement(version.getRelatesToName()); + relatesTo.setText(map.getRelatesTo()); + SoapHeaderElement to = header.addHeaderElement(version.getToName()); + to.setText(map.getTo()); + to.setMustUnderstand(true); + Transformer transformer = createTransformer(); + for (Iterator iterator = map.getReferenceParameters().iterator(); iterator.hasNext();) { + Node node = (Node) iterator.next(); + DOMSource source = new DOMSource(node); + transformer.transform(source, header.getResult()); + } + for (Iterator iterator = map.getReferenceProperties().iterator(); iterator.hasNext();) { + Node node = (Node) iterator.next(); + DOMSource source = new DOMSource(node); + transformer.transform(source, header.getResult()); + } + } + + public boolean supports(SoapMessage message) { + SoapHeader header = message.getSoapHeader(); + if (header != null) { + for (Iterator iterator = header.examineAllHeaderElements(); iterator.hasNext();) { + SoapHeaderElement headerElement = (SoapHeaderElement) iterator.next(); + if (version.getNamespaceUri().equals(headerElement.getName().getNamespaceURI())) { + return true; + } + } + } + return false; + + } + + public boolean understands(SoapHeaderElement header) { + return version.getNamespaceUri().equals(header.getName().getNamespaceURI()); + } +} diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/EndpointReference.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/EndpointReference.java new file mode 100644 index 00000000..c409133b --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/EndpointReference.java @@ -0,0 +1,78 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.addressing; + +import java.util.Collections; +import java.util.List; + +import org.springframework.util.Assert; + +/** @author Arjen Poutsma */ +public class EndpointReference { + + private final String address; + + private final List referenceProperties; + + private final List referenceParameters; + + public EndpointReference(String address) { + this.address = address; + this.referenceParameters = Collections.EMPTY_LIST; + this.referenceProperties = Collections.EMPTY_LIST; + } + + public EndpointReference(String address, List referenceProperties, List referenceParameters) { + Assert.notNull(address, "address must not be null"); + Assert.notNull(referenceProperties, "referenceProperties must not be null"); + Assert.notNull(referenceParameters, "referenceParameters must not be null"); + this.address = address; + this.referenceProperties = referenceProperties; + this.referenceParameters = referenceParameters; + } + + public String getAddress() { + return address; + } + + public List getReferenceProperties() { + return referenceProperties; + } + + public List getReferenceParameters() { + return referenceParameters; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o != null && o instanceof EndpointReference) { + EndpointReference other = (EndpointReference) o; + return address.equals(other.address); + } + return false; + } + + public int hashCode() { + return address.hashCode(); + } + + public String toString() { + return "EndpointReference[" + address + ']'; + } +} diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/MessageAddressingProperties.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/MessageAddressingProperties.java new file mode 100644 index 00000000..e6d45488 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/MessageAddressingProperties.java @@ -0,0 +1,145 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.addressing; + +import java.util.Collections; +import java.util.List; + +import org.springframework.util.StringUtils; + +/** + * Represents a set of Message Addressing Properties, as defined in the WS-Addressing specification. + *
+ * In earlier versions of the spec, these properties were called Message Information Headers. + * + * @author Arjen Poutsma + * @see Message Addressing Properties + */ +public class MessageAddressingProperties { + + private final String to; + + private final EndpointReference from; + + private final EndpointReference replyTo; + + private final EndpointReference faultTo; + + private final String action; + + private final String messageId; + + private final String relatesTo; + + private final List referenceProperties; + + private final List referenceParameters; + + public MessageAddressingProperties(String to, EndpointReference replyTo, String action, String messageId) { + this.to = to; + this.replyTo = replyTo; + this.action = action; + this.messageId = messageId; + this.from = null; + this.faultTo = null; + this.relatesTo = null; + this.referenceProperties = Collections.EMPTY_LIST; + this.referenceParameters = Collections.EMPTY_LIST; + } + + public MessageAddressingProperties(String to, + EndpointReference from, + EndpointReference replyTo, + EndpointReference faultTo, + String action, + String messageId) { + this.to = to; + this.from = from; + this.replyTo = replyTo; + this.faultTo = faultTo; + this.action = action; + this.messageId = messageId; + this.relatesTo = null; + this.referenceProperties = Collections.EMPTY_LIST; + this.referenceParameters = Collections.EMPTY_LIST; + } + + private MessageAddressingProperties(String to, + String action, + String messageId, + String relatesTo, + List referenceProperties, + List referenceParameters) { + this.to = to; + this.action = action; + this.messageId = messageId; + this.relatesTo = relatesTo; + this.referenceProperties = referenceProperties; + this.referenceParameters = referenceParameters; + this.from = null; + this.replyTo = null; + this.faultTo = null; + } + + public String getTo() { + return to; + } + + public EndpointReference getFrom() { + return from; + } + + public EndpointReference getReplyTo() { + return replyTo != null ? replyTo : getFrom(); + } + + public EndpointReference getFaultTo() { + return faultTo != null ? faultTo : getReplyTo(); + } + + public String getAction() { + return action; + } + + public String getMessageId() { + return messageId; + } + + public String getRelatesTo() { + return relatesTo; + } + + public List getReferenceProperties() { + return referenceProperties; + } + + public List getReferenceParameters() { + return referenceParameters; + } + + public boolean isValid() { + return StringUtils.hasLength(to) && StringUtils.hasLength(action) && + !(replyTo != null && !StringUtils.hasLength(messageId)) && + !(faultTo != null && !StringUtils.hasLength(messageId)); + + } + + public MessageAddressingProperties getReplyProperties(EndpointReference epr, String action, String messageId) { + return new MessageAddressingProperties(epr.getAddress(), action, messageId, this.messageId, + epr.getReferenceProperties(), epr.getReferenceParameters()); + } +} diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/StatefulAddressingInterceptor.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/StatefulAddressingInterceptor.java new file mode 100644 index 00000000..7a231fe5 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/StatefulAddressingInterceptor.java @@ -0,0 +1,95 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.addressing; + +import javax.xml.transform.TransformerException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.ws.context.MessageContext; +import org.springframework.ws.soap.SoapHeaderElement; +import org.springframework.ws.soap.SoapMessage; +import org.springframework.ws.soap.addressing.messageid.MessageIdProvider; +import org.springframework.ws.soap.server.SoapEndpointInterceptor; + +/** @author Arjen Poutsma */ +class StatefulAddressingInterceptor implements SoapEndpointInterceptor { + + private static final Log logger = LogFactory.getLog(StatefulAddressingInterceptor.class); + + private final AddressingHelper helper; + + private final MessageIdProvider messageIdProvider; + + private final MessageAddressingProperties requestMap; + + public StatefulAddressingInterceptor(AddressingHelper helper, + MessageIdProvider messageIdProvider, + MessageAddressingProperties map) { + this.helper = helper; + this.messageIdProvider = messageIdProvider; + this.requestMap = map; + } + + public boolean understands(SoapHeaderElement header) { + return helper.understands(header); + } + + public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception { + if (!requestMap.isValid()) { + helper.addMessageHeaderRequiredFault((SoapMessage) messageContext.getResponse()); + return false; + } + return true; + } + + public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception { + SoapMessage response = (SoapMessage) messageContext.getResponse(); + return handleReturnMessage(response, requestMap.getReplyTo()); + } + + public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception { + SoapMessage response = (SoapMessage) messageContext.getResponse(); + return handleReturnMessage(response, requestMap.getFaultTo()); + } + + private boolean handleReturnMessage(SoapMessage response, EndpointReference epr) throws TransformerException { + if (epr == null || helper.hasNoneAddress(epr)) { + logger.debug("Request has no response address"); + return false; + } + String replyMessageId = messageIdProvider.getMessageId(response); + if (logger.isDebugEnabled()) { + logger.debug("Generated response MessageID [" + replyMessageId + "]"); + } + MessageAddressingProperties replyMap = requestMap.getReplyProperties(epr, null, replyMessageId); + helper.addAddressingHeaders(response, replyMap); + if (helper.hasAnonymousAddress(epr)) { + logger.debug("Request has anonymous response address"); + return true; + } + else { + if (logger.isDebugEnabled()) { + logger.debug("Sending response message to EPR address [" + epr.getAddress() + "]"); + } + // TODO: send the message + throw new UnsupportedOperationException("Sending to out-of-band EPR not supported"); + } + } + + +} diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressing200408.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressing200408.java new file mode 100644 index 00000000..72fd3f52 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressing200408.java @@ -0,0 +1,159 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.addressing; + +import javax.xml.namespace.QName; + +/** + * Implements the August 2004 edition of the WS-Addressing specification. This version of the specification is used by + * Microsoft's Web Service Enhancements (WSE) 3.0. + * + * @author Arjen Poutsma + * @see Web Services Addressing, August 2004 + * @see Web Service Enhancements + */ +public class WsAddressing200408 implements WsAddressingVersion { + + private static final String NAMESPACE_URI = "http://schemas.xmlsoap.org/ws/2004/08/addressing"; + + private static final String NAMESPACE_PREFIX = "wsa"; + + private static final QName TO = new QName(NAMESPACE_URI, "To", NAMESPACE_PREFIX); + + private static final QName REPLY_TO = new QName(NAMESPACE_URI, "ReplyTo", NAMESPACE_PREFIX); + + private static final QName FROM = new QName(NAMESPACE_URI, "From", NAMESPACE_PREFIX); + + private static final QName FAULT_TO = new QName(NAMESPACE_URI, "FaultTo", NAMESPACE_PREFIX); + + private static final QName ACTION = new QName(NAMESPACE_URI, "Action", NAMESPACE_PREFIX); + + private static final QName MESSAGE_ID = new QName(NAMESPACE_URI, "MessageID", NAMESPACE_PREFIX); + + private static final QName RELATES_TO = new QName(NAMESPACE_URI, "RelatesTo", NAMESPACE_PREFIX); + + private static final QName RELATIONSHIP_REPLY = new QName(NAMESPACE_URI, "Reply", NAMESPACE_PREFIX); + + private static final QName RELATIONSHIP_TYPE = new QName(NAMESPACE_URI, "RelationshipType", NAMESPACE_PREFIX); + + private static final QName MESSAGE_INFORMATION_HEADER_REQUIRED = + new QName(NAMESPACE_URI, "MessageInformationHeaderRequired", NAMESPACE_PREFIX); + + private static final QName DESTINATION_UNREACHABLE = + new QName(NAMESPACE_URI, "DestinationUnreachable", NAMESPACE_PREFIX); + + private static final QName ACTION_NOT_SUPPORTED_NAME = + new QName(NAMESPACE_URI, "ActionNotSupported", NAMESPACE_PREFIX); + + private static final QName ADDRESS = new QName(NAMESPACE_URI, "Address", NAMESPACE_PREFIX); + + private static final QName REFERENCE_PARAMETERS = new QName(NAMESPACE_URI, "ReferenceParameters", NAMESPACE_PREFIX); + + private static final QName REFERENCE_PROPERTIES = new QName(NAMESPACE_URI, "ReferenceProperties", NAMESPACE_PREFIX); + + public String getNamespaceUri() { + return NAMESPACE_URI; + } + + public String getNamespacePrefix() { + return NAMESPACE_PREFIX; + } + + public String getAnonymousUri() { + return NAMESPACE_URI + "/role/anonymous"; + } + + public String getNoneUri() { + return null; + } + + public QName getToName() { + return TO; + } + + public QName getFromName() { + return FROM; + } + + public QName getReplyToName() { + return REPLY_TO; + } + + public QName getFaultToName() { + return FAULT_TO; + } + + public QName getActionName() { + return ACTION; + } + + public QName getMessageIdName() { + return MESSAGE_ID; + } + + public QName getRelatesToName() { + return RELATES_TO; + } + + public QName getRelationshipReplyName() { + return RELATIONSHIP_REPLY; + } + + public QName getAddressName() { + return ADDRESS; + } + + public QName getRelationshipTypeName() { + return RELATIONSHIP_TYPE; + } + + public QName getReferenceParametersName() { + return REFERENCE_PARAMETERS; + } + + public QName getReferencePropertiesName() { + return REFERENCE_PROPERTIES; + } + + public QName getMessageHeaderRequiredName() { + return MESSAGE_INFORMATION_HEADER_REQUIRED; + } + + public String getMessageHeaderRequiredText() { + return "A required message information header, To, MessageID, or Action, is not present."; + } + + public QName getDestinationUnreachableName() { + return DESTINATION_UNREACHABLE; + } + + public String getDestinationUnreachableText() { + return "No route can be determined to reach the destination role defined by the WS-Addressing To."; + } + + public QName getActionNotSupportedName() { + return ACTION_NOT_SUPPORTED_NAME; + } + + public String getActionNotSupportedText(String action) { + return "The " + action + " cannot be processed at the receiver."; + } + + public String toString() { + return NAMESPACE_URI; + } +} diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressingVersion.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressingVersion.java new file mode 100644 index 00000000..fa991825 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressingVersion.java @@ -0,0 +1,107 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.addressing; + +import javax.xml.namespace.QName; + +/** + * Defines the contract for a specific version of the WS-Addressing specification. + * + * @author Arjen Poutsma + */ +public interface WsAddressingVersion { + + /** Returns the WS-Addressing namespace handled by this specification. */ + String getNamespaceUri(); + + /** Returns the prefix associated with the WS-Addressing namespace handled by this specification. */ + String getNamespacePrefix(); + + /** Returns the anonymous URI. */ + String getAnonymousUri(); + + /** Returns the none URI, ornull if the spec does not define it. */
+ String getNoneUri();
+
+ /** Returns the qualified name of the To addressing header. */
+ QName getToName();
+
+ /** Returns the qualified name of the From addressing header. */
+ QName getFromName();
+
+ /** Returns the qualified name of the ReplyTo addressing header. */
+ QName getReplyToName();
+
+ /** Returns the qualified name of the FaultTo addressing header. */
+ QName getFaultToName();
+
+ /** Returns the qualified name of the Action addressing header. */
+ QName getActionName();
+
+ /** Returns the qualified name of the MessageID addressing header. */
+ QName getMessageIdName();
+
+ /** Returns the qualified name of the RelatesTo addressing header. */
+ QName getRelatesToName();
+
+ /**
+ * Returns the qualified name of the Relationship addressing attribute.
+ *
+ * @see #getRelationshipReplyName()
+ */
+ QName getRelationshipTypeName();
+
+ /**
+ * Returns the value of the RelationshipType attribute indicating a reply to the related message.
+ *
+ * @see #getRelationshipTypeName()
+ */
+ QName getRelationshipReplyName();
+
+ /**
+ * Returns the qualified name of the ReferenceProperties in the endpoint reference. Returns
+ * null when reference properties are not supported by this version of the spec.
+ */
+ QName getReferencePropertiesName();
+
+ /**
+ * Returns the qualified name of the ReferenceParameters in the endpoint reference. Returns
+ * null when reference parameters are not supported by this version of the spec.
+ */
+ QName getReferenceParametersName();
+
+ /** The qualified name of the Address in EndpointReference. */
+ QName getAddressName();
+
+ /** Returns the qualified name of the fault subcode that indicates that a header is missing. */
+ QName getMessageHeaderRequiredName();
+
+ /** Returns the text of the fault that indicates that a header is missing. */
+ String getMessageHeaderRequiredText();
+
+ /** Returns the qualified name of the DestinationUnreachable fault subcode. */
+ QName getDestinationUnreachableName();
+
+ /** Returns the text of the DestinationUnreachable fault. */
+ String getDestinationUnreachableText();
+
+ /** Returns the qualified name of the ActionNotSupported fault subcode. */
+ QName getActionNotSupportedName();
+
+ /** Returns the text of the ActionNotSupported fault. */
+ String getActionNotSupportedText(String action);
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/MessageIdProvider.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/MessageIdProvider.java
new file mode 100644
index 00000000..32301331
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/MessageIdProvider.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing.messageid;
+
+import org.springframework.ws.soap.SoapMessage;
+
+/**
+ * Declares the contract for classes that provide WS-Addressing MessageIds, either by generation or otherwise.
+ *
+ * @author Arjen Poutsma
+ */
+public interface MessageIdProvider {
+
+ /** Returns a WS-Addressing Message Id for the given message. */
+ String getMessageId(SoapMessage message);
+
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/UidMessageIdProvider.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/UidMessageIdProvider.java
new file mode 100644
index 00000000..1ba88e3a
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/UidMessageIdProvider.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing.messageid;
+
+import java.rmi.server.UID;
+
+import org.springframework.ws.soap.SoapMessage;
+
+/**
+ * Implementation of the {@link MessageIdProvider} interface that uses a {@link UID} to generate a Message Id. The UID
+ * is prefixed by uid:.
+ *
+ * @author Arjen Poutsma
+ */
+public class UidMessageIdProvider implements MessageIdProvider {
+
+ public static final String PREFIX = "uid:";
+
+ public String getMessageId(SoapMessage message) {
+ return PREFIX + new UID().toString();
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdProvider.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdProvider.java
new file mode 100644
index 00000000..c3d0f0ae
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing.messageid;
+
+import java.util.UUID;
+
+import org.springframework.ws.soap.SoapMessage;
+
+/**
+ * Implementation of the {@link MessageIdProvider} interface that uses a {@link UUID} to generate a Message Id. The UUID
+ * is prefixed by uuid:.
+ *
+ * Note that the {@link UUID} class is only available on Java 5 and above.
+ *
+ * @author Arjen Poutsma
+ * @see java.util.UUID
+ */
+public class UuidMessageIdProvider implements MessageIdProvider {
+
+ public static final String PREFIX = "uuid:";
+
+ public String getMessageId(SoapMessage message) {
+ return PREFIX + UUID.randomUUID().toString();
+ }
+}
\ No newline at end of file
diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingTestCase.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingTestCase.java
new file mode 100644
index 00000000..7e2ec1b1
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingTestCase.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing;
+
+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.springframework.ws.soap.saaj.SaajSoapMessage;
+
+/** @author Arjen Poutsma */
+public abstract class AbstractWsAddressingTestCase extends XMLTestCase {
+
+ protected MessageFactory messageFactory;
+
+ protected final void setUp() throws Exception {
+ messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
+ onSetUp();
+ }
+
+ protected void onSetUp() throws Exception {
+ }
+
+ protected SaajSoapMessage loadSaajMessage(String fileName) throws SOAPException, IOException {
+ MimeHeaders mimeHeaders = new MimeHeaders();
+ mimeHeaders.addHeader("Content-Type", " application/soap+xml");
+ InputStream is = getClass().getResourceAsStream(fileName);
+ try {
+ return new SaajSoapMessage(messageFactory.createMessage(mimeHeaders, is));
+ }
+ finally {
+ is.close();
+ }
+ }
+}
diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/AddressingHelperTest.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AddressingHelperTest.java
new file mode 100644
index 00000000..8c3b7fdd
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AddressingHelperTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPMessage;
+
+import org.springframework.ws.soap.saaj.SaajSoapMessage;
+import org.w3c.dom.Element;
+
+public class AddressingHelperTest extends AbstractWsAddressingTestCase {
+
+ private AddressingHelper helper;
+
+ private Element headerElement;
+
+ protected void onSetUp() throws Exception {
+ helper = new AddressingHelper(new WsAddressing200408());
+ SaajSoapMessage message = loadSaajMessage("request-200408.xml");
+ headerElement = message.getSaajMessage().getSOAPHeader();
+ }
+
+ public void testAddMessageHeaderRequiredFault12() throws Exception {
+ MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
+ SOAPMessage saajMessage = messageFactory.createMessage();
+ SaajSoapMessage message = new SaajSoapMessage(saajMessage);
+ helper.addMessageHeaderRequiredFault(message);
+
+ saajMessage.writeTo(System.out);
+ System.out.println();
+ }
+
+ public void testAddDestinationUnreachableFault() throws Exception {
+ MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
+ SOAPMessage saajMessage = messageFactory.createMessage();
+ SaajSoapMessage message = new SaajSoapMessage(saajMessage);
+ helper.addDestinationUnreachableFault(message);
+ saajMessage.writeTo(System.out);
+ System.out.println();
+ }
+
+ public void testAddActionNotSupportedFault() throws Exception {
+ MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
+ SOAPMessage saajMessage = messageFactory.createMessage();
+ SaajSoapMessage message = new SaajSoapMessage(saajMessage);
+ helper.addActionNotSupportedFault(message, "myAction");
+ saajMessage.writeTo(System.out);
+ System.out.println();
+ }
+}
\ No newline at end of file
diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/StatefulAddressingInterceptorTest.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/StatefulAddressingInterceptorTest.java
new file mode 100644
index 00000000..51a4ad05
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/StatefulAddressingInterceptorTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing;
+
+import java.util.Iterator;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+
+import org.springframework.ws.context.DefaultMessageContext;
+import org.springframework.ws.context.MessageContext;
+import org.springframework.ws.soap.SoapHeaderElement;
+import org.springframework.ws.soap.addressing.messageid.UuidMessageIdProvider;
+import org.springframework.ws.soap.saaj.SaajSoapMessage;
+import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
+
+public class StatefulAddressingInterceptorTest extends AbstractWsAddressingTestCase {
+
+ private StatefulAddressingInterceptor interceptor;
+
+ private SaajSoapMessage request;
+
+ private SOAPMessage saajRequest;
+
+ private MessageContext messageContext;
+
+ private WsAddressing200408 version;
+
+ protected void onSetUp() throws Exception {
+ version = new WsAddressing200408();
+ MessageAddressingProperties map = new MessageAddressingProperties("mailto:joe@fabrikam123.example",
+ new EndpointReference("http://business456.example/client1"), "http://fabrikam123.example/mail/Delete",
+ "uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff");
+ interceptor =
+ new StatefulAddressingInterceptor(new AddressingHelper(version), new UuidMessageIdProvider(), map);
+ request = loadSaajMessage("request-200408.xml");
+ saajRequest = request.getSaajMessage();
+ messageContext = new DefaultMessageContext(request, new SaajSoapMessageFactory(messageFactory));
+ }
+
+ public void testUnderstands() throws Exception {
+ Iterator iterator = request.getSoapHeader()
+ .examineAllHeaderElements();
+ SoapHeaderElement headerElement = (SoapHeaderElement) iterator.next();
+ assertTrue("Interceptor does not understand header", interceptor.understands(headerElement));
+ }
+
+ public void testHandleRequestNormal() throws Exception {
+ boolean result = interceptor.handleRequest(messageContext, null);
+ assertTrue("Invalid result", result);
+ }
+
+ public void testHandleRequestToMissing() throws Exception {
+ removeElement(version.getToName());
+ boolean result = interceptor.handleRequest(messageContext, null);
+ assertFalse("Invalid result", result);
+ assertTrue("Response has no fault", messageContext.getResponse().hasFault());
+ }
+
+ public void testHandleRequestActionMissing() throws Exception {
+ removeElement(version.getActionName());
+ boolean result = interceptor.handleRequest(messageContext, null);
+ assertFalse("Invalid result", result);
+ assertTrue("Response has no fault", messageContext.getResponse().hasFault());
+ }
+
+ public void testHandleRequestMessageIdMissing() throws Exception {
+ removeElement(version.getMessageIdName());
+ boolean result = interceptor.handleRequest(messageContext, null);
+ assertFalse("Invalid result", result);
+ assertTrue("Response has no fault", messageContext.getResponse().hasFault());
+ }
+
+ public void testHandleResponse() throws Exception {
+ interceptor.handleRequest(messageContext, null);
+ interceptor.handleResponse(messageContext, null);
+ messageContext.getResponse().writeTo(System.out);
+ }
+
+ public void testHandleFault() throws Exception {
+ interceptor.handleRequest(messageContext, null);
+ interceptor.handleFault(messageContext, null);
+ messageContext.getResponse().writeTo(System.out);
+ }
+
+ private void removeElement(QName name) throws SOAPException {
+ Iterator iterator = saajRequest.getSOAPHeader().getChildElements(name);
+ while (iterator.hasNext()) {
+ SOAPElement element = (SOAPElement) iterator.next();
+ element.detachNode();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/WsAddressingMappingTest.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/WsAddressingMappingTest.java
new file mode 100644
index 00000000..f5078b8a
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/WsAddressingMappingTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathFactory;
+
+import org.springframework.ws.soap.SoapMessage;
+import org.springframework.xml.namespace.SimpleNamespaceContext;
+import org.w3c.dom.Element;
+
+/** Test case for AbstractWsAddressingMapping */
+public class WsAddressingMappingTest extends AbstractWsAddressingTestCase {
+
+ private AbstractWsAddressingMapping mapping;
+
+ protected void onSetUp() throws Exception {
+ mapping = new MyWsAddressingMapping();
+// mapping.afterPropertiesSet();
+ }
+
+ public void testGetSoapHeaderElement() throws Exception {
+ SoapMessage message = loadSaajMessage("request-200408.xml");
+ Element element = mapping.getSoapHeaderElement(message);
+ assertNotNull("No element returned", element);
+ assertEquals("Invalid header element returned", "Header", element.getLocalName());
+ XPathFactory factory = XPathFactory.newInstance();
+ XPath xpath = factory.newXPath();
+ SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
+ namespaceContext.bindNamespaceUri("wsa", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
+ xpath.setNamespaceContext(namespaceContext);
+ XPathExpression expression = xpath.compile("wsa:To");
+ String result = expression.evaluate(element);
+ System.out.println("result = " + result);
+ }
+
+ private static class MyWsAddressingMapping extends AbstractWsAddressingMapping {
+
+ }
+
+}
\ No newline at end of file
diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/AbstractMessageIdProviderTestCase.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/AbstractMessageIdProviderTestCase.java
new file mode 100644
index 00000000..259273c5
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/AbstractMessageIdProviderTestCase.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing.messageid;
+
+import junit.framework.TestCase;
+import org.springframework.util.StringUtils;
+
+public abstract class AbstractMessageIdProviderTestCase extends TestCase {
+
+ private MessageIdProvider provider;
+
+ protected final void setUp() throws Exception {
+ provider = createProvider();
+ }
+
+ protected abstract MessageIdProvider createProvider();
+
+ public void testProvider() {
+ String messageId1 = provider.getMessageId(null);
+ System.out.println(messageId1);
+ assertTrue("Empty messageId", StringUtils.hasLength(messageId1));
+ String messageId2 = provider.getMessageId(null);
+ assertTrue("Empty messageId", StringUtils.hasLength(messageId2));
+ assertFalse("Equal messageIds", messageId1.equals(messageId2));
+ }
+}
diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/UidMessageIdProviderTest.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/UidMessageIdProviderTest.java
new file mode 100644
index 00000000..eb3d719d
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/UidMessageIdProviderTest.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing.messageid;
+
+public class UidMessageIdProviderTest extends AbstractMessageIdProviderTestCase {
+
+ protected MessageIdProvider createProvider() {
+ return new UidMessageIdProvider();
+ }
+}
\ No newline at end of file
diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdProviderTest.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdProviderTest.java
new file mode 100644
index 00000000..78376c7c
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/messageid/UuidMessageIdProviderTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.addressing.messageid;
+
+public class UuidMessageIdProviderTest extends AbstractMessageIdProviderTestCase {
+
+ protected MessageIdProvider createProvider() {
+ return new UuidMessageIdProvider();
+ }
+
+}
\ No newline at end of file