Product/Version: JasperReports Server Professional v3.5 | [toc] |
Step 1: Implement a custom Query Manipulator
To start, you will need to implement a custom query manipulator class, compile it, and add it to the server class path. The following is an example of such a query manipulator:
package com.jaspersoft.example.querymodifier; import java.util.Map; import org.acegisecurity.context.SecurityContextHolder; import com.jaspersoft.jasperserver.api.engine.common.service.IQueryManipulator; import com.jaspersoft.jasperserver.api.metadata.user.domain.impl.client.MetadataUserDetails; public class SimpleQueryManipulator implements IQueryManipulator public final static String ORGANIZATION = "$P{organization}"; public final static String USERNAME = "$P{username}"; public String updateQuery(String query, Map parameters) { MetadataUserDetails mud = (MetadataUserDetails)SecurityContextHolder .getContext() .getAuthentication().getPrincipal(); String username = mud.getUsername(); String organization = mud.getTenantId(); query = query.replace(ORGANIZATION, organization); query = query.replace(USERNAME, username); return query; } }
Step 2: Inject the Customer Query Manipulator into the Engine Service
Edit WEB-INF/applicationContext.xml in the JasperServer WAR.
1) Create a bean from your class.
<bean class="com.jaspersoft.example.querymodifier.SimpleQueryManipulator" id="simpleQueryManipulator" />
2) Include the new bean into the engineService bean in WEB-INF/applicationContext.xml.
<bean class="${bean.class.engineService}" destroy-method="release" id="engineService"> <property name="auditContext" ref="${bean.auditContext}" /> <property name="repositoryService"> <ref bean="${bean.repositoryService}" /> </property> <property name="dataSourceServiceFactories"> <ref bean="dataSourceServiceFactories" /> </property> <property name="compiledReportsCache"> <ref bean="${bean.engineService.compiledReportsCache}" /> </property> <!-- optional property for queryManipulator --> <property name="queryManipulator"> <ref bean="simpleQueryManipulator" /> </property> <property name="securityContextProvider" ref="${bean.securityContextProvider}" /> <property name="builtInParameterProviders" ref="builtInParameterProviders" /> <property name="reportParameterLabelKeyPrefix" value="net.sf.jasperreports.prompt.label." /> <property name="repositoryContextManager" ref="${bean.repositoryContextManager}" /> <property name="cacheableCompiledReports" ref="${bean.cacheableCompiledReports}" /> <property name="reportJarsProtectionDomainProvider" ref="reportsProtectionDomainProvider" /> </bean>
Step 3: Create a Query-based Input Control
Now, create an input control with a query like the following:
SELECT city FROM example WHERE username='$P{username}' AND organization='$P{organization}'
Step 4: Test
Assuming the following data, you should get the correct data tied to the logged in user based on their username and organization (or whatever other criterion you add to the QueryManipulator implementation) substituted into the query.
city | username | organization |
seattle | joe | west |
san jose | joe | west |
san francisco | jane | headquarters |
For example, logging in as "joe" in organization "west" will only return "seattle" and "san jose" to populate the input control.
Recommended Comments
There are no comments to display.