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

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

Webmaster