Viewing: Advanced Domain Features > Datatypes

The DomEL Syntax

Various components of a Domain need to compute values based on some expression involving constants, field values, and environment variables. The Domain Expression Language (DomEL) was created to fill this need. Currently, the following features in XML design files are expressed in DomEL:

   The on and where clauses of derived tables

   The on clause of join statements

   Calculated fields

   Filter expressions in Domains and Domain topics (equivalent to where clauses)

   The testProfileAttribute function

   Row-level security (see section The Domain Security File)

A DomEL expression is a shorthand way of writing a complex query. When processing a report based on a Domain, the server interprets DomEL expressions to generate parts of the SQL expression that perform the desired query. Depending on the data policy, either the augmented SQL is passed to the data source, or the server performs a simpler query and applies the DomEL expressions to the full dataset in memory.

Datatypes

The following simple datatypes may be declared as constants, used in expressions, and returned as values:

 

Simple Type

Description

Example of Constant

boolean

Expressions such as comparison operators return boolean values, but true and false constants are undefined and cannot be used.

none

integer

Whole numbers.

123 or -123

decimal

Floating point numbers. Decimal separator must be a period (.); other separators such as comma (,) are not supported.

123.45 or -123.45

string

Character string entered with single quotes ('); double quotes (") are not supported.

'hello world'

date

ANSI standard date.

d'2009-03-31' or
Date('2009-03-31')

timestamp

ANSI standard date and time.

ts'2009-03-31 23:59:59' or
TimeStamp('2009-03-31 23:59:59')

The following composite datatypes may be declared as constants and used with the in set or in range operator. The values in these composite types are not necessarily constant, they could be determined by field values:

 

Composite Type

Description

Example

set

Contains any number of any simple type above.

(1, 2, 3)('apples','oranges')

range

Inclusive range applicable to numbers and dates, including fields that are number or date types.

(0:12) or (0.0:12.34)(d'2009-01-01':d'2009-12-31')(limit_min:limit_max)

Field References

DomEL expressions are stored in the Domain design and interpreted when the server prepares to run a query to retrieve data from the data source. Therefore, all references to field values in an expression are based on the IDs given in the Domain design. Field references have the following format, depending on where the expression appears:

 

Appears In

Field Reference

Explanation

Derived table

table_ID.field_name

The SQL query that defines a derived table can refer to any previously defined table or derived table in the Domain. Therefore, you must include the table ID.

Join expression

table_alias.field_name

Within a join expression, tables are given alias names that must be used. Even though join expressions may appear in separate joinedDatasetRef elements, the alias declared in each one can be used in any subsequent one.

Calculated field on a table or derived table

field_name

 

Calculated fields can only appear on a table if they refer exclusively to fields of the table, in which case no table ID is needed. However, the table ID is not forbidden, and the Domain Designer sometimes includes it.

Calculated field on a join tree.

table_ID.field_name

Calculated fields declared in join trees refer to fields prefixed with their table ID.

Filter on a table or derived table

field_name

Filters that are evaluated within the table or derived table do not need the table ID.

Filter on a join tree

table_ID.field_name

Filters that refer to fields in separate tables of the join tree need to use the table ID on each field name.

Operators and Functions

DomEL provides the following operators, listed in order of precedence. Operators higher in this list are evaluated before operators lower in the list:

 

Operator

Syntax

Description

multiply, divide

i * j / k

Arithmetic operators for numeric types only. Parentheses for grouping are not supported.

add, subtract

i + j - k

equal

i == j

Comparison operators for string, numeric, and date types.

not equal

i != j

less than

i < j

Comparison operators for numeric and date types only.

less than or equal

i <= j

greater than

i > j

greater than or equal

i >= j

in set

i in ('apples','oranges')

Sets can be of any type.

in range

i in (j:k)

Ranges must be numeric or date types.

not

not ( i )

Boolean operators. Parentheses are required for not and may be used for grouping.

and

i and j and k

or

i or j or k

DomEL also defines the following operations as functions:

 

Function

Syntax

Description

startsWith

startsWith(i, 'prefix')

Comparison operators for strings. To test string equality, use i in ('string').

endsWith

endsWith(j, 'suffix')

contains

contains(k, 'substring')

concat

concat(i, ' and ', j, ...)

Returns the string of all parameters concatenated.

testProfileAttribute1

testProfileAttribute(table_ID.field_name,'profileAttribute')

table_ID.field_name is the table name and field name of the field you’re comparing to a profile attribute. This argument can also be an expression, such as a concatenation of fields. It cannot be a constant or a groovy call.

profileAttribute is the name of the user profile attribute.

Profile Attributes

A profile attribute is a name-value pair inserted in a user object, such as a user or role. It is ordinarily used to extend the object’s standard access grants, but it has other uses, as well. It can be added to objects by database tools or custom code.

For example, this Groovy expression tests users for the Cities access grant in the store_city field in the store table:

<filterExpression>store.store_city in (groovy('authentication.getPrincipal().getAttributes().find{ it.attrName == "Cities" }.attrValue.split(",").collect {"''" + it + "''" }.join(",").replaceFirst("^''","").replaceFirst("''\$","")'))</filterExpression>

Using profile attributes enables you to obtain similar results with simpler expressions. The example below uses a principal expression to find all users with the Cities profile attribute, then it uses a filter expression to grant access only to the users among them whose Cities profile attribute is San Francisco:

 

<resourceAccessGrant id="Jointree_1_row_access_grant_2">

<principalExpression><![CDATA[authentication.getPrincipal().getAttributes().any{ it.getAttrName() in ['Cities'] && it.getAttrValue() in ['San Francisco'] }]]></principalExpression>

<filterExpression>store.store_city in ('San Francisco')</filterExpression>

</resourceAccessGrant>

The next example tests the same profile attribute, Cities. However, instead of granting access only to users with a specific profile attribute, you use variable substitution in the filter expression to grant access to all users according to their Cities attribute. A user with the San Francisco profile attribute gets access to that city, a user with the Denver profile attribute gets access to that city, and so on:

 

<resourceAccessGrant id="Jointree_1_row_access_grant_4">

<principalExpression><![CDATA[authentication.getPrincipal().getAttributes().any{ it.getAttrName() in ['Cities'] }]]></principalExpression>

<filterExpression>store.store_city in (groovy('authentication.getPrincipal().getAttributes().find{ it.attrName == "Cities" }.attrValue'))</filterExpression>

</resourceAccessGrant>

Finally, testProfileAttribute is a function for taking advantage of the profile attributes feature. An extension of the DomEL language, testProfileAttribute examines an object for a given profile attribute and permits access to the related data when the attribute is present.

Using the testProfileAttribute function, you can write simpler expressions than you can using Groovy. For instance, this filter expression tests users for the Cities profile attribute. Compare it to the expression in the previous example:

<filterExpression>testProfileAttribute(store.store_city, 'Cities')</filterExpression>

For more information about profile attributes, variable substitution, and testProfileAttribute, see the JasperReports Server Ultimate Guide and Jaspersoft OLAP Ultimate Guide.

SQL Functions

You may use SQL functions in a DomEL expression, but only in limited circumstances:

   The functions must be supported by the database. See the vendor documentation for available functions and their syntax.

   The functions must follow the convention of comma-separated parameters. For example, you can use TRIM(person.name), but not TRIM('Jr' FROM person.name)

   The type of the return values must be appropriate, either within the expression or for the type of the calculated field.

   The SQL context must be appropriate for the functions. For example, you cannot use aggregation functions such as COUNT in a calculated field because there is no GROUP BY clause.

Except for the comma-separated parameter pattern, the DomEL validation cannot enforce these criteria. You must ensure that any SQL functions meet these criteria, otherwise the expression causes errors when using the Domain to create a report.

Complex Expressions

Complex expressions are written by grouping any of the operators or functions above. Parentheses () may be used for grouping boolean operators, but arithmetic expressions that rely on parentheses are not supported. To compute complex arithmetic expressions, you may need to define several expressions as separate calculated fields, and then reference them in a simpler expression in another calculated field.

The following examples show complex expressions suitable for filters. This first one selects only stores in Western states of the US:

s1.store_country in ('USA') and s1.store_state in ('WA', 'OR', 'CA', 'NV')

The following filter expression uses a date range:

s1.first_opened_date in ( Date( '2000-01-01' ) : Date( '2004-12-31' )) and not( s1.closed )

As shown in these examples, field values are often compared to constant values such as 'USA'. Therefore, the author of the design file must ensure that values used in a DomEL expression exist in the data source. Otherwise, a wrong value might go undetected and impact the quality of data in reports based on the Domain. The Domain Designer determines values for comparison by accessing the data source, so if you export a design file, you can use the values it has found. Another way to reduce errors and also support future data changes is to use more general expressions such as:

s1.store_country in ('US', 'USA', 'United States')

Return Value

DomEL expressions are used in different contexts for different purposes. The expected return type depends on where the expression appears:

 

Appears In

Expected Return Type

Explanation

Derived Table

SQL query with boolean expressions

A derived table is defined by an SQL expression that contains DomEL expressions. The join on clause may contain boolean comparisons and the where clause may contain filters, both of which are described below.

Join expression

boolean

Within a join expression, the on clause contains a comparison of fields from each table that has a boolean result. The on clause may also contain other DomEL expressions logically associated with and or or to create a complex join condition (see warning on See "Representing Joins in XML").

Calculated field

any type

The expression must evaluate to a type that is compatible with the SQL type declared in the Domain Designer or in the design file. For example, if the declared type is java.lang.Float, the expression must compute a decimal value.

Filter

boolean

Filters must be true or false overall. When there are several conditions, they must be logically associated with and or or (currently, only and is supported in the Domain Designer).