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