KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > core > StandardEngine


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.core;
20
21
22 import java.io.File JavaDoc;
23 import java.util.List JavaDoc;
24
25 import javax.management.MBeanServer JavaDoc;
26 import javax.management.MalformedObjectNameException JavaDoc;
27 import javax.management.ObjectName JavaDoc;
28
29 import org.apache.catalina.Container;
30 import org.apache.catalina.Engine;
31 import org.apache.catalina.Host;
32 import org.apache.catalina.LifecycleException;
33 import org.apache.catalina.Realm;
34 import org.apache.catalina.Service;
35 import org.apache.catalina.realm.JAASRealm;
36 import org.apache.catalina.util.ServerInfo;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.tomcat.util.modeler.Registry;
40 import org.apache.tomcat.util.modeler.modules.MbeansSource;
41
42 /**
43  * Standard implementation of the <b>Engine</b> interface. Each
44  * child container must be a Host implementation to process the specific
45  * fully qualified host name of that virtual host. <br/>
46  * You can set the jvmRoute direct or with the System.property <b>jvmRoute</b>.
47  *
48  * @author Craig R. McClanahan
49  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
50  */

51
52 public class StandardEngine
53     extends ContainerBase
54     implements Engine {
55
56     private static Log log = LogFactory.getLog(StandardEngine.class);
57
58     // ----------------------------------------------------------- Constructors
59

60
61     /**
62      * Create a new StandardEngine component with the default basic Valve.
63      */

64     public StandardEngine() {
65
66         super();
67         pipeline.setBasic(new StandardEngineValve());
68         /* Set the jmvRoute using the system property jvmRoute */
69         try {
70             setJvmRoute(System.getProperty("jvmRoute"));
71         } catch(Exception JavaDoc ex) {
72         }
73         // By default, the engine will hold the reloading thread
74
backgroundProcessorDelay = 10;
75
76     }
77
78
79     // ----------------------------------------------------- Instance Variables
80

81
82     /**
83      * Host name to use when no server host, or an unknown host,
84      * is specified in the request.
85      */

86     private String JavaDoc defaultHost = null;
87
88
89     /**
90      * The descriptive information string for this implementation.
91      */

92     private static final String JavaDoc info =
93         "org.apache.catalina.core.StandardEngine/1.0";
94
95
96     /**
97      * The <code>Service</code> that owns this Engine, if any.
98      */

99     private Service service = null;
100
101     /** Allow the base dir to be specified explicitely for
102      * each engine. In time we should stop using catalina.base property -
103      * otherwise we loose some flexibility.
104      */

105     private String JavaDoc baseDir = null;
106
107     /** Optional mbeans config file. This will replace the "hacks" in
108      * jk and ServerListener. The mbeans file will support (transparent)
109      * persistence - soon. It'll probably replace jk2.properties and could
110      * replace server.xml. Of course - the same beans could be loaded and
111      * managed by an external entity - like the embedding app - which
112      * can use a different persistence mechanism.
113      */

114     private String JavaDoc mbeansFile = null;
115     
116     /** Mbeans loaded by the engine.
117      */

118     private List JavaDoc mbeans;
119     
120
121     /**
122      * The JVM Route ID for this Tomcat instance. All Route ID's must be unique
123      * across the cluster.
124      */

125     private String JavaDoc jvmRouteId;
126
127
128     // ------------------------------------------------------------- Properties
129

130     /** Provide a default in case no explicit configuration is set
131      *
132      * @return configured realm, or a JAAS realm by default
133      */

134     public Realm getRealm() {
135         Realm configured=super.getRealm();
136         // If no set realm has been called - default to JAAS
137
// This can be overriden at engine, context and host level
138
if( configured==null ) {
139             configured=new JAASRealm();
140             this.setRealm( configured );
141         }
142         return configured;
143     }
144
145
146     /**
147      * Return the default host.
148      */

149     public String JavaDoc getDefaultHost() {
150
151         return (defaultHost);
152
153     }
154
155
156     /**
157      * Set the default host.
158      *
159      * @param host The new default host
160      */

161     public void setDefaultHost(String JavaDoc host) {
162
163         String JavaDoc oldDefaultHost = this.defaultHost;
164         if (host == null) {
165             this.defaultHost = null;
166         } else {
167             this.defaultHost = host.toLowerCase();
168         }
169         support.firePropertyChange("defaultHost", oldDefaultHost,
170                                    this.defaultHost);
171
172     }
173     
174     public void setName(String JavaDoc name ) {
175         if( domain != null ) {
176             // keep name==domain, ignore override
177
// we are already registered
178
super.setName( domain );
179             return;
180         }
181         // The engine name is used as domain
182
domain=name; // XXX should we set it in init() ? It shouldn't matter
183
super.setName( name );
184     }
185
186
187     /**
188      * Set the cluster-wide unique identifier for this Engine.
189      * This value is only useful in a load-balancing scenario.
190      * <p>
191      * This property should not be changed once it is set.
192      */

193     public void setJvmRoute(String JavaDoc routeId) {
194         jvmRouteId = routeId;
195     }
196
197
198     /**
199      * Retrieve the cluster-wide unique identifier for this Engine.
200      * This value is only useful in a load-balancing scenario.
201      */

202     public String JavaDoc getJvmRoute() {
203         return jvmRouteId;
204     }
205
206
207     /**
208      * Return the <code>Service</code> with which we are associated (if any).
209      */

210     public Service getService() {
211
212         return (this.service);
213
214     }
215
216
217     /**
218      * Set the <code>Service</code> with which we are associated (if any).
219      *
220      * @param service The service that owns this Engine
221      */

222     public void setService(Service service) {
223         this.service = service;
224     }
225
226     public String JavaDoc getMbeansFile() {
227         return mbeansFile;
228     }
229
230     public void setMbeansFile(String JavaDoc mbeansFile) {
231         this.mbeansFile = mbeansFile;
232     }
233
234     public String JavaDoc getBaseDir() {
235         if( baseDir==null ) {
236             baseDir=System.getProperty("catalina.base");
237         }
238         if( baseDir==null ) {
239             baseDir=System.getProperty("catalina.home");
240         }
241         return baseDir;
242     }
243
244     public void setBaseDir(String JavaDoc baseDir) {
245         this.baseDir = baseDir;
246     }
247
248     // --------------------------------------------------------- Public Methods
249

250
251     /**
252      * Add a child Container, only if the proposed child is an implementation
253      * of Host.
254      *
255      * @param child Child container to be added
256      */

257     public void addChild(Container child) {
258
259         if (!(child instanceof Host))
260             throw new IllegalArgumentException JavaDoc
261                 (sm.getString("standardEngine.notHost"));
262         super.addChild(child);
263
264     }
265
266
267     /**
268      * Return descriptive information about this Container implementation and
269      * the corresponding version number, in the format
270      * <code>&lt;description&gt;/&lt;version&gt;</code>.
271      */

272     public String JavaDoc getInfo() {
273
274         return (info);
275
276     }
277
278     /**
279      * Disallow any attempt to set a parent for this Container, since an
280      * Engine is supposed to be at the top of the Container hierarchy.
281      *
282      * @param container Proposed parent Container
283      */

284     public void setParent(Container container) {
285
286         throw new IllegalArgumentException JavaDoc
287             (sm.getString("standardEngine.notParent"));
288
289     }
290
291
292     private boolean initialized=false;
293     
294     public void init() {
295         if( initialized ) return;
296         initialized=true;
297
298         if( oname==null ) {
299             // not registered in JMX yet - standalone mode
300
try {
301                 if (domain==null) {
302                     domain=getName();
303                 }
304                 if(log.isDebugEnabled())
305                     log.debug( "Register " + domain );
306                 oname=new ObjectName JavaDoc(domain + ":type=Engine");
307                 controller=oname;
308                 Registry.getRegistry(null, null)
309                     .registerComponent(this, oname, null);
310             } catch( Throwable JavaDoc t ) {
311                 log.info("Error registering ", t );
312             }
313         }
314
315         if( mbeansFile == null ) {
316             String JavaDoc defaultMBeansFile=getBaseDir() + "/conf/tomcat5-mbeans.xml";
317             File JavaDoc f=new File JavaDoc( defaultMBeansFile );
318             if( f.exists() ) mbeansFile=f.getAbsolutePath();
319         }
320         if( mbeansFile != null ) {
321             readEngineMbeans();
322         }
323         if( mbeans != null ) {
324             try {
325                 Registry.getRegistry(null, null).invoke(mbeans, "init", false);
326             } catch (Exception JavaDoc e) {
327                 log.error("Error in init() for " + mbeansFile, e);
328             }
329         }
330         
331         // not needed since the following if statement does the same thing the right way
332
// remove later after checking
333
//if( service==null ) {
334
// try {
335
// ObjectName serviceName=getParentName();
336
// if( mserver.isRegistered( serviceName )) {
337
// log.info("Registering with the service ");
338
// try {
339
// mserver.invoke( serviceName, "setContainer",
340
// new Object[] { this },
341
// new String[] { "org.apache.catalina.Container" } );
342
// } catch( Exception ex ) {
343
// ex.printStackTrace();
344
// }
345
// }
346
// } catch( Exception ex ) {
347
// log.error("Error registering with service ");
348
// }
349
//}
350

351         if( service==null ) {
352             // for consistency...: we are probably in embeded mode
353
try {
354                 service=new StandardService();
355                 service.setContainer( this );
356                 service.initialize();
357             } catch( Throwable JavaDoc t ) {
358                 log.error(t);
359             }
360         }
361         
362     }
363     
364     public void destroy() throws LifecycleException {
365         if( ! initialized ) return;
366         initialized=false;
367         
368         // if we created it, make sure it's also destroyed
369
// this call implizit this.stop()
370
((StandardService)service).destroy();
371
372         if( mbeans != null ) {
373             try {
374                 Registry.getRegistry(null, null)
375                     .invoke(mbeans, "destroy", false);
376             } catch (Exception JavaDoc e) {
377                 log.error(sm.getString("standardEngine.unregister.mbeans.failed" ,mbeansFile), e);
378             }
379         }
380         //
381
if( mbeans != null ) {
382             try {
383                 for( int i=0; i<mbeans.size() ; i++ ) {
384                     Registry.getRegistry(null, null)
385                         .unregisterComponent((ObjectName JavaDoc)mbeans.get(i));
386                 }
387             } catch (Exception JavaDoc e) {
388                 log.error(sm.getString("standardEngine.unregister.mbeans.failed", mbeansFile), e);
389             }
390         }
391         
392         // force all metadata to be reloaded.
393
// That doesn't affect existing beans. We should make it per
394
// registry - and stop using the static.
395
Registry.getRegistry(null, null).resetMetadata();
396         
397     }
398     
399     /**
400      * Start this Engine component.
401      *
402      * @exception LifecycleException if a startup error occurs
403      */

404     public void start() throws LifecycleException {
405         if( started ) {
406             return;
407         }
408         if( !initialized ) {
409             init();
410         }
411
412         // Look for a realm - that may have been configured earlier.
413
// If the realm is added after context - it'll set itself.
414
if( realm == null ) {
415             ObjectName JavaDoc realmName=null;
416             try {
417                 realmName=new ObjectName JavaDoc( domain + ":type=Realm");
418                 if( mserver.isRegistered(realmName ) ) {
419                     mserver.invoke(realmName, "init",
420                             new Object JavaDoc[] {},
421                             new String JavaDoc[] {}
422                     );
423                 }
424             } catch( Throwable JavaDoc t ) {
425                 log.debug("No realm for this engine " + realmName);
426             }
427         }
428             
429         // Log our server identification information
430
//System.out.println(ServerInfo.getServerInfo());
431
if(log.isInfoEnabled())
432             log.info( "Starting Servlet Engine: " + ServerInfo.getServerInfo());
433         if( mbeans != null ) {
434             try {
435                 Registry.getRegistry(null, null)
436                     .invoke(mbeans, "start", false);
437             } catch (Exception JavaDoc e) {
438                 log.error("Error in start() for " + mbeansFile, e);
439             }
440         }
441
442         // Standard container startup
443
super.start();
444
445     }
446     
447     public void stop() throws LifecycleException {
448         super.stop();
449         if( mbeans != null ) {
450             try {
451                 Registry.getRegistry(null, null).invoke(mbeans, "stop", false);
452             } catch (Exception JavaDoc e) {
453                 log.error("Error in stop() for " + mbeansFile, e);
454             }
455         }
456     }
457
458
459     /**
460      * Return a String representation of this component.
461      */

462     public String JavaDoc toString() {
463
464         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("StandardEngine[");
465         sb.append(getName());
466         sb.append("]");
467         return (sb.toString());
468
469     }
470
471
472     // ------------------------------------------------------ Protected Methods
473

474
475     // -------------------- JMX registration --------------------
476

477     public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server,
478                                   ObjectName JavaDoc name) throws Exception JavaDoc
479     {
480         super.preRegister(server,name);
481
482         this.setName( name.getDomain());
483
484         return name;
485     }
486
487     // FIXME Remove -- not used
488
public ObjectName JavaDoc getParentName() throws MalformedObjectNameException JavaDoc {
489         if (getService()==null) {
490             return null;
491         }
492         String JavaDoc name = getService().getName();
493         ObjectName JavaDoc serviceName=new ObjectName JavaDoc(domain +
494                         ":type=Service,serviceName="+name);
495         return serviceName;
496     }
497     
498     public ObjectName JavaDoc createObjectName(String JavaDoc domain, ObjectName JavaDoc parent)
499         throws Exception JavaDoc
500     {
501         if( log.isDebugEnabled())
502             log.debug("Create ObjectName " + domain + " " + parent );
503         return new ObjectName JavaDoc( domain + ":type=Engine");
504     }
505
506     
507     private void readEngineMbeans() {
508         try {
509             MbeansSource mbeansMB=new MbeansSource();
510             File JavaDoc mbeansF=new File JavaDoc( mbeansFile );
511             mbeansMB.setSource(mbeansF);
512             
513             Registry.getRegistry(null, null).registerComponent
514                 (mbeansMB, domain + ":type=MbeansFile", null);
515             mbeansMB.load();
516             mbeansMB.init();
517             mbeansMB.setRegistry(Registry.getRegistry(null, null));
518             mbeans=mbeansMB.getMBeans();
519             
520         } catch( Throwable JavaDoc t ) {
521             log.error( "Error loading " + mbeansFile, t );
522         }
523         
524     }
525     
526     public String JavaDoc getDomain() {
527         if (domain!=null) {
528             return domain;
529         } else {
530             return getName();
531         }
532     }
533     
534     public void setDomain(String JavaDoc domain) {
535         this.domain = domain;
536     }
537     
538 }
539
Popular Tags