Annotation of java/classes/org/w3c/jigsaw/servlet/ServletWrapper.java, revision 1.7

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

Webmaster