KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > tomcat > TomcatContainer


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 package org.apache.geronimo.tomcat;
18
19 import java.io.File JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.net.URLStreamHandlerFactory JavaDoc;
23 import java.net.URL JavaDoc;
24
25 import org.apache.catalina.Container;
26 import org.apache.catalina.Context;
27 import org.apache.catalina.Engine;
28 import org.apache.catalina.Realm;
29 import org.apache.catalina.connector.Connector;
30 import org.apache.catalina.realm.JAASRealm;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.geronimo.gbean.GBeanInfo;
34 import org.apache.geronimo.gbean.GBeanInfoBuilder;
35 import org.apache.geronimo.gbean.GBeanLifecycle;
36 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
37 import org.apache.geronimo.management.geronimo.NetworkConnector;
38 import org.apache.geronimo.management.geronimo.WebManager;
39 import org.apache.geronimo.system.serverinfo.ServerInfo;
40 import org.apache.geronimo.tomcat.realm.TomcatGeronimoRealm;
41 import org.apache.geronimo.tomcat.realm.TomcatJAASRealm;
42 import org.apache.geronimo.tomcat.util.SecurityHolder;
43 import org.apache.geronimo.webservices.SoapHandler;
44 import org.apache.geronimo.webservices.WebServiceContainer;
45 import org.apache.naming.resources.DirContextURLStreamHandlerFactory;
46
47
48 /**
49  * Apache Tomcat GBean
50  * http://wiki.apache.org/geronimo/Tomcat
51  * http://nagoya.apache.org/jira/browse/GERONIMO-215
52  *
53  * @version $Rev: 486195 $ $Date: 2006-12-12 10:42:02 -0500 (Tue, 12 Dec 2006) $
54  */

55 public class TomcatContainer implements SoapHandler, GBeanLifecycle, TomcatWebContainer {
56
57     private static final Log log = LogFactory.getLog(TomcatContainer.class);
58
59     /**
60      * The default value of CATALINA_HOME variable
61      */

62     private static final String JavaDoc DEFAULT_CATALINA_HOME = "var/catalina";
63
64     /**
65      * Reference to the org.apache.catalina.Embedded embedded.
66      */

67     private TomcatGeronimoEmbedded embedded;
68
69     /**
70      * Tomcat Engine that will contain the host
71      */

72     private Engine engine;
73
74     /**
75      * Geronimo class loader
76      */

77     private ClassLoader JavaDoc classLoader;
78
79     private final Map JavaDoc webServices = new HashMap JavaDoc();
80     private final String JavaDoc objectName;
81     private final WebManager manager;
82     private static boolean first = true;
83
84     // Required as it's referenced by deployed webapps
85
public TomcatContainer() {
86         this.objectName = null; // is this OK??
87
setCatalinaHome(DEFAULT_CATALINA_HOME);
88         manager = null;
89     }
90
91     /**
92      * GBean constructor (invoked dynamically when the gbean is declared in a plan)
93      */

94     public TomcatContainer(ClassLoader JavaDoc classLoader, String JavaDoc catalinaHome, ObjectRetriever engineGBean, ServerInfo serverInfo, String JavaDoc objectName, WebManager manager) {
95         // Register a stream handler factory for the JNDI protocol
96
URLStreamHandlerFactory JavaDoc streamHandlerFactory =
97             new DirContextURLStreamHandlerFactory();
98         if (first) {
99             first = false;
100             try {
101                 URL.setURLStreamHandlerFactory(streamHandlerFactory);
102             } catch (Exception JavaDoc e) {
103                 // Log and continue anyway, this is not critical
104
log.error("Error registering jndi stream handler", e);
105             } catch (Throwable JavaDoc t) {
106                 // This is likely a dual registration
107
log.info("Dual registration of jndi stream handler: "
108                          + t.getMessage());
109             }
110         }
111
112
113         if (catalinaHome == null)
114             catalinaHome = DEFAULT_CATALINA_HOME;
115
116         setCatalinaHome(serverInfo.resolveServerPath(catalinaHome));
117
118         if (classLoader == null) {
119             throw new IllegalArgumentException JavaDoc("classLoader cannot be null.");
120         }
121
122         if (engineGBean == null) {
123             throw new IllegalArgumentException JavaDoc("engineGBean cannot be null.");
124         }
125
126         this.classLoader = classLoader;
127
128         this.engine = (Engine) engineGBean.getInternalObject();
129
130         this.objectName = objectName;
131         this.manager = manager;
132     }
133
134     public String JavaDoc getObjectName() {
135         return objectName;
136     }
137
138     public boolean isStateManageable() {
139         return true;
140     }
141
142     public boolean isStatisticsProvider() {
143         return false; // todo: return true once stats are integrated
144
}
145
146     public boolean isEventProvider() {
147         return true;
148     }
149
150     public NetworkConnector[] getConnectors() {
151         return manager.getConnectorsForContainer(this);
152     }
153
154     public NetworkConnector[] getConnectors(String JavaDoc protocol) {
155         return manager.getConnectorsForContainer(this, protocol);
156     }
157
158     public void doFail() {
159         try {
160             doStop();
161         } catch (Exception JavaDoc ignored) {
162         }
163     }
164
165     /**
166      * Instantiate and start up Tomcat's Embedded class
167      * <p/>
168      * See org.apache.catalina.startup.Embedded for details (TODO: provide the link to the javadoc)
169      */

170     public void doStart() throws Exception JavaDoc {
171         log.debug("doStart()");
172
173         log.debug("Endorsed Dirs set to:" + System.getProperty("java.endorsed.dirs"));
174
175         // The comments are from the javadoc of the Embedded class
176

177         // 1. Instantiate a new instance of this class.
178
if (embedded == null) {
179             embedded = new TomcatGeronimoEmbedded();
180         }
181
182         // Assemble FileLogger as a gbean
183
/*
184          * FileLogger fileLog = new FileLogger(); fileLog.setDirectory("."); fileLog.setPrefix("vsjMbedTC5");
185          * fileLog.setSuffix(".log"); fileLog.setTimestamp(true);
186          */

187
188         // 2. Set the relevant properties of this object itself. In particular,
189
// you will want to establish the default Logger to be used, as well as
190
// the default Realm if you are using container-managed security.
191
embedded.setUseNaming(false);
192
193         //Add default contexts
194
File JavaDoc rootContext = new File JavaDoc(System.getProperty("catalina.home") + "/ROOT");
195
196         String JavaDoc docBase = "";
197         if (rootContext.exists()) {
198             docBase = "ROOT";
199         }
200
201         Container[] hosts = engine.findChildren();
202         Context defaultContext;
203         for (int i = 0; i < hosts.length; i++) {
204             defaultContext = embedded.createContext("", docBase, classLoader);
205             if (defaultContext instanceof GeronimoStandardContext) {
206                 GeronimoStandardContext ctx = (GeronimoStandardContext) defaultContext;
207                 // Without this the Tomcat FallBack Application is left behind,
208
// MBean - ...J2EEApplication=none,J2EEServer=none,..........
209
ctx.setJ2EEApplication(null);
210                 // TODO if objectName != null extract J2EEServer from objectName/host
211
ctx.setJ2EEServer("geronimo");
212             }
213             hosts[i].addChild(defaultContext);
214         }
215
216         // 6. Call addEngine() to attach this Engine to the set of defined
217
// Engines for this object.
218
embedded.addEngine(engine);
219
220         // 9. Call start() to initiate normal operations of all the attached
221
// components.
222
embedded.start();
223     }
224
225     public void doStop() throws Exception JavaDoc {
226         if (embedded != null) {
227             embedded.stop();
228             embedded = null;
229         }
230
231     }
232
233     /**
234      * Creates and adds the context to the running host
235      * <p/>
236      * It simply delegates the call to Tomcat's Embedded and Host classes
237      *
238      * @param ctx the context to be added
239      * @see org.apache.catalina.startup.Embedded
240      * @see org.apache.catalina.Host
241      */

242     public void addContext(TomcatContext ctx) throws Exception JavaDoc {
243         Context anotherCtxObj = embedded.createContext(ctx.getContextPath(), ctx.getDocBase(), ctx.getClassLoader());
244
245         // Set the context for the Tomcat implementation
246
ctx.setContext(anotherCtxObj);
247
248         // Have the context to set its properties if its a GeronimoStandardContext
249
if (anotherCtxObj instanceof GeronimoStandardContext) {
250             ((GeronimoStandardContext) anotherCtxObj).setContextProperties(ctx);
251         }
252         //Was a virtual server defined?
253
String JavaDoc virtualServer = ctx.getVirtualServer();
254         if (virtualServer == null) {
255             virtualServer = engine.getDefaultHost();
256         }
257         Container host = engine.findChild(virtualServer);
258         if (host == null) {
259             throw new IllegalArgumentException JavaDoc("Invalid virtual host '" + virtualServer + "'. Do you have a matching Host entry in the plan?");
260         }
261
262         //Get the security-realm-name if there is one
263
String JavaDoc securityRealmName = null;
264         SecurityHolder secHolder = ctx.getSecurityHolder();
265         if (secHolder != null)
266             securityRealmName = secHolder.getSecurityRealm();
267
268         //Did we declare a GBean at the context level?
269
if (ctx.getRealm() != null) {
270             Realm realm = ctx.getRealm();
271
272             //Allow for the <security-realm-name> override from the
273
//geronimo-web.xml file to be used if our Realm is a JAAS type
274
if (securityRealmName != null) {
275                 if (realm instanceof JAASRealm) {
276                     ((JAASRealm) realm).setAppName(securityRealmName);
277                 }
278             }
279             anotherCtxObj.setRealm(realm);
280         } else {
281             Realm realm = host.getRealm();
282             //Check and see if we have a declared realm name and no match to a parent name
283
if (securityRealmName != null) {
284                 String JavaDoc parentRealmName = null;
285                 if (realm instanceof JAASRealm) {
286                     parentRealmName = ((JAASRealm) realm).getAppName();
287                 }
288
289                 //Do we have a match to a parent?
290
if (!securityRealmName.equals(parentRealmName)) {
291                     //No...we need to create a default adapter
292

293                     //Is the context requiring JACC?
294
if (secHolder.isSecurity()) {
295                         //JACC
296
realm = new TomcatGeronimoRealm();
297                     } else {
298                         //JAAS
299
realm = new TomcatJAASRealm();
300                     }
301
302                     log.debug("The security-realm-name '" + securityRealmName +
303                             "' was specified and a parent (Engine/Host) is not named the same or no RealmGBean was configured for this context. " +
304                             "Creating a default " + realm.getClass().getName() +
305                             " adapter for this context.");
306
307                     ((JAASRealm) realm).setUserClassNames("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal");
308                     ((JAASRealm) realm).setRoleClassNames("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal");
309                     ((JAASRealm) realm).setAppName(securityRealmName);
310
311                     anotherCtxObj.setRealm(realm);
312                 } else {
313                     //Use the parent since a name matches
314
anotherCtxObj.setRealm(realm);
315                 }
316             } else {
317                 anotherCtxObj.setRealm(realm);
318             }
319         }
320
321         host.addChild(anotherCtxObj);
322     }
323
324     public void removeContext(TomcatContext ctx) {
325         Context context = ctx.getContext();
326
327         if (context != null) {
328             if (context instanceof GeronimoStandardContext) {
329                 GeronimoStandardContext stdctx = (GeronimoStandardContext) context;
330
331                 try {
332                     stdctx.stop();
333                     stdctx.destroy();
334                 } catch (Exception JavaDoc e) {
335                     throw new RuntimeException JavaDoc(e);
336                 }
337
338             }
339             context.getParent().removeChild(context);
340         }
341
342     }
343
344     public void setCatalinaHome(String JavaDoc catalinaHome) {
345         System.setProperty("catalina.home", catalinaHome);
346     }
347
348     public void addConnector(Connector connector) {
349         embedded.addConnector(connector);
350     }
351
352     public void removeConnector(Connector connector) {
353         embedded.removeConnector(connector);
354     }
355
356     public void addWebService(String JavaDoc contextPath, String JavaDoc[] virtualHosts, WebServiceContainer webServiceContainer, String JavaDoc securityRealmName, String JavaDoc realmName, String JavaDoc transportGuarantee, String JavaDoc authMethod, ClassLoader JavaDoc classLoader) throws Exception JavaDoc {
357         Context webServiceContext = embedded.createEJBWebServiceContext(contextPath, webServiceContainer, securityRealmName, realmName, transportGuarantee, authMethod, classLoader);
358
359         String JavaDoc virtualServer;
360         if (virtualHosts != null && virtualHosts.length > 0) {
361             virtualServer = virtualHosts[0];
362         } else {
363             virtualServer = engine.getDefaultHost();
364         }
365
366         Container host = engine.findChild(virtualServer);
367         if (host == null) {
368             throw new IllegalArgumentException JavaDoc("Invalid virtual host '" + virtualServer + "'. Do you have a matchiing Host entry in the plan?");
369         }
370
371         host.addChild(webServiceContext);
372         webServices.put(contextPath, webServiceContext);
373     }
374
375     public void removeWebService(String JavaDoc contextPath) {
376         TomcatEJBWebServiceContext context = (TomcatEJBWebServiceContext) webServices.get(contextPath);
377         try {
378             context.stop();
379             context.destroy();
380         } catch (Exception JavaDoc e) {
381             throw new RuntimeException JavaDoc(e);
382         }
383         context.getParent().removeChild(context);
384         webServices.remove(contextPath);
385     }
386
387     public static final GBeanInfo GBEAN_INFO;
388
389     static {
390         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Tomcat Web Container", TomcatContainer.class);
391
392         infoFactory.setConstructor(new String JavaDoc[]{"classLoader", "catalinaHome", "EngineGBean", "ServerInfo", "objectName", "WebManager"});
393
394         infoFactory.addAttribute("classLoader", ClassLoader JavaDoc.class, false);
395
396         infoFactory.addAttribute("catalinaHome", String JavaDoc.class, true);
397
398         infoFactory.addAttribute("objectName", String JavaDoc.class, false);
399
400         infoFactory.addReference("EngineGBean", ObjectRetriever.class, NameFactory.GERONIMO_SERVICE);
401
402         infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean");
403         infoFactory.addReference("WebManager", WebManager.class);
404
405         infoFactory.addOperation("addContext", new Class JavaDoc[]{TomcatContext.class});
406         infoFactory.addOperation("removeContext", new Class JavaDoc[]{TomcatContext.class});
407
408         infoFactory.addOperation("addConnector", new Class JavaDoc[]{Connector.class});
409         infoFactory.addOperation("removeConnector", new Class JavaDoc[]{Connector.class});
410
411         infoFactory.addInterface(SoapHandler.class);
412         infoFactory.addInterface(TomcatWebContainer.class);
413
414         GBEAN_INFO = infoFactory.getBeanInfo();
415     }
416
417     public static GBeanInfo getGBeanInfo() {
418         return GBEAN_INFO;
419     }
420
421 }
422
Popular Tags