You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by Lars Trieloff <la...@trieloff.net> on 2007/12/21 14:49:03 UTC

Scriptable Filters

Here is my proposal for scriptable filtering:

== Goal ==
We want to allow users with limited knowledge and interest in OSGi,  
Maven and Java to create filters in a similar fashion to creating  
scripts for request handling.

== Current Situation ==
Filters are OSGI components, implementing the Filter interface and  
having a defined scope of either request, response or resource  
(although I have only found examples of filter.scope=request).

== Solution ==
We implement a RequestScriptFilter, ResponseScriptFilter and  
ResourceScriptFilter class that in their doFilter method resolve a  
filter script, execute this filter script and continue in the filter  
chain. For each stage, only a single script is executed, script  
authors that need more than one filter script per stage have following  
options
- implementing a dispatcher script that will delegate to other filter  
scripts
- subclassing the *ScriptFilter class and overriding the getSelector()  
method, which is used in script resolution
- implementing a full-Sling filter using OSGi mechanisms
The *ScriptFilter have a default order of 0, authors who would like to  
change this order have two options:
- implementing a dispatcher script that will delegate to other filter  
scripts
- subclassing the *ScriptFilter class and overriding filter.order  
property definition
Scripts are resolved in the following way:

request filter scripts:
/filters/request[.selector].{extension} - the selector is optional if  
the getSelector() method return null (which is the default), the  
extension is determined by the ScriptFactory, eg. js for Javascript  
or .rb for Ruby

response filter scripts:
/filters/request[.selector].{extension} - as above

resource filter scripts:
/filters/{sling/nodetype}/filter[.selector].{extension} - selector and  
extension as above, sling/nodetype is the resolved path to the  
matching resource type or node type.

== Open Questions ==
Does it make sense to include the HTTP method in script resolution? If  
so, how to express default filters that apply to all methods?

regards,

Lars

--
Lars Trieloff
lars@trieloff.net
http://weblogs.goshaky.com/weblogs/lars


Re: Scriptable Filters

Posted by Michael Marth <mm...@day.com>.
Lars,

good suggestion IMO.
re the resource filter scripts:
If the filter scripts reside in a different location than render scripts
anyway, why not apply the same naming schema as for render scripts? (
html.esp, POST.esp, etc)
re the default:
can we just call it "default.esp"?

Michael

-- 
Michael Marth, http://dev.day.com

Re: Scriptable Filters

Posted by Lars Trieloff <la...@trieloff.net>.
Indeed, this looks good.

On 29.12.2007, at 20:59, Felix Meschberger wrote:

> Hi all,
>
> Scriptable Filters may be implemented based on my recent "Everything  
> is
> a Resource" proposal. See [1]
>
> Regards
> Felix
>
> [1]
> http://cwiki.apache.org/SLING/everything-is-a-resource.html#EverythingisaResource-4.3Filters
>
> Am Freitag, den 21.12.2007, 14:49 +0100 schrieb Lars Trieloff:
>> Here is my proposal for scriptable filtering:
>>
>> == Goal ==
>> We want to allow users with limited knowledge and interest in OSGi,
>> Maven and Java to create filters in a similar fashion to creating
>> scripts for request handling.
>>
>> == Current Situation ==
>> Filters are OSGI components, implementing the Filter interface and
>> having a defined scope of either request, response or resource
>> (although I have only found examples of filter.scope=request).
>>
>> == Solution ==
>> We implement a RequestScriptFilter, ResponseScriptFilter and
>> ResourceScriptFilter class that in their doFilter method resolve a
>> filter script, execute this filter script and continue in the filter
>> chain. For each stage, only a single script is executed, script
>> authors that need more than one filter script per stage have  
>> following
>> options
>> - implementing a dispatcher script that will delegate to other filter
>> scripts
>> - subclassing the *ScriptFilter class and overriding the  
>> getSelector()
>> method, which is used in script resolution
>> - implementing a full-Sling filter using OSGi mechanisms
>> The *ScriptFilter have a default order of 0, authors who would like  
>> to
>> change this order have two options:
>> - implementing a dispatcher script that will delegate to other filter
>> scripts
>> - subclassing the *ScriptFilter class and overriding filter.order
>> property definition
>> Scripts are resolved in the following way:
>>
>> request filter scripts:
>> /filters/request[.selector].{extension} - the selector is optional if
>> the getSelector() method return null (which is the default), the
>> extension is determined by the ScriptFactory, eg. js for Javascript
>> or .rb for Ruby
>>
>> response filter scripts:
>> /filters/request[.selector].{extension} - as above
>>
>> resource filter scripts:
>> /filters/{sling/nodetype}/filter[.selector].{extension} - selector  
>> and
>> extension as above, sling/nodetype is the resolved path to the
>> matching resource type or node type.
>>
>> == Open Questions ==
>> Does it make sense to include the HTTP method in script resolution?  
>> If
>> so, how to express default filters that apply to all methods?
>>
>> regards,
>>
>> Lars
>>
>> --
>> Lars Trieloff
>> lars@trieloff.net
>> http://weblogs.goshaky.com/weblogs/lars
>>
>

--
Lars Trieloff
lars@trieloff.net
http://weblogs.goshaky.com/weblogs/lars


Re: Scriptable Filters

Posted by Felix Meschberger <fm...@gmail.com>.
Hi all,

Scriptable Filters may be implemented based on my recent "Everything is
a Resource" proposal. See [1]

Regards
Felix

[1]
http://cwiki.apache.org/SLING/everything-is-a-resource.html#EverythingisaResource-4.3Filters

Am Freitag, den 21.12.2007, 14:49 +0100 schrieb Lars Trieloff:
> Here is my proposal for scriptable filtering:
> 
> == Goal ==
> We want to allow users with limited knowledge and interest in OSGi,  
> Maven and Java to create filters in a similar fashion to creating  
> scripts for request handling.
> 
> == Current Situation ==
> Filters are OSGI components, implementing the Filter interface and  
> having a defined scope of either request, response or resource  
> (although I have only found examples of filter.scope=request).
> 
> == Solution ==
> We implement a RequestScriptFilter, ResponseScriptFilter and  
> ResourceScriptFilter class that in their doFilter method resolve a  
> filter script, execute this filter script and continue in the filter  
> chain. For each stage, only a single script is executed, script  
> authors that need more than one filter script per stage have following  
> options
> - implementing a dispatcher script that will delegate to other filter  
> scripts
> - subclassing the *ScriptFilter class and overriding the getSelector()  
> method, which is used in script resolution
> - implementing a full-Sling filter using OSGi mechanisms
> The *ScriptFilter have a default order of 0, authors who would like to  
> change this order have two options:
> - implementing a dispatcher script that will delegate to other filter  
> scripts
> - subclassing the *ScriptFilter class and overriding filter.order  
> property definition
> Scripts are resolved in the following way:
> 
> request filter scripts:
> /filters/request[.selector].{extension} - the selector is optional if  
> the getSelector() method return null (which is the default), the  
> extension is determined by the ScriptFactory, eg. js for Javascript  
> or .rb for Ruby
> 
> response filter scripts:
> /filters/request[.selector].{extension} - as above
> 
> resource filter scripts:
> /filters/{sling/nodetype}/filter[.selector].{extension} - selector and  
> extension as above, sling/nodetype is the resolved path to the  
> matching resource type or node type.
> 
> == Open Questions ==
> Does it make sense to include the HTTP method in script resolution? If  
> so, how to express default filters that apply to all methods?
> 
> regards,
> 
> Lars
> 
> --
> Lars Trieloff
> lars@trieloff.net
> http://weblogs.goshaky.com/weblogs/lars
> 


Re: Scriptable Filters

Posted by Carsten Ziegeler <cz...@apache.org>.
I think a servlet filter is more flexible than this proposed solution.
In a servlet filter you can modify the request and response before
calling the next component in the filter change, you can decide to call
the next in the chain and you can clean up or do some interesting stuff
when the next component in the chain has done its work.

So I think we need a way to mimic this instead of defining something new.


Carsten

Felix Meschberger wrote:
> Hi Lars,
> 
> Am Freitag, den 21.12.2007, 16:26 +0100 schrieb Lars Trieloff:
>> A typical servlet filter has following structure:
>>
>> - do something with the request
>> - call doFilter(request, response);
>> - do something with the response
> 
> I fear this does not work.... The request object has no setters to
> overwrite request internals and at the time the response filter is
> called, the response may already be committed. We could solve the
> request case in that the RequestScriptFilter class creates a request
> wrapper allowing the script set fields to overwrite.
> 
> For the response it is somewhat more complicated, especially if there is
> a lot of output, which when the response is not wrapped must be
> cached ....
> 
> So using request and response wrappers is easier and more stable to
> overwrite certain "data" and to modify input and output on the fly.
> 
>> In most of these filters only the request or the response is modified.  
>> With the separation of request.js and response.js I eliminate the  
>> necessity to call doFilter() which is too often forgotten and clearly  
> 
> Well, the problem is, that the Filter API defines a protocol. If this
> protocol is not followed, errors arise. I think, we should not try to
> work around people not being able to cope with protocols :-)
> 
>> separate request and response handling.
> 
> Not sure, whether it works that easily. In fact, sometimes processing
> may not even be separable for example if a filter decides based on the
> request, whether the next filter is to be called or a response should be
> generated and request processing terminated.
> 
> Regards
> Felix
> 
>> regards,
>>
>> Lars
>>
>> P.S. while writing this I see that it would be useful to have  
>> request.js and response.js also for resource-based filters. so please  
>> imagine following line:
>>
>> /filters/{sling/nodetype}/{request|response}[.selector].{extension}
>>
>> On 21.12.2007, at 15:25, Felix Meschberger wrote:
>>
>>> Hi Lars,
>>>
>>> Sounds simple and usefull.
>>>
>>> Just one question: What is the difference betwen the Request filter  
>>> and
>>> the Response filter ?
>>>
>>> And a clarification the script must/may wrap the request and response
>>> objects to inject new data, or do you think that only parameters would
>>> be "overwritten" ?
>>>
>>> Regards
>>> Felix
>>>
>>> Am Freitag, den 21.12.2007, 14:49 +0100 schrieb Lars Trieloff:
>>>> Here is my proposal for scriptable filtering:
>>>>
>>>> == Goal ==
>>>> We want to allow users with limited knowledge and interest in OSGi,
>>>> Maven and Java to create filters in a similar fashion to creating
>>>> scripts for request handling.
>>>>
>>>> == Current Situation ==
>>>> Filters are OSGI components, implementing the Filter interface and
>>>> having a defined scope of either request, response or resource
>>>> (although I have only found examples of filter.scope=request).
>>>>
>>>> == Solution ==
>>>> We implement a RequestScriptFilter, ResponseScriptFilter and
>>>> ResourceScriptFilter class that in their doFilter method resolve a
>>>> filter script, execute this filter script and continue in the filter
>>>> chain. For each stage, only a single script is executed, script
>>>> authors that need more than one filter script per stage have  
>>>> following
>>>> options
>>>> - implementing a dispatcher script that will delegate to other filter
>>>> scripts
>>>> - subclassing the *ScriptFilter class and overriding the  
>>>> getSelector()
>>>> method, which is used in script resolution
>>>> - implementing a full-Sling filter using OSGi mechanisms
>>>> The *ScriptFilter have a default order of 0, authors who would like  
>>>> to
>>>> change this order have two options:
>>>> - implementing a dispatcher script that will delegate to other filter
>>>> scripts
>>>> - subclassing the *ScriptFilter class and overriding filter.order
>>>> property definition
>>>> Scripts are resolved in the following way:
>>>>
>>>> request filter scripts:
>>>> /filters/request[.selector].{extension} - the selector is optional if
>>>> the getSelector() method return null (which is the default), the
>>>> extension is determined by the ScriptFactory, eg. js for Javascript
>>>> or .rb for Ruby
>>>>
>>>> response filter scripts:
>>>> /filters/request[.selector].{extension} - as above
>>>>
>>>> resource filter scripts:
>>>> /filters/{sling/nodetype}/filter[.selector].{extension} - selector  
>>>> and
>>>> extension as above, sling/nodetype is the resolved path to the
>>>> matching resource type or node type.
>>>>
>>>> == Open Questions ==
>>>> Does it make sense to include the HTTP method in script resolution?  
>>>> If
>>>> so, how to express default filters that apply to all methods?
>>>>
>>>> regards,
>>>>
>>>> Lars
>>>>
>>>> --
>>>> Lars Trieloff
>>>> lars@trieloff.net
>>>> http://weblogs.goshaky.com/weblogs/lars
>>>>
>> --
>> Lars Trieloff
>> lars@trieloff.net
>> http://weblogs.goshaky.com/weblogs/lars
>>
> 
> 


-- 
Carsten Ziegeler
cziegeler@apache.org

Re: Scriptable Filters

Posted by Felix Meschberger <fm...@gmail.com>.
Hi Lars,

Am Freitag, den 21.12.2007, 16:26 +0100 schrieb Lars Trieloff:
> A typical servlet filter has following structure:
> 
> - do something with the request
> - call doFilter(request, response);
> - do something with the response

I fear this does not work.... The request object has no setters to
overwrite request internals and at the time the response filter is
called, the response may already be committed. We could solve the
request case in that the RequestScriptFilter class creates a request
wrapper allowing the script set fields to overwrite.

For the response it is somewhat more complicated, especially if there is
a lot of output, which when the response is not wrapped must be
cached ....

So using request and response wrappers is easier and more stable to
overwrite certain "data" and to modify input and output on the fly.

> 
> In most of these filters only the request or the response is modified.  
> With the separation of request.js and response.js I eliminate the  
> necessity to call doFilter() which is too often forgotten and clearly  

Well, the problem is, that the Filter API defines a protocol. If this
protocol is not followed, errors arise. I think, we should not try to
work around people not being able to cope with protocols :-)

> separate request and response handling.

Not sure, whether it works that easily. In fact, sometimes processing
may not even be separable for example if a filter decides based on the
request, whether the next filter is to be called or a response should be
generated and request processing terminated.

Regards
Felix

> 
> regards,
> 
> Lars
> 
> P.S. while writing this I see that it would be useful to have  
> request.js and response.js also for resource-based filters. so please  
> imagine following line:
> 
> /filters/{sling/nodetype}/{request|response}[.selector].{extension}
> 
> On 21.12.2007, at 15:25, Felix Meschberger wrote:
> 
> > Hi Lars,
> >
> > Sounds simple and usefull.
> >
> > Just one question: What is the difference betwen the Request filter  
> > and
> > the Response filter ?
> >
> > And a clarification the script must/may wrap the request and response
> > objects to inject new data, or do you think that only parameters would
> > be "overwritten" ?
> >
> > Regards
> > Felix
> >
> > Am Freitag, den 21.12.2007, 14:49 +0100 schrieb Lars Trieloff:
> >> Here is my proposal for scriptable filtering:
> >>
> >> == Goal ==
> >> We want to allow users with limited knowledge and interest in OSGi,
> >> Maven and Java to create filters in a similar fashion to creating
> >> scripts for request handling.
> >>
> >> == Current Situation ==
> >> Filters are OSGI components, implementing the Filter interface and
> >> having a defined scope of either request, response or resource
> >> (although I have only found examples of filter.scope=request).
> >>
> >> == Solution ==
> >> We implement a RequestScriptFilter, ResponseScriptFilter and
> >> ResourceScriptFilter class that in their doFilter method resolve a
> >> filter script, execute this filter script and continue in the filter
> >> chain. For each stage, only a single script is executed, script
> >> authors that need more than one filter script per stage have  
> >> following
> >> options
> >> - implementing a dispatcher script that will delegate to other filter
> >> scripts
> >> - subclassing the *ScriptFilter class and overriding the  
> >> getSelector()
> >> method, which is used in script resolution
> >> - implementing a full-Sling filter using OSGi mechanisms
> >> The *ScriptFilter have a default order of 0, authors who would like  
> >> to
> >> change this order have two options:
> >> - implementing a dispatcher script that will delegate to other filter
> >> scripts
> >> - subclassing the *ScriptFilter class and overriding filter.order
> >> property definition
> >> Scripts are resolved in the following way:
> >>
> >> request filter scripts:
> >> /filters/request[.selector].{extension} - the selector is optional if
> >> the getSelector() method return null (which is the default), the
> >> extension is determined by the ScriptFactory, eg. js for Javascript
> >> or .rb for Ruby
> >>
> >> response filter scripts:
> >> /filters/request[.selector].{extension} - as above
> >>
> >> resource filter scripts:
> >> /filters/{sling/nodetype}/filter[.selector].{extension} - selector  
> >> and
> >> extension as above, sling/nodetype is the resolved path to the
> >> matching resource type or node type.
> >>
> >> == Open Questions ==
> >> Does it make sense to include the HTTP method in script resolution?  
> >> If
> >> so, how to express default filters that apply to all methods?
> >>
> >> regards,
> >>
> >> Lars
> >>
> >> --
> >> Lars Trieloff
> >> lars@trieloff.net
> >> http://weblogs.goshaky.com/weblogs/lars
> >>
> >
> 
> --
> Lars Trieloff
> lars@trieloff.net
> http://weblogs.goshaky.com/weblogs/lars
> 


Re: Scriptable Filters

Posted by Lars Trieloff <la...@trieloff.net>.
A typical servlet filter has following structure:

- do something with the request
- call doFilter(request, response);
- do something with the response

In most of these filters only the request or the response is modified.  
With the separation of request.js and response.js I eliminate the  
necessity to call doFilter() which is too often forgotten and clearly  
separate request and response handling.

regards,

Lars

P.S. while writing this I see that it would be useful to have  
request.js and response.js also for resource-based filters. so please  
imagine following line:

/filters/{sling/nodetype}/{request|response}[.selector].{extension}

On 21.12.2007, at 15:25, Felix Meschberger wrote:

> Hi Lars,
>
> Sounds simple and usefull.
>
> Just one question: What is the difference betwen the Request filter  
> and
> the Response filter ?
>
> And a clarification the script must/may wrap the request and response
> objects to inject new data, or do you think that only parameters would
> be "overwritten" ?
>
> Regards
> Felix
>
> Am Freitag, den 21.12.2007, 14:49 +0100 schrieb Lars Trieloff:
>> Here is my proposal for scriptable filtering:
>>
>> == Goal ==
>> We want to allow users with limited knowledge and interest in OSGi,
>> Maven and Java to create filters in a similar fashion to creating
>> scripts for request handling.
>>
>> == Current Situation ==
>> Filters are OSGI components, implementing the Filter interface and
>> having a defined scope of either request, response or resource
>> (although I have only found examples of filter.scope=request).
>>
>> == Solution ==
>> We implement a RequestScriptFilter, ResponseScriptFilter and
>> ResourceScriptFilter class that in their doFilter method resolve a
>> filter script, execute this filter script and continue in the filter
>> chain. For each stage, only a single script is executed, script
>> authors that need more than one filter script per stage have  
>> following
>> options
>> - implementing a dispatcher script that will delegate to other filter
>> scripts
>> - subclassing the *ScriptFilter class and overriding the  
>> getSelector()
>> method, which is used in script resolution
>> - implementing a full-Sling filter using OSGi mechanisms
>> The *ScriptFilter have a default order of 0, authors who would like  
>> to
>> change this order have two options:
>> - implementing a dispatcher script that will delegate to other filter
>> scripts
>> - subclassing the *ScriptFilter class and overriding filter.order
>> property definition
>> Scripts are resolved in the following way:
>>
>> request filter scripts:
>> /filters/request[.selector].{extension} - the selector is optional if
>> the getSelector() method return null (which is the default), the
>> extension is determined by the ScriptFactory, eg. js for Javascript
>> or .rb for Ruby
>>
>> response filter scripts:
>> /filters/request[.selector].{extension} - as above
>>
>> resource filter scripts:
>> /filters/{sling/nodetype}/filter[.selector].{extension} - selector  
>> and
>> extension as above, sling/nodetype is the resolved path to the
>> matching resource type or node type.
>>
>> == Open Questions ==
>> Does it make sense to include the HTTP method in script resolution?  
>> If
>> so, how to express default filters that apply to all methods?
>>
>> regards,
>>
>> Lars
>>
>> --
>> Lars Trieloff
>> lars@trieloff.net
>> http://weblogs.goshaky.com/weblogs/lars
>>
>

--
Lars Trieloff
lars@trieloff.net
http://weblogs.goshaky.com/weblogs/lars


Re: Scriptable Filters

Posted by Felix Meschberger <fm...@gmail.com>.
Hi Lars,

Sounds simple and usefull.

Just one question: What is the difference betwen the Request filter and
the Response filter ?

And a clarification the script must/may wrap the request and response
objects to inject new data, or do you think that only parameters would
be "overwritten" ?

Regards
Felix

Am Freitag, den 21.12.2007, 14:49 +0100 schrieb Lars Trieloff:
> Here is my proposal for scriptable filtering:
> 
> == Goal ==
> We want to allow users with limited knowledge and interest in OSGi,  
> Maven and Java to create filters in a similar fashion to creating  
> scripts for request handling.
> 
> == Current Situation ==
> Filters are OSGI components, implementing the Filter interface and  
> having a defined scope of either request, response or resource  
> (although I have only found examples of filter.scope=request).
> 
> == Solution ==
> We implement a RequestScriptFilter, ResponseScriptFilter and  
> ResourceScriptFilter class that in their doFilter method resolve a  
> filter script, execute this filter script and continue in the filter  
> chain. For each stage, only a single script is executed, script  
> authors that need more than one filter script per stage have following  
> options
> - implementing a dispatcher script that will delegate to other filter  
> scripts
> - subclassing the *ScriptFilter class and overriding the getSelector()  
> method, which is used in script resolution
> - implementing a full-Sling filter using OSGi mechanisms
> The *ScriptFilter have a default order of 0, authors who would like to  
> change this order have two options:
> - implementing a dispatcher script that will delegate to other filter  
> scripts
> - subclassing the *ScriptFilter class and overriding filter.order  
> property definition
> Scripts are resolved in the following way:
> 
> request filter scripts:
> /filters/request[.selector].{extension} - the selector is optional if  
> the getSelector() method return null (which is the default), the  
> extension is determined by the ScriptFactory, eg. js for Javascript  
> or .rb for Ruby
> 
> response filter scripts:
> /filters/request[.selector].{extension} - as above
> 
> resource filter scripts:
> /filters/{sling/nodetype}/filter[.selector].{extension} - selector and  
> extension as above, sling/nodetype is the resolved path to the  
> matching resource type or node type.
> 
> == Open Questions ==
> Does it make sense to include the HTTP method in script resolution? If  
> so, how to express default filters that apply to all methods?
> 
> regards,
> 
> Lars
> 
> --
> Lars Trieloff
> lars@trieloff.net
> http://weblogs.goshaky.com/weblogs/lars
>