Annotation of java/classes/org/w3c/jigsaw/servlet/ServletWrapper.java, revision 1.29
1.1 abaird 1: // ServletWrapper.java
1.29 ! bmahe 2: // $Id: ServletWrapper.java,v 1.28 1998/06/04 16:20:54 bmahe Exp $
1.1 abaird 3: // (c) COPYRIGHT MIT and INRIA, 1996.
4: // Please first read the full copyright statement in file COPYRIGHT.html
5:
1.18 bmahe 6: package org.w3c.jigsaw.servlet;
1.1 abaird 7:
8: import java.io.* ;
9: import java.util.*;
10:
1.9 bmahe 11: import javax.servlet.*;
1.1 abaird 12:
1.18 bmahe 13: import org.w3c.tools.resources.store.*;
14: import org.w3c.util.*;
15: import org.w3c.www.mime.*;
16: import org.w3c.www.http.*;
17: import org.w3c.jigsaw.http.*;
18: import org.w3c.tools.resources.*;
1.1 abaird 19:
1.2 abaird 20: /**
21: * @author Alexandre Rafalovitch <alex@access.com.au>
22: * @author Anselm Baird-Smith <abaird@w3.org>
1.18 bmahe 23: * @author Benoit Mahe <bmahe@w3.org>
1.2 abaird 24: */
25:
1.18 bmahe 26: public class ServletWrapper extends FramedResource implements ServletConfig
1.1 abaird 27: {
28:
1.22 bmahe 29: protected LocalServletLoader loader = null;
1.1 abaird 30:
1.20 bmahe 31: protected final static boolean debug = false;
1.9 bmahe 32:
1.20 bmahe 33: /**
34: * Attributes index - The servlet class name.
35: */
36: protected static int ATTR_SERVLET_CLASS = -1 ;
37: /**
38: * Attribute index - The init parameters for that servlet.
39: */
40: protected static int ATTR_PARAMETERS = 1;
41: /**
42: * Attribute index - Our parent-inherited servlet context.
43: */
44: protected static int ATTR_SERVLET_CONTEXT = -1;
45: /**
1.28 bmahe 46: * Attribute index - Our parent-inherited session context.
47: */
48: protected static int ATTR_SESSION_CONTEXT = -1;
49: /**
1.20 bmahe 50: * Attribute index - use auto-reload?
51: */
52: protected static int ATTR_AUTO_RELOAD = -1;
53:
54: static {
55: Attribute a = null ;
56: Class cls = null ;
57: try {
58: cls = Class.forName("org.w3c.jigsaw.servlet.ServletWrapper") ;
59: } catch (Exception ex) {
60: ex.printStackTrace();
61: System.exit(0);
62: }
63: // The servlet class attribute.
64: a = new StringAttribute("servlet-class"
1.1 abaird 65: , null
1.20 bmahe 66: , Attribute.EDITABLE | Attribute.MANDATORY) ;
67: ATTR_SERVLET_CLASS = AttributeRegistry.registerAttribute(cls, a) ;
68: // This servlet init parameters
69: a = new PropertiesAttribute("servlet-parameters"
70: , null
71: , Attribute.EDITABLE);
72: ATTR_PARAMETERS = AttributeRegistry.registerAttribute(cls, a);
73: // Our servlet context:
74: a = new ObjectAttribute("servlet-context",
1.24 bmahe 75: "org.w3c.jigsaw.servlet.JigsawServletContext",
1.20 bmahe 76: null,
77: Attribute.DONTSAVE);
78: ATTR_SERVLET_CONTEXT = AttributeRegistry.registerAttribute(cls, a);
1.28 bmahe 79: // Our session context:
80: a = new ObjectAttribute("session-context",
81: "org.w3c.jigsaw.servlet.JigsawHttpSessionContext",
82: null,
83: Attribute.DONTSAVE);
84: ATTR_SESSION_CONTEXT = AttributeRegistry.registerAttribute(cls, a);
1.20 bmahe 85: // Use auto-reload?
86: a = new BooleanAttribute("auto-reload",
87: Boolean.TRUE,
88: Attribute.EDITABLE);
89: ATTR_AUTO_RELOAD = AttributeRegistry.registerAttribute(cls, a);
90: }
1.1 abaird 91:
1.20 bmahe 92: /**
93: * Should we use LocalClassLoader? (auto-reload)
94: */
95: protected boolean getAutoReloadFlag() {
96: return getBoolean(ATTR_AUTO_RELOAD, true);
97: }
98:
99: /**
100: * The servlet wrapped within that Jigsaw resource.
101: */
102: protected Servlet servlet = null;
103: /**
104: * Is out servler initialized ?
105: */
106: protected boolean inited = false;
107:
108: /**
109: * The Path where we can find the servlet class file.
110: */
111: public File getServletDirectory() {
1.25 bmahe 112: ResourceReference rr = getParent();
113: if (rr != null) {
114: try {
115: Resource parent = rr.lock();
116: if (parent.definesAttribute("directory"))
117: return (File) parent.getValue("directory", null);
118: } catch(InvalidResourceException ex) {
119: ex.printStackTrace();
120: } finally {
121: rr.unlock();
122: }
123: }
124: return null;
1.20 bmahe 125: }
126:
127: /**
128: * Servlet stub implementation - Get an init parameter value.
129: */
130:
131: public synchronized String getInitParameter(String string) {
132: ArrayDictionary d = getServletParameters();
133: String v = (d != null) ? (String) d.get(string) : null;
134: return v;
135: }
136:
137: /**
138: * Servlet stub implementation - Get all init parameters.
139: */
140:
141: public synchronized Enumeration getInitParameterNames() {
142: // Convert init parameters to hashtable:
143: ArrayDictionary d = getServletParameters();
144: return (d != null) ? d.keys() : new EmptyEnumeration();
145: }
146:
147: /**
148: * Servlet stub implementation - Get that servlet context.
149: */
150:
151: public ServletContext getServletContext() {
152: return (ServletContext) getValue(ATTR_SERVLET_CONTEXT, null);
153: }
154:
1.28 bmahe 155: public JigsawHttpSessionContext getSessionContext() {
156: return (JigsawHttpSessionContext) getValue(ATTR_SESSION_CONTEXT, null);
157: }
158:
1.20 bmahe 159: protected void checkServletClass() {
160: if (getAutoReloadFlag()) {
1.26 bmahe 161: if (getLocalServletLoader().classChanged(getServletClass())) {
1.20 bmahe 162: inited = launchServlet();
163: }
164: } else {
165: if (! inited)
166: inited = launchServlet();
167: }
168: }
169:
170: protected boolean isInited() {
171: return inited;
172: }
173:
174: protected void service(Request request, Reply reply)
175: throws ServletException, IOException
176: {
1.23 bmahe 177: JigsawHttpServletResponse jRes = null;
178: JigsawHttpServletRequest jReq = null;
179: if (servlet instanceof SingleThreadModel) {
180: synchronized (this) {
181: jRes = new JigsawHttpServletResponse(request, reply);
1.28 bmahe 182: jReq = new JigsawHttpServletRequest(servlet,
183: request,
184: jRes,
185: getSessionContext());
186: jRes.setServletRequest(jReq);
1.23 bmahe 187: servlet.service(jReq , jRes);
1.29 ! bmahe 188: jRes.closeStream();
1.23 bmahe 189: }
190: } else {
191: jRes = new JigsawHttpServletResponse(request, reply);
1.28 bmahe 192: jReq = new JigsawHttpServletRequest(servlet,
193: request,
194: jRes,
195: getSessionContext());
196: jRes.setServletRequest(jReq);
1.23 bmahe 197: servlet.service(jReq , jRes);
1.29 ! bmahe 198: jRes.closeStream();
1.23 bmahe 199: }
1.20 bmahe 200: }
201:
202: /**
203: * Get the class name of the wrapped servlet.
204: * @return The class name for the servlet if attribute is defined.
205: * Otherwise the class name is deduced from the resource identifier.
206: */
207:
208: public String getServletClass()
209: {
210: String sclass = getString(ATTR_SERVLET_CLASS, null);
211: if (sclass == null) {
212: String ident = getIdentifier();
213: if (ident.endsWith(".class"))
214: sclass = ident;
215: }
216: return sclass;
217: }
218:
219: /**
220: * Get the init parameters for our wrapped servlet.
221: * @return An ArrayDictionary instance if the attribute is defined,
222: * <strong>false</strong> otherwise.
223: */
224:
225: public ArrayDictionary getServletParameters() {
226: return (ArrayDictionary) getValue(ATTR_PARAMETERS, null);
227: }
228:
1.26 bmahe 229: protected void setValueOfSuperClass(int idx, Object value) {
230: super.setValue(idx, value);
231: }
232:
1.20 bmahe 233: /**
234: * Catch assignements to the servlet class name attribute.
235: * <p>When a change to that attribute is detected, the servlet is
236: * automatically reinitialized.
237: */
238:
239: public void setValue(int idx, Object value) {
240: super.setValue(idx, value);
241: if ((idx == ATTR_SERVLET_CLASS) && (value != null))
242: inited = launchServlet();
243: if (idx == ATTR_AUTO_RELOAD) {
244: if (getAutoReloadFlag())
1.26 bmahe 245: loader = getNewLocalServletLoader(false);
1.20 bmahe 246: else
247: loader = null;
248: inited = launchServlet();
249: }
250: }
251:
252: /**
253: * Destroy the servlet we are wrapping.
254: */
255:
256: protected synchronized void destroyServlet() {
257: if (servlet != null) {
258: servlet.destroy();
259: servlet = null;
260: }
261: }
262:
263: /**
264: * Get the servlet we are wrapping.
265: * @return A servlet instance, if the servlet is alredy running,
266: * <strong>null</strong> otherwise.
267: */
268:
269: public Servlet getServlet() {
270: return servlet;
271: }
272:
273: /**
274: * Initialize our servlet from the given (loaded) class.
275: * @param cls The servlet loaded main class.
276: * @return A boolean, <strong>true</strong> if servlet was successfully
277: * initialised, <strong>false</strong> otherwise.
278: */
279:
280: protected boolean launchServlet(Class cls) {
281: try {
282: servlet = (Servlet) cls.newInstance();
283: servlet.init((ServletConfig) this);
284: } catch (Exception ex) {
285: String msg = ("unable to initialize servlet, exception: "+
286: ex.getMessage());
287: if ( debug )
288: ex.printStackTrace();
289: getServer().errlog(this, msg);
290: return false;
291: }
292: return (servlet != null) ;
293: }
294:
295: /**
296: * Launch the servlet we are wrapping.
297: * <p>This method either succeed, or the wrapper resource itself will fail
298: * to initialize, acting as transparently as possible (in some sense).
299: * @return A boolean, <strong>true</strong> if servlet launched.
300: */
301:
302: protected boolean launchServlet() {
303: // Get and check the servlet class:
304: if ( servlet != null )
305: destroyServlet();
306: String clsname = getServletClass();
307: if ( clsname == null ) {
308: getServer().errlog(this, "no servlet class attribute defined.");
309: return false;
310: } else {
311: Class c = null;
312: try {
313: if (getAutoReloadFlag()) {
1.26 bmahe 314: if (getLocalServletLoader().classChanged(clsname))
315: loader = getNewLocalServletLoader(true);
316: c = getLocalServletLoader().loadServletClass(clsname,
317: true);
1.20 bmahe 318: } else {
319: c = Class.forName(clsname);
320: }
321: } catch (ClassNotFoundException ex) {
322: if ( debug )
323: ex.printStackTrace();
324: String msg = ("unable to load servlet class \""+
325: getServletClass()+
326: "\" : "+
327: ex.getMessage());
328: getServer().errlog(msg);
329: }
330: return (c != null) ? launchServlet(c) : false;
331: }
332: }
333:
334: public void notifyUnload() {
335: destroyServlet();
1.26 bmahe 336: }
337:
338: /**
339: * Get or create a suitable LocalServletLoader instance to load
340: * that servlet.
341: * @return A LocalServletLoader instance.
342: */
343:
344: protected synchronized LocalServletLoader getLocalServletLoader() {
345: if ( loader == null ) {
346: loader = new LocalServletLoader(this);
347: }
348: return loader;
349: }
350:
351: protected synchronized
352: LocalServletLoader getNewLocalServletLoader(boolean keepold)
353: {
354: if ((loader != null) && keepold)
355: loader = new LocalServletLoader(loader);
356: else
357: loader = new LocalServletLoader(this);
358: return loader;
1.20 bmahe 359: }
360:
361: /**
362: * Initialize this servlet wrapper resource.
363: * After the wrapper itself is inited, it performs the servlet
364: * initialzation.
365: * @param values The default attribute values.
366: */
367:
368: public void initialize(Object values[]) {
369: super.initialize(values);
370: loader = new LocalServletLoader(this);
371: // Initialize the wrapped servlet (is now the rigt time ?)
372: if ( getServletClass() != null )
373: inited = launchServlet();
374: try {
375: registerFrameIfNone("org.w3c.jigsaw.servlet.ServletWrapperFrame",
376: "servlet-wrapper-frame");
377: } catch (Exception ex) {
378: ex.printStackTrace();
379: }
1.18 bmahe 380: }
1.1 abaird 381:
382: }
383:
384:
385:
386:
387:
388:
389:
390:
Webmaster