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