Using Groovy in a Filter Expression

Summary

Let's say you have a need to access the authentication object in the filterExpression of the security xml. It can only be accessed from the principalExpression, which is in Groovy. The SQLGenerator can be configured so that nearly any Groovy expression can be added. This article will take you through an example.

Define a Groovy Function

The SQL generator has a hook for defining functions using snippets of Groovy code, so we will just define a "groovy" function that takes the string passed into it and evaluates it (this is just like the "eval" function in JavaScript). Here's the bean that we changed in applicationContext-semanticLayer.xml:

<bean id="defaultSQLGenerator"
      class="com.jaspersoft.commons.semantic.dsimpl.SQLGenerator"
      scope="prototype">
    <property name="functionTemplates">
        <map>
            ...
            <entry key="groovy">
                <value>
                    "'" + evaluate(args[0].value) + "'"
                </value>
            </entry>
        </map>
    </property>
</bean>

Using the Groovy Function in the Security XML file

The use case we are concerned with is accessing the user name of the current user from a filterExpression in the security XML. This can be obtained from the authentication variable in the Groovy scope.

Here's an example filterExpression:

<resourceAccessGrant id="account_ROLE_SUPERMART_MANAGER_account_row_grant2" 
                     orMultipleExpressions="true">
    <principalExpression>
        authentication.getPrincipal().getRoles().any{ it.getRoleName() in ['ROLE_SUPERMART_MANAGER'] }
    </principalExpression>
    <filterExpression>
        s.store_number == 24
        and (s.store_manager == groovy('authentication.principal.username')
        and 1 == 1)
    </filterExpression>
</resourceAccessGrant>

This test case doesn't do anything useful, but the Groovy call gets the right value and put it in the SQL.

Using Groovy in Calculated Fields

We tried using this in a calculated field and it works there too. Here are a couple instances of calculated fields using Groovy. The second one also gets the user name:

<field id="e.groovyEval"
       dataSetExpression="groovy('(5.0/6).toString()')"
       type="java.lang.String" />
 
<field id="e.groovyUser"
       dataSetExpression="groovy('authentication.principal.username')"
       type="java.lang.String" />
Feedback
randomness