Annotation of java/classes/org/w3c/jigsaw/servlet/JigsawServletContext.java, revision 1.35

1.1       bmahe       1: // JigsawServletContext.java
1.35    ! ylafon      2: // $Id: JigsawServletContext.java,v 1.34 2007/02/11 10:50:01 ylafon Exp $
1.1       bmahe       3: // (c) COPYRIGHT MIT and INRIA, 1998.
                      4: // Please first read the full copyright statement in file COPYRIGHT.html
                      5: 
                      6: package org.w3c.jigsaw.servlet;
                      7: 
1.30      ylafon      8: import java.io.ByteArrayOutputStream;
                      9: import java.io.File;
                     10: import java.io.IOException;
                     11: import java.io.InputStream;
                     12: import java.io.PrintStream;
                     13: import java.io.PrintWriter;
                     14: import java.io.RandomAccessFile;
                     15: 
                     16: import java.net.MalformedURLException;
                     17: import java.net.URL;
                     18: import java.net.URLConnection;
                     19: 
                     20: import java.util.Date;
                     21: import java.util.Enumeration;
                     22: import java.util.Hashtable;
1.33      ylafon     23: import java.util.Set;
1.30      ylafon     24: 
                     25: import javax.servlet.RequestDispatcher;
                     26: import javax.servlet.Servlet;
                     27: import javax.servlet.ServletContext;
                     28: 
                     29: import org.w3c.util.EmptyEnumeration;
                     30: import org.w3c.util.ObservableProperties;
                     31: import org.w3c.util.PropertyMonitoring;
                     32: 
                     33: import org.w3c.tools.resources.event.StructureChangedAdapter;
                     34: import org.w3c.tools.resources.event.StructureChangedEvent;
                     35: 
                     36: import org.w3c.tools.resources.AttributeHolder;
                     37: import org.w3c.tools.resources.DirectoryResource;
                     38: import org.w3c.tools.resources.FileResource;
                     39: import org.w3c.tools.resources.FramedResource;
                     40: import org.w3c.tools.resources.InvalidResourceException;
                     41: import org.w3c.tools.resources.LookupResult;
                     42: import org.w3c.tools.resources.LookupState;
                     43: import org.w3c.tools.resources.ProtocolException;
                     44: import org.w3c.tools.resources.Resource;
                     45: import org.w3c.tools.resources.ResourceFrame;
                     46: import org.w3c.tools.resources.ResourceReference;
                     47: import org.w3c.tools.resources.ServerInterface;
                     48: 
                     49: import org.w3c.jigsaw.frames.HTTPFrame;
                     50: 
1.26      bmahe      51: import org.w3c.jigsaw.proxy.ForwardFrame;
1.22      bmahe      52: import org.w3c.jigsaw.resources.VirtualHostResource;
1.20      bmahe      53: import org.w3c.jigsaw.http.httpd;
1.1       bmahe      54: 
                     55: /**
1.35    ! ylafon     56:  * @version $Revision: 1.34 $
1.1       bmahe      57:  * @author  Benoît Mahé (bmahe@w3.org)
                     58:  */
1.5       bmahe      59: public class JigsawServletContext extends StructureChangedAdapter
                     60:                                   implements ServletContext,  
1.11      bmahe      61:                                             PropertyMonitoring
1.5       bmahe      62: {
                     63: 
1.25      bmahe      64:     public static final String TEMPDIR_P = "javax.servlet.context.tempdir";
                     65: 
1.5       bmahe      66:     class Logger {
                     67:        File             logfile  = null;
                     68:        RandomAccessFile log      = null ;
                     69:        byte             msgbuf[] = null ;
                     70:        boolean          closed   = true;      
                     71: 
                     72:        private final String monthnames[] = {
                     73:            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1.18      bmahe      74:            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1.5       bmahe      75:        };
                     76: 
                     77:        String getDate() {
                     78:            Date now = new Date();
                     79:            return (now.getDate()
                     80:                    + "/" + monthnames[now.getMonth()]
                     81:                    + "/" + (now.getYear() + 1900)
                     82:                    + ((now.getHours() < 10)
                     83:                       ? (":0" + now.getHours())
                     84:                       : (":" + now.getHours()))
                     85:                    + ((now.getMinutes() < 10)
                     86:                       ? (":0" + now.getMinutes())
                     87:                       : (":" + now.getMinutes()))
                     88:                    + ((now.getSeconds() < 10)
                     89:                       ? (":0" + now.getSeconds())
                     90:                       : (":" + now.getSeconds()))
                     91:                    + ((now.getTimezoneOffset() < 0)
                     92:                       ? " " + (now.getTimezoneOffset() / 60)
                     93:                       : " +" + (now.getTimezoneOffset() / 60)));
                     94:        }
                     95: 
                     96:        void log(String msg) {
                     97:            msg = "["+getDate()+"] "+msg+"\n";
                     98:            try {
                     99:                if ( log == null || closed)
                    100:                    openLogFile();
                    101:                if ( log != null ) {
                    102:                    int len = msg.length() ;
                    103:                    if ( len > msgbuf.length ) 
                    104:                        msgbuf = new byte[len] ;
                    105:                    msg.getBytes (0, len, msgbuf, 0) ;
                    106:                    log.write (msgbuf, 0, len) ;
                    107:                }
                    108:            } catch (IOException ex) {
1.7       bmahe     109:                System.out.println("Can't write ("+
                    110:                                   msg+") to logfile ["+
                    111:                                   logfile+"] : "+ex.getMessage());
1.5       bmahe     112:            }
                    113:        }
1.30      ylafon    114: 
1.5       bmahe     115:        void log(Exception ex, String msg) {
1.15      bmahe     116:            log(msg+" : "+ex.getClass().getName()+" ("+ex.getMessage()+")");
1.5       bmahe     117:        }
                    118: 
1.20      bmahe     119:        void log(Throwable throwable, String msg) {
                    120:            ByteArrayOutputStream out = new ByteArrayOutputStream();
                    121:            PrintWriter writer = new PrintWriter(out);
                    122:            throwable.printStackTrace(writer);
                    123:            writer.close();
                    124:            String stacktrace = out.toString();
                    125:            log(msg+" "+stacktrace);
                    126:        }
                    127: 
1.5       bmahe     128:        void openLogFile() 
                    129:            throws IOException
                    130:        {
                    131:            RandomAccessFile old = log ;
                    132:            log = new RandomAccessFile (logfile, "rw") ;
                    133:            log.seek (log.length()) ;
                    134:            closed = false;
                    135:            if ( old != null )
                    136:                old.close () ;
                    137:        }
                    138: 
                    139:        void close() {
                    140:            try {
                    141:                if (log != null)
                    142:                    log.close();
                    143:                closed = true;
                    144:            } catch (IOException ex) {
                    145:                ex.printStackTrace();
                    146:            }
                    147:        }
                    148: 
                    149:        Logger(File logfile) {
                    150:            this.logfile = logfile;
                    151:            this.msgbuf  = new byte[128] ;
                    152:            log("Servlet Logger started");
                    153:        }
                    154:     }
1.9       bmahe     155: 
1.1       bmahe     156:     private ResourceReference reference = null;
                    157: 
1.5       bmahe     158:     private Logger logger = null;
                    159: 
1.11      bmahe     160:     private ObservableProperties props = null;
                    161: 
1.15      bmahe     162:     private File directory = null;
                    163: 
1.20      bmahe     164:     private Hashtable attributes = null;
                    165: 
1.12      bmahe     166:     protected static String logdir     = "logs" ;
                    167: 
                    168:     protected static String deflogfile = "servlets";
                    169: 
1.11      bmahe     170:     public boolean propertyChanged (String name) {
1.13      bmahe     171:        if (name.equals(ServletProps.SERVLET_LOG_FILE_P)) {
1.5       bmahe     172:            if (logger != null) {
                    173:                logger.close();
1.26      bmahe     174:                File newlogfile = new File((String) 
                    175:                                   props.get(ServletProps.SERVLET_LOG_FILE_P));
1.11      bmahe     176:                if (newlogfile.getPath().length() < 1) 
1.7       bmahe     177:                    newlogfile = getServletLogFile();
                    178:                logger = new Logger(newlogfile);
1.5       bmahe     179:            }
                    180:        }
1.11      bmahe     181:        return true;
1.5       bmahe     182:     }
                    183: 
                    184:     public void resourceUnloaded(StructureChangedEvent evt){
                    185:        if (logger != null) {
                    186:            logger.close();
                    187:        }
1.21      bmahe     188:     }
                    189: 
                    190:     protected long getServletTimeout() {
1.23      bmahe     191:        return props.getLong(ServletProps.SERVLET_TIMEOUT, -1);
1.5       bmahe     192:     }
                    193: 
1.32      ylafon    194:     protected int getServletInstanceMax() { // added for single thread model servlet instance pool size limitation, tk, 20.10.2001
1.34      ylafon    195:        return props.getInteger(ServletProps.SERVLET_INSTANCEMAX, 0);
1.32      ylafon    196:     }
                    197:     
1.1       bmahe     198:     /**
                    199:      * A useful utility routine that tries to guess the content-type
                    200:      * of an object based upon its extension.
                    201:      */
                    202:     protected static String guessContentTypeFromName(String fname) {
1.17      bmahe     203:        return org.w3c.www.mime.Utils.guessContentTypeFromName(fname);
1.1       bmahe     204:     }
                    205: 
                    206:     /**
                    207:      * ServletContext implementation - Get the MIME type for given file.
                    208:      */
                    209:     public String getMimeType(String filename) {
                    210:        return guessContentTypeFromName(filename);
1.7       bmahe     211:     }
                    212: 
1.19      bmahe     213:     public ServerInterface getServer() {
1.7       bmahe     214:        try {
                    215:            Resource res = reference.lock();
1.11      bmahe     216:            return ((ServletDirectoryFrame)res).getServer();
1.7       bmahe     217:        } catch(InvalidResourceException ex) {
                    218:            ex.printStackTrace();
                    219:            return null;
                    220:        } finally {
                    221:            reference.unlock();
                    222:        }
1.1       bmahe     223:     }
                    224: 
1.11      bmahe     225:     public File getServletLogFile() {
                    226:        ServerInterface server = getServer();
                    227:        File logfile = null;
                    228:        String file = (String)
1.14      bmahe     229:            server.getProperties().getString(ServletProps.SERVLET_LOG_FILE_P,
                    230:                                             null);
1.11      bmahe     231:        if (file != null)
                    232:            logfile = new File(file);
                    233:        if ((logfile != null) && (logfile.getPath().length() < 1))
                    234:            logfile = null;
                    235:        if (logfile == null) {
                    236:            File root_dir = server.getRootDirectory();
                    237:            if (root_dir == null) {
                    238:                throw new RuntimeException("unable to build a default "+
                    239:                                           "value for the servlet log file.");
                    240:            }
                    241:            logfile = new File(new File(root_dir, logdir), deflogfile);
1.16      bmahe     242:            server.getProperties().putValue(ServletProps.SERVLET_LOG_FILE_P,
                    243:                                            logfile.getAbsolutePath());
1.11      bmahe     244:        }
                    245:        return logfile;
                    246:     }
                    247: 
1.1       bmahe     248:     /**
                    249:      * ServletContext implementation - Lookup a given servlet.
1.20      bmahe     250:      * @deprecated since jsdk2.1
1.1       bmahe     251:      */
                    252: 
                    253:     public Servlet getServlet(String name) {
                    254:        try {
                    255:            Resource res = reference.lock();
                    256:            return ((ServletDirectoryFrame)res).getServlet(name);
                    257:        } catch(InvalidResourceException ex) {
                    258:            ex.printStackTrace();
                    259:            return null;
                    260:        } finally {
                    261:            reference.unlock();
                    262:        }
                    263:     }
                    264: 
                    265:     /**
                    266:      * ServletContext implementation - Enumerate all servlets within context.
1.20      bmahe     267:      * @deprecated since jsdk2.1
1.1       bmahe     268:      */
                    269: 
                    270:     public Enumeration getServlets() {
                    271:        try {
                    272:            Resource res = reference.lock();
                    273:            return ((ServletDirectoryFrame)res).getServlets();
                    274:        } catch(InvalidResourceException ex) {
                    275:            ex.printStackTrace();
                    276:            return null;
                    277:        } finally {
                    278:            reference.unlock();
                    279:        }
                    280:     }
1.4       bmahe     281: 
                    282:     /**
                    283:      * ServletContext implementation - Enumerate all servlets names 
                    284:      * within context.
1.20      bmahe     285:      * @deprecated since jsdk2.1
1.4       bmahe     286:      */
1.1       bmahe     287:     public Enumeration getServletNames() {
1.2       bmahe     288:        try {
                    289:            Resource res = reference.lock();
                    290:            return ((ServletDirectoryFrame)res).getServletNames();
                    291:        } catch(InvalidResourceException ex) {
                    292:            ex.printStackTrace();
                    293:            return null;
                    294:        } finally {
                    295:            reference.unlock();
                    296:        }
1.1       bmahe     297:     }
                    298: 
                    299:     /**
                    300:      * ServletContext implementation - Log a message.
                    301:      */
                    302:     public void log(String msg) {
1.5       bmahe     303:        logger.log(msg);
1.1       bmahe     304:     }
1.30      ylafon    305: 
1.20      bmahe     306:     /**
                    307:      * @deprecated since jsdk2.1
                    308:      */
1.1       bmahe     309:     public void log(Exception ex, String msg) {
1.5       bmahe     310:        logger.log(ex,msg);
1.1       bmahe     311:     }
                    312: 
1.20      bmahe     313:     public void log(String message, Throwable throwable) {
                    314:        logger.log(throwable, message);
                    315:     }
                    316: 
1.1       bmahe     317:     /**
                    318:      * ServletContext implementation - Translate a piece of path.
1.27      bmahe     319:      * @param path the virtual path to translate
                    320:      * @param rr_root the Root ResourceReference
                    321:      * @param rr the target ResourceReference
                    322:      * @return the real path
                    323:      */
                    324:     protected static String getRealPath(String path, 
                    325:                                        ResourceReference rr_root,
                    326:                                        ResourceReference rr) 
                    327:     {
                    328:        ResourceReference local_root = getLocalRoot(rr_root, rr);
                    329:        try {
                    330:            FramedResource root = (FramedResource)local_root.lock();
                    331:            LookupState    ls   = new LookupState(path);
                    332:            LookupResult   lr   = new LookupResult(local_root);
                    333:            if (root.lookup(ls,lr)) {
                    334:                ResourceReference  target = lr.getTarget();
                    335:                if (target != null) {
                    336:                    try {
                    337:                        FramedResource res = (FramedResource)target.lock();
                    338:                        if (res instanceof FileResource) {
                    339:                            File file = ((FileResource)res).getFile();
                    340:                            return file.getAbsolutePath();
                    341:                        } else if (res instanceof DirectoryResource) {
                    342:                            DirectoryResource dir = (DirectoryResource) res;
                    343:                            return dir.getDirectory().getAbsolutePath();
                    344:                            //return getFilePath(dir);
                    345:                        }
                    346:                    } finally {
                    347:                        target.unlock();
                    348:                    }
                    349:                }
                    350:            }
                    351:            return null;
                    352:        } catch (InvalidResourceException ex) {
                    353:            return null;
                    354:        } catch (org.w3c.tools.resources.ProtocolException pex) {
                    355:            return null;
                    356:        } finally {
                    357:            local_root.unlock();
                    358:        }
1.33      ylafon    359:     }
                    360:     
                    361:     /**
                    362:      * from Servlet 2.3, very file-oriented
                    363:      * FIXME always returning null as of now
                    364:      */
                    365:     public Set getResourcePaths(String path) {
                    366:        return null;
                    367:     }
                    368:     /**
                    369:      * from Servlet 2.3, very file-oriented should return a web-app container
                    370:      * name
                    371:      * FIXME always returning null as of now
                    372:      */
                    373:     public String getServletContextName() {
                    374:        return null;
1.27      bmahe     375:     }
                    376: 
                    377:     /**
                    378:      * ServletContext implementation - Translate a piece of path.
                    379:      * @param path the virtual path to translate
                    380:      * @return the real path
1.1       bmahe     381:      */
1.27      bmahe     382:     public String getRealPath(String path) {
                    383:        ResourceReference rr_root = ((httpd) getServer()).getRootReference();
                    384:        return getRealPath(path, rr_root, reference);
                    385:     }
1.1       bmahe     386: 
1.27      bmahe     387:     protected static String getFilePath(DirectoryResource dir) {
                    388:        HTTPFrame frame = 
                    389:            (HTTPFrame)dir.getFrame("org.w3c.jigsaw.frames.HTTPFrame");
                    390:        String indexes[] = frame.getIndexes();
                    391:        if (indexes != null) {
1.35    ! ylafon    392:         for (String index : indexes) {
        !           393:             if (index != null && index.length() > 0) {
        !           394:                 ResourceReference rr = dir.lookup(index);
        !           395:                 if (rr != null) {
        !           396:                     try {
        !           397:                         FramedResource ri = (FramedResource) rr.lock();
        !           398:                         if (ri instanceof FileResource) {
        !           399:                             FileResource fr = (FileResource) ri;
        !           400:                             File file = fr.getFile();
        !           401:                             return file.getAbsolutePath();
        !           402:                         } else {
        !           403:                             // we don't know
        !           404:                             return null;
        !           405:                         }
        !           406:                     } catch (InvalidResourceException ex) {
        !           407:                     } finally {
        !           408:                         rr.unlock();
        !           409:                     }
        !           410:                 }
        !           411:             }
        !           412:         }
1.27      bmahe     413:            return dir.getDirectory().getAbsolutePath();
                    414:        } else {
                    415:            return dir.getDirectory().getAbsolutePath();
1.26      bmahe     416:        }
                    417:     }
                    418: 
1.27      bmahe     419:     protected static ResourceReference getLocalRoot(ResourceReference rr_root,
                    420:                                                    ResourceReference ref) 
                    421:     {
1.22      bmahe     422:        try {
                    423:            FramedResource root = (FramedResource)rr_root.lock();
                    424:            if (root instanceof VirtualHostResource) {
                    425:                //backward to the virtual host resource
                    426:                ResourceReference rr  = null;
                    427:                ResourceReference rrp = null;
                    428:                FramedResource    res = null;
                    429:                try {
1.26      bmahe     430:                    res = (FramedResource)ref.lock();
                    431:                    if (res instanceof ResourceFrame) {
                    432:                        ResourceFrame fr = (ResourceFrame)res;
                    433:                        rr = fr.getResource().getResourceReference();
                    434:                    } else {
                    435:                        rr = ref;
                    436:                    }
1.22      bmahe     437:                } catch (InvalidResourceException ex) {
1.27      bmahe     438:                    return rr_root;
1.22      bmahe     439:                } finally {
1.26      bmahe     440:                    ref.unlock();
1.22      bmahe     441:                }
                    442: 
                    443:                while (true) {
                    444:                    try {
                    445:                        res = (FramedResource)rr.lock();
                    446:                        rrp = res.getParent();
                    447:                        if ((rrp == rr_root) || (rrp == null)) {
1.27      bmahe     448:                            return getLocalRoot(rr, ref);
1.22      bmahe     449:                        }
                    450:                    } catch (InvalidResourceException ex) {
1.27      bmahe     451:                        return rr_root;
1.22      bmahe     452:                    } finally {
                    453:                        rr.unlock();
                    454:                    }
                    455:                    rr = rrp;
                    456:                }
1.26      bmahe     457:            } else {
1.27      bmahe     458:                try {
                    459:                    FramedResource res = (FramedResource)rr_root.lock();
                    460:                    ForwardFrame   ffr = (ForwardFrame)
                    461:                        res.getFrame("org.w3c.jigsaw.proxy.ForwardFrame");
                    462:                    if (ffr == null) {
                    463:                        return rr_root;
                    464:                    } else {
                    465:                        ResourceReference rr = ffr.getLocalRootResource();
                    466:                        return getLocalRoot(rr, ref);
                    467:                    }
                    468:                } catch (InvalidResourceException ex) {
                    469:                    return rr_root;
                    470:                }
1.22      bmahe     471:            }
                    472:        } catch (InvalidResourceException ex) {
1.27      bmahe     473:            return rr_root;
1.22      bmahe     474:        } finally {
                    475:            rr_root.unlock();
                    476:        }
1.1       bmahe     477:     }
                    478: 
                    479:     /**
                    480:      * ServletContext implementation - Get server informations.
                    481:      */
                    482: 
                    483:     public String getServerInfo() {
                    484:        try {
                    485:            Resource res = reference.lock();
                    486:            return ((ServletDirectoryFrame)res).getServerInfo();
                    487:        } catch(InvalidResourceException ex) {
                    488:            ex.printStackTrace();
                    489:            return null;
                    490:        } finally {
                    491:            reference.unlock();
                    492:        }       
                    493:     }
                    494: 
                    495:     /**
                    496:      * ServletContext implementation - Get an attribute value.
                    497:      * We map this into the ServletWrapper attributes, without
                    498:      * support for name clashes though.
                    499:      * @param name The attribute name.
                    500:      */
1.30      ylafon    501: 
1.1       bmahe     502:     public Object getAttribute(String name) {
1.20      bmahe     503:        Object attribute = attributes.get(name);
                    504:        if (attribute != null) {
                    505:            return attribute;
                    506:        } else {
                    507:            try {
                    508:                Resource res = reference.lock();
                    509:                return ((ServletDirectoryFrame)res).getAttribute(name);
                    510:            } catch(InvalidResourceException ex) {
                    511:                ex.printStackTrace();
                    512:                return null;
                    513:            } finally {
                    514:                reference.unlock();
                    515:            }
1.1       bmahe     516:        }
                    517:     }
                    518: 
1.20      bmahe     519:     public void setAttribute(String name, Object object) {
                    520:        attributes.put(name, object);
                    521:     }
                    522: 
                    523:     public void removeAttribute(String name) {
                    524:        attributes.remove(name);
                    525:     }
                    526: 
                    527:     public Enumeration getAttributeNames() {
                    528:        return attributes.keys();
                    529:     }
                    530: 
1.25      bmahe     531:     /**
                    532:      * Returns a <code>String</code> containing the value of the named
                    533:      * context-wide initialization parameter, or <code>null</code> if the 
                    534:      * parameter does not exist.
                    535:      *
                    536:      * <p>This method can make available configuration information useful
                    537:      * to an entire "web application".  For example, it can provide a 
                    538:      * webmaster's email address or the name of a system that holds 
                    539:      * critical data.
                    540:      *
                    541:      * @param name a <code>String</code> containing the name of the
                    542:      * parameter whose value is requested
                    543:      * @return         a <code>String</code> containing at least the 
                    544:      * servlet container name and version number
                    545:      * @see ServletConfig#getInitParameter
                    546:      */
                    547:     public String getInitParameter(String name) {
                    548:        // @@ not implemented @@
                    549:        return null;
                    550:     }
1.30      ylafon    551: 
                    552:    
1.25      bmahe     553: 
                    554: 
                    555:     /**
                    556:      * Returns the names of the context's initialization parameters as an
                    557:      * <code>Enumeration</code> of <code>String</code> objects, or an
                    558:      * empty <code>Enumeration</code> if the context has no initialization
                    559:      * parameters.
                    560:      *
                    561:      * @return an <code>Enumeration</code> of <code>String</code> 
                    562:      * objects containing the names of the context's initialization parameters
                    563:      * @see ServletConfig#getInitParameter
                    564:      */
                    565:     public Enumeration getInitParameterNames() {
                    566:        // @@ not implemented @@
                    567:        return new EmptyEnumeration();
                    568:     }
                    569: 
1.15      bmahe     570:     private AutoReloadServletLoader loader = null;
                    571: 
                    572:     /** 
                    573:      * Get or create a suitable LocalServletLoader instance to load 
                    574:      * that servlet.
                    575:      * @return A LocalServletLoader instance.
                    576:      */
                    577:     protected synchronized AutoReloadServletLoader getLocalServletLoader() {
                    578:        if ( loader == null ) {
                    579:            loader = new AutoReloadServletLoader(this);
                    580:        }
                    581:        return loader;
                    582:     }
                    583: 
                    584:     protected synchronized 
                    585:        AutoReloadServletLoader createNewLocalServletLoader (boolean keepold) 
                    586:     {
                    587:        if ((loader != null) && keepold)
                    588:            loader = new AutoReloadServletLoader(loader);
                    589:        else
                    590:            loader = new AutoReloadServletLoader(this);
                    591:        return loader;
                    592:     }
                    593: 
                    594:     public File getServletDirectory() {
                    595:        return directory;
                    596:     }
                    597: 
1.20      bmahe     598:     //jsdk2.1
                    599: 
                    600:     /**
                    601:      * Returns a RequestDispatcher object for the specified URL path if 
                    602:      * the context knows of an active source (such as a servlet, JSP page,
                    603:      * CGI script, etc) of content for the particular path. This format of
                    604:      * the URL path must be of the form /dir/dir/file.ext. The servlet 
                    605:      * engine is responsible for implementing whatever functionality is 
                    606:      * required to wrap the target source with an implementation of
                    607:      * the RequestDispatcher interface. 
                    608:      * @param urlpath Path to use to look up the target server resource
                    609:      */
                    610:     public RequestDispatcher getRequestDispatcher(String urlpath) {
1.25      bmahe     611:        return JigsawRequestDispatcher.getRequestDispatcher(urlpath, 
1.29      bmahe     612:                                                           (httpd)getServer(),
                    613:                                                            reference);
1.25      bmahe     614:     }
                    615: 
                    616:     /**
                    617:      * Returns a {@link RequestDispatcher} object that acts
                    618:      * as a wrapper for the named servlet.
                    619:      *
                    620:      * <p>Servlets (and JSP pages also) may be given names via server 
                    621:      * administration or via a web application deployment descriptor.
                    622:      * A servlet instance can determine its name using 
                    623:      * {@link ServletConfig#getServletName}.
                    624:      *
                    625:      * <p>This method returns <code>null</code> if the 
                    626:      * <code>ServletContext</code>
                    627:      * cannot return a <code>RequestDispatcher</code> for any reason.
                    628:      *
                    629:      * @param name a <code>String</code> specifying the name
                    630:      * of a servlet to wrap
                    631:      * @return a <code>RequestDispatcher</code> object
                    632:      * that acts as a wrapper for the named servlet
                    633:      * @see RequestDispatcher
                    634:      * @see ServletContext#getContext
                    635:      * @see ServletConfig#getServletName
                    636:      */
                    637:     public RequestDispatcher getNamedDispatcher(String name) {
                    638:        if (name == null) {
                    639:            throw new IllegalArgumentException("null");
                    640:        }
                    641:        return JigsawRequestDispatcher.getRequestDispatcher(name, 
                    642:                                                            reference,
                    643:                                                           (httpd)getServer());
1.20      bmahe     644:     }
                    645: 
                    646:     public int getMajorVersion() {
                    647:        return 2;
                    648:     }
                    649: 
                    650:     public int getMinorVersion() {
1.25      bmahe     651:        return 2;
1.20      bmahe     652:     }
1.30      ylafon    653: 
1.20      bmahe     654:     public ServletContext getContext(String uripath) {
                    655:        if (uripath == null)
                    656:            return null;
                    657:        //first, find the ServletDirectoryFrame.
                    658:        // Prepare for lookup:
                    659:        ResourceReference rr_root = null;
                    660:        rr_root = ((httpd) getServer()).getRootReference();
                    661: 
                    662:        FramedResource root = null;
                    663:        root = ((httpd) getServer()).getRoot();
                    664: 
                    665:        // Do the lookup:
                    666:        ResourceReference r_target = null;
                    667:        try {
                    668:            LookupState  ls = new LookupState(uripath);
                    669:            LookupResult lr = new LookupResult(rr_root);
                    670:            root.lookup(ls, lr);
                    671:            r_target = lr.getTarget();
                    672:        } catch (Exception ex) {
                    673:            r_target = null;
                    674:        }
                    675:        //then return its context
                    676:        if (r_target != null) {
                    677:            try {
                    678:                Resource target = r_target.lock();
                    679:                if (target instanceof FramedResource) {
                    680:                    ServletDirectoryFrame frame = (ServletDirectoryFrame)
                    681:                        ((FramedResource) target).
                    682:                      getFrame("org.w3c.jigsaw.servlet.ServletDirectoryFrame");
                    683:                    if (frame != null)
                    684:                        return frame.getServletContext();
                    685:                }
                    686:            } catch (InvalidResourceException ex) {
                    687:                // continue
                    688:            } finally {
                    689:                r_target.unlock();
                    690:            }
                    691:        }
                    692:        return null;
                    693:     }
                    694: 
                    695:     public URL getResource(String path) 
1.26      bmahe     696:        throws MalformedURLException
1.20      bmahe     697:     {
1.31      bmahe     698:        // FIXME? is it allowed?
                    699:        File file = new File(path);
                    700:        if (file.exists()) {
                    701:            return new URL("file", "", file.getAbsolutePath());
                    702:        }
1.27      bmahe     703:        String realpath = getRealPath(path);
                    704:        if (realpath != null) {
1.31      bmahe     705:            file = new File(realpath);
1.27      bmahe     706:            if (file.exists()) {
                    707:                return new URL("file", "", file.getAbsolutePath());
                    708:            } else {
                    709:                return null;
                    710:            }
                    711:        } else {
                    712:            // it could be a virtual resource
                    713:            // check that it exists (on server)
                    714:            // FIXME (Virtual host)
                    715:            return null;
1.26      bmahe     716:        }
1.24      bmahe     717:     }
1.26      bmahe     718: 
1.20      bmahe     719:     public InputStream getResourceAsStream(String path) {
                    720:        try {
                    721:            URL resource = getResource(path);
                    722:            if (resource == null)
                    723:                return null;
                    724:            try {
                    725:                URLConnection c = resource.openConnection();
                    726:                return c.getInputStream();
                    727:            } catch (IOException ex) {
                    728:                return null;
                    729:            }
                    730:        } catch (MalformedURLException ex) {
                    731:            return null;
                    732:        }
                    733:     }
                    734: 
1.1       bmahe     735:     /**
                    736:      * Create a new ServletContext.
                    737:      * @param ref a ResourceReference pointing on a ServletDirectoryFrame.
                    738:      */
1.11      bmahe     739:     protected JigsawServletContext(ResourceReference ref, 
                    740:                                   ObservableProperties props) 
                    741:     {
1.20      bmahe     742:        this.reference  = ref;
                    743:        this.props      = props;
                    744:        this.attributes = new Hashtable(3);
                    745:        this.logger     = new Logger(getServletLogFile());
                    746:        this.loader     = new AutoReloadServletLoader(this);
                    747: 
1.11      bmahe     748:        props.registerObserver(this);
1.20      bmahe     749: 
1.3       bmahe     750:        try {
                    751:            Resource res = reference.lock();
                    752:            if (! (res instanceof ServletDirectoryFrame)) {
1.25      bmahe     753:                throw new IllegalArgumentException("This reference is not "+
1.26      bmahe     754:                                      "pointing on a ServletDirectoryFrame.");
1.5       bmahe     755:            } else {
                    756:                ServletDirectoryFrame sframe = (ServletDirectoryFrame)res;
                    757:                FramedResource resource = (FramedResource)sframe.getResource();
                    758:                resource.addStructureChangedListener(this);
1.15      bmahe     759:                if (resource.definesAttribute("directory"))
                    760:                    this.directory = 
                    761:                        (File) resource.getValue("directory", null);
1.3       bmahe     762:            }
                    763:        } catch(InvalidResourceException ex) {
1.25      bmahe     764:            throw new IllegalArgumentException("This reference is pointing on"+
1.26      bmahe     765:                                         " an Invalid ServletDirectoryFrame.");
1.3       bmahe     766:        } finally {
                    767:            reference.unlock();
                    768:        }
1.1       bmahe     769:     }
                    770: 
                    771: }

Webmaster