Annotation of java/classes/org/w3c/jigsaw/servlet/ServletWrapper.java, revision 1.12
1.1 abaird 1: // ServletWrapper.java
1.12 ! bmahe 2: // $Id: ServletWrapper.java,v 1.11 1997/07/10 12:16:23 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:
6: package w3c.jigsaw.servlet;
7:
8: import java.io.* ;
9: import java.util.*;
10:
1.9 bmahe 11: import javax.servlet.*;
1.1 abaird 12:
1.5 abaird 13: import w3c.tools.store.*;
1.1 abaird 14: import w3c.util.*;
15: import w3c.www.mime.*;
16: import w3c.www.http.*;
17: import w3c.jigsaw.http.*;
18: import w3c.jigsaw.resources.*;
19:
1.2 abaird 20: /**
21: * @author Alexandre Rafalovitch <alex@access.com.au>
22: * @author Anselm Baird-Smith <abaird@w3.org>
23: */
24:
1.7 abaird 25: public class ServletWrapper extends FilteredResource implements ServletConfig
1.1 abaird 26: {
27:
1.9 bmahe 28: private LocalServletLoader loader = null;
1.1 abaird 29:
1.12 ! bmahe 30: private final static boolean debug = false;
1.9 bmahe 31:
32: public static final
33: String STATE_EXTRA_PATH = "w3c.jigsaw.servlet.extraPath";
34:
35: /**
36: * Attributes index - The servlet class name.
37: */
38: protected static int ATTR_SERVLET_CLASS = -1 ;
39: /**
40: * Attribute index - The init parameters for that servlet.
41: */
42: protected static int ATTR_PARAMETERS = 1;
43: /**
44: * Attribute index - Our parent-inherited servlet context.
45: */
46: protected static int ATTR_SERVLET_CONTEXT = -1;
47:
48: static {
49: Attribute a = null ;
50: Class cls = null ;
51: try {
52: cls = Class.forName("w3c.jigsaw.servlet.ServletWrapper") ;
53: } catch (Exception ex) {
54: ex.printStackTrace();
55: System.exit(0);
56: }
57: // The servlet class attribute.
58: a = new StringAttribute("servlet-class"
59: , null
60: , Attribute.EDITABLE | Attribute.MANDATORY) ;
61: ATTR_SERVLET_CLASS = AttributeRegistry.registerAttribute(cls, a) ;
62: // This servlet init parameters
63: a = new PropertiesAttribute("servlet-parameters"
1.1 abaird 64: , null
1.9 bmahe 65: , Attribute.EDITABLE);
66: ATTR_PARAMETERS = AttributeRegistry.registerAttribute(cls, a);
67: // Our servlet context:
68: a = new ObjectAttribute("servlet-context"
69: , "w3c.jigsaw.servlet.ServletDirectory"
70: , null
71: , Attribute.DONTSAVE);
72: ATTR_SERVLET_CONTEXT = AttributeRegistry.registerAttribute(cls, a);
73: }
1.1 abaird 74:
1.9 bmahe 75: /**
76: * The servlet wrapped within that Jigsaw resource.
77: */
78: protected Servlet servlet = null;
79: /**
80: * Is out servler initialized ?
81: */
82: protected boolean inited = false;
83:
84: /**
85: * The Path where we can find the servlet class file.
86: */
87: public File getServletDirectory() { //FIXME
88: ServletDirectory dir =
89: (ServletDirectory) getValue(ATTR_SERVLET_CONTEXT, null);
90: if (dir == null)
91: return null;
92: else return dir.getDirectory();
93: }
94:
95: /**
96: * Servlet stub implementation - Get an init parameter value.
97: */
98:
99: public synchronized String getInitParameter(String string) {
100: ArrayDictionary d = getServletParameters();
101: String v = (d != null) ? (String) d.get(string) : null;
102: return v;
103: }
104:
105: /**
106: * Servlet stub implementation - Get all init parameters.
107: */
108:
109: public synchronized Enumeration getInitParameterNames() {
110: // Convert init parameters to hashtable:
111: ArrayDictionary d = getServletParameters();
112: return (d != null) ? d.keys() : new EmptyEnumeration();
113: }
114:
115: /**
116: * Servlet stub implementation - Get that servlet context.
117: */
118:
119: public ServletContext getServletContext() {
120: return (ServletContext) getValue(ATTR_SERVLET_CONTEXT, null);
121: }
122:
123: /**
124: * Get the class name of the wrapped servlet.
125: * @return The class name for the servlet if attribute is defined,
126: * <strong>null</strong> otherwise.
127: */
128:
129: public String getServletClass()
130: {
131: String sclass = getString(ATTR_SERVLET_CLASS, null);
132: if (sclass == null) {
133: String ident = getIdentifier();
134: if (ident.endsWith(".class"))
135: sclass = ident;
136: else
137: sclass = ident+".class";
138: }
139: return sclass;
140: }
141:
142: /**
143: * Get the init parameters for our wrapped servlet.
144: * @return An ArrayDictionary instance if the attribute is defined,
145: * <strong>false</strong> otherwise.
146: */
147:
148: public ArrayDictionary getServletParameters() {
149: return (ArrayDictionary) getValue(ATTR_PARAMETERS, null);
150: }
151:
152: /**
153: * Catch assignements to the servlet class name attribute.
154: * <p>When a change to that attribute is detected, the servlet is
155: * automatically reinitialized.
156: */
157:
158: public void setValue(int idx, Object value) {
159: super.setValue(idx, value);
160: if ((idx == ATTR_SERVLET_CLASS) && (value != null))
161: inited = launchServlet();
162: }
163:
164: /**
165: * Destroy the servlet we are wrapping.
166: */
167:
168: protected synchronized void destroyServlet() {
169: if (servlet != null) {
170: servlet.destroy();
171: servlet = null;
172: }
173: }
174:
175: /**
176: * Get the servlet we are wrapping.
177: * @return A servlet instance, if the servlet is alredy running,
178: * <strong>null</strong> otherwise.
179: */
180:
181: public Servlet getServlet() {
182: return servlet;
183: }
184:
185: /**
186: * Initialize our servlet from the given (loaded) class.
187: * @param cls The servlet loaded main class.
188: * @return A boolean, <strong>true</strong> if servlet was successfully
189: * initialised, <strong>false</strong> otherwise.
190: */
191:
192: protected boolean launchServlet(Class cls) {
193: try {
194: servlet = (Servlet) cls.newInstance();
195: servlet.init((ServletConfig) this);
196: } catch (Exception ex) {
197: String msg = ("unable to initialize servlet, exception: "+
198: ex.getMessage());
199: if ( debug )
200: ex.printStackTrace();
201: getServer().errlog(this, msg);
202: return false;
203: }
204: return (servlet != null) ;
205: }
206:
207: /**
208: * Launch the servlet we are wrapping.
209: * <p>This method either succeed, or the wrapper resource itself will fail
210: * to initialize, acting as transparently as possible (in some sense).
211: * @return A boolean, <strong>true</strong> if servlet launched.
212: */
213:
214: protected boolean launchServlet() {
215: // Get and check the servlet class:
216: if ( servlet != null )
217: destroyServlet();
218: String clsname = getServletClass();
219: if ( clsname == null ) {
220: getServer().errlog(this, "no servlet class attribute defined.");
221: return false;
222: } else {
223: Class c = null;
224: try {
225: if (loader.classChanged(clsname))
226: loader = new LocalServletLoader(this.loader);
227: c = loader.loadClass(clsname, true);
228: } catch (ClassNotFoundException ex) {
1.1 abaird 229: if ( debug )
1.9 bmahe 230: ex.printStackTrace();
231: String msg = ("unable to load servlet class\""+
232: getServletClass()+
233: "at : "+
234: ex.getMessage());
235: getServer().errlog(msg);
236: }
237: return (c != null) ? launchServlet(c) : false;
238: }
239: }
240:
241: /**
242: * Dispatch the give request to our servlet.
243: * <p>If the servlet cannot be inititalized, we just throw an error message
244: * otherwise, we just delegate that request processing to the underlying
245: * servlet instance.
246: * @param request The request to be processed.
247: * @exception HTTPException If the wrapped servlet is not initialized.
248: */
249:
250: public Reply perform(Request request)
251: throws HTTPException
252: {
253: if (loader.classChanged(getServletClass())) {
254: inited = launchServlet();
255: }
256:
257: // Check that the servlet has been initialized properly:
258: if ( ! inited ) {
259: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
260: reply.setContent("Servlet not configured properly");
261: throw new HTTPException(reply);
262: }
263: // Dispatch the request:
264: Reply reply = createDefaultReply(request, HTTP.OK);
265: reply.setContentType(MimeType.TEXT_HTML);
266: try {
1.11 bmahe 267: servlet.service(new JigsawHttpServletRequest(servlet, request),
268: new JigsawHttpServletResponse(request, reply));
1.9 bmahe 269: } catch (Exception ex) {
270: if ( debug )
271: ex.printStackTrace();
272: reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
273: reply.setContent("Servlet has thrown exception:" + ex.toString());
1.1 abaird 274: }
1.9 bmahe 275: return reply;
276: }
1.1 abaird 277:
1.9 bmahe 278: /**
279: * Jigsaw's lookup on servlets.
280: * Once here, we have reached a leaf servlet (or at least the remaining
281: * lookup is to be done at the servlet itself). We keep track of the
282: * <em>path info</em> and mark that servlet as the target of request.
283: * @param ls The lookup state.
284: * @param lr The lookup result.
285: * @exception HTTPException If some error occurs.
286: */
287:
288: public boolean lookup(LookupState ls, LookupResult lr)
289: throws HTTPException
290: {
291: // Get the extra path information:
292: String extraPath = ls.getRemainingPath(true);
293: if ((extraPath == null) || extraPath.equals(""))
294: extraPath = "/";
295: // Keep this path info into the request, if possible:
296: Request request = ls.getRequest();
297: if ( request != null )
298: request.setState(STATE_EXTRA_PATH, extraPath);
299: lr.setTarget(this);
300: return super.lookup(ls, lr);
301: }
302:
303: public void notifyUnload() {
304: destroyServlet();
305: }
306:
307: /**
308: * Initialize this servlet wrapper resource.
309: * After the wrapper itself is inited, it performs the servlet
310: * initialzation.
311: * @param values The default attribute values.
312: */
313:
314: public void initialize(Object values[]) {
315: super.initialize(values);
316: loader = new LocalServletLoader(this);
317: // Initialize the wrapped servlet (is now the rigt time ?)
318: if ( getServletClass() != null )
319: inited = launchServlet();
320: }
1.1 abaird 321:
322: }
323:
324:
325:
326:
327:
328:
329:
330:
Webmaster