Event order sequence
Table 36-6 summarizes which engine task is responsible for a particular phase. The following sections describe the order of event firing for each phase in more detail.
Table 36-6 Engine task by phase
Report engine task
Preparation phase
Generation phase
Presentation phase
RunTask
Yes
Yes
No
RenderTask
No
No
Yes
RunAndRenderTask
Yes
Yes
Yes
Preparation phase operation
The preparation phase includes parameter validation as well as initialization and report element preparation for every element in the report. The preparation phase is identical for all reports. Table 36-7 lists the event types for RunTask and RunAndRenderTask in the order in which the events execute. RenderTask does not have a preparation phase. In RunAndRenderTask, the preparation phase triggers a beforeRender event.
Table 36-7 Preparation phase events
Element type and event
RunTask
RunAndRenderTask
Parameter getDefaultValueList
Yes
Yes
Parameter getSelectionValueList
Yes
Yes
Parameter validate
Yes
Yes
ReportDesign Initialize
Yes
Yes
ReportItem onPrepare (iterative)
Yes
Yes
ReportDesign beforeFactory
Yes
Yes
ReportDesign beforeRender
No
Yes
The parameter events fire first for each parameter. Before the parameter entry box is displayed, the getDefaultValueList is called for each parameter. This script returns either a single value or a list of values, depending on the parameter type.
Next, each parameter that provides a list of choices to the user calls the getSelectionValueList. If running reports using the API for RunTask or RunAndRenderTask, the getDefaultValueList script event fires for only parameters that have no value passed. The getSelectionValueList is not called. If using createGetParameterDefinitionTask to build your own parameter entry screen, these events fire much like the example viewer.
After a user enters values for the parameters, the next event is the validate event, which fires for each parameter. The ReportDesign event, initialize, follows. The initialize event fires once when using only one engine task. Using a separate engine task triggers the initialize event at least two times, one time for the preparation phase, and a second time for the render phase. Additional render tasks or phases also trigger the initialize method.
After the initialize event, the preparation phase triggers the onPrepare event for every element in the report. This process starts with the master page content and proceeds from left to right and top to bottom in the report body. All nested elements process before proceeding to the next element.
The beforeFactory event fires next. This event signals that report creation is about to occur and provides a location for altering a running report.
The beforeRender event fires when using a RunAndRenderTask. When using two tasks, this event does not fire until a render operation occurs.
Generation phase operation
The generation phase includes connecting to data sources, executing data sets and data cubes, evaluating data bindings, and creating all the report items in the report. The data source and data set events fire before the creation of data‑bound items, but this processing may not occur before the creation of other report items. For example, if a table is bound to a data set and the report uses a master page with only a label in the footer, the master page content onCreate event fires before the data source and data set events for the data set bound to the table.
This phase triggers the onCreate event for every report item. BIRT processes the report body after processing content on the master page. The report body contains all the report items to be created and rendered. BIRT processes all items at all levels in an iterative fashion, following the same process at each level as it does for the top-level items. A report item that is not contained in another report item is called a top-level report item. BIRT processes the top‑level items, going from left to right and proceeding a row at a time toward the bottom right. Every report has at least one top-level report item, usually a grid, list, or table. All nested elements complete OnCreate processing before the next element’s onCreate fires.
For each top-level item, BIRT processes all the second-level items before proceeding to the next top-level item. A second-level report item is a report item that is contained within a top-level item. For example, a table contained in a grid is a second-level report item.
There can be any number of levels of report items. To see the level of a particular report item, examine the structure of the report design in Outline, in the BIRT Report Designer, as shown in Figure 36‑1.
Figure 22-3 The Outline window, showing the level of a report itemFigure 22-3 The Outline window, showing the level of a report item
Figure 36‑1 Outline showing the level of a report item
If a RunAndRenderTask process executes the generation phase, each element is created and immediately rendered, which fires the onRender event before proceeding to the next element. If a RunTask process executes the generation phase, the onRender events do not fire.
Table 36-8 lists the events triggered in the generation phase for each major report component in the order in which these events execute. The data source, data set, and onPageBreak events are optional.
Table 36-8 Generation phase events
Report component
RunTask
RunAndRenderTask
Master Page content
Data source and data set events (optional)
onCreate
onPageBreak (optional)
Data source and data set events (optional)
onCreate
onRender
onPageBreak (optional)
Body (iterative)
Data source and data set events (optional)
onCreate
onPageBreak (optional)
Data source and data set events (optional)
onCreate
onRender
onPageBreak (optional)
Data source and data set events do not fire if a report item is not data bound or if the report item is bound to another report item that executed previously. The onPageBreak event fires only when an actual page break occurs. The next three sections describe the data source, data set, data binding, and page break events in more detail.
Data source and data set events
Events for data source and data set elements fire just prior to creating the report item bound to the data set. This sequence occurs for every report item bound to a data set with the exception of the data source beforeOpen and afterOpen events. These events do not fire if a data source has already been used. When a report item is bound to another report item, none of these events fire for the bound report item, supporting two data-bound items sharing one data set without re‑executing the data set.
The data source beforeClose and afterClose events fire at the end of the generation phase just before the afterFactory event fires. In the generation phase, there is no difference in data source or data set processing in RunTask and RunAndRenderTask.
BIRT supports data set caching, by which data sets execute only once and are used multiple times. In this case, the data set events fire on only the first use. If a data set is parameterized and the actual parameter value is changed within a report item, the query executes again using the new parameter value. This query execution causes the data set events to fire again. Table 36-9 lists the data source and data set types and events in the order in which these events execute.
Table 36-9 Data source and data set events
Event type and event
RunTask
RunAndRenderTask
Data source beforeOpen
Yes
Yes
Data source afterOpen
Yes
Yes
Data set beforeOpen
Yes
Yes
Data set afterOpen
Yes
Yes
Data set onFetch for all rows of data
Yes
Yes
Process the data-bound Report Item
Yes
Yes
Data set beforeClose
Yes
Yes
Data set afterClose
Yes
Yes
Data binding
Data binding in BIRT makes a logical separation between BIRT data sets and data-bound elements, such as tables and lists. Selecting a table or list and then the Binding tab in the Property Editor displays the current bindings for the item. A report developer can create bound columns that use external objects to calculate a specific column value. The bound data set continues to determine the number of rows that are processed for a given table or list.
In a table or list, evaluation of the data bindings for the detail rows occurs before the onCreate event on the current row. This approach supports the onCreate event handler retrieving the appropriate values for the row.
The bindings are evaluated for each detail row in a bound data set. Table footers containing data elements that use a binding are evaluated before the last onCreate event for the final detail row.
Trying to alter a bound column using the onCreate script is discouraged. For example, it is possible to concatenate a column value for a row with all previous rows for the given column using the onCreate script with a JavaScript variable. If this value is in the expression of a bound column, the last value is excluded from the bound column. To display the last value, use a computed column, an aggregation report item, or the dynamic text <VALUE‑OF> tag in a text element to display the JavaScript value.
A report developer must not assume any particular evaluation order of binding expressions relative to the various table item events, except that a binding evaluates before the onCreate event of an item that uses it. Best practice is to perform any required manipulation of the data in a data set script or the binding expression.
Data binding evaluation for a group evaluates the bound column many times before creating the table or list item. BIRT performs multiple passes over the data to support grouping. Any script in a group-bound column expression is called every time the data binding evaluates, affecting report performance.
All bindings of a table are always calculated, whether or not these bindings are used by the table. For performance reasons, check the binding list and remove any unused items from the report design.
Report items can share data bindings. For example, two tables can share the same set of bindings. The second table does not re-evaluate the data bindings. To use this feature in the BIRT Report Designer, select the second table, choose Binding in Property Editor, select Report Item, and select the appropriate report item from the list. The list supports only named data‑bound report items.
The above scenarios affect any BIRT expression that uses the Available Column Bindings category.
Page break events
Many report items support page breaks. Setting a page break interval on a table instructs the table to process a certain number of rows and then apply a page break. Setting a page break on a group section applies a page break both before and after or only after the group processes. A page break can be applied before many other report items. For example, applying a page break before a row in a table instructs the engine to apply a page break before every row of data that a table processes.
Page events are based on the paginated HTML emitter. If a report generates 5 HTML pages but has 20 PDF pages, the page events fire only 5 times.
The general order of the events is as follows:
*The engine creates the page.
*The onPageStart event fires for the report.
*The onPageStart event fires for the selected master page.
*For items that are to appear on the page, the onPageBreak event fires.
*The onPageEnd event fires for the selected master page.
*The onPageEnd event for the report fires.
*The engine evaluates the Master Page Auto Text fields.
The onCreate events for all items that are to appear on a page fire before the report’s onStart event. Some items have their onCreate triggered but do not appear on a page because of the keep together flag. Such items appear on the following page.
The page‑level scripts are used when the Run and Render tasks are separated.
Chart event order
Chart events are handled by the chart engine and execute within the presentation phase. These events are covered in a later chapter.
Table and list event order
The BIRT engine fires the onCreate event for report items iteratively. When processing report items that iterate over data rows, such as a table or list, the event order changes to add additional events for each row of data. Row containers process data rows.
Table and list method execution sequence
A list is equivalent to a table that has only a single cell in every row. BIRT processes tables and lists identically, except that for a list, BIRT does not iterate through multiple cells. BIRT processes tables in three steps, the setup, detail, and wrap-up processing steps.
The following sections describe the table and list execution sequence steps.
Table and list setup step
The pre‑table processing step is the same for all tables, both grouped and ungrouped.
Figure 36‑2 illustrates the execution sequence for the pre-table processing step. This illustration shows the event order when using a RunAndRenderTask in the generation phase.
A RunTask does not fire onRender events. A RenderTask does not fire onCreate, data source, and data set events. The data source and data set events are optional.
Figure 22-8 Table and list setup execution sequenceFigure 22-8 Table and list setup execution sequence
Figure 36‑2 Table and list setup execution sequence
Table and list processing step
The sequence for the table and list processing step depends on whether the table or list is grouped. A table or list having no grouping has a different sequence from one that has grouping.
Figure 36‑3 illustrates the execution sequence for a table or list without grouping.
Figure 22-10 Ungrouped table or list detail execution sequenceFigure 22-10 Ungrouped table or list detail execution sequence
Figure 36‑3 Ungrouped table or list detail execution sequence
For a table having grouping, BIRT creates one ListingGroup item per group.
A ListingGroup is similar to a table in that it has one or more header rows and one or more footer rows. BIRT processes grouped rows in the same way that it processes a table row.
In addition to the standard onPrepare, onCreate, and onRender events for these rows, the ListingGroup fires the onPageBreak and onPrepare events for the group. To access the script location for these event handlers, locate the group in the Outline view and select the Script tab. Use code in the onPrepare event handler to modify grouping behavior, such as changing the sort order.
Figure 36‑4 illustrates the method execution sequence for a table that has groups.
Figure 22-11 Grouped table execution sequenceFigure 22-11 Grouped table execution sequence
Figure 36‑4 Grouped table execution sequence
To verify the execution sequence of event handlers for a specific report, add logging code to the event handlers.
Row execution sequence
Tables and lists, and groups within those items have rows. Any slot in a list or table can contain multiple row elements. There are three kinds of rows and BIRT processes all these row types identically:
*Header
*Detail
*Footer
Figure 36‑5 illustrates the method execution sequence for a row.
Figure 22-6 Row execution sequenceFigure 22-6 Row execution sequence
Figure 36‑5 Row execution sequence
Table and list wrap-up step
The post-table processing step is the same for all tables, both grouped and ungrouped.
Completion of the generation phase
On completion of the generation phase, for all data sources, beforeClose and afterClose events fire, followed by the afterFactory event. If using the RunAndRenderTask, the afterRender event fires before closing the data sources. Table 36-10 describes the events available at completion of the generation phase.
Table 36-10 Completing the generation phase
Element type and event
RunTask
RunAndRenderTask
afterRender
No
Yes
Data source(s) beforeClose
Yes
Yes
Data source(s) afterClose
Yes
Yes
afterFactory
Yes
No
Presentation phase operation
The presentation phase launches the appropriate emitter and produces report output based on the generated report. This phase fires the onRender events for all items as they are created. If using the RenderTask to render an existing report document, the initialize event triggers first and then each rendered report item’s onRender event fires.
If the RenderTask renders pages individually, the onRender event fires only for items that are rendered. For example, BIRT Web Viewer uses a RunTask to create a report document. The web viewer uses a RenderTask to render the first page. This action fires the initialize event first and the onRender event for each item that appears on the page. Selecting a new page and using the pagination controls results in a new RenderTask that calls the initialize event again and triggers the onRender event for each item on the new page.