ResourceFilter tutorial

# Jigsaw resource's filter tutorial

This tutorial assumes that your are familiar with Jigsaw architecture, and that you have read both the configuration and the resource tutorials. It will explain you the last major concept of Jigsaw you should be aware of: resource filters.

As was said in the architectural overview of Jigsaw, each HTTP request ends up performed by some target resource instance. For the sake of simplicity, we didn't mentioned at that time, that most resource classes provided with the Jigsaw server inherits from the FilteredResource class. All instances of this class are able to manage a set of filters: these filters, which are to be instances of sub-classes of ResourceFilter, are called-back twice during request processing:

- During lookup: before the actual target of the request has been selected. The `ingoingFilter` method of the filter gets called with the request as a parameter.
- After the request has been processed by the target resource. The `outgoingFilter` of the filter gets called with the request and the reply as parameters.

A resource filter is itself a resource: this means, in particular, that it is described - like all other resources - by a Java class, and a set of attributes. It also means that it can be pickled/unpickled, etc.

The remaining of this tutorial will walk through the code of the CounterFilter. This filter just counts the number of hits to its target resource. Before going any further, you should again make sure you have understand the resource tutorial. This tutorial has two sections: the first one will describe our filter's code, and the second one will explain how to attach it to a target resource.

## The CounterFilter class

Its my hope that you will be amazed by how easy this filter is to code. As for writing new resource classes, the first thing we need to is to define the set of attributes that our filter will handle. In the case of a simple counter filter, the only attribute we need is simply the counter itself. Assuming we want our class to be in the `w3c.jigsaw.filters` package, we start by writing the following piece of code:

    package w3c.jigsaw.filters;

    import w3c.jigsaw.http.*;
    import w3c.jigsaw.resources.*;

    public class CounterFilter extends ResourceFilter {
        /**
         * Attribute index - The counter attribute.
         */
        protected static int ATTR_COUNTER = -1 ;

        static {
            Attribute a   = null ;
            Class     cls = null ;

            try {
                cls = Class.forName("w3c.jigsaw.filters.CounterFilter") ;
            } catch (Exception ex) {
                ex.printStackTrace() ;
                System.exit(1) ;
            }
            // Declare the counter attribute
            a = new IntegerAttribute("counter"
                                     , new Integer(0)
                                     , Attribute.EDITABLE) ;
            ATTR_COUNTER = AttributeRegistry.registerAttribute(cls, a) ;
        }
    }

This code does the following: it starts by declaring our resource filter class, and specify (through the `static` statement) its counter attribute, which is an editable integer attribute, whose default value is 0. We register this attribute to the AttributeRegistry, and get back the token for accessing the attribute. If some of this seems unfamiliar, then refer to the resource tutorial.

We can now implement the `ingoingFilter` method of our filter, which is as simple as you might expect:

    package w3c.jigsaw.filters;

    import w3c.jigsaw.http.*;
    import w3c.jigsaw.resources.*;

    public class CounterFilter extends ResourceFilter {
        /**
         * Attribute index - The counter attribute.
         */
        protected static int ATTR_COUNTER = -1 ;

        static {
            Attribute a   = null ;
            Class     cls = null ;

            try {
                cls = Class.forName("w3c.jigsaw.filters.CounterFilter") ;
            } catch (Exception ex) {
                ex.printStackTrace() ;
                System.exit(1) ;
            }
            // Declare the counter attribute
            a = new IntegerAttribute("counter"
                                     , new Integer(0)
                                     , Attribute.EDITABLE) ;
            ATTR_COUNTER = AttributeRegistry.registerAttribute(cls, a) ;
        }

        /**
         * We count all accesses, even the one that failed.
         * @param request The request being processed.
         */

        public synchronized int ingoingFilter(Request request) {
            int i = getInt (ATTR_COUNTER, 0) ;
            setInt(ATTR_COUNTER, i+1) ;
            return DontCallOutgoing ;
        }

    }

That's all ! However, this needs a bit more explanations. First of all, you might be surprised that we didn't provide an implementation for the `outgoingFilter` method. There is two reasons for this: the first one is that our super-class provide an empty `outgoingFilter` method, this solves the compiler problem. The second one is that as you might have noticed, our `ingoingFilter` returns a special integer, DontCallOutgoing. This integers tells the target filtered resource that the filter has performed all its tasks in the `ingoingFilter` method, so there is no need to call its `outgoingFilter` method.

Note that the counter value will be made persistent across servers invocation by the Jigsaw runtime. To be clear, this means that you can shutdown the server, and restart it: the count will keep up to date. Now, enough coding, let's play with our filter, the next section explains how to attach an instance of the filter to some target resource.

## Installing the filter

First, let's decide on some resource we want to count access to. For the sake of simplicity, let's say we want to count the number of accesses to the `/User` directory resource. As you might have guess, the first thing we want to do is to point our favorite browser to `/Admin/Editor/User`. This, as expected, brings up the form to edit the `/User` directory resource. We follow the AddFilter link at the bottom of the page, which prompts us for the filter's class. We fill this with `w3c.jigsaw.filters.CounterFilter`, and press the OK button. The `/User` directory resource editor now has two more link (at the bottom of the page), we follow the w3c.jigsaw.filter.CounterFilter one, to customize our filter attributes. The count is 0, and we don't care about the filter's name.

Now, we can access `/User` (point your browser to `/User`). Reload the filter's editor...the value is still 0, however, internally the value is now 1. To check this, restart the server (by using the `/Admin/PropertiesEditor` restart button). NOTE: form some reason, the editor of a resource doesn't update the attribute value it displays when they change behind the scene, this is why you still see the count has being 0. This should be fixed really soon.

## Further reading

If you want to understand better the concept of filters, then you can look at the available filters, here is a path (by increasing complexity):

- Start by reading the code of the DebugFilter. This one has an `outgoingFilter` method, and doesn't represent a significant step in complexity.
- You can then try to read the code of the AccessLimitFilter. It doesn't use more features then the one above, but the synchronized methods it relies on are significantly more complex then the previous to examples.
- Now, if you are courageous enough, you can go to the GenericAuthFilter. Once you have understand this one, then you can carry on with the following lists of possible filters (left as an exercise to the reader)
- Try to write a filter that will log the referer field of the requests (this can be pretty easy if done in the naive way, and can become much complex if you want to use a something more efficient).

Enjoy !

Jigsaw Team
$Id: filter.html,v 1.11 1998/05/27 13:39:18 yves Exp $