This commit is contained in:
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* 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.xpath.XPathExpression;
|
||||
import org.springframework.xml.xpath.XPathExpressionFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Abstract extension of the {@link AbstractWsAddressingInterceptor} that uses a {@link WsAddressingVersion}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.1.0
|
||||
*/
|
||||
abstract class AbstractVersionBasedWsAddressingInterceptor extends AbstractWsAddressingInterceptor {
|
||||
|
||||
private final WsAddressingVersion version;
|
||||
|
||||
private final XPathExpression toExpression;
|
||||
|
||||
private final XPathExpression actionExpression;
|
||||
|
||||
private final XPathExpression messageIdExpression;
|
||||
|
||||
private final XPathExpression fromExpression;
|
||||
|
||||
private final XPathExpression replyToExpression;
|
||||
|
||||
private final XPathExpression faultToExpression;
|
||||
|
||||
private final XPathExpression addressExpression;
|
||||
|
||||
private XPathExpression referencePropertiesExpression;
|
||||
|
||||
private XPathExpression referenceParametersExpression;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link AbstractVersionBasedWsAddressingInterceptor} with the given {@link
|
||||
* WsAddressingVersion}.
|
||||
*/
|
||||
protected AbstractVersionBasedWsAddressingInterceptor(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 boolean understands(SoapHeaderElement header) {
|
||||
return version.getNamespaceUri().equals(header.getName().getNamespaceURI());
|
||||
}
|
||||
|
||||
protected void addAddressingHeaders(SoapMessage message, MessageAddressingProperties map)
|
||||
throws TransformerException {
|
||||
SoapHeader header = message.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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Message Addressing Header Required fault to the given message.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-soap/#missingmapfault">Message Addressing Header Required</a>
|
||||
*/
|
||||
protected SoapFault addMessageAddressingHeaderRequiredFault(SoapMessage message) {
|
||||
return addAddressingFault(message, version.getMessageAddressingHeaderRequiredFaultSubcode(),
|
||||
version.getMessageAddressingHeaderRequiredFaultReason());
|
||||
}
|
||||
|
||||
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 if (message.getSoapBody() instanceof Soap12Body) {
|
||||
Soap12Body soapBody = (Soap12Body) message.getSoapBody();
|
||||
Soap12Fault soapFault = (Soap12Fault) soapBody.addClientOrSenderFault(reason, Locale.ENGLISH);
|
||||
soapFault.addFaultSubcode(subcode);
|
||||
return soapFault;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MessageAddressingProperties} for the given message.
|
||||
*
|
||||
* @param message the message to find the map for
|
||||
* @return the message addressing properties
|
||||
*/
|
||||
protected 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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the given endpoint reference has a Anonymous address. This address is used to indicate that a
|
||||
* message should be sent in-band.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-core/#formreplymsg">Formulating a Reply Message</a>
|
||||
*/
|
||||
protected boolean hasAnonymousAddress(EndpointReference epr) {
|
||||
String anonymous = version.getAnonymousUri();
|
||||
return anonymous != null && anonymous.equals(epr.getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the given endpoint reference has a None address. Messages to be sent to this address will not
|
||||
* be sent.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-core/#sendmsgepr">Sending a Message to an EPR</a>
|
||||
*/
|
||||
protected boolean hasNoneAddress(EndpointReference epr) {
|
||||
String none = version.getNoneUri();
|
||||
return none != null && none.equals(epr.getAddress());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
package org.springframework.ws.soap.addressing;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.soap.SoapFault;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.addressing.messageid.MessageIdProvider;
|
||||
import org.springframework.ws.soap.server.SoapEndpointInterceptor;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
import org.springframework.xml.transform.TransformerObjectSupport;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
public abstract class AbstractWsAddressingInterceptor extends TransformerObjectSupport
|
||||
implements SoapEndpointInterceptor {
|
||||
|
||||
/** Logger available for subclasses. */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private MessageIdProvider messageIdProvider;
|
||||
|
||||
private WebServiceMessageSender[] messageSenders = new WebServiceMessageSender[0];
|
||||
|
||||
public final void setMessageIdProvider(MessageIdProvider messageIdProvider) {
|
||||
this.messageIdProvider = messageIdProvider;
|
||||
}
|
||||
|
||||
public final boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
|
||||
Assert.isTrue(messageContext.getRequest() instanceof SoapMessage,
|
||||
"WsAddressingInterceptor requires a SoapMessage request");
|
||||
SoapMessage request = (SoapMessage) messageContext.getRequest();
|
||||
MessageAddressingProperties requestMap = getMessageAddressingProperties(request);
|
||||
if (!requestMap.isValid()) {
|
||||
addMessageAddressingHeaderRequiredFault((SoapMessage) messageContext.getResponse());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public final boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
|
||||
return handleResponseOrFault(messageContext);
|
||||
}
|
||||
|
||||
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
|
||||
return handleResponseOrFault(messageContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Message Addressing Header Required fault to the given message.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-soap/#missingmapfault">Message Addressing Header Required</a>
|
||||
*/
|
||||
protected abstract SoapFault addMessageAddressingHeaderRequiredFault(SoapMessage message);
|
||||
|
||||
private boolean handleResponseOrFault(MessageContext messageContext) throws Exception {
|
||||
Assert.isTrue(messageContext.getRequest() instanceof SoapMessage &&
|
||||
messageContext.getResponse() instanceof SoapMessage,
|
||||
"WsAddressingInterceptor requires a SoapMessage request and response");
|
||||
SoapMessage request = (SoapMessage) messageContext.getRequest();
|
||||
MessageAddressingProperties requestMap = getMessageAddressingProperties(request);
|
||||
SoapMessage response = (SoapMessage) messageContext.getResponse();
|
||||
EndpointReference responseEpr = response.hasFault() ? requestMap.getFaultTo() : requestMap.getReplyTo();
|
||||
if (responseEpr == null || hasNoneAddress(responseEpr)) {
|
||||
logger.debug("Request has none reply address");
|
||||
return false;
|
||||
}
|
||||
String responseMessageId = messageIdProvider.getMessageId(response);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Generated reply MessageID [" + responseMessageId + "]");
|
||||
}
|
||||
MessageAddressingProperties replyMap = requestMap.getResponseProperties(responseEpr, null, responseMessageId);
|
||||
addAddressingHeaders(response, replyMap);
|
||||
if (hasAnonymousAddress(responseEpr)) {
|
||||
logger.debug("Request has anonymous reply address");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Sending reply message to EPR address [" + responseEpr.getAddress() + "]");
|
||||
}
|
||||
sendOutOfBand(responseEpr.getAddress(), response);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOutOfBand(String uri, SoapMessage message) throws IOException {
|
||||
boolean supported = false;
|
||||
for (int i = 0; i < messageSenders.length; i++) {
|
||||
if (messageSenders[i].supports(uri)) {
|
||||
supported = true;
|
||||
WebServiceConnection connection = null;
|
||||
try {
|
||||
connection = messageSenders[i].createConnection(uri);
|
||||
connection.send(message);
|
||||
break;
|
||||
}
|
||||
finally {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!supported) {
|
||||
throw new IllegalArgumentException("Could not resolve [" + uri + "] to a WebServiceMessageSender");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MessageAddressingProperties} for the given message.
|
||||
*
|
||||
* @param message the message to find the map for
|
||||
* @return the message addressing properties
|
||||
*/
|
||||
protected abstract MessageAddressingProperties getMessageAddressingProperties(SoapMessage message)
|
||||
throws TransformerException;
|
||||
|
||||
/**
|
||||
* Indicates whether the given endpoint reference has a None address. Messages to be sent to this address will not
|
||||
* be sent.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-core/#sendmsgepr">Sending a Message to an EPR</a>
|
||||
*/
|
||||
protected abstract boolean hasNoneAddress(EndpointReference epr);
|
||||
|
||||
/**
|
||||
* Indicates whether the given endpoint reference has a Anonymous address. This address is used to indicate that a
|
||||
* message should be sent in-band.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-core/#formreplymsg">Formulating a Reply Message</a>
|
||||
*/
|
||||
protected abstract boolean hasAnonymousAddress(EndpointReference epr);
|
||||
|
||||
protected abstract void addAddressingHeaders(SoapMessage message, MessageAddressingProperties map)
|
||||
throws TransformerException;
|
||||
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* 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.transform.TransformerException;
|
||||
|
||||
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.server.EndpointMapping;
|
||||
import org.springframework.ws.soap.SoapHeader;
|
||||
import org.springframework.ws.soap.SoapHeaderElement;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.addressing.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;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link EndpointMapping} implementations that implement WS-Addressing.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public abstract class AbstractWsAddressingMapping extends TransformerObjectSupport implements SoapEndpointMapping {
|
||||
|
||||
private String[] actorsOrRoles;
|
||||
|
||||
private boolean isUltimateReceiver = true;
|
||||
|
||||
private MessageIdProvider messageIdProvider;
|
||||
|
||||
private AbstractWsAddressingInterceptor[] addressingInterceptors;
|
||||
|
||||
private EndpointInterceptor[] preInterceptors;
|
||||
|
||||
private EndpointInterceptor[] postInterceptors;
|
||||
|
||||
/** Protected constructor */
|
||||
protected AbstractWsAddressingMapping() {
|
||||
addressingInterceptors = new AbstractWsAddressingInterceptor[]{new WsAddressing200408Interceptor(),
|
||||
new WsAddressing200508Interceptor()};
|
||||
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;
|
||||
}
|
||||
|
||||
public final void setUltimateReceiver(boolean ultimateReceiver) {
|
||||
this.isUltimateReceiver = ultimateReceiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set additional interceptors to be applied before the implicit WS-Addressing interceptor, e.g.
|
||||
* <code>XwsSecurityInterceptor</code>.
|
||||
*/
|
||||
public final void setPreInterceptors(EndpointInterceptor[] preInterceptors) {
|
||||
this.preInterceptors = preInterceptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set additional interceptors to be applied after the implicit WS-Addressing interceptor, e.g.
|
||||
* <code>PayloadLoggingInterceptor</code>.
|
||||
*/
|
||||
public final void setPostInterceptors(EndpointInterceptor[] postInterceptors) {
|
||||
this.postInterceptors = postInterceptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message id provider used for creating WS-Addressing MessageIds.
|
||||
* <p/>
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the WS-Addressing interceptors to be supported by this mapping.
|
||||
* <p/>
|
||||
* By default, this includes the {@link WsAddressing200408Interceptor}, and the {@link
|
||||
* WsAddressing200508Interceptor}.
|
||||
*/
|
||||
public final void setAddressingInterceptors(AbstractWsAddressingInterceptor[] addressingInterceptors) {
|
||||
Assert.notEmpty(addressingInterceptors, "'addressingInterceptors' must not be empty");
|
||||
this.addressingInterceptors = addressingInterceptors;
|
||||
}
|
||||
|
||||
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 < addressingInterceptors.length; i++) {
|
||||
AbstractWsAddressingInterceptor interceptor = addressingInterceptors[i];
|
||||
if (!understands(interceptor, request)) {
|
||||
continue;
|
||||
}
|
||||
MessageAddressingProperties requestMap = interceptor.getMessageAddressingProperties(request);
|
||||
if (requestMap == null) {
|
||||
return null;
|
||||
}
|
||||
Object endpoint = getEndpointInternal(requestMap);
|
||||
if (endpoint == null) {
|
||||
return null;
|
||||
}
|
||||
return new SoapEndpointInvocationChain(endpoint, getAllEndpointInterceptors(interceptor), actorsOrRoles,
|
||||
isUltimateReceiver);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean understands(AbstractWsAddressingInterceptor interceptor, SoapMessage request) {
|
||||
SoapHeader header = request.getSoapHeader();
|
||||
if (header != null) {
|
||||
for (Iterator iterator = header.examineAllHeaderElements(); iterator.hasNext();) {
|
||||
SoapHeaderElement headerElement = (SoapHeaderElement) iterator.next();
|
||||
if (interceptor.understands(headerElement)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected EndpointInterceptor[] getAllEndpointInterceptors(AbstractWsAddressingInterceptor interceptor) {
|
||||
if (preInterceptors == null) {
|
||||
preInterceptors = new EndpointInterceptor[0];
|
||||
}
|
||||
if (postInterceptors == null) {
|
||||
postInterceptors = new EndpointInterceptor[0];
|
||||
}
|
||||
EndpointInterceptor[] interceptors =
|
||||
new EndpointInterceptor[preInterceptors.length + postInterceptors.length + 1];
|
||||
System.arraycopy(preInterceptors, 0, interceptors, 0, preInterceptors.length);
|
||||
interceptors[preInterceptors.length] = interceptor;
|
||||
System.arraycopy(postInterceptors, 0, interceptors, preInterceptors.length + 1, postInterceptors.length);
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup an endpoint for the given {@link MessageAddressingProperties}, returning <code>null</code> if no specific
|
||||
* one is found. This template method is called by {@link #getEndpoint(MessageContext)}.
|
||||
*
|
||||
* @param map the message addressing properties
|
||||
* @return the endpoint, or <code>null</code>
|
||||
*/
|
||||
protected abstract Object getEndpointInternal(MessageAddressingProperties map);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package org.springframework.ws.soap.addressing;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
/**
|
||||
* Abstract implementation of the {@link WsAddressingVersion} interface.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public abstract class AbstractWsAddressingVersion implements WsAddressingVersion {
|
||||
|
||||
public String getNamespacePrefix() {
|
||||
return "wsa";
|
||||
}
|
||||
|
||||
/*
|
||||
* Message addressing properties
|
||||
*/
|
||||
|
||||
public QName getToName() {
|
||||
return new QName(getNamespaceUri(), "To", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getFromName() {
|
||||
return new QName(getNamespaceUri(), "From", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getReplyToName() {
|
||||
return new QName(getNamespaceUri(), "ReplyTo", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getFaultToName() {
|
||||
return new QName(getNamespaceUri(), "FaultTo", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getActionName() {
|
||||
return new QName(getNamespaceUri(), "Action", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getMessageIdName() {
|
||||
return new QName(getNamespaceUri(), "MessageID", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getRelatesToName() {
|
||||
return new QName(getNamespaceUri(), "RelatesTo", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getRelationshipTypeName() {
|
||||
return new QName(getNamespaceUri(), "RelationshipType", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getReferencePropertiesName() {
|
||||
return new QName(getNamespaceUri(), "ReferenceProperties", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getReferenceParametersName() {
|
||||
return new QName(getNamespaceUri(), "ReferenceParameters", getNamespacePrefix());
|
||||
}
|
||||
|
||||
/*
|
||||
* Endpoint Reference
|
||||
*/
|
||||
|
||||
public QName getAddressName() {
|
||||
return new QName(getNamespaceUri(), "Address", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public QName getMetadataName() {
|
||||
return new QName(getNamespaceUri(), "Metadata", getNamespacePrefix());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Represents a set of Message Addressing Properties, as defined in the WS-Addressing specification.
|
||||
* <p/>
|
||||
* In earlier versions of the spec, these properties were called Message Information Headers.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-core/#eprs">Endpoint References</a>
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final class EndpointReference {
|
||||
|
||||
private final String address;
|
||||
|
||||
private final List referenceProperties;
|
||||
|
||||
private final List referenceParameters;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link EndpointReference} class with the given address. The reference parameters
|
||||
* and properties are empty.
|
||||
*
|
||||
* @param address the endpoint address
|
||||
*/
|
||||
public EndpointReference(String address) {
|
||||
this.address = address;
|
||||
this.referenceParameters = Collections.EMPTY_LIST;
|
||||
this.referenceProperties = Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link EndpointReference} class with the given address, reference properties, and
|
||||
* reference paramters.
|
||||
*
|
||||
* @param address the endpoint address
|
||||
* @param referenceProperties the reference properties, as a list of {@link Node}
|
||||
* @param referenceProperties the reference parameters, as a list of {@link Node}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/** Returns the address of the endpoint. */
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/** Returns the reference properties of the endpoint, as a list of {@link Node} objects. */
|
||||
public List getReferenceProperties() {
|
||||
return referenceProperties;
|
||||
}
|
||||
|
||||
/** Returns the reference parameters of the endpoint, as a list of {@link Node} objects. */
|
||||
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 + ']';
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* <p/>
|
||||
* In earlier versions of the spec, these properties were called Message Information Headers.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see <a href="http://www.w3.org/TR/ws-addr-core/#msgaddrprops">Message Addressing Properties</a>
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final 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;
|
||||
}
|
||||
*/
|
||||
|
||||
private MessageAddressingProperties(EndpointReference epr, String action, String messageId, String relatesTo) {
|
||||
this.to = epr.getAddress();
|
||||
this.action = action;
|
||||
this.messageId = messageId;
|
||||
this.relatesTo = relatesTo;
|
||||
this.referenceParameters = epr.getReferenceParameters();
|
||||
this.referenceProperties = epr.getReferenceProperties();
|
||||
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 Collections.unmodifiableList(referenceProperties);
|
||||
}
|
||||
|
||||
public List getReferenceParameters() {
|
||||
return Collections.unmodifiableList(referenceParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the given {@link MessageAddressingProperties} are valid, i.e. whether all required elements are
|
||||
* listed.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return StringUtils.hasLength(to) && StringUtils.hasLength(action) &&
|
||||
!(replyTo != null && !StringUtils.hasLength(messageId)) &&
|
||||
!(faultTo != null && !StringUtils.hasLength(messageId));
|
||||
|
||||
}
|
||||
|
||||
public MessageAddressingProperties getResponseProperties(EndpointReference epr, String action, String messageId) {
|
||||
return new MessageAddressingProperties(epr, action, messageId, this.messageId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
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 Services Enhancements (WSE) 3.0.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see <a href="http://msdn.microsoft.com/ws/2004/08/ws-addressing/">Web Services Addressing, August 2004</a>
|
||||
* @see <a href="http://msdn.microsoft.com/webservices/webservices/building/wse/">Web Services Enhancements</a>
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class WsAddressing200408Interceptor extends AbstractVersionBasedWsAddressingInterceptor {
|
||||
|
||||
protected WsAddressing200408Interceptor() {
|
||||
super(new WsAddressing200408());
|
||||
}
|
||||
|
||||
private static class WsAddressing200408 extends AbstractWsAddressingVersion {
|
||||
|
||||
private static final String NAMESPACE_URI = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
|
||||
|
||||
public String getNamespaceUri() {
|
||||
return NAMESPACE_URI;
|
||||
}
|
||||
|
||||
/*
|
||||
* Message addressing properties
|
||||
*/
|
||||
|
||||
public String getRelationshipReply() {
|
||||
return getNamespacePrefix() + ":Reply";
|
||||
}
|
||||
|
||||
/*
|
||||
* Address URIs
|
||||
*/
|
||||
|
||||
public String getAnonymousUri() {
|
||||
return NAMESPACE_URI + "/role/anonymous";
|
||||
}
|
||||
|
||||
public String getNoneUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Faults
|
||||
*/
|
||||
|
||||
public QName getMessageAddressingHeaderRequiredFaultSubcode() {
|
||||
return new QName(NAMESPACE_URI, "MessageInformationHeaderRequired", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public String getMessageAddressingHeaderRequiredFaultReason() {
|
||||
return "A required message information header, To, MessageID, or Action, is not present.";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package org.springframework.ws.soap.addressing;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
public class WsAddressing200508Interceptor extends AbstractVersionBasedWsAddressingInterceptor {
|
||||
|
||||
public WsAddressing200508Interceptor() {
|
||||
super(new WsAddressing200508());
|
||||
}
|
||||
|
||||
private static class WsAddressing200508 extends AbstractWsAddressingVersion {
|
||||
|
||||
private static final String NAMESPACE_URI = "http://www.w3.org/2005/08/addressing";
|
||||
|
||||
public String getNamespaceUri() {
|
||||
return NAMESPACE_URI;
|
||||
}
|
||||
|
||||
/*
|
||||
* Message addressing properties
|
||||
*/
|
||||
|
||||
public String getRelationshipReply() {
|
||||
return "http://www.w3.org/2005/08/addressing/reply";
|
||||
}
|
||||
|
||||
public QName getReferencePropertiesName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Address URIs
|
||||
*/
|
||||
|
||||
public String getAnonymousUri() {
|
||||
return NAMESPACE_URI + "/anonymous";
|
||||
}
|
||||
|
||||
public String getNoneUri() {
|
||||
return NAMESPACE_URI + "/none";
|
||||
}
|
||||
|
||||
/*
|
||||
* Faults
|
||||
*/
|
||||
|
||||
public QName getMessageAddressingHeaderRequiredFaultSubcode() {
|
||||
return new QName(NAMESPACE_URI, "MessageAddressingHeaderRequired", getNamespacePrefix());
|
||||
}
|
||||
|
||||
public String getMessageAddressingHeaderRequiredFaultReason() {
|
||||
return "A required header representing a Message Addressing Property is not present";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Provides WS-Addressing implementation classes.
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user