Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
org.apache.commons.logging.simplelog.defaultlog=trace
org.apache.commons.logging.simplelog.log.org.pentaho.reporting=trace
org.apache.commons.logging.simplelog.log.com.opensymphony.oscache=warn
org.apache.commons.logging.simplelog.log.net.sf.ehcache=warn
org.apache.commons.logging.simplelog.showlogname=true

Draft: Functions and expressions

Both Expressions and Functions are parametrized as JavaBeans by creating getter and setter methods. Both use the getValue() function to return the computed value and both should create a new fresh instance that does not share any modifiable object whenever the getInstance() method is called.

Expressions

Expressions are stateless, that means every call to the expression's getValue() is only dependent on the Expression's parameters and the values read from the datarow. The order in which expressions are called is not guaranteed, so it can be that the expression is called for the first row, then the 10th row and then for any other row. Due to their statelessness, expressions are cheap, as we do not have to clone them all the time to save their state.

Functions

Functions are statefull computations. Functions receive events (@see the Function interface) in a defined order, and maintain and update their state on every event. As the reporting engine iterates over the data multiple time, Functions get called several time. Each iteration has a processing-level, which describes the global state of the report-processing. Processing-levels greater or equal zero are function-processing levels, where functions compute the values. Level -1 (LayoutProcess.LEVEL_COLLECT) is reserved for layout preparations and Level -2 (LayoutProcess.LEVEL_PAGINATE) computes the layout.

The order of the function processing can be controlled via the Dependency-Level property of the Function. Functions with a higher dependency level are executed before functions with a lower dependency level. Functions will not be executed until the processing reached their respective level so that they do not see invalid results.

Functions that perform running computations (like the ItemSumFunction) are easy, as they can rely on the standard clone() functionality for the state management and simply recompute everything from scratch on each processing level.

Functions that compute global values (like the TotalGroupSumFunction), where function results are available before all data for the processing level has been processed are more complicated. These functions compute the running value in their defined processing level (@see FunctionUtilities.isDefinedPrepareRunLevel(..)) and store the result in a internal storage (usually a Map). On any later processing run, they simply recall the stored value to make it possible to print the value in report- or group-headers.

The event-order functions receive is well-defined. When saving report-states, the reporting engine will clone the function. This way, for a single function-instance, the event-flow always appears linear. The event-order is documented in the Wiki: http://wiki.pentaho.com/display/Reporting/JFR8States

You can monitor the event-flow by adding the EventMonitorFunction to your report. The function computes nothing but it logs all incoming report-processing events. Usually just looking at that log output makes the processing system a lot more understandable.