1 /*
2 * Title: Container
3 * Description:
4 *
5 * This software is published under the terms of the OpenSymphony Software
6 * License version 1.1, of which a copy has been included with this
7 * distribution in the LICENSE.txt file.
8 */
9
10 package com.opensymphony.module.sitemesh.util;
11
12 import java.util.HashMap;
13 import java.util.Iterator;
14 import java.util.Map;
15
16 /**
17 * Utility for determining the Servlet Container the application is running in.
18 * Currently supported containers: Tomcat, Resin, Orion, OC4J, WebLogic, HPAS, JRun,
19 * Websphere.
20 *
21 * <h3>Usage:</h3>
22 *
23 * <code>if (Container.get() == Container.TOMCAT) { .... }</code>
24 *
25 * @author <a href="mailto:joe@truemesh.com">Joe Walnes</a>
26 * @version $Revision: 1.2 $
27 */
28 public final class Container {
29 public static final int UNKNOWN = 0;
30 public static final int TOMCAT = 1;
31 public static final int RESIN = 2;
32 public static final int ORION = 3; // Orion or OC4J
33 public static final int WEBLOGIC = 4;
34 public static final int HPAS = 5;
35 public static final int JRUN = 6;
36 public static final int WEBSPHERE = 7;
37
38 private static int result = -1;
39
40 /**
41 * A map containing classes that can be searched for,
42 * and which container they are typically found in.
43 */
44 private static Map classMappings = null;
45
46 static {
47 // initialize the classes that can be searched for
48 classMappings = new HashMap(6);
49 classMappings.put("org.apache.jasper.runtime.JspFactoryImpl", new Integer(TOMCAT));
50 classMappings.put("com.caucho.jsp.JspServlet", new Integer(RESIN));
51 classMappings.put("com.evermind.server.http.JSPServlet", new Integer(ORION));
52 classMappings.put("weblogic.servlet.JSPServlet", new Integer(WEBLOGIC));
53 classMappings.put("com.hp.mwlabs.j2ee.containers.servlet.jsp.JspServlet", new Integer(HPAS));
54 classMappings.put("jrun.servlet.WebApplicationService", new Integer(JRUN));
55 classMappings.put("com.ibm.ws.webcontainer.jsp.servlet.JspServlet", new Integer(WEBSPHERE));
56 }
57
58 /** Get the current container. */
59 public static int get() {
60 if (result == -1) {
61 final String classMatch = searchForClosestClass(classMappings);
62
63 if (classMatch == null) {
64 result = UNKNOWN;
65 }
66 else {
67 result = ((Integer) classMappings.get(classMatch)).intValue();
68 }
69 }
70 return result;
71 }
72
73 /**
74 * Walk up the classloader hierachy and attempt to find a class in the classMappings Map
75 * that can be loaded.
76 *
77 * @return Name of the match class, or null if not found.
78 */
79 private static String searchForClosestClass(Map classMappings) {
80 // get closest classloader
81 ClassLoader loader = Container.class.getClassLoader();
82
83 // iterate up through the classloader hierachy (through parents), until no more left.
84 while (loader != null) {
85
86 for (Iterator iterator = classMappings.keySet().iterator(); iterator.hasNext();) {
87 String className = (String) iterator.next();
88
89 try {
90 // attempt to load current classname with current classloader
91 loader.loadClass(className);
92 // if no exception has been thrown, we're in luck.
93 return className;
94 }
95 catch (ClassNotFoundException e) {
96 // no problem... we'll keep trying...
97 }
98 }
99 loader = loader.getParent();
100 }
101
102 // couldn't find anything
103 return null;
104 }
105 }