Filter Configurations
Filters are added to an action using the <filter> element. They appear as children of an <action> element, following the action's <param> elements.
The class attribute may be used to identify a class implementing the Filter interface. As an alternative, the name attribute may be used to reference a filter class, that has been registered by a plugin under some unique name.
The when attribute can be used to specify a JSP EL expression (without "${" and "}") to conditionally execute the filter. During action invocation, the expression will be evaluated to a boolean value. If it results to true, the filter is executed as usual. Otherwise, the filter will be skipped and is not part of the filter chain for that request.
The <filter> element may contain any number of <param> elements as well as <dispatch> elements.
The Filter interface defines the init() and filter() methods. For an action, the controller instantiates the filter instances and arranges them into a sequence in the same order the <filter> elements appear within the <action> element.
Since a filter class may be registered by a plugin, it is not uncommon for filters to implement both, the Plugin and Filter interfaces.
Examples
Calyxo Control comes with some ready-to-use filters, that we'll use here to illustrate filter definitions.
Branch Filter
The branch simply dispatches to a target according to its configuration. It is used with a filter when condition. The filter may be attached to an action like this:
<action path="/login" class="org.foo.bar.LoginAction">
<filter class="de.odysseus.calyxo.control.misc.BranchFilter"
when="!empty param.forgotten">
<dispatch action="/recoverPassword"/>
</filter>
...
</action>
The filter also implements the Plugin interface to associate the filter with some name. The default filter name is "branch". Therefore, to reference the filter by its default name, we add the plugin configuration
<plugin class="de.odysseus.calyxo.control.misc.BranchFilter"/>
to the <plugins> element. Now, we can rewrite the above action definition as
<action path="/login" class="org.foo.bar.LoginAction">
<filter name="branch" when="!empty param.forgotten">
<dispatch action="/recoverPassword"/>
</filter>
...
</action>
The dispatch configuration may be either specified directly by a nested anonymous dispatch configuration (as above) or by the target parameter referencing a dispatch configuration visible to the enclosing action:
<action path="/login" class="org.foo.bar.LoginAction">
<filter name="branch" when="!empty param.forgotten">
<param name="target" value="recover"/>
</filter>
...
<dispatch name="recover" action="/recoverPassword"/>
</action>
No-Cache Filter
The no-cache filter adds some HTTP response headers to prevent browsers from caching the page. The filter may be attached to an action like this:
<action path="/login" class="org.foo.bar.LoginAction"> <filter class="de.odysseus.calyxo.control.misc.NoCacheFilter"/> ... </action>
The filter also implements the Plugin interface to associate the filter with some name. The default filter name is "no-cache". Therefore, to reference the filter by its default name, we add the plugin configuration
<plugin class="de.odysseus.calyxo.control.misc.NoCacheFilter"/>
to the <plugins> element. Now, we can rewrite the above action definition as
<action path="/login" class="org.foo.bar.LoginAction"> <filter name="no-cache"/> ... </action>
Cancel Filter
Consider a form containing a "Cancel" button. When the user presses this button, we usually do not want the core action implementation to handle this. The cancel filter checks for the existence of a request parameter, "cancel" by default, and - if it exists - directly dispatches to some target, without executing the remaining chain. Again, the default dispatch target name is "cancel".
This could be done with the branch filter. However, since this is a common task, the filter is provided for convenience.
<action path="/register" class="org.foo.bar.RegisterAction"> <filter class="de.odysseus.calyxo.control.misc.CancelFilter"/> ... <dispatch name="cancel" action="/goodbye"/> </action>
Above, we used the filter's default "cancel" for the request parameter name and target dispatch name. If the request parameter name were "abort" and we wanted to use a global dispatch configuration named "goodbye", our action might look like this:
<action path="/register" class="org.foo.bar.RegisterAction">
<filter class="de.odysseus.calyxo.control.misc.CancelFilter">
<param name="parameter" value="abort"/>
<param name="target" value="goodbye"/>
</filter>
...
</action>
The CancelFilter class also implements the Plugin interface to associate the filter with some name. The default filter name is - no wonder - "cancel". Thus, after adding CancelFilter as a plugin, we could rewrite the above examples by replacing class="..." with name="cancel".
Finally, the target dispatch configuration may also be specified directly using a nested anonymous dispatch configuration element:
<action path="/register" class="org.foo.bar.RegisterAction">
<filter name="cancel">
<dispatch action="/goodbye"/>
</filter>
...
</action>


