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

Quick Search    Search Deep

Source code: org/apache/axis/server/AxisServer.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.server ;
18  
19  import org.apache.axis.AxisEngine;
20  import org.apache.axis.AxisFault;
21  import org.apache.axis.AxisProperties;
22  import org.apache.axis.Constants;
23  import org.apache.axis.EngineConfiguration;
24  import org.apache.axis.Handler;
25  import org.apache.axis.Message;
26  import org.apache.axis.MessageContext;
27  import org.apache.axis.SimpleTargetedChain;
28  import org.apache.axis.message.SOAPEnvelope;
29  import org.apache.axis.soap.SOAPConstants;
30  import org.apache.axis.client.AxisClient;
31  import org.apache.axis.components.logger.LogFactory;
32  import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
33  import org.apache.axis.utils.ClassUtils;
34  import org.apache.axis.utils.Messages;
35  import org.apache.commons.logging.Log;
36  
37  import java.util.Map;
38  /**
39   *
40   * @author Doug Davis (dug@us.ibm.com)
41   * @author Glen Daniels (gdaniels@allaire.com)
42   */
43  public class AxisServer extends AxisEngine
44  {
45      protected static Log log =
46          LogFactory.getLog(AxisServer.class.getName());
47      private static Log tlog =
48          LogFactory.getLog("org.apache.axis.TIME");
49  
50      private static AxisServerFactory factory = null;
51      
52      public static AxisServer getServer(Map environment) throws AxisFault
53      {
54          if (factory == null) {
55              String factoryClassName = AxisProperties.getProperty("axis.ServerFactory");
56              if (factoryClassName != null) {
57                  try {
58                      Class factoryClass = ClassUtils.forName(factoryClassName);
59                      if (AxisServerFactory.class.isAssignableFrom(factoryClass))
60                          factory = (AxisServerFactory)factoryClass.newInstance();
61                  } catch (Exception e) {
62                      // If something goes wrong here, should we just fall
63                      // through and use the default one?
64                      log.error(Messages.getMessage("exception00"), e);
65                  }
66              }
67              
68              if (factory == null) {
69                  factory = new DefaultAxisServerFactory();
70              }
71          }
72          
73          return factory.getServer(environment);                
74      }
75  
76      /**
77       * the AxisClient to be used by outcalling Services
78       */
79      private AxisEngine clientEngine;
80  
81      public AxisServer()
82      {
83          this(EngineConfigurationFactoryFinder.newFactory().getServerEngineConfig());
84      }
85  
86      public AxisServer(EngineConfiguration config)
87      {
88          super(config);
89          // Server defaults to persisting configuration
90          setShouldSaveConfig(true);
91      }
92  
93      /** Is this server active?  If this is false, any requests will
94       * cause a SOAP Server fault to be generated.
95       */
96      private boolean running = true;
97  
98      public boolean isRunning() { return running; }
99  
100     /** Start the server.
101      */
102     public void start()
103     {
104         // re-init...
105         init();
106         running = true;
107     }
108 
109     /** Stop the server.
110      */
111     public void stop()
112     {
113         running = false;
114     }
115 
116     /**
117      * Get this server's client engine.  Create it if it does
118      * not yet exist.
119      */
120     public synchronized AxisEngine getClientEngine () {
121         if (clientEngine == null) {
122             clientEngine = new AxisClient(); // !!!!
123         }
124         return clientEngine;
125     }
126 
127     /**
128      * Main routine of the AXIS server.  In short we locate the appropriate
129      * handler for the desired service and invoke() it.
130      */
131     public void invoke(MessageContext msgContext) throws AxisFault {
132         long t0=0, t1=0, t2=0, t3=0, t4=0, t5=0;
133         if( tlog.isDebugEnabled() ) {
134             t0=System.currentTimeMillis();
135         }
136         
137         if (log.isDebugEnabled()) {
138             log.debug("Enter: AxisServer::invoke");
139         }
140 
141         if (!isRunning()) {
142             throw new AxisFault("Server.disabled",
143                                 Messages.getMessage("serverDisabled00"),
144                                 null, null);
145         }
146 
147         String  hName = null ;
148         Handler h     = null ;
149 
150         // save previous context
151         MessageContext previousContext = getCurrentMessageContext();
152 
153         try {
154             // set active context
155             setCurrentMessageContext(msgContext);
156 
157             hName = msgContext.getStrProp( MessageContext.ENGINE_HANDLER );
158             if ( hName != null ) {
159                 if ( (h = getHandler(hName)) == null ) {
160                     ClassLoader cl = msgContext.getClassLoader();
161                     try {
162                         log.debug( Messages.getMessage("tryingLoad00", hName) );
163                         Class cls = ClassUtils.forName(hName, true, cl);
164                         h = (Handler) cls.newInstance();
165                     }
166                     catch( Exception e ) {
167                         h = null ;
168                     }
169                 }
170                 if( tlog.isDebugEnabled() ) {
171                     t1=System.currentTimeMillis();
172                 }
173                 if ( h != null )
174                     h.invoke(msgContext);
175                 else
176                     throw new AxisFault( "Server.error",
177                                          Messages.getMessage("noHandler00", hName),
178                                          null, null );
179                 if( tlog.isDebugEnabled() ) {
180                     t2=System.currentTimeMillis();
181                     tlog.debug( "AxisServer.invoke " + hName + " invoke=" +
182                                 ( t2-t1 ) + " pre=" + (t1-t0 ));
183                 }
184                 
185             }
186             else {
187                 // This really should be in a handler - but we need to discuss it
188                 // first - to make sure that's what we want.
189                 /* Now we do the 'real' work.  The flow is basically:         */
190                 /*   Transport Specific Request Handler/Chain                   */
191                 /*   Global Request Handler/Chain                               */
192                 /*   Protocol Specific-Handler(ie. SOAP, XP)                  */
193                 /*     ie. For SOAP Handler:                                  */
194                 /*           - Service Specific Request Handler/Chain           */
195                 /*           - SOAP Semantic Checks                           */
196                 /*           - Service Specific Response Handler/Chain          */
197                 /*   Global Response Handler/Chain                              */
198                 /*   Transport Specific Response Handler/Chain                  */
199                 /**************************************************************/
200 
201                 // When do we call init/cleanup??
202                 if (log.isDebugEnabled()) {
203                     log.debug(Messages.getMessage("defaultLogic00") );
204                 }
205 
206                 /*  This is what the entirety of this logic might evolve to:
207 
208                 hName = msgContext.getStrProp(MessageContext.TRANSPORT);
209                 if ( hName != null ) {
210                 if ((h = hr.find( hName )) != null ) {
211                 h.invoke(msgContext);
212                 } else {
213                 log.error(Messages.getMessage("noTransport02", hName));
214                 }
215                 } else {
216                 // No transport set, so use the default (probably just
217                 // calls the global->service handlers)
218                 defaultTransport.invoke(msgContext);
219                 }
220 
221                 */
222 
223                 /* Process the Transport Specific Request Chain */
224                 /**********************************************/
225                 hName = msgContext.getTransportName();
226                 SimpleTargetedChain transportChain = null;
227 
228                 if (log.isDebugEnabled())
229                     log.debug(Messages.getMessage("transport01", "AxisServer.invoke", hName));
230 
231                 if( tlog.isDebugEnabled() ) {
232                     t1=System.currentTimeMillis();
233                 }
234                 if ( hName != null && (h = getTransport( hName )) != null ) {
235                     if (h instanceof SimpleTargetedChain) {
236                         transportChain = (SimpleTargetedChain)h;
237                         h = transportChain.getRequestHandler();
238                         if (h != null)
239                             h.invoke(msgContext);
240                     }
241                 }
242 
243                 if( tlog.isDebugEnabled() ) {
244                     t2=System.currentTimeMillis();
245                 }
246                 /* Process the Global Request Chain */
247                 /**********************************/
248                 if ((h = getGlobalRequest()) != null ) {
249                     h.invoke(msgContext);
250                 }
251 
252                 /**
253                  * At this point, the service should have been set by someone
254                  * (either the originator of the MessageContext, or one of the
255                  * transport or global Handlers).  If it hasn't been set, we
256                  * fault.
257                  */
258                 h = msgContext.getService();
259                 if (h == null) {
260                     // It's possible that we haven't yet parsed the
261                     // message at this point.  This is a kludge to
262                     // make sure we have.  There probably wants to be
263                     // some kind of declarative "parse point" on the handler
264                     // chain instead....
265                     Message rm = msgContext.getRequestMessage();
266                     rm.getSOAPEnvelope().getFirstBody();
267                     
268                     h = msgContext.getService();
269                     if (h == null)
270                         throw new AxisFault("Server.NoService",
271                                             Messages.getMessage("noService05",
272                                                                  "" + msgContext.getTargetService()),
273                                             null, null );
274                 }
275                 if( tlog.isDebugEnabled() ) {
276                     t3=System.currentTimeMillis();
277                 }
278                 
279                 initSOAPConstants(msgContext);
280                 try {
281                     h.invoke(msgContext);
282                 } catch (AxisFault ae) {
283                     if ((h = getGlobalRequest()) != null ) {
284                         h.onFault(msgContext);
285                     }
286                     throw ae;
287                 }
288 
289                 if( tlog.isDebugEnabled() ) {
290                     t4=System.currentTimeMillis();
291                 }
292 
293                 /* Process the Global Response Chain */
294                 /***********************************/
295                 if ((h = getGlobalResponse()) != null)
296                     h.invoke(msgContext);
297 
298                 /* Process the Transport Specific Response Chain */
299                 /***********************************************/
300                 if (transportChain != null) {
301                     h = transportChain.getResponseHandler();
302                     if (h != null)
303                         h.invoke(msgContext);
304                 }
305                 
306                 if( tlog.isDebugEnabled() ) {
307                     t5=System.currentTimeMillis();
308                     tlog.debug( "AxisServer.invoke2 " +
309                                 " preTr=" +
310                                 ( t1-t0 ) + " tr=" + (t2-t1 ) +
311                                 " preInvoke=" + ( t3-t2 ) +
312                                 " invoke=" + ( t4-t3 ) +
313                                 " postInvoke=" + ( t5-t4 ) +
314                                 " " + msgContext.getTargetService() + "." +
315                                  ((msgContext.getOperation( ) == null) ?
316                                  "" : msgContext.getOperation().getName()) );
317                 }
318 
319             }
320         } catch (AxisFault e) {
321             throw e;
322         } catch (Exception e) {
323             // Should we even bother catching it ?
324             throw AxisFault.makeFault(e);
325 
326         } finally {
327             // restore previous state
328             setCurrentMessageContext(previousContext);
329         }
330         
331         if (log.isDebugEnabled()) {
332             log.debug("Exit: AxisServer::invoke");
333         }
334     }
335 
336     /**
337      * Extract ans store soap constants info from the envelope
338      * @param msgContext
339      * @throws AxisFault
340      */ 
341     private void initSOAPConstants(MessageContext msgContext) throws AxisFault {
342         Message msg = msgContext.getRequestMessage();
343         if (msg == null)
344             return;
345         SOAPEnvelope env = msg.getSOAPEnvelope();
346         if (env == null)
347             return;
348         SOAPConstants constants = env.getSOAPConstants();
349         if (constants == null)
350             return;
351         // Ensure that if we get SOAP1.2, then reply using SOAP1.2
352         msgContext.setSOAPConstants(constants);
353     }
354 
355     /**
356      *
357      */
358     public void generateWSDL(MessageContext msgContext) throws AxisFault {
359         if (log.isDebugEnabled()) {
360             log.debug("Enter: AxisServer::generateWSDL");
361         }
362 
363         if (!isRunning()) {
364             throw new AxisFault("Server.disabled",
365                                 Messages.getMessage("serverDisabled00"),
366                                 null, null);
367         }
368 
369         String  hName = null ;
370         Handler h     = null ;
371 
372         // save previous context
373         MessageContext previousContext = getCurrentMessageContext();
374 
375         try {
376             // set active context
377             setCurrentMessageContext(msgContext);
378 
379             hName = msgContext.getStrProp( MessageContext.ENGINE_HANDLER );
380             if ( hName != null ) {
381                 if ( (h = getHandler(hName)) == null ) {
382                     ClassLoader cl = msgContext.getClassLoader();
383                     try {
384                         log.debug( Messages.getMessage("tryingLoad00", hName) );
385                         Class cls = ClassUtils.forName(hName, true, cl);
386                         h = (Handler) cls.newInstance();
387                     }
388                     catch( Exception e ) {
389                         throw new AxisFault(
390                                 "Server.error",
391                                 Messages.getMessage("noHandler00", hName),
392                                 null, null );
393                     }
394                 }
395                 h.generateWSDL(msgContext);
396             }
397             else {
398                 // This really should be in a handler - but we need to discuss it
399                 // first - to make sure that's what we want.
400                 /* Now we do the 'real' work.  The flow is basically:         */
401                 /*   Transport Specific Request Handler/Chain                   */
402                 /*   Global Request Handler/Chain                               */
403                 /*   Protocol Specific-Handler(ie. SOAP, XP)                  */
404                 /*     ie. For SOAP Handler:                                  */
405                 /*           - Service Specific Request Handler/Chain           */
406                 /*           - SOAP Semantic Checks                           */
407                 /*           - Service Specific Response Handler/Chain          */
408                 /*   Global Response Handler/Chain                              */
409                 /*   Transport Specific Response Handler/Chain                  */
410                 /**************************************************************/
411 
412                 // When do we call init/cleanup??
413                 log.debug( Messages.getMessage("defaultLogic00") );
414 
415                 /*  This is what the entirety of this logic might evolve to:
416 
417                 hName = msgContext.getStrProp(MessageContext.TRANSPORT);
418                 if ( hName != null ) {
419                 if ((h = hr.find( hName )) != null ) {
420                 h.generateWSDL(msgContext);
421                 } else {
422                 log.error(Messages.getMessage("noTransport02", hName));
423                 }
424                 } else {
425                 // No transport set, so use the default (probably just
426                 // calls the global->service handlers)
427                 defaultTransport.generateWSDL(msgContext);
428                 }
429 
430                 */
431 
432                 /* Process the Transport Specific Request Chain */
433                 /**********************************************/
434                 hName = msgContext.getTransportName();
435                 SimpleTargetedChain transportChain = null;
436 
437                 if (log.isDebugEnabled())
438                     log.debug(Messages.getMessage("transport01",
439                                                    "AxisServer.generateWSDL",
440                                                    hName));
441                 if ( hName != null && (h = getTransport( hName )) != null ) {
442                     if (h instanceof SimpleTargetedChain) {
443                         transportChain = (SimpleTargetedChain)h;
444                         h = transportChain.getRequestHandler();
445                         if (h != null) {
446                             h.generateWSDL(msgContext);
447                         }
448                     }
449                 }
450 
451                 /* Process the Global Request Chain */
452                 /**********************************/
453                 if ((h = getGlobalRequest()) != null )
454                     h.generateWSDL(msgContext);
455 
456                 /**
457                  * At this point, the service should have been set by someone
458                  * (either the originator of the MessageContext, or one of the
459                  * transport or global Handlers).  If it hasn't been set, we
460                  * fault.
461                  */
462                 h = msgContext.getService();
463                 if (h == null) {
464                     // It's possible that we haven't yet parsed the
465                     // message at this point.  This is a kludge to
466                     // make sure we have.  There probably wants to be
467                     // some kind of declarative "parse point" on the handler
468                     // chain instead....
469                     Message rm = msgContext.getRequestMessage();
470                     if (rm != null) {
471                         rm.getSOAPEnvelope().getFirstBody();
472                         h = msgContext.getService();
473                     }
474                     if (h == null) {
475                         throw new AxisFault(Constants.QNAME_NO_SERVICE_FAULT_CODE,
476                                             Messages.getMessage("noService05",
477                                                                  "" + msgContext.getTargetService()),
478                                             null, null );
479                     }
480                 }
481 
482                 h.generateWSDL(msgContext);
483 
484                 /* Process the Global Response Chain */
485                 /***********************************/
486                 if ((h = getGlobalResponse()) != null )
487                     h.generateWSDL(msgContext);
488 
489                 /* Process the Transport Specific Response Chain */
490                 /***********************************************/
491                 if (transportChain != null) {
492                     h = transportChain.getResponseHandler();
493                     if (h != null) {
494                         h.generateWSDL(msgContext);
495                     }
496                 }
497             }
498         } catch (AxisFault e) {
499             throw e;
500         } catch(Exception e) {
501             // Should we even bother catching it ?
502             throw AxisFault.makeFault(e);
503         } finally {
504             // restore previous state
505             setCurrentMessageContext(previousContext);
506         }
507 
508         if (log.isDebugEnabled()) {
509             log.debug("Exit: AxisServer::generateWSDL");
510         }
511     }
512 }