Annotation of java/classes/org/w3c/jigsaw/servlet/ServletWrapperFrame.java, revision 1.22
1.1 bmahe 1: // ServletWrapperFrame.java
1.22 ! ylafon 2: // $Id: ServletWrapperFrame.java,v 1.21 2001/01/16 10:23:12 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;
1.22 ! ylafon 98: PipedInputStream pis = null;
1.5 ylafon 99:
100: if (wrapper == null) {
101: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
102: reply.setContent("Servlet Wrapper Frame not configured properly: "+
103: "must be attached to a ServletWrapper.");
104: throw new HTTPException(reply);
105: }
106:
1.10 bmahe 107: try {
108: wrapper.checkServlet();
109: } catch (ClassNotFoundException ex) {
110: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
111: reply.setContent("The server was unable to find the "+
112: "servlet class : "+ex.getMessage());
113: if ( wrapper.debug )
114: ex.printStackTrace();
115: throw new HTTPException(reply);
116: } catch (ServletException ex) {
117: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
118: reply.setContent("The server was unable to initialize the "+
119: "servlet : "+ex.getMessage());
120: if ( wrapper.debug )
121: ex.printStackTrace();
122: throw new HTTPException(reply);
123: }
1.5 ylafon 124:
1.8 bmahe 125: // Check that the servlet has been initialized properly:
1.5 ylafon 126: if ( ! wrapper.isInited() ) {
127: Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
128: reply.setContent("Servlet not configured properly");
129: throw new HTTPException(reply);
130: }
131: // Dispatch the request:
132: Reply reply = createDefaultReply(request, HTTP.OK);
133: reply.setContentType(MimeType.TEXT_HTML);
134: try {
1.17 ylafon 135: if (request.hasState(JigsawHttpServletResponse.INCLUDED)) {
1.16 ylafon 136: wrapper.service(request, reply);
1.17 ylafon 137: } else {
1.22 ! ylafon 138: pis = new PipedInputStream();
! 139: request.setState(JigsawHttpServletResponse.STREAM, pis);
1.17 ylafon 140: PipedOutputStream pos = new PipedOutputStream(pis);
141: reply.setState(JigsawHttpServletResponse.STREAM, pos);
142: reply.setStream(pis);
143: Object o = new Object();
144: reply.setState(JigsawHttpServletResponse.MONITOR, o);
145: // wait until the reply is constructed by the processing thread
1.18 ylafon 146: ServerInterface server = getServer();
147: if (server instanceof httpd) {
148: synchronized (o) {
149: wrapper.service(request, reply);
150: o.wait((long)((httpd)server).getRequestTimeOut());
151: }
152: Object strm;
153: strm = reply.getState(JigsawHttpServletResponse.STREAM);
154: if (strm != null) {
155: // it is a timeout
156: try {
1.19 ylafon 157: pis.close();
1.18 ylafon 158: pos.close();
159: } catch (IOException ex) {};
1.21 ylafon 160: if (strm instanceof PipedOutputStream) {
161: Thread r;
162: r = (Thread) reply.getState(ServletWrapper.RUNNER);
163: if (r != null) {
164: r.interrupt();
165: }
166: throw new ServletException("Timed out");
1.20 ylafon 167: }
1.19 ylafon 168: }
1.18 ylafon 169: } else {
170: synchronized (o) {
171: wrapper.service(request, reply);
172: o.wait();
173: }
1.17 ylafon 174: }
1.16 ylafon 175: }
1.6 bmahe 176: } catch (UnavailableException uex) {
1.13 ylafon 177: reply = request.makeReply(HTTP.SERVICE_UNAVAILABLE);
1.6 bmahe 178: if (uex.isPermanent()) {
179: reply.setContent("<h2>The servlet is permanently "+
180: "unavailable :</h2>"+
181: "Details: <b>"+uex.getMessage()+"</b>");
182: } else {
183: int delay = uex.getUnavailableSeconds();
1.13 ylafon 184: if (delay > 0) {
185: reply.setRetryAfter(delay);
1.6 bmahe 186: reply.setContent("<h2>The servlet is temporarily "+
187: "unavailable :</h2>"+
1.7 bmahe 188: "Delay : "+delay+
1.6 bmahe 189: " seconds<br><br>Details: <b>"+
190: uex.getMessage()+"</b>");
1.13 ylafon 191: } else {
1.6 bmahe 192: reply.setContent("<h2>The servlet is temporarily "+
193: "unavailable :</h2>"+
194: "Details: <b>"+uex.getMessage()+"</b>");
1.13 ylafon 195: }
1.6 bmahe 196: }
1.22 ! ylafon 197: if (pis != null) {
! 198: try {
! 199: pis.close();
! 200: } catch (IOException ioex) {}
! 201: }
1.5 ylafon 202: } catch (Exception ex) {
203: if ( wrapper.debug )
204: ex.printStackTrace();
205: reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
206: reply.setContent("Servlet has thrown exception:" + ex.toString());
1.22 ! ylafon 207: if (pis != null) {
! 208: try {
! 209: pis.close();
! 210: } catch (IOException ioex) {}
! 211: }
1.5 ylafon 212: }
213: return reply;
1.1 bmahe 214: }
1.15 ylafon 215:
1.5 ylafon 216: /**
217: * Jigsaw's lookup on servlets.
218: * Once here, we have reached a leaf servlet (or at least the remaining
219: * lookup is to be done at the servlet itself). We keep track of the
220: * <em>path info</em> and mark that servlet as the target of request.
221: * @param ls The lookup state.
222: * @param lr The lookup result.
223: * @exception ProtocolException If some error occurs.
224: */
225:
226: protected boolean lookupOther(LookupState ls, LookupResult lr)
227: throws ProtocolException
228: {
229: // Get the extra path information:
230: String extraPath = ls.getRemainingPath(true);
231: if ((extraPath == null) || extraPath.equals(""))
232: extraPath = "/";
233: // Keep this path info into the request, if possible:
234: Request request = (Request) ls.getRequest();
1.12 bmahe 235: if ( request != null ) {
1.14 bmahe 236: if (request.getState(JigsawRequestDispatcher.PATH_INFO_P) == null)
237: request.setState(JigsawRequestDispatcher.PATH_INFO_P,
238: extraPath);
1.12 bmahe 239: }
1.5 ylafon 240: lr.setTarget(resource.getResourceReference());
241: return super.lookupOther(ls, lr);
242: }
1.1 bmahe 243:
244: }
Webmaster