KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > client > AxisClient


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 JavaDoc;
20 import javax.xml.rpc.handler.HandlerChain JavaDoc;
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 JavaDoc hName = null;
80         Handler h = null;
81         HandlerChain JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc getJAXRPChandlerChain(MessageContext context) {
235         java.util.List JavaDoc 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 JavaDoc portName = (QName JavaDoc) context.getProperty(Call.WSDL_PORT_NAME);
245         if(portName == null) {
246             return null;
247         }
248
249         javax.xml.rpc.handler.HandlerRegistry JavaDoc 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 }
278
Popular Tags