Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / mcr-test / WWW / User / Tutorials / SSIResource.html
diff --git a/JMCR-Stable/mcr-test/WWW/User/Tutorials/SSIResource.html b/JMCR-Stable/mcr-test/WWW/User/Tutorials/SSIResource.html
new file mode 100644 (file)
index 0000000..ccc16c6
--- /dev/null
@@ -0,0 +1,645 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+<HEAD>\r
+  <!-- Changed by: Benoit Mahe, 18-Jul-1997 -->\r
+  <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (X11; I; SunOS 5.5 sun4u) [Netscape]">\r
+  <TITLE>SSIResource extension tutorial</TITLE>\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<P>\r
+<!-- Changed by: Benoit Mahe,  1-Jul-1997 -->\r
+<P>\r
+<!-- Created by GNNpress --><!-- Changed by: Anselm Baird-Smith,  4-Feb-1997\r
+--><A HREF="http://www.w3.org/pub/WWW/" TARGET="_top_"><IMG SRC="/icons/WWW/w3c_home.gif"\r
+    ALT="W3C" BORDER=0 HEIGHT=48 WIDTH=72></A>\r
+<A HREF="http://www.w3.org/pub/WWW/Jigsaw/" TARGET="_top_"><IMG SRC="/icons/jigsaw.gif" ALT="Jigsaw"\r
+    BORDER=0 HEIGHT=49 WIDTH=212></A>\r
+<H1>\r
+  SSIResource extension tutorial\r
+</H1>\r
+<P>\r
+The SSIResource\r
+(<A HREF="../api/w3c.jigsaw.ssi.SSIResource.html">w3c.jigsaw.ssi.SSIResource</A>)\r
+is a Jigsaw resource that provides a flexible way of generating part of the\r
+content of a document from individual pieces. This may sound too general,\r
+and that's because there is little constraint on the way the constituent\r
+pieces are generated. For example, one use of the SSIResource is the traditional\r
+one: the content of any resource can be embedded within any document exported\r
+by the SSIResource, by using the <TT>include</TT> command from the default\r
+command registry. Some other of the default commands allow you to include\r
+the size of the document, the time of day, the hit count, and other general\r
+data.\r
+<P>\r
+One of the goals of this tutorial is to show that the SSIResource is useful\r
+beyond its traditional use, as a powerful way of creating documents with\r
+a dynamically generated content. It is assumed that you are familiar with\r
+the administration of Jigsaw in general.\r
+<H2>\r
+  Commands and registries\r
+</H2>\r
+<P>\r
+The SSIResource will scan through the text of the file looking for a special\r
+kind of HTML comment. If it finds something of the form <TT>&lt;!--#command\r
+par_1=val_1 par_2=val_2 ... par_n=val_n --&gt;</TT>, it will interpret it\r
+as a command. <TT>par_1</TT> ... <TT>par_n </TT>are the names of the parameters,\r
+and <TT>val_1</TT> ... <TT>val_n</TT> are their values. The values can optionaly\r
+be enclosed in single or double quotes; otherwise they are delimited by ASCII\r
+white space. For example, the string <TT>&lt;!--#include\r
+virtual="doc.html"--&gt;</TT> denotes a&nbsp;call to a command called "include",\r
+with one parameter called "virtual" that has&nbsp;a&nbsp;value of "doc.html".\r
+<P>\r
+Upon finding a command, the SSIResource will look it up in&nbsp;an object\r
+called the <I>command registry</I>. The command registry returns the <I>command\r
+</I>that is registered by that name. Then, it will call the command's\r
+<TT>execute</TT> method with the specified parameters, and with other contextual\r
+data.\r
+<P>\r
+Command registries are objects of class\r
+<A HREF="../api/w3c.jigsaw.ssi.CommandRegistry.html">w3c.jigsaw.ssi.CommandRegistry</A>.\r
+Since this is an abstract class, a concrete implementation of one must be\r
+available for SSIResource to work. One such implementation is supplied with\r
+the distribution: it is\r
+<A HREF="../api/w3c.jigsaw.ssi.DefaultCommandRegistry.html">w3c.jigsaw.ssi.DefaultCommandRegistry</A>,\r
+which includes the bread-and-butter SSI commands. Commands are implementations\r
+of the <A HREF="../api/w3c.jigsaw.ssi.Command.html">w3c.jigsaw.ssi.Command\r
+</A>interface or\r
+<A HREF="../api/w3c.jigsaw.ssi.ControlCommand.html">w3c.jigsaw.ssi.ControlCommand</A>.\r
+The SSIResource declares a <TT>registryClass</TT> attribute, which is set\r
+to the particular command registry to use in parsing a given document.\r
+<P>\r
+Therefore, the way to extend the SSIResource is to create (either from scratch\r
+or by subclassing an existing one) a command registry that knows about the\r
+new commands that are being added. A good way to become familiar with these\r
+classes is too look at the code for\r
+<A HREF="../api/w3c.jigsaw.ssi.DefaultCommandRegistry.html">DefaultCommandRegistry</A>\r
+and its superclass,\r
+<A HREF="../api/w3c.jigsaw.ssi.BasicCommandRegistry.html">BasicCommandRegistry</A>,\r
+and at the code for the default commands (in rough order of complexity):\r
+<A HREF="../api/w3c.jigsaw.ssi.SampleCommand.html">SampleCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.CountCommand.html">CountCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.ConfigCommand.html">ConfigCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.FSizeCommand.html">FSizeCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.FLastModCommand.html">FLastModCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.EchoCommand.html">EchoCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.IncludeCommand.html">IncludeCommand,</A>\r
+<A HREF="../api/w3c.jigsaw.ssi..jdbc.jdbcCommand.html">jdbcCommand,</A>\r
+<A HREF="../api/w3c.jigsaw.ssi.CounterCommand.html">CounterCommand,</A>\r
+<A HREF="../api/w3c.jigsaw.ssi.servlets.ServletCommand.html">ServletCommand</A>.\r
+<P>\r
+SSIResource allows you to create control commands like loop and test. These\r
+commands implements the\r
+<A HREF="../api/w3c.jigsaw.ssi.ControlCommand.html">w3c.jigsaw.ssi.ControlCommand\r
+</A>interface. Here is the code of the default control commands :\r
+<A HREF="../api/w3c.jigsaw.ssi.IfCommand.html">IfCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.ElseCommand.html">ElseCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.EndifCommand.html">EndifCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.LoopCommand.html">LoopCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.ExitloopCommand.html">ExitloopCommand</A>,\r
+<A HREF="../api/w3c.jigsaw.ssi.EndloopCommand.html">EndloopCommand</A>. The\r
+<A HREF="../api/w3c.jigsaw.ssi.Command.html">w3c.jigsaw.ssi.Command\r
+</A>interface has been modified, a new method was added (getValue). This\r
+method is used by some control commands (if) to get some value relative to\r
+the command.\r
+<P>\r
+Let's have a look of what can be done with control commands :\r
+<P>\r
+This shtml page display the content of the users database.\r
+<PRE>&lt;html&gt;\r
+  &lt;head&gt;\r
+    &lt;title&gt;Database SSI&lt;/title&gt;\r
+  &lt;/head&gt;\r
+\r
+  &lt;body&gt;\r
+      &lt;h1&gt;Database SSI&lt;/h1&gt;\r
+      &lt;p&gt;This Server Side Include extension allows you to query a database,\r
+         to make some loop and some tests.\r
+        (which I am doing right now) \r
+\r
+&lt;!--#jdbc select="SELECT * FROM users" name="result" driver="COM.imaginary.sql.msql.MsqlDriver" url="jdbc:msql://www43.inria.fr:4333/users" --&gt;\r
+\r
+        &lt;p&gt;The query has run, here is all the results:&lt;p&gt;\r
+        &lt;table border=2&gt;\r
+        &lt;tr&gt;&lt;td&gt;&lt;b&gt;Name&lt;/td&gt;&lt;td&gt;&lt;b&gt;Login&lt;/td&gt;\r
+        &lt;td&gt;&lt;b&gt;Email&lt;/td&gt;&lt;td&gt;&lt;b&gt;Age&lt;/td&gt;&lt;/tr&gt;   \r
+&lt;!--#loop name="loop1" --&gt;\r
+      &lt;!--#jdbc name="result" next="true" --&gt;\r
+\r
+      &lt;!--#if name="if1" command="jdbc" var="result" equals="empty" --&gt;\r
+                &lt;!--#exitloop name="loop1" --&gt;\r
+      &lt;!--#endif name="if1" --&gt;\r
+      \r
+      &lt;!-- the three lines above can be changed in : --&gt;\r
+      \r
+      &lt;!--#exitloop name="loop1" command="jdbc" var="result" equals="empty" --&gt;\r
+\r
+        &lt;tr&gt;&lt;td&gt;\r
+        &lt;!--#jdbc name="result" column="1" --&gt;\r
+        &lt;/td&gt;&lt;td&gt;\r
+        &lt;!--#jdbc name="result" column="2" --&gt;\r
+        &lt;/td&gt;&lt;td&gt;\r
+        &lt;!--#jdbc name="result" column="3" --&gt;\r
+        &lt;/td&gt;&lt;td&gt;\r
+        &lt;!--#jdbc name="result" column="4" --&gt;\r
+        &lt;/td&gt;&lt;/tr&gt;\r
+&lt;!--#endloop name="loop1" --&gt;\r
+        &lt;/table&gt;\r
+      &lt;hr&gt;\r
+  &lt;/body&gt;\r
+&lt;/html&gt;\r
+</PRE>\r
+<H2>\r
+  IfCommand : the source code\r
+</H2>\r
+<P>\r
+This command implements the <I>classic</I> if statement. This command can\r
+only be used with\r
+<A HREF="../api/w3c.jigsaw.ssi.EndifCommand.html">EndifCommand</A> and\r
+(optionnaly) with\r
+<A HREF="../api/w3c.jigsaw.ssi.ElseCommand.html">ElseCommand</A>.\r
+<PRE>\r
+package w3c.jigsaw.ssi;\r
+\r
+import java.util.*;\r
+\r
+import <A HREF="../api/Package-w3c.jigsaw.http.html">w3c.jigsaw.http.*</A> ;\r
+import <A HREF="../api/Package-w3c.www.http.html">w3c.www.http.*</A> ;\r
+import <A HREF="../api/Package-w3c.jigsaw.resources.html">w3c.jigsaw.resources.*</A> ;\r
+import <A HREF="../api/Package-w3c.util.html">w3c.util.*</A> ;\r
+\r
+<B></B>\r
+<B>/**</B>\r
+<B> * Implementation of the SSI <CODE>if</CODE> command.  </B>\r
+<B> * @author Benoit Mahe :<I>bmahe@sophia.inria.fr</I></B>\r
+<B> */ </B>\r
+\r
+public class IfCommand implements <A HREF="../api/w3c.jigsaw.ssi.ControlCommand.html">ControlCommand</A> {\r
+  private final static String  NAME  = "if";\r
+  private final static boolean debug = true;\r
+<B>    </B>\r
+<B>  // The parameters accepted by the if command </B>\r
+  private static final String keys[] = { \r
+    "name",\r
+    "command",\r
+    "var",\r
+    "equals"\r
+  };\r
+<B></B>\r
+<B>  // Used to store the position of each if command </B>\r
+  protected static Hashtable ifstore = null;\r
+\r
+  static {\r
+     ifstore = new Hashtable(23);\r
+  }\r
+<B></B>\r
+<B>  /**</B>\r
+<B>   * Returns the (String) value of the given variable.</B>\r
+<B>   * @return a String instance.</B>\r
+<B>   */ </B>\r
+  public String getValue(Dictionary variables, String var) {\r
+    return null;\r
+  }\r
+\r
+  protected static int getPosition(String name) \r
+    throws ControlCommandException    \r
+  {\r
+    Integer pos = (Integer)ifstore.get(name);\r
+    if (pos == null)\r
+      throw new ControlCommandException(NAME,"Position unknown.");\r
+     else return pos.intValue();\r
+  }\r
+\r
+<B></B>\r
+<B>  /**</B>\r
+<B>   * register the command position in the structure</B>\r
+<B>   * witch store the SSIResource.</B>\r
+<B>   */ </B>\r
+  public void setPosition(<A HREF="../api/w3c.jigsaw.ssi.SSIResource.html">SSIResource</A> resource,\r
+                         <A HREF="../api/w3c.jigsaw.ssi.CommandRegistry.html">CommandRegistry</A> registry,\r
+                         <A HREF="../api/w3c.util.ArrayDictionary.html">ArrayDictionary</A> parameters,\r
+                         Dictionary variables,\r
+                         int position) \r
+  {\r
+    Object values[] = parameters.getMany(keys);\r
+    String name     = (String) values[0];\r
+    if (name != null)\r
+      ifstore.put(resource.getURLPath()+":"+name, new Integer(position));\r
+  }\r
+<B></B>\r
+<B>  /**</B>\r
+<B>   * Executes this command. Might modify variables.</B>\r
+<B>   * Must <EM>not</EM> modify the parameters.</B>\r
+<B>   * It may handle conditional requests, <EM>except</EM> that if</B>\r
+<B>   * it replies with a status of HTTP.NOT_MODIFIED, it <EM>must</EM></B>\r
+<B>   * still reply with a content (the same content that it would have</B>\r
+<B>   * returned for an inconditional request).  This is because</B>\r
+<B>   * further SSI commands down the line may decide thay they have</B>\r
+<B>   * been modified, and then a content must be emitted by SSIResource.</B>\r
+<B>   * @param request the original HTTP request</B>\r
+<B>   * @param parameters The parameters for this command</B>\r
+<B>   * @param variables The global variables for the parse </B>\r
+<B>   * @return a Reply with the output from the command */ </B>\r
+\r
+  public <A HREF="../api/w3c.jigsaw.http.Reply.html">Reply</A> execute(<A HREF="../api/w3c.jigsaw.ssi.SSIResource.html">SSIResource</A> resource,\r
+                      <A HREF="../api/w3c.jigsaw.http.Request.html">Request</A> request,\r
+                      <A HREF="../api/w3c.util.ArrayDictionary.html">ArrayDictionary</A> parameters,\r
+                      Dictionary variables) \r
+  { <B></B>\r
+<B>    // Empty reply </B>\r
+    return resource.createCommandReply(request, HTTP.OK);\r
+  }\r
+\r
+  protected boolean check(<A HREF="../api/w3c.jigsaw.ssi.CommandRegistry.html">CommandRegistry</A> registry,\r
+                         <A HREF="../api/w3c.util.ArrayDictionary.html">ArrayDictionary</A> parameters,\r
+                         Dictionary variables)\r
+  {\r
+    Object values[] = parameters.getMany(keys);\r
+    String name     = (String) values[0];\r
+    String command  = (String) values[1];\r
+    String var      = (String) values[2];\r
+    String equals   = (String) values[3];\r
+    \r
+    if ((command == null) || (var == null) || (equals == null))\r
+      return false;\r
+    Command cmd = registry.lookupCommand(command);\r
+    String value = cmd.getValue(variables,var);\r
+    <B>// here is the test</B>\r
+    return value.equals(equals);\r
+  }\r
+<B></B>\r
+<B>  /**</B>\r
+<B>   * Give the next position in the structure witch</B>\r
+<B>   * store the SSIResource.</B>\r
+<B>   */ </B>\r
+  public int jumpTo(<A HREF="../api/w3c.jigsaw.ssi.SSIResource.html">SSIResource</A> resource,\r
+                   <A HREF="../api/w3c.jigsaw.ssi.CommandRegistry.html">CommandRegistry</A> registry,\r
+                   <A HREF="../api/w3c.util.ArrayDictionary.html">ArrayDictionary</A> parameters,\r
+                   Dictionary variables)\r
+    throws ControlCommandException\r
+  {\r
+    Object values[] = parameters.getMany(keys);\r
+    String name     = (String) values[0];\r
+    if (name != null) {\r
+      if (check(registry,parameters,variables))\r
+       return getPosition(resource.getURLPath()+":"+name)+1;\r
+      try {\r
+       return (ElseCommand.getPosition(resource.getURLPath()+":"+name)+1);\r
+      } catch (ControlCommandException ex) {\r
+       return (EndifCommand.getPosition(resource.getURLPath()+":"+name)+1);\r
+      }\r
+    }\r
+    throw new ControlCommandException(NAME,"name not initialized.");    \r
+  }\r
+<B></B>\r
+<B>  /** </B>\r
+<B>   * Returns the name of this command. <EM>(Case sensitivity is up to</EM></B>\r
+<B><EM>   * the <CODE>lookupCommand</CODE> method in the command registry.)</EM></B>\r
+<B>   * @return the name of the command</B>\r
+<B>   * @see w3c.jigsaw.ssi.CommandRegistry#lookupCommand</B>\r
+<B>   */ </B>\r
+  public String getName() {\r
+    return NAME;\r
+  }\r
+\r
+}\r
+\r
+</PRE>\r
+<P>\r
+With this in mind, let's implement a useful extension of SSIResource.\r
+<H2>\r
+  A server statistics page with SSIResource\r
+</H2>\r
+<P>\r
+There is an existing Jigsaw resource\r
+(<A HREF="../api/w3c.jigsaw.status.Statistics.html">w3c.jigsaw.status.Statistics</A>)\r
+that is used to display the internal statistics of the server. In what follows,\r
+we will mimic the functionality of this resource with an SSI command. There\r
+is an object that supplies all these statistics for us; its class is\r
+<A HREF="../api/w3c.jigsaw.http.httpdStatistics.html">w3c.jigsaw.http.httpdStatistics</A>\r
+and it can be obtained from the server. Our SSI command will query this object\r
+and emit the values. We'd like to be able to use it like this: &lt;!--#stat\r
+data=&lt;type&gt; --&gt;, where &lt;type&gt; specifies the particular statistic\r
+that is going to be inserted, and is one of:\r
+<UL>\r
+  <LI>\r
+    <TT>serverLoad</TT>\r
+  <LI>\r
+    <TT>freeThreads</TT>\r
+  <LI>\r
+    <TT>idleThreads</TT>\r
+  <LI>\r
+    <TT>totalThreads</TT>\r
+  <LI>\r
+    <TT>hitCount</TT>\r
+  <LI>\r
+    <TT>meanReqTime</TT>\r
+  <LI>\r
+    <TT>maxReqTime</TT>\r
+  <LI>\r
+    <TT>maxReqURL</TT>\r
+  <LI>\r
+    <TT>minReqTime</TT>\r
+  <LI>\r
+    <TT>minReqUrl</TT>\r
+  <LI>\r
+    <TT>emittedBytes</TT>\r
+</UL>\r
+<P>\r
+Each of them will correspond to one of the methods in httpdStatistics.\r
+<H3>\r
+  Writing the <TT>stat</TT> command\r
+</H3>\r
+<P>\r
+This command can be written in a very straightforward manner. All we have\r
+to do is:\r
+<OL>\r
+  <LI>\r
+    Obtain the httpdStatistics instance from the server.\r
+  <LI>\r
+    Call in it the appropriate method, according to the data parameter.\r
+  <LI>\r
+    Return a reply with this value as content.\r
+</OL>\r
+<P>\r
+This translates to the following java class, which will be called\r
+StatCommand:<BR>\r
+<TABLE CELLPADDING=2 >\r
+  <CAPTION ALIGN="Bottom">\r
+  </CAPTION>\r
+  <TBODY>\r
+    <TR>\r
+      <TD><PRE>package w3c.jigsaw.tutorials ;\r
+\r
+import java.util.* ;\r
+\r
+import <A HREF="../api/Package-w3c.jigsaw.http.html">w3c.jigsaw.http.*</A> ;\r
+import<A HREF="../api/w3c.www.http.HTTP.html"> w3c.www.http.HTTP</A> ;\r
+import <A HREF="../api/Package-w3c.jigsaw.ssi.html">w3c.jigsaw.ssi.*</A> ;\r
+import <A HREF="../api/Package-w3c.util.html">w3c.util.*</A> ;\r
+\r
+public class StatCommand implements <A HREF="../api/w3c.jigsaw.ssi.Command.html">Command</A> {\r
+    private static final String NAME = "stat" ;\r
+\r
+    public final String getName()\r
+    {\r
+        return NAME ;\r
+    }\r
+\r
+    <B>// Unuseful here</B>\r
+    public String getValue(Dictionary variables, String variable) {\r
+       return null;\r
+    }\r
+    \r
+    public <A HREF="../api/w3c.jigsaw.http.Reply.html">Reply</A> execute(<A HREF="../api/w3c.jigsaw.ssi.SSIResource.html">SSIResource</A> resource,\r
+                          <A HREF="../api/w3c.jigsaw.http.Request.html">Request</A> request,\r
+                          <A HREF="../api/w3c.util.ArrayDictionary.html">ArrayDictionary</A> parameters,\r
+                          Dictionary variables)\r
+    {\r
+        <B>// Obtain the statistics from the server</B>\r
+        <A HREF="../api/w3c.jigsaw.http.httpdStatistics.html">httpdStatistics</A> stats = resource.getServer().getStatistics() ;\r
+\r
+        <B>// Get the parameter specifying the kind of statistic to emit.</B>\r
+        String data = (String) parameters.get("data") ;\r
+\r
+        <B>// If the parameter is not supplied, do nothing</B>\r
+        if(data == null)\r
+            return null ;\r
+\r
+        <B>// Otherwise, compare it against the possible different keywords</B>\r
+<B>        // (Since there are no "pointers to methods", this is the simplest way it</B>\r
+<B>        // can be written)</B>\r
+        long result = -1 ;\r
+        String urlResult = null ;\r
+        if(data.equalsIgnoreCase("serverload")) {\r
+            result = stats.getServerLoad() ;\r
+        } else if(data.equalsIgnoreCase("freethreads")) {\r
+            result = stats.getFreeThreadCount() ;\r
+        } else if(data.equalsIgnoreCase("idlethreads")) {\r
+            result = stats.getIdleThreadCount() ;\r
+        } else if(data.equalsIgnoreCase("totalthreads")) {\r
+            result = stats.getTotalThreadCount() ;\r
+        } else if(data.equalsIgnoreCase("hitcount")) {\r
+            result = stats.getHitCount() ;\r
+        } else if(data.equalsIgnoreCase("meanreqtime")) {\r
+            result = stats.getMeanRequestTime() ;\r
+        } else if(data.equalsIgnoreCase("maxreqtime")) {\r
+            result = stats.getMaxRequestTime() ;\r
+        } else if(data.equalsIgnoreCase("maxrequrl")) {\r
+            urlResult = stats.getMaxRequestURL().toExternalForm() ;\r
+        } else if(data.equalsIgnoreCase("minreqtime")) {\r
+            result = stats.getMinRequestTime() ;\r
+        } else if(data.equalsIgnoreCase("minrequrl")) {\r
+            urlResult = stats.getMinRequestURL().toExternalForm() ;\r
+        } else if(data.equalsIgnoreCase("emittedbytes")) {\r
+            result = stats.getEmittedBytes() ;\r
+        } else return null ;\r
+\r
+        <B>// Make a reply with the datum and return it</B>\r
+        <A HREF="../api/w3c.jigsaw.http.Reply.html">Reply</A> reply = resource.createCommandReply(request, HTTP.OK) ;\r
+        reply.setContent( urlResult == null\r
+                          ? Long.toString(result)\r
+                          : urlResult ) ;\r
+        return reply ;\r
+    }\r
+}\r
+</PRE>\r
+      </TD>\r
+    </TR>\r
+  </TBODY>\r
+  <TBODY>\r
+    <TR>\r
+      <TD>Listing 1: The command class</TD>\r
+    </TR>\r
+  </TBODY>\r
+</TABLE>\r
+<P>\r
+The <A HREF="../api/w3c.jigsaw.ssi.Command.html">Command</A> interface defines\r
+three methods. The <TT>getName</TT> method simply returns a String with the\r
+name of the command. The getValue method returns a value relative to the\r
+given parameter (Used by control commands).The <TT>execute</TT> method is\r
+the one that does the work. This method can be thought of as the <TT>get</TT>\r
+method in a resource: it takes, among other things, a\r
+<A HREF="../api/w3c.jigsaw.http.Request.html">Request</A> object, and it\r
+produces a <A HREF="../api/w3c.jigsaw.http.Reply.html">Reply</A> object.\r
+The SSIResource will insert the contents of the replies of each of the commands\r
+(<I>partial replies</I>) into the main, global, content, and it will also\r
+merge the relevant headers of the partial replies into the headers of the\r
+global reply. Besides taking a request, the <TT>execute</TT> method takes\r
+these arguments as well:\r
+<DL>\r
+  <DT>\r
+    <TT><A HREF="../api/w3c.jigsaw.ssi.SSIResource.html">w3c.jigsaw.ssi.SSIResource</A>\r
+    resource</TT>\r
+  <DD>\r
+    This is the SSIResource that is executing the command.\r
+  <DT>\r
+    <TT><A HREF="../api/w3c.util.ArrayDictionary.html">w3c.util.ArrayDictionary</A>\r
+    parameters</TT>\r
+  <DD>\r
+    The parameters that the command is called with. An ArrayDictionary is a subclass\r
+    of java.util.Dictionary. The parameters are stored as strings with the parameter\r
+    names as keys.\r
+  <DT>\r
+    <TT>java.util.Dictionary variables</TT>\r
+  <DD>\r
+    The current set of variables. A command may change its behavior according\r
+    to the values of these variables, and it can also modify the variables. The\r
+    meaning of the variables is\r
+    <A HREF="../Reference/w3c.jigsaw.ssi.SSIResource.html#very-global-variables">almost</A>\r
+    completely command- and command registry-dependent. The\r
+    <A HREF="../api/w3c.jigsaw.ssi.DefaultCommandRegistry.html">DefaultCommandRegistry</A>\r
+    uses the variables to keep state across different command calls in the same\r
+    document, such as the current date and time formats.\r
+</DL>\r
+<P>\r
+The <TT>execute</TT> method can also return <B><TT>null</TT></B>, which is\r
+interpreted as the absence of output. There are some subtle differences between\r
+the <TT>execute</TT> method and a regular resource <TT>get</TT> method. In\r
+particular, care must be taken if dealing with conditional requests. This\r
+example is simple enough that this is not a concern.\r
+<P>\r
+Now that the command itself is finished, we need to make it part of a command\r
+registry, so that it can be actually used in documents.\r
+<H3>\r
+  Writing a command registry\r
+</H3>\r
+<P>\r
+Since we'd like to be able to use the "standard" SSI commands in adition\r
+to our brand-new <TT>stat</TT> command, it's not a bad idea to make our new\r
+registry a subclass DefaultCommandRegistry. The way to do this is very\r
+straightforward: <BR>\r
+<TABLE CELLPADDING=2 >\r
+  <CAPTION ALIGN="Bottom">\r
+  </CAPTION>\r
+  <TBODY>\r
+    <TR>\r
+      <TD><PRE>package w3c.jigsaw.tutorials ;\r
+\r
+import <A HREF="../api/Package-w3c.jigsaw.ssi.html">w3c.jigsaw.ssi.*</A> ;\r
+\r
+public class MyCommandRegistry extends <A HREF="../api/w3c.jigsaw.ssi.DefaultCommandRegistry">DefaultCommandRegistry</A> {       \r
+    public MyCommandRegistry()\r
+    {\r
+        registerCommand(new StatCommand()) ;\r
+    }\r
+}\r
+</PRE>\r
+      </TD>\r
+    </TR>\r
+  </TBODY>\r
+  <TBODY>\r
+    <TR>\r
+      <TD>Listing 2: The command registry class</TD>\r
+    </TR>\r
+  </TBODY>\r
+</TABLE>\r
+<P>\r
+The constructor simply calls the <TT>registerCommand</TT> method (defined\r
+in\r
+<A HREF="../api/w3c.jigsaw.ssi.BasicCommandRegistry.java">BasicCommandRegistry</A>),\r
+with a new instance of the command that we're adding.\r
+<P>\r
+We're now ready to use this command in a future document.\r
+<H3>\r
+  Using the new registry\r
+</H3>\r
+<P>\r
+One way of using the newly-created command registry is to change the\r
+<TT>registryClass</TT> attribute defined for the <TT>.shtml</TT> extension\r
+to "<TT>w3c.jigsaw.tutorials.MyCommandRegistry</TT>". After doing that, Jigsaw\r
+will use the new registry when indexing new files with the <TT>.shtml</TT>\r
+extension (or reindexing old files). Then we can create a file that makes\r
+use of the new command, and place it in a Jigsaw-accesible directory. For\r
+example, we could do this:<BR>\r
+<TABLE CELLPADDING=2 >\r
+  <CAPTION ALIGN="Bottom">\r
+  </CAPTION>\r
+  <TBODY>\r
+    <TR>\r
+      <TD><PRE>&lt;!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"&gt;\r
+&lt;html&gt;\r
+  &lt;head&gt;\r
+    &lt;meta http-equiv="Refresh" content="5"&gt;\r
+    &lt;title&gt;Server Statistics&lt;/title&gt;\r
+  &lt;/head&gt;\r
+  &lt;body&gt;\r
+      &lt;ul&gt;\r
+        &lt;li&gt;hits: <B>&lt;!--#stat data=hitCount  --&gt;</B>\r
+        &lt;li&gt;bytes: <B>&lt;!--#stat data=emittedBytes  --&gt;</B>\r
+      &lt;/ul&gt;\r
+      &lt;p&gt;Request processing times:\r
+      &lt;table border&gt;\r
+        &lt;tr&gt;\r
+          &lt;th align="center"&gt; min\r
+          &lt;th align="center"&gt; avg\r
+          &lt;th align="center"&gt; max\r
+        &lt;/tr&gt;\r
+        &lt;tr&gt;\r
+          &lt;th align="center"&gt; <B>&lt;!--#stat data=minReqTime  --&gt;</B>\r
+          &lt;th align="center"&gt; <B>&lt;!--#stat data=meanReqTime  --&gt;</B>\r
+          &lt;th align="center"&gt; <B>&lt;!--#stat data=maxReqTime  --&gt;</B>\r
+        &lt;/tr&gt;   \r
+      &lt;/table&gt;\r
+      &lt;p&gt;Thread counts:\r
+      &lt;table border&gt;\r
+        &lt;tr&gt;\r
+          &lt;th align="center"&gt; free\r
+          &lt;th align="center"&gt; idle\r
+          &lt;th align="center"&gt; total\r
+        &lt;/tr&gt;\r
+        &lt;tr&gt;\r
+          &lt;th align="center"&gt; <B>&lt;!--#stat data=freeThreads  --&gt;</B>\r
+          &lt;th align="center"&gt; <B>&lt;!--#stat data=idleThreads  --&gt;</B>\r
+          &lt;th align="center"&gt; <B>&lt;!--#stat data=totalThreads  --&gt;</B>\r
+      &lt;/table&gt;\r
+      &lt;p&gt;Current load: <B>&lt;!--#stat data=serverLoad  --&gt;</B>\r
+  &lt;/body&gt;\r
+&lt;/html&gt;\r
+</PRE>\r
+      </TD>\r
+    </TR>\r
+  </TBODY>\r
+  <TBODY>\r
+    <TR>\r
+      <TD>Listing 3: A possible use of the new command</TD>\r
+    </TR>\r
+  </TBODY>\r
+</TABLE>\r
+<P>\r
+The above document will produce exactly the same output that the\r
+<A HREF="../api/w3c.jigsaw.status.Statistics.html">Statistics</A> resource\r
+would emit.\r
+<H2>\r
+  What have we gained?\r
+</H2>\r
+<P>\r
+At this point we can compare two different approaches to generating HTML\r
+dynamically. The first one involves writing a new, specialized, resource.\r
+The approach illustrated in this tutorial consists&nbsp;of writing an SSI\r
+command and serving the document with the SSIResource. Doing it this way\r
+has these advantages:\r
+<UL>\r
+  <LI>\r
+    The structure of the served document is not hard-coded. Instead, the Java\r
+    code only expresses the minimal needed functionality (in this case, that\r
+    of emitting server statistics), while the markup of the document can be modified\r
+    without having to recompile.\r
+  <LI>\r
+    Different functionalities can be mixed in a more orthogonal way. That is,\r
+    it is inefficient at best to create a resource that combines the function\r
+    of two existing resources. By distilling the functionality into SSI commands,\r
+    it is straightforward to make a registry that has all the needed commands.\r
+</UL>\r
+<P>\r
+One disadvantage of the SSI approach is the extra overhead incurred at serve-time\r
+of constructing the content from the pieces supplied by the commands. The\r
+SSIResource tries to avoid this overhead as much as possible. The most important\r
+optimization in this&nbsp;respect is the fact that the parsing of the document\r
+(i.e., scanning the text for commands, and reading the parameters) is done\r
+only when the file is modified. Even then, each command needs to check its\r
+parameters, which <I>does</I> add to serve-time overhead.\r
+<P>\r
+  <HR>\r
+<P>\r
+<I><A HREF="mailto:anto@w3.org">Antonio Ram&iacute;rez<BR>\r
+</A>$Id: SSIResource.html,v 1.1 2010/06/15 12:28:36 smhuang Exp $</I>\r
+</BODY></HTML>\r