JFreeReport Documentation
Introduction
JFreeReport is a successful embedded reporting engine. By providing a high degree of flexibility and minimal requirements for the execution environment, JFreeReport can be integrated into most programms with little effort.
The original design of the library itself was driven by the need to easily print Swing-TableModels. During the last four years, the original design of JFreeReport got transformed into a complete report generator system. It is important to note, that the original design did not include or anticipate the features implemented today.
The initial narrow focus on simple printing resulted in severe architectural problems of JFreeReport. The most notable limitations are certainly the missing support of subreports and the restriction of a band's height to a single page.
To solve all the problems, to lift all the restrictions and to bring JFreeReport's architecture into a clean and well-defined state, this is the aim of the new version, called JFreeReport 0.9.1 Main aim of the development is to remove all 'historical remainings', to cut down the unnecessary complex processes and to create a simple, cleanly structured library. The known advantages of the old system, how ever, should remain intact and should be extended if possible.
The development aims can be broken down into the following steps:
- Strict separation of data processing ("the reporting") and layouting ("content creation")
- Preserve the unmatched flexiblity of the report processing. JFreeReport allows to reconfigure the report definition while the report is being processed. (As far as I know, no other reporting engine allows that.) With this feature, one is able to create even irregular structures, as long as the rules for that can be implemented as Java-Function.
- Maintain JFreeReport's great extensibility at all levels of the library's architecture (OutputFormats, Functions, Report types, data sources, GUI, etc)
- create an simple, well structured codebase, which can be understood by everyone.
- Keep the system dependencies and requirements minimal, maximize the scalability.
Naturally, deep changes to the engine influence all other programms, which use JFreeReport. It is unavoidable that the changed API will be incompatible to any previously released version. As even minor API changes will break programms anyway, our development follow that path with full-force, happily refactoring or removing all ugly code. Once the JFreeReport 0.9 release is feature complete, the API will be driven to stability. At that point, only show-stoppers or complex features or bug-fixes will cause non-backward-compatible changes. Once JFreeReport reached 1.0, the API will be frozen for long-term maintainance. At that point, JFreeReport's code will maintain backward compatibility at all costs.
Reports, which use the API to create the report definition from scratch, are not be compatible with the new release. There will be no easy upgrade-path for these reports, as most classes referenced by that legacy code will be gone and the reporting logic changed radically. Applications, which use the XML definitions will enjoy an easier upgrade. A compatibility layer will be provided, which takes care of most of the gory details of transforming old report definitions into the new format. Of course, report definitions kept in the old format will not be able to use exciting new features.
The compatibilty layer consists of an XML-parser for the old report definitions and several LayoutController implementations to emulate the old behaviour of the engine. This allows to execute the old reports without explicitly porting them to the new system. For user defined functions, custom mapping rules have to be defined and/or implemented by the user.
More details on how the project 'JFreeReport' is now organized
Historical Note: The classical report process
The Layout oriented Reporting Process
JFreeReport 0.9 uses a completely different reporting approach. Instead of using the data as control factor for the report process, JFreeReport concentrates on the layout that should be generated. In the new model, JFreeReport iterates over the layout (the report definition). The data processing is controlled by embedded data control commands, which control the iteration over the data sources.
By concentrating on the desired output format, now it is realitivly easy to create reports, which are no longer bounds to the classical nested grouping structures. Groups are controlled by the defined data commands, and therefore it is possible to create paralell or even irregular grouping structures.
Each processing step of the layout processing forms an atomic unit. A layout processing step represents a simple work unit, for instance 'open element', 'process content', 'close element'. This fine grained state generation makes sure that the limitations of the previous versions of JFreeReport will no longer cause trouble when using these states for the report processing recovery which is needed for the paginated reports.
JFreeReport 0.8 already had the unique feature of being able to reconfigure the report processing at runtime. Combining this feature with the new layout driven report generation, functions are now able to affect every single aspect of the report processing.
With JFreeReport 0.9, we are now able to go even further. The actual implementation on how certain elements should be processed is now controlled by small classes. New report elements and/or new, possibly complex behaviour (Pivot-tables, for instance) can be added to the engine by implementing and registering custom LayoutController classes.
A strict separation of all subsystems and all the state machines involved ensures, that the reporting engine has a simple and small core.
The layouting and content generation subsystem has been fully decoupled from the JFreeReport core. The report engine generates the input events for the 'input-feed's of LibLayout. Neither does JFreeReport know the internals of Liblayout nor is LibLayout a JFreeReport specific extension. The layouting engine has been explicitly designed as an independent library. That separation reduces the tight coupeling between both libraries and increases the flexibility of the entire system.
Terms and Concepts
Flow control and available operations
The implemented default behaviour of the Report-Elements
Introduction
JFreeReport as an engine is not bound to a specific processing model. The LayoutControllers we use define a very abstract processs model, in common words, their interface says, that they do some work, but it does not state how they do the work and what object types might be the base for their work. JFreeReport's default processing model is called the 'Flow-Modell'. When describing how JFreeReport processes content and how the data and layout layer interact with each other, we will use that Flow-Modell as reference.
A report model is a system of report elements and their behaviour. JFreeReport offers a general framework for implementing report models. A report model has to cope with two general tasks: (1) To process the report structure and (2) to update or process the data for the report. There are only a limited number of operations one can do to the data-set. As this data processing can be broken down into relatively fixed tasks, the engine provides a fine grained library of functions which should cover all current and future needs of data processing.
Elements of the flow model
The default flow model is a very minimalistic (yet still complete) reporting model. The model is built on the idea, that a report definition and its structural dependencies can be seen as some sort of content and processing description language. Each node in the tree represents specific layout and data processing instructions. Iterating the report definition (the instruction tree) drives the report processing. Once the tree is fully processed, the reporting is finished. Reporting is a highly iterative process: the same itemband is printed several times (but each time with new data, of course). The flow modell follows this approach by introducing repeatable nodes. These nodes can (depending on certain conditions) be repeatedly iterated. The 'flow-modell' uses a DOM tree to describe the report content. The tree consists of several Node types.
- Static-Text
- Content-Element
- Sections
- Group
- Detail-Section
- Sub-Report
- Report
Static Text
Static text is immutable text content. This node type cannot have attributes or styles. When layouting, text nodes always inherit the style from their parent node.
Element Types
Elements are nodes that can have attributes and style. Contrary to the XML-DOM model, elements cannot have child nodes by default. Elements can have named expressions and functions. Named expressions get added to the global data-row and can be accessed from other expressions and functions by their name. Once the element goes out of scope, these expressions get removed from the data-row.
Attributes and styles can be computed at runtime. For this purpose, the Element class provides Style- and Attribute-Expression slots. The evaluation result of these expressions will be set as attribute. Attributes computed from expressions override any previously defined attribute on the element. Style properties computed from expressions override any previously declared style, no matter whether the style is static or computed indirectly by an attribute expression.
All elements can have a display-condition. A display condition is an anonymous expression. If that condition returns false, the element will be ignored for the processing. Display conditions are evaluated before the element's expressions get activated, so they have no access to any of these expressions. The display condition for the root element is ignored.
Content-Element
Content-Elements are mutable content. The element cannot have static children. The element's contents are read from a 'Value-Expression'. The 'Value-Expression' is an ordinary, anonymous and stateless expression that cannot be precomputed.
Flow-Behaviour
If the 'Value-Expression' returns a Node on evaluation, the node is inserted into the Document-Tree as if it were a direct child of the content element. The report processing continues with that returned element.
The 'LibLayout' report target treats the evaluation result as a special attribute and forwards this attibute along with all known meta-data to the layouting layer. The content can be formated or processed using the style rule system.
Section
A section is an element that can contain child nodes.
Sections can have flow operations defined. These flow operations can either be executed before the element is processed (and thus before any of the expressions gets activated, but after the display condition is evaluated) or after the element is fully processed.
Flow-Behaviour
If a section is marked as repeatable section, the layout controller has the choice to reprocess the contents of the section. The section will be repeated, if an advance has been requested and the data-row is advancable (there is a next row). By binding the repeatability of sections to the data-row, we effectivly prevent infinite loops caused by invalid expressions or other definitions.
If the section is contained in a group, the group's grouping expression will be evaluated. If the grouping expression indicates that the processing should stop (by returning 'true'), the section will not be repeated. If the expression indicates that the grouping should continue, the next sub-group is queried until all groups declare that they want to repeat the section.
If the layout controller decides to repeat the section, the 'advance' request will be commited and the cursor of the data-row is shifted to the next row. (A manual commit can be triggered by adding a 'Commit'-flow operation to any of the section's queues.) After that, the section is fully processed again.
Named expressions on a repeatable section go out-of scope and get readded as fresh instances on each iteration.
Group
A group is a section that has a grouping expression. Groups are repeatable by default.
Flow-Behaviour
If the group is repeatable, the repeat-test described above will use the parent group as first test for repeatability. The group's grouping expression will be ignored for that matter.
Detail-Section
The detail band is a ordinary band with no extra properties. It is repeatable by default and contains an 'Advance' Flow-Operation in its postprocessing queue. The main purpose of the Detail-Section is to provide some familiar elements for all users who are used to the old reporting engines.
JFreeReport
This is the first element of all report processings. The JFreeReport object holds several global objects, which influence the whole report processing.
- Data-Factory and the initial Query
- Input-Parameters
- The Style-Sheet collection
- The report configuration and the localization support
- The data-factory is a generic interface to query data-sources. The query-string and the given input-parameters are used for the query operation.
- The input parameters are a plain collection of objects. These parameters are accessible through the global DataRow.
- The (possibly empty) style-sheet collection is passed on to the layouting layer.