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