Germán Sancho
Germán Sancho

Reputation: 111

modify/override filter provided by Grails plugin

In my Grails project, I would like to override a filter provided by a plugin so it better fits my needs.

More specifically, the filter is defined so it is applied to all actions on all controllers: filterName(controller:"*", action:"*") { ... }, and I want to restrict it to only certain controllers.

I tried to create a filter class in my project with the same name as the filter I want to override, but the result is both filters are being executed on every request.

So does anyone know how to change/override/(or even deactivate) a filter provided by a plugin? Thanks in advance!

Upvotes: 3

Views: 1185

Answers (2)

Germán Sancho
Germán Sancho

Reputation: 111

dmahapatro's answer put me in the way to finding a solution: the key concept is getting access to the filterInterceptor bean, which contains the definitions of all filters in the Grails application. It can be accessed e.g. in the BootStrap.groovy file in order to modify available filters at application startup:

class BootStrap {
    def filterInterceptor

    def init = { servletContext ->
        // modify myPluginFilter provided by plugin so it 
        // is only applied to certain requests
        def myPluginFilterHandler = filterInterceptor.handlers.find{ it.filterConfig.name == 'myPluginFilter' }
        myPluginFilterHandler.filterConfig.scope.controller = 'myController'
        myPluginFilterHandler.filterConfig.scope.action = 'myAction'
        myPluginFilterHandler.afterPropertiesSet()

        log.info "myPluginFilter scope modified"
    }

    ...
}

This code is executed once at application startup and it finds the filter myPluginFilter (e.g., defined in a plugin) and changes its scope (the controller and action to which it is applied).

The filter could be destroyed instead of redefined by removing myPluginFilterHandler from the filterInterceptor.handlers collection.

Upvotes: 2

dmahapatro
dmahapatro

Reputation: 50245

You can try clearing the handlers from the new filter class in your project something like:

blockPluginFilter(controller:"*", action:"*"){
    before = {
        def compInterceptor = applicationContext.getBean("filterInterceptor", CompositeInterceptor)
        compInterceptor.handlers?.clear()
    }
}

Each filter has a configured spring bean filterInterceptor registered as a CompositeInterceptor which has an handle to all the filters represented as handlers. If you clear the handlers in the new filter (if it was not late) then you can avoid executing the filter from the plugin. You can create another filter in your project filter class to handle your customized logic. This would work only if the plugin's filter executes after this filter. You can clear the handlers in any other place but before the plugin's filter is hit.

Upvotes: 0

Related Questions