Groovy und TIBCO Jaspersoft

In den Einstellungen eines Reports kann die Sprache zur Auswertung der Expression gewählt werden. Zur Auswahl steht neben Java auch Groovy. Aber weshalb sollten Sie überhaupt etwas anderes als Java auswählen?

Auswahlmöglichkeiten zum Festlegen der Report LanguageIn den Expressions können im Grunde nur Java-Einzeiler eingefügt werden. Manche komplexe Datenverarbeitung wird deshalb in eine eigene Bibliothek exportiert und als JAR eingebunden. Die Reporterstellung ist nun von diesem externen Artefakt abhängig.
In der Sprache Groovy (http://groovy-lang.org/) hingegen können viele dieser Anweisungen in einer Zeile ausgedrückt werden ohne dass dabei die Lesbarkeit verloren geht. Da vieles funktional bzw. deklarativ beschrieben ist, ist der der Code lesbarer und die Intention einfacher zu verstehen.
Zudem bietet Groovy einige Sprachfeatures, die das Lesen und Verständnis von Code deutlich erleichtern.

Defaultwerte und bedingte Ausführung

In Groovy kann der bekannte ternäre Operator und die Prüfung auf null kombiniert werden: Die Prüfung auf null und das Setzen eines Defaulwertes via $P{NAME} != null ? $P{NAME} : "Johannes" lässt sich mit ?:, dem sogenannten Elvis-Operator, kompakter als $P{NAME} ?: "Johannes" schreiben.
Hinweis: Es wird nicht ausschließlich auf null geprüft. Auch ein leerer String oder eine leere Collection triggern den Defaultwert. '' ?: "leerer String" //Result: 'leerer String'

Ein weiterer interessanter Operator ist ?. mit dem eine Methode (oder eine Methodenkette) nur dann ausgewertet wird, wenn die Operanden ungleich null sind. Ansonsten wird der gesamte Ausdruck zu null ausgewertet. Anstatt (X != null && X.getPerson() != null && X.getPerson().getName() != null) ? X.getPerson().getName() : "Johannes" schreiben wir X?.getPerson()?.getName() ?: "Johannes" und erhalten das gleiche Ergebnis: Entweder den Namen der Person, so vorhanden, oder einen von uns gewählten Defaultwert.

Collections

In Groovy können Listen per

[]-Literal angelegt werden. Die Methode collect wertet die angegebene Closure für jedes Element der Liste aus und überführt die Ergebnisse in eine neue Liste. Wird in der Closure nur eine Methode ausgeführt, so bietet sich die Kurzschreibweise mit dem *.-Operator an.

names = ["johannes", "alice", "bob"]
cap_names = names.collect { name -> name.capitalize() } // Result: ['Johannes', 'Alice', 'Bob']
cap_names2 = names*.capitalize() // Result: ['Johannes', 'Alice', 'Bob']

Ebenfalls sehr nützlich ist die Methode join, mit der Elemente einer Collection zu einem String konkateniert werden: names*.capitalize().join(', ') // Result: 'Johannes, Alice, Bob'
In Verbindung mit der Mehtode collate, die eine Liste in Teillisten aufteilt, lässt sich eine entsprechende Variable in einem Report sehr schön ausgeben:

values = ["a1", "a2", "a3", "c1", "b2", "b3", "c1", "c2"]
values.collate(3)*.join(", ").join("\n") // Result: 'a1, a2, a3\nc1, b2, b3\nc1, c2'

Weitere nützliche Methoden und Wissenswertes über den Umgang mit Collections ist gut dokumentiert: http://groovy-lang.org/groovy-dev-kit.html#_working_with_collections

Datumswerte

In einer einzeiligen Expression lassen sich mit Java Datumswerte nur bedingt manipulieren und es muss daher auf die von Jaspersoft bereitgestellten Funktionen zurückgegriffen werden. In Groovy hingegen kann mit Datumswerten einfach gerechnet werden java.util.Date vorgestern = new java.util.Date() - 2 und diese ebenso verglichen werden due_date <= new java.util.Date() + 2. Solch ein Ausdruck kann auch sehr gut als Expression für einen bedingten Stil genutzt werden.

Einiges ist lediglich syntactic sugar anderes eine wirkliche Erleichterung. Probieren Sie es doch selbst einmal aus und profitieren auch Sie von lesbaren Expressions!

Prodato verbindet.

Autor

Dr. Johannes Held
Principal

johannes.held@prodato.de