View Javadoc

1   /*
2    * Copyright  2004 The Apache Software Foundation.
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.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 }