--- /dev/null
+<HTML>\r
+<HEAD>\r
+ <!-- Created by GNNpress/1.2 -->\r
+ <!-- Changed by: Anselm Baird-Smith, 4-Feb-1997 -->\r
+ <TITLE>ResourceFilter tutorial</TITLE>\r
+</HEAD>\r
+<BODY BGCOLOR="white">\r
+<P>\r
+<A HREF="http://www.w3.org/pub/WWW/" TARGET="_top_"><IMG BORDER="0" SRC="/icons/WWW/w3c_home.gif"\r
+ ALT="" WIDTH="72" HEIGHT="48"></A>\r
+<A HREF="http://www.w3.org/pub/WWW/Jigsaw/" TARGET="_top_"><IMG SRC="/icons/jigsaw" WIDTH="212"\r
+ HEIGHT="49" ALT="Jigsaw" BORDER="0"></A>\r
+<H1>\r
+ Jigsaw resource's filter tutorial\r
+</H1>\r
+<P>\r
+This tutorial assumes that your are familiar with\r
+<A HREF="../Introduction/architecture.html"><B>Jigsaw</B> architecture</A>,\r
+and that you have read both the\r
+<A HREF="configuration.html">configuration</A> and the\r
+<A HREF="resource.html">resource</A> tutorials. It will explain you the last\r
+major concept of <B>Jigsaw</B> you should be aware of: resource filters.\r
+<P>\r
+As was said in the architectural overview of <B>Jigsaw</B>, each HTTP request\r
+ends up performed by some target resource instance. For the sake of simplicity,\r
+we didn't mentioned at that time, that most resource classes provided with\r
+the <B>Jigsaw</B> server inherits from the\r
+<A HREF="../api/w3c.jigsaw.resources.FilteredResource.html">FilteredResource</A>\r
+class. All instances of this class are able to manage a set of filters: these\r
+filters, which are to be instances of sub-classes of\r
+<A HREF="../api/w3c.jigsaw.resources.ResourceFilter.html">ResourceFilter</A>,\r
+are called-back twice during request processing:\r
+<UL>\r
+ <LI>\r
+ During lookup: before the actual target of the request has been selected.\r
+ The\r
+ <CODE><A HREF="../api/w3c.jigsaw.resources.ResourceFilter.html#ingoingFilter">ingoingFilter</A></CODE>\r
+ method of the filter gets called with the request as a parameter.\r
+ <LI>\r
+ After the request has been processed by the target resource. The\r
+ <CODE>outgoingFilter</CODE> of the filter gets called with the request and\r
+ the reply as parameters.\r
+</UL>\r
+<P>\r
+A resource filter is itself a resource: this means, in particular, that it\r
+is described - like all other resources - by a Java class, and a set of\r
+attributes. It also means that it can be pickled/unpickled, etc.\r
+<P>\r
+The remaining of this tutorial will walk through the code of the\r
+<A HREF="../api/w3c.jigsaw.filters.CounterFilter.html">CounterFilter</A>.\r
+This filter just counts the number of hits to its target resource. Before\r
+going any further, you should again make sure you have understand the\r
+<A HREF="resource.html">resource tutorial</A>. This tutorial has two sections:\r
+<A HREF="#counter-filter">the first one </A>will describe our filter's code,\r
+and the <A HREF="#installing">second one</A> will explain how to attach it\r
+to a target resource.\r
+<H2>\r
+ <A NAME="counter-filter">The CounterFilter class</A>\r
+</H2>\r
+<P>\r
+Its my hope that you will be amazed by how easy this filter is to code. As\r
+for writing new resource classes, the first thing we need to is to define\r
+the set of attributes that our filter will handle. In the case of a simple\r
+counter filter, the only attribute we need is simply the counter itself.\r
+Assuming we want our class to be in the <CODE>w3c.jigsaw.filters</CODE> package,\r
+we start by writing the following piece of code:\r
+<P>\r
+<TABLE BORDER CELLPADDING="2">\r
+ <TR>\r
+ <TD><PRE><B>package <A HREF="../api/Package-w3c.jigsaw.filters.html">w3c.jigsaw.filters</A>;</B>\r
+\r
+<B>import <A HREF="../api/Package-w3c.jigsaw.http.html">w3c.jigsaw.http</A>.*;</B>\r
+<B>import <A HREF="../api/Package-w3c.jigsaw.resources.html">w3c.jigsaw.resources</A>.*;</B>\r
+\r
+<B>public class CounterFilter extends <A HREF="../api/w3c.jigsaw.resources.ResourceFilter.html">ResourceFilter</A> {</B>\r
+<B> /**</B>\r
+<B> * Attribute index - The counter attribute.</B>\r
+<B> */</B>\r
+<B> protected static int ATTR_COUNTER = -1 ;</B>\r
+\r
+<B> static {</B>\r
+<B> <A HREF="../api/w3c.tools.store.Attribute.html">Attribute</A> a = null ;</B>\r
+<B> Class cls = null ;</B>\r
+<B> </B>\r
+<B> try {</B>\r
+<B> cls = Class.forName("w3c.jigsaw.filters.CounterFilter") ;</B>\r
+<B> } catch (Exception ex) {</B>\r
+<B> ex.printStackTrace() ;</B>\r
+<B> System.exit(1) ;</B>\r
+<B> }</B>\r
+<B> // Declare the counter attribute</B>\r
+<B> a = new <A HREF="../api/w3c.tools.store..IntegerAttribute.html">IntegerAttribute</A>("counter"</B>\r
+<B> , new Integer(0)</B>\r
+<B> , Attribute.EDITABLE) ;</B>\r
+<B> ATTR_COUNTER = <A HREF="../api/w3c.jigsaw.resources.AttributeRegistry.html">AttributeRegistry</A>.registerAttribute(cls, a) ;</B>\r
+<B> }</B>\r
+<B>}</B>\r
+</PRE>\r
+ </TD>\r
+ </TR>\r
+</TABLE>\r
+<P>\r
+This code does the following: it starts by declaring our resource filter\r
+class, and specify (through the <CODE>static</CODE> statement) its counter\r
+attribute, which is an editable integer attribute, whose default value is\r
+<B>0</B>. We register this attribute to the AttributeRegistry, and get back\r
+the <I>token</I> for accessing the attribute. If some of this seems unfamiliar,\r
+then refer to the <A HREF="resource.html">resource tutorial</A>.\r
+<P>\r
+We can now implement the <CODE>ingoingFilter</CODE> method of our filter,\r
+which is as simple as you might expect:\r
+<P>\r
+<TABLE BORDER CELLPADDING="2">\r
+ <TR>\r
+ <TD><PRE>package <A HREF="../api/Package-w3c.jigsaw.filters.html">w3c.jigsaw.filters</A>;\r
+\r
+import <A HREF="../api/Package-w3c.jigsaw.http.html">w3c.jigsaw.http</A>.*;\r
+import <A HREF="../api/Package-w3c.jigsaw.resources.html">w3c.jigsaw.resources</A>.*;\r
+\r
+public class CounterFilter extends <A HREF="../api/w3c.jigsaw.resources.ResourceFilter.html">ResourceFilter</A> {\r
+ /**\r
+ * Attribute index - The counter attribute.\r
+ */\r
+ protected static int ATTR_COUNTER = -1 ;\r
+\r
+ static {\r
+ <A HREF="../api/w3c.jigsaw.resources.Attribute.html">Attribute</A> a = null ;\r
+ Class cls = null ;\r
+ \r
+ try {\r
+ cls = Class.forName("w3c.jigsaw.filters.CounterFilter") ;\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace() ;\r
+ System.exit(1) ;\r
+ }\r
+ // Declare the counter attribute\r
+ a = new <A HREF="../api/w3c.jigsaw.resources.IntegerAttribute.html">IntegerAttribute</A>("counter"\r
+ , new Integer(0)\r
+ , Attribute.EDITABLE) ;\r
+ ATTR_COUNTER = <A HREF="../api/w3c.jigsaw.resources.AttributeRegistry.html">AttributeRegistry</A>.registerAttribute(cls, a) ;\r
+ }\r
+\r
+<B> /**</B>\r
+<B> * We count all accesses, even the one that failed.</B>\r
+<B> * @param request The request being processed.</B>\r
+<B> */</B>\r
+\r
+<B> public synchronized int ingoingFilter(<A HREF="../api/w3c.jigsaw.http.Request.html">Request</A> request) {</B>\r
+<B> int i = getInt (ATTR_COUNTER, 0) ;</B>\r
+<B> setInt(ATTR_COUNTER, i+1) ;</B>\r
+<B> return <A HREF="../api/w3c.jigsaw.resources.ResourceFilter.html#DontCallOutgoing">DontCallOutgoing</A> ;</B>\r
+<B> }</B>\r
+\r
+\r
+}\r
+</PRE>\r
+ </TD>\r
+ </TR>\r
+</TABLE>\r
+<P>\r
+<I>That's all !</I> However, this needs a bit more explanations. First of\r
+all, you might be surprised that we didn't provide an implementation for\r
+the <CODE>outgoingFilter</CODE> method. There is two reasons for this: the\r
+first one is that our super-class provide an empty\r
+<CODE>outgoingFilter</CODE> method, this solves the compiler problem. The\r
+second one is that as you might have noticed, our <CODE>ingoingFilter</CODE>\r
+returns a special integer,\r
+<A HREF="../api/w3c.jigsaw.resources.ResourceFilter.html#DontCallOutgoing">DontCallOutgoing</A>.\r
+This integers tells the target filtered resource that the filter has performed\r
+all its tasks in the <CODE>ingoingFilter</CODE> method, so there is no need\r
+to call its <CODE>outgoingFilter</CODE> method.\r
+<P>\r
+Note that the counter value will be made persistent across servers invocation\r
+by the <B>Jigsaw</B> runtime. To be clear, this means that you can shutdown\r
+the server, and restart it: the count will keep up to date. Now, enough coding,\r
+let's play with our filter, the next section explains how to attach an instance\r
+of the filter to some target resource.\r
+<H2>\r
+ <A NAME="installing">Installing the filter</A>\r
+</H2>\r
+<P>\r
+First, let's decide on some resource we want to count access to. For the\r
+sake of simplicity, let's say we want to count the number of accesses to\r
+the <CODE>/User</CODE> directory resource. As you might have guess, the first\r
+thing we want to do is to point our favorite browser to\r
+<CODE>/Admin/Editor/User</CODE>. This, as expected, brings up the form to\r
+edit the <CODE>/User</CODE> directory resource. We follow the\r
+<I>AddFilter</I> link at the bottom of the page, which prompts us for the\r
+filter's class. We fill this with\r
+<CODE>w3c.jigsaw.filters.CounterFilter</CODE>, and press the <I>OK</I> button.\r
+The <CODE>/User</CODE> directory resource editor now has two more link (at\r
+the bottom of the page), we follow the <I>w3c.jigsaw.filter.CounterFilter</I>\r
+one, to customize our filter attributes. The count is <B>0</B>, and we don't\r
+care about the filter's name.\r
+<P>\r
+Now, we can access <CODE>/User</CODE> (point your browser to\r
+<CODE>/User</CODE>). Reload the filter's editor...the value is still\r
+<B>0</B>, however, internally the value is now <B>1</B>. To check this, restart\r
+the server (by using the <CODE>/Admin/PropertiesEditor</CODE> <I>restart</I>\r
+button). NOTE: form some reason, the editor of a resource doesn't update\r
+the attribute value it displays when they change behind the scene, this is\r
+why you still see the count has being <B>0</B>. This should be fixed really\r
+soon.\r
+<H2>\r
+ Further reading\r
+</H2>\r
+<P>\r
+If you want to understand better the concept of filters, then you can look\r
+at the available filters, here is a path (by increasing complexity):\r
+<UL>\r
+ <LI>\r
+ Start by reading the code of the\r
+ <A HREF="../api/w3c.jigsaw.filters.DebugFilter.html">DebugFilter</A>. This\r
+ one has an <CODE>outgoingFilter</CODE> method, and doesn't represent a\r
+ significant step in complexity.\r
+ <LI>\r
+ You can then try to read the code of the\r
+ <A HREF="../api/w3c.jigsaw.filters.AccessLimitFilter.html">AccessLimitFilter</A>.\r
+ It doesn't use more features then the one above, but the synchronized methods\r
+ it relies on are significantly more complex then the previous to examples.\r
+ <LI>\r
+ Now, if you are courageous enough, you can go to the\r
+ <A HREF="../api/w3c.jigsaw.auth.GenericAuthFilter.html">GenericAuthFilter</A>.\r
+ Once you have understand this one, then you can carry on with the following\r
+ lists of possible filters (left as an exercise to the reader)\r
+ <LI>\r
+ Try to write a filter that will log the referer field of the requests (this\r
+ can be pretty easy if done in the naive way, and can become much complex\r
+ if you want to use a something more efficient).\r
+</UL>\r
+<P>\r
+Enjoy !\r
+<P>\r
+ <HR>\r
+<P>\r
+<I><A HREF="mailto:jigsaw@w3.org">Jigsaw Team</A><BR>\r
+$Id: filter.html,v 1.1 2010/06/15 12:28:35 smhuang Exp $</I>\r
+<P>\r
+</BODY></HTML>\r