Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / mcr-test / WWW / Doc / Programmer / samples / NegotiatedFrame.html
diff --git a/JMCR-Stable/mcr-test/WWW/Doc/Programmer/samples/NegotiatedFrame.html b/JMCR-Stable/mcr-test/WWW/Doc/Programmer/samples/NegotiatedFrame.html
new file mode 100644 (file)
index 0000000..cdfaa13
--- /dev/null
@@ -0,0 +1,588 @@
+<!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>NegotiatedFrame.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">// NegotiatedFrame.java\r
+// $Id: NegotiatedFrame.html,v 1.1 2010/06/15 12:20:05 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\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">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">resources</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">jigsaw</span>.<span class="reference">html</span>.<span class="type">HtmlGenerator</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
+\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
+ * Content negotiation.\r
+ */</span>\r
+<span class="reference">public</span> <span class="keyword">class</span> <span class="function-name">NegotiatedFrame</span> <span class="keyword">extends</span> <span class="type">HTTPFrame</span> {\r
+  \r
+    <span class="keyword">class</span> <span class="function-name">VariantState</span> {\r
+       <span class="type">ResourceReference</span> <span class="variable-name">variant</span> = <span class="keyword">null</span> ;\r
+       <span class="type">double</span> <span class="variable-name">qs</span>      = 0.0 ;\r
+       <span class="type">double</span> <span class="variable-name">qe</span>      = 0.0 ;\r
+       <span class="type">double</span> <span class="variable-name">qc</span>      = 0.0 ;\r
+       <span class="type">double</span> <span class="variable-name">ql</span>      = 0.0 ;\r
+       <span class="type">double</span> <span class="variable-name">q</span>       = 0.0 ;     <span class="comment">// quality (mime type one)\r
+</span>        <span class="type">double</span> <span class="variable-name">Q</span>       = 0.0 ;     <span class="comment">// the big Q\r
+</span>\r
+       <span class="reference">public</span> <span class="type">String</span> <span class="function-name">toString</span>() {\r
+           <span class="keyword">try</span> {\r
+               <span class="type">Resource</span> <span class="variable-name">res</span> = variant.lock();\r
+               <span class="type">String</span> <span class="variable-name">name</span> = (<span class="type">String</span>) res.getIdentifier() ;\r
+               <span class="keyword">if</span> ( name == <span class="keyword">null</span> )\r
+                   name = "<span class="string">&lt;noname&gt;</span>" ;\r
+               <span class="keyword">return</span> "<span class="string">[</span>" + name \r
+                   + "<span class="string"> qs=</span>" + qs \r
+                   + "<span class="string"> qe=</span>" + qe\r
+                   + "<span class="string"> ql=</span>" + ql\r
+                   + "<span class="string"> q =</span>" + q\r
+                   + "<span class="string"> Q =</span>" + getQ() \r
+                   +"<span class="string">]</span>" ;\r
+           } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+               <span class="keyword">return</span> "<span class="string">invalid</span>";\r
+           } <span class="keyword">finally</span> {\r
+               variant.unlock();\r
+           }\r
+       }\r
+\r
+       <span class="type">void</span> <span class="function-name">setContentEncodingQuality</span> (<span class="type">double</span> <span class="variable-name">qe</span>) {\r
+           <span class="reference">this</span>.qe = qe ;\r
+       }\r
+\r
+       <span class="type">void</span> <span class="function-name">setQuality</span> (<span class="type">double</span> <span class="variable-name">q</span>) {\r
+           <span class="reference">this</span>.q = q ;\r
+       }\r
+\r
+       <span class="type">void</span> <span class="function-name">setQuality</span> (<span class="type">HttpAccept</span> <span class="variable-name">a</span>) {\r
+           q = a.getQuality() ;\r
+       }\r
+\r
+       <span class="type">void</span> <span class="function-name">setLanguageQuality</span> (<span class="type">double</span> <span class="variable-name">ql</span>) {\r
+           <span class="reference">this</span>.ql = ql ;\r
+       }\r
+\r
+       <span class="type">void</span> <span class="function-name">setLanguageQuality</span> (<span class="type">HttpAcceptLanguage</span> <span class="variable-name">l</span>) {\r
+           <span class="reference">this</span>.ql = l.getQuality() ;\r
+       }\r
+\r
+       <span class="type">double</span> <span class="function-name">getLanguageQuality</span> () {\r
+           <span class="keyword">return</span> ql ;\r
+       }\r
+\r
+       <span class="type">ResourceReference</span> <span class="function-name">getResource</span> () {\r
+           <span class="keyword">return</span> variant ;\r
+       }\r
+\r
+       <span class="type">double</span> <span class="function-name">getQ</span>() {\r
+           <span class="keyword">return</span> qe * q * qs * ql ;\r
+       }\r
+\r
+       <span class="function-name">VariantState</span> (<span class="type">ResourceReference</span> <span class="variable-name">variant</span>, <span class="type">double</span> <span class="variable-name">qs</span>) {\r
+           <span class="reference">this</span>.qs      = qs ;\r
+           <span class="reference">this</span>.variant = variant ;\r
+       }\r
+    }\r
+\r
+    <span class="string">private</span> <span class="type">static</span> <span class="type">Class</span> <span class="variable-name">httpFrameClass</span> = <span class="keyword">null</span>;\r
+\r
+    <span class="type">static</span> {\r
+       <span class="keyword">try</span> {\r
+           httpFrameClass = 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
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">RuntimeException</span>("<span class="string">No HTTPFrame class found.</span>");\r
+       }\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Turn debugging on/off.\r
+     */</span>\r
+    <span class="string">private</span> <span class="type">static</span> <span class="type">final</span> <span class="type">boolean</span> <span class="variable-name">debug</span> = <span class="keyword">false</span>;\r
+    <span class="comment">/**\r
+     * Minimum quality for a resource to be considered further.\r
+     */</span>\r
+    <span class="string">private</span> <span class="type">static</span> <span class="type">final</span> <span class="type">double</span> <span class="variable-name">REQUIRED_QUALITY</span> = 0.0001 ;\r
+    <span class="comment">/**\r
+     * The Vary header field for this resource is always the same.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">HttpTokenList</span> <span class="variable-name">VARY</span> = <span class="keyword">null</span>;\r
+\r
+    <span class="comment">/**\r
+     * Attribute index - The set of names of variants.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">static</span> <span class="type">int</span> <span class="variable-name">ATTR_VARIANTS</span> = -1 ;\r
+\r
+    <span class="type">static</span> {\r
+       <span class="comment">// Compute and initialize the Vary header once and for all\r
+</span>        <span class="type">String</span> <span class="variable-name">vary</span>[] = { "<span class="string">Accept</span>",\r
+                         "<span class="string">Accept-Charset</span>",\r
+                         "<span class="string">Accept-Language</span>",\r
+                         "<span class="string">Accept-Encoding</span>" };\r
+       VARY = HttpFactory.makeStringList(vary);\r
+    }\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
+       <span class="keyword">try</span> {\r
+           cls = Class.forName("<span class="string">org.w3c.jigsaw.frames.NegotiatedFrame</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 names of the varint we negotiate\r
+</span>        a = <span class="keyword">new</span> <span class="type">StringArrayAttribute</span>("<span class="string">variants</span>"\r
+                                    , <span class="keyword">null</span>\r
+                                    , Attribute.EDITABLE) ;\r
+       ATTR_VARIANTS = AttributeRegistry.registerAttribute(cls, a) ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get the variant names.\r
+     */</span>\r
+    <span class="reference">public</span> <span class="type">String</span>[] <span class="function-name">getVariantNames</span>() {\r
+       <span class="keyword">return</span> (<span class="type">String</span>[]) getValue(ATTR_VARIANTS, <span class="keyword">null</span>) ;\r
+    }\r
+\r
+    <span class="reference">public</span> <span class="type">void</span> <span class="function-name">setVariants</span>(<span class="type">String</span> <span class="variable-name">variants</span>[]) {\r
+       setValue(ATTR_VARIANTS, variants);\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Get the variant resources.\r
+     * This is somehow broken, it shouldn't allocate the array of variants\r
+     * on each call. However, don't forget that the list of variants can be\r
+     * dynamically edited, this means that if we are to keep a cache of it \r
+     * (as would be the case if we kept the array of variants as instance var)\r
+     * we should also take care of editing of attributes (possible, but I\r
+     * just don't have enough lifes).\r
+     * </span><span class="keyword">@return </span><span class="comment">An array of ResourceReference, or &lt;strong&gt;null&lt;/strong&gt;.\r
+     * </span><span class="keyword">@exception </span><span class="type">ProtocolException</span><span class="comment"> If one of the variants doesn't exist.\r
+     */</span>\r
+\r
+    <span class="reference">public</span> <span class="type">ResourceReference</span>[] <span class="function-name">getVariantResources</span>() \r
+       <span class="keyword">throws</span> <span class="type">ProtocolException</span>\r
+    {\r
+       <span class="comment">// Get the variant names:\r
+</span>        <span class="type">String</span> <span class="variable-name">names</span>[] = getVariantNames() ;\r
+       <span class="keyword">if</span> ( names == <span class="keyword">null</span> )\r
+           <span class="keyword">return</span> <span class="keyword">null</span> ;\r
+       <span class="comment">// Look them up in our parent directory:\r
+</span>        <span class="type">ResourceReference</span> <span class="variable-name">variants</span>[] = <span class="keyword">new</span> <span class="type">ResourceReference</span>[names.length] ;\r
+       <span class="type">ResourceReference</span> <span class="variable-name">r_parent</span>     = resource.getParent() ;\r
+       <span class="keyword">try</span> {\r
+           <span class="type">DirectoryResource</span> <span class="variable-name">parent</span> = (<span class="type">DirectoryResource</span>) r_parent.lock();\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < names.length ; i++) {\r
+               variants[i] = parent.lookup(names[i]) ;\r
+               <span class="keyword">if</span> (variants[i] == <span class="keyword">null</span>)\r
+                   <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span>(names[i]+\r
+                                           "<span class="string">: couldn't be restored.</span>");\r
+           }\r
+       } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span>("<span class="string">invalid parent for negotiation</span>");\r
+       } <span class="keyword">finally</span> {\r
+           r_parent.unlock();\r
+       }\r
+       <span class="keyword">return</span> variants ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Print the current negotiation state.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">header</span><span class="comment"> The header to print first.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">states</span><span class="comment"> The current negotiation states.\r
+     */</span>\r
+  \r
+    <span class="preprocessor">protected</span> <span class="type">void</span> <span class="function-name">printNegotiationState</span> (<span class="type">String</span> <span class="variable-name">header</span>, <span class="type">Vector</span> <span class="variable-name">states</span>) {\r
+       <span class="keyword">if</span> ( debug ) {\r
+           System.out.println ("<span class="string">------</span>" + header) ;\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               System.out.println (state) ;\r
+           }\r
+           System.out.println ("<span class="string">-----</span>") ;\r
+       }\r
+    }\r
+  \r
+    <span class="comment">/**\r
+     * Negotiate among content encodings.\r
+     * &lt;p&gt;BUG: This will work only for single encoded variants.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">states</span><span class="comment"> The current negotiation states.\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">boolean</span> <span class="function-name">negotiateContentEncoding</span> (<span class="type">Vector</span> <span class="variable-name">states</span>,\r
+                                               <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> ( ! request.hasAcceptEncoding() ) {\r
+           <span class="comment">// All encodings accepted:\r
+</span>            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               state.setContentEncodingQuality(1.0) ;\r
+           }\r
+       } <span class="keyword">else</span> {\r
+           <span class="type">String</span> <span class="variable-name">encodings</span>[] = request.getAcceptEncoding() ;\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span>    = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               <span class="type">ResourceReference</span> <span class="variable-name">rr</span>  = state.getResource();\r
+               <span class="keyword">try</span> {\r
+                   <span class="type">FramedResource</span> <span class="variable-name">resource</span> = (<span class="type">FramedResource</span>)rr.lock() ;\r
+                   <span class="type">HTTPFrame</span> <span class="variable-name">itsframe</span> = \r
+                       (<span class="type">HTTPFrame</span>) resource.getFrame(httpFrameClass);\r
+                   <span class="keyword">if</span> (itsframe != <span class="keyword">null</span>) {\r
+                       <span class="keyword">if</span> ( !itsframe.definesAttribute("<span class="string">content-encoding</span>") ) {\r
+                           state.setContentEncodingQuality (1.0) ;\r
+                       } <span class="keyword">else</span> {\r
+                           <span class="type">String</span> <span class="variable-name">ve</span> = itsframe.getContentEncoding() ;\r
+                           state.setContentEncodingQuality (0.001) ;\r
+                       <span class="reference">encoding_loop</span>:\r
+                           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">j</span> = 0 ; j < encodings.length ; j++) {\r
+                               <span class="keyword">if</span> ( ve.equals (encodings[j]) ) {\r
+                                   state.setContentEncodingQuality(1.0) ;\r
+                                   <span class="keyword">break</span> <span class="reference">encoding_loop</span> ;\r
+                               }\r
+                           }\r
+                       }\r
+                   }\r
+               } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+         \r
+               } <span class="keyword">finally</span> {\r
+                   rr.unlock();\r
+               }\r
+           }\r
+           <span class="comment">// FIXME We should check here against unlegible variants as now\r
+</span>        }\r
+       <span class="keyword">return</span> <span class="keyword">false</span> ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Negotiate on charsets.\r
+     * &lt;p&gt;BUG: Not implemented yet.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">states</span><span class="comment"> The current states of negotiation.\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">boolean</span> <span class="function-name">negotiateCharsetQuality</span> (<span class="type">Vector</span> <span class="variable-name">states</span>\r
+                                              , <span class="type">Request</span> <span class="variable-name">request</span>) {\r
+       <span class="keyword">return</span> <span class="keyword">false</span> ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Negotiate among language qualities.\r
+     * &lt;p&gt;BUG: This will only work for variants that have one language tag.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">states</span><span class="comment"> The current states of negotiation.\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">boolean</span> <span class="function-name">negotiateLanguageQuality</span> (<span class="type">Vector</span> <span class="variable-name">states</span>\r
+                                               , <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> ( ! request.hasAcceptLanguage() ) {\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               state.setLanguageQuality (1.0) ;\r
+           }\r
+       } <span class="keyword">else</span> {\r
+           <span class="type">HttpAcceptLanguage</span> <span class="variable-name">languages</span>[] = request.getAcceptLanguage() ;\r
+           <span class="type">boolean</span>  <span class="variable-name">varyLang</span>    = <span class="keyword">false</span> ;\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span>    = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               <span class="type">ResourceReference</span> <span class="variable-name">rr</span>  = state.getResource();\r
+               <span class="keyword">try</span> {\r
+                   <span class="type">FramedResource</span> <span class="variable-name">resource</span> = (<span class="type">FramedResource</span>)rr.lock() ;\r
+                   <span class="type">HTTPFrame</span> <span class="variable-name">itsframe</span> = \r
+                       (<span class="type">HTTPFrame</span>) resource.getFrame(httpFrameClass);\r
+                   <span class="keyword">if</span> (itsframe != <span class="keyword">null</span>) {\r
+                       <span class="keyword">if</span> ( !itsframe.definesAttribute("<span class="string">content-language</span>") ) {\r
+                           state.setLanguageQuality (-1.0) ;\r
+                       } <span class="keyword">else</span> {\r
+                           varyLang = <span class="keyword">true</span> ;\r
+                           <span class="type">String</span> <span class="variable-name">lang</span> = itsframe.getContentLanguage() ;\r
+                           <span class="type">int</span> <span class="variable-name">jidx</span>    = -1 ;\r
+                           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">j</span> = 0 ; j < languages.length ; j++) {\r
+                               <span class="keyword">if</span> ( languages[j].getLanguage().equals(lang) )\r
+                                   jidx = j ;\r
+                           }\r
+                           <span class="keyword">if</span> ( jidx < 0 ) \r
+                               state.setLanguageQuality(0.001) ;\r
+                           <span class="keyword">else</span> \r
+                               state.setLanguageQuality (languages[jidx]) ;\r
+                       }\r
+                   }\r
+               } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+                   <span class="comment">//FIXME\r
+</span>                } <span class="keyword">finally</span> {\r
+                   rr.unlock();\r
+               }\r
+           }\r
+           <span class="keyword">if</span> ( varyLang ) {\r
+               <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+                   <span class="type">VariantState</span> <span class="variable-name">s</span> = (<span class="type">VariantState</span>) states.elementAt(i);\r
+                   <span class="keyword">if</span> ( s.getLanguageQuality() < 0 )\r
+                       s.setLanguageQuality (0.5) ;\r
+               }\r
+           } <span class="keyword">else</span> {\r
+               <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+                   <span class="type">VariantState</span> <span class="variable-name">s</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+                   s.setLanguageQuality (1.0) ;\r
+               }\r
+           }\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">false</span> ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Negotiate among content types.\r
+     * </span><span class="keyword">@param </span><span class="variable-name">states</span><span class="comment"> The current states of negotiation.\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">boolean</span> <span class="function-name">negotiateContentType</span> (<span class="type">Vector</span> <span class="variable-name">states</span>,\r
+                                           <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> ( ! request.hasAccept() ) {\r
+           <span class="comment">// All variants get a quality of 1.0\r
+</span>            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               state.setQuality (1.0) ;\r
+           }\r
+       } <span class="keyword">else</span> {\r
+           <span class="comment">// The browser has given some preferences:\r
+</span>            <span class="type">HttpAccept</span> <span class="variable-name">accepts</span>[] = request.getAccept() ;\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++ ) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               <span class="comment">// Get the most specific match for this variant:\r
+</span>                <span class="type">ResourceReference</span> <span class="variable-name">rr</span> = state.getResource();\r
+               <span class="keyword">try</span> {\r
+                   <span class="type">FramedResource</span> <span class="variable-name">resource</span> = (<span class="type">FramedResource</span>)rr.lock() ;\r
+                   <span class="type">HTTPFrame</span> <span class="variable-name">itsframe</span> = \r
+                       (<span class="type">HTTPFrame</span>) resource.getFrame(httpFrameClass);\r
+                   <span class="keyword">if</span> (itsframe != <span class="keyword">null</span>) {\r
+                       <span class="type">MimeType</span> <span class="variable-name">vt</span> = itsframe.getContentType();\r
+                       <span class="type">int</span> <span class="variable-name">jmatch</span> = -1 ;\r
+                       <span class="type">int</span> <span class="variable-name">jidx</span>   = -1 ;\r
+                       <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">j</span> = 0 ; j < accepts.length ; j++) {\r
+                           <span class="type">int</span> <span class="variable-name">match</span> = vt.match (accepts[j].getMimeType()) ;\r
+                           <span class="keyword">if</span> ( match > jmatch ) {\r
+                               jmatch = match ;\r
+                               jidx   = j ;\r
+                           }\r
+                       }\r
+                       <span class="keyword">if</span> ( jidx < 0 )\r
+                           state.setQuality (0.0) ;\r
+                       <span class="keyword">else</span> \r
+                           state.setQuality(accepts[jidx]) ;\r
+                   }\r
+               } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+                   <span class="comment">//FIXME\r
+</span>                } <span class="keyword">finally</span> {\r
+                   rr.unlock();\r
+               }\r
+           }\r
+       }\r
+       <span class="keyword">return</span> <span class="keyword">false</span> ;\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Negotiate among the various variants for the Resource.\r
+     * We made our best efforts to be as compliant as possible to the HTTP/1.0\r
+     * content negotiation algorithm.\r
+     */</span>\r
+    <span class="preprocessor">protected</span> <span class="type">ResourceReference</span> <span class="function-name">negotiate</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="comment">// Check for zero or one variant:\r
+</span>        <span class="type">ResourceReference</span> <span class="variable-name">variants</span>[] = getVariantResources() ;\r
+       <span class="keyword">if</span> ( variants.length < 2 ) {\r
+           <span class="keyword">if</span> ( variants.length == 0 ) {\r
+               <span class="type">Reply</span> <span class="variable-name">reply</span> = request.makeReply(HTTP.NOT_ACCEPTABLE) ;\r
+               reply.setContent ("<span class="string">&lt;p&gt;No acceptable variants.</span>") ;\r
+               <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (reply) ;\r
+           } <span class="keyword">else</span> {\r
+               <span class="keyword">return</span> variants[0] ;\r
+           }\r
+       }\r
+       <span class="comment">// Build a vector of variant negociation states, one per variants:\r
+</span>        <span class="type">Vector</span> <span class="variable-name">states</span> = <span class="keyword">new</span> <span class="type">Vector</span> (variants.length) ;\r
+       <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < variants.length ; i++) {\r
+           <span class="type">double</span> <span class="variable-name">qs</span> = 1.0 ;\r
+           <span class="keyword">try</span> {\r
+               <span class="type">FramedResource</span> <span class="variable-name">resource</span> = (<span class="type">FramedResource</span>)variants[i].lock() ;\r
+               <span class="type">HTTPFrame</span> <span class="variable-name">itsframe</span> = \r
+                   (<span class="type">HTTPFrame</span>) resource.getFrame(httpFrameClass);\r
+               <span class="keyword">if</span> (itsframe != <span class="keyword">null</span>) {\r
+                   <span class="keyword">if</span> ( itsframe.definesAttribute ("<span class="string">quality</span>") )\r
+                       qs = itsframe.getQuality() ;\r
+                   <span class="keyword">if</span> ( qs > REQUIRED_QUALITY )\r
+                       states.addElement(<span class="keyword">new</span> <span class="type">VariantState</span> (variants[i], qs)) ;\r
+               }\r
+           } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+               <span class="comment">//FIXME\r
+</span>            } <span class="keyword">finally</span> {\r
+               variants[i].unlock();\r
+           }\r
+       }\r
+       <span class="comment">// Content-encoding negociation:\r
+</span>        <span class="keyword">if</span> ( debug )\r
+           printNegotiationState ("<span class="string">init:</span>", states) ;\r
+       <span class="keyword">if</span> ( negotiateContentEncoding (states, request) ) \r
+           <span class="comment">// Remains a single acceptable variant:\r
+</span>            <span class="keyword">return</span> ((<span class="type">VariantState</span>) states.elementAt(0)).getResource() ;\r
+       <span class="keyword">if</span> ( debug )\r
+           printNegotiationState ("<span class="string">encoding:</span>", states) ;\r
+       <span class="comment">// Charset quality negociation:\r
+</span>        <span class="keyword">if</span> ( negotiateCharsetQuality (states, request) ) \r
+           <span class="comment">// Remains a single acceptable variant:\r
+</span>            <span class="keyword">return</span> ((<span class="type">VariantState</span>) states.elementAt(0)).getResource() ;\r
+       <span class="keyword">if</span> ( debug )\r
+           printNegotiationState ("<span class="string">charset:</span>", states) ;\r
+       <span class="comment">// Language quality negociation:\r
+</span>        <span class="keyword">if</span> ( negotiateLanguageQuality (states, request) ) \r
+           <span class="comment">// Remains a single acceptable variant:\r
+</span>            <span class="keyword">return</span> ((<span class="type">VariantState</span>) states.elementAt(0)).getResource() ;\r
+       <span class="keyword">if</span> ( debug )\r
+           printNegotiationState ("<span class="string">language:</span>", states) ;\r
+       <span class="comment">// Content-type negociation:\r
+</span>        <span class="keyword">if</span> ( negotiateContentType (states, request) )\r
+           <span class="comment">// Remains a single acceptable variant:\r
+</span>            <span class="keyword">return</span> ((<span class="type">VariantState</span>) states.elementAt(0)).getResource() ;\r
+       <span class="keyword">if</span> ( debug )\r
+           printNegotiationState ("<span class="string">type:</span>", states) ;\r
+       <span class="comment">// If we reached this point, this means that multiple variants are \r
+</span>        <span class="comment">// acceptable at this point. Keep the one that have the best quality.\r
+</span>        <span class="keyword">if</span> ( debug )\r
+           printNegotiationState ("<span class="string">before Q selection:</span>", states) ;\r
+       <span class="type">double</span> <span class="variable-name">qmax</span> = REQUIRED_QUALITY ;\r
+       <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; ) {\r
+           <span class="type">VariantState</span> <span class="variable-name">state</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+           <span class="keyword">if</span> ( state.getQ() > qmax ) {\r
+               <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">j</span> = i ; j > 0 ; j--)\r
+                   states.removeElementAt(0) ;\r
+               qmax = state.getQ() ;\r
+               i = 1 ;\r
+           } <span class="keyword">else</span> {\r
+               states.removeElementAt(i) ;\r
+           }\r
+       }\r
+       <span class="keyword">if</span> ( debug )\r
+           printNegotiationState ("<span class="string">After Q selection:</span>", states) ;\r
+       <span class="keyword">if</span> ( qmax == REQUIRED_QUALITY ) {\r
+           <span class="type">Reply</span> <span class="variable-name">reply</span> = request.makeReply(HTTP.NOT_ACCEPTABLE) ;\r
+           reply.setContent ("<span class="string">&lt;p&gt;No acceptable variant.</span>") ;\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (reply) ;\r
+       } <span class="keyword">else</span> <span class="keyword">if</span> ( states.size() == 1 ) {\r
+           <span class="keyword">return</span> ((<span class="type">VariantState</span>) states.elementAt(0)).getResource() ;\r
+       } <span class="keyword">else</span> {\r
+           <span class="comment">// Respond with multiple choice (for the time being, there should\r
+</span>            <span class="comment">// be a parameter to decide what to do.\r
+</span>            <span class="type">Reply</span> <span class="variable-name">reply</span> = request.makeReply(HTTP.MULTIPLE_CHOICE) ;\r
+           <span class="type">HtmlGenerator</span> <span class="variable-name">g</span> = <span class="keyword">new</span> <span class="type">HtmlGenerator</span> ("<span class="string">Multiple choice for </span>"+\r
+                                                resource.getIdentifier()) ;\r
+           g.append ("<span class="string">&lt;ul&gt;</span>") ;\r
+           <span class="keyword">for</span> (<span class="type">int</span> <span class="variable-name">i</span> = 0 ; i < states.size() ; i++) {\r
+               <span class="type">VariantState</span> <span class="variable-name">state</span> = (<span class="type">VariantState</span>) states.elementAt(i) ;\r
+               <span class="type">String</span> <span class="variable-name">name</span> = <span class="keyword">null</span>;\r
+               <span class="type">ResourceReference</span> <span class="variable-name">rr</span> = state.getResource();\r
+               <span class="keyword">try</span> {\r
+                   name = rr.lock().getIdentifier();\r
+                   g.append ("<span class="string">&lt;li&gt;</span>" \r
+                             + "<span class="string">&lt;a href=\"</span>" + name + "<span class="string">\"&gt;</span>" + name + "<span class="string">&lt;/a&gt;</span>"\r
+                             + "<span class="string"> Q= </span>" + state.getQ()) ;\r
+               } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+                   <span class="comment">//FIXME\r
+</span>                } <span class="keyword">finally</span> {\r
+                   rr.unlock();\r
+               }\r
+           }\r
+           reply.setStream (g) ;\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span> (reply) ;\r
+       }\r
+    }\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>.registerOtherResource(resource);\r
+    }\r
+\r
+    <span class="comment">/**\r
+     * Perform an HTTP request.\r
+     * Negotiate among the variants, the best variant according to the request\r
+     * fields, and make this elect3d variant serve the request.\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 negotiating among the resource variants \r
+     *    failed.\r
+     */</span>\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> = performFrames(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">Request</span> <span class="variable-name">request</span> = (<span class="type">Request</span>) req;\r
+       <span class="comment">// Run content negotiation now:\r
+</span>        <span class="type">ResourceReference</span> <span class="variable-name">selected</span> = negotiate(request) ;\r
+       <span class="comment">// This should never happen: either the negotiation succeed, or the\r
+</span>        <span class="comment">// negotiate method should return an error.\r
+</span>        <span class="keyword">if</span> ( selected == <span class="keyword">null</span> ) {\r
+           <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;\r
+           error.setContent("<span class="string">Error negotiating among resource's variants.</span>");\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span>(error) ;\r
+       }\r
+       <span class="comment">// FIXME content neg should be done at lookup time\r
+</span>        <span class="comment">// FIXME enhencing the reply should be done at outgoingfilter\r
+</span>        <span class="comment">// Get the original variant reply, and add its location as a header:\r
+</span>        <span class="keyword">try</span> {\r
+           <span class="type">FramedResource</span> <span class="variable-name">resource</span> = (<span class="type">FramedResource</span>) selected.lock();\r
+           <span class="type">Reply</span> <span class="variable-name">reply</span> = (<span class="type">Reply</span>)resource.perform(request) ;\r
+           reply.setHeaderValue(reply.H_VARY, VARY);\r
+           <span class="type">HTTPFrame</span> <span class="variable-name">itsframe</span> = \r
+               (<span class="type">HTTPFrame</span>) resource.getFrame(httpFrameClass);\r
+           <span class="keyword">if</span> (itsframe != <span class="keyword">null</span>) {\r
+               reply.setContentLocation(\r
+                                 itsframe.getURL(request).toExternalForm()) ;\r
+               <span class="keyword">return</span> reply;\r
+           }\r
+           <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;\r
+           error.setContent("<span class="string">Error negotiating : </span>"+\r
+                            "<span class="string">selected resource has no HTTPFrame</span>");\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span>(error) ;\r
+       } <span class="keyword">catch</span> (<span class="type">InvalidResourceException</span> <span class="variable-name">ex</span>) {\r
+           <span class="type">Reply</span> <span class="variable-name">error</span> = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;\r
+           error.setContent("<span class="string">Error negotiating : Invalid selected resource</span>");\r
+           <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">HTTPException</span>(error) ;\r
+       } <span class="keyword">finally</span> {\r
+           selected.unlock();\r
+       }\r
+    }\r
+  \r
+}\r
+\r
+    </pre>\r
+  </body>\r
+</html>\r