Jump to content
We've recently updated our Privacy Statement, available here ×
  • This documentation is an older version of Jaspersoft Studio User Guide. View the latest documentation.

    Using Collection of JavaBeans Data Sources

    A JavaBeans set data source allows you to use JavaBeans as data to fill a report. In this context, a JavaBean is a Java class that exposes its attributes with a series of getter methods, with the following syntax:

    public <returnType> getXXX()

    where <returnType> (the return value) is a generic Java class or a primitive type (such as int, double, and so on).

    In order to create a connection to handle JavaBeans, select Collection of JavaBeans in the list of data source types to bring up the dialog box shown in “JavaBeans set data source”.

    javabeans-data-adapter_357x339.png.1dedeba8081f7f224659e6199a03fd3e.png

    JavaBeans set data source

    Once again, the first thing to do is to specify the name of the new data source.

    Fields of a JavaBean Set Data Source

    One peculiarity of a JavaBeans set data source is that the fields are exposed through get methods. This means that if the JavaBean has a getXyz() method, xyz is the name of a record field (the JavaBean represent the record).

    In this example, the PersonBean object shows two fields: name and age; register them in the fields list as String and Integer, respectively.

    Create a new empty report and add the two fields by right-clicking the Fields node in the outline view and selecting Add field. The name and the type of the fields are: name (java.lang.String) and age (java.lang.Integer).

    Drag the fields into the Detail band and run the report (being sure the active connection is the Test Factory). To refer to an attribute of an attribute, you can use a special notation in which attributes are separated by periods. For example, to access the street attribute of a hypothetical Address class contained in the PersonBean, you can use the syntax address.street. The real call would be <someBean>.getAddress().getStreet().

    Layout of a JavaBeans-Based Report

    javabeans-layout_302x120.png.9e2dc49b64ac9edced3e177ca8c5d03e.png

    If the flag Use field description is set when you are specifying the properties of your JavaBeans set data source, the mapping between JavaBean attribute and field value is done using the field description instead of the field name. The data source only considers the description to look up the field value, and the field can have any name.

    Jaspersoft Studio provides a visual tool to map JavaBean attributes to report fields. To use it, open the query window, go to the tab JavaBean Data Source, insert the full class name of the bean you want to explore, and click Read attributes. The tab is populated with the attributes of the specified bean class.

    For attributes that are also Java objects, you can double-click the objects to display the objects’ other attributes.
    To map a field, select an attribute name and click the Add Selected Field(s) button.

    Using XML Data Adapters

    JasperReports provides the ability to use XML as a data adapter in three different ways: XML documents, remote XML documents, and XML/A servers.

    An XML document is typically organized as a tree, and its structure hardly matches the table-like form required by JasperReports. For this reason, you have to use an XPath expression to define a node set. The specifications of the XPath language are available at http://www.w3.org/TR/xpath; it is used to identify values or nodes in an XML document. Some examples can help you understand how to define the nodes.

    The XML file in Example XML file is a hypothetical address book in which different people appear, grouped in categories. At the end of the categories list, a second list, of favorites objects, appears. In this case, it is possible to define different node set types. The choice is determined by how you want to organize the data in your report.

    Example XML file

    To select only the people contained in the categories (that is, all the people in the address book), use the following expression:

    /addressbook/category/person

    Four nodes are returned, as shown in “Node set with expression /addressbook/category/person”.

    Node set with expression /addressbook/category/person

    If you want to select the people appearing in the favorites node, the expression to use is

    /addressbook/favorites/person

    Two nodes are returned.

    Here is another expression. It is a bit more complex, but it shows all the power of the Xpath language. The idea is to select the person nodes belonging to the work category. The expression to use is the following:

    /addressbook/category[@name = "work"]/person

    The expression returns only one node, that with an ID equal to 4, as shown here:

    After you have created an expression for the selection of a node set, you can proceed to the creation of an XML data source.

    Open the window for creating a new data source and select XML File data source from the list of connection types to bring up the dialog box shown in “Configuring an XML Data Adapter”.

    xml-data-adapter_357x341.png.5d6082263ff372354d87f80b5e51a240.png

    Configuring an XML Data Adapter

    The only mandatory information to specify is the XML file name. Optionally, you can provide a set of nodes, using a pre-defined static XPath expression. Alternatively, the XPath expression can be set directly inside the report.

    I always suggest that you use a report-defined XPath expression. The advantage of this solution is the ability to use parameters inside the XPath expression, which acts like a real query on the supplied XML data. Optionally, you can specify Java patterns to convert dates and numbers from plain strings to more appropriate Java objects (like Date and Double). For the same purpose, you can define a specific locale and time zone to use when parsing the XML stream.

    Registration of Fields for an XML Data Source

    In the case of an XML data source, the definition of a field in the report needs a particular expression inserted as a field description in addition to the type and the name. As the data source aims always to be one node of the selected node set, the expressions are relative to the current node.

    To select the value of an attribute of the current node, use the following syntax:

    @<name attribute>

    For example, to define a field that must point to the id attribute of a person (attribute id of the node person), it is sufficient to create a new field, name it as you want, and set the description to

    @id

    Similarly, it is possible to get to the child nodes of the current node. For example, if you want to refer to the lastname node, child of person, use the following syntax:

    lastname

    To move to the parent value of the current node (for example, to determine the category to which a person belongs), use a slightly different syntax:

    ancestor::category/@name

    The ancestor keyword indicates that you are referring to a parent node of the current node; in particular, you are referring to the first parent of category type, of which you want to know the value of the name attribute.

    Now, let’s see everything in action. Prepare a simple report with the registered fields shown here:

    Field name

    Description

    Type

    id

    @id

    Integer

    lastname

    lastname

    String

    firstname

    firstname

    String

    name of category

    ancestor::category/@name

    String

    Jaspersoft Studio provides a visual tool to map XML nodes to report fields; to use it, open the query window and select XPath as the query language. If the active connection is a valid XML data source, the associated XML document is shown in a tree view. To register the fields, set the record node by right-clicking a Person node and selecting the menu item Set record node. The record nodes are displayed in bold.

    Then one by one, select the nodes or attributes and select the pop-up menu itemAdd node as field to map them to report fields. Jaspersoft Studio determines the correct XPath expression to use and creates the fields for you. You can modify the generated field name and set a more suitable field type after the registration of the field in the report (which happens when you close the query dialog).

    Insert the different fields into the Detail band. The XML file used to fill the report is that shown:

    The XPath expression for the node set selection specified in the query dialog is:

    /addressbook/category/person

    XML Data Source and Subreports

    A node set allows you to identify a series of nodes that represent, from a JRDataSource point of view, some records. However, due to the tree-like nature of an XML document, it may be necessary to see other node sets that are subordinated to the main nodes.

    Consider the XML in Complex XML example. This is a slightly modified version of the document presented in “Example XML file”. For each person node, a hobbies node is added which contains a series of hobby nodes and one or more e-mail addresses.

    Complex XML example

    What we want to produce is a document that is more elaborate than those you have seen until now—for each person, we want to present their e-mail addresses, hobbies, and favorite people.

    To obtain such a document, use subreports; in particular, you need a subreport for the e-mail addresses list, one for hobbies, and one for favorite people (that is a set of nodes out of the scope of the XPath query we used). To generate these subreports, you need to understand how to produce new data sources to feed them. In this case, you use the JRXmlDataSource, which exposes two extremely useful methods:

    public JRXmlDataSource dataSource(String selectExpression)

    public JRXmlDataSource subDataSource(String selectExpression)

    The difference between the two is that the first method processes the expression by applying it to the whole document, starting from the actual root, while the second assumes the current node is the root.

    Both methods can be used in the data source expression of a subreport element to produce dynamically the data source to pass to the element. The most important thing to note is that this mechanism allows you to make both the data source production and the expression of node selection dynamic.

    The expression to create the data source that feeds the subreport of the e-mail addresses is:

    	((net.sf.jasperreports.engine.data.JRXmlDataSource)		$P{REPORT_DATA_SOURCE}).subDataSource("/person/email")

    This code returns all the e-mail nodes that are direct descendants of the present node (person).

    The expression for the hobbies subreport is similar, except for the node selection:

    ((net.sf.jasperreports.engine.data.JRXmlDataSource)

    $P{REPORT_DATA_SOURCE}).subDataSource("/person/hobbies/hobby")

    Next, declare the master report’s fields. In the subreport, you have to refer to the current node value, so the field expression is simply a dot (.),

    Proceed with building your three reports: xml_addressbook.jasper, xml_addresses.jasper, and xml_hobbies.jasper.

    In the master report, xml_addressbook.jrxml, insert a group named “Name of category,” in which you associate the expression for the category field ($F{name of category}). In the header band for Name of category, insert a field to display the category name. By doing this, the names of the different people are grouped by category (as in the XML file).

    In the Detail band, position the id, lastname, and firstname fields. Underneath these fields, add the two Subreport elements, the first for the e-mail addresses, the second for the hobbies.

    The e-mail and hobby subreports are identical except for the name of the field in each one. The two reports should be as large as the Subreport elements in the master report, so remove the margins and set the report width accordingly.

    Preview both the subreports just to compile them and generate the relative .jasper files. Jaspersoft Studio returns an error during the fill process, but that's expected. We haven't set an Xpath query, so JasperReports can't get any data. You can resolve the problem by setting a simple Xpath query (it isn't used in the final report), or you can preview the subreport using an empty data source (select it from the combo box in the tool bar).

    When the subreports are done, execute the master report. If everything is okay, the report groups people by home and work categories and the subreports associated with each person.

    As this example demonstrates, the real power of the XML data source is the versatility of XPath, which allows navigation of the node selection in a refined manner.

    Using XML/A Data Adapters

    XML for Analysis is an XML standard used to access remote data stored in an OLAP schema. Jaspersoft Studio supports an XML/A data adapter that can connect various XML/A providers such as JasperReports Server and Microsoft SQL Server Analytic Services (SSAS). Because Jaspersoft Studio uses OLAP4J (http://www.olap4j.org/), it may also be able to connect to other types of XML/A provider.

    The remote server must also be configured for XML/A. For more information, including instructions for configuring Jaspersoft OLAP, see the Jaspersoft OLAP User Guide .

    To create an XML/A Data Adapter:

    1. Right-click Data Adapters in the Repository Explorer, and select Create Data Adapter.
    2. Select XML/A Server and click Next.
    3. Enter a name for the data adapter.
    4. Enter the URL for your XML/A provider.

    The type of server determines the value you must specify.For example:

         If the XML/A server is JasperReports Server, the URL is something like http://<hostname>:<port>/jasperserver-pro/xmla
         If the XML/A server is Microsoft SSAS 2012, he URL is something like http://<hostname>/MSSQL_2012/msmdpump.dll
    5. Enter a user name and password of a user that has sufficient access in the report server to return your data. If you leave these fields blank, Jaspersoft Studio prompts you for them.
    6. Click Get Metadata.

    Jaspersoft Studio attempts to connect to the server and return information about its data sources, catalogs, and cubes. If it is successful, default values appear in the drop-downs. If the connection fails, check the URL, ensure that the remote server is available, and try again.

    7. Select the data source, catalog, and cube that stores the data you want to fill your report.
    8. Click Test.

    Jaspersoft Studio attempts to connect to the server and read the cube you selected. If it connects, a message indicating success appears. If the connection fails, check the URL, ensure that the remote server is available, and try again.

    9. When the test succeeds, click OK to close the message and click Finish to close the New Data Adapter wizard.

    When you create a report using this data adapter, you may see a message indicating that the data adapter doesn't support the ability to retrieve fields. The point of this message is that Jaspersoft Studio does not have enough information at this point to preview your data. Once you supply an MDX query, Jaspersoft Studio can automatically read fields and suggest their datatypes.

    Registration of fields in XML/A Providers

    When you create an XML/A data adapter, you define the cube from which to read data. Jaspersoft Studio can then inspect the remote server and suggest datatypes for the fields returned.

    To register fields returned by an XML/A data adapter:

    1. With your report open in the design pane, click dataset-and-query-button.png.89a1ab2b11b67c86cac685807c1e8673.png
    2. Select the data adapter that points to your XML/A provider from the drop-down in the upper-left corner.
    3. Select MDX from the Language drop-down.
    4. Enter a valid MDX query in the text field.

    To create a good MDX query, you must be familiar with both the language itself and the data you want to work with. If you are unfamiliar with MDX or the data in your cube, you can use a tool (such as the Jaspersoft OLAP Workbench) to load your OLAP schema and automatically generate MDX queries from it.

    5. Click Read Fields.

    Jaspersoft Studio returns the XML/A provider's data, including fields and parameters, and populates the window's tabs with information. For more information on how these tabs can be used to define the data in your report, see Creating Queries.

    Jaspersoft Studio also sets the class type of each field to an appropriate Java datatype. If Jaspersoft Studio sets an incorrect datatype, you can set the correct type after the fields are added to your report.

    6. When the data in the Data Preview tab looks like the data you want to fill your report, click OK to close the Dataset and Query window.

    Using CSV Data Sources

    Initially, the data source for CSV documents was a very simple data source proof-of-concept that showed how to implement a custom data source. The CSV data source interface was improved when JasperReports added a native implementation to fill a report using a CSV file.

    To create a connection based on a CSV file, click the New button in the Connections/Datasources dialog box and select File CSV data source from the data source types list to bring up the dialog box shown in “CSV Data Adapter”.

    csv-data-adapter_357x415.png.8adabc79c2dc2d372c540c439e06466a.png

    CSV Data Adapter

    Set a name for the connection and choose a CSV file. Then declare the fields in the data source.

    If the first line in your file contains the names of the columns, click the Get column names from the first row of the file button and select the Skip the first line check box option. This forces JasperReports to skip the first line (the one containing your column labels). In any case, the column names that are read from the file are used instead of the declared ones, so avoid modifying the names found with the Get column names button.
    If the first line of your CSV file doesn’t contain the column names, set a name for each column using the syntax COLUMN_0, COLUMN_1, and so on.

    warning-icon-ns_28x28.png.80c713d827ce610f95e67df2847da362.png

    If you define more columns than the ones available, you’ll get an exception at report filling time.

    JasperReports assumes that, for each row, all the columns have a value (even if they are empty).

    If your CSV file uses nonstandard characters to separate fields and rows, you can adjust the default setting for separators using the Separators tab.

    csv-separators_357x415.png.1fb9288461fccdd32dff6e37ebe76e14.png

    Separators Tab

    Registration of the Fields for a CSV Data Source

    When you create a CSV data source, you must define a set of column names that is used as fields for your report. To add them to the fields list, set your CSV data source as the active connection and open the Report query dialog box. Open the Dataset and Query Dialog and click the Read Fields button.

    By default, Jaspersoft Studio sets the class type of all fields to java.lang.String. If you are sure that the text of a particular column can be easily converted to a number, a date, or a Boolean value, set the correct field type yourself after the fields are added to your report.

    The pattern used to recognize a timestamp (or date) object can be configured at the data source level by selecting the Use custom date format check box option.

    Using JREmptyDataSource

    JasperReports provides a special data source named JREmptyDataSource.

    This source returns true to the next method for the record number (by default only one), and always returns null to every call of the getFieldValue method. It is like having records without fields, that is, an empty data source.

    The two constructors of this class are:

    public JREmptyDataSource(int count)public JREmptyDataSource()

     

    The first constructor indicates how many records to return, and the second sets the number of records to one.

    By default, Jaspersoft Studio provides a pre-configured empty data source that returns a single record.

    To create a new empty data source with more records:

    1. Double-click One Empty Record from the Repository View.

    The Data Adapter Wizard appears, with Empty rows.

    Data Adapter Wizard > Empty Record

    data-adapter-empty-record_357x277.png.1e891764c0d4c728ae4962f7ab4285f8.png

    2. Set the number or empty records that you need. Remember, whatever field you add to the report, its value is set to null. Since this data source doesn’t care about field names or types, this is a perfect way to test any report (keeping in mind that the fields are always set to null).
    3. Click Finish.

    Using HQL and Hibernate Connections

    JasperReports provides a way to use HQL directly in your report. To do so, first set up a Hibernate connection. Expand your classpath to include all classes, JARs, and configuration files used by your Hibernate mapping. In other words, Jaspersoft Studio must be able to access all the *.hbm.xml files you plan to use, the JavaBeans declared in those files, the hibernate.cfg.xml file, and any other JARs used (for example, JARs that access the database under Hibernate).

    To add these objects to the classpath:

    1. Right-click Data Adapters in the Repository Explorer, and select Create Data Adapter.
    2. Click the Driver Classpath tab.

    data-adapter-add-jar-files_357x375.png.351e6e26790053c89375b59e09fc47f2.png

    Data Adapter Wizard > Add JAR Files

    3. Click the Add button.
    4. Navigate to your JAR file.
    5. Click Open.
    6. Repeat for any additional files.
    7. Give your data adapter a unique name.
    8. Click the Test button to check the path resolution to be certain that hibernate.cfg.xml is in the classpath.

    Currently Jaspersoft Studio works only with the first hibernate.cfg.xml file found in the classpath.

    9. Click Finish.

    If you use the Spring framework, you can use a Spring configuration file to define your connection. In this case, you’ll need to set the configuration file name and the Session Factory Bean ID.

    Now that a Hibernate connection is available, use an HQL query to select the data to print. You can use HQL in the same way that you use SQL: open the Report query dialog box and choose HQL as the query language from the combo box at the top of the window.

    When you enter an HQL query, Jaspersoft Studio tries to retrieve the available fields. According to the JasperReports documentation, the field mappings are resolved as follows:

    If the query returns one object per row, a field mapping can be one of the following:
         If the object’s type is a Hibernate entity or component type, the field mappings are resolved as the property names of the entity/component. If a select alias is present, it can be used to map a field to the whole entity/component object.
         Otherwise, the object type is considered scalar, and only one field can be mapped to its value.
    If the query returns a tuple (object array) per row, a field mapping can be one of the following:
         A select alias. The field is mapped to the value corresponding to the alias.
         A property name prefixed by a select alias and a period (.). The field is mapped to the value of the property for the object corresponding to the alias. The type corresponding to the select alias has to be an entity or component.

    note-icon-ns_28x28.png.3f3f997f832f44bbfa62f4c2fa3f4087.png

    If you don’t understand this field mapping information, simply accept the fields listed by Jaspersoft Studio when the query is parsed.

    Jaspersoft Studio provides a mapping tool to map objects and attributes to report fields. The objects (or JavaBeans) available in each record are listed in the combo box on top of the object tree.

    To add a field from the tree, select the corresponding node and click the Add selected field(s) button.

    Using a Hadoop Hive Connection

    JasperReports provides a way to use Hive in your reports. Unlike traditional databases, Hadoop systems support huge amounts of data, generally called big data. However, this capability has a cost: high latency with access times between 30 seconds and 2 minutes.

    note-icon-ns_28x28.png.7e8f6240fedc0992d2f5e52d2500121a.png

    Because of the latency, reports based on Hadoop-Hive data sources are best suited to be run in the background or to be scheduled. For example, the report could be run at 6 a.m. and the HTML or PDF could be exported and stored for anyone wanting to access the report during the day.

    To use Hadoop Hive with Jaspersoft Studio:

    1. Double-click New Data Adapter in the Repository view.

    The Data Adapter Wizard opens.

    data-adapter-hadoop-hive_357x375.png.60f86c0cbb42ddc5d37e8b06ff6a5c24.png

    Hadoop Hive Connection

    2. Choose Hadoop Hive connection as your JDBC driver.
    3. Enter the path to your Hive JDBC.

    Usually it looks something like jdbc:hive://localhost:10000/default.

    4. Click the Test button to check the path resolution.
    5. Click Finish.

    Now that a Hive connection is available, use a HiveQL query to retrieve data in your report. You can use HiveQL the same way that you use SQL. To use a HiveQL query, open the Report Query dialog box and choose HiveQL as the query language from the combo box at the top of the window.

    When you enter a HiveQL query, Jaspersoft Studio retrieves all available fields. In the next two screens, select the fields you want to display in your report, and how you want to group them. After defining your HiveQL query and choosing your fields, your report is configured to receive data from your Hadoop Hive data source.

    warning-icon-ns_28x28.png.0fa8f04fabfb768bdfe38c6a3ff87664.png

    The Hive JDBC driver does not yet fully implement the JDBC specifications, and it does not yet work correctly with the JasperReports Server metadata layer (Data Domains). If reporting against a Hive data source and you are using JasperReports Server, use Topics rather than Domains.

    Implementing a New JRDataSource

    Sometimes the JRDataSource supplied with JasperReports cannot satisfy your needs. In these cases, it is possible to write a new JRDataSource. This operation is not complex; in fact, all you have to do is create a class that implements the JRDataSource interface that exposes two simple methods: next and getFieldValue:

    The JRDataSource interface

    The next method is used to set the current record into the data source. It has to return true if a new record to elaborate exists; otherwise it returns false.

    If the next method has been called positively, the getFieldValue method has to return the value of the requested field or null. In particular, the requested field name is contained in the JRField object passed as a parameter. Also, JRField is an interface through which it is possible to get the information associated with a field—the name, description, and Java type that represents it (as mentioned previously in Understanding the JRDataSource Interface).

    Now try writing your personalized data source. The idea is a little original—you have to write a data source that explores the directory of a file system and returns the found objects (files or directories). The fields you create to manage your data source are the same as the file name, which should be named FILENAME; a flag that indicates whether the object is a file or a directory, which should be named IS_DIRECTORY; and the file size, if available, which should be named SIZE.

    You data source should have two constructors: the first receives as a parameter the directory to scan; the second has no parameters and uses the current directory to scan.

    Once instantiated, the data source looks for the files and the directories present in the way you indicate and fill the array files.

    The next method increases the index variable that you use to keep track of the position reached in the array files, and returns true until you reach the end of the array.

    Sample personalized data source

    The getFieldValue method returns the requested file information. Your implementation does not use the information regarding the return type expected by the caller of the method, but it assumes that the name has to be returned as a string, the flag IS_DIRECTORY as a Boolean object, and the file size as a Long object.

    The next section shows how to use your personalized data source in Jaspersoft Studio and test it.

    Using a Custom JasperReports Data Source with Jaspersoft Studio

    Jaspersoft Studio provides support for almost all the data sources provided by JasperReports, such as JRXmlDataSource, JRBeanArrayDataSource, and JRBeanCollectionDataSource.

    To use your personalized data sources, a special connection is provided. It is useful for employing whatever JRDataSource you want to use through some kind of factory class that provides an instance of that JRDataSource implementation. The factory is just a simple Java class useful to test your data source and to fill a report in Jaspersoft Studio. The idea is the same as what you have seen for the JavaBeans set data source—it is necessary to write a Java class that creates the data source through a static method and returns it. For example, if you want to test the JRFileSystemDataSource in the previous section, you need to create a simple class like that shown in this code sample:

    Class for testing a custom data source

    This class, and in particular the static method that is called, executes all the necessary code for instancing the data source correctly. In this case, you create a new JRFileSystemDataSource object by specifying a way to scan the directory root ("/").

    Now that you have defined the way to obtain the JRDataSource you prepared and the data source is ready to be used, you can create the connection through which it can be used.

    Create a new connection as you normally would (see Creating and Using Database JDBC Connections), then select Custom implementation of JRDataSource from the list and specify a data source name such as TestFileSystemDataSource (or whatever name you want), as shown in “Configuring a Custom Data Adapter”.

    custom-data-adapter_357x325.png.b27917832242e80ce2ee04ad2cfcc219.png

    Configuring a Custom Data Adapter

    Next, specify the class and method to use to obtain an instance of your JRFileSystemDataSource, that is, TestFileSystemDataSource and test.

    note-icon-ns_28x28.png.b053a5f246ed66b7b05905c000e2e0e5.png

    There is no automatic method to find the fields managed by a custom data source.

    In this case, you know that the JRFileSystemDataSource provides three fields: FILENAME (String), IS_DIRECTORY (Boolean), and SIZE (Long). After you have created these fields, insert them in the report’s Detail band.

    Divide the report into two columns, and in the Column Header band, insert Filename and Size tags. Then add two images, one representing a document and the other an open folder. In the Print when expression setting of the Image element that is placed in the foreground, insert the expression $F{IS_DIRECTORY}, or use as your image expression a condition like the following:

    ($F{IS_DIRECTORY}) ? “folder.png” : “file.png”

    In this example, the class that instantiated the JRFileSystemDataSource was very simple. However, you can use more complex classes, such as one that obtains the data source by calling an Enterprise JavaBean or by calling a web service.


    User Feedback

    Recommended Comments

    There are no comments to display.



    Guest
    This is now closed for further comments

×
×
  • Create New...