/* * Copyright 2005-2014 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.client; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import javax.xml.transform.TransformerException; import org.springframework.util.Assert; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.client.core.WebServiceMessageCallback; import org.springframework.ws.soap.SoapMessage; import org.springframework.ws.soap.addressing.core.EndpointReference; import org.springframework.ws.soap.addressing.core.MessageAddressingProperties; import org.springframework.ws.soap.addressing.messageid.MessageIdStrategy; import org.springframework.ws.soap.addressing.messageid.UuidMessageIdStrategy; import org.springframework.ws.soap.addressing.version.Addressing10; import org.springframework.ws.soap.addressing.version.AddressingVersion; import org.springframework.ws.transport.context.TransportContext; import org.springframework.ws.transport.context.TransportContextHolder; /** * {@link WebServiceMessageCallback} implementation that sets the WS-Addressing {@code Action} header on the * message. * * <p>A usage example with {@link org.springframework.ws.client.core.WebServiceTemplate}: * <pre> * WebServiceTemplate template = new WebServiceTemplate(messageFactory); * Result result = new DOMResult(); * template.sendSourceAndReceiveToResult( * new StringSource("<content xmlns=\"http://tempuri.org\"/>"), * new ActionCallback(new URI("http://tempuri.org/Action")), * result); * </pre> * * @author Arjen Poutsma * @since 1.0.0 */ public class ActionCallback implements WebServiceMessageCallback { private final AddressingVersion version; private final URI action; private final URI to; private MessageIdStrategy messageIdStrategy; private EndpointReference from; private EndpointReference replyTo; private EndpointReference faultTo; /** * Create a new {@code ActionCallback} with the given {@code Action}. * * <p>The {@code To} header of the outgoing message will reflect the {@link org.springframework.ws.transport.WebServiceConnection#getUri() * connection URI}. * * <p>The {@link AddressingVersion} is set to {@link Addressing10}. * * @param action the value of the action property to set */ public ActionCallback(String action) throws URISyntaxException { this(new URI(action), new Addressing10(), null); } /** * Create a new {@code ActionCallback} with the given {@code Action}. * * <p>The {@code To} header of the outgoing message will reflect the {@link org.springframework.ws.transport.WebServiceConnection#getUri() * connection URI}. * * <p>The {@link AddressingVersion} is set to {@link Addressing10}. * * @param action the value of the action property to set */ public ActionCallback(URI action) { this(action, new Addressing10(), null); } /** * Create a new {@code ActionCallback} with the given version and {@code Action}. * * <p>The {@code To} header of the outgoing message will reflect the {@link org.springframework.ws.transport.WebServiceConnection#getUri() * connection URI}. * * @param action the value of the action property to set * @param version the WS-Addressing version to use */ public ActionCallback(URI action, AddressingVersion version) { this(action, version, null); } /** * Create a new {@code ActionCallback} with the given version, {@code Action}, and optional * {@code To}. * * @param action the value of the action property * @param version the WS-Addressing version to use * @param to the value of the destination property */ public ActionCallback(URI action, AddressingVersion version, URI to) { Assert.notNull(action, "'action' must not be null"); Assert.notNull(version, "'version' must not be null"); this.action = action; this.version = version; this.to = to; messageIdStrategy = new UuidMessageIdStrategy(); } /** * Returns the WS-Addressing version */ public AddressingVersion getVersion() { return version; } /** * Returns the message id strategy used for creating WS-Addressing MessageIds. * * <p>By default, the {@link UuidMessageIdStrategy} is used. */ public MessageIdStrategy getMessageIdStrategy() { return messageIdStrategy; } /** * Sets the message id strategy used for creating WS-Addressing MessageIds. * * <p>By default, the {@link UuidMessageIdStrategy} is used. */ public void setMessageIdStrategy(MessageIdStrategy messageIdStrategy) { Assert.notNull(messageIdStrategy, "'messageIdStrategy' must not be null"); this.messageIdStrategy = messageIdStrategy; } /** * Returns the {@code Action}. * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getAction() */ public URI getAction() { return action; } /** * Returns the {@code From}. * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getFrom() */ public EndpointReference getFrom() { return from; } /** * Sets the {@code From}. * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getFrom() */ public void setFrom(EndpointReference from) { this.from = from; } /** * Returns the {@code ReplyTo}. * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getReplyTo() */ public EndpointReference getReplyTo() { return replyTo; } /** * Sets the {@code ReplyTo}. * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getReplyTo() */ public void setReplyTo(EndpointReference replyTo) { this.replyTo = replyTo; } /** * Returns the {@code FaultTo}. * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getFaultTo() */ public EndpointReference getFaultTo() { return faultTo; } /** * Sets the {@code FaultTo}. * @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getFaultTo() */ public void setFaultTo(EndpointReference faultTo) { this.faultTo = faultTo; } /** * Returns the {@code Destination} for outgoing messages. * * <p>Defaults to the {@link org.springframework.ws.transport.WebServiceConnection#getUri() connection URI} if no * destination was set. */ protected URI getTo() { if (to == null) { TransportContext transportContext = TransportContextHolder.getTransportContext(); if (transportContext != null && transportContext.getConnection() != null) { try { return transportContext.getConnection().getUri(); } catch (URISyntaxException ex) { // ignore } } throw new IllegalStateException("Could not obtain connection URI from Transport Context"); } else { return to; } } @Override public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException { Assert.isInstanceOf(SoapMessage.class, message); SoapMessage soapMessage = (SoapMessage) message; URI messageId = getMessageIdStrategy().newMessageId(soapMessage); MessageAddressingProperties map = new MessageAddressingProperties(getTo(), getFrom(), getReplyTo(), getFaultTo(), getAction(), messageId); version.addAddressingHeaders(soapMessage, map); } }