Annotation of java/classes/org/w3c/jigsaw/servlet/ServletWrapperFrame.java, revision 1.20
1.1 bmahe 1: // ServletWrapperFrame.java
1.20 ! ylafon 2: // $Id: ServletWrapperFrame.java,v 1.19 2000/12/28 23:32:26 ylafon Exp $
1.1 bmahe 3: // (c) COPYRIGHT MIT and INRIA, 1996.
4: // Please first read the full copyright statement in file COPYRIGHT.html
5:
6: package org.w3c.jigsaw.servlet;
7:
1.15 ylafon 8: import javax.servlet.ServletException;
9: import javax.servlet.UnavailableException;
1.1 bmahe 10:
1.18 ylafon 11: import java.io.IOException;
1.16 ylafon 12: import java.io.PipedInputStream;
13: import java.io.PipedOutputStream;
14:
1.15 ylafon 15: import org.w3c.www.mime.MimeType;
1.1 bmahe 16:
1.15 ylafon 17: import org.w3c.www.http.HTTP;
18: import org.w3c.www.http.HttpEntityMessage;
19: import org.w3c.www.http.HttpMessage;
20: import org.w3c.www.http.HttpReplyMessage;
21:
1.18 ylafon 22: import org.w3c.jigsaw.http.httpd;
1.15 ylafon 23: import org.w3c.jigsaw.http.HTTPException;
24: import org.w3c.jigsaw.http.Reply;
25: import org.w3c.jigsaw.http.Request;
26:
27: import org.w3c.jigsaw.frames.HTTPFrame;
28:
29: import org.w3c.tools.resources.FramedResource;
30: import org.w3c.tools.resources.LookupResult;
31: import org.w3c.tools.resources.LookupState;
32: import org.w3c.tools.resources.ProtocolException;
33: import org.w3c.tools.resources.ReplyInterface;
34: import org.w3c.tools.resources.RequestInterface;
35: import org.w3c.tools.resources.Resource;
36: import org.w3c.tools.resources.ResourceException;
37: import org.w3c.tools.resources.ResourceFrame;
1.18 ylafon 38: import org.w3c.tools.resources.ServerInterface;
1.1 bmahe 39:
1.2 bmahe 40: import org.w3c.tools.resources.ProtocolException;
1.11 bmahe 41: import org.w3c.tools.resources.ResourceException;
1.2 bmahe 42:
1.1 bmahe 43: /**
44: * @author Alexandre Rafalovitch <alex@access.com.au>
45: * @author Anselm Baird-Smith <abaird@w3.org>
46: * @author Benoit Mahe <bmahe@w3.org>
47: */
48:
49: public class ServletWrapperFrame extends HTTPFrame {
50:
1.5 ylafon 51: protected ServletWrapper wrapper = null;
1.1 bmahe 52:
1.9 bmahe 53: /**
54: * Register our resource. Must be an instance of ServletWrapper.
55: */
1.5 ylafon 56: public void registerResource(FramedResource resource) {
57: super.registerOtherResource(resource);
58: if (resource instanceof ServletWrapper)
59: wrapper = (ServletWrapper) resource;
1.1 bmahe 60: }
61:
1.5 ylafon 62: /**
63: * Create a reply to answer to request on this file.
64: * This method will create a suitable reply (matching the given request)
65: * and will set all its default header values to the appropriate
66: * values. The reply will not have LastModified field setted.
67: * @param request The request to make a reply for.
68: * @return An instance of Reply, suited to answer this request.
69: */
70:
71: public Reply createDefaultReply(Request request, int status) {
72: Reply reply = super.createDefaultReply(request, status);
73: reply.setLastModified( -1 );
74: return reply;
75: }
1.1 bmahe 76:
1.5 ylafon 77: /**
78: * Dispatch the give request to our servlet.
79: * <p>If the servlet cannot be inititalized, we just throw an error message
80: * otherwise, we just delegate that request processing to the underlying
81: * servlet instance.
82: * @param request The request to be processed.
83: * @exception ProtocolException If the wrapped servlet is not initialized.
1.11 bmahe 84: * @exception ResourceException If the resource got a fatal error.
1.5 ylafon 85: */
86:
87: public ReplyInterface perform(RequestInterface req)
1.11 bmahe 88: throws ProtocolException, ResourceException
1.5 ylafon 89: {
90: ReplyInterface repi = performFrames(req);
91: if (repi != null)
92: return repi;
93:
94: if (! checkRequest(req))
95: return null;
96:
97: Request request = (Request) req;
98:
99: if (wrapper == null) {
100: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
101: reply.setContent("Servlet Wrapper Frame not configured properly: "+
102: "must be attached to a ServletWrapper.");
103: throw new HTTPException(reply);
104: }
105:
1.10 bmahe 106: try {
107: wrapper.checkServlet();
108: } catch (ClassNotFoundException ex) {
109: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
110: reply.setContent("The server was unable to find the "+
111: "servlet class : "+ex.getMessage());
112: if ( wrapper.debug )
113: ex.printStackTrace();
114: throw new HTTPException(reply);
115: } catch (ServletException ex) {
116: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
117: reply.setContent("The server was unable to initialize the "+
118: "servlet : "+ex.getMessage());
119: if ( wrapper.debug )
120: ex.printStackTrace();
121: throw new HTTPException(reply);
122: }
1.5 ylafon 123:
1.8 bmahe 124: // Check that the servlet has been initialized properly:
1.5 ylafon 125: if ( ! wrapper.isInited() ) {
126: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
127: reply.setContent("Servlet not configured properly");
128: throw new HTTPException(reply);
129: }
130: // Dispatch the request:
131: Reply reply = createDefaultReply(request, HTTP.OK);
132: reply.setContentType(MimeType.TEXT_HTML);
133: try {
1.17 ylafon 134: if (request.hasState(JigsawHttpServletResponse.INCLUDED)) {
1.16 ylafon 135: wrapper.service(request, reply);
1.17 ylafon 136: } else {
137: PipedInputStream pis = new PipedInputStream();
138: PipedOutputStream pos = new PipedOutputStream(pis);
139: reply.setState(JigsawHttpServletResponse.STREAM, pos);
140: reply.setStream(pis);
141: Object o = new Object();
142: reply.setState(JigsawHttpServletResponse.MONITOR, o);
143: // wait until the reply is constructed by the processing thread
1.18 ylafon 144: ServerInterface server = getServer();
145: if (server instanceof httpd) {
146: synchronized (o) {
147: wrapper.service(request, reply);
148: o.wait((long)((httpd)server).getRequestTimeOut());
149: }
150: Object strm;
151: strm = reply.getState(JigsawHttpServletResponse.STREAM);
152: if (strm != null) {
153: // it is a timeout
154: try {
1.19 ylafon 155: pis.close();
1.18 ylafon 156: pos.close();
157: } catch (IOException ex) {};
1.20 ! ylafon 158: Thread runner;
! 159: runner = (Thread)reply.getState(ServletWrapper.RUNNER);
! 160: if (runner != null) {
! 161: runner.interrupt();
! 162: }
! 163: throw new ServletException("Timed out");
1.19 ylafon 164: }
1.18 ylafon 165: } else {
166: synchronized (o) {
167: wrapper.service(request, reply);
168: o.wait();
169: }
1.17 ylafon 170: }
1.16 ylafon 171: }
1.6 bmahe 172: } catch (UnavailableException uex) {
1.13 ylafon 173: reply = request.makeReply(HTTP.SERVICE_UNAVAILABLE);
1.6 bmahe 174: if (uex.isPermanent()) {
175: reply.setContent("<h2>The servlet is permanently "+
176: "unavailable :</h2>"+
177: "Details: <b>"+uex.getMessage()+"</b>");
178: } else {
179: int delay = uex.getUnavailableSeconds();
1.13 ylafon 180: if (delay > 0) {
181: reply.setRetryAfter(delay);
1.6 bmahe 182: reply.setContent("<h2>The servlet is temporarily "+
183: "unavailable :</h2>"+
1.7 bmahe 184: "Delay : "+delay+
1.6 bmahe 185: " seconds<br><br>Details: <b>"+
186: uex.getMessage()+"</b>");
1.13 ylafon 187: } else {
1.6 bmahe 188: reply.setContent("<h2>The servlet is temporarily "+
189: "unavailable :</h2>"+
190: "Details: <b>"+uex.getMessage()+"</b>");
1.13 ylafon 191: }
1.6 bmahe 192: }
1.5 ylafon 193: } catch (Exception ex) {
194: if ( wrapper.debug )
195: ex.printStackTrace();
196: reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
197: reply.setContent("Servlet has thrown exception:" + ex.toString());
198: }
199: return reply;
1.1 bmahe 200: }
1.15 ylafon 201:
1.5 ylafon 202: /**
203: * Jigsaw's lookup on servlets.
204: * Once here, we have reached a leaf servlet (or at least the remaining
205: * lookup is to be done at the servlet itself). We keep track of the
206: * <em>path info</em> and mark that servlet as the target of request.
207: * @param ls The lookup state.
208: * @param lr The lookup result.
209: * @exception ProtocolException If some error occurs.
210: */
211:
212: protected boolean lookupOther(LookupState ls, LookupResult lr)
213: throws ProtocolException
214: {
215: // Get the extra path information:
216: String extraPath = ls.getRemainingPath(true);
217: if ((extraPath == null) || extraPath.equals(""))
218: extraPath = "/";
219: // Keep this path info into the request, if possible:
220: Request request = (Request) ls.getRequest();
1.12 bmahe 221: if ( request != null ) {
1.14 bmahe 222: if (request.getState(JigsawRequestDispatcher.PATH_INFO_P) == null)
223: request.setState(JigsawRequestDispatcher.PATH_INFO_P,
224: extraPath);
1.12 bmahe 225: }
1.5 ylafon 226: lr.setTarget(resource.getResourceReference());
227: return super.lookupOther(ls, lr);
228: }
1.1 bmahe 229:
230: }
Webmaster