KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > winstone > ServletConfiguration


1 /*
2  * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
3  * Distributed under the terms of either:
4  * - the common development and distribution license (CDDL), v1.0; or
5  * - the GNU Lesser General Public License, v2.1 or later
6  */

7 package winstone;
8
9 import java.io.IOException JavaDoc;
10 import java.util.Collections JavaDoc;
11 import java.util.Enumeration JavaDoc;
12 import java.util.Hashtable JavaDoc;
13 import java.util.Map JavaDoc;
14
15 import javax.servlet.Servlet JavaDoc;
16 import javax.servlet.ServletContext JavaDoc;
17 import javax.servlet.ServletException JavaDoc;
18 import javax.servlet.ServletRequest JavaDoc;
19 import javax.servlet.ServletResponse JavaDoc;
20 import javax.servlet.UnavailableException JavaDoc;
21 import javax.servlet.http.HttpServletResponse JavaDoc;
22
23 import org.w3c.dom.Node JavaDoc;
24
25 /**
26  * This is the one that keeps a specific servlet instance's config, as well as
27  * holding the instance itself.
28  *
29  * @author <a HREF="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
30  * @version $Id: ServletConfiguration.java,v 1.15 2006/09/01 04:23:10 rickknowles Exp $
31  */

32 public class ServletConfiguration implements javax.servlet.ServletConfig JavaDoc,
33         Comparable JavaDoc {
34     
35     static final String JavaDoc ELEM_NAME = "servlet-name";
36     static final String JavaDoc ELEM_DISPLAY_NAME = "display-name";
37     static final String JavaDoc ELEM_CLASS = "servlet-class";
38     static final String JavaDoc ELEM_JSP_FILE = "jsp-file";
39     static final String JavaDoc ELEM_DESCRIPTION = "description";
40     static final String JavaDoc ELEM_INIT_PARAM = "init-param";
41     static final String JavaDoc ELEM_INIT_PARAM_NAME = "param-name";
42     static final String JavaDoc ELEM_INIT_PARAM_VALUE = "param-value";
43     static final String JavaDoc ELEM_LOAD_ON_STARTUP = "load-on-startup";
44     static final String JavaDoc ELEM_RUN_AS = "run-as";
45     static final String JavaDoc ELEM_SECURITY_ROLE_REF = "security-role-ref";
46     static final String JavaDoc ELEM_ROLE_NAME = "role-name";
47     static final String JavaDoc ELEM_ROLE_LINK = "role-link";
48     
49     final String JavaDoc JSP_FILE = "org.apache.catalina.jsp_file";
50
51     private String JavaDoc servletName;
52     private String JavaDoc classFile;
53     private Servlet JavaDoc instance;
54     private Map JavaDoc initParameters;
55     private WebAppConfiguration webAppConfig;
56     private int loadOnStartup;
57     private String JavaDoc jspFile;
58 // private String runAsRole;
59
private Map JavaDoc securityRoleRefs;
60     private Object JavaDoc servletSemaphore = new Boolean JavaDoc(true);
61     private boolean isSingleThreadModel = false;
62     private boolean unavailable = false;
63     private Throwable JavaDoc unavailableException = null;
64     
65     protected ServletConfiguration(WebAppConfiguration webAppConfig) {
66         this.webAppConfig = webAppConfig;
67         this.initParameters = new Hashtable JavaDoc();
68         this.loadOnStartup = -1;
69         this.securityRoleRefs = new Hashtable JavaDoc();
70     }
71
72     public ServletConfiguration(WebAppConfiguration webAppConfig, String JavaDoc servletName,
73             String JavaDoc className, Map JavaDoc initParams, int loadOnStartup) {
74         this(webAppConfig);
75         if (initParams != null)
76             this.initParameters.putAll(initParams);
77         this.servletName = servletName;
78         this.classFile = className;
79         this.jspFile = null;
80         this.loadOnStartup = loadOnStartup;
81     }
82
83     public ServletConfiguration(WebAppConfiguration webAppConfig, Node JavaDoc elm) {
84         this(webAppConfig);
85
86         // Parse the web.xml file entry
87
for (int n = 0; n < elm.getChildNodes().getLength(); n++) {
88             Node JavaDoc child = elm.getChildNodes().item(n);
89             if (child.getNodeType() != Node.ELEMENT_NODE)
90                 continue;
91             String JavaDoc nodeName = child.getNodeName();
92
93             // Construct the servlet instances
94
if (nodeName.equals(ELEM_NAME))
95                 this.servletName = WebAppConfiguration.getTextFromNode(child);
96             else if (nodeName.equals(ELEM_CLASS))
97                 this.classFile = WebAppConfiguration.getTextFromNode(child);
98             else if (nodeName.equals(ELEM_JSP_FILE))
99                 this.jspFile = WebAppConfiguration.getTextFromNode(child);
100             else if (nodeName.equals(ELEM_LOAD_ON_STARTUP)) {
101                 String JavaDoc index = child.getFirstChild() == null ? "-1" :
102                     WebAppConfiguration.getTextFromNode(child);
103                 this.loadOnStartup = Integer.parseInt(index);
104             } else if (nodeName.equals(ELEM_INIT_PARAM)) {
105                 String JavaDoc paramName = "";
106                 String JavaDoc paramValue = "";
107                 for (int k = 0; k < child.getChildNodes().getLength(); k++) {
108                     Node JavaDoc paramNode = child.getChildNodes().item(k);
109                     if (paramNode.getNodeType() != Node.ELEMENT_NODE)
110                         continue;
111                     else if (paramNode.getNodeName().equals(ELEM_INIT_PARAM_NAME))
112                         paramName = WebAppConfiguration.getTextFromNode(paramNode);
113                     else if (paramNode.getNodeName().equals(ELEM_INIT_PARAM_VALUE))
114                         paramValue = WebAppConfiguration.getTextFromNode(paramNode);
115                 }
116                 if (!paramName.equals("")) {
117                     this.initParameters.put(paramName, paramValue);
118                 }
119             } else if (nodeName.equals(ELEM_RUN_AS)) {
120                 for (int m = 0; m < child.getChildNodes().getLength(); m++) {
121                     Node JavaDoc roleElm = child.getChildNodes().item(m);
122                     if ((roleElm.getNodeType() == Node.ELEMENT_NODE)
123                             && (roleElm.getNodeName().equals(ELEM_ROLE_NAME))) {
124 // this.runAsRole = WebAppConfiguration.getTextFromNode(roleElm); // not used
125
}
126                 }
127             } else if (nodeName.equals(ELEM_SECURITY_ROLE_REF)) {
128                 String JavaDoc name = "";
129                 String JavaDoc link = "";
130                 for (int k = 0; k < child.getChildNodes().getLength(); k++) {
131                     Node JavaDoc roleRefNode = child.getChildNodes().item(k);
132                     if (roleRefNode.getNodeType() != Node.ELEMENT_NODE)
133                         continue;
134                     else if (roleRefNode.getNodeName().equals(ELEM_ROLE_NAME))
135                         name = WebAppConfiguration.getTextFromNode(roleRefNode);
136                     else if (roleRefNode.getNodeName().equals(ELEM_ROLE_LINK))
137                         link = WebAppConfiguration.getTextFromNode(roleRefNode);
138                 }
139                 if (!name.equals("") && !link.equals(""))
140                     this.initParameters.put(name, link);
141             }
142         }
143
144         if ((this.jspFile != null) && (this.classFile == null)) {
145             this.classFile = WebAppConfiguration.JSP_SERVLET_CLASS;
146             WebAppConfiguration.addJspServletParams(this.initParameters);
147         }
148         Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
149                 "ServletConfiguration.DeployedInstance", new String JavaDoc[] {
150                         this.servletName, this.classFile });
151     }
152     
153     public void ensureInitialization() {
154         
155         if (this.instance != null) {
156             return; // already init'd
157
}
158         
159         synchronized (this.servletSemaphore) {
160
161             if (this.instance != null) {
162                 return; // already init'd
163
}
164             
165             // Check if we were decommissioned while blocking
166
if (this.unavailableException != null) {
167                 return;
168             }
169             
170             // If no instance, class load, then call init()
171
ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
172             Thread.currentThread().setContextClassLoader(this.webAppConfig.getLoader());
173             
174             Servlet JavaDoc newInstance = null;
175             Throwable JavaDoc otherError = null;
176             try {
177                 Class JavaDoc servletClass = Class.forName(classFile, true, this.webAppConfig.getLoader());
178                 this.isSingleThreadModel = Class.forName("javax.servlet.SingleThreadModel").isInstance(this.instance);
179                 newInstance = (Servlet JavaDoc) servletClass.newInstance();
180                 
181                 // Initialise with the correct classloader
182
Logger.log(Logger.DEBUG, Launcher.RESOURCES, "ServletConfiguration.init", this.servletName);
183                 newInstance.init(this);
184                 this.instance = newInstance;
185             } catch (ClassNotFoundException JavaDoc err) {
186                 Logger.log(Logger.WARNING, Launcher.RESOURCES,
187                         "ServletConfiguration.ClassLoadError", this.classFile, err);
188                 setUnavailable(newInstance);
189                 this.unavailableException = err;
190             } catch (IllegalAccessException JavaDoc err) {
191                 Logger.log(Logger.WARNING, Launcher.RESOURCES,
192                         "ServletConfiguration.ClassLoadError", this.classFile, err);
193                 setUnavailable(newInstance);
194                 this.unavailableException = err;
195             } catch (InstantiationException JavaDoc err) {
196                 Logger.log(Logger.WARNING, Launcher.RESOURCES,
197                         "ServletConfiguration.ClassLoadError", this.classFile, err);
198                 setUnavailable(newInstance);
199                 this.unavailableException = err;
200             } catch (ServletException JavaDoc err) {
201                 Logger.log(Logger.WARNING, Launcher.RESOURCES,
202                         "ServletConfiguration.InitError", this.servletName, err);
203                 this.instance = null; // so that we don't call the destroy method
204
setUnavailable(newInstance);
205                 this.unavailableException = err;
206             } catch (RuntimeException JavaDoc err) {
207                 otherError = err;
208                 throw err;
209             } catch (Error JavaDoc err) {
210                 otherError = err;
211                 throw err;
212             } finally {
213                 Thread.currentThread().setContextClassLoader(cl);
214                 if ((otherError == null) && (this.unavailableException == null)) {
215                     this.instance = newInstance;
216                 }
217             }
218         }
219         return;
220     }
221
222     public void execute(ServletRequest JavaDoc request, ServletResponse JavaDoc response, String JavaDoc requestURI)
223             throws ServletException JavaDoc, IOException JavaDoc {
224         
225         ensureInitialization();
226         
227         // If init failed, return 500 error
228
if (this.unavailable) {
229 // ((HttpServletResponse) response).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
230
// resources.getString("StaticResourceServlet.PathNotFound", requestURI));
231
RequestDispatcher rd = this.webAppConfig.getErrorDispatcherByClass(
232                     this.unavailableException);
233             rd.forward(request, response);
234             return;
235         }
236         
237         if (this.jspFile != null)
238             request.setAttribute(JSP_FILE, this.jspFile);
239
240         ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
241         Thread.currentThread().setContextClassLoader(this.webAppConfig.getLoader());
242
243         try {
244             if (this.isSingleThreadModel) {
245                 synchronized (this) {
246                     this.instance.service(request, response);
247                 }
248             } else
249                 this.instance.service(request, response);
250         } catch (UnavailableException JavaDoc err) {
251             // catch locally and rethrow as a new ServletException, so
252
// we only invalidate the throwing servlet
253
setUnavailable(this.instance);
254             ((HttpServletResponse JavaDoc) response).sendError(HttpServletResponse.SC_NOT_FOUND,
255                     Launcher.RESOURCES.getString("StaticResourceServlet.PathNotFound", requestURI));
256 // throw new ServletException(resources.getString(
257
// "RequestDispatcher.ForwardError"), err);
258
} finally {
259             Thread.currentThread().setContextClassLoader(cl);
260         }
261     }
262     
263     public int getLoadOnStartup() {
264         return this.loadOnStartup;
265     }
266
267     public String JavaDoc getInitParameter(String JavaDoc name) {
268         return (String JavaDoc) this.initParameters.get(name);
269     }
270
271     public Enumeration JavaDoc getInitParameterNames() {
272         return Collections.enumeration(this.initParameters.keySet());
273     }
274
275     public ServletContext JavaDoc getServletContext() {
276         return this.webAppConfig;
277     }
278
279     public String JavaDoc getServletName() {
280         return this.servletName;
281     }
282
283     public Map JavaDoc getSecurityRoleRefs() {
284         return this.securityRoleRefs;
285     }
286
287     /**
288      * This was included so that the servlet instances could be sorted on their
289      * loadOnStartup values. Otherwise used.
290      */

291     public int compareTo(Object JavaDoc objTwo) {
292         Integer JavaDoc one = new Integer JavaDoc(this.loadOnStartup);
293         Integer JavaDoc two = new Integer JavaDoc(((ServletConfiguration) objTwo).loadOnStartup);
294         return one.compareTo(two);
295     }
296
297     /**
298      * Called when it's time for the container to shut this servlet down.
299      */

300     public void destroy() {
301         synchronized (this.servletSemaphore) {
302             setUnavailable(this.instance);
303         }
304     }
305
306     protected void setUnavailable(Servlet JavaDoc unavailableServlet) {
307         
308         this.unavailable = true;
309         if (unavailableServlet != null) {
310             Logger.log(Logger.DEBUG, Launcher.RESOURCES,
311                     "ServletConfiguration.destroy", this.servletName);
312             ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
313             Thread.currentThread().setContextClassLoader(this.webAppConfig.getLoader());
314             try {
315                 unavailableServlet.destroy();
316             } finally {
317                 Thread.currentThread().setContextClassLoader(cl);
318                 this.instance = null;
319             }
320         }
321         
322         // remove from webapp
323
this.webAppConfig.removeServletConfigurationAndMappings(this);
324     }
325 }
326
Popular Tags