lukeshannon.com

JasperReports Based Reporting & Java Web Development

Reports and Coffee

The Repository Advantage: Deploying JRXML to JRS

Introduction

In this article we will explore a few of the advantages of using JasperReports Server (JRS), specifically the repository and some of the advantages it provides for report deployment. We are going to look at how reports can be linked together in the repository to create a drill down effect. Part of this discussion will include widgets referred to as input controls. These can be used to collect data from clients before running the reports.

Repository and Input Controls Overivew

Repository

Before we begin lets review what the repository is:

  • A database that the JRS application is in constant communication with
  • Developers can deploy reports and their dependancies to the repository (rather than the file system)
  • Report outputs are stored in the repository (rather than the file system)
  • The repository can be easily backed up and restored with scripts provided by JasperSoft (see JRS Administrators Guide)
  • Everything added to the repository has a Type (folder, JRXML, Image, Jar, Data Source, etc), a Name (what a client sees) and an ID (unique identifier)

Input Controls

Some reports need information to be collected from the user before they run. Think of getting a transaction history for your credit card from online banking. You need to provide a start and end date before you can get the records, otherwise you would be waiting for a very long query to complete and then sorting through a long list of records (assuming you actually use your card often enough).

This is where input controls come in. They are the JRS repository element that provides a widgets to collect this sort of information from the user before the report runs.

From a report design point of view parameters are created to contain information passed in when the report runs. Thus parameters in JRXML map to input controls in JRS. With this data we capture we can do power manupilations to the query of the report. For a nice example of this please read this JR sample doc.

Input controls can allow for users to data in a text field (can be a date, number or raw text), pick options from a list or set of check boxes or simply check a boolean style check box. The options users choose from can be data base driven or a static list stored in the repository. There is more to be said on Input Controls, but for now this will get us started.

Lets discuss how all this comes into play when deploying a report.

The Reports

We are going to use the Foodmart data which ships with JRS Pro for this example. Both reports were created with iReport CE 4.0.
I am not going to go through the creation of the reports. We will go over making some configuration changes to a pie chart, but not how to make one from scratch. There are plenty of resources online that cover this.

Also in this article, deployment to JasperReports Server from iReport will be done using iReport's JasperServer Repository plugin. All these same steps can be also be done by logging into JRS and using the right click menu options and the various wizards.

I have included the reports for download should anyone wish to inspect them further or try them out. Click here to obtain a zip with both reports.

One thing to note. When designing reports in iReport, especially when using the CE editions, ensure to set the JasperReports (JR) compatibiltiy to be the same as the environment you intend to deploy too. This is done in Tools > Options. In the General tab there is a Compatibility tab were you can set the JR version you will deploy too. This is key. If you develop a report with a version of JR that is newer than the one you are deploying too, the resulting JRXML could contain references not supported by the older version resulting in errors when you attempt to execute the report.

The first report is called chart summary. It is a simple pie that shows the total salaries per department in a company, note the JRS logo in the upper right.

All the work is done in the query, we are simply just writing out the details in the chart:

select
	sum(e.salary) as salary,
	d.department_description as department,
	d.department_id as id
from employee e
	inner join department d on e.department_id = d.department_id
	group by d.department_description
					

The pie chart uses the department as the key expression and the salary as the value.

Simple enough. The desired functionality, in run time, is to be able to click on a slice of pie and get a report that lists all the individual salaries in the department.

To do this we create a seperate stand alone report that lists all the salaries for an individual department. The report looks like this.

The query of this report makes use of a parameter to ensure we are only seeing the salaries for a specific department, which we plan to determine at runtime.

SELECT
	e.salary,
     d.department_description AS department,
     e.last_name AS name
FROM
     employee e INNER JOIN department d ON e.department_id = d.department_id
WHERE
     d.department_id = $P{departmentId}
					

These are the reports. Lets look at deploying them to JRS and linking them together.

Deploying to JRS

For this report a JNDI data source was used that comes with the samples optionally installed with JRS Professional. However you can easily create your own JDBC or JNDI connection in the repository to reports can share. Just make sure that you create it in a location that users running the actually reports will have access too (permissions with in the repository will not be handled in this acticle. From a high level Users log into JRS and are assigned Roles. Items in the repository are assigned access permission based on Role or a specific User by a system administrator).

The deployment was done from iReport using the JasperReportsServer Repository Browser. It has a nice feature that allows for easy upload of the JRXML report being developed.

Steps:

  1. Create a name and label in the repository
  2. Associate the report unit with a data source
  3. Upload the JRXML
  4. Decide if resources should be uploaded (optional step)

The repository only keeps one version of the JRXML. Working with source control is a topic I plan to address in a separate article (coming soon).

On the topic of step 4, deciding if resource should be uploaded to the repository. If you deploy a report unit from iReport using the plugin to JRS, if the report contains local resources, the plugin will offer to update the path to these resources and add the element to the repository to the location listed in the new path. Lets talk about this.

Referencing Repository Locations

In the example above you can see the plugin is offering the path:

repo:jrs-logo.jpg
					

The term 'repo' is a path that lets the engine know this location is in the JRS repository. When creating a path you generally start with a '/' to denote the root level of the repository. From here you list the folder id(s) all the way down to the ID of the resource you wish to reference.

Best practice when working with files suchs as images, jars and properties files is to give both the label and the id of the element to be the same of the entire file name (including the extension). So in this case jrs-logo.jpg is both the id and label.

The following is an example of a path that references an image within an organization. The image ID is "JRLogo". It should have been named "JRLogo.png" to follow best practices, but it works just fine anyway.:

repo:/organizations/organization_1/images/JRLogo
					

If you are a CE user of JRS you will be confused by the term Organization. In JRS Professional there is a feature to assist clients who host multiple companies in JRS and don't wish them to see each other's data. This feature is called Multi Tenancy. Each tenanant is an Organization, complete with its own Users, Roles, folders and content. From a repository point of view there is a folder called organizations that contains each organization, organization_1 is the ID of the top level folder of this organization, next is a folder called images and finally the resource itself.

If a report is referencing this within the organization it can use a relative path:

repo:images/JRLogo
					

You will notes that in the path that the plugin has suggested (repo:jrs-logo.jpg) there is no '/'. In fact there is no path at all. This illustrates another important repository concept, the local resource.

When creating a report unit like we are doing we have the option to deploy something locally to the unit. This can be any dependancies the report has. The end result here is the resource is added to the repository but it only referenceable by the report unit. Nothing else in the repository can reference this.

In the case of an Image this might not make sense. If this is a logo I plan to use in a lot of reports I would probably want to deploy this to the repository on its own to a location that all the reports I want to use it in can access it.

But there are situations where a dependancy may be only used by this report and you don't wish anyone else being able to reference it. In these situations the image is placed in a folder called resource within the report unit. For this example this is what we will do by accepting the suggestion of the iReport plugin on deployment.

You can see from the repository the entire report unit once you have deployed it.

Once you have updated a path to a resource to use the 'repo' syntax, you may have an issue running the report in your local environment. There are two solutions for this.

The first is to run the report through the iReport plug. This entails a web services initated report execution on JRS with a JasperPrint object returned to iReport which is exported to the Preview iReport is set to show. This can be achieved by right clicking on the repository navigator and selecting 'Run JasperServer Report'.

The second option is to update the expression of the resource to know when to look locally and when to look in the repository.

To do this we will create a new parameter called runningLocally. It will be of type Boolean with a default value of 'false'. We will set the 'Use as Prompt' so iReport will display a dialogue allowing us to change the value when running in iReport (this setting is ignored by JRS).

In a JasperReports (JR) template a expression, including one to locate a resource can be a line of Java code. In this case a tenenary condition:

$P{runningLocally} ? "C:\\source\\lukeshannon.com\\images\\jrs-logo.jpg" : "repo:jrs-logo.jpg"
					

If the value of the parameter runningLocally is 'true' then the first path is used, otherwise the repository path is used. Since we have set 'Use as Prompt', when running locally we can set the value to true.

Since we will not override the default of this when the report is deployed to JRS there is no need to create an input control for this parameter. Next we will deploy our second report, the detailed report.

The steps are the same as the previous one except that we will need to create an Input Control to capture the departmentId value when the report executes.

Input Controls

In JRS when a report is deployed, if you wish to set the value of a parameter in the report upon execution (whether is be inputed by a user, passed in programatically or through the URL), an Input Control must be created in JRS.

This article is not going to go into the topic of Input Controls, which is a detailed topic. For this example we will simply create a single text value control. The type will be text, which is the only type of value that can be obtained from a URL. The input control's ID must match the Parameter name exactly (case sensitive).
For the type we create a Single Value control which is Mandatory (the report cannot run without this value supplied) and Visible (the user will be able to open this control and change the value).

When an input control is created of a single type, a data type must be created. This can be thought of as validation and ensures the correct value is collected by the control.

Like the image the Input Control and Data Type can be deployed in the repository and shared across report units or deployed locally (in the resource folder). For this example we will be deploying locally.

The deployed report looks like this.

Test both reports, either using the iReport plugin or by logging into JRS and executing them in a browser.

The final step is too configure the drill downs in the chart. Here is where things can get confusing. The repository only contains one version of the report. After your first deployment from iReport, the JS Repository plugin might have updated your report template to accommodate local resources that had been added to the repository (such as an image or subreport). Be careful not to over write that version of the report with your local one. I will be handling deployment and source control in a separate article along with what I hope will be some interesting tools.

So based on this you may have to obtain the JRXML for the server to make this modification. This can easily be done by double clicking on the JRXML file within the report unit (or right click on the JRXML and choosing open in editor).

Once the report is open simply right click on the pie chart element and select Chart Data. In Chart Data choose Details > Section Hyperlink.

For the Hyperlink target choose Self and the Hyperlink type choose Reference.

This enables links in the chart. Now we need to specify the values passed in on the link. Click on the Link Parameters Tab.

The parameter to specify a report is '_report'. In the expression put the location of the report to link to in the repo (without using the repo syntax).

Now we can add the departmentId parameter. For this we will specifiy the field in the report containing the departmentId. We have the key expression of this chart to be the department name (this means a slice of the pie for each department). If you add the departmentId as the hyper link details, the engine is clever enough to to put the appropriate Id for the department in the URL.

Making sure to save the report locally and then the JRXML can over right the repository version by right clicking on the JRXML and choosing Replace with Current Document.

The final step to ensure our drill down effect is smooth is to select the root level of the report in the JS Repository navigator and select Properties. In the tabs across the top choose Other tab. Ensure the Always Prompt is unchecked. This will stop the Input Control from loading up with the departmentId that is being passed from the chart before the report loads (we just want out users to see the detailed report for the department).

That should be it. Now a user can run the main chart report, click on a slice of pie, and see the salary details for the department represented by the slice.

Conclusion

We covered a lot in this article and I hope it was benificial. Happy Reporting!

Please continue to check the site for more articles or tutorials. Please send me comments or questions on this article here.


Useful links: JasperReports | iReport | Jasperserver