JasperReports Ultimate Guide - Samples - Schema - Configuration - Functions - FAQ - API (Javadoc)

JasperReports - Generic Element Sample (version 6.21.0)


Shows how generic elements embedded in reports can be managed at export time by custom handlers.

Download All Sample Source Files
Browse Sample Source Files on Git


Main Features in This Sample

Generic Elements


top

Generic ElementsDocumented by Sanda Zaharia


Description / Goal
How to implement and use generic elements to embed custom content into reports.

Since
3.1.0


Generic Elements - Overview

Generic elements are built-in placeholders to be declared in a report template at report design time, in order to reserve space for special content available only at export time, generated in a specific manner by different exporters. At report filling time generic elements are processed into generic print elements that reserve room for their future content and evaluate report element expressions. Expression results will be stored as parameter values in the generic print element.
The necessity of generic elements comes from the fact that some output formats do provide dedicated support for embedding various objects that are not available in the JasperReports built-in elements gallery. Such an example is the case of embedding Flash movies in reports when they are exported to HTML format. JasperReports deals naturally with displaying text, shapes and images, but there is no built-in element for displaying Flash movies. When exporting to HTML, the empty space reserved by the generic element can be filled with specific Flash movie content generated by the HTML export handler registered for Flash movies type.

Generic Elements - Schema

Below is the schema of a generic element:
<element name="genericElement">
  <annotation>
    <documentation></documentation>
  </annotation>
  <complexType>
    <sequence>
      <element ref="jr:reportElement"/>
      <element ref="jr:genericElementType"/>
      <element ref="jr:genericElementParameter" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="evaluationTime" use="optional" default="Now" type="jr:complexEvaluationTime">
      <annotation>
        <documentation></documentation>
      </annotation>
    </attribute>
    <attribute name="evaluationGroup" type="string" use="optional">
      <annotation>
        <documentation></documentation>
      </annotation>
    </attribute>
  </complexType>
</element>

<element name="genericElementType">
  <annotation>
    <documentation></documentation>
  </annotation>
  <complexType>
    <attribute name="namespace" type="string" use="required">
      <annotation>
        <documentation></documentation>
      </annotation>
    </attribute>
    <attribute name="name" type="string" use="required">
      <annotation>
        <documentation></documentation>
      </annotation>
    </attribute>
  </complexType>
</element>

<element name="genericElementParameter">
  <annotation>
    <documentation></documentation>
  </annotation>
  <complexType>
    <sequence>
      <element name="valueExpression" minOccurs="0" maxOccurs="1">
        <annotation>
          <documentation>Indicates the specific <code>&lt;valueExpression&gt;</code> tag for generic element parameters. 
          Unlike other <code>&lt;valueExpression&gt;</code> elements, it contains a <code>class</code> attribute.</documentation>
        </annotation>
        <complexType mixed="true">
          <attribute name="class" type="string" use="optional" default="java.lang.Object">
            <annotation>
	          <documentation></documentation>
            </annotation>
          </attribute>
        </complexType>
      </element>
    </sequence>
    <attribute name="name" type="string" use="required">
      <annotation>
        <documentation></documentation>
      </annotation>
    </attribute>
    <attribute name="skipWhenNull" type="boolean" use="optional" default="false">
      <annotation>
        <documentation></documentation>
      </annotation>
    </attribute>
  </complexType>
</element>
In order to be well defined, a generic element must contain:
  • a reportElement definition, like any other JR element
  • a genericElementType - that identifies the class/type the generic element belongs to. Export element handlers are registered with generic element types, in order to handle uniformly elements of the same type. Types are characterized by:
    • namespace - usually an URI associated with an organization or a product
    • name - the name of the class/type
  • any number of genericElementParameters to store parameter values to be used by the export element handlers to produce the required output in the exported report.
Notice also the evaluationTime and evaluationGroup attributes, with the same meanings as in other JR report elements.

Export Element Handlers

Export element handlers provide the mechanism able to generate specific content associated with a given generic element type at export time. Usually handlers that share the same type namespace are packed together in a handler bundle. Handler bundles are deployed as JasperReports extensions, using the GenericElementHandlerBundle as extension type.
Generic element handlers are also specific to a report exporter. Currently only the HTML exporter features support for generic elements. A generic element handler that has to be used for the HTML exporter would implement the GenericElementHtmlHandler interface.

Generic Elements Sample

This sample shows how to embed a special HTML snippet into a report to show content coming from a public website. The GenericElementReport.jrxml file contains two generic elements configured to embed specific statistics widgets for the JasperReports project, provided by the ohloh.net site.
<genericElement>
  <reportElement x="0" y="100" width="400" height="200" style="widget1"/>
  <genericElementType namespace="http://jasperreports.sourceforge.net/jasperreports/ohloh" name="languages"/>
  <genericElementParameter name="ProjectID">
    <valueExpression class="java.lang.Integer"><![CDATA[$P{JRProjectID}]] ></valueExpression>
  </genericElementParameter>
</genericElement>
<genericElement>
  <reportElement x="420" y="100" width="400" height="200"/>
  <genericElementType namespace="http://jasperreports.sourceforge.net/jasperreports/ohloh" name="stats"/>
  <genericElementParameter name="ProjectID">
    <valueExpression class="java.lang.Integer"><![CDATA[$P{JRProjectID}]] ></valueExpression>
  </genericElementParameter>
</genericElement>
Both generic elements share the same namespace, but they have different names. This means that there are two different types (languages and stats) to be processed at export time using specific export handlers.
In our example both languages and stats types are processed identically, using the same handler. One can see the handler class in the src/net/sf/jasperreports/ohloh directory:
  • OhlohWidgetHtmlHandler - registered for the HTML output format
To register these handlers, two properties were defined in the jasperreports_extension.properties file:
  • net.sf.jasperreports.extension.registry.factory.jr.statistics=net.sf.jasperreports.extensions.SpringExtensionsRegistryFactory - indicates that the extensions registry factory for jr.statistics is based on the Spring framework.
  • net.sf.jasperreports.extension.jr.statistics.spring.beans.resource=net/sf/jasperreports/ohloh/beans.xml - is pointing to the Spring beans.xml XML bundle.
In the beans.xml file is configured the export handlers bundle associated with the http://jasperreports.sourceforge.net/jasperreports/ohloh namespace:
<bean id="ohlohExportHandlerBundle" 
    class="net.sf.jasperreports.engine.export.DefaultElementHandlerBundle">
  <property name="namespace" value="http://jasperreports.sourceforge.net/jasperreports/ohloh"/>
  <property name="elementHandlers">
    <map>
      <entry key="languages">
        <map>
          <entry key="net.sf.jasperreports.html">
            <ref bean="languagesHtmlExportHandler"/>
          </entry>
        </map>
      </entry>
      <entry key="stats">
        <map>
          <entry key="net.sf.jasperreports.html">
            <ref bean="statsHtmlExportHandler"/>
          </entry>
        </map>
      </entry>
    </map>
  </property>
</bean>

<bean id="baseHtmlExportHandler" class="net.sf.jasperreports.ohloh.OhlohWidgetHtmlHandler"
    abstract="true">
  <property name="projectIDParameter" value="ProjectID"/>
</bean>

<bean id="languagesHtmlExportHandler" class="net.sf.jasperreports.ohloh.OhlohWidgetHtmlHandler"
    parent="baseHtmlExportHandler">
  <property name="widgetName" value="project_languages"/>
</bean>

<bean id="statsHtmlExportHandler" class="net.sf.jasperreports.ohloh.OhlohWidgetHtmlHandler"
    parent="baseHtmlExportHandler">
  <property name="widgetName" value="project_basic_stats"/>
</bean>
Notice the languages and stats keys in the exporter bundle map, each one providing a handler for the HTML format.
Also notice the Spring bean property widgetName defined for all export handlers, in order to store the widget name required at export time.
Further, one can see that net.sf.jasperreports.ohloh.OhlohWidgetHtmlHandler class handles both languages and stats for the HTML output, preparing a <script/> snippet to be included in the generated HTML document, in order to request a specific widget from the ohloh.net site.

Now it's time go back to generic elements in the JRXML file. The only two parameters required by the ohloh.net site in order to process the requested statistics, are the project ID and the widget name. Therefore, both generic elements in the JRXML contain the following generic element parameter:
<genericElementParameter name="ProjectID">
  <valueExpression class="java.lang.Integer"><![CDATA[$P{JRProjectID}]] ></valueExpression>
</genericElementParameter>
The widget name parameter is injected as Spring bean property, as shown above.

Running the Sample

Running the sample requires the Apache Ant library. Make sure that ant is already installed on your system (version 1.5 or later).
In a command prompt/terminal window set the current folder to demo/samples/genericelement within the JasperReports source project and run the > ant test view command.
It will generate the HTML pages containing the sample report in the demo/samples/genericelement/build/reports directory.
Then the report will open in the JasperReports internal viewer.



© 2001- Cloud Software Group, Inc. www.jaspersoft.com