1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ws.addressing.handler;
18
19 import org.apache.axis.message.addressing.Action;
20 import org.apache.axis.message.addressing.AddressingHeaders;
21 import org.apache.axis.message.addressing.Constants;
22 import org.apache.axis.message.addressing.EndpointReference;
23 import org.apache.axis.message.addressing.To;
24 import org.apache.axis.types.URI;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import javax.xml.rpc.JAXRPCException;
29 import javax.xml.rpc.handler.MessageContext;
30 import javax.xml.rpc.handler.soap.SOAPMessageContext;
31 import javax.xml.soap.SOAPMessage;
32
33 /***
34 * A client-side JAX-RPC {@link javax.xml.rpc.handler.Handler} that inserts WS-Addressing headers into outgoing SOAP requests
35 * and extracts them from incoming SOAP responses.
36 *
37 * @author Davanum Srinivas (dims@yahoo.com)
38 * @author Ian P. Springer <ian_springer@hp.com>
39 */
40 public class ClientSideAddressingHandler extends AbstractAddressingHandler {
41
42 private static final Log LOG =
43 LogFactory.getLog(ClientSideAddressingHandler.class.getName());
44
45 private static final String MSG_CONTEXT_PROP__SOAP_ACTION = javax.xml.rpc.Call.SOAPACTION_URI_PROPERTY;
46
47 public boolean handleRequest(MessageContext msgContext) {
48 SOAPMessageContext soapMsgContext = (SOAPMessageContext) msgContext;
49 try {
50 AddressingHeaders headers =
51 (AddressingHeaders) msgContext.getProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS);
52 if (headers == null) {
53 headers = new AddressingHeaders();
54 }
55 headers.setSetMustUnderstand(isMustUnderstandEnabled(msgContext));
56 addMessageIdHeader(headers);
57 addToHeader(headers, msgContext);
58 addActionHeader(headers, msgContext);
59 addFromHeader(headers, msgContext);
60 addReplyToHeader(headers, msgContext);
61 if (headers.getFaultTo() == null && msgContext
62 .containsProperty(Constants.ENV_ADDRESSING_FAULTTO_URI)) {
63 headers.setFaultTo(new EndpointReference((String) msgContext
64 .getProperty(Constants.ENV_ADDRESSING_FAULTTO_URI)));
65 }
66
67 SOAPMessage msg = soapMsgContext.getMessage();
68 headers.toEnvelope(msg.getSOAPPart().getEnvelope(), getActor());
69 msgContext.setProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS, headers);
70 } catch (Exception e) {
71 if (LOG.isDebugEnabled()) {
72 e.printStackTrace();
73 }
74 throw new JAXRPCException("unexpected error in handleRequest(): " + e, e);
75 }
76 return CONTINUE_HANDLER_CHAIN_PROCESSING;
77 }
78
79 public boolean handleResponse(MessageContext msgContext) {
80 SOAPMessageContext soapMsgContext = (SOAPMessageContext) msgContext;
81 try {
82 SOAPMessage msg = soapMsgContext.getMessage();
83 if (msg == null) {
84 return CONTINUE_HANDLER_CHAIN_PROCESSING;
85 }
86
87 AddressingHeaders headers =
88 new AddressingHeaders(msg.getSOAPPart().getEnvelope(),
89 getActor(),
90 true,
91 isRemoveHeadersEnabled(),
92 false,
93 getReferencePropertyQNames());
94 msgContext.setProperty(Constants.ENV_ADDRESSING_RESPONSE_HEADERS,
95 headers);
96 } catch (Exception e) {
97 if (LOG.isDebugEnabled()) {
98 e.printStackTrace();
99 }
100 throw new JAXRPCException("unexpected error in handleResponse(): " + e, e);
101 }
102 return CONTINUE_HANDLER_CHAIN_PROCESSING;
103 }
104
105 public boolean handleFault(MessageContext messageContext) {
106 return CONTINUE_HANDLER_CHAIN_PROCESSING;
107 }
108
109 /***
110 * The JAX-RPC APIs don't provide a way to retrieve the value of the SOAPAction HTTP header,
111 * so platform-specific subclasses should implement this method if feasible.
112 *
113 * @param msgContext JAX-RPC message context
114 * @return the value of the SOAPAction HTTP header
115 */
116 protected String getSOAPAction(MessageContext msgContext) {
117 String soapAction = (String) msgContext.getProperty(MSG_CONTEXT_PROP__SOAP_ACTION);
118 return soapAction != null ? soapAction : "";
119 }
120
121 /***
122 * The JAX-RPC APIs don't provide a way to set the value of the SOAPAction HTTP header,
123 * so platform-specific subclasses should implement this method if feasible.
124 *
125 * @param msgContext JAX-RPC message context
126 * @param actionURI the SOAPAction URI to be set
127 */
128 protected void setSOAPAction(MessageContext msgContext, String actionURI) {
129 msgContext.setProperty(MSG_CONTEXT_PROP__SOAP_ACTION, actionURI);
130 }
131
132 /***
133 * Returns the endpoint URL for the specified message context. Since there's no
134 * generic JAX-RPC way to obtain the request's endpoint URL, we return null here.
135 * Platform-specific handlers can override if the platform provides a means to
136 * obtain the endpoint URL.
137 *
138 * @return the endpoint URL for the specified message context
139 */
140 protected String getEndpointURL(MessageContext msgContext) {
141 return null;
142 }
143
144 private void addReplyToHeader(AddressingHeaders addrHeaders, MessageContext msgContext)
145 throws URI.MalformedURIException {
146 if (isPropertyTrue(msgContext, Constants.ENV_ADDRESSING_SEND_REPLYTO)) {
147 if (addrHeaders.getReplyTo() == null) {
148 if (msgContext
149 .containsProperty(Constants.ENV_ADDRESSING_REPLYTO_URI)) {
150 addrHeaders.setReplyTo(new EndpointReference((String) msgContext
151 .getProperty(Constants.ENV_ADDRESSING_REPLYTO_URI)));
152 } else {
153 addrHeaders.setReplyTo(addrHeaders.getFrom());
154 }
155 }
156 }
157 }
158
159 private void addFromHeader(AddressingHeaders addrHeaders, MessageContext msgContext)
160 throws URI.MalformedURIException {
161 if (addrHeaders.getFrom() == null) {
162 if (msgContext
163 .containsProperty(Constants.ENV_ADDRESSING_FROM_URI)) {
164 addrHeaders.setFrom(new EndpointReference((String) msgContext
165 .getProperty(Constants.ENV_ADDRESSING_FROM_URI)));
166 } else {
167 addrHeaders.setFrom(new EndpointReference(Constants.NS_URI_ANONYMOUS));
168 }
169 }
170 }
171
172 private void addMessageIdHeader(AddressingHeaders addrHeaders)
173 throws URI.MalformedURIException {
174 if (addrHeaders.getMessageID() == null) {
175 addrHeaders.setMessageID(createMessageID());
176 }
177 }
178
179 private void addToHeader(AddressingHeaders addrHeaders, MessageContext msgContext)
180 throws URI.MalformedURIException {
181 if (addrHeaders.getTo() == null) {
182 String endpointURL = getEndpointURL(msgContext);
183 addrHeaders.setTo(endpointURL != null ? new To(endpointURL) : null);
184 }
185 }
186
187 private void addActionHeader(AddressingHeaders addrHeaders, MessageContext msgContext)
188 throws URI.MalformedURIException {
189 String actionURI = getSOAPAction(msgContext);
190 if (actionURI != null) {
191 addrHeaders.setAction(new Action(new URI(actionURI)));
192 } else if (addrHeaders.getAction() != null) {
193 setSOAPAction(msgContext, addrHeaders.getAction().toString());
194 }
195 }
196
197 }