Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/client/AxisClient.java


1   /*
2    * Copyright 2001-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.axis.client ;
18  
19  import javax.xml.namespace.QName;
20  import javax.xml.rpc.handler.HandlerChain;
21  
22  import org.apache.axis.AxisEngine;
23  import org.apache.axis.AxisFault;
24  import org.apache.axis.Constants;
25  import org.apache.axis.EngineConfiguration;
26  import org.apache.axis.Handler;
27  import org.apache.axis.MessageContext;
28  import org.apache.axis.components.logger.LogFactory;
29  import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
30  import org.apache.axis.handlers.HandlerInfoChainFactory;
31  import org.apache.axis.handlers.soap.MustUnderstandChecker;
32  import org.apache.axis.handlers.soap.SOAPService;
33  import org.apache.axis.utils.Messages;
34  import org.apache.commons.logging.Log;
35  
36  /**
37   * Provides the equivalent of an "Axis engine" on the client side.
38   * Subclasses hardcode initialization & setup logic for particular
39   * client-side transports.
40   *
41   * @author Rob Jellinghaus (robj@unrealities.com)
42   * @author Doug Davis (dug@us.ibm.com)
43   * @author Glen Daniels (gdaniels@allaire.com)
44   */
45  public class AxisClient extends AxisEngine {
46      protected static Log log =
47              LogFactory.getLog(AxisClient.class.getName());
48  
49      MustUnderstandChecker checker = new MustUnderstandChecker(null);
50  
51      public AxisClient(EngineConfiguration config) {
52          super(config);
53      }
54  
55      public AxisClient() {
56          this(EngineConfigurationFactoryFinder.newFactory().
57                  getClientEngineConfig());
58      }
59  
60      /**
61       * @return this instance, as this is the client engine
62       */
63      public AxisEngine getClientEngine () {
64          return this;
65      }
66  
67      /**
68       * Main routine of the AXIS engine.  In short we locate the appropriate
69       * handler for the desired service and invoke() it.
70       *
71       * @param msgContext the <code>MessageContext</code> to invoke relative
72       *                   to
73       * @throws AxisFault if anything goes wrong during invocation
74       */
75      public void invoke(MessageContext msgContext) throws AxisFault {
76          if (log.isDebugEnabled()) {
77              log.debug("Enter: AxisClient::invoke");
78          }
79          String hName = null;
80          Handler h = null;
81          HandlerChain handlerImpl = null;
82          
83          // save previous context
84          MessageContext previousContext = getCurrentMessageContext();
85          try {
86              // set active context
87              setCurrentMessageContext(msgContext);
88              hName = msgContext.getStrProp(MessageContext.ENGINE_HANDLER);
89              if (log.isDebugEnabled()) {
90                  log.debug("EngineHandler: " + hName);
91              }
92              if (hName != null) {
93                  h = getHandler(hName);
94                  if (h != null)
95                      h.invoke(msgContext);
96                  else
97                      throw new AxisFault("Client.error",
98                              Messages.getMessage("noHandler00",
99                                      hName),
100                             null, null);
101             } else {
102                 /* Now we do the 'real' work.  The flow is basically:         */
103                 /*                                                            */
104                 /*   Service Specific Request Chain                           */
105                 /*   Global Request Chain                                     */
106                 /*   Transport Request Chain - must have a send at the end    */
107                 /*   Transport Response Chain                                 */
108                 /*   Global Response Chain                                    */
109                 /*   Service Specific Response Chain                          */
110                 /*   Protocol Specific-Handler/Checker                        */
111                 /**************************************************************/
112                 SOAPService service = null;
113                 msgContext.setPastPivot(false);
114 
115                 /* Process the Service Specific Request Chain */
116                 /**********************************************/
117                 service = msgContext.getService();
118                 if (service != null) {
119                     h = service.getRequestHandler();
120                     if (h != null)
121                         h.invoke(msgContext);
122                 }
123 
124                 /* Process the Global Request Chain */
125                 /**********************************/
126                 if ((h = getGlobalRequest()) != null)
127                     h.invoke(msgContext);
128 
129                 /* Process the JAX-RPC Handlers  - handleRequest.
130                  * Make sure to set the pastPivot to true if this returns a
131                  * false. In that case we do not invoke the transport request
132                  * chain. Also note that if a a false was returned from the
133                  * JAX-RPC handler chain, then the chain still holds the index
134                  * of the handler that returned false. So when we invoke the
135                  * handleResponse method of the chain, it will correctly call
136                  * the handleResponse from that specific handler instance. So
137                  * do not destroy the chain at this point - the chain will be
138                  * destroyed in the finally block.
139                  */
140                 handlerImpl = getJAXRPChandlerChain(msgContext);
141                 if (handlerImpl != null) {
142                     try {
143                         if (!handlerImpl.handleRequest(msgContext)) {
144                             msgContext.setPastPivot(true);
145                         }
146                     } catch (RuntimeException re) {
147                         handlerImpl.destroy();  // WS4EE 1.1 6.2.2.1 Handler Life Cycle. "RuntimeException" --> destroy handler
148                         throw re;
149                     }
150                 }
151 
152                 /** Process the Transport Specific stuff
153                  *
154                  * NOTE: Somewhere in here there is a handler which actually
155                  * sends the message and receives a response.  Generally
156                  * this is the pivot point in the Transport chain. But invoke
157                  * this only if pivot point has not been set to false. This
158                  * can be set to false if any of the JAX-RPC handler's
159                  * handleRequest returned false.
160                  */
161                 if (!msgContext.getPastPivot()) {
162                     hName = msgContext.getTransportName();
163                     if (hName != null && (h = getTransport(hName)) != null) {
164                         try {
165                             h.invoke(msgContext);
166                         } catch (AxisFault e) {
167                             throw e;
168                         }
169                     } else {
170                         throw new AxisFault(Messages.getMessage("noTransport00",
171                                 hName));
172                     }
173                 }
174                 
175                 msgContext.setPastPivot(true);
176                 if (!msgContext.isPropertyTrue(Call.ONE_WAY)) {
177                     if ((handlerImpl != null) &&
178                             !msgContext.isPropertyTrue(Call.ONE_WAY)) {
179                         try {
180                             handlerImpl.handleResponse(msgContext);                            
181                         } catch (RuntimeException ex) {
182                             handlerImpl.destroy();  // WS4EE 1.1 6.2.2.1 Handler Life Cycle. "RuntimeException" --> destroy handler
183                             throw ex;    
184                         }                        
185                     }
186 
187                     /* Process the Global Response Chain */
188                     /***********************************/
189                     if ((h = getGlobalResponse()) != null) {
190                         h.invoke(msgContext);
191                     }
192                     
193                     /* Process the Service-Specific Response Chain */
194                     /***********************************************/
195                     if (service != null) {
196                         h = service.getResponseHandler();
197                         if (h != null) {
198                             h.invoke(msgContext);
199                         }
200                     }
201 
202                     // Do SOAP Semantics checks here - this needs to be a call
203                     // to a pluggable object/handler/something
204                     if (msgContext.isPropertyTrue(Call.CHECK_MUST_UNDERSTAND,
205                             true)) {
206                         checker.invoke(msgContext);
207                     }
208                 }
209             }
210         } catch (Exception e) {
211             // Should we even bother catching it ?
212             if (e instanceof AxisFault) {
213                 throw (AxisFault) e;
214             } else {
215                 log.debug(Messages.getMessage("exception00"), e);
216                 throw AxisFault.makeFault(e);
217             }
218         } finally {
219             if (handlerImpl != null) {
220                 handlerImpl.destroy();
221             }
222             // restore previous state
223             setCurrentMessageContext(previousContext);
224         }
225         if (log.isDebugEnabled()) {
226             log.debug("Exit: AxisClient::invoke");
227         }
228     }
229 
230     /**
231      * @param context Stores the Service, port QName and optionnaly a HandlerInfoChainFactory
232      * @return Returns a HandlerChain if one has been specified
233      */
234     protected HandlerChain getJAXRPChandlerChain(MessageContext context) {
235         java.util.List chain = null;
236         HandlerInfoChainFactory hiChainFactory = null;
237         boolean clientSpecified = false;
238 
239         Service service = (Service) context.getProperty(Call.WSDL_SERVICE);
240         if(service == null) {
241             return null;
242         }
243 
244         QName portName = (QName) context.getProperty(Call.WSDL_PORT_NAME);
245         if(portName == null) {
246             return null;
247         }
248 
249         javax.xml.rpc.handler.HandlerRegistry registry;
250         registry = service.getHandlerRegistry();
251         if(registry != null) {
252             chain = registry.getHandlerChain(portName);
253             if ((chain != null) && (!chain.isEmpty())) {
254                 hiChainFactory = new HandlerInfoChainFactory(chain);
255                 clientSpecified = true;
256             }
257         }
258 
259         // Otherwise, use the container support
260         if (!clientSpecified) {
261             SOAPService soapService = context.getService();
262             if (soapService != null) {
263                 // A client configuration exists for this service.  Check
264                 // to see if there is a HandlerInfoChain configured on it.
265                 hiChainFactory = (HandlerInfoChainFactory)
266                         soapService.getOption(Constants.ATTR_HANDLERINFOCHAIN);
267             }
268         }
269 
270         if (hiChainFactory == null) {
271             return null;
272         }
273 
274         return hiChainFactory.createHandlerChain();
275     }
276 
277 }