Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / mcr-test / WWW / Doc / Programmer / samples / HTTPFrame.html
diff --git a/JMCR-Stable/mcr-test/WWW/Doc/Programmer/samples/HTTPFrame.html b/JMCR-Stable/mcr-test/WWW/Doc/Programmer/samples/HTTPFrame.html
new file mode 100644 (file)
index 0000000..83ce02c
--- /dev/null
@@ -0,0 +1,1901 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"\r
+                      "http://www.w3.org/TR/REC-html40/strict.dtd">\r
+<html>\r
+  <head>\r
+    <title>HTTPFrame.java</title>\r
+    <meta name="Author" content="Benoit Mahe">\r
+    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">\r
+    <meta name="Generator" content="*emacs: emacs-css">\r
+\r
+    <link rel="Stylesheet" media="screen" type="text/css" href="default-html.css">\r
+  </head>\r
+  <body>\r
+\r
+    <pre>\r
+<span class="comment">// HTTPFrame.java\r
+// $Id: HTTPFrame.html,v 1.1 2010/06/15 12:20:08 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1997.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+</span>\r
+<span class="keyword">package</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">jigsaw</span>.<span class="type">frames</span>;\r
+\r
+<span class="keyword">import</span> <span class="reference">java</span>.<span class="reference">io</span>.*;\r
+<span class="keyword">import</span> <span class="reference">java</span>.<span class="reference">net</span>.*;\r
+<span class="keyword">import</span> <span class="reference">java</span>.<span class="reference">util</span>.*;\r
+\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">tools</span>.<span class="reference">codec</span>.*;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">tools</span>.<span class="reference">sorter</span>.*;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">tools</span>.<span class="reference">resources</span>.*;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">tools</span>.<span class="reference">resources</span>.<span class="reference">event</span>.*;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">jigsaw</span>.<span class="reference">http</span>.* ;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">jigsaw</span>.<span class="reference">html</span>.* ;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">www</span>.<span class="reference">mime</span>.*;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">www</span>.<span class="reference">http</span>.*;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">tools</span>.<span class="reference">crypt</span>.<span class="type">Md5</span>;\r
+\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">tools</span>.<span class="reference">resources</span>.<span class="type">ProtocolException</span>;\r
+<span class="keyword">import</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">tools</span>.<span class="reference">resources</span>.<span class="type">NotAProtocolException</span>;\r
+\r
+<span class="comment">/**\r
+ * Default class to handle the HTTP protocol, manage FileResource and\r
+ * DirectoryResource.\r
+ */</span>\r
+<span class="reference">public</span> <span class="keyword">class</span> <span class="function-name">HTTPFrame</span> <span class="keyword">extends</span> <span class="type">ProtocolFrame</span> {\r
+\r
+    <span class="comment">/**\r
+     * The special class of filter.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">Class</span> <span class="variable-name">filterClass</span> = <span class="keyword">null</span>;\r
+\r
+    <span class="comment">/**\r
+     * Condition check return code - Condition existed but failed.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">static</span> <span class="type">final</span> <span class="type">int</span> <span class="variable-name">COND_FAILED</span> = 1;\r
+    <span class="comment">/**\r
+     * Condition check return code - Condition existed and succeeded.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">static</span> <span class="type">final</span> <span class="type">int</span> <span class="variable-name">COND_OK</span> = 2;\r
+  \r
+    <span class="comment">// Methods allowed by that class in general:\r
+</span>    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">HttpTokenList</span> <span class="variable-name">_allowed</span>        = <span class="keyword">null</span>;\r
+    <span class="string">private</span>   <span class="type">static</span> <span class="type">HttpTokenList</span> <span class="variable-name">_put_allowed</span>    = <span class="keyword">null</span>;\r
+    <span class="string">private</span>   <span class="type">static</span> <span class="type">HttpTokenList</span> <span class="variable-name">_browse_allowed</span> = <span class="keyword">null</span>;\r
+    <span class="string">private</span>   <span class="type">static</span> <span class="type">HttpTokenList</span> <span class="variable-name">_accept_ranges</span>  = <span class="keyword">null</span>;\r
+\r
+    <span class="type">static</span> {\r
+       <span class="comment">// allowed shares _allowed value, that's a feature.\r
+</span>        <span class="type">String</span> <span class="variable-name">str_allowed</span>[] = { "<span class="string">GET</span>", "<span class="string">HEAD</span>", "<span class="string">OPTIONS</span>", "<span class="string">TRACE</span>"};\r
+       _allowed = HttpFactory.makeStringList(str_allowed);\r
+       <span class="type">String</span> <span class="variable-name">str_allow</span>[] = { "<span class="string">HEAD</span>" , "<span class="string">GET</span>" , "<span class="string">PUT</span>" , "<span class="string">OPTIONS</span>", "<span class="string">TRACE</span>" };\r
+       _put_allowed = HttpFactory.makeStringList(str_allow);\r
+       <span class="type">String</span> <span class="variable-name">str_all</span>[] = { "<span class="string">HEAD</span>" , "<span class="string">GET</span>" , "<span class="string">BROWSE</span>" , "<span class="string">OPTIONS</span>","<span class="string">TRACE</span>" };\r
+       _browse_allowed = HttpFactory.makeStringList(str_allow);\r
+       <span class="type">String</span> <span class="variable-name">accept_ranges</span>[] = { "<span class="string">bytes</span>" };\r
+       _accept_ranges = HttpFactory.makeStringList(accept_ranges);\r
+    }\r
+    <span class="comment">// Methods allowed by instances of that class in particular:\r
+</span>    <span class="preprocessor">protected</span>        <span class="type">HttpTokenList</span>  <span class="variable-name">allowed</span> = _allowed;\r
+\r
+\r
+    <span class="comment">/**\r
+     * Attributes index - The index for the quality attribute.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_QUALITY</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - The index for the title attribute.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_TITLE</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - The index for the content languages attribute.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_CONTENT_LANGUAGE</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - The index for the content encodings attribute.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_CONTENT_ENCODING</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - The index for the content type attribute.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_CONTENT_TYPE</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - The index for the content length attribute.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_CONTENT_LENGTH</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - The icon (if any) associated to the resource.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_ICON</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - Max age: the maximum drift allowed from reality.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_MAXAGE</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - Send MD5 Digest: the md5 digest of the resource sent\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_MD5</span> = -1;\r
+\r
+\r
+    <span class="comment">//\r
+</span>    <span class="comment">// Attribute relative to FileResource\r
+</span>    <span class="comment">//\r
+</span>\r
+    <span class="comment">/**\r
+     * Attribute index - Do we allow PUT method on this file.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_PUTABLE</span> = -1 ;\r
+\r
+    <span class="comment">//\r
+</span>    <span class="comment">// Attribute relative to DirectoryResource\r
+</span>    <span class="comment">//\r
+</span>\r
+    <span class="comment">/**\r
+     * Attribute index - The index for our relocate attribute.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_RELOCATE</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - our index resource name.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_INDEX</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - The icon directory to use in dir listing.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_ICONDIR</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - Allow the GNN browse method.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_BROWSABLE</span> = -1 ;\r
+    <span class="comment">/**\r
+     * Attribute index - Style sheet for directory listing\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_STYLE_LINK</span> = -1 ;\r
+\r
+    <span class="type">static</span> {\r
+       <span class="type">Attribute</span> <span class="variable-name">a</span>   = <span class="keyword">null</span> ;\r
+       <span class="type">Class</span>     <span class="variable-name">cls</span> = <span class="keyword">null</span> ;\r
+\r
+       <span class="keyword">try</span> {\r
+           filterClass = \r
+               Class.forName("<span class="string">org.w3c.tools.resources.ResourceFilter</span>");\r
+       } <span class="keyword">catch</span> (<span class="type">Exception</span> <span class="variable-name">ex</span>) {\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">RuntimeException</span>("<span class="string">No ResourceFilter class found.</span>");\r
+       }\r
+\r
+       <span class="comment">// Get a pointer to our class:\r
+</span>        <span class="keyword">try</span> {\r
+           cls = Class.forName("<span class="string">org.w3c.jigsaw.frames.HTTPFrame</span>") ;\r
+       } <span class="keyword">catch</span> (<span class="type">Exception</span> <span class="variable-name">ex</span>) {\r
+           ex.printStackTrace() ;\r
+           System.exit(1) ;\r
+       }\r
+       <span class="comment">// The quality attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">DoubleAttribute</span>("<span class="string">quality</span>"\r
+                               , <span class="keyword">new</span> <span class="type">Double</span>(1.0) \r
+                               , Attribute.EDITABLE);\r
+       ATTR_QUALITY = AttributeRegistry.registerAttribute(cls, a) ;\r
+       <span class="comment">// The title attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">StringAttribute</span>("<span class="string">title</span>"\r
+                               , <span class="keyword">null</span>\r
+                               , Attribute.EDITABLE) ;\r
+       ATTR_TITLE = AttributeRegistry.registerAttribute(cls, a) ;\r
+       <span class="comment">// The content language attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">LanguageAttribute</span>("<span class="string">content-language</span>"\r
+                                 , <span class="keyword">null</span>\r
+                                 , Attribute.EDITABLE) ;\r
+       ATTR_CONTENT_LANGUAGE = AttributeRegistry.registerAttribute(cls,a);\r
+       <span class="comment">// The content encoding attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">EncodingAttribute</span>("<span class="string">content-encoding</span>"\r
+                                 , <span class="keyword">null</span>\r
+                                 , Attribute.EDITABLE) ;\r
+       ATTR_CONTENT_ENCODING = AttributeRegistry.registerAttribute(cls,a);\r
+       <span class="comment">// The content type attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">MimeTypeAttribute</span>("<span class="string">content-type</span>"\r
+                                 , <span class="reference">MimeType</span>.<span class="type">TEXT_PLAIN</span>\r
+                                 , Attribute.EDITABLE) ;\r
+       ATTR_CONTENT_TYPE = AttributeRegistry.registerAttribute(cls,a);\r
+       <span class="comment">// The content length attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">IntegerAttribute</span>("<span class="string">content-length</span>"\r
+                                , <span class="keyword">null</span>\r
+                                , Attribute.COMPUTED);\r
+       ATTR_CONTENT_LENGTH = AttributeRegistry.registerAttribute(cls,a);\r
+       <span class="comment">// The icon attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">StringAttribute</span>("<span class="string">icon</span>"\r
+                               , <span class="keyword">null</span>\r
+                               , Attribute.EDITABLE) ;\r
+       ATTR_ICON = AttributeRegistry.registerAttribute(cls, a) ;\r
+       <span class="comment">// The max age attribute (in ms)\r
+</span>        a = <span class="keyword">new</span> <span class="type">LongAttribute</span>("<span class="string">maxage</span>"\r
+                             , <span class="keyword">null</span>\r
+                             , Attribute.EDITABLE) ;\r
+       ATTR_MAXAGE = AttributeRegistry.registerAttribute(cls, a) ;\r
+       <span class="comment">// Should we send MD5 digest?\r
+</span>        a = <span class="keyword">new</span> <span class="type">BooleanAttribute</span>("<span class="string">send-md5</span>"\r
+                                , <span class="reference">Boolean</span>.<span class="type">FALSE</span>\r
+                                , Attribute.EDITABLE);\r
+       ATTR_MD5 = AttributeRegistry.registerAttribute(cls, a) ;\r
+\r
+       <span class="comment">//\r
+</span>        <span class="comment">// Attribute relative to a FileResource\r
+</span>        <span class="comment">//\r
+</span>\r
+       <span class="comment">// The putable flag:\r
+</span>        a = <span class="keyword">new</span> <span class="type">BooleanAttribute</span>("<span class="string">putable</span>"\r
+                                , <span class="reference">Boolean</span>.<span class="type">FALSE</span>\r
+                                , Attribute.EDITABLE) ;\r
+       ATTR_PUTABLE = AttributeRegistry.registerAttribute(cls, a) ;\r
+\r
+       <span class="comment">//\r
+</span>        <span class="comment">// Attribute relative to a DirectoryResource\r
+</span>        <span class="comment">//\r
+</span>\r
+       <span class="comment">//Should we relocate invalid request to this directory ?\r
+</span>        a = <span class="keyword">new</span> <span class="type">BooleanAttribute</span>("<span class="string">relocate</span>"\r
+                                , <span class="reference">Boolean</span>.<span class="type">TRUE</span>\r
+                                , Attribute.EDITABLE);\r
+       ATTR_RELOCATE = AttributeRegistry.registerAttribute(cls, a) ;\r
+       <span class="comment">// Our index resource name (optional).\r
+</span>        a = <span class="keyword">new</span> <span class="type">StringAttribute</span>("<span class="string">index</span>"\r
+                               , <span class="keyword">null</span>\r
+                               , Attribute.EDITABLE) ;\r
+       ATTR_INDEX = AttributeRegistry.registerAttribute(cls, a) ;\r
+       <span class="comment">// Our icon directory.\r
+</span>        a = <span class="keyword">new</span> <span class="type">StringAttribute</span>("<span class="string">icondir</span>"\r
+                               , <span class="keyword">null</span>\r
+                               , Attribute.EDITABLE) ;\r
+       ATTR_ICONDIR = AttributeRegistry.registerAttribute(cls,a);\r
+       <span class="comment">// The browsable flag:\r
+</span>        a = <span class="keyword">new</span> <span class="type">BooleanAttribute</span>("<span class="string">browsable</span>"\r
+                                , <span class="reference">Boolean</span>.<span class="type">FALSE</span>\r
+                                , Attribute.EDITABLE) ;\r
+       ATTR_BROWSABLE = AttributeRegistry.registerAttribute(cls, a) ;\r
+       <span class="comment">// The style sheet attribute:\r
+</span>        a = <span class="keyword">new</span> <span class="type">StringAttribute</span>("<span class="string">style-sheet-link</span>"\r
+                               , <span class="keyword">null</span>\r
+                               , Attribute.EDITABLE) ;\r
+       ATTR_STYLE_LINK = AttributeRegistry.registerAttribute(cls, a) ;\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">DirectoryResource</span> <span class="variable-name">dresource</span> = <span class="keyword">null</span>;\r
+    <span class="preprocessor">protected</span> <span class="type">FileResource</span>      <span class="variable-name">fresource</span> = <span class="keyword">null</span>;\r
+\r
+    <span class="reference">public</span> <span class="type">void</span> <span class="function-name">registerResource</span>(<span class="type">FramedResource</span> <span class="variable-name">resource</span>) {\r
+       <span class="reference">super</span>.registerResource(resource);\r
+       <span class="keyword">if</span> (resource <span class="keyword">instanceof</span> <span class="type">FileResource</span>)\r
+           fresource = (<span class="type">FileResource</span>) resource;\r
+       <span class="keyword">else</span> <span class="keyword">if</span> (resource <span class="keyword">instanceof</span> <span class="type">DirectoryResource</span>)\r
+           dresource = (<span class="type">DirectoryResource</span>) resource;\r
+    }\r
+\r
+    <span class="reference">public</span> <span class="type">FileResource</span> <span class="function-name">getFileResource</span>() {\r
+       <span class="keyword">return</span> fresource;\r
+    }\r
+\r
+    <span class="reference">public</span> <span class="type">DirectoryResource</span> <span class="function-name">getDirectoryResource</span>() {\r
+       <span class="keyword">return</span> dresource;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * use this one instead of registerResource if the resource type \r
+     * doesn't matter or if this is not a file or a directory resource.\r
+     * In subclasses you should have to do that:\r
+     * &lt;pre&gt;\r
+     *  public void registerResource(FramedResource resource) {\r
+     *   super.registerOtherResource(resource);\r
+     *  }\r
+     * &lt;/pre&gt;\r
+     * </span><span class="keyword">@param </span><span class="variable-name">the</span><span class="comment"> resource to register.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">void</span> <span class="function-name">registerOtherResource</span>(<span class="type">FramedResource</span> <span class="variable-name">resource</span>) {\r
+       <span class="reference">super</span>.registerResource(resource);\r
+       dresource = <span class="keyword">null</span>;\r
+       fresource = <span class="keyword">null</span>;\r
+    }\r
+\r
+    <span class="comment">// The HTTPResource keeps a cache of ready to use Http values. This \r
+</span>    <span class="comment">// allows to save converting to/from wire rep these objects. Not \r
+</span>    <span class="comment">// much CPU time, but also memory is spared.\r
+</span>    <span class="type">HttpMimeType</span>  <span class="variable-name">contenttype</span>     = <span class="keyword">null</span>;\r
+    <span class="type">HttpInteger</span>   <span class="variable-name">contentlength</span>   = <span class="keyword">null</span>;\r
+    <span class="type">HttpDate</span>      <span class="variable-name">lastmodified</span>    = <span class="keyword">null</span>;\r
+    <span class="type">HttpTokenList</span> <span class="variable-name">contentencoding</span> = <span class="keyword">null</span>;\r
+    <span class="type">HttpTokenList</span> <span class="variable-name">contentlanguage</span> = <span class="keyword">null</span>;\r
+\r
+    <span class="comment">// The Http entity tag for this resource (for FileResource only)\r
+</span>    <span class="type">HttpEntityTag</span> <span class="variable-name">etag</span>   = <span class="keyword">null</span>;\r
+    <span class="comment">// the MD5 digest for this resource (for FileResource only)\r
+</span>    <span class="type">HttpString</span> <span class="variable-name">md5Digest</span> = <span class="keyword">null</span>;\r
+\r
+    <span class="comment">/**\r
+     * Get this resource's help url.\r
+     * </span><span class="keyword">@return </span><span class="comment">An URL, encoded as a String, or &lt;strong&gt;null&lt;/strong&gt; if not\r
+     * available.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getHelpURL</span>() {\r
+       httpd server = (httpd) getServer();\r
+       <span class="keyword">if</span> ( server == <span class="keyword">null</span> ) \r
+           <span class="keyword">return</span> <span class="keyword">null</span>;\r
+       <span class="type">String</span> <span class="variable-name">docurl</span> = server.getDocumentationURL();\r
+       <span class="keyword">if</span> ( docurl == <span class="keyword">null</span> )\r
+           <span class="keyword">return</span> <span class="keyword">null</span>;\r
+       <span class="keyword">return</span> docurl + "<span class="string">/</span>" + getClass().getName() + "<span class="string">.html</span>";\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get the help URL for that resource's attribute.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">topic</span><span class="comment"> The topic (can be an attribute name, or a property, etc).\r
+     * </span><span class="keyword">@return </span><span class="comment">A String encoded URL, or &lt;strong&gt;null&lt;/strong&gt;.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getHelpURL</span>(<span class="type">String</span> <span class="variable-name">topic</span>) {\r
+       httpd server = (httpd) getServer();\r
+       <span class="keyword">if</span> ( server == <span class="keyword">null</span> ) \r
+           <span class="keyword">return</span> <span class="keyword">null</span>;\r
+       <span class="type">String</span> <span class="variable-name">docurl</span> = server.getDocumentationURL();\r
+       <span class="keyword">if</span> ( docurl == <span class="keyword">null</span> )\r
+           <span class="keyword">return</span> <span class="keyword">null</span>;\r
+       <span class="type">Class</span> <span class="variable-name">defines</span> = AttributeRegistry.getAttributeClass(getClass(), topic);\r
+       <span class="keyword">if</span> ( defines != <span class="keyword">null</span> ) \r
+           <span class="keyword">return</span> docurl + "<span class="string">/</span>" + defines.getName() + "<span class="string">.html</span>";\r
+       <span class="keyword">return</span> <span class="keyword">null</span>;\r
+    }\r
+\r
+    <span class="comment">/** \r
+     * give the md5 digest from cache or calculate it\r
+     * </span><span class="keyword">@return </span><span class="comment">the HttpString version of the digest\r
+     */</span>\r
+\r
+    <span class="string">private</span> <span class="type">HttpString</span> <span class="function-name">getMd5Digest</span>() {\r
+       <span class="keyword">if</span> (md5Digest != <span class="keyword">null</span>)\r
+           <span class="keyword">return</span> md5Digest;\r
+       <span class="comment">// not found, compute it if necessary!\r
+</span>        <span class="type">Resource</span> <span class="variable-name">r</span> = getResource();\r
+       <span class="keyword">if</span> (r <span class="keyword">instanceof</span> <span class="type">FileResource</span>) {\r
+           <span class="keyword">try</span> {\r
+               <span class="type">Md5</span> <span class="variable-name">md5</span> = <span class="keyword">new</span> <span class="type">Md5</span> (\r
+                   <span class="keyword">new</span> <span class="type">FileInputStream</span>(((<span class="type">FileResource</span>)r).getFile()));\r
+               <span class="type">String</span> <span class="variable-name">s</span> = <span class="keyword">null</span>;\r
+               <span class="keyword">try</span> {\r
+                   <span class="type">byte</span> <span class="variable-name">b</span>[] = md5.getDigest();\r
+                   <span class="type">Base64Encoder</span> <span class="variable-name">b64</span>;\r
+                   <span class="type">ByteArrayOutputStream</span> <span class="variable-name">bos</span> = <span class="keyword">new</span> <span class="type">ByteArrayOutputStream</span>();\r
+                   b64 = <span class="keyword">new</span> <span class="type">Base64Encoder</span>(<span class="keyword">new</span> <span class="type">ByteArrayInputStream</span>(b), bos);\r
+                   b64.process();\r
+                   s = bos.toString();\r
+                   md5Digest = HttpFactory.makeString(s);\r
+               } <span class="keyword">catch</span> (<span class="type">Exception</span> <span class="variable-name">mdex</span>) {\r
+                   <span class="comment">// error, set it to null\r
+</span>                    md5Digest = <span class="keyword">null</span>;\r
+               }\r
+               <span class="keyword">return</span> md5Digest;\r
+           } <span class="keyword">catch</span> (<span class="type">FileNotFoundException</span> <span class="variable-name">ex</span>) {\r
+               <span class="comment">// silent fail\r
+</span>                md5Digest = <span class="keyword">null</span>;\r
+           }\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">null</span>;\r
+    }\r
+    \r
+    <span class="comment">/**\r
+     * Listen its resource.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">void</span> <span class="function-name">attributeChanged</span>(<span class="type">AttributeChangedEvent</span> <span class="variable-name">evt</span>) {\r
+       <span class="reference">super</span>.attributeChanged(evt);\r
+       <span class="type">String</span> <span class="variable-name">name</span> = evt.getAttribute().getName();\r
+       <span class="keyword">if</span> (name.equals("<span class="string">file-stamp</span>")) {\r
+           etag = <span class="keyword">null</span>;\r
+           lastmodified = <span class="keyword">null</span>;\r
+           md5Digest = <span class="keyword">null</span>;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> (name.equals("<span class="string">file-length</span>")) {\r
+           setValue(ATTR_CONTENT_LENGTH, evt.getNewValue());\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> (name.equals("<span class="string">last-modified</span>")) {\r
+           setValue(ATTR_LAST_MODIFIED, evt.getNewValue());\r
+       } <span class="keyword">else</span> {\r
+           lastmodified = <span class="keyword">null</span>;\r
+       }\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Catch setValue, to maintain cached header values correctness.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">idx</span><span class="comment"> The index of the attribute to be set.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">value</span><span class="comment"> The new value for the attribute.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">synchronized</span> <span class="type">void</span> <span class="function-name">setValue</span>(<span class="type">int</span> <span class="variable-name">idx</span>, <span class="type">Object</span> <span class="variable-name">value</span>) {\r
+       <span class="reference">super</span>.setValue(idx, value);\r
+       <span class="keyword">if</span> (idx == ATTR_CONTENT_TYPE)\r
+           contenttype = <span class="keyword">null</span>;\r
+       <span class="keyword">if</span> (idx == ATTR_CONTENT_LENGTH)\r
+           contentlength = <span class="keyword">null</span>;\r
+       <span class="keyword">if</span> ( idx == ATTR_CONTENT_ENCODING )\r
+           contentencoding = <span class="keyword">null</span>;\r
+       <span class="keyword">if</span> ( idx == ATTR_CONTENT_LANGUAGE )\r
+           contentlanguage = <span class="keyword">null</span>;\r
+       <span class="keyword">if</span> ( idx == ATTR_PUTABLE) {\r
+           <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+               <span class="keyword">if</span> (value == Boolean.TRUE)\r
+                   allowed = _put_allowed;\r
+               <span class="keyword">else</span>\r
+                   allowed = _allowed;\r
+           }\r
+       }\r
+       <span class="keyword">if</span> (idx == ATTR_MD5) {\r
+           md5Digest = <span class="keyword">null</span>; <span class="comment">// reset the digest state\r
+</span>        }\r
+       <span class="comment">// Any attribute setting modifies the last modified time:\r
+</span>        lastmodified = <span class="keyword">null</span>;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get the full URL for that resource.\r
+     * </span><span class="keyword">@return </span><span class="comment">An URL instance.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">URL</span> <span class="function-name">getURL</span>(<span class="type">Request</span> <span class="variable-name">request</span>) {\r
+       <span class="keyword">try</span> {\r
+           <span class="keyword">return</span> <span class="keyword">new</span> <span class="type">URL</span>(request.getURL(), resource.getURLPath());\r
+       } <span class="keyword">catch</span> (<span class="type">MalformedURLException</span> <span class="variable-name">ex</span>) {\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">RuntimeException</span>("<span class="string">unable to build </span>"+\r
+                                      getURLPath()+\r
+                                      "<span class="string"> full URL, from server </span>"+\r
+                                      getServer().getURL());\r
+       }\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this resource quality.\r
+     * </span><span class="keyword">@return </span><span class="comment">The resource quality, or some negative value if not defined.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">double</span> <span class="function-name">getQuality</span>() {\r
+       <span class="keyword">return</span> getDouble(ATTR_QUALITY, -1.0) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this resource title.\r
+     * </span><span class="keyword">@return </span><span class="comment">This resource's title, or &lt;strong&gt;null&lt;/strong&gt; if not \r
+     *    defined.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getTitle</span>() {\r
+       <span class="keyword">return</span> getString(ATTR_TITLE, <span class="keyword">null</span>) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this resource content language.\r
+     * Language are stored as a comma separated String of tokens.\r
+     * </span><span class="keyword">@return </span><span class="comment">A comma separated string of language tokens, or\r
+     *    &lt;strong&gt;null&lt;/strong&gt; if undefined.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getContentLanguage</span>() {\r
+       <span class="keyword">return</span> (<span class="type">String</span>) getValue(ATTR_CONTENT_LANGUAGE, <span class="keyword">null</span>) ;\r
+    } \r
+\r
+    <span class="comment">/**\r
+     * Get this resource content encoding.\r
+     * The content encoding of a resource is stored as a comma separated\r
+     * list of tokens (as decribed in the Content_encoding header of the\r
+     * HTTP specification, and in the order they should appear in the header).\r
+     * </span><span class="keyword">@return </span><span class="comment">A string of comma separated encoding tokens, or\r
+     *    &lt;strong&gt;null&lt;/strong&gt; if not defined.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getContentEncoding</span>() {\r
+       <span class="type">String</span> <span class="variable-name">def</span> = (<span class="type">String</span>) attributes[ATTR_CONTENT_ENCODING].getDefault();\r
+       System.out.println("<span class="string">Default [</span>"+def+"<span class="string">]</span>");\r
+       <span class="type">String</span> <span class="variable-name">s</span> =  (<span class="type">String</span>) getString (ATTR_CONTENT_ENCODING, def) ;\r
+       System.out.println("<span class="string">Defaulted to [</span>"+s+"<span class="string">]</span>");\r
+\r
+       <span class="keyword">return</span> (<span class="type">String</span>) getString (ATTR_CONTENT_ENCODING, def) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this resource content type.\r
+     * </span><span class="keyword">@return </span><span class="comment">An instance of MIMEType, or &lt;strong&gt;null&lt;/strong&gt; if not\r
+     *    defined.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">MimeType</span> <span class="function-name">getContentType</span>() {\r
+       <span class="keyword">return</span> (<span class="type">MimeType</span>) getValue(ATTR_CONTENT_TYPE, <span class="keyword">null</span>);\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this resource content length.\r
+     * </span><span class="keyword">@return </span><span class="comment">The resource content length, or &lt;strong&gt;-1&lt;/strong&gt; if not\r
+     *    defined.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">int</span> <span class="function-name">getContentLength</span>() {\r
+       <span class="keyword">return</span> getInt(ATTR_CONTENT_LENGTH, -1) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this resource's icon.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getIcon</span>() {\r
+       <span class="keyword">return</span> getString(ATTR_ICON, <span class="keyword">null</span>) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this resource's max age.\r
+     * The max age of a resource indicates how much drift is allowed between\r
+     * the physicall version of the resource, and any in-memory cached version\r
+     * of it.\r
+     * &lt;p&gt;The max age attribute is a long number giving the number of \r
+     * milliseconds of allowed drift.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">long</span> <span class="function-name">getMaxAge</span>() {\r
+       <span class="keyword">return</span> getLong(ATTR_MAXAGE, (<span class="type">long</span>) -1) ;\r
+    }\r
+\r
+    <span class="comment">//\r
+</span>    <span class="comment">// Relative to FileResource ...\r
+</span>    <span class="comment">//\r
+</span>\r
+    <span class="comment">/**\r
+     * Does this resource support byte ranges.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">boolean</span> <span class="variable-name">acceptRanges</span> = <span class="keyword">false</span>;\r
+\r
+    <span class="comment">/**\r
+     * Get the PUT'able flag (are we allow to PUT to the resource ?)\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">boolean</span> <span class="function-name">getPutableFlag</span>() {\r
+       <span class="keyword">return</span> getBoolean(ATTR_PUTABLE, <span class="keyword">false</span>) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Do we send the MD5 digest?\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">boolean</span> <span class="function-name">getMD5Flag</span>() {\r
+       <span class="keyword">return</span> getBoolean(ATTR_MD5, <span class="keyword">false</span>) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * handles a Range Request\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment">, the request\r
+     * </span><span class="keyword">@param </span><span class="variable-name">r</span><span class="comment">, the HttpRange\r
+     * </span><span class="keyword">@return </span><span class="comment">a Reply if range is valid, or null if there is a change in the\r
+     * resource, or if the HttpRange is not valid ( 4-2, for example).\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">handleRangeRequest</span>(<span class="type">Request</span> <span class="variable-name">request</span>, <span class="type">HttpRange</span> <span class="variable-name">r</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="comment">// Should we check against a IfRange header ?\r
+</span>        <span class="type">HttpEntityTag</span> <span class="variable-name">t</span> = request.getIfRange();\r
+\r
+       <span class="keyword">if</span> ( t != <span class="keyword">null</span> ) {\r
+           <span class="keyword">if</span> (t.isWeak() || ! t.getTag().equals(etag.getTag()))\r
+               <span class="keyword">return</span> <span class="keyword">null</span>;\r
+       }\r
+       <span class="comment">// Check the range:\r
+</span>        <span class="type">int</span> <span class="variable-name">cl</span> = getContentLength();\r
+       <span class="type">int</span> <span class="variable-name">fb</span> = r.getFirstPosition();\r
+       <span class="type">int</span> <span class="variable-name">lb</span> = r.getLastPosition();\r
+       <span class="type">int</span> <span class="variable-name">sz</span>;\r
+\r
+       <span class="keyword">if</span> (fb > cl-1) { <span class="comment">// first byte already out of range\r
+</span>            <span class="type">HttpContentRange</span> <span class="variable-name">cr</span> = HttpFactory.makeContentRange("<span class="string">bytes</span>", 0,\r
+                                                              cl - 1, cl);\r
+           <span class="type">Reply</span> <span class="variable-name">rr</span>;\r
+           rr = createDefaultReply(request, \r
+                                   HTTP.REQUESTED_RANGE_NOT_SATISFIABLE);\r
+           rr.setContentLength(-1);\r
+           rr.setHeaderValue(rr.H_CONTENT_RANGE, cr);\r
+           <span class="keyword">if</span> (getMD5Flag()) \r
+               rr.setContentMD5(<span class="keyword">null</span>);\r
+           <span class="keyword">return</span> rr;\r
+       }\r
+\r
+       <span class="keyword">if</span> ((fb < 0) && (lb >= 0)) { <span class="comment">// ex: bytes=-20 final 20 bytes\r
+</span>            <span class="keyword">if</span> (lb >= cl)   <span class="comment">// cut the end\r
+</span>                lb = cl;\r
+           sz = lb;\r
+           fb = cl - lb;\r
+           lb = cl - 1;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> (lb < 0) {  <span class="comment">// ex: bytes=10- the last size - 10\r
+</span>            lb = cl-1;\r
+           sz = lb-fb+1;\r
+       } <span class="keyword">else</span> {              <span class="comment">// ex: bytes=10-20\r
+</span>            <span class="keyword">if</span> (lb >= cl)  <span class="comment">// cut the end\r
+</span>                lb = cl-1;\r
+           sz = lb-fb+1;\r
+       }\r
+       <span class="keyword">if</span> ((fb < 0) || (lb < 0) || (fb <= lb)) {\r
+           <span class="type">HttpContentRange</span> <span class="variable-name">cr</span> = <span class="keyword">null</span>;\r
+           fb = (fb < 0) ? 0 : fb;\r
+           lb = ((lb > cl) || (lb < 0)) ? cl : lb;\r
+           cr = HttpFactory.makeContentRange("<span class="string">bytes</span>", fb, lb, cl);\r
+           <span class="comment">// Emit reply:\r
+</span>            <span class="type">Reply</span> <span class="variable-name">rr</span> = createDefaultReply(request, HTTP.PARTIAL_CONTENT);\r
+           <span class="comment">// FIXME check for MD5 of only the subpart\r
+</span>            <span class="keyword">try</span> { <span class="comment">// create the MD5 for the subpart\r
+</span>                <span class="keyword">if</span> (getMD5Flag()) {\r
+                   <span class="type">String</span> <span class="variable-name">s</span> = <span class="keyword">null</span>;\r
+                   <span class="keyword">try</span> {\r
+                       <span class="type">ByteRangeOutputStream</span> <span class="variable-name">br</span>;\r
+                       br = <span class="keyword">new</span> <span class="type">ByteRangeOutputStream</span>(fresource.getFile(),\r
+                                                      fb, lb+1);\r
+                       <span class="type">Md5</span> <span class="variable-name">md5</span> = <span class="keyword">new</span> <span class="type">Md5</span> (br);\r
+                       <span class="type">byte</span> <span class="variable-name">b</span>[] = md5.getDigest();\r
+                       <span class="type">Base64Encoder</span> <span class="variable-name">b64</span>;\r
+                       <span class="type">ByteArrayOutputStream</span> <span class="variable-name">bs</span> = <span class="keyword">new</span> <span class="type">ByteArrayOutputStream</span>();\r
+                       b64 = <span class="keyword">new</span> <span class="type">Base64Encoder</span>(<span class="keyword">new</span> <span class="type">ByteArrayInputStream</span>(b),\r
+                                               bs);\r
+                       b64.process();\r
+                       s = bs.toString();\r
+                   } <span class="keyword">catch</span> (<span class="type">Exception</span> <span class="variable-name">md_ex</span>) {\r
+                       <span class="comment">// default to null, no action here then\r
+</span>                    }\r
+                   <span class="keyword">if</span> (s == <span class="keyword">null</span>)\r
+                       rr.setContentMD5(<span class="keyword">null</span>); \r
+                   <span class="keyword">else</span> \r
+                       rr.setContentMD5(s);\r
+               }\r
+               rr.setContentLength(sz);\r
+               rr.setHeaderValue(rr.H_CONTENT_RANGE, cr);\r
+               rr.setStream(<span class="keyword">new</span> <span class="type">ByteRangeOutputStream</span>(fresource.getFile(),\r
+                                                      fb,\r
+                                                      lb+1));\r
+               <span class="keyword">return</span> rr;\r
+           } <span class="keyword">catch</span> (<span class="type">IOException</span> <span class="variable-name">ex</span>) {\r
+           }\r
+       } \r
+       <span class="keyword">return</span> <span class="keyword">null</span>;\r
+    }\r
+\r
+    <span class="comment">//\r
+</span>    <span class="comment">// Relative to DirectoryResource ...\r
+</span>    <span class="comment">//\r
+</span>\r
+    <span class="comment">/**\r
+     * Get this class browsable flag.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">boolean</span> <span class="function-name">getBrowsableFlag</span>() {\r
+       <span class="keyword">return</span> getBoolean (ATTR_BROWSABLE, <span class="keyword">false</span>) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get this frame style sheet link\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getStyleSheetURL</span>() {\r
+       <span class="keyword">return</span> getString (ATTR_STYLE_LINK, <span class="keyword">null</span>);\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Our current (cached) directory listing.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">HtmlGenerator</span> <span class="variable-name">listing</span> = <span class="keyword">null</span> ;\r
+    <span class="comment">/**\r
+     * The time at which we generated the directory index.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">long</span> <span class="variable-name">listing_stamp</span> = -1 ;\r
+\r
+    <span class="string">private</span> <span class="type">String</span> <span class="function-name">getUnextendedName</span>(<span class="type">String</span> <span class="variable-name">name</span>) {\r
+       <span class="type">int</span> <span class="variable-name">strlen</span> = name.length() ;\r
+       <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < strlen ; i++) {\r
+           <span class="comment">// FIXME: Should use the system props to get the right sep\r
+</span>            <span class="keyword">if</span> ( name.charAt(i) == '<span class="string">.</span>' ) {\r
+               <span class="keyword">if</span> ( i == 0 )\r
+                   <span class="keyword">return</span> <span class="keyword">null</span> ;\r
+               <span class="keyword">return</span> name.substring(0, i) ;\r
+           }\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">null</span> ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get the optional icon directory.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getIconDirectory</span>() { \r
+       <span class="keyword">return</span> getString(ATTR_ICONDIR, "<span class="string">/icons</span>") ;\r
+    }\r
+\r
+\r
+\r
+    <span class="comment">/**\r
+     * Should we relocate invalid requests to this directory.\r
+     * </span><span class="keyword">@return </span><span class="comment">A boolean &lt;strong&gt;true&lt;/strong&gt; if we should relocate.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">boolean</span> <span class="function-name">getRelocateFlag</span>() {\r
+       <span class="keyword">return</span> getBoolean(ATTR_RELOCATE, <span class="keyword">true</span>) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get the optinal index name for this directory listing.\r
+     * </span><span class="keyword">@return </span><span class="comment">The name of the resource responsible to list that container.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">String</span> <span class="function-name">getIndex</span>() {\r
+       <span class="keyword">return</span> (<span class="type">String</span>) getValue(ATTR_INDEX, <span class="keyword">null</span>) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Add our own Style Sheet to the HtmlGenerator.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">g</span><span class="comment"> The HtmlGenerator.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">void</span> <span class="function-name">addStyleSheet</span>(<span class="type">HtmlGenerator</span> <span class="variable-name">g</span>) {\r
+       <span class="comment">// Add style link\r
+</span>        <span class="type">String</span> <span class="variable-name">css_url</span> = getStyleSheetURL();\r
+       <span class="keyword">if</span> (css_url != <span class="keyword">null</span>) {\r
+           g.addLink( <span class="keyword">new</span> <span class="type">HtmlLink</span>("<span class="string">STYLESHEET</span>", \r
+                                   css_url, \r
+                                   MimeType.TEXT_CSS));\r
+       }\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Reply with an HTML doc listing the resources of this directory.\r
+     * This function takes special care not to regenerate a directory listing\r
+     * when one is available. It also caches the date of the directory \r
+     * listing, so that it can win big with NOT_MODIFIED.\r
+     * &lt;p&gt;Using a modem, I know that each place I can reply with an \r
+     * NOT_MODIFIED, &lt;strong&gt;is&lt;/strong&gt; a big win.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> If processsing the request failed.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">synchronized</span> <span class="type">Reply</span> <span class="function-name">getDirectoryListing</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (dresource == <span class="keyword">null</span>) \r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">NotAProtocolException</span>("<span class="string">this frame is not attached to a </span>"+\r
+                                           "<span class="string">DirectoryResource. (</span>"+\r
+                                           resource.getIdentifier()+"<span class="string">)</span>");\r
+       <span class="comment">// delete us if the directory was deleted\r
+</span>        <span class="keyword">if</span> (! dresource.getDirectory().exists()) {\r
+           <span class="comment">//delete us and emit an error\r
+</span>            <span class="type">String</span> <span class="variable-name">msg</span> = dresource.getIdentifier()+\r
+               "<span class="string">: deleted, removing the DirectoryResource</span>";\r
+           getServer().errlog(dresource, msg);\r
+           <span class="keyword">try</span> {\r
+               dresource.delete();\r
+           } <span class="keyword">catch</span> (<span class="type">MultipleLockException</span> <span class="variable-name">ex</span>) {\r
+           }\r
+           <span class="comment">// Emit an error back:\r
+</span>            <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_FOUND) ;\r
+           error.setContent ("<span class="string">&lt;h1&gt;Document not found&lt;/h1&gt;</span>"+\r
+                             "<span class="string">&lt;p&gt;The document </span>"+\r
+                             request.getURL()+\r
+                             "<span class="string"> is indexed but not available.</span>"+\r
+                             "<span class="string">&lt;p&gt;The server is misconfigured.</span>") ;\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+       }\r
+       <span class="comment">// Have we already an up-to-date computed a listing ?\r
+</span>        <span class="keyword">if</span> ((listing == <span class="keyword">null</span>) \r
+           || (dresource.getDirectory().lastModified() > listing_stamp)\r
+           || (dresource.getLastModified() > listing_stamp)\r
+           || (getLastModified() > listing_stamp)) {\r
+      \r
+           <span class="type">Class</span> <span class="variable-name">http_class</span> = <span class="keyword">null</span>;\r
+           <span class="keyword">try</span> {\r
+               http_class = Class.forName("<span class="string">org.w3c.jigsaw.frames.HTTPFrame</span>");\r
+           } <span class="keyword">catch</span> (<span class="type">ClassNotFoundException</span> <span class="variable-name">ex</span>) {\r
+               http_class = <span class="keyword">null</span>;\r
+           }\r
+\r
+           <span class="type">Enumeration</span>   <span class="variable-name">enum</span>      = \r
+               dresource.enumerateResourceIdentifiers() ;\r
+           <span class="type">Vector</span>        <span class="variable-name">resources</span> = Sorter.sortStringEnumeration(enum) ;\r
+           <span class="type">HtmlGenerator</span> <span class="variable-name">g</span>         = \r
+               <span class="keyword">new</span> <span class="type">HtmlGenerator</span>("<span class="string">Directory of </span>"+\r
+                                 dresource.getIdentifier());\r
+           <span class="comment">// Add style link\r
+</span>            addStyleSheet(g);\r
+           g.append("<span class="string">&lt;h1&gt;</span>"+dresource.getIdentifier()+"<span class="string">&lt;/h1&gt;</span>");\r
+           <span class="comment">// Link to the parent, when possible:\r
+</span>            <span class="keyword">if</span> ( dresource.getParent() != <span class="keyword">null</span> )\r
+               g.append("<span class="string">&lt;p&gt;&lt;a href=\"..\"&gt;Parent&lt;/a&gt;&lt;br&gt;</span>");\r
+           <span class="comment">// List the children:\r
+</span>            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < resources.size() ; i++) {\r
+               <span class="type">String</span>       <span class="variable-name">name</span>     = (<span class="type">String</span>) resources.elementAt(i);\r
+               <span class="type">ResourceReference</span> <span class="variable-name">rr</span> = <span class="keyword">null</span>;\r
+               rr = dresource.lookup(name);\r
+               <span class="type">FramedResource</span> <span class="variable-name">resource</span> = <span class="keyword">null</span>;\r
+               <span class="keyword">if</span> (rr != <span class="keyword">null</span>) {\r
+                   <span class="keyword">try</span> {\r
+                       resource = (<span class="type">FramedResource</span>) rr.lock();\r
+                       <span class="type">HTTPFrame</span> <span class="variable-name">itsframe</span> = <span class="keyword">null</span>;\r
+                       <span class="keyword">if</span> (http_class != <span class="keyword">null</span>)\r
+                           itsframe = \r
+                               (<span class="type">HTTPFrame</span>) resource.getFrame(http_class);\r
+                       <span class="keyword">if</span> (itsframe != <span class="keyword">null</span>) {\r
+                           <span class="comment">// Icon first, if available\r
+</span>                            <span class="type">String</span> <span class="variable-name">icon</span> = itsframe.getIcon() ;\r
+                           <span class="keyword">if</span> ( icon != <span class="keyword">null</span> ) \r
+                               g.append("<span class="string">&lt;img src=\"</span>"+\r
+                                        getIconDirectory() +"<span class="string">/</span>" + icon+\r
+                                        "<span class="string">\"&gt;</span>");\r
+                           <span class="comment">// Resource's name with link:\r
+</span>                            g.append("<span class="string">&lt;a href=\"</span>" \r
+                                    , resource.getURLPath()\r
+                                    , "<span class="string">\"&gt;</span>"+name+"<span class="string">&lt;/a&gt;</span>");\r
+                           <span class="comment">// resource's title, if any:\r
+</span>                            <span class="type">String</span> <span class="variable-name">title</span> = itsframe.getTitle();\r
+                           <span class="keyword">if</span> ( title != <span class="keyword">null</span> )\r
+                               g.append("<span class="string"> </span>"+title);\r
+                           g.append("<span class="string">&lt;br&gt;</span>");\r
+                       } <span class="keyword">else</span> {\r
+                           <span class="comment">// Resource's name with link:\r
+</span>                            g.append(name+"<span class="string"> (&lt;i&gt;Not available via HTTP.&lt;/i&gt;)</span>");\r
+                           g.append("<span class="string">&lt;br&gt;</span>");\r
+                       }\r
+                   } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+                       g.append(name+\r
+                                "<span class="string"> cannot be loaded (server misconfigured)</span>");\r
+                       g.append("<span class="string">&lt;br&gt;</span>");\r
+                       <span class="keyword">continue</span>;\r
+                   } <span class="keyword">finally</span> { \r
+                       rr.unlock();\r
+                   }\r
+               }\r
+           }\r
+           g.close() ;\r
+           listing_stamp = getLastModified() ;\r
+           listing       = g ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( checkIfModifiedSince(request) == COND_FAILED ) {\r
+           <span class="comment">// Is it an IMS request ?\r
+</span>            <span class="type">Reply</span> <span class="variable-name">reply</span> = createDefaultReply(request, HTTP.NOT_MODIFIED) ;\r
+           reply.setContentMD5(<span class="keyword">null</span>);\r
+           <span class="keyword">return</span> reply;\r
+       }\r
+       <span class="comment">// New content or need update:\r
+</span>        <span class="type">Reply</span> <span class="variable-name">reply</span> = createDefaultReply(request, HTTP.OK) ;\r
+       reply.setLastModified(listing_stamp) ;\r
+       reply.setStream(listing) ;\r
+       <span class="comment">// check MD5\r
+</span>        <span class="keyword">return</span> reply ;\r
+    }\r
+\r
+    <span class="comment">//\r
+</span>    <span class="comment">// Commom part.\r
+</span>    <span class="comment">//\r
+</span>\r
+\r
+\r
+    <span class="comment">/**\r
+     * Update the cached headers value.\r
+     * Each resource maintains a set of cached values for headers, this\r
+     * allows for a nice sped-up in headers marshalling, which - as the \r
+     * complexity of the protocol increases - becomes a bottleneck.\r
+     */</span>\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">void</span> <span class="function-name">updateCachedHeaders</span>() {\r
+       <span class="comment">// Precompute a set of header values to keep by:\r
+</span>        <span class="keyword">if</span> ( contenttype == <span class="keyword">null</span> )\r
+           contenttype = HttpFactory.makeMimeType(getContentType());\r
+       <span class="keyword">if</span> (contentlength == <span class="keyword">null</span>) {\r
+           <span class="type">int</span> <span class="variable-name">cl</span> = -1;\r
+           <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) \r
+               cl = fresource.getFileLength();\r
+           <span class="keyword">if</span> ( cl >= 0 ) {\r
+               setValue(ATTR_CONTENT_LENGTH, <span class="keyword">new</span> <span class="type">Integer</span>(cl));\r
+               contentlength = HttpFactory.makeInteger(cl);\r
+           }\r
+       }\r
+       <span class="keyword">if</span> ( lastmodified == <span class="keyword">null</span> ) {\r
+           <span class="type">long</span> <span class="variable-name">lm</span> = getLastModified();\r
+           <span class="keyword">if</span> ( lm > 0 )\r
+               lastmodified = HttpFactory.makeDate(getLastModified());\r
+       }\r
+       <span class="keyword">if</span> (definesAttribute(ATTR_CONTENT_ENCODING) &&(contentencoding==<span class="keyword">null</span>))\r
+           contentencoding = HttpFactory.makeStringList(getContentEncoding());\r
+       <span class="keyword">if</span> (definesAttribute(ATTR_CONTENT_LANGUAGE) &&(contentlanguage==<span class="keyword">null</span>))\r
+           contentlanguage = HttpFactory.makeStringList(getContentLanguage());\r
+\r
+       <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="comment">// We only take car eof etag here:\r
+</span>            <span class="keyword">if</span> ( etag == <span class="keyword">null</span> ) {\r
+               <span class="type">long</span> <span class="variable-name">lstamp</span> = fresource.getFileStamp();\r
+               <span class="keyword">if</span> ( lstamp >= 0L ) {\r
+                   <span class="type">String</span> <span class="variable-name">soid</span>  = Integer.toString(getOid(), 32);\r
+                   <span class="type">String</span> <span class="variable-name">stamp</span> = Long.toString(lstamp, 32);\r
+                   etag = HttpFactory.makeETag(<span class="keyword">false</span>, soid+"<span class="string">:</span>"+stamp);\r
+               }\r
+           }\r
+           <span class="keyword">if</span> (getMD5Flag() && (md5Digest == <span class="keyword">null</span>)) {\r
+               getMd5Digest();\r
+           }\r
+       }\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Create a reply to answer to request on this file.\r
+     * This method will create a suitable reply (matching the given request)\r
+     * and will set all its default header values to the appropriate \r
+     * values.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to make a reply for.\r
+     * </span><span class="keyword">@return </span><span class="comment">An instance of Reply, suited to answer this request.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">createDefaultReply</span>(<span class="type">Request</span> <span class="variable-name">request</span>, <span class="type">int</span> <span class="variable-name">status</span>) {\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = request.makeReply(status);\r
+       updateCachedHeaders();\r
+       <span class="keyword">if</span> ( status != HTTP.NOT_MODIFIED ) {\r
+           <span class="keyword">if</span> ( contentlength != <span class="keyword">null</span> )\r
+               reply.setHeaderValue(Reply.H_CONTENT_LENGTH, contentlength);\r
+           <span class="keyword">if</span> ( contenttype != <span class="keyword">null</span> )\r
+               reply.setHeaderValue(Reply.H_CONTENT_TYPE, contenttype);\r
+           <span class="keyword">if</span> ( lastmodified != <span class="keyword">null</span> )\r
+               reply.setHeaderValue(Reply.H_LAST_MODIFIED, lastmodified);\r
+           <span class="keyword">if</span> ( contentencoding != <span class="keyword">null</span> ) {\r
+System.out.println("<span class="string">Content Encoding [</span>" + contentencoding +"<span class="string">]</span>");\r
+               reply.setHeaderValue(Reply.H_CONTENT_ENCODING,contentencoding);\r
+           }\r
+           <span class="keyword">if</span> ( contentlanguage != <span class="keyword">null</span> )\r
+               reply.setHeaderValue(Reply.H_CONTENT_LANGUAGE,contentlanguage);\r
+      \r
+       }\r
+       <span class="type">long</span> <span class="variable-name">maxage</span> = getMaxAge();\r
+       <span class="keyword">if</span> ( maxage >= 0 ) {\r
+           <span class="keyword">if</span> (reply.getMajorVersion() >= 1 ) {\r
+               <span class="keyword">if</span> (reply.getMinorVersion() >= 1) {\r
+                   reply.setMaxAge((<span class="type">int</span>) (maxage / 1000));\r
+               } \r
+               <span class="comment">// If max-age is zero, say what you mean:\r
+</span>                <span class="type">long</span> <span class="variable-name">expires</span> = (System.currentTimeMillis()\r
+                               + ((maxage == 0) ? -1000 : maxage));\r
+               reply.setExpires(expires);\r
+           }\r
+       }\r
+       <span class="comment">// Set the date of the reply (round it to secs):\r
+</span>        reply.setDate((System.currentTimeMillis() / 1000L) * 1000L);\r
+    \r
+       <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="comment">// Set the entity tag:\r
+</span>            <span class="keyword">if</span> ( etag != <span class="keyword">null</span> )\r
+               reply.setHeaderValue(reply.H_ETAG, etag);\r
+           <span class="keyword">if</span> ( acceptRanges )\r
+               reply.setHeaderValue(reply.H_ACCEPT_RANGES, _accept_ranges);\r
+           <span class="keyword">if</span> ( getMD5Flag()) {\r
+               reply.setHeaderValue(reply.H_CONTENT_MD5, getMd5Digest());\r
+           }\r
+       }\r
+\r
+       <span class="keyword">return</span> reply;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Check the &lt;code&gt;If-Match&lt;/code&gt; condition of that request.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to check.\r
+     * </span><span class="keyword">@return </span><span class="comment">An integer, either &lt;code&gt;COND_FAILED&lt;/cond&gt; if condition\r
+     * was checked, but failed, &lt;code&gt;COND_OK&lt;/code&gt; if condition was checked\r
+     * and succeeded, or &lt;strong&gt;0&lt;/strong&gt; if the condition was not checked\r
+     * at all (eg because the resource or the request didn't support it).\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">int</span> <span class="function-name">checkIfMatch</span>(<span class="type">Request</span> <span class="variable-name">request</span>) {\r
+       <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="type">HttpEntityTag</span> <span class="variable-name">tags</span>[] = request.getIfMatch();\r
+           <span class="keyword">if</span> ( tags != <span class="keyword">null</span> ) {\r
+               <span class="comment">// Good, real validators in use:\r
+</span>                <span class="keyword">if</span> ( etag != <span class="keyword">null</span> ) {\r
+                   <span class="comment">// Note: if etag is null this means that the resource has \r
+</span>                    <span class="comment">// changed and has not been even emited since then...\r
+</span>                    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < tags.length ; i++) {\r
+                       <span class="type">HttpEntityTag</span> <span class="variable-name">t</span> = tags[i];\r
+                       <span class="keyword">if</span> ((!t.isWeak()) && t.getTag().equals(etag.getTag()))\r
+                           <span class="keyword">return</span> COND_OK;\r
+                   }\r
+               }\r
+               <span class="keyword">return</span> COND_FAILED;\r
+           }\r
+       }\r
+       <span class="keyword">return</span> 0;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Check the &lt;code&gt;If-None-Match&lt;/code&gt; condition of that request.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to check.\r
+     * </span><span class="keyword">@return </span><span class="comment">An integer, either &lt;code&gt;COND_FAILED&lt;/cond&gt; if condition\r
+     * was checked, but failed, &lt;code&gt;COND_OK&lt;/code&gt; if condition was checked\r
+     * and succeeded, or &lt;strong&gt;0&lt;/strong&gt; if the condition was not checked\r
+     * at all (eg because the resource or the request didn't support it).\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">int</span> <span class="function-name">checkIfNoneMatch</span>(<span class="type">Request</span> <span class="variable-name">request</span>) {\r
+       <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="comment">// Check for an If-None-Match conditional:\r
+</span>            <span class="type">HttpEntityTag</span> <span class="variable-name">tags</span>[] = request.getIfNoneMatch();\r
+           <span class="keyword">if</span> ( tags != <span class="keyword">null</span> ) {\r
+               <span class="keyword">if</span> ( etag == <span class="keyword">null</span> )\r
+                   <span class="keyword">return</span> COND_OK;\r
+               <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < tags.length ; i++) {\r
+                   <span class="type">HttpEntityTag</span> <span class="variable-name">t</span> = tags[i];\r
+                   <span class="keyword">if</span> (( ! t.isWeak()) && t.getTag().equals(etag.getTag()))\r
+                       <span class="keyword">return</span> COND_FAILED;\r
+               }\r
+               <span class="keyword">return</span> COND_OK;\r
+           }\r
+       }\r
+       <span class="keyword">return</span> 0;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Check the &lt;code&gt;If-Modified-Since&lt;/code&gt; condition of that request.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to check.\r
+     * </span><span class="keyword">@return </span><span class="comment">An integer, either &lt;code&gt;COND_FAILED&lt;/cond&gt; if condition\r
+     * was checked, but failed, &lt;code&gt;COND_OK&lt;/code&gt; if condition was checked\r
+     * and succeeded, or &lt;strong&gt;0&lt;/strong&gt; if the condition was not checked\r
+     * at all (eg because the resource or the request didn't support it).\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">int</span> <span class="function-name">checkIfModifiedSince</span>(<span class="type">Request</span> <span class="variable-name">request</span>) {\r
+       <span class="comment">// Check for an If-Modified-Since conditional:\r
+</span>        <span class="type">long</span> <span class="variable-name">ims</span> = request.getIfModifiedSince();\r
+       <span class="keyword">if</span> (dresource != <span class="keyword">null</span>) {\r
+           <span class="keyword">if</span> (ims >= 0) \r
+               <span class="keyword">return</span> (((listing_stamp > 0) && (listing_stamp - 1000 <= ims))\r
+                       ? <span class="type">COND_FAILED</span>\r
+                       : COND_OK);\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="type">long</span> <span class="variable-name">cmt</span> = getLastModified();\r
+           <span class="keyword">if</span> ( ims >= 0 )\r
+               <span class="keyword">return</span> ((cmt > 0) && (cmt - 1000 <= ims)) \r
+                   ? COND_FAILED : COND_OK;\r
+       }\r
+       <span class="keyword">return</span> 0;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Check the &lt;code&gt;If-Unmodified-Since&lt;/code&gt; condition of that request.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to check.\r
+     * </span><span class="keyword">@return </span><span class="comment">An integer, either &lt;code&gt;COND_FAILED&lt;/cond&gt; if condition\r
+     * was checked, but failed, &lt;code&gt;COND_OK&lt;/code&gt; if condition was checked\r
+     * and succeeded, or &lt;strong&gt;0&lt;/strong&gt; if the condition was not checked\r
+     * at all (eg because the resource or the request didn't support it).\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">int</span> <span class="function-name">checkIfUnmodifiedSince</span>(<span class="type">Request</span> <span class="variable-name">request</span>) {\r
+       <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="comment">// Check for an If-Unmodified-Since conditional:\r
+</span>            <span class="type">long</span> <span class="variable-name">iums</span> = request.getIfUnmodifiedSince();\r
+           <span class="type">long</span> <span class="variable-name">cmt</span> = getLastModified();\r
+           <span class="keyword">if</span> ( iums >= 0 ) \r
+               <span class="keyword">return</span> ((cmt > 0) && (cmt - 1000) >= iums) \r
+                   ? COND_FAILED : COND_OK;\r
+       }\r
+       <span class="keyword">return</span> 0;\r
+    }\r
+\r
+    <span class="reference">public</span> <span class="type">boolean</span> <span class="function-name">lookup</span>(<span class="type">LookupState</span> <span class="variable-name">ls</span>, <span class="type">LookupResult</span> <span class="variable-name">lr</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="type">RequestInterface</span> <span class="variable-name">req</span> = ls.getRequest(); \r
+       <span class="keyword">if</span> (! checkRequest(req)) \r
+           <span class="keyword">return</span> <span class="keyword">false</span>;\r
+       <span class="keyword">if</span> (lookupFilters(ls,lr))\r
+           <span class="keyword">return</span> <span class="keyword">true</span>;\r
+       <span class="keyword">return</span> lookupResource(ls,lr);\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">boolean</span> <span class="function-name">lookupResource</span>(<span class="type">LookupState</span> <span class="variable-name">ls</span>, <span class="type">LookupResult</span> <span class="variable-name">lr</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="keyword">return</span> lookupFile(ls,lr);\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> (dresource != <span class="keyword">null</span>) {\r
+           <span class="keyword">return</span> lookupDirectory(ls,lr);\r
+       } <span class="keyword">else</span> {\r
+           <span class="keyword">return</span> lookupOther(ls,lr);\r
+       }\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">boolean</span> <span class="function-name">lookupFilters</span>(<span class="type">LookupState</span> <span class="variable-name">ls</span>, <span class="type">LookupResult</span> <span class="variable-name">lr</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="type">ResourceFilter</span> <span class="variable-name">filters</span>[] = getFilters();\r
+       <span class="keyword">if</span> ( filters != <span class="keyword">null</span> ) {\r
+           <span class="comment">// Mark filters, for them to be called at outgoing time:\r
+</span>            lr.addFilters(filters);\r
+           <span class="comment">// Some clever filter around ?\r
+</span>            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < filters.length ; i++) {\r
+               <span class="keyword">if</span> ( filters[i] == <span class="keyword">null</span> )\r
+                   <span class="keyword">continue</span>;\r
+               <span class="keyword">if</span> ( filters[i].lookup(ls, lr) )\r
+                   <span class="keyword">return</span> <span class="keyword">true</span>;\r
+           }\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">false</span>;\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">boolean</span> <span class="function-name">lookupDirectory</span>(<span class="type">LookupState</span> <span class="variable-name">ls</span>, <span class="type">LookupResult</span> <span class="variable-name">lr</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="comment">// Give a chance to our super-class to run its own lookup scheme:\r
+</span>        <span class="comment">// do we have to create a resource (PUT) ?\r
+</span>        <span class="keyword">if</span> ((ls.hasMoreComponents()) && getPutableFlag()) {\r
+           <span class="type">Request</span> <span class="variable-name">request</span> = (<span class="type">Request</span>) ls.getRequest() ;\r
+           <span class="keyword">if</span> ((request == <span class="keyword">null</span>) || request.getMethod().equals("<span class="string">PUT</span>")) {\r
+               <span class="comment">// We might well want to create a resource:\r
+</span>                <span class="type">String</span>            <span class="variable-name">name</span> = ls.peekNextComponent() ;\r
+               <span class="type">ResourceReference</span> <span class="variable-name">rr</span>   = dresource.lookup(name);\r
+               <span class="keyword">if</span> ((rr == <span class="keyword">null</span>) && (dresource.getExtensibleFlag())) {\r
+                   <span class="keyword">if</span> (ls.countRemainingComponents() == 1)\r
+                       rr = dresource.createResource(name, request);\r
+                   <span class="keyword">else</span>\r
+                       rr = dresource.createDirectoryResource(name);\r
+                   <span class="keyword">if</span> (rr == <span class="keyword">null</span>) {\r
+                       <span class="type">Reply</span> <span class="variable-name">error</span> = \r
+                           request.makeReply(HTTP.UNSUPPORTED_MEDIA_TYPE);\r
+                       error.setContent(\r
+                           "<span class="string">Failed to create resource </span>"+\r
+                           name +"<span class="string"> : </span>"+\r
+                           "<span class="string">Unable to create the appropriate file:</span>"+\r
+                           request.getURLPath()+\r
+                           "<span class="string"> this media type is not supported</span>");\r
+                       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error);\r
+                   }\r
+               } <span class="keyword">else</span> <span class="keyword">if</span> (rr == <span class="keyword">null</span>) {\r
+                   <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.FORBIDDEN) ;\r
+                   error.setContent("<span class="string">You are not allowed to create resource </span>"+\r
+                                    name +"<span class="string"> : </span>"+\r
+                                    dresource.getIdentifier()+\r
+                                    "<span class="string"> is not extensible.</span>");\r
+                   <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error);\r
+               }\r
+           }\r
+       }\r
+       <span class="keyword">if</span> ( <span class="reference">super</span>.lookup(ls, lr) ) {\r
+           <span class="keyword">if</span> ( ! ls.isDirectory() && ! ls.isInternal() ) {\r
+               <span class="comment">// The directory lookup URL doesn't end with a slash:\r
+</span>                <span class="type">Request</span> <span class="variable-name">request</span> = (<span class="type">Request</span>)ls.getRequest() ;\r
+               <span class="keyword">if</span> ( request == <span class="keyword">null</span> ) {\r
+                   lr.setTarget(<span class="keyword">null</span>);\r
+                   <span class="keyword">return</span> <span class="keyword">true</span>;\r
+               }\r
+               <span class="type">URL</span> <span class="variable-name">url</span> = <span class="keyword">null</span>;\r
+               <span class="keyword">try</span> {\r
+                   url = (ls.hasRequest() \r
+                          ? getURL(request)\r
+                          : <span class="keyword">new</span> <span class="type">URL</span>(getServer().getURL(), \r
+                                    resource.getURLPath()));\r
+               } <span class="keyword">catch</span> (<span class="type">MalformedURLException</span> <span class="variable-name">ex</span>) {\r
+                   getServer().errlog(<span class="reference">this</span>, "<span class="string">unable to build full URL.</span>");\r
+                   <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span>("<span class="string">Internal server error</span>");\r
+               }\r
+               <span class="type">String</span> <span class="variable-name">msg</span> = "<span class="string">Invalid requested URL: the directory resource </span>"+\r
+                   "<span class="string"> you are trying to reach is available only through </span>"+\r
+                   "<span class="string"> its full URL: &lt;a href=\"</span>"+\r
+                   url + "<span class="string">\"&gt;</span>" + url + "<span class="string">&lt;/a&gt;.</span>";\r
+               <span class="keyword">if</span> ( getRelocateFlag() ) {\r
+                   <span class="comment">// Emit an error (with reloc if allowed)\r
+</span>                    <span class="type">Reply</span> <span class="variable-name">reloc</span> = request.makeReply(HTTP.FOUND);\r
+                   reloc.setContent(msg) ;\r
+                   reloc.setLocation(url);\r
+                   lr.setTarget(<span class="keyword">null</span>);\r
+                   lr.setReply(reloc);\r
+                   <span class="keyword">return</span> <span class="keyword">true</span>;\r
+               } <span class="keyword">else</span> {\r
+                   <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_FOUND) ;\r
+                   error.setContent(msg) ;\r
+                   lr.setTarget(<span class="keyword">null</span>);\r
+                   lr.setReply(error);\r
+                   <span class="keyword">return</span> <span class="keyword">true</span>;\r
+               }\r
+           } <span class="keyword">else</span> <span class="keyword">if</span> ( ! ls.isInternal() ) {\r
+               <span class="comment">// return the index file.\r
+</span>                <span class="type">String</span> <span class="variable-name">index</span> = getIndex();\r
+               <span class="keyword">if</span> ( index != <span class="keyword">null</span> && index.length() > 0) {\r
+                   <span class="type">DirectoryResource</span> <span class="variable-name">dir</span> = (<span class="type">DirectoryResource</span>) resource;\r
+                   <span class="type">ResourceReference</span> <span class="variable-name">rr</span> = dir.lookup(index);\r
+                   <span class="keyword">if</span> (rr != <span class="keyword">null</span>) {\r
+                       <span class="keyword">try</span> {\r
+                           <span class="type">FramedResource</span> <span class="variable-name">rindex</span> = (<span class="type">FramedResource</span>) rr.lock();\r
+                           <span class="keyword">return</span> rindex.lookup(ls,lr);\r
+                       } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+                       } <span class="keyword">finally</span> {\r
+                           rr.unlock();\r
+                       }\r
+                   }\r
+               }\r
+           }\r
+           <span class="keyword">return</span> <span class="keyword">true</span>;\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">false</span>;\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">boolean</span> <span class="function-name">lookupFile</span>(<span class="type">LookupState</span> <span class="variable-name">ls</span>, <span class="type">LookupResult</span> <span class="variable-name">lr</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="keyword">return</span> <span class="reference">super</span>.lookup(ls,lr);\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">boolean</span> <span class="function-name">lookupOther</span>(<span class="type">LookupState</span> <span class="variable-name">ls</span>, <span class="type">LookupResult</span> <span class="variable-name">lr</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="keyword">return</span> <span class="reference">super</span>.lookup(ls,lr);\r
+    }\r
+\r
+    <span class="reference">public</span> <span class="type">boolean</span> <span class="function-name">checkRequest</span>(<span class="type">RequestInterface</span> <span class="variable-name">request</span>) {\r
+       <span class="keyword">return</span> ((request == <span class="keyword">null</span>) \r
+               ? <span class="keyword">true</span> \r
+               :(request <span class="keyword">instanceof</span> <span class="reference">org</span>.<span class="reference">w3c</span>.<span class="reference">jigsaw</span>.<span class="reference">http</span>.<span class="type">Request</span>));\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">ReplyInterface</span> <span class="function-name">performFrames</span>(<span class="type">RequestInterface</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">return</span> <span class="reference">super</span>.performFrames(request);\r
+    }\r
+\r
+    <span class="reference">public</span> <span class="type">ReplyInterface</span> <span class="function-name">perform</span>(<span class="type">RequestInterface</span> <span class="variable-name">req</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">ReplyInterface</span> <span class="variable-name">repi</span> = <span class="reference">super</span>.perform(req);\r
+       <span class="keyword">if</span> (repi != <span class="keyword">null</span>)\r
+           <span class="keyword">return</span> repi;\r
+\r
+       <span class="keyword">if</span> (! checkRequest(req))\r
+           <span class="keyword">return</span> <span class="keyword">null</span>;\r
+\r
+       <span class="type">Reply</span>  <span class="variable-name">reply</span>  = <span class="keyword">null</span>;\r
+       <span class="type">Request</span> <span class="variable-name">request</span> = (<span class="type">Request</span>) req;\r
+       <span class="type">String</span> <span class="variable-name">method</span> = request.getMethod () ;\r
+       <span class="comment">// Perform the request:\r
+</span>        <span class="keyword">if</span> ( method.equals("<span class="string">GET</span>") ) {\r
+           reply = get(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">HEAD</span>") ) {\r
+           reply = head(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">POST</span>") ) {\r
+           reply = post(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">PUT</span>") ) {\r
+           reply = put(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">OPTIONS</span>") ) {\r
+           reply = options(request);\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">DELETE</span>") ) {\r
+           reply = delete(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">LINK</span>") ) {\r
+           reply = link(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">UNLINK</span>") ) {\r
+           reply = unlink(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( method.equals("<span class="string">TRACE</span>") ) {\r
+           reply = trace(request) ;\r
+       } <span class="keyword">else</span> {\r
+           reply = extended(request) ;\r
+       }\r
+       <span class="keyword">return</span> reply;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default GET method.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> if processing the request failed.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">get</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (dresource != <span class="keyword">null</span>) {\r
+           <span class="comment">// we manage a DirectoryResource\r
+</span>            <span class="keyword">return</span> getDirectoryResource(request) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="comment">// we manage a FileResource\r
+</span>            <span class="keyword">return</span> getFileResource(request);\r
+       } <span class="keyword">else</span> {\r
+           <span class="keyword">return</span> getOtherResource(request);\r
+       }\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">getOtherResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="comment">// we don't manage this kind of resource\r
+</span>        <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+       error.setContent("<span class="string">Method GET not implemented.</span>") ;\r
+       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Create the reply relative to the given file.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> the incomming request.\r
+     * </span><span class="keyword">@return </span><span class="comment">A Reply instance\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">createFileReply</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">File</span> <span class="variable-name">file</span> = fresource.getFile() ;\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = <span class="keyword">null</span>;\r
+       <span class="comment">// Check for a range request:\r
+</span>        <span class="type">HttpRange</span> <span class="variable-name">ranges</span>[] = request.getRange();\r
+       <span class="keyword">if</span> ((ranges != <span class="keyword">null</span>) && (ranges.length == 1)) {\r
+           <span class="type">Reply</span> <span class="variable-name">rangereply</span> = handleRangeRequest(request, ranges[0]);\r
+           <span class="keyword">if</span> ( rangereply != <span class="keyword">null</span> )\r
+               <span class="keyword">return</span> rangereply;\r
+       }\r
+       <span class="comment">// Default to full reply:\r
+</span>        reply = createDefaultReply(request, HTTP.OK) ;\r
+       <span class="keyword">try</span> { \r
+           reply.setStream(<span class="keyword">new</span> <span class="type">FileInputStream</span>(file));\r
+       } <span class="keyword">catch</span> (<span class="type">IOException</span> <span class="variable-name">ex</span>) {\r
+           <span class="comment">// I hate to have to loose time in tries\r
+</span>        }\r
+       <span class="keyword">return</span> reply ;\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">getFileResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (fresource == <span class="keyword">null</span>) \r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">NotAProtocolException</span>("<span class="string">this frame is not attached to a </span>"+\r
+                                           "<span class="string">FileResource. (</span>"+\r
+                                           resource.getIdentifier()+"<span class="string">)</span>");\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = <span class="keyword">null</span>;\r
+       <span class="type">File</span> <span class="variable-name">file</span> = fresource.getFile() ;\r
+       fresource.checkContent();\r
+       updateCachedHeaders();\r
+       <span class="comment">// Check validators:\r
+</span>        <span class="keyword">if</span> ( checkIfMatch(request) == COND_FAILED ) {\r
+           reply = request.makeReply(HTTP.PRECONDITION_FAILED);\r
+           reply.setContent("<span class="string">Pre-conditions failed.</span>");\r
+           reply.setContentMD5(<span class="keyword">null</span>);\r
+           <span class="keyword">return</span> reply;\r
+       }\r
+       <span class="keyword">if</span> ( checkIfNoneMatch(request) == COND_FAILED ) {\r
+           reply = createDefaultReply(request, HTTP.NOT_MODIFIED);\r
+           reply.setContentMD5(<span class="keyword">null</span>);\r
+           <span class="keyword">return</span> reply;\r
+       }\r
+       <span class="keyword">if</span> ( checkIfModifiedSince(request) == COND_FAILED ) {\r
+           reply = createDefaultReply(request, HTTP.NOT_MODIFIED);\r
+           reply.setContentMD5(<span class="keyword">null</span>);\r
+           <span class="keyword">return</span> reply;\r
+       }\r
+       <span class="keyword">if</span> ( checkIfUnmodifiedSince(request) == COND_FAILED ) {\r
+           reply = request.makeReply(HTTP.PRECONDITION_FAILED);\r
+           reply.setContent("<span class="string">Pre-conditions failed.</span>");\r
+           reply.setContentMD5(<span class="keyword">null</span>);\r
+           <span class="keyword">return</span> reply;\r
+       }\r
+       <span class="comment">// Does this file really exists, if so send it back\r
+</span>        <span class="keyword">if</span> ( file.exists() ) {\r
+           <span class="keyword">return</span> createFileReply(request);\r
+       } <span class="keyword">else</span> {\r
+           <span class="comment">// Delete the resource if parent is extensible:\r
+</span>            <span class="type">boolean</span> <span class="variable-name">extensible</span> = <span class="keyword">false</span>;\r
+           <span class="type">ResourceReference</span> <span class="variable-name">rr</span> = fresource.getParent();\r
+           <span class="type">ResourceReference</span> <span class="variable-name">rrtemp</span> = <span class="keyword">null</span>;\r
+           <span class="type">Resource</span> <span class="variable-name">p</span> = <span class="keyword">null</span>;\r
+           <span class="keyword">while</span> ( <span class="keyword">true</span> ) {\r
+               <span class="keyword">try</span> {\r
+                   <span class="keyword">if</span> (rr == <span class="keyword">null</span>)\r
+                       <span class="keyword">break</span>;\r
+                   p = rr.lock();\r
+                   <span class="keyword">if</span> (p <span class="keyword">instanceof</span> <span class="type">DirectoryResource</span>) {\r
+                       extensible = \r
+                           ((<span class="type">DirectoryResource</span>)p).getExtensibleFlag();\r
+                       <span class="keyword">break</span>;\r
+                   }\r
+                   rrtemp = p.getParent();\r
+               } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+                   <span class="keyword">break</span>;\r
+               } <span class="keyword">finally</span> {\r
+                   <span class="keyword">if</span> (rr != <span class="keyword">null</span>)\r
+                       rr.unlock();\r
+               }\r
+               rr = rrtemp;\r
+           }\r
+           <span class="keyword">if</span> (extensible) {\r
+               <span class="comment">// The resource is indexed but has no file, emit an error\r
+</span>                <span class="type">String</span> <span class="variable-name">msg</span> = fresource.getFile()+\r
+                   "<span class="string">: deleted, removing the FileResource.</span>";\r
+               getServer().errlog(fresource, msg);\r
+               <span class="keyword">try</span> {\r
+                   fresource.delete();\r
+               } <span class="keyword">catch</span> (<span class="type">MultipleLockException</span> <span class="variable-name">ex</span>) {\r
+                   <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_FOUND) ;\r
+                   error.setContentMD5(<span class="keyword">null</span>); <span class="comment">// FIXME must compute it!\r
+</span>                    error.setContent ("<span class="string">&lt;h1&gt;Document not found&lt;/h1&gt;</span>"+\r
+                                     "<span class="string">&lt;p&gt;The document </span>"+\r
+                                     request.getURL()+\r
+                                     "<span class="string"> is indexed but not available.</span>"+\r
+                                     "<span class="string">&lt;p&gt;</span>"+ex.getMessage()+\r
+                                     "<span class="string">&lt;p&gt;The server is misconfigured.</span>") ;\r
+                   <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+               }\r
+           }\r
+           <span class="comment">// Emit an error back:\r
+</span>            <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_FOUND) ;\r
+           error.setContentMD5(<span class="keyword">null</span>);\r
+           error.setContent ("<span class="string">&lt;h1&gt;Document not found&lt;/h1&gt;</span>"+\r
+                             "<span class="string">&lt;p&gt;The document </span>"+\r
+                             request.getURL()+\r
+                             "<span class="string"> is indexed but not available.</span>"+\r
+                             "<span class="string">&lt;p&gt;The server is misconfigured.</span>") ;\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+       }\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">getDirectoryResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">return</span> getDirectoryListing(request) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default HEAD method replies does a GET and removes entity.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> Always thrown, to return a NOT_IMPLEMENTED\r
+     *    error.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">head</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (dresource != <span class="keyword">null</span>) {\r
+           <span class="keyword">return</span> headDirectoryResource(request);\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="keyword">return</span> headFileResource(request);\r
+       } <span class="keyword">else</span> {\r
+           <span class="keyword">return</span> headOtherResource(request);\r
+       }\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">headOtherResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = <span class="keyword">null</span>;\r
+       reply = getOtherResource(request) ;\r
+       reply.setStream((<span class="type">InputStream</span>) <span class="keyword">null</span>);\r
+       <span class="keyword">return</span> reply;\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">headDirectoryResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = <span class="keyword">null</span>;\r
+       reply = getDirectoryResource(request) ;\r
+       reply.setStream((<span class="type">InputStream</span>) <span class="keyword">null</span>);\r
+       <span class="keyword">return</span> reply;\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">headFileResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (fresource == <span class="keyword">null</span>) \r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">NotAProtocolException</span>("<span class="string">this frame is not attached to a </span>"+\r
+                                           "<span class="string">FileResource. (</span>"+\r
+                                           resource.getIdentifier()+"<span class="string">)</span>");\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = <span class="keyword">null</span>;\r
+       fresource.checkContent();\r
+       updateCachedHeaders();\r
+       <span class="comment">// Conditional check:\r
+</span>        <span class="keyword">if</span> ( checkIfMatch(request) == COND_FAILED ) {\r
+           <span class="type">Reply</span> <span class="variable-name">r</span> = request.makeReply(HTTP.PRECONDITION_FAILED);\r
+           r.setContent("<span class="string">Pre-conditions failed.</span>");\r
+           <span class="keyword">return</span> r;\r
+       }\r
+       <span class="keyword">if</span> ( checkIfNoneMatch(request) == COND_FAILED )\r
+           <span class="keyword">return</span> createDefaultReply(request, HTTP.NOT_MODIFIED);\r
+       <span class="keyword">if</span> ( checkIfModifiedSince(request) == COND_FAILED )\r
+           <span class="keyword">return</span> createDefaultReply(request, HTTP.NOT_MODIFIED);\r
+       <span class="keyword">if</span> ( checkIfUnmodifiedSince(request) == COND_FAILED ) {\r
+           <span class="type">Reply</span> <span class="variable-name">r</span> = request.makeReply(HTTP.PRECONDITION_FAILED);\r
+           r.setContent("<span class="string">Pre-conditions failed.</span>");\r
+           <span class="keyword">return</span> r;\r
+       }\r
+       <span class="keyword">if</span> (! fresource.getFile().exists()) {\r
+           <span class="comment">// Delete the resource if parent is extensible:\r
+</span>            <span class="type">boolean</span> <span class="variable-name">extensible</span> = <span class="keyword">false</span>;\r
+           <span class="type">ResourceReference</span> <span class="variable-name">rr</span> = fresource.getParent();\r
+           <span class="type">ResourceReference</span> <span class="variable-name">rrtemp</span> = <span class="keyword">null</span>;\r
+           <span class="type">Resource</span> <span class="variable-name">p</span> = <span class="keyword">null</span>;\r
+           <span class="keyword">while</span> ( <span class="keyword">true</span> ) {\r
+               <span class="keyword">try</span> {\r
+                   <span class="keyword">if</span> (rr == <span class="keyword">null</span>)\r
+                       <span class="keyword">break</span>;\r
+                   p = rr.lock();\r
+                   <span class="keyword">if</span> (p <span class="keyword">instanceof</span> <span class="type">DirectoryResource</span>)\r
+                       extensible = \r
+                           ((<span class="type">DirectoryResource</span>)p).getExtensibleFlag();\r
+                   rrtemp = p.getParent();\r
+               } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+                   <span class="keyword">break</span>;\r
+               } <span class="keyword">finally</span> {\r
+                   <span class="keyword">if</span> (rr != <span class="keyword">null</span>)\r
+                       rr.unlock();\r
+               }\r
+               rr = rrtemp;\r
+           }\r
+           <span class="keyword">if</span> (extensible) {\r
+               <span class="comment">// The resource is indexed but has no file, emit an error\r
+</span>                <span class="type">String</span> <span class="variable-name">msg</span> = fresource.getFile()+\r
+                   "<span class="string">: deleted, removing the FileResource.</span>";\r
+               getServer().errlog(fresource, msg);\r
+               <span class="keyword">try</span> {\r
+                   fresource.delete();\r
+               } <span class="keyword">catch</span> (<span class="type">MultipleLockException</span> <span class="variable-name">ex</span>) {\r
+                   <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_FOUND) ;\r
+                   error.setContent ("<span class="string">&lt;h1&gt;Document not found&lt;/h1&gt;</span>"+\r
+                                     "<span class="string">&lt;p&gt;The document </span>"+\r
+                                     request.getURL()+\r
+                                     "<span class="string"> is indexed but not available.</span>"+\r
+                                     "<span class="string">&lt;p&gt;</span>"+ex.getMessage()+\r
+                                     "<span class="string">&lt;p&gt;The server is misconfigured.</span>") ;\r
+                   <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+               }\r
+           }\r
+           <span class="comment">// Emit an error back:\r
+</span>            <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_FOUND) ;\r
+           error.setContent ("<span class="string">&lt;h1&gt;Document not found&lt;/h1&gt;</span>"+\r
+                             "<span class="string">&lt;p&gt;The document </span>"+\r
+                             request.getURL()+\r
+                             "<span class="string"> is indexed but not available.</span>"+\r
+                             "<span class="string">&lt;p&gt;The server is misconfigured.</span>") ;\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+       }\r
+       <span class="keyword">return</span> createDefaultReply(request, HTTP.OK);\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default POST method replies with a not implemented.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> Always thrown, to return a NOT_IMPLEMENTED\r
+     *    error.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">post</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_ALLOWED) ;\r
+       <span class="keyword">if</span> ( allowed != <span class="keyword">null</span> )\r
+           error.setHeaderValue(Reply.H_ALLOW, allowed);\r
+       error.setContent("<span class="string">Method POST not allowed on this resource.</span>") ;\r
+       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default PUT method replies with a not implemented.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> Always thrown, to return a NOT_IMPLEMENTED\r
+     *    error.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">put</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (fresource != <span class="keyword">null</span>) {\r
+           <span class="keyword">return</span> putFileResource(request);\r
+       } <span class="keyword">else</span> {\r
+           <span class="keyword">return</span> putOtherResource(request);\r
+       }\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">putOtherResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+       error.setContent("<span class="string">Method PUT not implemented.</span>") ;\r
+       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+    }\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">Reply</span> <span class="function-name">putFileResource</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = <span class="keyword">null</span>;\r
+       <span class="type">int</span> <span class="variable-name">status</span> = HTTP.OK;\r
+       fresource.checkContent();\r
+       updateCachedHeaders();\r
+       <span class="comment">// Is this resource writable ?\r
+</span>        <span class="keyword">if</span> ( ! getPutableFlag() ) {\r
+           <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_ALLOWED) ;\r
+           error.setContent("<span class="string">Method PUT not allowed.</span>") ;\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+       }\r
+       <span class="comment">// Check validators:\r
+</span>        <span class="keyword">if</span> ((checkIfMatch(request) == COND_FAILED)\r
+           || (checkIfNoneMatch(request) == COND_FAILED)\r
+           || (checkIfModifiedSince(request) == COND_FAILED)\r
+           || (checkIfUnmodifiedSince(request) == COND_FAILED)) {\r
+           <span class="type">Reply</span> <span class="variable-name">r</span> = request.makeReply(HTTP.PRECONDITION_FAILED);\r
+           r.setContent("<span class="string">Pre-condition failed.</span>");\r
+           <span class="keyword">return</span> r;\r
+       }\r
+       <span class="comment">// Check the request:\r
+</span>        <span class="type">InputStream</span> <span class="variable-name">in</span> = <span class="keyword">null</span>;\r
+       <span class="keyword">try</span> {\r
+           in = request.getInputStream();\r
+           <span class="keyword">if</span> ( in == <span class="keyword">null</span> ) {\r
+               <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.BAD_REQUEST) ;\r
+               error.setContent ("<span class="string">&lt;p&gt;Request doesn't have a valid content.</span>");\r
+               <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+           }\r
+       } <span class="keyword">catch</span> (<span class="type">IOException</span> <span class="variable-name">ex</span>) {\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">ClientException</span>(request.getClient(), ex);\r
+       }\r
+       <span class="comment">// We do not support (for the time being) put with ranges:\r
+</span>        <span class="keyword">if</span> ( request.hasContentRange() ) {\r
+           <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.BAD_REQUEST);\r
+           error.setContent("<span class="string">partial PUT not supported.</span>");\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span>(error);\r
+       }\r
+       <span class="comment">// Check that if some type is provided it doesn't conflict:\r
+</span>        <span class="keyword">if</span> ( request.hasContentType() ) {\r
+           <span class="type">MimeType</span> <span class="variable-name">rtype</span> = request.getContentType() ;\r
+           <span class="type">MimeType</span> <span class="variable-name">type</span>  = getContentType() ;\r
+           <span class="keyword">if</span> ( type == <span class="keyword">null</span> ) {\r
+               setValue (ATTR_CONTENT_TYPE, rtype) ;\r
+           } <span class="keyword">else</span> <span class="keyword">if</span> ( rtype.match (type) < 0 ) {\r
+               <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.UNSUPPORTED_MEDIA_TYPE) ;\r
+               error.setContent ("<span class="string">&lt;p&gt;Invalid content type: </span>"+type.toString());\r
+               <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+           }\r
+       }\r
+       <span class="comment">// Write the body back to the file:\r
+</span>        <span class="keyword">try</span> {\r
+           <span class="comment">// We are about to accept the put, notify client before continuing\r
+</span>            <span class="type">Client</span> <span class="variable-name">client</span> = request.getClient();\r
+           <span class="keyword">if</span> ( client != <span class="keyword">null</span>  && request.getExpect() != <span class="keyword">null</span> ) {\r
+               client.sendContinue();\r
+           }\r
+           <span class="keyword">if</span> ( fresource.newContent(request.getInputStream()) )\r
+               status = HTTP.CREATED;\r
+           <span class="keyword">else</span>\r
+               status = HTTP.NO_CONTENT;\r
+       } <span class="keyword">catch</span> (<span class="type">IOException</span> <span class="variable-name">ex</span>) {\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">ClientException</span>(request.getClient(), ex);\r
+       }\r
+       <span class="keyword">if</span> ( status == HTTP.CREATED ) {\r
+           reply = request.makeReply(status);\r
+           reply.setLocation(getURL(request));\r
+           reply.setContent ("<span class="string">&lt;p&gt;Entity body saved succesfully !</span>") ;\r
+       } <span class="keyword">else</span> {\r
+           reply = createDefaultReply(request, status);\r
+       }\r
+       <span class="keyword">return</span> reply ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default OPTIONS method replies with a not implemented.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> In case of errors.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">options</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = createDefaultReply(request, HTTP.OK);\r
+       <span class="comment">// Removed unused headers:\r
+</span>        reply.setContentLength(-1);\r
+       reply.setContentType(<span class="keyword">null</span>);\r
+       <span class="comment">// Add the allow header:\r
+</span>        <span class="keyword">if</span> ( allowed != <span class="keyword">null</span> )\r
+           reply.setHeaderValue(Reply.H_ALLOW, allowed);\r
+       <span class="keyword">return</span> reply;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default DELETE method replies with a not implemented.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> Always thrown, to return a NOT_IMPLEMENTED\r
+     *    error.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">delete</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+       error.setContent("<span class="string">Method DELETE not implemented.</span>") ;\r
+       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default LINK method replies with a not implemented.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> Always thrown, to return a NOT_IMPLEMENTED\r
+     *    error.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">link</span>(<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+       error.setContent("<span class="string">Method LINK not implemented.</span>") ;\r
+       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default UNLINK method replies with a not implemented.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> Always thrown, to return a NOT_IMPLEMENTED\r
+     *    error.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">unlink</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+       error.setContent("<span class="string">Method UNLINK not implemented.</span>") ;\r
+       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * The default TRACE method replies with a not implemented\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">HTTPException</span><span class="comment"> In case of errors.\r
+     * </span><span class="keyword">@exception </span><span class="type">ClientException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">trace</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+        <span class="keyword">throws</span> <span class="type">HTTPException</span>, <span class="type">ClientException</span>\r
+    {\r
+        <span class="type">Reply</span> <span class="variable-name">reply</span> = createDefaultReply(request, HTTP.OK);\r
+       reply.setNoCache(); <span class="comment">// don't cache this\r
+</span>        reply.setMaxAge(-1); <span class="comment">// \r
+</span>        reply.setContentMD5(<span class="keyword">null</span>);\r
+        <span class="comment">// Dump the request as the body\r
+</span>        <span class="comment">// Removed unused headers:\r
+</span>        <span class="comment">// FIXME should be something else for chuncked stream\r
+</span>        <span class="type">ByteArrayOutputStream</span> <span class="variable-name">ba</span> = <span class="keyword">new</span> <span class="type">ByteArrayOutputStream</span>();\r
+       <span class="keyword">try</span> {\r
+           reply.setContentType(<span class="keyword">new</span> <span class="type">MimeType</span>("<span class="string">message/http</span>"));\r
+           request.dump(ba);\r
+           reply.setContentLength(ba.size());\r
+       } <span class="keyword">catch</span> (<span class="type">Exception</span> <span class="variable-name">ex</span>) {\r
+           ex.printStackTrace();\r
+       }\r
+       reply.setStream(<span class="keyword">new</span> <span class="type">ByteArrayInputStream</span>(ba.toByteArray()));\r
+       <span class="keyword">return</span> reply;\r
+    }\r
+    \r
+    <span class="comment">/**\r
+     * The handler for unknown method replies with a not implemented.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> Always thrown, to return a NOT_IMPLEMENTED\r
+     *    error.\r
+     * </span><span class="keyword">@exception </span><span class="type">NotAProtocolException</span><span class="comment"> If the client instance controling the\r
+     * request processing got a fatal error.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">extended</span>(<span class="type">Request</span> <span class="variable-name">request</span>)\r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>, <span class="type">NotAProtocolException</span>\r
+    {\r
+       <span class="type">String</span> <span class="variable-name">method</span> = request.getMethod() ;\r
+       <span class="keyword">if</span> ((method != <span class="keyword">null</span>) && method.equals("<span class="string">BROWSE</span>") && getBrowsableFlag())\r
+           <span class="keyword">return</span> browse(request) ;\r
+\r
+       <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+       error.setContent("<span class="string">Method </span>"+method+"<span class="string"> not implemented.</span>") ;\r
+       <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Handle the browse method.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to handle.\r
+     */</span>\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">MimeType</span>  <span class="variable-name">browsetype</span> = <span class="keyword">null</span>;\r
+\r
+    <span class="preprocessor">protected</span> <span class="type">synchronized</span> <span class="type">MimeType</span> <span class="function-name">getBrowseType</span>() {\r
+       <span class="keyword">if</span> ( browsetype == <span class="keyword">null</span> ) {\r
+           <span class="keyword">try</span> {\r
+               browsetype = <span class="keyword">new</span> <span class="type">MimeType</span>("<span class="string">application/x-navibrowse</span>");\r
+           } <span class="keyword">catch</span> (<span class="type">Exception</span> <span class="variable-name">ex</span>) {\r
+               ex.printStackTrace();\r
+           }\r
+       }\r
+       <span class="keyword">return</span> browsetype;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * A present to GNNPress users !\r
+     * This method implements the &lt;code&gt;BROWSE&lt;/code&gt; method that\r
+     * AOL press (or GNN press, or whatever its last name is) expects.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">request</span><span class="comment"> The request to process.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> If some error occurs.\r
+     * </span><span class="keyword">@return </span><span class="comment">A Reply instance.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">Reply</span> <span class="function-name">browse</span> (<span class="type">Request</span> <span class="variable-name">request</span>) \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="keyword">if</span> (dresource == <span class="keyword">null</span>) {\r
+           <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+           error.setContent("<span class="string">Method </span>"+request.getMethod()+\r
+                            "<span class="string"> not implemented.</span>") ;\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (error) ;\r
+       }\r
+\r
+       <span class="type">Enumeration</span>  <span class="variable-name">enum</span>      = dresource.enumerateResourceIdentifiers() ;\r
+       <span class="type">Vector</span>       <span class="variable-name">resources</span> = Sorter.sortStringEnumeration(enum) ;\r
+       <span class="type">int</span>          <span class="variable-name">rsize</span>     = ((resources == <span class="keyword">null</span>) ? 0 : resources.size()) ;\r
+       <span class="type">StringBuffer</span> <span class="variable-name">sb</span>        = <span class="keyword">new</span> <span class="type">StringBuffer</span>() ;\r
+\r
+       <span class="comment">// As we have enumerated all resources, just looking the store is ok\r
+</span>        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < rsize ; i++) {\r
+           <span class="type">String</span>            <span class="variable-name">rname</span> = (<span class="type">String</span>) resources.elementAt(i) ;\r
+           <span class="type">ResourceReference</span> <span class="variable-name">rr</span>    = <span class="keyword">null</span>;\r
+           <span class="type">Resource</span>          <span class="variable-name">r</span>     = <span class="keyword">null</span>;\r
+           <span class="keyword">try</span> {\r
+               rr = dresource.lookup(rname) ;\r
+               r = rr.lock();\r
+               <span class="comment">// may throw InvalidResourceException\r
+</span>\r
+               <span class="keyword">if</span> ( r <span class="keyword">instanceof</span> <span class="type">DirectoryResource</span> ) {\r
+                   sb.append("<span class="string">application/x-navidir </span>"+\r
+                             rname+\r
+                             "<span class="string">\r\n</span>") ;\r
+               } <span class="keyword">else</span> {\r
+                   <span class="type">HTTPFrame</span> <span class="variable-name">itsframe</span> = \r
+                       (<span class="type">HTTPFrame</span>) resource.getFrame(getClass());\r
+                   <span class="keyword">if</span> (itsframe != <span class="keyword">null</span>) {\r
+                       sb.append(itsframe.getContentType().toString()+\r
+                                 "<span class="string"> </span>"+\r
+                                 rname+\r
+                                 "<span class="string">\r\n</span>") ;\r
+                   }\r
+               }\r
+           } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+               <span class="keyword">continue</span>;\r
+           } <span class="keyword">finally</span> {\r
+               rr.unlock();\r
+           }\r
+       }\r
+       <span class="type">Reply</span> <span class="variable-name">reply</span> = request.makeReply(HTTP.OK) ;\r
+       reply.addPragma("<span class="string">no-cache</span>");\r
+       reply.setNoCache();\r
+       reply.setContent(sb.toString()) ;\r
+       reply.setContentType(getBrowseType());\r
+       <span class="keyword">return</span> reply ;\r
+    }\r
+\r
+    <span class="comment">//\r
+</span>    <span class="comment">// Filtered part\r
+</span>    <span class="comment">//\r
+</span>\r
+    <span class="comment">/**\r
+     * Get our whole list of filters.\r
+     */</span>\r
+  \r
+    <span class="reference">public</span> <span class="type">synchronized</span> <span class="type">ResourceFilter</span>[] <span class="function-name">getFilters</span>() {\r
+       <span class="type">ResourceFrame</span> <span class="variable-name">frames</span>[] = collectFrames(filterClass);\r
+       <span class="keyword">if</span> ( frames != <span class="keyword">null</span> ) {\r
+           <span class="comment">// FIXME Normally a simple cast should suffice (?)\r
+</span>            <span class="type">ResourceFilter</span> <span class="variable-name">f</span>[] = <span class="keyword">new</span> <span class="type">ResourceFilter</span>[frames.length];\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < frames.length ; i++)\r
+               f[i] = (<span class="type">ResourceFilter</span>) frames[i];\r
+           <span class="keyword">return</span> f;\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">null</span>;\r
+    }\r
+    \r
+    <span class="comment">/**\r
+     * Get the list of filters of this class.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">cls</span><span class="comment"> The class of filters requested.\r
+     * </span><span class="keyword">@return </span><span class="comment">An array of filters, which are instances of the given class.\r
+     */</span>\r
+  \r
+    <span class="reference">public</span> <span class="type">synchronized</span> <span class="type">ResourceFilter</span>[] <span class="function-name">getFilters</span>(<span class="type">Class</span> <span class="variable-name">cls</span>) {\r
+       <span class="type">ResourceFrame</span> <span class="variable-name">frames</span>[] = collectFrames(cls);\r
+       <span class="keyword">if</span> ( frames != <span class="keyword">null</span> ) {\r
+           <span class="comment">// FIXME Normally a simple cast should suffice (?)\r
+</span>            <span class="type">ResourceFilter</span> <span class="variable-name">f</span>[] = <span class="keyword">new</span> <span class="type">ResourceFilter</span>[frames.length];\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < frames.length ; i++)\r
+               f[i] = (<span class="type">ResourceFilter</span>) frames[i];\r
+           <span class="keyword">return</span> f;\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">null</span>;\r
+    }\r
+\r
+}\r
+\r
+    </pre>\r
+  </body>\r
+</html>\r