In the tutorial How to create and use a JRDataSource adapter we have seen how to create a simple data adapter that gets the data from a custom class. One of the problem of that adapter was the managing of the fields. Suppose to use a custom JRDataSource providden by someone, how do you know which fields are required? Obviously you can read documentation on the data adapter or ask the author, but we will see another way to provide a data adapter, and integrated with it all these informations like list of fields, with name, description and type. We can do this by definig a custom datasource provider, a java class that implements the interface JRDataSourceProvider.
The interface JRDataSourceProvider
To create a custom datasource provider we need to implement the interface JRDataSourceProvider, lets see which method this interface require:
- boolean supportsGetFieldsOperation() : returns true if the provider supports the field retriving operation, using the method getField. By returning true in this method the data source provider indicate that it is able to introspect the data source and discover the available fields.
- public JRField getFields(JasperReport report) : Returns the fields that are available from the data source. The provider can use the passed in report to extract some additional configuration information such as report properties.
- public JRDataSource create(JasperReport arg0) : Creates and returns a new instance of the provided data source. The provider can use the passed in report to extract some additional configuration information such as report properties. In other words this return the class that implements a JRDataSource interface (like the class MyImplementation seen in How to create and use a JRDataSource adapter) that contains the real data.
- public void dispose(JRDataSource dataSource) : disposes the data source previously obtained using the create method. This method must close any resources associated with the data source.
Now we have a general idea on how this inderface does, but lets see a pratical example. In this example as data adapter for the create method we have used MyImplementation, seen in How to create and use a JRDataSource adapter, inside the implementation of the method create:
You can find this example attached.
Location of the class
This class to work must be placed in the same project folder where you have your custom data adapter (MyImplementation in the example). We can put the class in a new package, so right click in the project folder MyReports and select New->Package.
At this point right click on the CustomDataAdapter package and select New -> Class. On the dialog that will appear insert MyDataSource as class name. Then press the button Add to add a new interface and select JRDataSourceProvider, if you have done right the JRDataSourceProvider interface will appear in the list of the used interfaces. Finally hit the Finish button to create the new class. At this point you have to write the data adapter code, but for this example you can just copy and paste the code written before.
Creation of the Data Adapter
Now you have to create the data adapter that use this class, from select the element File -> New -> Data adapter.
From the dialog select the same project folder where you put the class (in this case MyReports) and has name of the file put MyCustomSource and hit Next. Now you have to choose the type of the data adapter, select JasperReports DataSource Provider Class and hit Next. At this point you must provide the information to get the class previously written:
- As name of the datasource you can put anything you like, in this case we can use MyCustomSource.
- On the field JasperReports DataSource Provider Class Name hit the button with three dots "...", and in the new dialog search for MyCustomSource and hit Ok. At the end in this field you should find something like CustomDataSource.MyDataSource.
Creation of the Report