View Javadoc

1   /*
2    * Copyright 2008 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.soap.addressing.client;
18  
19  import java.io.IOException;
20  import java.net.URI;
21  import java.net.URISyntaxException;
22  import javax.xml.transform.TransformerException;
23  
24  import org.springframework.core.JdkVersion;
25  import org.springframework.util.Assert;
26  import org.springframework.ws.WebServiceMessage;
27  import org.springframework.ws.client.core.WebServiceMessageCallback;
28  import org.springframework.ws.soap.SoapMessage;
29  import org.springframework.ws.soap.addressing.core.EndpointReference;
30  import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
31  import org.springframework.ws.soap.addressing.messageid.MessageIdStrategy;
32  import org.springframework.ws.soap.addressing.messageid.RandomGuidMessageIdStrategy;
33  import org.springframework.ws.soap.addressing.messageid.UuidMessageIdStrategy;
34  import org.springframework.ws.soap.addressing.version.Addressing10;
35  import org.springframework.ws.soap.addressing.version.AddressingVersion;
36  import org.springframework.ws.transport.context.TransportContext;
37  import org.springframework.ws.transport.context.TransportContextHolder;
38  
39  /**
40   * {@link WebServiceMessageCallback} implementation that sets the WS-Addressing <code>Action</code> header on the
41   * message.
42   * <p/>
43   * A usage example with {@link org.springframework.ws.client.core.WebServiceTemplate}:
44   * <pre>
45   * WebServiceTemplate template = new WebServiceTemplate(messageFactory);
46   * Result result = new DOMResult();
47   * template.sendSourceAndReceiveToResult(
48   *     new StringSource("&lt;content xmlns=\"http://tempuri.org\"/&gt;"),
49   *     new ActionCallback(new URI("http://tempuri.org/Action")),
50   *     result);
51   * </pre>
52   *
53   * @author Arjen Poutsma
54   * @since 1.0.0
55   */
56  public class ActionCallback implements WebServiceMessageCallback {
57  
58      private final AddressingVersion version;
59  
60      private final URI action;
61  
62      private final URI to;
63  
64      private MessageIdStrategy messageIdStrategy;
65  
66      private EndpointReference from;
67  
68      private EndpointReference replyTo;
69  
70      private EndpointReference faultTo;
71  
72      /**
73       * Create a new <code>ActionCallback</code> with the given <code>Action</code>.
74       * <p/>
75       * The <code>To</code> header of the outgoing message will reflect the {@link org.springframework.ws.transport.WebServiceConnection#getUri()
76       * connection URI}.
77       * <p/>
78       * The {@link AddressingVersion} is set to {@link Addressing10}.
79       *
80       * @param action the value of the action property to set
81       */
82      public ActionCallback(String action) throws URISyntaxException {
83          this(new URI(action), new Addressing10(), null);
84      }
85  
86      /**
87       * Create a new <code>ActionCallback</code> with the given <code>Action</code>.
88       * <p/>
89       * The <code>To</code> header of the outgoing message will reflect the {@link org.springframework.ws.transport.WebServiceConnection#getUri()
90       * connection URI}.
91       * <p/>
92       * The {@link AddressingVersion} is set to {@link Addressing10}.
93       *
94       * @param action the value of the action property to set
95       */
96      public ActionCallback(URI action) {
97          this(action, new Addressing10(), null);
98      }
99  
100     /**
101      * Create a new <code>ActionCallback</code> with the given version and <code>Action</code>.
102      * <p/>
103      * The <code>To</code> header of the outgoing message will reflect the {@link org.springframework.ws.transport.WebServiceConnection#getUri()
104      * connection URI}.
105      *
106      * @param action  the value of the action property to set
107      * @param version the WS-Addressing version to use
108      */
109     public ActionCallback(URI action, AddressingVersion version) {
110         this(action, version, null);
111     }
112 
113     /**
114      * Create a new <code>ActionCallback</code> with the given version, <code>Action</code>, and optional
115      * <code>To</code>.
116      *
117      * @param action  the value of the action property
118      * @param version the WS-Addressing version to use
119      * @param action  the value of the destination property
120      */
121     public ActionCallback(URI action, AddressingVersion version, URI to) {
122         Assert.notNull(action, "'action' must not be null");
123         Assert.notNull(version, "'version' must not be null");
124         this.action = action;
125         this.version = version;
126         this.to = to;
127         if (JdkVersion.isAtLeastJava15()) {
128             messageIdStrategy = new UuidMessageIdStrategy();
129         }
130         else {
131             messageIdStrategy = new RandomGuidMessageIdStrategy();
132         }
133     }
134 
135     /**
136      * Sets the message id strategy used for creating WS-Addressing MessageIds.
137      * <p/>
138      * By default, the {@link UuidMessageIdStrategy} is used on Java 5 and higher, and the {@link
139      * RandomGuidMessageIdStrategy} on Java 1.4.
140      */
141     public void setMessageIdStrategy(MessageIdStrategy messageIdStrategy) {
142         Assert.notNull(messageIdStrategy, "'messageIdStrategy' must not be null");
143         this.messageIdStrategy = messageIdStrategy;
144     }
145 
146     public void setFrom(EndpointReference from) {
147         this.from = from;
148     }
149 
150     public void setReplyTo(EndpointReference replyTo) {
151         this.replyTo = replyTo;
152     }
153 
154     public void setFaultTo(EndpointReference faultTo) {
155         this.faultTo = faultTo;
156     }
157 
158     /**
159      * Returns the <code>Destination</code> for outgoing messages.
160      * <p/>
161      * Defaults to the {@link org.springframework.ws.transport.WebServiceConnection#getUri() connection URI} if no
162      * destination was set.
163      */
164     protected URI getTo() {
165         if (to == null) {
166             TransportContext transportContext = TransportContextHolder.getTransportContext();
167             if (transportContext != null && transportContext.getConnection() != null) {
168                 try {
169                     return transportContext.getConnection().getUri();
170                 }
171                 catch (URISyntaxException ex) {
172                     // ignore
173                 }
174             }
175             throw new IllegalStateException("Could not obtain connection URI from Transport Context");
176         }
177         else {
178             return to;
179         }
180     }
181 
182     public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
183         Assert.isInstanceOf(SoapMessage.class, message);
184         SoapMessage soapMessage = (SoapMessage) message;
185         URI to = getTo();
186         URI messageId = messageIdStrategy.newMessageId(soapMessage);
187         MessageAddressingProperties map =
188                 new MessageAddressingProperties(to, from, replyTo, faultTo, action, messageId);
189         version.addAddressingHeaders(soapMessage, map);
190     }
191 
192 
193 }