Accessing a report parameter
A report parameter is a report element that provides input to a report design before an application generates the report. A report document does not use report parameters to create a formatted report. If an application already has the parameter names and the values to set, or the default values for all report parameters for a report design are always valid, or the report source is a report document, you do not need to perform the tasks in this section.
Report parameters have attributes that a reporting application can access. The most commonly used attributes are name and value. The report engine uses the report design logic and the report parameter values to perform tasks such as filtering a data set or displaying an external value in the report.
After the reporting application sets values for the report parameters, it must pass these values to the task that generates the report, as shown later in this chapter. To access report parameters and their default values and to set user‑supplied values to a parameter, the application uses the BIRT Report Engine API classes and interfaces shown in Table 5-4.
An application can access report parameters by name or using generic code. Use generic code if the application must be able to run any report design, for example, to access report designs from a list that depends on user input. An application that runs only a fixed set of known report designs can access the report parameters by name.
Table 5-4 Classes and interfaces that support report parameters
Class or interface
Use
ReportEngine class
Instantiates the task that accesses report parameters. To create the task object, call the createGetParameterDefinitionTask( ) method. This method returns an instance of IGetParameterDefinitionTask.
IGetParameterDefinitionTask interface
Accesses a single report parameter or a collection of all the report parameters in a report design. Also provides access to valid values for parameters that use restricted sets of values, such as cascading parameters.
IParameterDefnBase interface
The base interface for report parameter elements. Scalar parameters implement the derived interface, IScalarParameterDefn. Parameter groups implement the derived interface IParameterGroupDefn. To get information about parameter attributes, use objects implementing these interfaces.
IParameterGroupDefn interface
The base interface for report parameter groups. Cascading parameter groups implement the derived interface ICascadingParameterGroup.
IParameterSelectionChoice interface
Defines valid values for a report parameter that uses a restricted set of values, such as a cascading parameter.
ReportParameterConverter class
Converts a String value provided by a user interface into a locale-independent format.
Creating a parameter definition task object for the report design
A single IGetParameterDefinitionTask object provides access to all parameters in a report design. Create only one of these objects for each report design, by calling ReportEngine.createGetParameterDefinitionTask( ). Close the parameter definition task object after use by calling its close( ) method.
Testing whether a report design has report parameters
To test if a report design has report parameters, call the getParameterDefns( ) method on IGetParameterDefinitionTask. This method returns a Collection. To test whether the Collection has elements call the Collection.isEmpty( ) method. An application that runs only known report designs does not need to perform this task.
Getting the report parameters in a report design
To access a single report parameter of a known name, use the IGetParameterDefinitionTask.getParameterDefn( ) method. This method returns an object of type IParameterDefnBase.
Use the IGetParameterDefinitionTask.getParameterDefns( ) method to return a Collection of IParameterDefnBase objects. The application can then use an Iterator to access each report parameter from this Collection in turn. The getParameterDefns( ) method takes a boolean argument. For an argument value of false, the method returns an ungrouped set of report parameters. For a value of true, the method returns parameter groups, as defined in the report design. To create a user interface that replicates the parameter group structure, use a value of true.
To check whether a report parameter is a group, the application must
call IParameterDefnBase.getParameterType( ). This method returns IParameterDefnBase.PARAMETER_GROUP if the parameter is a group or IParameterDefnBase.CASCADING_PARAMETER_GROUP if the parameter is a cascading parameter group. To access the group’s report parameters, use the IParameterGroupDefn.getContents( ) method. This method returns an ArrayList object of objects of type IScalarParameterDefn.
Getting the default value of each report parameter
This task is optional. To get the default value of a single known report parameter, use IGetParameterDefinitionTask.getDefaultValue( ). This method returns an Object. To determine the effective class of the Object, use IScalarParameterDefn
.getDataType( ). This method returns an int value, which is one of the static fields in IScalarParameterDefn. Call IGetParameterDefinitionTask.getDefaultValues( ) to get the default value of all parameters in the report design. This method returns a HashMap object, which maps the report parameter names and their default values.
Getting valid values for parameters using a restricted set of values
Some report parameters accept only values from a restricted list. In some cases, this list is a static list of values, such as RED, BLUE, or GREEN. In other cases,
the list is dynamic and a query to a database provides the valid values. For example, a query can return the set of sales regions in a sales tracking database. To determine the list of valid values, call the method, IGetParameterDefinitionTask.getSelectionList( ). This method returns a Collection of IParameterSelectionChoice objects. IParameterSelectionChoice has two methods. getLabel( ) returns the display text and getValue( ) returns the value. If the Collection is null, the report parameter can take any value.
Getting the attributes of each report parameter
This task is optional. To get the attributes of a report parameter, use the IScalarParameterDefn methods. The application can use the attributes to generate a customized user interface. For example, to get the data type of a report parameter, use the getDataType( ) method.
Collecting an updated value for each report parameter
To provide new values for the report parameters, provide application logic such as a user interface or code to retrieve values from a database.
Call IGetParameterDefinitionTask.setParameterValue( ) to set the value of the parameter. If a user interface returns String values to your application for date and number parameters, convert the String into a locale-independent format before setting the value. To perform this task, call the method, ReportParameterConverter.parse( ), before calling setParameterValue( ).
After setting the report parameter values, call the method, IGetParameterDefinitionTask.getParameterValues( ). This method returns a HashMap object containing the current parameter values as set by calls to IGetParameterDefinitionTask.setParameterValue( ). Use this HashMap object to set parameter values for report generation, as described later in this chapter.
How to set the value of a known report parameter
The code sample in Listing 5‑6 shows how to set the value of a report parameter that has a known name. The sample creates a HashMap object that contains the parameter values to use later to run the report. The variable, engine, is a ReportEngine object. The variable, runnable, is an object of type IReportRunnable. This sample does not show details of code for retrieving the parameter value from a user interface or a database. The code to perform these tasks depends on your application’s requirements.
Listing 5‑6 Setting the value of a single parameter
// Create a parameter definition task.
IGetParameterDefinitionTask task = engine.createGetParameterDefinitionTask( runnable );
// Instantiate a scalar parameter.
IScalarParameterDefn param = (IScalarParameterDefn)
task.getParameterDefn( "customerID" );
// Get the default value of the parameter. In this case,
// the data type of the parameter, customerID, is Double.
int customerID =
((Double) task.getDefaultValue( param )).intValue( );
// Get a value for the parameter. This example assumes that
// this step creates a correctly typed object, inputValue.
// Set the value of the parameter.
task.setParameterValue( "customerID", inputValue );
// Get the values set by the application for all parameters.
HashMap parameterValues = task.getParameterValues( );
// Close the parameter definition task.
task.close( );
How to use the Collection of report parameters
The code sample in Listing 5‑7 shows how to use the Collection of report parameters. The sample uses the ReportParameterConverter class to convert the String values that the user interface supplies into the correct format for the parameter. The sample creates a HashMap object that contains the parameter values to use later to run the report. The variable, engine, is a ReportEngine object. The variable, runnable, is an IReportRunnable object. This sample does not show details of code for retrieving the parameter values from a user interface or a database. The code to perform these tasks depends on your application’s requirements.
Listing 5‑7 Setting the values of multiple parameters without grouping
// Create a parameter definition task.
IGetParameterDefinitionTask task = engine.createGetParameterDefinitionTask( runnable );
 
// Create a flat collection of the parameters in the design.
Collection params = task.getParameterDefns( false );
// Get the default values of the parameters.
HashMap parameterValues = task.getDefaultValues( );
 
// Get values for the parameters. Later code in this example
// assumes that this step creates a HashMap object,
// inputValues. The keys in the HashMap are the parameter
// names and the values are those that the user provided.
 
// Iterate through the report parameters, setting the values
// in standard locale-independent format.
Iterator iterOuter = params.iterator( );
ReportParameterConverter cfgConverter = new ReportParameterConverter( "", Locale.getDefault( ) );
while ( iterOuter.hasNext( ) ) {
IScalarParameterDefn param =
(IScalarParameterDefn) iterOuter.next( );
String value = (String) inputValues.get( param.getName( ));
if ( value != null ) {
parameterValues.put( param.getName( ),
cfgConverter.parse( value, param.getDataType( ) ) );
}
}
// Close the parameter definition task.
task.close( );
Getting the values for cascading parameters
A cascading parameter group contains an ordered set of parameters that provide lists of acceptable values for the end user to select. The value chosen for the first parameter limits the available values for the second one, and so on. The parameters use one or more queries to retrieve the values to display to the user from a data set. The parameter definition task uses the data rows from the queries to filter the values for each parameter, based on the values of preceding parameters in the group. For example, consider a cascading parameter group that uses the following query:
SELECT
PRODUCTS.PRODUCTLINE,
PRODUCTS.PRODUCTNAME,
PRODUCTS.PRODUCTCODE
FROM CLASSICMODELS.PRODUCTS
The group has two parameters, ProductLine on PRODUCTS.PRODUCTLINE and ProductCode on PRODUCTS.PRODUCTCODE. The display text for ProductCode uses values from PRODUCTS.PRODUCTNAME. Figure 5‑2 shows the appearance of the requester that prompts for values for these parameters when a user previews the report in BIRT Report Designer.
Figure 5‑2 Cascading report parameters
To use the Report Engine API to get the values for cascading parameters, perform the tasks in the following list.
*To populate the list of values for the first report parameter in the group, call IGetParameterDefinitionTask.getSelectionListForCascadingGroup( ). This method takes two parameters, the String name of the parameter group and an array of Object. For the first parameter, this array is empty. The method returns a Collection of IParameterSelectionChoice objects.
*To populate the list of values for further report parameter in the group, call getSelectionListForCascadingGroup( ) again. In this case, the Object[ ] array contains the values for the preceding report parameters in the group. In the example shown in Figure 5‑2, the Object[ ] array is:
new Object[ ] { "Trains" }
How to use cascading parameters
The code sample in Listing 5‑8 accesses the set of valid values for each parameter in the cascading parameter group in turn. The variable, task, is an object of type IGetParameterDefinitionTask.
Listing 5‑8 Getting the valid values for cascading parameters
// Create a grouped collection of the design’s parameters.
Collection params = task.getParameterDefns( true );
 
// Iterate through the parameters to find the cascading group.
Iterator iter = params.iterator( );
while ( iter.hasNext( ) ) {
IParameterDefnBase param = (IParameterDefnBase) iter.next();
if ( param.getParameterType() ==
IParameterDefnBase.CASCADING_PARAMETER_GROUP ) {
ICascadingParameterGroup group =
(ICascadingParameterGroup) param;
String groupName = group.getName();
Iterator i2 = group.getContents( ).iterator( );
 
Object[ ] userValues =
new Object[group.getContents( ).size( )];
 
// Get the report parameters in the cascading group.
int i = 0;
while ( i2.hasNext( ) ) {
IScalarParameterDefn member =
(IScalarParameterDefn) i2.next( );
 
// Get the values for the parameter.
Object[ ] setValues = new Object[i];
if ( i > 0 ) {
System.arraycopy( userValues, 0, setValues, 0, i );
}
Collection c = task.getSelectionListForCascadingGroup
( group.getName(), setValues );
String[ ] choiceValue = new String[c.size( )];
String[ ] choiceLabel = new String[c.size( )];
 
// Iterate through the values for the parameter.
Iterator i3 = c.iterator();
for ( int j = 0; j < c.size( ); j++ ) {
IParameterSelectionChoice s =
( IParameterSelectionChoice ) i3.next( );
choiceValue[j] = ( String ) s.getValue( );
choiceLabel[j] = s.getLabel( );
}
// Get the value for the parameter from the list of
// choices. This example does not provide the code for
// this task.
userValues[i] = inputChoiceValue;
i++;
}
}