Gosu Ref Guide
Gosu Ref Guide
Contents
Part 1
Gosu language basics
1 Gosu introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19
Welcome to Gosu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19
Overview of control flow. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20
Overview of blocks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22
Overview of enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .23
Overview of collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .23
Overview of access to Java types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .24
Overview of Gosu classes and properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .24
Overview of interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29
List and array expansion operator *. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29
Overview of comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30
Case sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30
Compound assignment statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31
Delegating interface implementation with composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31
Overview of concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .32
Overview of exceptions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
Overview of annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34
Overview of templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34
Overview of XML and XSD support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35
Overview of web service support for consuming WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36
Gosu character set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36
Running Gosu programs and calling other classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36
Guidewire internal methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38
More about the Gosu type system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38
Compile-time error prevention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38
Type inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39
Intelligent code completion and other Gosu editor tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39
Null safety for properties and other operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39
Generics in Gosu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41
Gosu primitive types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
Gosu case sensitivity and capitalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
Gosu statement terminators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
Gosu comments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43
Gosu reserved words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
Legal variable names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
Gosu generated documentation (Gosudoc) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
Code coverage support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
Notable differences between Gosu and Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
Get ready for Gosu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
3
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
4
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
4 Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Gosu statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Statement lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Using the operator new as a statement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Gosu variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Variable type declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Variable assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Gosu conditional execution and looping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
if - else statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
for statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
while statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
do…while statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
switch statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Gosu functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Named arguments and argument defaults. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Public and private functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Importing types and package namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Packages always in scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Importing static members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
6 Intervals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
What are intervals? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Reversing interval order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Granularity of interval steps and units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Writing your own interval type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Custom iterable intervals using sequenceable items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Custom iterable intervals using manually written iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Example: Color interval written with manual iterators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Custom non-iterable interval types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
5
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
8 Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
What are classes? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Creating and instantiating classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Extending another class to make a subclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Static methods and variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Using public properties instead of public variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Creating a new instance of a class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Naming conventions for packages and types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Using uses lines to import a type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Properties are dynamic and virtual functions that act like data . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Property paths are null tolerant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Designing APIs around null-safe property paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Static properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
More property examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Access modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Override modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Abstract modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Final modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Static modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Inner classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Named inner classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Referring to members of the outer class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Static inner classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Classes that extend the outer class can use the inner class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Anonymous inner classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
9 Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Using enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Create an enumeration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Extracting information from an enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Extract information from an enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Comparing enumerations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
10 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
What is an interface? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Defining and using an interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Create and implement an interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Defining and using properties on interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Modifiers and interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
11 Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
What are blocks? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Basic block definition and invocation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Block return types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Invoking blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Variable scope and capturing variables in blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Argument type inference shortcut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Block type literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
6
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
12 Collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Basic lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Creating a list. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Type inference and list initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Getting and setting list values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Basic hash maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Creating a hash map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Getting and setting values in a hash map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Special enhancements on maps. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Wrapped maps with default values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
List expansion (*.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Array flattening to a single dimensional array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Enhancements on Gosu collections and related types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Finding data in collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Sorting lists or other comparable collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Mapping data in collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Iterating across collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Partitioning collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Converting lists, arrays, and sets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Flat mapping a series of collections or arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Sizes and length of collections and strings are equivalent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
List of enhancement methods on collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
13 Enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Using enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Syntax for using enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Creating a new enhancement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Syntax for defining enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
Enhancement naming and package conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Enhancements on arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Part 2
Advanced Gosu features
14 Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Annotating a class, method, type, class variable, or argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Function argument annotations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Built-in annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Getting annotations at run time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
Annotation access at run time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
Getting multiple annotations of multiple types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Getting annotation data from a type at run time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Defining your own annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Customizing annotation context and behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Limiting annotation usage to specific code contexts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Setting retention of an annotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Setting inheritance of an annotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Setting documented status of an annotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
15 Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Dimensions overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Dimensions expressions example (Score) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
7
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
16 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Overview of Gosu generics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Compatibility of Gosu generics with Java generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
Parameterizing a class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Parameterizing a method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Generic methods that reify a type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Restricting generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Using generics with collections and blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Multiple dimensionality generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Generics with custom containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
19 Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Using Gosu composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Overriding methods independent of the delegate class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Declaring delegate implementation type in the variable definition . . . . . . . . . . . . . . . . . . . . . . . . . 251
Using one delegate for multiple interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Using composition with built-in interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
8
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
22 Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Template overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Template expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Running Gosu statements in a template scriptlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Escaping special characters for templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Using template files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Creating and running a template file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Create and use a template file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Template parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Support and use parameters in a template file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Maximum file-based template size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
Extending a template from a class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
Template comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
Template export formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
10
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
26 Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
Overview of thread safety and concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
Request and session scoped variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Concurrent lazy variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Optional non-locking lazy variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Concurrent cache. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Create a thread-safe cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
Concurrency with monitor locks and reentrant objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
27 Checksums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
Overview of checksums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
Creating a fingerprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
11
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Part 3
Gosu programs
28 Command-prompt tool. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Gosu command-prompt tool basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Accessing entities and other types from the Gosu command-prompt tool. . . . . . . . . . . . . . . . . . . 431
Unpacking and installing the Gosu command-prompt tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Command-prompt tool and options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Write and run a Gosu program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Command-prompt arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Create and run a Gosu program that processes arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
29 Programs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
The structure of a Gosu program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Metaline as first line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Functions in a Gosu program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Part 4
Testing
30 GUnit Test Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Create a framework test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Core functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
Support functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Create a framework test suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Run a test suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Part 5
Gosu style
32 Coding style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
General coding guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
12
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
13
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Document Purpose
InsuranceSuite Guide If you are new to Guidewire InsuranceSuite applications, read the InsuranceSuite Guide for informa‐
tion on the architecture of Guidewire InsuranceSuite and application integrations. The intended read‐
ers are everyone who works with Guidewire applications.
Application Guide If you are new to PolicyCenter or want to understand a feature, read the Application Guide. This guide
describes features from a business perspective and provides links to other books as needed. The in‐
tended readers are everyone who works with PolicyCenter.
Database Upgrade Guide Describes the overall PolicyCenter upgrade process, and describes how to upgrade your PolicyCenter
database from a previous major version. The intended readers are system administrators and imple‐
mentation engineers who must merge base application changes into existing PolicyCenter application
extensions and integrations.
Configuration Upgrade Guide Describes the overall PolicyCenter upgrade process, and describes how to upgrade your PolicyCenter
configuration from a previous major version. The intended readers are system administrators and im‐
plementation engineers who must merge base application changes into existing PolicyCenter applica‐
tion extensions and integrations. The Configuration Upgrade Guide is published with the Upgrade
Tools and is available from the Guidewire Community.
New and Changed Guide Describes new features and changes from prior PolicyCenter versions. Intended readers are business
users and system administrators who want an overview of new features and changes to features. Con‐
sult the “Release Notes Archive” part of this document for changes in prior maintenance releases.
Installation Guide Describes how to install PolicyCenter. The intended readers are everyone who installs the application
for development or for production.
System Administration Guide Describes how to manage a PolicyCenter system. The intended readers are system administrators re‐
sponsible for managing security, backups, logging, importing user data, or application monitoring.
Configuration Guide The primary reference for configuring initial implementation, data model extensions, and user inter‐
face (PCF) files for PolicyCenter. The intended readers are all IT staff and configuration engineers.
PCF Reference Guide Describes PolicyCenter PCF widgets and attributes. The intended readers are configuration engineers.
Data Dictionary Describes the PolicyCenter data model, including configuration extensions. The dictionary can be gen‐
erated at any time to reflect the current PolicyCenter configuration. The intended readers are configu‐
ration engineers.
Security Dictionary Describes all security permissions, roles, and the relationships among them. The dictionary can be
generated at any time to reflect the current PolicyCenter configuration. The intended readers are con‐
figuration engineers.
Globalization Guide Describes how to configure PolicyCenter for a global environment. Covers globalization topics such as
global regions, languages, date and number formats, names, currencies, addresses, and phone num‐
bers. The intended readers are configuration engineers who localize PolicyCenter.
Rules Guide Describes business rule methodology and the rule sets in Guidewire Studio for PolicyCenter. The in‐
tended readers are business analysts who define business processes, as well as programmers who
write business rules in Gosu.
Contact Management Guide Describes how to configure Guidewire InsuranceSuite applications to integrate with ContactManager
and how to manage client and vendor contacts in a single system of record. The intended readers are
PolicyCenter implementation engineers and ContactManager administrators.
Document Purpose
Best Practices Guide A reference of recommended design patterns for data model extensions, user interface, business
rules, and Gosu programming. The intended readers are configuration engineers.
Integration Guide Describes the integration architecture, concepts, and procedures for integrating PolicyCenter with ex‐
ternal systems and extending application behavior with custom programming code. The intended
readers are system architects and the integration programmers who write web services code or plu‐
gin code in Gosu or Java.
Java API Reference Javadoc‐style reference of PolicyCenter Java plugin interfaces, entity fields, and other utility classes.
The intended readers are system architects and integration programmers.
Gosu Reference Guide Describes the Gosu programming language. The intended readers are anyone who uses the Gosu lan‐
guage, including for rules and PCF configuration.
Gosu API Reference Javadoc‐style reference of PolicyCenter Gosu classes and properties. The reference can be generated
at any time to reflect the current PolicyCenter configuration. The intended readers are configuration
engineers, system architects, and integration programmers.
Glossary Defines industry terminology and technical terms in Guidewire documentation. The intended readers
are everyone who works with Guidewire applications.
Product Model Guide Describes the PolicyCenter product model. The intended readers are business analysts and implemen‐
tation engineers who use PolicyCenter or Product Designer. To customize the product model, see the
Product Designer Guide.
Product Designer Guide Describes how to use Product Designer to configure lines of business. The intended readers are busi‐
ness analysts and implementation engineers who customize the product model and design new lines
of business.
cd installDir
narrow bold The name of a user interface element, such as Click Submit.
a button name, a menu item name, or a tab
name.
monospace Code examples, computer output, class and The getName method of the IDoStuff API returns the name of the
method names, URLs, parameter names, string object.
literals, and other objects that might appear in
programming code.
monospace Variable placeholder text within code Run the startServer server_name command.
italic examples, command examples, file paths, and Navigate to [Link]
URLs.
Support
For assistance, visit the Guidewire Community.
About PolicyCenter documentation 15
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Guidewire customers
[Link]
Guidewire partners
[Link]
Gosu introduction
This topic introduces the Gosu language, including basic syntax and a list of features.
Welcome to Gosu
Welcome to the Gosu language. Gosu is a general-purpose programming language built on top of the Java Virtual
Machine (JVM). Because Gosu uses the JVM, Gosu includes the following features:
• Java compatible, so you can use Java types, extend Java types, and implement Java interfaces
• Object-orientation
• Easy to learn, especially for programmers familiar with Java
• Imperative paradigm
Gosu includes the following additional features:
• Static typing, which helps you find errors at compile time.
• Type inference, which simplifies your code and preserves static typing.
• Blocks, which are in-line functions that you can pass around as objects. Some languages call these closures or
lambda expressions.
• Enhancements, which add functions and properties to other types, even Java types. Gosu includes built-in
enhancements to common Java classes, some of which add features that are unavailable in Java (such as blocks).
• Generics, which abstracts the behavior of a type to work with multiple types of objects. The Gosu generics
implementation is 100% compatible with Java, and adds additional powerful improvements.
• XML/XSD support.
• Web service (SOAP) support.
Large companies around the world use Gosu every day in production systems for critical applications.
Basic Gosu
The following Gosu program uses the built-in print function to write the text "Hello World" to the default output
stream or console:
print("Hello World")
Gosu uses the Java type [Link] as its native String type to manipulate texts. You can create in-line
String literals just as in Java. In addition, Gosu supports native in-line templates, which simplify common text
substitution coding patterns.
To declare a variable in the simplest way, use the var statement followed by the variable name. Typical Gosu code
also initializes the variable by using the equal sign followed by any Gosu expression:
Gosu introduction 19
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
var x = 10
var y = x + x
Although this example does not specify types for the variables, Gosu is statically typed. All variables have a
compile-time type that Gosu enforces at compile time, even though this example has no explicit type declaration.
Gosu automatically assigns the type int to these variables. Gosu infers the type int from the expressions on the
right side of the equal signs on lines that declare the variables. Inferring the type of an item from the expression that
initializes the item is called type inference.
Type inference simplifies Gosu code compared to other statically typed programming languages. Type inference
makes typical Gosu code easy to read but retains the power and safety of static typing. For example, take the
common pattern of declaring a variable and instantiating an object.
In Gosu, this pattern looks like:
The Gosu version is more readable and concise than the Java version.
Gosu also supports explicit type declarations of variables during declaration by adding a colon character and a type
name. The type name could be a language primitive, a class name, or interface name. For example:
var x : int = 3
Explicit type declarations are required if you are not initializing the variable on the same statement as the variable
declaration. Explicit type declarations are also required for all class variable declarations.
From the previous examples, you might notice another difference between Gosu and Java: no semicolons or other
line ending characters. Semicolons are unnecessary in nearly every case, and the standard style is to omit them.
See also
• “Generics in Gosu” on page 41
• “Type inference” on page 39
• “More about the Gosu type system” on page 38
• “Gosu statement terminators” on page 42
if statements
Gosu has the familiar if, else if, and else statements:
Gosu permits the more readable English words for the Boolean operators: and, or, and not. Alternatively, you can
use the symbolic versions from Java (&&, ||, and !).
20 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
for loop
The for loop in Gosu is similar to the Java 1.5 syntax:
This syntax accepts arrays or any Iterable object. Although the syntax does not specify a type for ad, the variable
is strongly typed. Gosu infers the type based on the iterated variable’s type. In the previous example, if addressList
has type Address[], then ad has type Address. If the addressList variable is null, Gosu skips the for statement
entirely, and generates no error. In contrast, Java throws a null pointer exception if the iterable object is null.
If you need an index within the loop, use the following syntax to access the zero-based index:
Intervals
Gosu has native support for intervals. An interval is a sequence of values of the same type between a given pair of
endpoint values. For example, the set of integers beginning with 0 and ending with 10 is an integer interval. A
closed interval contains the starting and ending values, in this example, including 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. The
Gosu syntax for this closed interval is 0..10. A typical use for intervals is in writing concise for loops:
for (i in 1..10) {
print(i)
}
An open interval excludes the value at one or both ends of the interval. The Gosu syntax 1|..|10 defines an interval
that is open on both sides, and contains the values from 2 through 9.
Intervals do not need to represent numbers. Intervals can be of types including numbers, dates, or other abstractions
such as names. Gosu accepts the shorthand syntax of the two periods, (..) for intervals of dates and common
number types. You can also add custom interval types that support iterable comparable sequences. If your interval
type implements the required interfaces, you can use intervals of that type in for loop declarations:
Gosu does not have a direct general purpose equivalent of the Java three-part for declaration:
In practice, using intervals makes most use of this pattern unnecessary. If necessary, you can use a Gosu while loop
to duplicate this pattern.
To use intervals with for loops, the interval must be iterable. Custom non-iterable intervals are useful mainly for
math and theoretical work. For example, a non-iterable interval could represent non-countable values such as the
infinite set of real numbers between two other real numbers.
switch statement
The Gosu switch statement can test any type of object, with a special default case at the end:
var x = "b"
switch (x) {
case "a":
print("a")
break
Gosu introduction 21
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
case "b":
print("b")
break
default:
print("c")
}
In Gosu, you must put a break statement at the end of each case to jump to the end of the switch statement.
Otherwise, Gosu continues to the next case in the series. In the previous example, if you remove the break
statements, the code prints both "b" and "c". Java has the same requirement. Some other languages do not require
the break statement to prevent continuing to the next case.
See also
• “Intervals” on page 131
Overview of blocks
Gosu supports in-line functions that you can pass around as objects, which are called blocks. Other languages call
blocks closures or lambda expressions.
Blocks are useful as method parameters, in which the method’s implementation generalizes a task or algorithm but
callers provide code to implement the details of the task. For example, Gosu adds many useful methods to Java
collections classes that take a block as a parameter. That block could return an expression, such as a condition
against which to test each item, or could represent an action to perform on each item.
For example, the following Gosu code makes a list of strings, sorts the list by String length, and then iterates across
the result list to print each item in order:
See also
• “Blocks” on page 175
• “Gosu block shortcut for anonymous classes implementing an interface” on page 168
Define a block
A block defines an in-line function. For example, a block named square multiplies a value by itself and returns the
result.
Procedure
1. Start with the \ character.
2. Optionally add a list of arguments as name : type pairs.
3. Add the -> characters, which mark the beginning of the block’s body.
4. Finally, add either a statement list surrounded by braces: { and }, or a Gosu expression.
Example
The following block multiplies a number with itself to square the number:
22 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
var square = \ x : Integer-> x * x // No need for braces for expressions, but must use for statements
var myResult = square(10) // Call the block
Overview of enhancements
Gosu provides a feature called enhancements, which supports adding functions and properties to other types.
Enhancements are especially powerful for enhancing native Java types, and types defined in other people’s code.
For example, Gosu includes built-in enhancements on collection classes and interfaces, such as [Link],
that improve power and readability of collections code. For example, the following code takes a list of String
objects, and uses a block to sort the list by the length of each String. The code then uses another block in the
iteration across the result list to print each item:
The sortBy and each methods in this example are Gosu enhancement methods on the List interface. Both methods
return the result list, which makes them useful for chaining methods in series.
See also
• “Enhancements” on page 201
• “Blocks” on page 175
Overview of collections
Gosu provides several features for usage of collections like lists and maps. Gosu directly uses the built-in Java
collection classes like [Link] and [Link]. This usage makes Gosu straightforward to
use for interaction with pre-existing Java classes and libraries.
In addition, Gosu adds the following features:
• Shorthand syntax for creating lists and maps that is natural to read and still uses static typing:
• Shorthand syntax for getting and setting elements of lists and maps
• Gosu includes enhancements that improve Java collection classes. Some enhancements enable you to use Gosu
features that are unavailable in Java. For example, the following Gosu code initializes a list of String objects and
then uses enhancement methods that use Gosu blocks, which are in-line functions.
// Iterate across the list and run arbitrary code for each item:
[Link](\ str -> print(str))
Notice how the collection APIs are chainable. Alternatively, for readability, you can put each step on a separate
lines. The following example declares some data, then uses a block to search for a subset of the items, and then sorts
the results.
var minLength = 4
var strings = { "yellow", "red", "blue" }
Gosu introduction 23
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Overview of blocks” on page 22
Gosu includes transformations on Java types that make your Gosu code clearer, such as turning getters and setters
into Gosu properties.
Access to Java types from Gosu includes:
• Instantiation of Java classes with the new keyword
• Implementing Java interfaces
• Manipulating Java objects as native Gosu objects
• Calling object methods on instantiated objects
• Exposing object methods that look like getters and setters as properties
• Calling static methods on Java types
• Providing built-in extensions and improvements of many common Java types by using Gosu enhancements
• Support for your own extensions of Java types and interfaces
• Support for Java primitive types
See also
• “Packages always in scope” on page 116
• “Overview of enhancements” on page 23
• “Calling Java from Gosu” on page 139
To create a class, use the class keyword, followed by the class name, and then define the variables, then the
methods for the class. To define one or more constructor (object instance initialization) methods, use the construct
keyword. The following example shows a simple class with one constructor that requires a String argument:
class ABC {
construct(id : String) {
}
}
You can optionally specify that your class implements one or more interfaces.
To create a new instance of a class, use the new keyword in the same way as in Java. Pass any constructor arguments
in parentheses. Gosu decides what version of the class constructor to use based on the number and types of the
arguments. For example, the following calls the constructor for the ABC class defined earlier in this topic:
Gosu improves on this basic pattern and introduces a standard compact syntax for property initialization during
object creation. For example, suppose you have the following Gosu code:
After the first line, four more lines contain the object variable name, which is repeated information.
You can use Gosu object initializers to simplify this code to only a couple of lines:
You can also choose to list each initialization on its own line, which uses more lines but is more readable:
Unlike in Java, for special case usage you can optionally omit the type name entirely in a new expression if the type
is known from its context. Do not omit the type name in typical code. However, for dense hierarchical structure,
omitting the type name can make your Gosu code more readable.
See also
• “Overview of interfaces” on page 29
• “Creating and instantiating classes” on page 148
• “Using the operator new in object expressions” on page 86
• “Importing types and package namespaces” on page 114
Functions
Declare a function by using the function keyword. Gosu uses the term method for a function that is part of another
type. In Gosu, types follow the variable or function definition, separated by a colon. In contrast, Java types precede
the variable or parameter name with no delimiter. To return a value, add a statement with the return keyword
followed by the value. The following simple function returns a value:
Gosu introduction 25
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Method invocation in Gosu looks familiar to programmers of imperative languages, particularly Java. Just use the
period symbol followed by the method name and the argument list in parentheses:
[Link](myUser)
Pass multiple parameters, which can be Gosu expressions, delimited by commas, just as in Java:
In some cases, such as in-line functions in Gosu programs, functions are not attached to a class or other type. You
call such functions directly in your code. A rare globally available function for any Gosu code is print. Call that
function with a String argument to write data to the system console or other default output stream. For example, the
following line prints text to the console:
print("Hello Gosu!")
Gosu supports access control modifiers (public, private, internal, and protected). These modifiers have the
same meaning as in Java. For example, if you mark a method public, any other code can call that method.
Gosu also supports static methods, which are methods on the type rather than on object instances.
If the return type for a method is not void, all possible code paths in the method must contain a return statement
and return a value. The set of all paths includes all outcomes of conditional execution, such as if and switch
statements. This requirement is identical to the analogous requirement in Java. The Gosu editor notifies you at
compile time if your code violates this requirement.
See also
• “Access modifiers” on page 157
• “Static members” on page 28
• “Gosu functions” on page 111
One difference between Gosu and some languages, including Java, is full support in Gosu for properties. A property
provides a dynamic getter method and a dynamic setter method for its value. To set or get properties from an object,
use natural syntax. Type the period (.) character followed by the property name just as for an object variable:
var s = [Link]
[Link] = "John"
Internally, Gosu calls the property getter and setter methods. In addition, Gosu has a special null-safety behavior
with pure property paths, which have the form obj.Property1.Property2.Property3.
Define a property accessor function, which is a property getter, by using the declaration property get instead of
function. Define a setter function by using function declaration property set instead of function. These
property functions dynamically get or set the property, depending on whether the definition is property get or
property set. Properties can be read/write, read-only, or write-only. Gosu provides a special shortcut to expose
internal variables as public properties with other names. Use the syntax as PROPERTY_NAME in the definition for a
26 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
variable. This syntax separates the internal implementation of the variable from how you expose the property to
other code:
var _name : String as Name // Exposes the _name field as a readable and writable 'Name' property
This syntax is a shortcut for creating a property get function and a property set function for each variable. This
syntax is the standard and recommended Gosu style for designing public properties. Do not expose actual class
variables as public, although for compatibility with Java, Gosu does support exposing these variables.
The following code defines a simple Gosu class:
class Person {
var _name : String as Name // Exposes the _name field as a readable and writable 'Name' property
var _id : String // Variables are private by default
// Constructors are like functions called construct but omit the function keyword.
// You can supply multiple method signatures with different numbers or types of arguments
construct(id : String){
_id = id
_name = ""
}
With this class, you can use concise code like the following:
See also
• “Property accessor paths are null safe” on page 28
method but without the prefix is. For example, suppose a Java method signature is isVisible(). Gosu exposes
this method as a property get function for a Boolean property named Visible.
If the Java code has a setter and a getter, Gosu makes the property readable and writable. If the setter is absent, Gosu
makes the property read-only. If the getter is absent, Gosu makes the property write-only.
For example, consider a Java class called Circle with the following method declarations:
Gosu exposes these methods as the Radius property, which is readable and writable. With this property, you can use
straightforward code such as:
See also
• “Java get, set, and is methods convert to Gosu properties” on page 141
obj.Property1.Property2.Property3
In most cases, if any object to the left of the period character is null, Gosu does not throw a null pointer exception
(NPE) and the expression returns null. Gosu null-safe property paths tend to simplify real-world code. Gosu null-
tolerant property accessor paths are a very good reason to expose data as properties in Gosu classes and interfaces
rather than as setter and getter methods.
Gosu provides additional null-safe operators. For example, specify default values with code like:
// Set display text to the String in the txt variable, or if it is null use "(empty)"
var displayText = txt ?: "(empty)"
WARNING In Studio, Gosu code in the Gosu Scratchpad has different compiler behavior than any
other part of Studio. If you run code in Gosu Scratchpad directly in Studio without being
connected to a running server, the code compiles and runs locally in Studio with different
behavior. Most notably, the behavior of null safety in the period operator is different. In nearly all
other contexts in Studio, the period operator is null safe. However, in Gosu Scratchpad in Studio
without a connection to a running server, Gosu is not null-safe. Code that might not throw an
exception in a Gosu class might throw an exception in Gosu Scratchpad. If Studio is connected to
a running server, Studio sends the Gosu code to the server. The PolicyCenter server uses the
standard null-safe behavior for the period operator.
See also
• “Null safety for properties and other operators” on page 39
Static members
Gosu supports static members on a type. Static members include variables, functions, property declarations, and
static inner classes on a type. A static member exists only once, on the type, not on instances of the type.
To declare a type as static for a new Gosu class, use the static keyword, as in Java.
28 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The syntax for using a static member is to use the period (.) character followed by the property name or method call
after a type reference, which is the type name. For example, the following code accesses a static property and calls a
static method:
Alternatively, to use the static members without qualifying them with the class name, you use the syntax of the uses
statement that imports static members. For example, the following code is equivalent to the previous lines:
uses MyClass#*
...
var myVar = MY_CONST // Get a static property value
staticMethodName() // Call a static method
See also
• “Modifiers” on page 157
• “Importing static members” on page 116
Overview of interfaces
Gosu supports interfaces, including full support for Java interfaces. An interface is a set of method signatures that a
type must implement. An interface defines a contract that specifies the minimum set of functionality to be
considered compatible. To define an interface, use the interface keyword, then the interface name, and then a set
of method signatures without function bodies. The following Gosu code uses the interface keyword to define a
simple interface:
package example
interface ILoadable {
function load()
}
A class can implement the interface with the implements keyword followed by a comma-delimited list of interfaces.
A class that implements an interface contains all methods in the interface, as shown in the following code:
package example
function load() {
print("Loading...")
}
}
See also
• “Interfaces” on page 171
names*.length
Using the expansion operator on a list retrieves a property from every item in the list and returns all instances of that
property in a new list. The expansion operator works similarly with arrays.
Gosu introduction 29
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Let us consider the previous example names*.length. Assume that names contains a list of String objects, and
each one represents a name. All String objects contain a length field. The result of the previous expression is a list
containing the same number of items as the original list. However, each item is the length (the [Link]
property) of the corresponding name String object.
Gosu uses Gosu generics, an advanced type feature, to infer the type of the list as the appropriate parameterized
type. Similarly, Gosu infers the type of the result array if you call the operator on an array.
See also
• “Generics in Gosu” on page 41
• “List expansion (*.)” on page 187
Overview of comparisons
In general, the comparison operators work as you might expect if you are familiar with most programming
languages. Some notable differences are:
• The operators >, <, >=, and <= operators work with all objects that implement the Comparable interface, not just
with numbers.
• The standard equal comparison == operator implicitly uses the equals method on the first (leftmost) object. This
operator does not check for pointer equality. It is null safe in that if the value on either side of the operator is
null, Gosu does not throw a null pointer exception.
Note: In contrast, in the Java language, the == operator evaluates to true if and only if both
operands have exactly the same reference value. The Java expression evaluates to true if both
terms refer to the same object in memory. This behavior provides the expected result for primitive
types like integers. For reference types, the references are not usually what you want to compare.
Instead, to compare value equality, Java code typically uses [Link](), rather than the ==
operator.
• In some cases, you do need to compare identity references, to determine whether two objects reference the same
in-memory object. Gosu provides a special equality operator called === (three equal signs) to compare object
equality. This operator compares whether both references point to the same in-memory object. The following
examples illustrate some differences between == and === operators:
var x = 1 + 2 false These two comparison arguments reference the same value but different objects. Using
var str = x as String the triple‐equals operator returns false.
print(str === "3")
See also
• “Property accessor paths are null safe” on page 28
Case sensitivity
Gosu language itself is case sensitive. Write all Gosu as case-sensitive code matching the declaration of the language
element.
See also
• “Gosu case sensitivity and capitalization” on page 42
30 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
i++
These operators always form statements, not expressions. For example, the following Gosu is valid:
var i = 1
while (i < 10) {
i++
print(i)
}
The following Gosu is invalid because statements are impermissible in an expression, which Gosu requires in a
while statement:
var i = 1
while (i++ < 10) { // Compilation error!
print(i)
}
Gosu supports the increment and decrement operator only after a variable, not before a variable, so i++ is valid but +
+i is invalid. The ++i form exists in other languages to support expressions in which the result is an expression that
you pass to another statement or expression. In Gosu, these operators do not form an expression, so you cannot use
increment or decrement in while declarations, if declarations, and for declarations.
See also
• “Variable assignment” on page 103
interface IClipboardPart {
function load()
}
construct() {
_clipboardPart = new ClipboardPart(this)
[Link]()
Gosu introduction 31
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
}
}
In this example, the class definition for MyWindow uses the delegate keyword to delegate implementation of the
IClipboardPart interface. To complete the delegation, the constructor for the MyWindow class creates an object of
the ClipboardPart class. This object is the delegate. It has the delegate’s name, _clipboardPart. When a class
delegates the implementation of an interface, it must construct the delegate it declares. Upon doing so, the class
fulfills indirectly its implementation duty.
The class that defines a delegate object must implement the interface that the delegate represents. In the example
code, the ClipboardPart class defines the delegate object, _clipboardPart. This definition implements the sole
method that the IClipboardPart interface declares, load().
When instantiating the MyWindow class, the class constructor in the example code calls the constructor for the class
that defines the delegate object, _clipboardPart. Upon its construction, _clipboardPart has access to all of the
methods that its defining class, ClipboardPart, implements, including the load() method. Upon constructing its
delegate, the MyWindow class has access to the load() method as well.
The class constructor in the example code then calls the load() method. This method in turn calls the print()
method. The print() method then writes the sentence “Gosu is loaded!” to the system console or default output
stream.
You can use a delegate to represent (provide methods for) multiple interfaces for the enclosing class. In the
delegate statement, specify a comma-separated list of interfaces. For example:
The Gosu type system handles the type of the variable in the previous example by using a special kind of type called
a compound type.
See also
• “Composition” on page 249
Overview of concurrency
If more than one Gosu thread interacts with data structures that another thread needs, you must ensure that you
protect data access to avoid data corruption. The requirement to support concurrent access from multiple threads is
called concurrency. Code that can safely get or set concurrently accessed data is called thread-safe.
Gosu provides the following concurrency APIs:
• Support for Java monitor locks, reentrant locks, and custom reentrant objects – Gosu provides access to
Java-based classes for monitor locks and reentrant locks in the Java package [Link]. Gosu
provides straightforward access to these classes with using clauses that also properly handle cleanup if
exceptions occur. Additionally, Gosu provides a straightforward way to create custom Gosu objects that support
reentrant object handling, as shown in the following example. The following Gosu code that uses the using
keyword shows the compact readable syntax for using Java-defined reentrant locks.
// A property get function uses the lock and calls another method for the main work
property get SomeProp() : Object using (_lock) {
return _someVar.someMethod() // Do your work here and Gosu synchronizes it, and handles cleanup
}
• Scoping classes (pre-scoped maps) – Scope-related utilities in the class [Link] provide
synchronization and protect access to shared data. These APIs return Map objects that you can use to safely get
and put data by using different scope semantics.
• Lazy concurrent variables – The LazyVar class in [Link] implements what is known as a lazy
variable. Gosu does not construct a lazy variable until the first time any code uses the variable. For example, the
following code is part of a class definition that defines the object instance. For example, Gosu does not run the
following Gosu block that creates an ArrayList until the first usage of the variable:
32 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
• Concurrent cache – The Cache class in [Link] declares a cache of values that you can look up
quickly and in a thread-safe way. A Cache object provides a concurrent cache similar to a Least Recently Used
(LRU) cache. To use the cache, call the get method with an argument of the input value, which is the key. If the
value is in the cache, the get method returns the value from the cache. If the value is not cached, Gosu calls the
block and calculates the value from the key, and then caches the result. For example:
print([Link]("Hello world")
See also
• “Concurrency” on page 417
Overview of exceptions
Gosu supports the full feature set for Java exception handling, including try/catch/finally blocks. However,
unlike Java, no exceptions are checked. Standard Gosu style is to avoid checked exceptions where possible. You can
throw any exception in Gosu, but if the exception is not a RuntimeException, Gosu wraps the exception in a
RuntimeException.
Catching exceptions
The following Gosu code is a simple try/catch/finally:
try {
[Link](bar)
} catch (e : Exception) {
print("Failed to enter the bar!")
} finally {
// Clean-up code here...
}
To catch only specific exceptions, specify a subclass such as IOException instead of Exception. For example:
try {
doSomethingThatMayThrowIOException()
} catch (e : IOException) {
// Handle the IOException
}
Throwing exceptions
In Gosu, throw an exception with the throw statement, which is the throw keyword followed by an object. The
following example creates an explicit RuntimeException exception:
You can also pass a non-exception object to the throw statement. If you pass a non-exception object, Gosu first
coerces it to a String. Next, Gosu wraps the String in a new RuntimeException, which has a Message property
that contains the String data. Your error-handling code can use the Message property for logging or displaying
messages to users.
You could rewrite the previous throw code example as the concise code:
Gosu introduction 33
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Overview of annotations
Gosu annotations are a syntax to provide metadata about a Gosu class, constructor, method, class variable, or
property. An annotation can control the behavior of the item or the documentation for the item.
This code demonstrates adding a @Throws annotation to a method to indicate what exceptions it throws.
class MyClass{
You can define custom annotations, and optionally have your annotations take arguments. If there are no arguments,
you can omit the parentheses.
You can get annotations from types at run time.
Gosu supports named arguments syntax for annotations:
See also
• “Annotations” on page 209
Overview of templates
Gosu provides a syntax that supports in-line dynamic templates. Use a template to combine static text with values
from variables or other calculations Gosu evaluates template values at run time. For example, suppose you want to
display text with a calculation in the middle of the text:
Template expressions can include variables and dynamic calculations. Gosu substitutes the run-time values of the
expressions in the template. The following line is an example of a method call inside a template:
At compile time, Gosu ensures all template expression are valid and type safe. At run time, Gosu runs the template
expression, which must return a String value or a type that can cast to a String.
In addition to in-line Gosu templates, Gosu supports a powerful file-based approach for Gosu templates with
optional parameter passing. Any use of the parameters is validated for type-safety, just like any other Gosu code. For
example, use a template to generate a customized notification email, and design the template to take parameters.
Parameters could include type safe references to the recipient email address, the sender email address, and other
objects. Insert the parameters directly into template output, or call methods or get properties from parameters to
generate your customized email report.
See also
• “Templates” on page 301
34 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
[Link].*
<xs:element name="DriverInfo">
<xs:complexType>
<xs:sequence>
<xs:element ref="DriversLicense" minOccurs="0? maxOccurs="unbounded"/>
<xs:element name="PurposeUse" type="String" minOccurs="0?/>
<xs:element name="PermissionInd" type="String" minOccurs="0?/>
<xs:element name="OperatorAtFaultInd" type="String" minOccurs="0?/>
</xs:sequence>
<xs:attribute name="id" type="xs:ID" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="DriversLicense">
<xs:complexType>
<xs:sequence>
<xs:element name="DriversLicenseNumber" type="String"/>
<xs:element name="StateProv" type="String" minOccurs="0?/>
<xs:element name="CountryCd" type="String" minOccurs="0?/>
</xs:sequence>
<xs:attribute name="id" type="xs:ID" use="optional"/>
</xs:complexType>
</xs:element>
The following Gosu code uses XSD-based types to manipulate XML objects:
uses [Link]
uses [Link]
uses [Link]
The example to follow uses the XSD file, [Link]. In particular, the code relies upon the following
portion of the XSD file:
Gosu introduction 35
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
<xs:complexType name="CredentialsArrayType">
<xs:sequence>
<xs:element ref="tns:CredentialsElem" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
In this example, the following Gosu code creates a first element defined in the XSD file. This first element is of type
CredentialsArray. Next, the code creates a second element defined in the same XSD file. This second element is
of type CredentialsElem. The code then adds the second element as a child to the first element:
uses [Link].*
// Create a new child element that is legal in the XSD, and add it as a child
var c1 = new CredentialsElem()
[Link]("Harry Truman")
[Link]("password")
[Link](c1)
See also
• “Working with XML in Gosu” on page 253
See also
• Integration Guide
In Gosu, your main Gosu program (.gsp file) can call any necessary code, including Gosu or Java classes. If you
want to mirror the Java style, your .gsp file can contain a single line that calls a main method on a Gosu class or
Java class.
To tell Gosu where to load additional classes, do either of the following:
• Use the Class-Path attribute in the manifest of a JAR file.
• Use the -classpath option on the command-prompt tool.
You can combine these two options for greater flexibility and to support very long class paths.
Manifest-Version: 1.0
Class-Path: [Link] classfiles/[Link] file:/C:/javalib/[Link]
Created-By: 1.8.0_92 (Oracle Corporation)
C:\gosu\myprograms\test1\[Link]
Copy your class file for the class [Link] to the location:
C:\gosu\myprograms\test1\src\mypackage\[Link]
C:\gosu\myprograms\test1\lib\[Link]
For this example, add two directories to the class path with the following command:
See also
• “Programs” on page 437
• “Command-prompt tool and options” on page 432
Gosu introduction 37
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Intelligent code completion and other Gosu editor tools” on page 39
• “Type system” on page 403
• “Variable type declaration” on page 102
• “Generics” on page 221
If you write code that calls this method and passes an integer instead of a Person, the code fails with a type
mismatch compiler error. The compiler recognizes that the parameter value is not a Person, which is the contract
between the function definition and the code that calls the function.
Similarly, Gosu ensures that all property access on the Person object (LastName and FirstName properties) are
valid properties on the class definition of Person. If the code inside the function calls any methods on the object,
Gosu also ensures that the method name that you are calling actually exists on the type.
Within the Gosu editor, violations of these rules become compilation errors. By finding this large class of problems
at compile time, you can avoid unexpected run-time failures.
Type inference
Gosu supports type inference, in which Gosu can often infer the type of an item without requiring explicit type
declarations in the Gosu code. For instance, Gosu can determine the type of a variable from its initialized value:
var length = 12
var list = new [Link]()
In the first line, Gosu infers the length variable has the type int. In the second line, Gosu infers the type of the list
variable is of type ArrayList. In most cases, it is unnecessary to declare a variable’s type if Gosu can determine the
type of the initialization value.
The Gosu syntax for explicit declarations of the type of the variable during declaration is:
For typical code, Gosu coding style is to omit the type and use type inference to determine the variable’s type.
Another standard Gosu coding style is to use a coercion on the right side of the expression with an explicit type. For
example, suppose you use a class called Vehicle, which has a subclass Car. If the variable v has the compile-time
type Vehicle, the following code coerces the variable to the subtype:
Refactoring
Static typing makes it much easier for development tools to perform smart code refactoring.
See also
• Configuration Guide
One notable difference between Gosu and some other languages is that property accessor paths in Gosu are null-
tolerant, also called null-safe. Only expressions separated by period (.) characters that access a series of instance
variables or properties support null safety, such as the following form:
[Link]
In most cases, if any object to the left of the period character is null, Gosu does not throw a null-pointer exception
(NPE) and the expression returns null. Gosu null-safe property paths tend to simplify real-world code. Often, a
null expression result has the same meaning whether the final property access is null or earlier parts of the path are
null. For such cases in Gosu, do not check for the null value at every level of the path. This conciseness makes
your Gosu code easier to read and understand.
For example, suppose you have a variable called house, which contains a property called Walls, and that object has
a property called Windows. The syntax to get the Windows value is:
[Link]
In some languages, you must be aware that if house is null or [Link] is null, your code throws a null-
pointer exception. The following common coding pattern avoids the exception:
// Initialize to null
var x : ArrayList<Windows> = null
// Check earlier parts of the path for null to avoid a null-pointer exceptions (NPE)
if (house != null and [Link] != null) {
x = [Link]
}
In Gosu, if earlier parts of a pure property path are null, the expression is valid and returns null. The following
Gosu code is equivalent to the previous example and a null-pointer exception never occurs:
var x = [Link]
By default, method calls are not null-safe. If the right side of a period character is a method call, Gosu throws a null-
pointer exception (NPE) if the value on the left side of the period is null.
For example:
[Link]()
If house is null, Gosu throws an NPE. Gosu assumes that method calls might have side effects, so Gosu cannot skip
the method call and return null.
Gosu provides a variant of the period operator that is always explicitly null-safe for both property access and method
access. The null-safe period operator has a question mark before the period: ?.
If the value on the left of the ?. operator is null, the expression evaluates to null.
For example, the following expression evaluates left-to-right and contains three null-safe property operators:
obj?.PropertyA?.PropertyB?.PropertyC
house?.myaction()
If house is null, Gosu does not throw an exception. Gosu returns null from the expression.
40 chapter 1: Gosu introduction
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
var displayName = [Link] ?: "(Unknown Title)" // Return "(Unknown Title)" if [Link] is null
• The null-safe index operator (?[]). Use this operator with lists and arrays. The expression returns null if the list
or array value is null at run time, rather than throwing an exception. For example:
• The null-safe math operators (?+, ?-, ?*, ?/, and ?%). For example:
See also
• “Handling null values in expressions” on page 96
• “Properties” on page 151
Generics in Gosu
Generics abstract the behavior of a type to support working with multiple types of objects. Generics are particularly
useful for implementing collections such as lists and maps in a type-safe way. At compile time, each use of the
collection can specify the specific type of its items. For example, instead of just referring to a list of objects, you can
refer to a list of Address objects or a list of Vehicle objects. To specify a type, add one or more parameters types
inside angle brackets (< and >). This syntax that specifies the type of a collection or another item of unknown type is
called parameterizing a generic type. For example:
uses [Link].*
In this example, ArrayList<Date> is an array list of date objects. The Map<String, Date> is a map that maps
String to Date.
The Gosu generics implementation is compatible with the Java 1.5 generics implementation, and adds more
improvements:
• Gosu type inference greatly improves readability. You can omit unnecessary type declarations, which is
especially important for generics because the syntax tends to be verbose.
• Gosu generics support array-style variance of different generic types. In Java, this is a compilation error, even
though it is natural to assume it works. In Java, this is a compilation error:
ArrayList<Object> mylist;
mylist = new ArrayList<String>()
• Gosu types support reified generics. Reified generics preserve generic type information at run time. In complex
cases, you can check the exact type of an object at run time, including any parameterization. In contrast, Java
discards this information completely after compilation, so it is unavailable at run time.
Note: Even in Gosu, parameterization information is unavailable for all native Java types because
Java does not preserve this information beyond compile time. For example the run-time type of
[Link]<Address> in Gosu returns the unparameterized type [Link].
• Gosu includes shortcut initialization syntax for common collection types so that you do not need to see the
generics syntax, which tends to be verbose. For example, consider the following Gosu:
Although this code does not specify a type, the strlist variable is statically typed. Gosu detects the types of
objects that you use to initialize a variable and uses type inference to determine that strlist has the type
[Link]<[Link]>. This generics syntax means “a list of String objects.”
See also
• “Generics” on page 221
See also
• “General coding guidelines” on page 465
Although not recommended, you may also use the following to terminate a Gosu statement:
• A semicolon character (;)
• White space, such as space characters or tab characters
In general, use new-line characters to separate lines so that Gosu code looks cleaner.
For typical code, omit semicolons because they are unnecessary in almost all cases. Standard Gosu style uses
semicolons between multiple Gosu statements when they are all on one line. For example, a short Gosu block
definition uses this style. However, even in those cases, semicolons are optional in Gosu.
// NO - Do not rely on whitespace for line breaks. It is hard to read and errors are common.
print(x) print(y)
// NO - Do not rely on whitespace for line breaks. It is hard to read and errors are common.
var pnum = [Link] cnum = [Link]
IMPORTANT In almost all cases, omit semicolon characters in Gosu. However, standard Gosu style
uses semicolons between multiple Gosu statements on one line, such as in short Gosu block
definitions.
Invalid statements
See also
• “Blocks” on page 175
Gosu comments
Add comments to your Gosu code to explain its programming logic. Gosu supports several styles of comments.
Block comments Use block comments to describe the purpose of classes and methods. A block comment begins with
a slash/asterisk (/*) and ends with an asterisk/slash (*/).
/*
* This is a block comment.
* Use block comments at the beginnings of files and before
* classes and functions.
*/
Use proper capitalization and punctuation in block comments.
Single-line comments Use single‐line comments to describe one or more statements within a function or method. A single‐
line comment begins with double slashes (//) as the first non‐whitespace characters on the line.
if (condition) {
// Handle the condition
Gosu introduction 43
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
...
return true
}
If you cannot fit your comment on a single line, use a sequence of single‐line statements.
Trailing comments Use trailing comments to briefly describe single lines of code. A trailing comment begins with double
slashes (//) as the first non‐whitespace characters after the code that the comment describes.
if (a == 2) {
return true // Desired value of ’a’
}
else {
return false // Unwanted value of ’a’
}
If you place two or more trailing comments on lines of code in a block, indent them all to a common
alignment
You can use some styles of comments to temporarily disable lines or blocks of code during development and testing.
This technique is known as commenting out code.
Commenting out a single line of code Use a single‐line comment delimiter (//) to comment out a line of code.
if (x = 3) {
// y = z This line is commented out for testing.
y = z + 1 This line will excecute for testing.
}
Commenting out a block of code Use a pair of block comment delimiters (/*, */) to comment out a block of code,
even if the block you want to comment out contains block comments.
/*
/*
* The function returns the sum of its parts.
*/
public function myMethod(int A, int B) {
return A + B
}
*/
The preceding function cannot be called, because it is commented out. Gosu per‐
mits the nested block comment within the commented out block of code.
See also
• Rules Guide
• abstract • iterator
• and • length
• annotation • long
• as • NaN
• assert • new
• block • not
• boolean • null
• break • or
• byte • out
• case • outer
• catch • override
• char • package
• class • print
• classpath • private
• construct • property
• contains • protected
• continue • public
• default • readonly
• delegate • represents
• do • return
• double • set
• else • short
• enhancement • startswith
• enum • static
• eval • statictypeof
• extends • structure
• false • super
• final • switch
• finally • this
• float • throw
• for • transient
• foreach • true
• function • try
• get • typeas
• hide • typeis
• if • typeloader
• implements • typeof
• in • uses
• index • using
• Infinity • var
• int • void
• interface • where
Gosu introduction 45
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
• internal • while
gwb gosudoc
PolicyCenter/modules/configuration/out/classes
This feature requires tools that use Java class files, not source code, as input.
The following table shows the differences in functions and variables between Gosu and Java.
To declare variable argument functions, also public String Method call using array initializ‐ Required
called vararg functions, Gosu does not support format(Object... args); er syntax:
the special Java syntax that specifies the argu‐ public String var c =
ments with ... after the parameter type to indi‐ errorMessage(Object... format({"aa","bb"})
cate a variable number of arguments. Instead, de‐ args); Function declaration:
sign methods to use arrays or lists. public function
format(args :
Object[]) : String
Method call with no arguments:
Gosu introduction 47
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The following table shows the differences in the type system between Gosu and Java.
Check if an object is a specific type or myobj instanceof String; myobj typeis String Required.
its subtypes by using typeis, which is
similar to the Java instanceof opera‐
tor.
Gosu downcasts to a more specific Object x = "nice"; var x : Object = "nice" Optional.
type in if and switch statements. Int sl = 0; var sl = 0
Omit casting to the specific type. if (x instanceof String) { if (x typeis String) {
sl = ((String) x).length; sl = [Link] // Downcast
} }
Gosu generics support array‐style var‐ In Java, this code causes a compila‐ The analogous Gosu code works: Optional.
iance of different generic types. In tion error: var mylist :
Java, this usage is a compilation error, ArrayList<Object> mylist; ArrayList<Object>
even though it is natural to assume mylist = new mylist = new
that it works. ArrayList<String>(); ArrayList<String>()
In Gosu, type names are first‐class Class sc = [Link]; var sc = String Required.
symbols for the type. Do not get the
class property from a type name.
The following table shows the differences in defining classes between Gosu and Java.
Declare that you use specific static type import uses Required
members with the keyword uses rather [Link].MY_CONST; [Link]#MY_CONST
than import. Use the # symbol before import [Link].*; uses [Link]#*
the member name or * symbol, not the
period (.) symbol.
To declare one or more class construc‐ class ABC { class ABC { Required
tors, write them as functions named public ABC(String id){ construct(id : String) {
construct but omit the keyword
} }
function. Gosu does not support Java‐
style constructors. } }
The following table shows the differences in control flow between Gosu and Java.
The for loop syntax in Gosu is different for iterating a loop for an integer for (int for (item in 20) Required
number of times. The loop variable contains the zero‐based index. i=1; i<20; i {
Gosu has native support for intervals, which are sequences of values of the ++){ ...
same type between a given pair of end‐point values. For example, the set of ... }
integers beginning with 0 and ending with 10 has the shorthand syntax }
Using Gosu inter‐
0..10. Intervals are useful for writing concise for loops.
vals:
Gosu does not support the for (initialize;compare;increment) syntax
for (i in 1..20)
that Java uses. You can duplicate this syntax by using a while statement.
{
...
}
Gosu introduction 49
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The following table shows optional enhancements that Java does not support and that Gosu provides.
Gosu blocks, which are in‐line functions that Not applicable \ x : Integer -> x * x Optional
act like objects. These blocks are especially
useful with the Gosu collections enhance‐
ments. Blocks can also be useful as a shortcut
for implementing one‐method interfaces.
Native XML support and XSD support. Not applicable var e = [Link](xmlText) Optional
Native support for consuming web services Not applicable [Link](1, true, "c") Optional
with syntax similar to native method calls.
Native String templates and file‐based tem‐ Not applicable var s = "Total = ${ x }." Optional
plates with type‐safe parameters.
Gosu uses the Java‐based collections APIs but List<String> strs = Simplified initialization: Optional
improves upon them: new ArrayList<String>( var strs = {"a", "ab", "abc"}
• Simplified initialization syntax that [Link]( Array‐like "set" and "get":
preserves type safety. "a", "ab", "abc" strs[0] = "b"
• Simpler array‐like syntax for getting and )); var val = strs[1]
setting values in lists, maps, and sets. New APIs on Java collections types:
• Additional methods and properties to [Link](\ str ->
improve functionality of the Java classes. { print(str) })
Some enhancements use Gosu blocks for
concise, flexible code.
For new code, use the Gosu style initialization
and APIs. You can call the more verbose Java
style for compatibility.
List and array expansion operator. Not applicable names*.length Optional
See also
• “Property accessor paths are null safe” on page 28
• “Variable assignment” on page 103
• “Basic type checking” on page 403
• “Enhancements” on page 201
• “Blocks” on page 175
• “Blocks as shortcuts for anonymous classes” on page 181
• “Working with XML in Gosu” on page 253
• “Templates” on page 301
• “Collections” on page 183
• “List expansion (*.)” on page 187
• Integration Guide
See also
• Configuration Guide
Gosu introduction 51
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Gosu types
The Gosu language provides primitive data types and standard object types. The Gosu language also supports the
use of Java types.
See also
• “Type system” on page 403
Gosu includes transformations on Java types that make your Gosu code clearer, such as turning getters and setters
into Gosu properties.
Gosu types 53
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Packages always in scope” on page 116
• “Overview of enhancements” on page 23
• “Calling Java from Gosu” on page 139
The following table lists the Java primitives that you can access from Gosu. The table mentions IEEE 754, which is
the Institute of Electrical and Electronics Engineers standard for binary floating-point arithmetic.
See also
• [Link]
Gosu objects
The root type for all object types in Gosu is the Java class [Link]. An object encapsulates some data as
variables and provides properties and methods, which are functions that act on the object. Because
[Link] is always in scope, your code uses Object unless a similarly named type is in scope and
requires disambiguation.
You can create classes that extend the root object type Object. If you do not declare a new class to extend a specific
class, your new class extends the Object class.
Do not use the root object type Object to create objects directly. In some cases, you need to declare a variable that
uses the type Object to support a variety of object subclasses. For example, you can define a collection to contain a
heterogeneous mix of object types, all of which extend the root object type Object.
Example
var a : Address
var map = new [Link]()
See also
• “Bundles and database transactions” on page 387
• Configuration Guide
Example
For example:
See also
• “Bundles and database transactions” on page 387
• “Using the operator new in object expressions” on page 86
• Configuration Guide
Gosu types 55
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Syntax
<object-property-path> = <expression>
Example
[Link] = "John"
Gosu first evaluates a.B, and then on the result object sets the Name property to the value "John".
If the AClass.B property supports instantiation of intermediate objects, the same code works even if a.B is null at
run time.
At run time, if Gosu detects that a.B is null:
1. Gosu instantiates a new instance of BClass.
2. Gosu sets a.B to the new instance.
3. Gosu sets [Link] property on the new instance of BClass.
For all Guidewire entity types, properties that contain a foreign key reference support automatic instantiation of
intermediate objects.
You can add instantiation of intermediate objects to any Gosu class property. On the line before the property
declaration, add the annotation:
@Autocreate
See also
• “Handling null values in expressions” on page 96
• “Annotating a class, method, type, class variable, or argument” on page 209
Syntax
object.PROPERTY_NAME
Examples
Expression Result
[Link] Pam Trujillo
See also
• “Handling null values in expressions” on page 96
Syntax
object.METHOD_NAME()
Example
Expression Result
[Link]() Returns a Boolean value indicating the status of Claim
See also
• “Handling null values in expressions” on page 96
• “Static method calls” on page 95
Gosu types 57
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
0 int false
"false" or any String false See note for column value "true".
non‐null
String value
other than
"true"
null See note If coerced to the boolean type, the re‐ The boolean type is a primitive and can never contain
sult depends on the type of the de‐ null. The Boolean type is an object type, and variables
clared variable. For some types, includ‐ of that type can contain null.
ing Object and number types such as Be careful to check for null values for variables de‐
Integer, null coerces to the value clared as String. A null value might indicate uninitial‐
false. For other types, coercion is dis‐ ized data or other unexpected code paths.
allowed at compile time.
If coerced to the Boolean type, value
remains null.
Example
Example values for the String data type are "hello", "123456", and "" (the empty string). If you need to type a
quotation mark character in a String literal, escape the quotation mark character by putting a backslash before it,
such as "hello \"Bob\"".
Alternatively, you can use single quotation marks instead of double quotation marks. This style is useful if you want
to type String literals that contain the quotation mark character because you do not need to escape quotation mark
characters:
If you use single quotes and the literal has exactly one character, Gosu infers the type to be char instead of String.
If the variable holds an empty String or null, the HasContent method returns false. Using the HasContent
method is more intuitive than using the Empty property in typical cases where null represents absence of data.
Gosu types 59
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Note that the entity property has no initial or trailing spaces in the first case, and is set to null in the other cases.
If you want to test a String variable to see if it has content or is either null or empty, use the HasContent method.
<column
desc="Primary email address associated with the contact."
name="EmailAddress1"
type="varchar">
<columnParam name="size" value="60"/>
<columnParam name="trimwhitespace" value="false"/>
</column>
The parameter controls only whether PolicyCenter trims leading and trailing spaces. You cannot configure whether
PolicyCenter coerces an empty string to null.
For both trimming and converting empty String values to null, the change happens immediately that you set the
value.
See also
• “String variables can have content, be empty, or be null” on page 59
• “Setting values of String properties in entity instances” on page 59
cat
Type "new String()" into the Gosu Scratchpad and then press period (.) to see the full list of methods.
String utilities
You can access additional String methods in the API class [Link]. Type
[Link] into the Gosu Scratchpad and press period to see the full list of methods.
For example, to perform search and replace, instead of the Java native method replace on [Link], you
can use the StringUtil method substituteGlobalCaseInsensitive.
See also
• “Templates” on page 301
Sequence Result
\\ Inserts a backslash into the string without forcing an escape sequence.
\" Inserts a double‐quotation mark into the string without terminating it.
Note: This escape sequence is not used in embedded code inside Gosu templates. In such cases, do not escape
the quotation mark characters.
\n Inserts a new line into the string so that the remainder of the text begins on a new line if printed.
\t Inserts a tab into the string to add horizontal space in the line if printed.
Examples
Claim["ClaimNumber"]
var address = "123 Main Street"
"LOGGING: \n\"Global Activity Assignment Rules\""
Gosu types 61
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Templates” on page 301
${ EXPRESSION }
If the expression does not return a value of type String, Gosu attempts to coerce the result to the type String.
For example, suppose you need to display text with a calculation in the middle of the text:
var mycalc = 1 + 1
var str = "One plus one equals " + mycalc + "."
print(str)
Instead of this multiple-line code, embed the calculation directly in the String as a template:
Gosu runs the statements in the scriptlet before evaluating the text in the string.
The following code shows the use of scriptlets in a String value:
var str = "<% for (i in 1..5) { var odd = (i % 2 == 1) %>${i} is ${ (odd?"odd":"even") }\n<% } %>"
print(str)
1 is odd
2 is even
3 is odd
4 is even
5 is odd
The following line is invalid because of incorrect escaping of the internal quotation marks:
See also
• “Templates” on page 301
Entity types
An entity is a type of object that is constructed from the data model configuration files. Like other types of objects,
entities have data in the form of object properties, and actions in the form of object domain methods.
Some Guidewire API methods take an argument of type IEntityType. The IEntityType type is an interface, not a
class. All Guidewire entity types implement this interface. To use an API that requires an IEntityType, pass an
entity instance to the API. For example, to pass an Address to an API that takes an IEntityType as the method
argument, use code such as:
[Link](Address)
In rare cases, you might need to get the type from an entity dynamically, for example to get the subtype of an entity
instance. If you have a reference to an entity instance, get its Type property. For example, if you have a variable ad
that contains an Address entity instance, use code such as the following:
[Link]([Link])
WARNING The base configuration includes visible usages of the entity instance method
setFieldValue. The setFieldValue method is reserved for Guidewire internal use. Calling this
method can cause serious data corruption or errors in application logic that may not be
immediately apparent. You must obtain explicit prior approval from Guidewire Support to call
setFieldValue as part of a specific approved workaround.
See also
• Configuration Guide
Example
Do not confuse a key (the type called Key) and a typekey (the type called Typekey).
See also
• “Typekeys and typelists” on page 64
Gosu types 63
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Typelist Literals
In most cases, to get a literal for a typelist, you can type the typelist name in the appropriate programming context.
Ambiguity about the name or package of the typelist might occur in some programming contexts. To resolve this
ambiguity, type the fully qualified syntax [Link]. For example, [Link].
Typecode Literals
To reference an existing typecode from Gosu, access the typecode by using the typelist name and the typecode value
in capital letters and the prefix TC_:
TYPELISTNAME.TC_TYPECODENAME
For example, to select from the AddressType typelist a reference to the typekey with code BUSINESS, use:
AddressType.TC_BUSINESS
In the data model configuration, the typecode definition has an optional identifierCode attribute, which changes
how the application generates the programmatic typekey name in Gosu. The value of the identifierCode attribute
can include only characters that are valid for a Gosu identifier such as a class or variable name. For example, you
cannot include a hyphen (-) character in the value of the identifierCode attribute. The maximum length of the
identifier code value is three characters fewer than the maximum length of a Gosu identifier name. For practical
purposes, this length is unlimited.
PolicyCenter uses the following rules to generate the typecode literal:
• If the optional identifierCode attribute exists, PolicyCenter transforms the identifierCode attribute to upper
case, and adds the prefix TC_. Using the identifierCode attribute ensures that all identifier names are unique,
which prevents name conflicts among typecode literals.
• If the identifierCode attribute does not exist for a typecode, PolicyCenter generates the typecode literal from
the code attribute. PolicyCenter transforms the code attribute to upper case, replaces invalid characters with
underscores (_), and adds the prefix TC_. For example, codes abc, 123, and a-b become the identifiers TC_ABC,
TC_123, and TC_A_B, respectively. The substitution of invalid characters by underscores might cause two codes to
become the same identifier. For example, codes A_B and A-B both become TC_A_B, which is a conflict that causes
compilation errors.
[Link](includeRetiredTypekeys)
The Boolean argument indicates whether to include obsolete typekeys that are marked as retired. If the argument is
set to true, the return value includes retired typekeys. Otherwise, the method returns only unretired typekeys.
For example:
64 chapter 2: Gosu types
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
If your application is multi-lingual and manipulates typekeys, choose very carefully whether you want to get the
DisplayName property, the UnlocalizedName property, or the Code property. In almost all cases, use the Code if you
might store or compare values later on or use the DisplayName if you are displaying something to the user. The
UnlocalizedName property exists for debugging reasons and compatibility reasons and in general do not use it.
Instead, use Code or DisplayName.
To extract display name information, you can use [Link]
For example:
print(AddressType.TC_BUSINESS.DisplayName)
Business
Gosu types 65
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Alternatively, you can set the size of an array implicitly by providing a list of values or objects with which to
initialize the array. The size of the array is the number of items in the list. The following statement implicitly sets the
size of a String array to four elements.
Examples
The following code accesses the first exposure on a claim.
[Link][0]
The following code creates an array of five elements and then accesses the third element, the character “c”.
one
two
three
four
See also
• “Iteration in for statements” on page 107
3
3
5
4
Suppose you have an array of Book objects, each of which has a String property Name. You could use array
expansion to extract the Name property from each item in the array. Array expansion creates a new array containing
just the Name properties of all books in the array.
If a variable named myArrayOfBooks holds your array, use the following code to extract the Name properties:
The nameArray variable contains an array whose length is exactly the same as the length of myArrayofBooks. The
first item is the value myArrayofBooks[0].Name, the second item is the value of myArrayofBooks[1].Name, and so
on.
Suppose you wanted to get a list of the groups to which a user belongs so that you can display the display name
property of each group. Suppose a User object contains a MemberGroups property that returns a read-only array of
Gosu types 67
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
groups to which the user belongs. In this case, the Gosu syntax [Link] returns an array of Group
objects, each one of which has a DisplayName property. To get the display name property from each group, use the
following Gosu code
[Link]*.DisplayName
Because MemberGroups is an array, Gosu expands the array by the DisplayName property on the Group component
type. The result is an array of the names of all the Groups to which the user belongs. The type is String[].
The result might look like the following:
The expansion operator also applies to methods. Gosu uses the type on which the method runs to determine how to
expand the type:
• If the original object is an array, Gosu creates an expanded array.
• If the original object is a list, Gosu creates an expanded list.
The following example calls a method on the String component of the List of String objects. Gosu generates a
list of initials by extracting the first character in each String.
See also
• “Enhancements on Gosu collections and related types” on page 189
//Iterate through the Java list the same way as a Gosu array.
for (element in list) {
print(element)
}
zero
one
two
threeUPDATED
four
See also
• “for statements” on page 107
• “Collections” on page 183
contact["PostalCode"]
Use associative array syntax if a property name is unknown at compile but can be determined at run time with input
from users. If the property name does not exist at run time, Gosu throws an exception.
WARNING Gosu cannot check associative array syntax at compile time to be certain that a
property name is accurate or that the property exists. Be careful whenever you use associate array
syntax to catch unexpected run time errors. Use property path expressions, which provide type-
safe property access, instead of associative array syntax whenever possible.
Associative arrays on objects in Gosu are similar to instances of the Java map class [Link]. Associative
array syntax for property access works with most classes, including the Map class and types that do not take array-
style index numbers.
You cannot use associative array syntax with String objects in Gosu. A String object behaves like an ordered list
of characters and requires array index notation to access its individual character elements.
Examples
The following code demonstrates single associative array syntax to get the StreetAddress property on a Person
object. At run time, the code is equivalent to the property path expression [Link]. The code might
evaluate to 123 Main Street.
person["StreetAddress"]
The following code demonstrates double associative array syntax to get the City property on the Address object
that is a property of a Person object. At run time, the code is equivalent to the property path expression
[Link]. The code might evaluate to Birmingham.
person["Address"]["City"]
Gosu types 69
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The following code uses single associative array syntax to set the City property on an Address object.
newAddress["City"] = "Birmingham"
See also
• “Null-safe property access” on page 96
• “Collections” on page 183
Entity arrays
In the data model definition of an entity type, you can define a property that is an array of read-only entity instances
of another specific type.
By default, array fields on entities are unordered indexed arrays in Gosu. An indexed entity array acts like a typical
array in that you can get an object by using a numeric index offset from the beginning. For example, myArray[2].
Because the items are unordered, do not rely on the meaning or long term position of a specific element. However,
use numeric ordering to loop across the array with looping syntax, such as a for loop.
Gosu defines other enhancement methods and properties on arrays, such as each, firstWhere, HasElements, and
map. Use enhancement methods and properties to write concise powerful Gosu code. However, be aware that
bringing many entities into memory can be resource intensive if the entity array size is large.
For example, in PolicyCenter, on a User entity type definition file in [Link], the property Roles is an array of
role objects that relate to a user:
Gosu adds an addTo… method and a removeFrom… method to the containing entity type to help manage the elements
of each associative array defined on the entity. In the preceding example, Gosu adds the methods addToRoles and
removeFromRoles to the entity type User.
Optionally, entity arrays support an associative syntax like a map.
IMPORTANT Entity arrays are inherently unordered with a non-deterministic order each time they are
generated. For example, the order in which an addTo… method adds elements to its entity array is not
necessarily the order in which a for loop retrieves them.
See also
• “Enhancements on Gosu collections and related types” on page 189
• Configuration Guide
Casting arrays
The as keyword can be used to cast an array type to another compatible array type. For example, String is a
subtype of Object, so an array of type String can be cast to an array of type Object.
The compiler can detect and produce a compilation error when two referenced types are incompatible. For example,
an Integer[] can never be converted to a String[], so the following code statements produce a compilation error.
In some cases, you know that all the objects in an array are of a particular subtype of the defined type of the array. In
other cases, you filter an array to retrieve only objects of a particular subtype. As shown in a preceding code
example, you cannot use the as keyword to convert an array to an array of a subtype. Instead, you can use the Gosu
enhancement method cast to make an array of the subtype. You can then perform operations on the new array that
are specific to the subtype and not available to the parent type. The following code demonstrates how to use the
cast method.
You cannot use the cast method to convert incompatible types. The compiler does not detect this type of error. The
following code produces a run-time error.
Gosu types 71
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
• Gosu infers that the following variables have type Float because the right side of the assignment uses a numeric
literal with an f after the number.
var aFloat = 4f
var anotherFloat = 4.0f
You can omit the suffix of a numeric literal if the type is declared explicitly such that no type inference is necessary.
Gosu does not support floating point hexadecimal literals.
The following table lists the suffix or prefix for different numeric, binary, and hexadecimal literals.
Examples
print (result1)
print (typeof result1)
print (result2)
print (typeof result2)
27.599999999999998
double
2057.0
double
Array
The Array type exists for compatibility with earlier Gosu releases. For new code, instead use standard array syntax
with bracket notation with a specific type, such as Integer[].
See also
• “Gosu array types” on page 65
Gosu types 73
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Gosu provides many operators that are similar to operators in the Java language. Gosu also provides additional
operators. You use the operators, constants, and variables to create expressions.
Gosu operators
Gosu uses standard programming operators to perform a wide variety of mathematical, logical, and object
manipulation operations. If you are familiar with the C, C++ or Java programming languages, you might find that
Gosu operators function similar to those other languages. Gosu evaluates operators within an expression or
statement in order of precedence.
Gosu operators take either a single operand (unary operators), two operands (binary operators), or three operands (a
ternary operator). The following list provides examples of each operator type:
See also
• “Operator precedence” on page 75
Operator precedence
The following list orders the Gosu operators from highest to lowest precedence. Gosu evaluates operators with the
same precedence from left to right. The use of parentheses can modify the evaluation order as determined by
operator precedence. Gosu first evaluates an expression within parentheses, then uses that value in evaluating the
remainder of the expression.
Operator Description
. Property access, array indexing, function calls and expression grouping. The operators with the ques‐
[ ] tion marks are the null‐safe operators.
( )
?.
?[]
?:
+ Addition, subtraction, string concatenation. The versions with the question marks are the null‐safe
- versions.
?+
?-
< Less than, less than or equal, greater than, greater than or equal
<=
>
>=
Operator Description
= += -= *= /= %= &= Assignment operator statements. These operators apply to Gosu statements, not expressions.
&&= ^= |= ||= <<=
>>= >>>=
See also
• “Handling null values in expressions” on page 96
• “Null-safe math operators” on page 99
• “Equality expressions” on page 81
• “Gosu variables” on page 102
See also
• “Checked arithmetic for add, subtract, and multiply” on page 80
Expression Result
3 + 5 8
8 + 7.583 15.583
Expression Result
"Auto" + "Policy" "AutoPolicy"
10 + "5" "105"
IMPORTANT By default, the addition operator does not check for overflow errors. Optionally, you can
enable checked arithmetic, which generates Gosu exceptions for overflow errors.
Expression Result
9 - 2 7
8 - 3.359 4.641
IMPORTANT By default, the subtraction operator does not check for overflow errors. Optionally, you
can enable checked arithmetic, which generates Gosu exceptions for overflow errors.
Expression Result
2 * 6 12
12 * 3.26 39.12
"9" * "3" 27
IMPORTANT By default, the multiplication operator does not check for overflow errors. Optionally,
you can enable checked arithmetic, which generates Gosu exceptions for overflow errors.
Expression Result
10 / 2 5
1 / 0 Infinity
0 / 0 NaN
0/1 0
Expression Result
10 % 3 1
2 % 0.75 0.5
For example, 10 >> 1 evaluates to 5. The decimal number 10 is 1010 binary. In binary, this code does a binary
bitwise right shift of 1010 one bit to the right. The result is binary 0101, which is decimal 5.
The expression -10 >> 2 evaluates to -3. The decimal number -10 is 11111111 11111111 11111111 11110110 binary.
This expression does a binary bitwise right shift two bits to the right, filling in the top two bits with a 1 because the
original number was negative. The result is binary 11111111 11111111 11111111 11111101, which is decimal -3.
See also
• “Null-safe math operators” on page 99
• “Checked arithmetic for add, subtract, and multiply” on page 80
In contrast, the following example uses the unchecked arithmetic operator !*, which is only for special
circumstances in which overflow is desirable:
Because the arithmetic in the second example is unchecked, the result that prints 2 successfully is possibly
unexpected and invalid.
See also
• Configuration Guide
Equality expressions
Equality expressions return a Boolean value (true or false) indicating the result of the comparison between the
two expressions. Equality expressions consist of the following types:
• Relational equality operator (==)
• Object equality operator (===)
• Inequality operator (!=)
• Object inequality operator (!==)
IMPORTANT To determine whether two objects are the same in-memory object, instead use the ===
or !== operators.
In the Java language, the == operator evaluates to true if and only if both operands have exactly the same
reference value, which refers to the same object in memory. This behavior works well for primitive types like
integers. For reference types, you usually do not want to compare the object in memory. Instead, to compare value
equality, Java code typically uses [Link](), not the == operator. The [Link]() method includes
the comparison of object reference values, but also compares property values.
If you use the == operator for comparison of reference types, Gosu calls [Link](). In most cases, this
behavior is what you want for reference types.
Syntax
a == b
Examples
Expression Result
7 == 7 true
"3" == 3 true
3 == 5 false
print("3" == "4") false The two String objects contain different values.
print("3" === "4") false Gosu represents the two String literals as separate objects in memory (as well as
separate values).
var x = 1 + 2 true These two variables reference the same value but different objects, so the double‐
var s = x as String equals operator returns true.
print(s == "3")
var x = 1 + 2 false These two variables reference the same value but different objects, so the triple‐
var s = x as String equals operator returns false.
print(s === "3")
print("3" === "3") true This example is harder to understand. By just looking at the code, it seems like these
two String objects would be different objects. However, the Gosu compiler detects
that the objects are the same String. Gosu optimizes the code to point to the same
String object in memory for both usages of the String literal "3".
print("3" === new false The two String objects both contain the value "3", but are not the same object.
String("3"))
IMPORTANT To compare whether two objects are the same in-memory object, instead use the ===
or !== operators.
Syntax
a != b
Examples
Expression Result
7 != 7 false
"3" != 3 false
3 != 5 true
The operands can be of any compatible types. The result type is always Boolean.
Syntax
a !== b
var x = 1 + 2 true These two variables reference the same value but different objects. If you use the
var s = x as String === operator, it returns false.
print(s !== "3")
print("3" != "3") false The two String objects contain the same value. Compare to the examples in the
following rows.
print("3" != new false The two String objects contain the same value.
String("3"))
print("3" !== "3") false This example is harder to understand. By just looking at the code, it seems like these
two String objects would be different objects. However, in this case, the Gosu com‐
piler detects they are the same String at compile time. Gosu optimizes the code for
both usages of a String literal to point to the same object in memory for both usag‐
es of the "3".
print("3" !== new true The two String objects both contain the value "3", but are not the same object.
String("3"))
Evaluation expressions
The eval() expression evaluates Gosu source at run time, which enables dynamic execution of Gosu source code.
Gosu executes the source code within the same scope as the call to eval().
Syntax
eval(Expression)
Examples
Expression Result
eval( "2 + 2" ) 4
Logical expressions
Gosu logical expressions use standard logical operators to evaluate the expression in terms of the boolean values of
true and false.
Operators and expressions 83
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Logical AND
Gosu uses either and or && to indicate a logical AND expression. The operands must be of the Boolean data type or
any type convertible to Boolean. The result is always Boolean.
Syntax
a and b
a && b
Examples
Expression Result
(4 > 3) and (3 > 2) (true/true) = true
Logical OR
Gosu uses either or or || to indicate a logical OR expression. The operands must be of the Boolean data type or any
type convertible to Boolean. The result is always Boolean.
Syntax
a or b
a || b
Examples
Expression Result
(4 > 3) or (3 > 2) (true/true) = true
Logical NOT
To indicate a logical negation (a logical NOT expression), use either the keyword not or the exclamation point
character (!). The operand must be of the Boolean data type or any type convertible to Boolean. The result is
always Boolean.
Syntax
not a
!a
Examples
Expression Result
!true false
!null true
This example causes an error at run time because Gosu associates the NOT operator with the variable to its right
before evaluating the expression. This association causes the expression to become:
(false == [Link])
• Better example – The following example demonstrates how to use the NOT operator correctly.
In this example, the extra parentheses force the desired comparison, and associate the NOT operator with the
correct expression.
• Preferred example – Use the != operator rather than NOT for writing code of this type.
if ([Link] != [Link]) {
return true
}
The expression had no need to use the NOT operator. The final code expression is somewhat simpler and does
exactly what is required.
typeis expressions
Gosu uses the operator typeis to test the type of an object against a named type. The result is true if the object has
that type or a subtype.
Operators and expressions 85
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Using Boolean values in Gosu” on page 58
• “Test type with typeis” on page 404
new javaType (argument_list) // The optional argument list contains constructor arguments.
new gosuType (argument_list) // The optional argument list contains constructor arguments.
new arrayType [size]
new arrayType [] {array_Value_List} // This syntax allows declaring a list of initial array members.
If you pass arguments to the new operator, Gosu passes those arguments to the constructor. There might be multiple
constructors defined, in which case Gosu uses the types and numbers of objects passed as arguments to determine
which constructor to call.
Examples
Expression Result
new [Link](8) Creates an instance of the HashMap Java class.
new String[12] Creates a String array that has12 members with no initial values.
new String[] {"a", "b", "c"} Creates a String array that has three members, initialized to "a", "b", and "c".
See also
• “Using the operator new as a statement” on page 102
Code that uses the new operator to instantiate an entity type must include all required properties when constructing
an instance of that entity as arguments to the constructor. If the constructor has other constructor arguments, the
required properties appear after those other arguments.
For example, suppose an entity called MyEntity has one required parameter that is has type Address. The
expression new MyEntity() is a compilation error because the required property is missing from the argument list.
To fix the error, get a reference to a non-null Address entity instance and pass it to the constructor, such as:
WARNING Be extremely careful if you use bundle and transaction APIs to override the default
behavior for bundle management.
See also
• “Bundles and database transactions” on page 387
WARNING Omitting the type name with the new keyword is strongly discouraged in typical code.
Omit the type name only for XML manipulation and dense hierarchical structures with long type
names. Some types imported from XSDs have complex and hard-to-read type names. The
following simple examples demonstrate the concepts, but do not promote usage of this syntax in
simple cases.
For example, first declare a variable with an explicit type. Next, assign that variable a new object of that type in a
simple assignment statement that omits the type name:
You can also omit the type name if the context is a method argument type:
class SimpleObj {
}
class Test {
function doAction (arg1 : SimpleObj) {
}
}
The following example uses both local variables and class variables:
class Person {
private var _name : String as Name
private var _age : int as Age
}
class Tutoring {
private var _teacher : Person as Teacher
private var _student : Person as Student
}
// Declare a variable as a specific type to omit the type name in the "new" expression
// during assignment to that variable.
var p : Person
var t : Tutoring
p = new() // type name omitted
t = new() // type name omitted
// If a class var or other data property has a declared type, optionally omit the type name.
[Link] = new()
[Link] = new()
See also
• “Object initializer syntax” on page 88
Object initializers comprise one or more property initializer expressions, separated by commas, and enclosed by
braces. A property initializer expression is the following, in order: a colon (:), a property name, an equal sign (=),
and a value or any expression that results in a value.
:propertyName = value
For example, suppose you have the following code, which sets properties on a new file container by using
assignment statements that follow the new statement:
The following sample code is functionally equivalent to the preceding code but uses an object initializer to make the
assignments within the bounds of in the new statement:
[Link](test) // Add the new test to the array of the test set.
[Link](new Test()) // Create another test and add it to the array.
[Link](1).final = true // Set the final property on the second test in the array.
[Link](1).type = new TestType() // Create a test type and assign the type property
// on the second test in the array to that type.
You can rewrite the preceding code by using nested new object expressions with their own object initializers to
reflect visually the nested object structure that the code creates.
:style =
new TestStyle() { // Create and initalize a test style and set the
:color = Red, // style of the test set to that style.
:number = 5
}
}
Nested object initializers are especially useful when constructing in-memory XML data structures.
See also
• “Basic lists” on page 183
• “Basic hash maps” on page 185
Relational expressions
Gosu relational operators support all types of objects that implements the [Link] interface, not just
numbers. Relational expressions return a Boolean value (true or false) indicating the result of a comparison
between two expressions. Relational expressions use the following operators:
• > operator
• >= operator
• < operator
• <= operator
Gosu supports the use of multiple relatational operators to compare multiple values. Add parentheses around each
comparison expression. For example, the following expression ultimately evaluates to true:
The first compound expression evaluates to false ((1 <= 2) <= (3 > 4)) as does the second expression (5 > 6).
However, the larger expression tests for greater than or equal. Therefore, because false is equal to false, the entire
expression evaluates to true.
> operator
The > operator tests two expressions and returns true if the left value is greater than the right value. The operands
can be numeric, String, or [Link] data types. The result is Boolean.
Syntax
Examples
Expression Result
8 > 8 false
>= operator
The >= operator tests two expressions and returns true if the left value is greater than or equal to the right value.
The operands can be numeric, String, or [Link] data types. The result is Boolean.
Syntax
Examples
Expression Result
8 >= 8 true
< operator
The < operator tests two expressions and returns true if the left value is less than the right value. The operands can
be numeric, String, or [Link] data types. The result is Boolean.
Syntax
Examples
Expression Result
8 < 5 false
<= operator
The <= operator tests two expressions and returns true if the left value is less than or equal to the right value. The
operands can be numeric, String, or [Link] data types. The result is Boolean.
Syntax
Examples
Expression Result
8 <= 5 false
Expression Result
5 <= "6" true
Unary expressions
Gosu supports the following unary (single operand) expressions:
• Numeric negation
• Bit-wise NOT
• Typeof expressions
The following sections describe these expressions. The value of a typeof expression cannot be fully determined at
compile time. For example, an expression at compile time might resolve as a supertype. At run time, the expression
may evaluate to a more specific subtype.
Numeric negation
Gosu uses the unary - operator before a number to indicate numeric negation. The operand must be a number data
type. The result is always the same type as the original number.
Syntax
-value
Examples
Expression Result
-42 -42
-(3.14 - 2) -1.14
Bit‐wise NOT
The bit-wise NOT operator treats a numeric value as a series of binary digits (bits) and inverts them. This behavior is
different from the logical NOT operator (!), which treats the entire numeral as a single Boolean value. In the
following example, the logical NOT operator assigns a Boolean value of true to x if y is false, or false if y is true:
x = !y
In the following example, the bit-wise NOT operator (~) treats a numerical value as a set of bits and inverts each bit,
including the sign operator.
z = ~7
The decimal number 7 is the binary value 0111 with a positive sign bit. By using the bit-wise NOT, the expression ~7
evaluates to the decimal value -8. The binary value 0111 reverses to 1000, the binary value for 8, and the sign bit
changes as well to produce -8.
Use the bit-wise NOT operation to manipulate a bit mask. A bit mask is a number or byte field that maintains the state
of many items by flags mapping to each bit in the field.
Typeof expressions
Gosu uses the operator typeof to determine meta information about the type to which an expression evaluates. The
operand can be any valid data type. The result is the type of the expression.
92 chapter 3: Operators and expressions
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Basic type checking” on page 403
Syntax
The second and third operands that follow the question mark (?) must be of compatible types.
At run time, Gosu evaluates the first operand, the conditional expression. If the conditional expression evaluates to
true, Gosu evaluates the second operand, the expression that follows the question mark. It ignores the third
operand, the expression that follows the colon. Conversely, if the conditional expression evaluates to false, Gosu
ignores the second operand, the true expression, and the evaluates the third operand, the false expression.
For example, consider the following ternary expression:
At run time, if the value of myNumberVar is greater than 10, Gosu prints “Bigger than 10”. Conversely, if the value
of myNumberVar is 10 or less, Gosu prints “10 or less”.
Examples
In the example, the true expression is of type String and the false expression is of type Boolean. If at run time the
contact is new, ternaryResult is of type String, and its value is hello. If the contact is not new, ternaryResult
is of type Boolean, and its value is false. Although the true expression and the false expression are of different
types, their types are compatible because String and Boolean descend from Object.
At compile time, if the true and false expressions are of different types, Gosu reconciles the type of the ternary
expression to the type of their nearest common ancestor. Gosu requires that the types of the true and false
expressions in a ternary expression be compatible so that Gosu can reconcile their types. If the expressions have no
common ancestor, the type at compile time of the ternary expression is Object.
For example, reconsider the earlier example.
At compile time, Gosu sets the type of ternaryResult to Object. Because Gosu implicitly declares its type as
Object, the ternaryResult variable can hold instances of type String and of type Boolean. The following
example makes the type as set by the compiler explicit.
// The type of a ternary expression is the common acestor type of its true and false expressions.
var ternaryResult : Object = [Link] == "new" ? "hello" : false
At run time, the type evaluation of the ternary expression and the ternaryResult variable depends on the current
state of the system. Different type checking keywords produce different results. For example, if the contact in the
following example is new, ternaryResult is of type String.
true
true
false
String
If the contact in the following example is not new, ternaryResult is of type Boolean.
true
false
true
Boolean
See also
• “Logical expressions” on page 83
• “Null-safe default operator” on page 98
94 chapter 3: Operators and expressions
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Function calls
This expression calls a function with an optional list of arguments and returns the result.
Syntax
functionName(argumentList)
Examples
Expression Result
now() Current Date
Syntax
[Link](argumentList)
Examples
Expression Result
[Link]() Current time
See also
• “Modifiers” on page 157
Syntax
[Link]
Examples
Expression Result
[Link] Claim typeInfo
Expression Result
[Link] Friday value
See also
• “Modifiers” on page 157
Syntax
[entity.]typeName
[typekey.]typeName
Examples
Expression Result
Claim Claim type
See also
• “Property assignment triggering instantiation of intermediate objects” on page 56
• “Null-safe method access” on page 98
in an object path short-circuits evaluation and results in a null value, with no exception being thrown. This feature
is called null-safe short circuiting for a property path expression.
For example, suppose that you have an expression similar to the following:
Remember that if any element in the path evaluates to null, the entire expression evaluates to null. If claim is
null, the result is null. Also, if [Link] is null, the result is null.
If the expression contains a method call, the rules are different. The period operator does not default to null if the left
side of the period is null. With the standard period operator, if the value on the left of the period is null, Gosu
throws a null pointer exception (NullPointerException). In other words, method calls are not null-safe because
the method could have side effects.
Note: Technically speaking, property access from a dynamic property get function could generate
side effects, but this is strongly discouraged. If a property accessor has any side effects, convert the
accessor into a method.
Example 1
Suppose that you have an expression similar to the following:
[Link]("abc")
In this case, if either claim or [Link] evaluate to null, Gosu throws a NullPointerException.
The method call follows the null value.
Example 2
Suppose that you have an expression similar to the following:
[Link]().[Link]
Example 3
For those cases in which Gosu expects a Boolean value (for example, in an if statement), a null value coerces to
false in Gosu. This is true regardless of whether the expression’s value was short-circuited. For example, the
following if statement prints “Benefits decision not made yet”, even if claim or [Link] is
null:
a.P1.P2.P3
By using null-safe paths, Gosu returns null if any of the following are null:
• a
• a.P1
• a.P1.P2
However, if the type of the P3 property is int or char or another primitive type, then the expression a.P1.P2.P3 is
not null safe.
Primitive types (in contrast to object types, which are descendents of Object) can never contain the value null.
Thus, Gosu cannot return null from that expression, and any casting from null to the primitive type would be
meaningless. Therefore, Gosu throws a null pointer exception in those conditions.
WARNING In Studio, Gosu code in the Gosu Scratchpad has different compiler behavior than any
other part of Studio. If you run code in Gosu Scratchpad directly in Studio without being
connected to a running server, the code compiles and runs locally in Studio with different
behavior. Most notably, the behavior of null safety in the period operator is different. In nearly all
other contexts in Studio, the period operator is null safe. However, in Gosu Scratchpad in Studio
without a connection to a running server, Gosu is not null-safe. Code that might not throw an
exception in a Gosu class might throw an exception in Gosu Scratchpad. If Studio is connected to
a running server, Studio sends the Gosu code to the server. The PolicyCenter server uses the
standard null-safe behavior for the period operator.
See also
• “Property assignment triggering instantiation of intermediate objects” on page 56
See also
• “Property assignment triggering instantiation of intermediate objects” on page 56
See also
• “How the standard period operator handles null” on page 96
For example, suppose there is a variable str of type String. At run time, the value contains either a String or
null. Perhaps you want to pass the input to a display routine. However, if the value of str is null, you want to use
a default value rather than null. Use the ?: operator as follows:
var result = str ?: "(empty)" // Return str, but if the value is null return a default string
You can chain the null-safe default operator to get the first non-null value in a set of items. If every value in the
chain is null, the result of the chain is null. For example, the following code gets the first day of the week that has
an assigned task or returns null if no day has a task:
var v = myArray?[2]
If the value to the left of the question mark is null, the entire expression for the operator returns null. If the left-
hand-operand is not null, Gosu evaluates the index subexpression and indexes the array, list, or map. Finally, Gosu
returns the result, just as for the typical use of the brackets for indexing lists, arrays, and maps.
Null-safe indexing does not protect against array-index out-of-bounds exceptions. If the array is non-null, but the
index is greater than or equal to the size of the array, Gosu throws an out-of-bounds exception at run time. Any value
of the index causes this exception if the array is empty rather than null. To test for an empty array, use the
HasElements property.
}
// Test whether the string is not empty
if (!nullStr?.isEmpty()) {
print("Got here!") // This message does appear, but the string has no contents.
// If you put code here to use the string value, you risk a null-pointer exception.
}
See also
• “How null values get in the database” on page 325
uses [Link]
Similarly, if a function in a class uses the this name to reference the current object, do not use the null-safe
operators, such as this?.methodName(). The this object never has a value of null.
names*.length
See also
• “List expansion (*.)” on page 187
Statements
This topic describes important concepts in writing more complex Gosu code to perform operations required by your
business logic.
Gosu statements
A Gosu expression has a value, but Gosu statements do not. The result of a Gosu expression can be passed as an
argument to a function. A Gosu statement does not have a result that can be passed as an argument to a function.
For example, the following lines are all Gosu expressions as each results in a value:
5 * 6
typeof 42
exists (var e in [Link] where e == null)
print(x * 3 + 5)
for (i in 10) { ... }
if (a == b) { ... }
Note: Do not confuse statement lists with expressions or Gosu blocks. Blocks are anonymous
functions that Gosu can pass as objects, even as function arguments.
See also
• “Blocks” on page 175
Statement lists
A statement list is a list containing zero or more Gosu statements enclosed by braces ({}).
The Gosu standard is always to omit semicolon characters at the ends of lines of Gosu code. Code is more readable
without optional semicolons. In the rare cases in which you type multiple statement lists on one line, such as within
block definitions, do use semicolons to separate statements.
Syntax
{ statement-list }
Statements 101
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
{
var x = 0
var y = myfunction( x )
print( y )
}
See also
• “General coding guidelines” on page 465
See also
• “Using the operator new in object expressions” on page 86
Gosu variables
To create and assign variables, consider the type of the variable as well as its value.
Syntax
Examples
var age = 42
var age2 : int
var age3 : int = "42"
var c : Claim
...
Variable assignment
Gosu uses the standard programming assignment operator = to assign the value on the right-side of the statement to
the item on the left-side of the statement.
Syntax
variable = expression
Examples
count = 0
time = now()
Gosu also supports compound assignment operators that perform an action and assign a value in one action. The
following lists each compound operator and its behavior. The examples assume the variables are previous declared
as int values.
Statements 103
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Statements 105
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The following Gosu is invalid because statements are not permissible in an expression, which Gosu requires in a
while statement:
It is important to understand that Gosu supports the increment and decrement operator only after a variable, not
before a variable. In other words, i++ is valid but ++i is invalid. The ++i form exists in other languages to support
expressions in which the result is an expression that you pass to another statement or expression. As mentioned
earlier, in Gosu these operators do not form an expression. Thus you cannot use increment or decrement in while
declarations, if declarations, and for declarations. Because the ++i style exists in other languages to support forms
that are unsupported in Gosu, Gosu does not support the ++i form of this operator.
IMPORTANT Gosu supports the ++ operator after a variable, such as i++. Using it before the variable,
such as ++i is unsupported and generates compiler errors.
See also
• “Variable assignment” on page 103
if ‐ else statements
The most commonly used statement block within the Gosu language is the if block. The if block uses a multi-part
construction. The else block is optional.
Syntax
if (<expression>) <statement>
[ else <statement> ]
Example
To improve the readability of your Gosu code, Gosu automatically downcasts after a typeis expression if the type is
a subtype of the original type. This is particularly useful for if statements and similar Gosu structures. Within the
106 chapter 4: Statements
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Gosu code bounded by the if statement, you do not need to do casting (as TYPE expressions) to that subtype.
Because Gosu confirms that the object has the more specific subtype, Gosu implicitly considers that variable’s type
to be the subtype, at least within that block of code.
See also
• “Basic type checking” on page 403
for statements
The for statement block uses a multi-part construction.
Syntax
The scope of the <identifier> is limited to the statement block itself. The keyword var before the local variable
identifier is optional.
The <expression> expression in the in clause must evaluate to one of the following:
• An array.
• An iterator – an object that implements the Java Iterable interface. Iteration starts with the initial member and
continues sequentially until terminating at the last member.
• A Java list or collection class, such as [Link]. Iteration starts with the initial member and
continues sequentially until terminating at the last member.
• A String object, which Gosu treats as a list of characters.
• A Gosu interval.
If the expression evaluates at run time to null, the body of the loop block is skipped entirely.
Gosu provides backwards compatibility for the use of an older Gosu style foreach statement. Better style is to use
the for statement instead.
See also
• “Intervals” on page 131
• “Array list access with array index notation” on page 68
Examples
for (1..10) {
print("hello!")
}
Example:
// This code prints the index of the highest score in an array of test scores.
// This particular example prints "3".
var testScores = new int[] {91, 75, 97, 100, 89, 99}
print(getIndexOfHighestScore(testScores))
return highIndex
}
Example:
red
green
blue
// Example 2: Print a message for the first exposure with 'other coverage'.
for (var exp in [Link]) {
if ([Link]) { // OtherCoverage is a Boolean property.
print("Found an exposure with other coverage.")
// Transfer control to statement following this for…in statement
break
}
}
while statements
Gosu evaluates the while() expression, which must evaluate to true or false, and uses the Boolean result to
determine the next course of action:
• If the expression is initially true, Gosu executes the statements in the statement block repeatedly until the
expression becomes false. At this point, Gosu exits the while statement and continues statement execution at
the next statement after the while statement.
• If the expression is initially false, Gosu never executes any of the statements in the statement block, and
continues statement execution at the next statement after the while statement.
Syntax
while (<expression>) {
<statements>
}
Example
do…while statements
The do...while block is similar to the while block in that it evaluates an expression and uses the Boolean result to
determine the next course of action. The principal difference is that Gosu tests the expression for validity after
executing the statement block, instead of prior to executing the statement block. The statements in the statement
block execute at least once when execution first accesses the block.
• If the expression is initially true, Gosu executes the statements in the statement block repeatedly until the
expression becomes false. At this point, Gosu exits the do...while block and continues statement execution at
the next statement after the do...while statement.
• If the expression is initially false, Gosu executes the statements in the statement block once, then evaluates the
condition. If nothing in the statement block has changed so that the expression still evaluates to false, Gosu
continues statement execution at the next statement after the do...while block. If action in the statement block
Statements 109
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
causes the expression to evaluate to true, Gosu executes the statement block repeatedly until the expression
becomes false, as in the previous case.
Syntax
do {
<statements>
} while (<expression>)
Example
do {
print(i)
i = i + 1
} while (i < 10)
switch statements
Gosu evaluates the switch expression, and uses the result to choose one course of action from a set of multiple
choices. Gosu evaluates the expression, and then iterates through the case expressions in order until it finds a match.
• If a case value equals the expression, Gosu executes its accompanying statement list. Statement execution
continues until Gosu encounters a break statement, or the switch statement ends. Gosu continues to the next case
and executes multiple case sections if you omit the break statement.
• If no case value equals the expression, Gosu skips to the default case, if one exists. The default case is a case
section with the label default: rather than case VALUE:. The default case must be the last case in the list of
sections.
The switch statement block uses a multi-part construction. The default statement is optional. In most cases, you
implement a default case to handle any unexpected conditions.
Syntax
switch (<expression>) {
case label1 :
[statementlist1]
[break]
[ ...
[ case labelN :
[statementlistN]
[break] ] ]
[ default :
[statementlistDefault]]
}
Example
switch (strDigitName) {
case "one":
strOrdinalName = "first"
break
case "two":
strOrdinalName = "second"
break
case "three":
strOrdinalName = "third"
break
case "five":
strOrdinalName = "fifth"
break
case "eight":
strOrdinalName = "eighth"
break
case "nine":
strOrdinalName = "ninth"
break
default:
strOrdinalName = strDigitName + "th"
}
To improve the readability of your Gosu code, Gosu automatically downcasts the object after a typeis expression if
the type is a subtype of the original type. This is particularly valuable for if statements and similar Gosu structures
such as switch. Within the Gosu code bounded by the if or switch statement, you do not need to do casting
(as TYPE expressions) to that subtype for that case. Because Gosu confirms that the object has the more specific
subtype, Gosu implicitly considers that variable’s type to be the subtype for that block of code. There are several
special cases that turn off the downcasting.
See also
• “Basic type checking” on page 403
Gosu functions
Functions encapsulate a series of Gosu statements to perform an action and optionally return a value. Generally
speaking, functions exist attached to a type. For example, declaring functions within a class. As in other object-
oriented languages, functions declared on a type are also called methods.
In the context of a Gosu program (a .gsp file), you can declare functions at the top level, without attaching them
explicitly to a class. You can then call this function from other places in that Gosu program.
Note: The built-in print function is special because it is always in scope, and is not attached to a
type. It is the only true global function in Gosu.
Gosu does not support functions defined within other functions. However, you can use the Gosu feature called
blocks to do something similar.
Unlike Java, Gosu does not support variable argument functions (so-called vararg functions), meaning that Gosu
does not support arguments with “...” arguments.
Gosu permits you to specify only type literals for a function’s return type. Gosu does not support other expressions
that might evaluate (indirectly) to a type.
Gosu requires that you provide the return type in the function definition, unless the return type is void (no return
value). If the return type void, omit the type and the colon before it. Also, any return statement must return a type
that matches the declared function return type. A missing return type or a mismatched return value generates a
compiler error.
Syntax
Examples
Statements 111
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
If the return type is not void, all possible code paths must return a value in a method that declares a return type.
In other words, if any code path contains a return statement, Gosu requires a return statement for all possible
paths through the function. The set of all paths includes all outcomes of conditional execution, such as if and
switch statements.
For example, the following method is invalid:
// Invalid...
class MyClass {
function myfunction(myParameter) : boolean {
if (myParameter == 1) {
return true
}
if (myParameter == 2) {
return false
}
}
}
Gosu generates a “Missing Return Statement” error for this function and you must fix this error. The Gosu compiler
sees two separate if expressions for a total of four total code paths. Even if you believe the function is always used
with myParameter set to value 1 or 2 but no other value, you must fix the error. To fix the error, rewrite the code so
that all code paths contain a return statement.
For example, you can fix the earlier example using an else clause:
class MyClass {
function myfunction(myParameter) : boolean {
if (myParameter == 1) {
return true
} else {
return false
}
}
}
See also
• “What are blocks?” on page 175
• “Modifiers” on page 157
someMethod(true, false)
If you pass series of one or more comma-separated arguments, it is difficult or impossible to tell what each value
represents. It can be difficult to visually confirm the argument order in code that was written long ago or written by
others.
112 chapter 4: Statements
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Alternatively, for each argument you can explicitly specify the argument name. Instead of just the argument value,
pass the following items in this order:
1. A colon character
2. The argument name
3. The equal sign
4. The value
For example:
someMethod(:redisplay=true, :sendUpdate=false)
class MyClass {
var _names : [Link]<String>
construct(strings : [Link]<String>) {
_strings = strings
}
In the printWithPrefix declaration, the prefix value has the default value " ---> ". To use the default values, call
the printWithPrefix method and omit the optional arguments.
The following example calls the printWithPrefix method using the default value:
The following example calls the printWithPrefix method providing an explicit value:
The Gosu named arguments feature requires that the method name is not already overloaded on the class.
Statements 113
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Because funcA() is defined as public, it can be called from any other Gosu expression. However, funcB() is
private, and therefore is not valid anywhere except within the library.
For example, a function in another library could call funcA(), but it could not call the private funcB(). Because
funcA() is defined in the same library as funcB(), however, funcA() can call funcB().
Do not make any function public without good reason. Therefore, mark a function as private if it is defined only for
use inside the library.
See also
• “Modifiers” on page 157
Syntax
After the uses statement, specify a package namespace or a specific type such as a fully qualified class name.
uses type
uses namespace
uses type#static member
uses type#all static members
Namespaces can be specified with an asterisk (*) character to indicate a hierarchy. For example:
uses [Link].*
Example 1
The following code uses a fully qualified type name.
Instead, you can use the following code that declares an explicit type with the uses operator.
// Use this simpler expression without specifying the full package name:
var myInputStream = new FileInputStream()
Example 2
The following code uses a fully qualified type name.
Instead, you can use the following code that declares a package hierarchy with the uses operator.
// This "uses" expression provides access to all the classes in the [Link] package hierarchy
uses [Link].*
// Use this simpler expression without specifying the full package name:
var myInputStream = new FileInputStream()
Example 3
The following code uses a qualified type name. Because classes in the [Link] package are always in scope, you
do not need to specify [Link].
Instead, you can use the following code that declares a single static field from the [Link] class.
// This "uses" expression provides access to the PI constant in the [Link] class
uses [Link]#PI
Example 4
The following code uses a qualified type name. Because classes in the [Link] package are always in scope, you
do not need to specify [Link].
// This "uses" expression provides access to all the static members in the [Link] class
uses [Link]#*
Statements 115
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
List
The Gosu type system performs special treatment for the type List. Gosu resolves List to [Link] in
general use but to [Link] if code creates an untyped list. For example, the following code creates an
ArrayList:
var x = {}
Note: Use static imports with caution. Excessive use of unqualified names of static members from
outside the scope of a class creates code that is confusing to read.
package example
class TestClass {
Note that the class contains a static field and a static method. Without using static imports, Gosu code in other
classes needs to qualify the field or method:
uses [Link]
print(2 + [Link])
[Link]()
If you import the static members from the type, you can omit the type name before using static members:
// Import all static members from a type (note the #* at the end)
uses [Link]#*
// You can now use a static field without specifying what type it is on
print(2 + OneHundred)
Statements 117
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Exception handling
Gosu supports the following standard exception handling constructions from other languages such as throw
statements, try/catch/finally blocks, and special Gosu statements such as the using keyword.
Syntax
try
<try statements>
[catch ( exception )
<catch statements>]
[finally
<finally statements>]
Example
try {
print( "Outer TRY running..." )
try {
print( "Nested TRY running..." )
throw "an error"
}
catch (e : Exception) {
print( "Nested CATCH caught "+e )
throw e + " rethrown"
}
finally { print( "Nested FINALLY running..." ) }
}
catch (e : Exception) { print( "Outer CATCH caught " + e ) }
finally { print( "Outer FINALLY running" ) }
Output
See also
• “Throwing exceptions” on page 121
• “Catching exceptions” on page 120
Catching exceptions
Gosu allows you to catch all general exceptions, or test for and catch specific types of exceptions.
The standard syntax for catch is the following, which catches all exceptions by specifying the class Exception:
catch (e : Exception)
To catch a single specific exception type, specify a subclass such as IOException instead of Exception. The
technique of catching a named exception is called checked exceptions. The recommended Gosu coding style is not to
use checked exceptions, although this technique is supported.
The following code is an example of checked exceptions:
try {
doSomething()
}
catch (e : IOException) {
// Handle the IOException
}
Add a finally block at the end to perform cleanup code that runs for both error and success code paths:
try {
doSomething()
}
catch (e : IOException) {
}
finally {
// PERFORM CLEANUP HERE
}
Throwable
The class Throwable is the superclass of all errors and exceptions in the Java language. Best practice is to catch
Exception, not Throwable. Use catch(e : Exception) not catch(e : Throwable). Catching Throwable can
catch serious infrastructure problems like OutOfMemoryException or AssertionFailedException. Typical code
120 chapter 5: Exception handling
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
cannot handle those types of exceptions, so catch Exception so that these serious infrastructure exceptions
propagate upward.
Throwing exceptions
The throw statement generates an error condition that you can handle through the use of try/catch/finally
blocks.
WARNING Do not use throw statements as part of regular non-error program flow. Use these
statements only for handling actual error conditions.
if ( [Link] < 21 ) {
throw new RuntimeException("User is not allowed in the bar")
}
You can also pass a non-exception object to the throw statement. If you pass a non-exception object, Gosu first
coerces it to a String. Next, Gosu wraps the String in a new RuntimeException, which has a Message property
that contains the String data. Your error-handling code can use the Message property for logging or displaying
messages to users.
You could rewrite the previous throw code example as the concise code:
if ( [Link] < 21 ) {
throw "User is not allowed in the bar"
}
Syntax
throw <expression>
In the following example, notice how the error message changes if the value of x changes from 0 to 1.
Example
uses [Link]
function doOuterCode() {
try {
doInnerCode(0)
doInnerCode(1)
}
catch (e : Exception) {
print( [Link] + " -- caught in OUTER code" )
}
}
OutputStream os = SetupMyOutputStream() // Insert your code that creates your output stream
try {
// Do something with the output stream
}
finally {
[Link]();
}
You can simplify that code by using the Gosu using statement:
using ( ASSIGNMENT_OR_LIST_OF_STATEMENTS ) {
// Do something here
}
The parentheses after the using keyword can contain either a Gosu expression or a list of one or more Gosu
statements delimited by commas, not semicolons.
Several categories of objects work with the using keyword: disposable objects, closeable objects, and reentrant
objects. If you try to use an object that does not satisfy the requirements of one of these categories, Gosu displays a
compiler error.
If Gosu detects that an object is in more than one category, at run time, Gosu considers the object to be in only one
category. Gosu selects the category by the following precedence: disposable, closeable, reentrant. For example, if an
object has a dispose and close method, Gosu only calls the dispose method.
Use the return statement to return values from using clauses.
If Gosu successfully evaluates and initializes all variables, each variable is examined in order. For each object, if the
object has an enter action, that action is taken:
• If the object implements the Lock interface, Gosu calls [Link]()
• If the object implements the IReentrant interface, Gosu calls [Link]()
• If the object has a a method named lock and it takes no parameters, Gosu calls the lock method.
• If the object was cast to the IMonitorLock interface, Gosu synchronizes on the variable
If the enter action completes without an exception, Gosu guarantees that the corresponding exit action for that object
will run. If no enter action applies to the object, Gosu guarantees that the exit action for the object will run. Exit
actions are called in the reverse order of declaration in the using clause. Exit actions are as follows:
• If the object implements the IDisposable interface, Gosu calls [Link]()
• If the object has a method named dispose and it takes no parameters, Gosu calls the method.
• If the object implements the Closeable interface, Gosu calls [Link]()
• If the object has a method named close and it takes no parameters, Gosu calls the method.
• If the object implements the IReentrant interface, Gosu calls [Link]()
• If the object implements the Lock interface, Gosu calls [Link]()
• If the object has a method named unlock that takes no parameters, Gosu calls the unlock method.
• If the object was cast to the IMonitorLock interface, Gosu unsynchronizes on the variable
If an exception occurs during the execution of an exit action of an object, the exit actions defined before that exit
action run, and then the exception throws. If an exception occurs in more than one exit action, the outermost
exception, which occurs later in the code, takes precedence and is thrown to the surrounding code.
For example:
To pass multiple reentrant objects, nest multiple using clauses, such as:
using ( lock1 ) {
using ( lock2 ) {
...
}
}
You can combine the multiple item feature with the ability to assign variables. Gosu runs any statements, including
variable assignment, at run time and uses the result as an object to manage in the using clause. Within each comma-
delimited assignment statement, you do not need a return statement.
For example:
[Link]()
[Link]()
}
return false
}
}
Gosu ensures that all objects are properly cleaned up. Gosu cleans up only the objects that initialized without
throwing exceptions or otherwise having errors such as returning null for a resource.
If you choose to initialize multiple resources and some but not all objects in the list successfully initialize, Gosu
performs the following actions:
1. Gosu skips initialization for any subsequent items not yet initialized, in other words the items that appear later
in the initialization list.
2. Gosu skips execution of the main part of the using clause.
3. Gosu cleans up exactly the set of objects that initialized without errors. In other words, Gosu releases, closes,
or disposes the object, depending on the type of object.
For example, suppose you try to acquire three resources, and the first one succeeds but the second one fails. Gosu
does not attempt to acquire the third resource. Then, Gosu cleans up the one resource that did acquire successfully.
See also
• “Assigning variables inside a using expression declaration” on page 123
Disposable objects
Disposable objects are objects of which Gosu can dispose to release all system resources. For Gosu to recognize a
valid disposable object, the object must have one of the following attributes:
• The object implements the Gosu interface IDisposable. This interface contains only a single method called
dispose. This method takes no arguments. Always use a type that implements IDisposable if possible due to
faster run time performance.
• The object has a dispose method even if it does not implement the IDisposable interface. This approach works
but is slower at run time because Gosu must use reflection (examining the type at run time) to find the method.
A type’s dispose method must release all the resources that it owns. The dispose method must release all resources
owned by its base types by calling its parent type’s dispose method.
To ensure that resources clean up appropriately even under error conditions, you must design your dispose method
such that Gosu can call it multiple times without throwing an exception. In other words, if the stream is already
closed, then invoking this method has no effect nor throws an exception.
The following example shows a basic disposable object:
124 chapter 5: Exception handling
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
A using clause supports passing multiple objects. If you pass multiple objects to the using clause, exit actions
(closing, disposing, unlocking) happen in reverse order of the object declarations.
In contrast, you can write more readable Gosu code using the using keyword:
A using clause supports passing multiple objects. If you pass multiple objects to the using clause, exit actions
(closing, disposing, unlocking) happen in reverse order of the object declarations.
uses [Link].*
...
uses [Link]
...
function useReentrantLockNew() {
using ( _lock ) {
// Do your main work here
}
}
Similarly, you can cast any object to a monitor lock by adding as IMonitorLock after the object. For example, the
following method code uses the object itself, by using the keyword this, as the monitor lock:
126 chapter 5: Exception handling
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
function monitorLock() {
using ( this as IMonitorLock ) {
// Do stuff
}
}
function useReentrantLockOld() {
_lock.lock()
try {
// Do your main work here
}
finally {
[Link]()
}
}
Alternatively, you can do your change in a Gosu block. This approach is not recommended. Returning the value
from a block imposes more restrictions on how you implement return statements. It is typically better to use the
using statement structure shown earlier in this topic.
uses [Link]
...
A using clause supports passing multiple objects. If you pass multiple objects to the using clause, exit actions
(closing, disposing, unlocking) happen in reverse order of the object declarations.
The profiler tag class ([Link]) implements the IReentrant interface. This class adds
hints to the Gosu profiler which actions happen within a block of code.
See also
• [Link]
• “Object life-cycle management with using clauses” on page 122
• “Concurrency” on page 417
• “Using profiler tags” on page 127
new ProfilerTag("EventPayloadXML")
See also
• System Administration Guide
uses [Link]
uses [Link]
uses [Link]
See also
• “Disposable objects” on page 124
• “Closeable objects and using clauses” on page 125
• “Reentrant objects and using clauses” on page 126
construct(){
print("LOG: Created my object!")
_open = true
}
The following code creates a disposable object in a using clause, and throws an exception in the body of the using
clause. Note that the finally clause still runs:
[Link]: / by zero
[...]
Assert statements
An assert statement provides a concise syntax for asserting expectations and enforcing a programmatic contract with
calling code. For this purpose, Gosu has an assert statement with the same semantics and syntax as in Java.
You can use the Gosu assert statement in two different forms:
assert expressionBoolean
assert expressionBoolean : expressionMessage
assert i > 0 : i
Intervals
An interval is a sequence of values of the same type between a given pair of endpoint values. Gosu provides native
support for intervals. For instance, the set of integers beginning with 0 and ending with 5 is an integer interval
containing the values 0, 1, 2, 3, 4, 5. The Gosu syntax for this set is 0..5. Intervals are useful for concise, readable
for loops. Intervals can be of many types including numbers, dates, dimensions, and names. You can add custom
interval types. In some programming languages, intervals are called ranges.
for (i in 0..10) {
print("The value of i is " + i)
}
The value of i is 0
The value of i is 1
The value of i is 2
The value of i is 3
The value of i is 4
The value of i is 5
The value of i is 6
The value of i is 7
The value of i is 8
The value of i is 9
The value of i is 10
This code replaces the more verbose and harder-to-read design pattern:
var i = 0
while( i <= 10 ) {
print("The value of i is " + i)
i++
}
Intervals 131
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Intervals do not need to be numbers. Intervals can be of many types including numbers, dates, dimensions, and
names. Gosu includes built-in shorthand syntax with a double period (..) for intervals for dates and common
number types, such as the previous 0..10 example. The built-in shortcut works with the types Integer, Long,
BigInteger, BigDecimal, and Date. All decimal types map to the BigDecimal interval.
You can also add custom interval types that support any type that supports iterable comparable sequences. You can
then use your new intervals in for loop declarations.
If you need to get a reference to the interval’s iterator object ([Link]), call the iterate method,
which returns the iterator.
See also
• “Writing your own interval type” on page 133
for( i in 10..1) {
print ( i )
}
If you have a reference to a reversed interval, you can force the interval to operate in its natural order. In other
words, you can undo the flag that marks the interval as reversed. Use the following syntax:
The result is that the leftIterator variable contains the interval for 0, 1, 2, 3, 4, 5.
The iterate method, which returns the iterator, always iterates across the items in the declared order, either regular
order or reverse, depending on your definition of the interval.
132 chapter 6: Intervals
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Notice the WEEKS value, which is an enumeration constant. You do not need to qualify WEEKS with the enumeration
type. Gosu can infer the enumeration type so the code is always type-safe.
package [Link]
enum Color {
Red, Orange, Yellow, Green, Blue, Indigo, Violet
}
All Gosu enumerations automatically implement the [Link] interface, which is a requirement for
intervals. However, Gosu enumerations do not automatically implement the ISequenceable interface.
To determine an iterable interval dynamically, Gosu requires that a comparable endpoint also be sequenceable. To be
sequenceable means that a class knows how to find the next and previous items in the sequence. Sequenceable and
interval types have a lot in common. Both types both have the concept of granularity in terms of step amount and
optionally a unit such as weeks, months, and so on.
The interface for ISequenceable is as follows. Implement these me thods and declare your class to implement this
interface.
Intervals 133
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
int index
previousNthInSequence Returns E element, the element that is int index previous in the sequence
S step An alias for the column name in the row query result
U unit
int index
The syntax for the interface might look unusual because of the use of Gosu generics. This syntax indicates that the
interface is parameterized across three dimensions:
• The type of each sequenceable element in the interval.
• The type of the step amount. For example, to skip every other item, the step is 2, which is an Integer. For
typical use cases, pass Integer as the type of the step amount.
• The type of units for the interval. For example, for an integer (1, 2, 3), choose Integer. For a date interval, the
type is DateUnit. That type contains values representing days, weeks, or months. For instance, [Link].
If you do not use units with the interval, type [Link] for this dimension of the parameterization.
Carefully note the capitalization of this type, because it is particularly important to access Java types, especially
when using Gosu generics. In Gosu, as in Java, [Link] is the special type of the value null.
The example later in this topic has a class that extends the type:
This bidirectional interface can fetch both next and previous elements. Gosu needs this capability to handle
navigation from either endpoint in an interval to support the reverse mode. Gosu also requires that the class know
how to jump to an element by its index in the series. This functionality can be achieved with the single step methods,
some sequenceable objects can optimize this method without having to visit all elements in between. For example, if
the step value is 100, Gosu does not need to call the nextInSequence method 100 times to get the next value.
The following example defines an enumeration class with additional methods that implement the required methods
of ISequenceable.
package [Link]
enum ColorSequenceable
implements [Link]<ColorSequenceable, Integer, [Link]>
{
// Enumeration values....
Red, Orange, Yellow, Green, Blue, Indigo, Violet
for (i in colorRange) {
print(i)
}
for (i in colorRangeOpen) {
print(i)
}
To make your code look even more readable, you could create your own subclass of SequenceableInterval named
for the sequenceable type that you plan to use. For example, ColorSequenceInterval.
See also
• “Enumerations” on page 169
• “Generics” on page 221
See also
• “Inner classes” on page 164
• “Generics” on page 221
• “Example: Color interval written with manual iterators” on page 136
package [Link]
enum Color {
Red, Orange, Yellow, Green, Blue, Indigo, Violet
}
All Gosu enumerations automatically implement the [Link] interface, which is a requirement for
intervals.
Next, create a new class that extends the following type:
Next, implement the methods from the IIterableInterval interface. It is important to note that in this example the
iterator classes are inner classes of the main ColorInterval class.
package [Link]
uses [Link]
construct() {
throw "required start at # -- use other constructor"
}
construct(startAt : int ) {
_currentIndex = startAt
}
construct(startAt : int ) {
Intervals 137
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
super(startAt)
}
Note the parameterized element type using Gosu generics syntax. It enforces the property that elements in the
interval are mutually comparable.
Finally, you can use your new intervals in for loop declarations:
uses [Link]
uses [Link]
for (i in colorRange) {
print(i)
}
for (i in colorRangeOpen) {
print(i)
}
See also
• “Custom iterable intervals using sequenceable items” on page 133
• “Enumerations” on page 169
You can write Gosu code that uses Java types. Gosu code can instantiate Java types, access properties of Java types,
and call methods of Java types. Instead of writing Java code for your Gosu to call, if you write that code directly in
Gosu, you can do everything that you can do in Java. For example, you can directly call existing Java classes and
Java libraries. You can even write Gosu code enhancements that add properties and methods to Java types, and the
new members are accessible from all Gosu code.
This topic describes how to write Gosu code that works with Java and how to write Java code that works with Gosu
and works with Guidewire products.
See also
• “Gosu introduction” on page 19
• “Notable differences between Gosu and Java” on page 46
• Integration Guide
Gosu provides additional optional features and more concise syntax than Java, such as optional type inference and
optional semicolons.
Gosu code can integrate with Java types in the following ways:
• Instantiate Java types.
• Manipulate Java classes as native Gosu objects.
• Manipulate Java objects as native Gosu objects.
• Manipulate Java primitives as native Gosu objects.
Gosu converts between primitives and the equivalent object types automatically in most cases.
• Call methods on Java types.
For methods that look like getters and setters, Gosu exposes the methods also as Gosu properties.
• Get instance variables and static variables from Java types.
• Add new methods to Java types by using Gosu enhancements.
• Add new properties to Java types by using Gosu enhancements.
• Add new properties to Java types automatically for methods that look like getters and setters.
• Create Gosu classes that extend Java classes.
• Create Gosu interfaces that extend Java interfaces.
• Use Java enumerations.
• Use Java annotations.
• Use Java properties files.
All these features work with built-in Java types as well as your own Java classes and libraries.
If you do not use Guidewire entity types, you do not need to do anything other than to put compiled classes in a
special directory. If your Java code needs to get, set, or query Guidewire entity data, you must understand how
PolicyCenter works with entity data.
See also
• “Gosu introduction” on page 19
• “Notable differences between Gosu and Java” on page 46
• Integration Guide
[Link]
print([Link](0))
See also
• “Importing types and package namespaces” on page 114
package [Link];
// Constructor #1 - no arguments
public Circle() {
}
// Constructor #2
public Circle( int dRadius ) {
_radius = dRadius;
}
// From Java, these are METHODS that begin with get, set, is.
// From Gosu, these are PROPERTY accessors.
// For GET/IS, the method must take 0 args and return a value
public void isMethod1 () {
[Link]("running Java METHOD isMethod1() \n");
}
public double getMethod2 (double a, double b) {
[Link]("running Java METHOD isMethod2() \n");
return 1;
}
// For SET, the method must take 1 arg and return void
public void setMethod3 () {
[Link]("running Java METHOD setMethod3() \n");
}
public double setMethod4 (double a, double b) {
[Link]("running Java METHOD setMethod4() \n");
return 1;
}
}
The following Gosu code uses this Java class. Note which Java methods become property accessors and which ones
do not.
// Use natural property syntax to SET GOSU PROPERTIES. In Java, this was a method.
[Link] = 10
For Gosu code that accesses static members, you qualify the class that declares the static member or import the static
members from the class. For example, the following line uses the cosine function and the static reference to value PI
from the Math class without importing the static members:
To use the static members without qualifying them with the class name, you use the syntax of the uses statement
that imports static members. For example, the following lines are equivalent to the previous, single line of code:
uses [Link]#*
var cosHalfPiDgrees = cos(PI * 0.5)
See also
• “Importing static members” on page 116
See also
• “Interfaces” on page 171
See also
• “Enumerations” on page 169
Calling Java from Gosu 143
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Annotations” on page 209
# [Link]
# The hash character as the first char means that the line is a comment
! The exclamation mark character as the first char means that the line is a comment
website = [Link]
transport = bicycle
# Unicode support
tab : \u0009
The following Gosu class converts some of the Java properties into static Gosu properties.
package [Link]
uses [Link]
class MyPropsAccess {
static property get MyProperties() : Properties {
// Using getProperties reads the file only once. The Properties are cached as a static property.
// You must use the fully qualified path to the properties file even though MyPropsAccess and
// [Link] are in the same folder.
return [Link]("doc/examples/[Link]")
}
// Use methods on the MyProperties static property to access other property values
print(" tab: before${[Link]("tab")}after")
// Access a multi-level property
print("multi-level: ${[Link]("[Link].Key1")}")
website: [Link]
transport: bicycle
message: Welcome to Gosu!
tab: before after
multi-level: Value1
Classes
Gosu classes encapsulate data and code for a specific purpose. You can store and access data and invoke functions,
known as methods, on instances of a class or on the class itself. You can subclass and extend Gosu classes to store
and retrieve additional data and to invoke new methods. You can use Guidewire Studio to create and manage Gosu
classes.
See also
• Configuration Guide
You can also define data and methods that belong to the class itself, rather than an instance of the class. You use this
technique, for instance, to define a library of functions of similar purpose. The class encapsulates the functions but
you never need to create an instance of the class. You can create static methods on a class independent of whether
any code creates an instance of the class. Gosu does not force you to choose between the two design styles.
Classes 147
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
You can write Gosu classes that extend from Java classes. Your class can include Gosu generics features that
reference or extend Java classes or subtypes of Java classes.
See also
• “Static modifier” on page 163
• “Generics” on page 221
• Configuration Guide
Define methods with the keyword function followed by the method name and parentheses that enclose a parameter
list, which is empty if the method has no arguments. The parameter list uses commas to separate multiple
parameters. Each parameter has the format:
parameterName : typeName
If the method returns a value, after the parentheses, put a colon (:) and the return type. If the method does not return
a value, specifying void as the return type is optional.
For example, the following line declares a method that has a single String parameter. The method does not return a
value:
A Gosu class with one instance variable and one public method looks like the following:
class MyClass {
var myStringInstanceVariable : String
Your class is a subclass and subtype of the parent class. The parent class is a superclass and supertype of your class.
Constructors
A Gosu class can have a constructor, which is a special method that Gosu calls after creating an instance of the
class. For example, the Gosu code “new MyClass()” calls the MyClass class’s constructor for initialization or other
actions. To create a constructor, name the method construct. Do not use the function keyword. If you do not need
a class constructor, you do not need to create the construct method.
For example, the following class contains one constructor that takes no arguments:
class Tree {
construct() {
print("I just created a Tree object!")
}
}
You can create constructors that take arguments, just as for other methods. Any code that instantiates that object can
pass arguments to the new expression. For example, if the constructor takes one argument that is a String object,
you can instantiate the class by using code such as the following line:
If the class constructors all take one or more arguments, any code that instantiates the class must provide a parameter
list. Failing to pass arguments to a new expression for this class produces a compilation error.
If your class extends another class, your constructor can call the constructor of its superclass by using the super
keyword, followed by parentheses. This statement must be the first statement in the subclass constructor. For
example, the following code calls the superclass constructor, and then performs additional work.
If you call super() with no arguments between the parentheses, Gosu calls the superclass no-argument constructor.
If you call super(parameter_list), Gosu calls the superclass constructor that matches the matching parameter list.
You can call a superclass constructor with different number of arguments or different types than the current
constructor.
For every constructor that you write, Gosu always calls a version of the superclass constructor, even if you omit an
explicit reference to super(). If your class does not call the superclass constructor explicitly, Gosu attempts to use
the no-argument superclass constructor:
• If a no-argument constructor exists in the supertype, Gosu calls that constructor, which is equivalent to the code
super().
• If a no-argument constructor does not exist in the supertype, Gosu throws a no default constructor
compilation syntax error.
Classes 149
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Gosu does not support a class having both an instance method and a static method that have the same name and
argument list.
See also
• “Static modifier” on page 163
public var FirstName : String // Do not do this. Public variables are not standard Gosu style
See also
• “Properties” on page 151
You can use object initializers to set properties on an object immediately after a new expression. Use object
initializers for compact and clear object declarations. Object initializers are especially useful in combination with
data structure syntax and nested objects. A simple use of an object initializer looks like the following line:
var sampleClaim = new Claim() {:ClaimId = "TestID"} // Initialize the ClaimID on the new claim.
Note: You can use static methods, static variables, and static properties of a Gosu class without
creating an instance of the class.
See also
• “Using the operator new in object expressions” on page 86
• “Static modifier” on page 163
you will not be able to create classes in the package. This warning applies only to Java classes. You can create a
Gosu class in the package.
Class names or other type names must always start with a capital letter. Type names can contain additional capital
letters later in the name for clarity. If you write Gosu enhancements, the naming rules are slightly different from the
conventions for other types.
Use the following standard package naming conventions:
WARNING Your types must never use a package name with the prefix “[Link].” or the
prefix “gw.” Those package namespaces are reserved for internal types.
See also
• “Importing types and package namespaces” on page 114
• “Enhancement naming and package conventions” on page 204
uses [Link]
The uses lines must be at the top of the class, not within a Gosu method definition.
See also
• “Importing types and package namespaces” on page 114
• “Importing static members” on page 116
Properties
Gosu classes can define properties for other objects to access the property value similarly to variables on the class.
Other objects use the intuitive syntax of the period symbol (.) to access the properties. You can use Gosu code to
implement get and set functionality for a property. The simplest code that gets or sets a property value uses an
instance variable, but you can implement properties in other, more dynamic ways.
To get and set properties on an object that has Field1 and Field2 properties, use the period symbol just as for
getting and setting standard variables:
The most straightforward form of a property definition is like a function that uses the keywords “property get” or
“property set” before the function name instead of “function”. The get property function must take zero
parameters and the set property function must take exactly one parameter.
Classes 151
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
For example, the following code defines a Field3 property that supports both set and get functionality:
class MyClass {
property get Field3() : String {
return "myFirstClass" // In this simple example, do not return a saved value.
}
property set Field3(str : String) {
print(str) // Print only. In this simple example, do not save the value.
}
}
The set property function does not save the value in that simple example. In a typical class, you use a private
instance variable to store the value:
class MyClass {
private var _field4 : String
Although the data is stored in private variable _field4, code that accesses this data does not access the private
instance variable directly. Any code that needs to use the data uses the period symbol (.) and the property name:
Code within a class does not need to use the property name to access a property on the same class. Classes can
access their own private variables. In the previous example, other methods in that class could reference the _field4
variable rather than using the property accessor Field4.
Your property getter and setter methods can perform complex calculations or store the data in some other way than
as a variable.
class MyClass {
private var _field4 : String as Field4
}
Standard Gosu style is to use public properties backed by private variables instead of using public variables.
Write your Gosu classes to declare properties similar to the following line:
This code declares a private variable called _firstname, which Gosu exposes as a public property called
FirstName.
Do not write your classes to declare public variables like the following line:
Read‐only properties
By default, properties are both readable and writable, but you can make a property read-only by adding the keyword
readonly before the property name, as shown in the following code:
class MyClass {
private var _firstname : String as readonly FirstName
}
Properties are dynamic and virtual functions that act like data
In contrast to standard instance variables, property get and property set functions are virtual. You can override
virtual property functions in subclasses and implement them from interfaces. The following code shows how you
override a property in a subclass. You can even call the superclass’s get or set property function:
class MyClass {
var _propertyVar : String as MyProperty
}
The overridden property get function first calls the implicitly defined get function from the superclass, which
gets the class variable called _propertyVar, and then appends a string. This get function does not change the value
of the class variable _propertyVar, but code that accesses the MyProperty property from the subclass gets a
different value.
For example, create the classes in the previous code. Next, write and then run the following code in the Gosu
Scratchpad:
[Link] = "MyPropValue"
[Link] = "MyPropValue"
print([Link])
print([Link])
MyPropValue
MyPropValue from MySubClass
[Link]
In most cases, if any object to the left of the period character is null, Gosu does not throw a null-pointer exception
(NPE) and the expression returns null. Gosu null-safe property paths tend to simplify real-world code. Often, a
null expression result has the same meaning whether the final property access is null or earlier parts of the path are
null. For such cases in Gosu, do not check for the null value at every level of the path. This conciseness makes
your Gosu code easier to read and understand.
For example, suppose you have a variable called house, which contains a property called Walls, and that object has
a property called Windows. The syntax to get the Windows value is:
Classes 153
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
[Link]
In some languages, you must be aware that if house is null or [Link] is null, your code throws a null-
pointer exception. The following common coding pattern avoids the exception:
// Initialize to null
var x : ArrayList<Windows> = null
// Check earlier parts of the path for null to avoid a null-pointer exceptions (NPE)
if (house != null and [Link] != null) {
x = [Link]
}
In Gosu, if earlier parts of a pure property path are null, the expression is valid and returns null. The following
Gosu code is equivalent to the previous example and a null-pointer exception never occurs:
var x = [Link]
By default, method calls are not null-safe. If the right side of a period character is a method call, Gosu throws a null-
pointer exception (NPE) if the value on the left side of the period is null.
For example:
[Link]()
If house is null, Gosu throws an NPE. Gosu assumes that method calls might have side effects, so Gosu cannot skip
the method call and return null.
Gosu provides a variant of the period operator that is always explicitly null-safe for both property access and method
access. The null-safe period operator has a question mark before the period: ?.
If the value on the left of the ?. operator is null, the expression evaluates to null.
For example, the following expression evaluates left-to-right and contains three null-safe property operators:
obj?.PropertyA?.PropertyB?.PropertyC
house?.myaction()
If house is null, Gosu does not throw an exception. Gosu returns null from the expression.
var displayName = [Link] ?: "(Unknown Title)" // Return "(Unknown Title)" if [Link] is null
• The null-safe index operator (?[]). Use this operator with lists and arrays. The expression returns null if the list
or array value is null at run time, rather than throwing an exception. For example:
• The null-safe math operators (?+, ?-, ?*, ?/, and ?%). For example:
IMPORTANT Expose public data as properties rather than as getter functions. By using a property, you
to take advantage of Gosu null-safe property accessor paths. Standard Gosu practice is to separate
your implementation from your class’s interaction with other code by using properties rather than
public instance variables. Gosu provides the as keyword to expose an instance variable as a property.
See also
• “Handling null values in expressions” on page 96
if ([Link])
Because null coerces implicitly to the type Boolean, which is the type of the Empty property, the expression
evaluates to false in either of the following cases:
• If [Link] has the value null.
• The value of StringProperty is non-null but its Empty property evaluates to false.
In typical code, distinguishing between these two very different cases is important. For example, if you need to use
the value [Link] only if the value is non-empty, just checking the value
[Link] is insufficient.
To work around this restriction, Gosu adds an enhancement property to [Link] called HasContent. This
property effectively has the reverse of the logic of the Empty property. The HasContent property only returns true if
the property has content, so you can use property accessor paths such as the following line:
if ([Link])
Because null coerces implicitly to the type Boolean, which is the type of the Empty property, the expression
evaluates to false in either of the following cases:
• If [Link] is null.
• The String is non-null but the string has no content and so its HasContent property evaluates to false.
These cases are much more similar semantically than the variant that uses Empty ([Link]).
Be sure to consider null-safety of property paths as you design your code, particularly with Boolean properties.
Static properties
You can use static properties directly on the class without creating an instance of the class.
See also
• “Static modifier” on page 163
Classes 155
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
package mypackage
class MyFirstClass {
package mypackage
// Explicit property setter for _f2, visible only to classes in this package
internal property set F2( value : String ) {
_f2 = value
}
Create the classes, and then try the following lines in Gosu Scratchpad to test these classes.
First, create an instance of your class:
Assign a property value. This code internally calls a hidden method to assign "hello" to variable _f0:
test.F0 = "hello"
Get a property value. This code indirectly calls the mySecondClass property getter function for F2:
print( test.F2 ) // Prints null because the property is not set yet
The following line is invalid because F2 is not visible outside of the package namespace of MySecondClass. The F2
property is publicly read-only.
The following line is invalid because Calculation is read-only. This property does not have a setter function:
Demonstrate that properties can be overridden through inheritance because properties are virtual:
Modifiers
Gosu supports several types of modifiers.
Access modifiers
You can use access modifier keywords to set the level of access to a Gosu class, interface, enumeration, or a type
member, which is a function, variable, or property. The access level determines whether other classes can use a
particular variable or invoke a particular function.
For example, methods and variables marked public are visible from other classes in the package. Additionally,
because they are public, functions and variables also are visible to all subclasses of the class and to all classes
outside the current package. For example, the following code uses the public access modifier on a class variable:
package [Link]
class Test1 {
public var Name : String
}
In contrast, the internal access modifier lets the variable be accessed only in the same package as the class:
package [Link]
class Test2 {
internal var Name : String
}
For example, another class with fully qualified name [Link].Test2 could access the Name variable
because it is in the same package. Another class [Link].Test3 cannot see the [Link]
variable because it is not in the same package.
Similarly, modifiers can apply to an entire type, such as a Gosu class:
package [Link]
Classes 157
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Some access modifiers apply only to type members (functions, variables, properties, and inner types). Other access
modifiers apply to both type members and top-level types (outer Gosu classes, interfaces, enumerations). The
following table lists the Gosu access modifiers and their applicability and visibility:
If you do not specify a modifier, Gosu uses the following default access levels:
Functions public
Properties public
See also
• “Coding style” on page 465
Override modifier
Apply the override modifier to a function or property implementation to declare that the subtype overrides the
implementation of an inherited function or property with the same signature.
For example, the following line might appear in a subtype overriding a myFunction method in its superclass:
If Gosu detects that you are overriding an inherited function or method with the same name but you omit the
override keyword, you get a compiler warning. Additionally, the Gosu editor offers to insert the modifier if the
override keyword seems appropriate.
Abstract modifier
The abstract modifier indicates that a type is intended only to be a base type of other types. Typically, an abstract
type does not provide implementations, which contain code to perform the function, for some or all of its functions
and properties. This modifier applies to classes, interfaces, functions, and properties.
For example, the following code is a simple abstract class:
If a type is specified as abstract, Gosu code cannot construct an instance of that type. For example, you cannot use
code such as new MyType() for an abstract type. You can instantiate a subtype of the abstract type if the subtype
fully implements all abstract members (functions and properties). A subtype that contains implementations for all
abstract members of its supertype is called a concrete type.
For example, if class A is abstract and defines one method’s parameters and return value but does not provide code
for the method, that method would be declared abstract. Another class B could extend A and provide code to
implement that abstract method. Class A is the abstract class and class B is a concrete subclass of A.
For example, the following code defines an abstract Gosu class called Vehicle, which contains members but no
abstract members:
package [Link]
You cannot construct an instance of this class, but you can define another class that extends the class:
package [Link]
You can now use code such as the following to create an instance of Truck:
Things work differently if the supertype, in this case, Vehicle, defines abstract members. If the supertype defines
abstract methods or abstract properties, the subtype must define a concrete implementation of each abstract method
or property to support instantiation of the subclass. A concrete method implementation must implement actual
behavior, not just inherit the method signature. A concrete property implementation must implement actual behavior
of getting and setting the property, not just inherit the property name.
The subtype must implement an abstract function or abstract property using the same name as the supertype. Use the
override keyword to tell Gosu that the subtype overrides an inherited function or method of the same name. If you
omit the override keyword, Gosu displays a compiler warning. Additionally, the Gosu editor offers to insert the
override modifier if the override keyword seems appropriate.
For example, the following code expands the Vehicle class with abstract members:
package [Link]
Classes 159
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
A concrete subtype of this Vehicle class looks like the following code:
package [Link]
/* Create a class instance variable that uses the "as ..." syntax to define a property.
* This variable provides a concrete implementation of the abstract property "Plate".
*/
var _licenseplate : String as Plate
You can now construct an instance of the concrete subtype Truck, even though you cannot directly construct an
instance of the supertype Vehicle because that type is abstract.
Create the classes, and then try the following lines in Gosu Scratchpad to test these classes.
Final modifier
The final modifier applies to types (including classes), type members (variables, properties, methods), local
variables, and function parameters.
The final modifier specifies that the value of a property, local variable, or parameter cannot be modified after the
initial value is assigned. The final modifier cannot be combined with the abstract modifier on anything. These
modifiers are mutually exclusive. The final modifier implies that there is a concrete implementation and the
abstract modifier implies that there is no concrete implementation.
Final types
If you use the final modifier on a type, the type cannot be inherited. For example, if a Gosu class is final, you
cannot create a subclass of that class.
The final modifier is implicit with enumerations. An enumeration is an encapsulated list of enumerated constants.
Enumerations are implemented like Gosu classes in most ways. No Gosu code can subclass an enumeration.
See also
• “Enumerations” on page 169
For example:
class TestABC {
final var _name : String = "John"
}
Optionally, you can use the final keyword on a class variable declaration without immediately initializing the
variable. If you do not immediately initialize the variable in the same statement, all class constructors must initialize
that variable in all possible code paths.
For example, the following syntax is valid because all constructors initialize the final variable once in each code
path:
class TestABC {
final var _name : String
construct() {
_name = "hello"
}
construct(b : boolean){
_name = "there"
}
}
The following code is invalid because one constructor does not initialize the final variable:
class TestABC {
final var _name : String // INVALID CODE, ALL CONSTRUCTORS MUST INITIALIZE _name IN ALL CODE PATHS.
construct(b : boolean){
_name = "there"
}
}
package [Link]
class Auto {
See also
• “Properties” on page 151
class final1 {
function PrintGreeting() {
Classes 161
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
var f = "frozen"
f = "dynamic"
}
}
This code is not valid because it attempts to change the value of the final variable:
class final1 {
function PrintGreeting() {
final var f = "frozen"
f = "dynamic" // Compile error because it attempts to change a final variable
}
}
If you define a local variable as final, you can initialize the value of the variable immediately in the declaration.
Alternatively, you can declare the variable as final but not immediately initialize the variable with a value. You
must set the value in that function for all possible code paths. For example, any if statements or other flow control
structures must set the value of the variable and not change a value that previous code set. The Gosu compiler
verifies that all code paths initialize the final variable exactly once.
For example, the following code is valid:
If you remove the else branch, the code is not valid because the final variable is initialized only if a is true.
package example
class FinalTest {
function SuffixTest(greeting : String) {
greeting = greeting + "fly"
print(greeting)
}
}
Butterfly
If you add the final modifier to the parameter, the code generates a compile error because the function attempts to
modify the value of a final parameter:
class FinalTest {
function SuffixTest(final greeting : String) {
greeting = greeting + "fly"
print(greeting)
}
}
Static modifier
Gosu supports static variables, functions, properties, and inner types.
Static variables
Gosu classes can define a variable as static. A static variable is stored once for a Gosu class, rather than once for
each instance of the class. The static modifier can be used with variables and properties.
WARNING If you use static variables in a multi-threaded environment, you must take precautions
to prevent simultaneous access from different threads. Use static variables sparingly if ever. If you
use static variables, be sure you understand synchronized thread access fully.
For additional help on static variables and synchronized access, contact Customer Support.
To use a Gosu class variable, set its access level, such as internal or public, to restrict access to the set of classes
that need to use the variable.
The static modifier cannot be combined with the abstract modifier.
class Greeting {
The Name property get and set functions and the PrintGreeting method are part of the Greeting class itself
because they are marked as static.
The following code accesses properties on the class itself, not an instance of the class. You can create the class, and
then test this code in the Gosu Scratchpad:
This example does not use the new keyword to construct an instance of the Greeting class.
Classes 163
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
package example
class Greeting {
static class FrenchGreeting {
static public function sayWhat() : String {
return "Bonjour"
}
}
Create the classes, and then try the following lines in Gosu Scratchpad to test the inner class.
print([Link])
Bonjour
See also
• “Access modifiers” on page 157
• “Abstract modifier” on page 159
• “Inner classes” on page 164
• “Concurrency” on page 417
Inner classes
You can define inner classes in Gosu, similar to inner classes in Java. Inner classes are useful for encapsulating code
even further within the same class as related code. Use named inner classes if you need to refer to the inner class
from multiple related methods or multiple related classes. Use anonymous inner classes if you need a simple
subclass that you can define in-line within a class method.
Inner classes can optionally include generics features.
The outer class that defines the inner class is also called the enclosing class.
See also
• “Generics” on page 221
Example
The following code demonstrates a simple inner class.
164 chapter 8: Classes
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
package example
class Greeting {
// function in the main (outer) class
public function greet() {
var x = new FrenchGreeting()
print([Link]())
}
Create the classes, and then try the following lines in Gosu Scratchpad to test the inner class.
Bonjour
package example
class Greeting {
// Field in the main (outer) class
public var intro : String = "I would like to say"
If there is no ambiguity about the variable to which a name refers, the outer keyword and the following period are
optional:
package example
Classes 165
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
class Greeting {
public property get Hello() : String {
return [Link]()
}
You can test this class in the Gosu Scratchpad using the code:
print([Link])
Bonjour
Notice that this example does not construct a new instance of the Greeting class or the FrenchGreeting class using
the new keyword. The inner class in this example has the static modifier.
An inner class must be declared static in order to define static members, such as static methods, static fields, or
static properties. This Gosu requirement mirrors the requirement of Java inner classes.
See also
• “Static modifier” on page 163
Classes that extend the outer class can use the inner class
Classes that derive from the outer class can use the inner class.
The following code defines the Greeting class and its inner class FrenchGreeting.
package example
class Greeting {
// function in the main (outer) class
public function greet() {
var x = new FrenchGreeting()
print([Link]())
}
The following example subclasses the Greeting class and uses the method in the inner FrenchGreeting class:
package example
You can test this code by using the following code in the Gosu Scratchpad:
166 chapter 8: Classes
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Bonjour
Example 1
The following class uses an anonymous inner class:
package example
class InnerTest {
// Anonymous inner classes can have variables (public, private, and so on)
private var i = 0
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
}
}
You can use the following code in the Gosu Scratchpad to test this class:
[Link]()
Value is 0 at creation!
Value is 1
Value is 2
Value is 3
Value is 4
Value is 5
Classes 167
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Example 2
The following example demonstrates an advanced anonymous inner class. This anonymous inner class derives from
a more functional class than Object. In this example, new inner class inherits the constructor and another method.
The following code defines a base class named Vehicle for the inner class:
package example
class Vehicle {
construct() {
print("A vehicle was just constructed!")
}
The following code creates a different class that uses Vehicle and defines an anonymous inner class that is based on
Vehicle:
package example
class FancyVehicle {
The inner class that defines the actionTwo method uses the new operator and not the class operator. The new
operator defines a new class with no name and then creates one instance of that class.
Create the classes, and then try the following lines in Gosu Scratchpad to test the FancyVehicle class:
See also
• “Blocks as shortcuts for anonymous classes” on page 181
Enumerations
An enumeration is a list of named constants that are encapsulated into a special type of class. Gosu supports
enumerations natively, as well as provides compatibility to use enumerations defined in Java.
Using enumerations
An enumeration is a list of named constants that are encapsulated into a special type of class. For example, an
application tracking cars might want to store the car manufacturer in a property, but track the manufacturers as
named constants that can be checked at compile time. Gosu supports enumerations natively and also is compatible
with enumerations defined in Java.
Create an enumeration
An enumeration provides a fixed set of values that you can use for a property or variable. For example, a FruitType
enumeration provides names of fruits.
Procedure
1. Create an enumeration by using the same approach that you use to create a class.
a. In Studio, right-click a package folder and click the New submenu.
b. Click Class to create the enumeration class in that package.
c. Type a name for the enumeration.
d. In the drop-down list, click Enum.
Your enumeration looks like:
package example
enum FruitType {
enum FruitType {
Apple, Orange, Banana, Kiwi, Passionfruit
}
[Link]
To use the name of the enumeration element as a String, get its Name property. To use the zero-based index of the
enumeration element as an Integer, get its Ordinal property.
Procedure
1. In Studio, in Scratchpad, create a variable that contains an enumeration constant:
uses [Link]
var myFruitType = [Link]
2. Add the following lines to access the properties of the enumeration constant:
Banana
Banana
2
Comparing enumerations
You can compare two enumerations by using the == operator. For example:
if (myFruitType == [Link]) {
print("An apple a day keeps the doctor away.")
}
if (myFruitType == [Link]) {
print("Watch out for banana peels.")
}
Running this code produces the following line if myFruitType references [Link]:
See also
• “Create an enumeration” on page 169
• “Extract information from an enumeration” on page 170
Interfaces
Gosu can define and implement interfaces that define a strict contract of interaction and expectation between two or
more software elements. From a syntax perspective, interfaces look like class definitions but merely specify a set of
required functions necessary for any class that implements the interface. An interface is conceptually a list of
method signatures grouped together. Some other piece of code must implement that set of methods to successfully
implement that interface. Gosu classes can implement interfaces defined in either Gosu or Java.
What is an interface?
Interfaces are a set of required functions necessary for a specific task. Interfaces define a strict contract of interaction
and expectation between two or more software elements, but leave the implementation details to the code that
implements the interface. In many cases, the person who writes the interface is different from the person who writes
code to implement the interface.
A physical example of an interface is a car stereo system. The buttons, such as for channel up and channel down, are
the interface between you and the complex electrical circuits on the inside of the box. You press buttons to change
the channel. However, you probably do not care about the implementation details of how the stereo performs those
tasks behind the solid walls of the stereo. If you get a new stereo, it has equivalent buttons and matching behavior.
Because you interact only with the buttons and the output audio, if the user interface is appropriate and outputs
appropriate sounds, the internal details do not matter to you. You do not care about the details of how the stereo
internally handles the button presses for channel up, channel down, volume up, and volume down.
Similarly, PolicyCenter defines interfaces that PolicyCenter calls to perform various tasks or calculate values. For
example, to integrate PolicyCenter with a document management system, implement a plugin interface that defines
how the application interacts with a document management system. The implementation details of document
management are separate from the contract that defines what actions your document management code must handle.
If a Gosu class implements this interface, Gosu validates at compile time that all required methods are present and
that the implementor class has the required method signatures.
An interface provides a group of related method signatures with empty bodies grouped together for the purpose of
some other piece of code implementing the methods. If a class implements the interface, the class agrees to
implement all these methods with the appropriate method signatures. The code implementing the interface agrees
that each method appropriately performs the desired task if external code calls those methods.
You can write Gosu classes that implement or extend interfaces defined in either Gosu or Java.
See also
• Integration Guide
Interfaces 171
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The Gosu editor reveals compilation errors if your class does not properly implement the plugin interface. You must
fix these issues.
A common compilation issue is that interface methods that look like properties must be implemented in Gosu
explicitly as a Gosu property. In other words, if the interface contains a method whose name starts with "get" or
"is" and takes no parameters, define the method using the Gosu property syntax. In this case, do not use the
function keyword to define the method as a standard class method.
For example, if interface IMyInterface declares methods isVisible() and getName(), your implementation of
this interface might look like:
Gosu interfaces can extend from Java interfaces. You can also have your interface include Gosu generics. Your
interface can extend from a Java interface that supports generics. Your interface can abstract an interface across a
type defined in Java or a subtype of such a type.
See also
• “Generics” on page 221
interface Restaurant {
function retrieveMeals() : String[]
function retrieveMealDetails(dishname : String) : String
}
3. To implement an interface, create a Gosu class and add "implements MyInterfaceName" after the class name.
For example, if your class is called MyRestaurant, go to the line:
class MyRestaurant
5. For the example Restaurant interface, implement the interface with a class.
For example, use code like the following lines:
Classes can implement an interface property with the explicit property get or property set syntax.
For example, the following code defines an interface:
package example
interface MyInterface {
property get VolumeLevel() : int
property set VolumeLevel(vol : int) : void
}
After creating the class and interface, you can test the following code in the Gosu Scratchpad:
uses [Link]
Alternatively, a class implementing a property can implement the property with the variable alias syntax by using
the as keyword. Using this language feature, you make set methods that use a class instance variable to store
property values, and get methods to get property values from the variable.
Interfaces 173
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
For example, the following, more concise code is functionally identical to the previous example implementation of
MyStereo:
uses [Link]
If you run the same Gosu Scratchpad code as previously, the code prints the same results.
See also
• “Classes” on page 147
• “Properties” on page 151
Implementing methods
Use of the override modifier is optional on an implementation of an interface method. If you do use the override
modifier, your code in a class that implements an interface is more robust against changes in method signatures in
the interface.
Superclass properties
When implementing an interface and referencing a property on a superclass, use the [Link] syntax,
such as:
See also
• “Modifiers” on page 157
Blocks
Gosu blocks are a special type of function that you can define in-line within another function. You can then pass that
block of code to yet other functions to invoke as appropriate. Blocks are useful for generalizing algorithms and
simplifying interfaces to certain APIs. For example, blocks can simplify tasks related to collections, such as finding
items within or iterating across all items in a collection.
a hyphen character (-) and a greater-than character (>) to form the appearance of an arrow: ->. Finally, add a Gosu
expression or a statement list surrounded by braces ({}).
The syntax of a block definition is:
The argument list (argumentList) is a standard function argument list, for example:
x : int, y : int
The argument list defines the parameters to pass to the block. The parameter list uses identical syntax as parameters
to regular functions. In some cases, you can omit the types of the parameters, such as passing a block directly into a
class method such that Gosu can infer the parameter type.
The block body (blockBody) can be either of the following:
• A simple expression. This expression includes anything legal on the right-hand side of an assignment statement.
For example, the following line is a simple expression:
• A statement list of one or more statements surrounded by braces and separated by semi-colon characters, such as
the following simple single-statement statement list:
For single-statement statement lists, you must explicitly include the brace characters. In particular, note that
variable assignment operations are always statements, not expressions. Thus, the following block is invalid:
For multiple statements, separate the statements with a semicolon character. For example:
The following block multiplies a number by itself, which is known as squaring a number:
IMPORTANT All parameter names in a block definition’s argument list must not conflict with any
existing in-scope variables, including but not limited to local variables.
Standard Gosu style is to omit all semicolon characters in Gosu at the ends of lines. Gosu code is more readable
without these optional semicolons. However, if you provide statement lists on one line, such as within block
definitions, use semicolons to separate statements.
See also
• “Argument type inference shortcut” on page 178
• “General coding guidelines” on page 465
176 chapter 11: Blocks
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Because the statement return "hello blocks" returns a String object, the Gosu compiler infers that the return
type of the block is String.
Invoking blocks
You can invoke blocks just like normal functions by referencing a variable to which you previously assigned the
block. To use a block, type the following items in the following order:
• The name of the block variable or an expression that resolves to a block
• An open parenthesis
• A series of argument expressions
• A closing parenthesis
For example, suppose you create a Gosu block with no arguments and a simple return statement:
Because the statement list returns a String, Gosu infers that the block returns a String. The new block is assigned
to a new variable blockWithStatementBody, and the variable has a type of String even though the code text does
not show the type explicitly.
To call this block and assign the result to the variable myresult, use this code:
The value of the variable myresult is the String value "hello blocks" after this line executes.
The following example creates a simple block that has two numbers as parameters and returns the result of adding
those numbers:
After defining this block, you can call it with code such as:
The variable mysum has the type int and has the value 30 after the line is executed.
You can also implement the same block behavior by using an expression rather than a statement list, which uses an
even more concise syntax:
by reference means that blocks do not capture the current value of the variable at the time its enclosing code creates
the block. If the variable changes after the enclosing code creates the block, the block uses the most recent value in
the original scope. This behavior continues even if the original scope exited or finished.
The following example adds 10 to a value. However, the value 10 was captured in a local variable, rather than
included in an argument. The captured variable, called captured in this example, is used but not defined within the
block:
var captured = 10
var addTo10 = \ x : int -> captured + x
var myresult = addTo10(10)
After the third line is executed, myresult contains the value 20.
A block captures the state of the stack at the point of its declaration, including all variables and the special symbol
this, which represents the current object. For example, this can represent the current instance of a Gosu class
running a method.
This capturing feature allows the block to access variables in scope at its definition. Capturing occurs even in the
following cases:
• After passing the block as an argument to another function
• After the block returns to the function that defines it
• If code assigns the block to a variable and retains the variable indefinitely
• After the original scope exits or finishes
Each time the block runs, the block can access all variables declared in the original scope in which the block was
defined. The block can get or set those variables. The values of captured variables are evaluated each time the block
is executed, and can be read or set as needed. Captured variable values are not a static snapshot of the values at the
time that the block was created.
The following example creates a block that captures a variable (x) from the surrounding scope. Next, the code that
created the block changes the value of x. Code calls the block only after that change happens:
// Note: the variable "x" is now SHARED by the block and the surrounding context
// At the time the block runs, it uses the current value of "x".
// This value is NOT a snapshot of the value at the time the block was created
var z = captureX( 10 )
The captured variable is shared by the original scope and the block that was created within that scope. The block
references the variable itself, not merely its original value.
IMPORTANT Capturing variables in blocks is very powerful. Use this feature very carefully.
Document your assumptions so that people who read your code can understand that code.
In other words, if you pass a block to a method, in some cases Gosu can infer the type so you can omit the type for
more concise code. This behavior is particularly relevant for using collection-related code that takes blocks as
arguments.
For example, suppose you have this code:
You can omit the argument type (String). The map method signature allows Gosu to infer the argument type in the
block from the definition of the map method.
You can use the more concise code:
The list method map is a built-in list enhancement method that takes a block with one argument. That argument is
always the same as the type of the list. Therefore, Gosu infers that str must be of type String. You do not need to
explicitly define either the type of the arguments or the return type.
The map method is implemented using a built-in Gosu enhancement of the Java language List interface.
See also
• See “Collections” on page 183
For example, to declare that strBlock is a variable that can contain a block that takes a single String argument and
returns a String value, use this code:
In declarations, you can also optionally use the block keyword, although this is discouraged in declarations:
For example, this code declares the same block type as described earlier:
Blocks 179
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
For example:
The b variable is assigned a value that is a block type. Because the block type literal is not directly part of the
declaration, Gosu requires the block keyword.
For example, suppose you want to declare a function that takes one argument, which is a block. Suppose the block
takes a single String argument and returns no value. To refer to this block by name as myCallback, define the
argument using the syntax:
package mytest
class test1 {
function myMethod( myCallBack( String ) : void ) {
After creating the class, you can test the following code in the Gosu Scratchpad:
For more concise code, you can omit the argument type “: String” in the in-line block. The block is defined in-line
as an argument to a method whose argument types are already defined. In other words, you can use the following
code:
<contents>Hello World</contents>
This code has two end conditions. The first end condition ensures that the block terminates if the result would be
greater than Integer.MAX_VALUE or if the parameter value is less than 1. The second end condition terminates the
recursion when the argument value is 1. To test this block, use code like the following:
print(bFactorial(6))
720
You can use blocks to sort the list based on various attributes, such as the length of the strings. Create a block that
takes a String and returns the sort key, which in this case is the String object’s length. The built-in list
sortBy(...) method handles the rest of the sorting algorithm and then returns the new sorted array:
These block-based collection methods are implemented using a built-in Gosu enhancement of the Java language
List class.
See also
• “Collections” on page 183
As a naming convention, if an API uses a type with a name that contains the word Block, you can probably use a
block for that type.
This technique works with any interface, including interfaces defined as inner interfaces within another interface.
Example
This example demonstrates the use of a block argument for an inner functional interface that an outer interface
defines. The MyCallbackHandler interface contains an inner functional interface called
[Link]. This functional interface implements a single method named run, similar to
the Runnable interface. Instead of creating an anonymous class to use the inner interface, use a block that takes no
arguments and has no return value.
This Java code defines the MyCallbackHandler interface:
// ...
Collections
Gosu collection and list classes rely on collection classes from the Java language. Gosu collections and lists provide
significant built-in enhancements over the Java classes. By using the enhanced Gosu collection and list classes, you
can loop through collection items to perform actions, extract item information, or sort items with single lines of
code.
Gosu provides additional initializer syntax for both lists and maps similar to Gosu’s compact initializer syntax for
arrays.
Basic lists
Lists in Gosu inherit from the Java interface [Link] and its common Java subclasses, such as
[Link].
See also
• “Sorting lists or other comparable collections” on page 190
Creating a list
To create an empty list, you use generics notation to specify the type of object that the list contains, such as in this
example of an ArrayList of String objects:
In many cases, you need to initialize the list with data. Gosu provides a natural syntax for initializing lists similar to
initializing arrays.
For example, the following line is an array instantiation:
Collections 183
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
[Link]("ab")
[Link]("abc")
See also
• “Generics” on page 221
The compile-time type of the list is [Link]<String>. The run-time type is different,
[Link]<Object>.
Gosu infers the type of the result list as the least upper bound of the components of the list. If you pass different
types of objects, Gosu finds the most specific type that includes all of the items in the list.
If the types implement interfaces, Gosu attempts to preserve commonality of interface support in the list type. This
behavior ensures that your list acts as expected with APIs that rely on support for the interface. In some cases, the
resulting type is a compound type, which combines:
• Zero classes or one class, which might be [Link], if no other common class is found
• One or more interfaces
At compile time, the list and its elements use the compound type. You can use the list and its elements with APIs
that expect those interfaces or the ancestor element.
For example, the following code creates classes that extend a parent class and implement an interface.
interface HasHello {
function hello()
}
class TestParent {
function unusedMethod() {}
}
See also
• “Compound types” on page 409
You can write this code in Gosu in more natural index syntax using Gosu shortcuts.
This Gosu syntax does not automatically resize lists. If a list has only three items, the following code fails at run
time with an index out of bounds exception.
In many cases, you need to initialize the map with data. Gosu provides a natural syntax for initializing maps similar
to initializing arrays and lists.
For example, the following code creates a new HashMap where "aKey" and "bKey" are keys, whose values are
"aValue" and "bValue" respectively:
var strMap = new HashMap<String, String>(){"aKey" -> "aValue", "bKey" -> "bValue"}
This Gosu syntax simplifies the declaration of static final data structures of this type, and produces more readable
code than the equivalent Java code.
Although the type name is omitted, the map is not untyped. Gosu infers that you want to create a HashMap by the
way you use the hyphen and greater than symbol. Gosu infers the exact type of the map from the object types that
you pass to the initialization.
The run-time type is always:
[Link]<[Link], [Link]>
Collections 185
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The compile-time type depends on the types of what you pass as keys and values. Gosu infers the type of the map to
be the least upper bound of the components of the map. If you are consistent in the type of your keys and the types
of your values, the compile-time type of the map is HashMap<KEY_TYPE, VALUE_TYPE>.
If you pass different types of objects to either the keys or the values, Gosu finds the most specific type that includes
all of the items that you pass. Gosu finds a common ancestor class that all the objects support. If the types
implement interfaces, Gosu attempts to preserve commonality of interface support in the map type. This behavior
ensures that your map and its elements act as expected with APIs that rely on support for interfaces. In some cases,
the resulting type at compile time is a compound type. A compound type, which combines zero or one classes and
one or more interfaces into a single type. The purpose is for you to be able to use that list and its elements with APIs
that require the interface as the argument type. At run-time, the type of the initialized map is HashMap<Object,
Object>.
See also
• “Creating a list” on page 183
• “Generics” on page 221
var strs = new HashMap<String, String>(){"aKey" -> "aValue", "bKey" -> "bValue"}
[Link]("cKey", "cValue")
var valueForCKey = [Link]("cKey")
You can write this code in the more natural index syntax using Gosu shortcuts:
var strs = new HashMap<String, String>(){"aKey" -> "aValue", "bKey" -> "bValue"}
strs["cKey"] = "cValue"
var valueForCKey = strs["cKey"]
var strMap = new HashMap<String, String>(){"aKey" -> "aValue", "bKey" -> "bValue"}
[Link]( \ key, value -> print("key : " + key + ", value : " + value ) )
The AutoMap class wraps a [Link] and provides a default value for the map if the key is not present. When
you create an AutoMap object, you pass a Gosu block into the constructor. If some calling code calls get on the map
and its value is null, Gosu runs a mapping block that you provide. Gosu takes the return value from the block,
stores it in the map for that key, then returns the value to the original caller. All other methods delegate directly to
the wrapped map.
The simplest constructor takes only one argument, which is a Gosu block that provides a default value. The block
takes one argument, which is the key, and returns the default value to use. If you use this constructor, Gosu creates a
new instance of [Link] as its wrapped map.
Another constructor takes a map (any object whose class implements [Link]) as the first argument and the
Gosu block as the second argument. Use this alternative constructor if you have an existing map that you want to
wrap rather than create a new map.
For example, the following code assigns values in a new map to entries that do not have values in the original map:
apple
I want 2 blueberries
I want 3 blueberries
orange
I want 5 blueberries
3
3
5
4
Collections 187
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Suppose you have an array of Book objects, each of which has a String property Name. You could use array
expansion to extract the Name property from each item in the array. Array expansion creates a new array containing
just the Name properties of all books in the array.
If a variable named myArrayOfBooks holds your array, use the following code to extract the Name properties:
The nameArray variable contains an array whose length is exactly the same as the length of myArrayofBooks. The
first item is the value myArrayofBooks[0].Name, the second item is the value of myArrayofBooks[1].Name, and so
on.
Suppose you wanted to get a list of the groups to which a user belongs so that you can display the display name
property of each group. Suppose a User object contains a MemberGroups property that returns a read-only array of
groups to which the user belongs. In this case, the Gosu syntax [Link] returns an array of Group
objects, each one of which has a DisplayName property. To get the display name property from each group, use the
following Gosu code
[Link]*.DisplayName
Because MemberGroups is an array, Gosu expands the array by the DisplayName property on the Group component
type. The result is an array of the names of all the Groups to which the user belongs. The type is String[].
The result might look like the following:
The expansion operator also applies to methods. Gosu uses the type on which the method runs to determine how to
expand the type:
• If the original object is an array, Gosu creates an expanded array.
• If the original object is a list, Gosu creates an expanded list.
The following example calls a method on the String component of the List of String objects. Gosu generates a
list of initials by extracting the first character in each String.
See also
• “Enhancements on Gosu collections and related types” on page 189
package test
class Family {
var _members : String[] as Members
}
uses [Link]
uses [Link]
print(allMembers)
Examples
The following expression produces a name for each Form attached to a policy period.
[Link]*.DisplayName
[Link]*.DisplayName
See also
• “Enhancements” on page 201
Boolean expression evaluates to true. In this way, the where method forms a new collection of elements. The
method then returns this new collection. If the where method finds no matching items, it returns null.
The following example demonstrates how to find all items that match a criterion:
The value of longerStrings is {"ab", "abc"}. The expression [Link] >= 2 is true for both of them.
The firstWhere method takes a block as a parameter. As in the case of the where method, this block takes an
element as a parameter, evaluates a Boolean expression body for the element, and returns the element in the case
that the expression evaluates to true. The firstWhere method returns the first element that the block returns. If the
firstWhere method finds no matching items, it returns null.
The following example demonstrates how to find the first item that matches a criterion:
The value of firstLongerStr is "ab" because "ab" is the first element in the list for which [Link] >= 2
evaluates to true.
The lastWhere method operates in a similar manner as the where and firstWhere methods. If the lastWhere
method finds no matching items, it returns null.
[Link]()
[Link]([Link]())
If you need a comparator for a different locale, LocaleUtil provides methods to get a comparator by language or
locale.
To retain the existing list and create a new list rather than sorting in place, use the orderBy and orderByDescending
methods.
The following line prints the contents of the collection of sorted strings:
a
ab
abc
abcd
Similarly, you can use the sortByDescending method, which sorts in the opposite order.
For both of these methods, the block must return a comparable value. Comparable values include Integer, String,
or any other values that can be compared with the greater than (>) or less than (<) operators.
By default, these methods do not use a localized sort collation order. For localized sorting, pass a comparator as a
second argument to the method.
Although using the sort method is powerful, in most cases Gosu code is more readable if you use the sortBy or
sortByDescending methods.
By default, these methods do not use a localized sort collation order. For localized sorting, pass a comparator as a
second argument to the method.
After the preceding code executes, the variable lengthsOnly is an array list, with elements 1, 1, 2, 2, 3, and 4.
The type declaration for the argument to the block uses the declaration :String. The type declaration for the object
that map method returns is more complex. The code declares that the map method returns an object that implements
the List interface, with the type declaration : List<Integer>. The code downcasts the type of the returned object
to an ArrayList, with the as key word.
Note: The downcast to ArrayList is for clarity only. By convention, the Gosu compiler assumes that
a type declaration of List<T> is a declaration of ArrayList<T>.
See also
• “Generics” on page 221
Use the each method to perform repeated actions with the elements in a collection.
You can achieve concise code by chaining the map and each methods in a single Gosu statement. Sometimes, the
conciseness of method chaining makes your code hard for others to read and interpret. In these cases, you might
instead assign the return value of the map method to a variable, and then call the each method on the variable. For
example:
Method chaining discards the new list after executing the statement that includes the map method. If you need to
access the new list returned by the map method later in your code, assign the return value to a variable.
Partitioning collections
Partitioning a collection creates a new [Link] of key/value pairs from values in a simple list. Gosu provides
the partition and partitionUniquely methods to partition collections. Each method has a single parameter that is
a Gosu block, which takes an element from the original list as the block argument. The value returned by the block
becomes the key for that element in the new map. Gosu uses type inference to statically type the Map objects that the
methods return.
The following line of code partitions the preceding list into a Map that uses the lengths of the various String values
as the keys to those value.
Because some of the values in the original list have the same lengths, the created map contains four keys and six
values, which the following example map definition illustrates:
Map { 1 -> ["a", "b"], 2 -> ["bb", "ab"], 3 -> ["abc"], 4 -> ["abcd"] }
If you partition a list with the partition method, subsequent code must handle the case where a map expression
resolves to a list instead of a single value.
The following line of code partitions the preceding list into a Map that uses the lengths of the various String values
as the keys to those value.
Because each value in the original list has a different length, the created map contains four keys and four values,
which the following example map definition illustrates:
If more than one list element has the same calculated value for its key, the partitionUniquely method throws an
exception.
uses [Link]
uses [Link]
The value of contactsById is a Map of contact PublicID values to contacts created yesterday. You can access a
contact entity instance and its properties from the map by using the public ID as the key.
Collections 193
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
joinedString = [Link](",")
[Link]<[Link]> 6 [1, 1, 2, 2, 3, 4]
[Link]<[Link]> 4 [1, 2, 3, 4]
[Link][] 6
1|1|2|2|3|4
Example
Suppose your data has the following structure:
• A claim object has an Exposures property that contains an array of exposure objects.
• An exposure has a Notes property that contains a list of Note objects.
The [Link] property is the outer collection of exposures. The [Link] properties are the inner
collections.
First, write a block that extracts the note objects from an exposure object:
\ e -> [Link]
Next, pass this block to the flatMap method to generate a single list of all notes on the claim:
194 chapter 12: Collections
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
This code generates a single list that contains all the notes on all the exposures on the claim. In generics notation, the
flatMap method returns an instance of List<Note>.
See also
• “Gosu arrays and the expansion operator” on page 67
toCollection() Returns this iterable object if the object is already of type Collection. Otherwise, copies all values out
of this Iterable into a new Collection.
Collections 195
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The following methods provide functionality to perform an action on every item in a collection.
Method Description
each() Iterates each element of the Collection.
eachWithIndex() Iterates each element of the Collection with an index.
The following methods provide functionality to get a particular element or value from a collection.
Method Description
average(selector) Returns the average of the numeric values selected from the Collection<T>.
first() Returns the first element in the Collection, or return null if the collection is empty.
firstWhere(cond) Returns the first element in the Collection that satisfies the condition, or returns null if none do.
last() Returns the last element in the Collection or return null if the list is empty.
lastWhere(cond) Returns the last element in the Collection that matches the given condition, or null if no elements
match it.
max() Returns the maximum of the selected values from Collection<T>. This method excludes any null values
in the collection. If there are no non‐null values, this method throws an exception.
maxBy(proj) Returns the maximum T of the Collection based on the projection to a Comparable object.
min() Returns the minimum of the selected values from Collection<T>. This method excludes any null values
in the collection. If there are no non‐null values, this method throws an exception.
minBy(proj) Returns the minimum T of the Collection based on the projection to a Comparable object.
singleWhere(cond) If there is only one element in the Collection that matches the given condition, returns that value.
Otherwise, throws an IllegalStateException.
sum(proj) Returns the sum of the numeric values selected from the Collection<T>.
Method Description
orderBy(proj) Returns a new List<T> ordered by a block that you provide. This method is different from
sortBy, which is retained on List<T> and which sorts in place.
orderByDescending(proj) Returns a new List<T> reverse ordered by the given value. This method is different from
sortByDescending, which is retained on List<T> and which sorts in place.
Method Description
removeWhere(cond) Removes all elements that satisfy the given criteria.
retainWhere(cond) Removes all elements that do not satisfy the given criteria. This method returns no value, so it cannot be
chained in series. This is to make clear that the mutation is happening in place, rather than a new collec‐
tion created with offending elements removed.
Method Description
where(cond) Returns all elements in this Iterable that satisfy the given condition.
whereTypeIs(Type) Returns a new List<T> of all elements that are of the given type.
The following methods provide functionality to convert the collection to another class or format.
Method Description
asIterable() Returns this Collection<T> as a pure Iterable<T>, not as a List<T>).
flatMap(proj) Maps each element of the Collection to a Collection of values and then flattens them into a
single List.
fold() Accumulates the values of an Collection<T> into a single T.
join() Joins all elements together as a string with a delimiter.
map(proj) Returns a List of each element of the Collection<T> mapped to a new value.
partition(proj) Partitions this Collection into a Map of keys to a list of elements in this Collection.
partitionUniquely(proj) Partitions this Collection into a Map of keys to elements in this Collection. Throws an
IllegalStateException if more than one element maps to the same key.
reduce(init, reducer) Accumulates the values of a Collection<T> into a single V given an initial seed value.
toList() If this Collection is already a list, returns the same Collection. Otherwise creates a new List
and copies this Collection to it.
toSet() Converts the Collection to a Set.
toTypedArray() Converts this Collection<T> into an array T[].
Method Description
disjunction(coll) Returns a new Set<T> that is the set disjunction of this collection and the other collection.
intersect(iter) Returns a Set<T> that is the intersection of the two collection objects.
subtract(coll) Returns a new Set<T> that is the set subtraction of the other collection from this collection.
union(coll) Returns a new Set<T> that is the union of the two collections.
Method Description
copy() Creates a copy of the list.
freeze() Returns a new unmodifiable version of the list.
reverse() Reverses the Iterable.
shuffle() Shuffles the list in place.
sort() Sorts the list in place, with optional support for localized sorting. By default, this method does not use
a localized sort collation order. For localized sorting, pass a comparator as a second argument to the
method.
Collections 197
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Method Description
sortBy(proj) Sorts the list in place but instead of comparing the items directly like sort does, uses a block that re‐
turns the item to compare. By default, this method does not use a localized sort collation order. For
localized sorting, pass a comparator as a second argument to the method.
sortByDescending() Same as sortBy, but sorts the list in place in descending order.
sortDescending() Same as sort, but sorts the list in place in descending order.
The following methods provide functionality to perform an action on every item in a map.
Method Description
eachKey(block) Runs a block for every key in the map. The block must take one argument (the key) and return no
value.
eachKeyAndValue(block) Runs a block for every key‐value pair in the map. The block must take two arguments: a key and a
value. The block must return no value.
eachValue(block) Runs a block for every value in the map. The block must take one argument (the value) and return
no value.
The following methods provide functionality to filter and remap a map. The methods that have retain in the name
are destructive. The methods with filter in the name create a new map and do not modify the original map.
Method Description
filterByKeys(keyFilter) Returns a new map that is a clone of the original map but without entries whose keys do
not satisfy the keyFilter expression. The key filter block must take one argument (a
key) and return true or false.
filterByValues(valueFilter) Returns a new map that is a clone of the original map but without entries whose values
do not satisfy the valueFilter expression. The key filter block must take one argument
(a value) and return true or false.
mapValues(mapperBlock) Returns a new map that contains the same keys as the original map but different values
based on a block that you provide. The block must take one argument (the original val‐
ue) and return a new value based on that value. The values can have an entirely differ‐
ent type.
Method Description
Gosu infers the return type of the block based on what you return and creates the ap‐
propriate type of map. For example, the following Gosu takes a Map<Integer,String>
and maps it to a new object of type Map<Integer,Integer>:
retainWhereKeys(keyFilter) Destructively removes all entries whose keys do not satisfy the keyFilter expression.
Returns true if and only if this map changed as a result of the block. The key filter block
must take one argument (a key) and return true or false.
retainWhereValues(valueFilter) Destructively removes all entries whose values do not satisfy the valueFilter expres‐
sion. Return true if this map changed as a result of the call. The value filter block must
take one argument (a value) and return true or false.
The following methods provide functionality to use properties files for a map.
Method Description
readFromPropertiesFile(file) Reads the contents of this map from a file in the Java properties format using APIs on
[Link]. The method takes a [Link] object and returns a map
of the keys and values. The return type is Map<String,String>.
writeToPropertiesFile(file) Writes the contents of this map to a file in the Java properties format using APIs on
writeToPropertiesFile(file, [Link]. The method takes a [Link] object and returns noth‐
comments) ing. The second method signature takes a String object to write comments in the
properties file.
Method Description
copy() Creates a copy of the set
freeze() Returns a new unmodifiable version of the set
powerSet() Returns the power set of the set
See also
• “Enhancements” on page 201
• “Generics” on page 221
• “Sorting lists or other comparable collections” on page 190
• “Wrapped maps with default values” on page 186
• “Flat mapping a series of collections or arrays” on page 194
Collections 199
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Enhancements
Gosu enhancements allow you to augment classes and other types with additional concrete methods and properties.
For example, use enhancements to define additional utility methods on a class or interface that cannot be directly
modified, even code written in Java. You can enhance Guidewire entity instances and classes originally written in
Gosu or Java.
Enhancements differ from subclasses in important ways. Enhancement methods and properties on a class are
available to all objects of the enhanced class. Methods and enhancements on subclass are available only to objects of
the subtype, not to objects of the superclass. Use enhancements to add powerful functionality omitted by the original
authors.
Using enhancements
Gosu enhancements allow you to augment classes and other types with additional concrete methods and properties.
The most valuable use of this feature is to define additional utility methods on a Java class or interface that cannot
be directly modified. This feature is most useful if the source code for a class is unavailable or class is marked final
and so cannot be subclassed. Enhancements can be applied to interfaces as well as classes, which enables you to add
useful methods to interfaces.
Enhancing a class or other type is different from subclassing: enhancing a class makes the new methods and
properties available to all instances of that class, not merely subclass instances. For example, if you add an
enhancement method to the String class, all String instances in Gosu automatically have the additional method.
You can also use enhancements to overcome the language shortcomings of Java or other languages defining a class
or interface. For example, Java-based classes and interfaces can be used from Gosu, but they do not natively allow
use of blocks, which are anonymous functions defined in-line within another function. Gosu includes many built-in
enhancements to commonly used Java classes in its products so that any Gosu code can use them.
For example, Gosu extends the Java class [Link] so you can use concise Gosu syntax to sort, find,
and map members of a list. These list enhancements provide additional methods to Java lists that take Gosu blocks
as parameters. The original Java class does not support blocks because the Java language does not support blocks.
However, these enhancements add utilities without direct modifications to the class. Gosu makes these additional
methods automatically and universally available for all places where Gosu code uses [Link].
You can also enhance an interface. An enhancement does not add new methods to the interface itself, nor add new
requirements for classes that implement the interface. Instead, enhancing an interface provides all objects whose
class implements the interface with new methods and properties. For example, if you enhance the
[Link] interface with a new method, all collection types have your newly added method.
Although you can add custom properties to existing entities, any new properties that you add do not appear in the
generated Data Dictionary documentation that describes the application data model.
Enhancements 201
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Blocks” on page 175
• “Collections” on page 183
You could even use the method on a value you provide at compile time:
"a string".calculateHash()
Similarly, if the enhancement adds a property called MyProperty to the String type, you could use code such as:
The new methods and properties all appear in the list of methods that appears if you type a period (.) character in the
Gosu editor. For example, suppose you are typing “[Link]()”. In typing this statement, after you type
“s1.”, the list that appears displays the calculateHash method as a choice.
package example
Note the use of the syntax property get for the method defined as a property.
With this example, use code like the following to get values:
"length: 17"
"Secret message!"
Enhanced methods can call other methods internally, as demonstrated with the getPrettyLengthString method,
which calls the built-in String method length().
Enhancements 203
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
IMPORTANT Enhancements can create new methods but cannot override existing methods.
package example
uses [Link]
print(strlist)
[Link] = "hello"
print(strlist)
You can add new properties and add property set functions to set those properties. However, in contrast to a class,
enhancements cannot define new variables on the type to store instance data for your enhancement. This limits most
types of state management if you cannot directly change the source code for the enhanced type to add more variables
to the enhanced type. Enhancements cannot add new variables because different types have dramatically different
property storage techniques, such as a persistent database storage, Gosu memory storage, or file-based storage.
Enhancements cannot transparently mirror these storage mechanisms.
Also, although enhancements can add properties, enhancements cannot override existing properties.
IMPORTANT Enhancements can add new properties by adding new dynamic property get and set
functions to the type. However, enhancements cannot override property get or set functions. Also,
enhancements cannot create new native variables on the object that would require additional data
storage with the original object. Enhancements cannot override methods either.
[EnhancedTypeName][OptionalFunctionalDescripton]Enhancement
For example, to enhance the Report class, you could call your enhancement:
ReportEnhancement
If the enhancement adds methods related to financials data, you can the enhancement’s functional purpose by
naming the enhancement:
ReportFinancialsEnhancement
Enhancement packages
Use your own company package to hierarchically group your own code and separate it from built-in types, in almost
all cases. For example, you could define your enhancement with the fully qualified name
[Link]. Even if you are enhancing a built-in type, if at all possible use your own
package for the enhancement class itself.
In extremely rare cases, you might need to enhance a built-in type and to use a protected property or method. If so,
you might need to define your enhancement in a subpackage of the enhanced type. However, to avoid namespace
conflicts with built-in types, avoid this approach if possible.
See also
• “Modifiers” on page 157
• “Naming conventions for packages and types” on page 150
Enhancements on arrays
To specify the enhanced type for an enhancement on an array type:
• For regular types, use standard array syntax, such as String[].
• For generic types, use the syntax T[], which means all arrays.
Enhancements 205
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Annotations
Gosu annotations are a syntax to provide metadata about a Gosu class, constructor, method, property, field, or
parameter. An annotation can control the behavior of the type, the documentation for the type, or the behavior of the
code editor.
@Deprecated
class MyServiceAPI {
public function myRemoteMethod() {}
}
You can use both annotations that are defined natively in Gosu and also Java annotations.
In your annotation usage, you can use either the fully qualified name of the annotation class or just the name. If you
do not use the fully qualified name, add a uses line for that annotation class at the top of the file. For example, the
following line shows the uses line for the @Deprecated annotation:
uses [Link]
In some cases, you follow the annotation name with an argument list within parentheses. The following example
uses arguments to the annotation to specify that a function might throw a specific exception:
class MyClass{
Annotations 209
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The annotation may not require any arguments, or the arguments may be optional. If you do not provide arguments
to an annotation, you can omit the parentheses. For example, suppose you add an annotation called MyAnnotation
that takes no arguments. You could use MyAnnotation in the following, verbose syntax:
@MyAnnotation()
Because there are no arguments, you can optionally omit the parentheses:
@MyAnnotation
Gosu requires argument lists to be in the same format as regular function or method argument lists:
Gosu annotations optionally support the named arguments calling convention, which includes a colon before the
argument name, and commas between arguments:
See also
• “Named arguments and argument defaults” on page 112
• “Importing types and package namespaces” on page 114
package test
uses [Link]
uses [Link]
uses [Link]
class TestABC {
The Gosu compiler permits argument annotations. However, Gosu does not support special compiler or IDE
behavior for Java 8 Type annotations such as @m, @Nonnull, @ReadOnly, @Regex, @Tainted, and @Untainted.
See also
• “Importing types and package namespaces” on page 114
Built‐in annotations
The Gosu language includes built-in annotations defined in the [Link].* package. This package is always in
scope, so the fully qualified annotation name is not required.
The following table lists the built-in general annotations:
210 chapter 14: Annotations
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Internal annotations
Some Gosu annotations are reserved for internal use. You may see internal annotations in built-in Gosu code. These
annotations are not supported for your use. The following table lists these internal annotations so that you
understand their role in built-in classes.
Examples
The following code uses several built-in annotations:
Annotations 211
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
package [Link]
uses [Link]
@WsiWebService
class Test {
@Param("Name", "The user's name. Must not be an empty string.")
@Returns("A friendly greeting with the user's name")
@Throws(Exception, "General exception if the string passed to us is empty or null")
public function FriendlyGreeting(Name : String) : String {
The following example specifies that a method is deprecated. A deprecated API component is temporarily available,
but a future release will remove that component. Immediately start to refactor code that uses deprecated APIs. This
refactoring ensures that your code is compatible with future releases. Following this advice simplifies future
upgrades.
package example
class MyClass {
The annotation class that you are implicitly using must be in the current Gosu scope. You can ensure that it is in
scope by fully qualifying the annotation. For example, if the SomeAnnotation annotation is defined within the
package [Link], specify the annotation as:
@[Link]
class SomeClass {
...
}
Alternatively, import the package using the Gosu uses statement and then use the annotation more naturally and
concisely by using only its name:
uses [Link].*
@SomeAnnotation
class SomeClass {
...
}
See also
• Integration Guide
For a list of multiple annotation instances of one type, call the getAnnotationsOfType of the type.
To get an annotation from targets such as constructors, methods, or properties, call the getAnnotation method on
the item, not on the type itself. The following table shows how to get an annotation from each target type. In the
examples in the table, the variable i represents the index in the list. In practice, you would probably search for the
required target by name using List methods like [Link](\ s -> [Link] = "MethodName").
Get annotations on this object Example Gosu to access the example @MyAnnotation annotation
Type (typeof obj).[Link](MyAnnotation)
The return result of these methods is typed as a list of the expected type. Using the examples in the previous table,
the result is of type List<MyAnnotation>. This type is shown using generics syntax, which means “a list of
instances of the MyAnnotation annotation class”.
See also
• “Getting annotations at run time” on page 212
• “Generics” on page 221
5. Cast the result to the desired annotation type using the as keyword. For example, suppose the result of the
previous step is a variable called res and your annotation is called @MyAnnotation. Use the syntax:
as MyAnnotation.
6. From the result, get the data from the annotation instance with any annotation arguments defined as methods.
For example, if an annotation has constructor arguments purpose and importance, get those values using
methods purpose and importance.
Example
The classes [Link] and [Link] demonstrate the prior steps:
package example
annotation MyAnnotation {
function purpose() : String
function importance() : int = 0
}
package example
uses [Link]
uses [Link]
package example
annotation MyAnnotation {
function purpose() : String
function importance() : int = 0
}
package example
By default, this annotation can be used on any method, type, property, or constructor, and as many times as
necessary.
See also
• “Getting annotations at run time” on page 212
package example
uses [Link]
uses [Link]
Annotations 215
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
uses [Link]
@Retention( RUNTIME)
annotation MyAnnotation {
function purpose() : String
function importance() : int = 0
}
Dimensions
Dimensions represent a quantifiable amount that can be measured in one or more units.
Dimensions overview
Dimensions represent a quantifiable amount that can be measured in one or more units. Dimensions can include any
measurable physical or abstract dimension, for example:
• Length, such as 1 mm
• Time, such as 1 day or 1 year
• Weight, such as 1 kg
• Money, such as 1 US Dollar
• Amount of computer storage space, such as 1 GB
Dimensions can reference complex combinations of dimensions. Speed can be represented by a unit that combines
distance and time, such as 60 miles per hour. Acceleration can be represented as speed per time unit, such as 1 meter
per second per second.
Each Gosu dimension is represented by a class that implements the interface [Link]. You create
custom dimensions by implementing the IDimension interface. In your class declaration, parameterize the interface
as follows:
Replace YOURCLASSNAME with your class name. Replace UNITNAME with a unit. The unit type might be a built-in
numeric type like int or BigDecimal, but could also be any arbitrary type including custom types.
The default syntax for creating a dimension object is the standard new operator with constructor arguments. A
typical dimension class uses at least one numeric constructor argument and optionally a unit type if the context
requires the unit type. For example, a new monetary amount object representing 3 US Dollars might require a
numeric value (3) and the unit (US Dollars):
Create as many constructors as typical usage of your custom dimension type requires.
Gosu natively supports basic arithmetic functions on dimensions as part of the IDimension interface. The Gosu
parser looks for special methods for each operator and checks the argument types to see what types of operations are
supported. For example, a Velocity dimension can define a multiply method that takes a Time argument and
returns a Length dimension. Gosu uses this information to let you use the * operator to multiply a Velocity and
Time dimension, which generates a Length object:
Dimensions 217
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
// Multiple Velocity and Time to get a Length object representing 150 miles
var distance = velocity * time
The following methods implement arithmetic on a custom dimension. The argument must be the type of the object
on the right hand side of the arithmetic operator. The return type can be any type.
• add – Addition using the + operator
• subtract – Subtraction using the - operator
• multiply – Multiplication using the * operator
• division – Division using the / operator
• modulo – Modulo (remainder after division) using the % operator
Additionally, you can support the unary negation operator (-) by implementing the negate method, which takes no
arguments.
package example
uses [Link]
/* REQUIRED BY IDimension */
construct( p : BigDecimal) {
_points = p
}
construct() {
_points = 0 // If used with a no argument constructor, just set points to 0
}
/* REQUIRED BY Comparable */
override function compareTo(o: Score): int {
return (_points.compareTo([Link]))
}
/* Improve printing... */
public function toString() : String {
return "Score is " + _points + " points"
}
// ADDITIONAL conversions
Consider the following code that you can run in the Gosu Scratchpad:
uses [Link]
x = x + addme
y = y + addme + addme
print ("x = " + x + " ..... y = " + y)
var z = x * [Link]
print ("z = " + z )
Built‐in dimensions
The built-in dimensions are as follows:
• [Link]
• [Link]
Both classes have a numeric component and a currency from the Currency typelist. For example, you can instantiate
each of them as follows:
Dimensions 219
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Generics
Generics is a language feature that you use to define a class or function that applies to many types by abstracting its
behavior across multiple types of objects. Gosu generics work in a very similar manner to generics in Java.
You use generics to write statically typed code that can be abstracted to work with multiple types. By designing an
API to apply to different types of objects, you write the code only once, and the code supports those different types.
In this way, you can generalize classes or methods to work with multiple types and retain compile-time type safety.
Generics make the relationships explicit between the types of parameters and return values of a function. Generics
are especially useful if any of the parameters or return value are collections. For example, you can require two
arguments to a function to be homogeneous collections of the same type of object, and that the function returns the
same type of collection. Designing functions to be abstract in that way enables your code and the Gosu language to
infer other relationships. For example, a function that returns the first item in a collection of String objects is
always typed as a String. You do not need to write coercion code with the syntax as TYPE with functions that use
generics. Because generics increase how often Gosu can use type inference, your collection-related code can be
readable, concise, and type-safe.
See also
• “More about the Gosu type system” on page 38
Generics 221
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Note: In practice, you sometimes do not need to define the type because of type inference or special
object constructors. For example, var myStrs = { "a", "ab", "abc"} is equivalent to var myStrs
= new ArrayList<String>() { "a", "ab", "abc"}.
You can create a method that parameterizes an argument as a specific type of list, in this case a list of strings. This
argument has an explicit type and does not use generics to support multiple types of array list. The code in the
method uses methods that are specific to the String type, so does not support other list types.
To call a method that uses a parameterized argument type, call the method in the usual way:
printStrings( myStrs )
A compile-time error occurs if you use an argument that does not match the parameterized specification on a method
that uses Gosu generics to specify the argument type:
Parameterizing collections and other containers is a typical use of generics, but Gosu does not limit generics support
to only container types. You can define any class to use Gosu generics to generalize what the class supports or how
the class works with various types.
Gosu provides two ways to use generic types:
• You can parameterize a class, which adds generic types to a class definition.
• You can parameterize a method, which adds generic types to a method definition.
class MyTester {
// Return a map from two lists
// This signature returns a Java object that has its type erased
public reified function mapArray<K,V>(kArray : ArrayList<K>, vArray : ArrayList<V>) : HashMap<K,V> {
In the mapArray method, the symbols K and V are used as types and Gosu matches K and V to the types of the
collections passed into the method.
Code can use this class:
Comment out the method signature in the MyTester class that returns a HashMap object and uncomment the
signature that returns a MyMapper object. In the code that uses the MyTester class, the variable myMap is now typed
as MyMapper<[Link], [Link]>.
See also
• “Restricting generics” on page 226
Parameterizing a class
To specify a class that operates with a generic type, define the class with the angle bracket notation
CLASSNAME<GENERIC_TYPE_WILDCARD>. By convention, for GENERIC_TYPE_WILDCARD, use a one-letter name,
preferably T. For example, you could define a class MyClass as MyClass<T>.
In the following example, the class Genericstest has one method that returns the first item in a list. Gosu strongly
types the return value to match the type of the items in the collection:
class GenericsTest<T> {
// Print out (for debugging) and then return the first item in the list, strongly typed
public function printAndReturnFirst(aList : ArrayList<T>) : T {
print(aList[0])
return aList[0]
}
}
Other code can use this class and pass an array list of any type to the method:
The variable first is strongly typed as String at compile time because the code uses a method that was defined
with generics.
Because the code is strongly typed at compile time, the reliability of the code improves at run time.
Generics 223
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
• For an enhancement that applies to a specific type on the generic class, you specify the type only on the class
name. For example, the declaration of an enhancement to the String type of the GenericsTest class looks like
the following line.
See also
• “Enhancements” on page 201
Parameterizing a method
You can add a finer granularity of type usage by adding generic type modifiers to a method, immediately after the
method name. In Gosu, this syntax of adding the generic type modifiers is called parameterizing the method. In
other languages, this syntax of adding the generic type modifiers is known as making a polymorphic method with a
generic type.
If the parameterized method needs information about the runtime type of the type parameter, you must add the
modifier reified to the method declaration. Some parameterized methods do not require information about the
runtime type of the type parameter. For these methods, the modifier reified is optional.
For example, in the following code, the class is not parameterized but one method is parameterized and does not
require information about the type of T at run time:
class GenericTypesTester<T> {
// Return whether the argument is a String
public function isStringType<T>(t : T) : boolean {
// public reified function isStringType<T>(t : T) : boolean { // This declaration is also valid
return t typeis String
}
}
In the method’s Gosu code, the symbol T can be used as a type and Gosu matches T to the type of the argument
passed into the method.
The following code uses this class and the parameterized method:
type erasure. Use the modifier reified on a parameterized function that has any of the following characteristics,
where T is the token for the type parameter of a generic type:
• The method uses the new keyword to create an instance of T.
• The method uses the new keyword to create an instance of a generic type and includes the <T> qualifier on the
type name.
• An expression in the method uses the generic type with the typeis or typeof operator.
• The method contains code that uses as T to cast a value to the generic type.
• The method overrides a reified method in a parent class or implements a reified method in an interface.
• The method calls another reified method and passes an argument of a generic type to that method.
The modifier reified is optional on a parameterized method that does not have any of these characteristics.
Gosu forbids the modifier reified on methods that are not generic.
For a function that requires this modifier, the signature looks like the following examples:
Although some parameterized functions do not require the reified keyword, good practice is to make such
methods reified. Using the reified keyword prevents error conditions if future changes to the code in the method or
code that overrides the method cause reification of the parameterized type.
// reified is optional because the code populates the ArrayList with an existing object
function oneListFromE<E>(e : E) : List<E> {
return new ArrayList<E>({e})
}
// reified is required because the code creates a new object of type E to populate the ArrayList
reified function oneListE<E>() : List<E> {
return new ArrayList<E>({new E()})
}
class BasicReificationTester {
public reified function returnAsT<T>(a : ArrayList<T>) : T {
return this as T
}
}
In the method’s Gosu code, the symbol T is used as a type. Gosu matches T to the type of the collection passed into
the method.
The following code uses this class and the reified method:
Generics 225
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Example: Parameterized method that does not require the reified keyword
The following method is parameterized but does not require reification, so the reified keyword is optional:
If future code changes to the code in this method or code that overrides this method cause reification to be necessary,
the methods would not compile. Good practice is to use the reified keyword.
Example: Another parameterized method that does not require the reified keyword
In the following example, the class Genericstest is parameterized:
class GenericsTest<T> {
// Print out (for debugging) and then return the first item in the list, strongly typed
public function printAndReturnFirst(aList : ArrayList<T>) : T {
print(aList[0])
return aList[0]
}
}
The following method is parameterized but does not require reification, so the reified keyword is optional:
Because the code does not specify the type of GenericsTest, Gosu uses the the lowest possible bound of
GenericsTest for the type of the variable x, which is Object.
If future modifications to the code in this method or code that overrides this method cause reification to be
necessary, the methods would not compile. Good practice is to use the reified keyword.
Restricting generics
You can use restrictions on generics to define a parameter that supports a specific set of types. For example, you
might want to support homogeneous collections or only instances of a class and its subclasses or subinterfaces. A
homogeneous collection is one in which all items are of the same type.
226 chapter 16: Generics
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Consider a custom class Shape. You might need a method to support collections of circle shapes or collections of
line shapes, where both Circle and Line classes extend the Shape class. For this example, assume the collections
are always homogeneous and never contain a mix of both types. You might attempt to define a method like this:
The method accepts an argument of only type ArrayList<Shape>. Your code would not compile if you tried to pass
an ArrayList<Circle> to the method, even though Circle is a subclass of Shape.
You can specify support of multiple types but limit support to certain types and types that extend those types. Use
the syntax “extends TYPE” after the wildcard character. In Java, this restriction is known as bounded generics.
For example:
A valid argument for the parameter shapeArray is an ArrayList containing objects that are all of the same type,
and that type extends the Shape class.
Example: Generic class using a restricted bound for its type parameter
The following class restricts the generic type to types that extend Number:
• Specifying the type of the type parameter creates a strongly typed object that uses the explicit type. For example,
in the following line of code, the type of the variable x is BoundedGenericsTest<Integer>:
• Omitting the type parameter creates a strongly typed object that uses the least restrictive type of the bound. For
example, in the following line of code, the type of the variable x is BoundedGenericsTest<Number>:
You can include this instantiation of BoundedGenericsTest in a parameterized method without using the
reified keyword because Gosu substitutes the least restrictive type of the specified bound for the type
parameter.
Generics 227
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
class GenericsTest<T>
For an enhancement that applies to a restricted set of type on the generic class, you specify the restrictions on the
enhancement name and the type wildcard on the class name. For example, the declaration of an enhancement to
types that extend CharSequence types of the GenericsTest class looks like the following line:
See also
• “Enhancements” on page 201
In the definition of the enhancement, the method, and the block parameter, the symbol T is treated as the type of the
collection. Note the use of the letter T in the block signature:
value(elt : T):Comparable
That signature specifies that the block parameter takes one argument of type T and returns a Comparable value, such
as an Integer or String.
Consider the following array list of strings:
You can re-sort the list based on the length of the strings by using a block. Create a block that takes a String
parameter and returns the sort key, in this case the text length. The [Link](...) method implements the
sorting algorithm to sort the original list in place, and does not return an entirely new list.
228 chapter 16: Generics
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The following example uses the sortBy method to sort a list of String objects by the length of the String, and then
prints the sorted list values.
a
ab
abc
abcd
Using generics for type inference in cases like this example produces readable and concise Gosu code.
This example omitted the types of the block argument str and the sort key. You do not have to specify these types
explicitly. Although the following code is valid, Gosu uses type inference to determine the types.
See also
• “Blocks” on page 175
• “Collections” on page 183
The parameter theMap has type Map. Gosu generics uses two type wildcards as single capital letters separated by
commas to parameterize the types in the map. By convention, the first wildcard (K) represents the type of the key
and the second wildcard (V) represents the type of the value. Because the method signature uses the V again in the
return value type, the Gosu compiler makes assumptions about relationships between the type of map and the return
value. The two uses of V in the method signature specify the same type for both the map value in the parameter and
the return value.
At run time, the symbols K and V are assigned to specific types. The code that calls the method creates new instances
of the parameterized class with specific types. The compiler can determine which method to call and the types that K
and V represent.
A specific type of map that has keys of type Long and values of type String has a definition like the following line
of code.
If you pass the variable contacts to this getHighestValue method, the compiler knows that this call to the method
returns a String value.
You can also define a class that uses multiple dimensions of types. For example, to work with key-value maps, you
can use generics to define a class:
Generics 229
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
class Mymapping<K,V> {
public function put( key : K, value : V) {...}
public function get( key : K) : V {...}
}
In the method definitions, the values in angle brackets have the same meanings as the type names in the
parameterized class definition. In this example, the K and V symbols specify the types. Use these symbols in method
signatures in the class to represent types in arguments, return values, and Gosu code inside the method. You can use
this class to provide strongly typed results.
In the following example, the concrete types are String for K and Integer for V.
Abstract example
Suppose you want to need to store key-value maps. You can define a class that uses the Object class to define two
types of object:
class Mymapping {
function put( key : Object, value : Object) {...}
function get( key : Object) : Object {...}
}
class Mymapping<K,V> {
function put( key : K, value : V) {...}
function get( key : K) : V {...}
}
This class enforces strongly typed values at compile time. In the following code, the theValue variable is strongly
typed at compile time as Integer.
Real‐world example
Consider a program that tracks the construction of vehicles within multiple factories. You can represent cars with
Car objects, trucks with Truck objects, and vans with Van objects. All these classes derive from a root class
Vehicle.
Your program uses custom container object of type FactoryGroup that does not derive from the built-in collection
classes. For this example, assume that each factory only contains one type of vehicle. A FactoryGroup can contain
multiple Car objects, or multiple Truck objects, or multiple Van objects.
230 chapter 16: Generics
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
By using generics, the method supports all types of FactoryGroup objects. Because the letter T appears more than
once in the method signature, this syntax defines relationships between the parameter and the return value. The
method getLastStepVehicles takes one argument that is a factory group containing any one vehicle type. The
method returns another factory group that is guaranteed to contain the same type of vehicle.
Alternatively, you could define your API with bounded wild cards for the type:
By using this approach, your code can make more assumptions about the type of object in the factory group. This
approach also prevents some coding errors, such as accidentally passing FactoryGroup<String> or
FactoryGroup<Integer>, which fail at compile time. You can discover your coding errors quickly.
To use this approach, you must use Gosu syntax to inform the compiler that your class is a container class that
supports generics. Add the bracket notation in the definition of the class, and use a capital letter to represent the type
of the class. For example, a standard class definition is:
The definition of a class as a container class supporting generics uses the syntax:
Generics 231
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Gosu supports dynamic language features that permit coding styles similar to non-statically typed languages. The
[Link] type allows dynamic assignment as well as dynamic dispatch of property access and method
invocation. Gosu also provides support for expando objects, which simplify dynamic property and method access for
typical code contexts.
Note that these two features are separate from structural types. Structural types are similar to interfaces but can be
used with objects with no shared ancestry or interfaces.
See also
• “Structural types” on page 241
Dynamic type
In a variable declaration or function parameter, you can declare the type as the type Dynamic. The Dynamic type
permits any type of object to be assigned to that variable. The fully qualified name is [Link]. At first
Dynamic types and expando objects 233
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
glance, this might be similar to using the Object type, which is the base class of all reference types. However, there
are important differences.
By declaring the Dynamic type for the variable or function argument, you can programmatically access any property
or method without requiring compile-time confirmation of its existence. For example, get the Name or Age property
from an object even if it does not exist at compile time. In contrast, if you use the Object type, the Gosu compiler
validates any property or method on the Object class itself, which does not have many properties or methods.
On its own, the dynamic feature can be used for dynamic programming styles where property names and method
names may not be known at compile type. To dynamically get properties, set properties, and invoke methods, you
can optionally implement special methods on the target class directly on the declaring class or with a Gosu
enhancement.
WARNING Use dynamic language features judiciously because misuse can hide errors that the
Gosu editor cannot catch at compile type. For example, if you misspell a property or method
name, there is no compiler error but run time errors can occur.
The following table lists the special methods you may implement on classes who objects are accessed by variables
declared with the [Link] type. In the following table, the term UNHANDLED refers to value
[Link].
$setMissingProperty Similar to $setProperty, but Gosu only calls this method if the type does not explicitly declare the
property.
Gosu calls this method if some code sets a property and either of the following is true:
• The $setProperty method is absent and the property is not defined explicitly on the class
• The $setProperty method exists and it returned UNHANDLED.
$invokeMethod Invokes a method by its name specified as an argument, with the parameter list in the second ar‐
gument as an array of Object instances. If the method is unknown or the arguments have the
wrong number or types, return the value UNHANDLED. If you return UNHANDLED, Gosu calls the
$invokeMissingMethod method, which must exist or Gosu throws an exception.
$invokeMissingMethod Similar to $invokeMethod, but Gosu only calls this method if the type does not explicitly declare
the method.
Gosu calls this method if some code invokes a method and either of the following is true:
• The $invokeMethod method is absent and the method with matching argument number and
types is not defined explicitly on the class
• The $invokeMethod method exists and it returned UNHANDLED.
The following example defines a simple object with a dynamic property getter method. In the example, the
$getProperty method handles two property names explicitly, and then returns UNHANDLED for any other property
names. Note that for the unhandled property name, Gosu automatically calls the $getMissingProperty method.
In real-world code, the $getProperty method might get the value from a [Link], from a related subobject,
from a calculation, or even from an external system:
234 chapter 17: Dynamic types and expando objects
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
package [Link]
uses [Link]
uses [Link]
class DynamicGetter {
if (fieldName == "StreetAddress") {
return "123 Main Street"
} else if (fieldName == "FirstName") {
return "John"
} else {
return [Link]
}
}
The following code uses the dynamic object and gets a property from it:
uses [Link]
uses [Link]
print("---")
print("Dynamically get a known property...")
print("RESULT = " + [Link])
print("---")
print("Dynamically get a missing property...")
print("RESULT = " + [Link])
---
Dynamically get a known property...
$getProperty called with field: StreetAddress
RESULT = 123 Main Street
---
Dynamically get a missing property...
$getProperty called with field: OtherField
$getMissingProperty called with field: OtherField
RESULT = fakeValue
The dynamic type works well with the IExpando interface and Expando objects. Use these objects together to create
dynamic property getters and setters and store data in a [Link] object.
See also
• “Expando objects” on page 235
• “Structural types” on page 241
• “Enhancements” on page 201
Expando objects
An expando object is an object whose properties, and potentially methods, are created dynamically on assignment.
Most dynamic languages provide what are called expando objects. For object oriented programming, some
Dynamic types and expando objects 235
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
languages provide only expando objects. An expando object behaves a lot like a map, in that you associate named
keys with values. In contrast to a map, with expando objects the keys appear as natural properties directly on the
object.
IExpando interface
To enable dynamic programming with a map-based implementation, Gosu provides the IExpando interface, which
contains the following method and property declarations. Any class that implements this interface can behave as an
expando object in the context of a variable declared as the Dynamic type.
The base configuration provides the Expando class, which is an implementation of this interface.
Invoke method
The invoke method invokes a method with zero, one, or more arguments passed as an array.
The setDefaultFieldValue method sets a field default value. Gosu calls this method in certain cases where Gosu
code tries to get an uninitialized field value. The only situation where Gosu calls the method is during automatic
creation of intermediary objects in an object path. For example:
In this example, note the middle line. Because the [Link] property does not exist yet, and it is necessary to set the
[Link] property, Gosu creates the intermediate object. During this automatic creation process, Gosu calls the
setDefaultFieldValue to create the default value for abc. In the built-in Expando implementation, this method
always creates another instance of the Expando class.
See also
• “Expando objects” on page 235
• “The Expando class” on page 236
• “Property assignment triggering instantiation of intermediate objects” on page 56
The property name is always a String value, the value is an Object. If you get an uninitialized property, the value
is null.
For any methods, the value must be a Gosu block. If you try to call a method that does not exist, the method returns
the special value [Link].
The following example creates an Expando instance in a variable declared to type Dynamic.
uses [Link]
uses [Link]
// Set dynamic properties and methods, which are stored internally in a [Link]
[Link] = 10
[Link] = \-> { if ( [Link] > 0 ) [Link]-- }
[Link] = \-> [Link] <= 0
while ( ![Link]() ) {
[Link]()
print("After punch, health = " + [Link])
}
Health = 10
After punch, health = 9
After punch, health = 8
After punch, health = 7
After punch, health = 6
After punch, health = 5
After punch, health = 4
After punch, health = 3
After punch, health = 2
After punch, health = 1
After punch, health = 0
Health = 0
See also
• “Blocks” on page 175
• “Dynamic type” on page 233
• “Structural types” on page 241
• “Enhancements” on page 201
• Gosu supports dynamic non-type-safe access to properties and methods for variables of the type called
[Link]. No declaration of specific property names or method names is required in advance. For
Dynamic types and expando objects 237
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
programming contexts of type [Link], a newly instantiated object assumes the default run-time type
of Expando. The Expando class implements the Bindings interface. Gosu adds enhancement methods to this
class to convert to JSON (toJson), XML (toXml), or Gosu object initialization code (toGosu).
When you combine these features, you can create objects with multiple types of data without declaring any specific
structure in advance, and can convert to other formats as needed.
The following Gosu code creates a dynamic complex object and prints it in JSON syntax, XML syntax, and Gosu
object initialization syntax:
person = new() {
:Name = "John Smith",
:Age = 39,
:Address = new() {
:Number = 123,
:Street = "Main St.",
:City = "Foster City",
:State = "CA"
},
:Hobby = {
new() {
:Category = "Sport",
:Name = "Swimming"
},
new() {
:Category = "Recreation",
:Name = "Hiking"
}
}
}
print("**** To JSON:")
print([Link]())
print("**** To XML:")
print([Link]())
print("**** To Gosu:")
print([Link]())
**** To JSON:
{
"Name": "John Smith",
"Age": 39,
"Address": {
"Number": 123,
"Street": "Main St.",
"City": "Foster City",
"State": "CA"
},
"Hobby": [
{
"Category": "Sport",
"Name": "Swimming"
},
{
"Category": "Recreation",
"Name": "Hiking"
}
]
}
**** To XML:
<object>
<Name>John Smith</Name>
<Age>39</Age>
<Address>
<Number>123</Number>
<Street>Main St.</Street>
<City>Foster City</City>
<State>CA</State>
</Address>
<Hobby>
<li>
<Category>Sport</Category>
<Name>Swimming</Name>
</li>
<li>
<Category>Recreation</Category>
<Name>Hiking</Name>
</li>
</Hobby>
</object>
**** To Gosu:
new Dynamic() {
:Name = "John Smith",
:Age = 39,
:Address = new() {
:Number = 123,
:Street = "Main St.",
:City = "Foster City",
:State = "CA"
},
:Hobby = {
new() {
:Category = "Sport",
:Name = "Swimming"
},
new() {
:Category = "Recreation",
:Name = "Hiking"
}
}
}
Note that for the Gosu initializer syntax serialization, you can evaluate the String data at run time to create a Gosu
object:
See also
• “Optional omission of type name with the new keyword” on page 87
• “Object initializer syntax” on page 88
• “Dynamic types and expando objects” on page 233
Structural types
Use structural typing to write code that works with objects with similar features but no common inheritance and
interface declarations. Define structural types similar to defining interfaces, by specifying the common properties
and method signatures. However, use the structure keyword, not the interface keyword.
Structural types are weaker than interfaces with respect to the amount of enforced type information they have in
them. However, their flexibility supports situations where interfaces are ineffective or impossible. Structural types
extend static typing to include a broader set of real-world situations but still support concise code that catches
common coding problems at compile time.
class UIObject {
public var X : double
public var Y : double
public var H : double
public var W : double
}
class Rectangle {
private var _x : double as X
private var _y : double as Y
private var _w : double as Width
private var _h : double as Height
}
class Point {
private var _x : double as X
Suppose you want to write code that just gets the X and Y properties and you want your code to work with instances
of any of the three classes.
Although each of these classes defines methods for obtaining the X and Y properties, these properties do not appear
as part of a common interface or ancestor class. Remember that in this example, the classes are defined in a third-
party library, so you cannot control the class declarations. Their only base class in common is Object, but Object
does not have the properties X or Y. To write code that reads the X and Y properties for these three different classes,
you must write three distinct yet nearly identical versions of the code.
Situations like this are common. Typically programmers resolve the problem by duplicating potentially large
amounts of code for each related use cases, which makes it more difficult to maintain the code.
Structural typing helps these types of situations. Use structural typing in Gosu to unite the behavior of the three
classes based on the presence of being able to read the X and Y properties.
Just like you would declare an interface, define the method signatures. However, use the structure keyword:
package [Link]
structure Coordinate {
property get X() : double // get the "X" public property or field
property get Y() : double // get the "Y" public property or field
}
You can now create code that uses the new structural type [Link].
A variable declared as the structural type can contain any object with compatible qualities defined by the structural
type. For example, a variable defined to the structural type Coordinate can be assigned with a Rectangle instance.
This works because Rectangle has the X and Y properties of type double:
To illustrate the flexibility of structural typing, suppose you want to write a function that gets the X and Y properties
and prints them and performs arithmetic with the values. Using structural typing, implementing this behavior once
works with any class instance that satisfies the requirements of the structural type. For example, the following
function takes the structural type as a parameter:
In many ways this coding style is similar to using an interface defined by the interface keyword. You can call this
function and pass any object that satisfies the requirements of the structural type. However, unlike interfaces, this
code works independent of inheritance or interface declarations for the classes.
Use the following example to see how this function can be used by multiple concrete classes that are unrelated.
Paste the following into the Gosu Scratchpad:
class Rectangle {
private var _x : double as X
private var _y : double as Y
private var _w : double as Width
private var _h : double as Height
}
class Point {
private var _x : double as X
private var _y : double as Y
class UIObject {
public var X : double
public var Y : double
public var H : double
public var W : double
}
// Define a function that works with any class that is compatible with the structural type
public function printCoordinate(myStruct : Coordinate) {
print("X value is " + myStruct.X)
print("Y value is " + myStruct.Y)
print("Sum of X and Y value is " + (myStruct.X + myStruct.Y) )
}
// Use that function with three different classes that all contain X and Y public fields
// or properties, but are unrelated
X value is 2.0
Y value is 3.0
Sum of X and Y value is 5.0
X value is 4.0
Y value is 5.0
Sum of X and Y value is 9.0
X value is 6.0
Y value is 7.0
Sum of X and Y value is 13.0
These examples demonstrate that structural types are statically weaker than interfaces regarding the amount of
enforced type information, but their flexibility supports situations where interfaces are ineffective or impossible.
Structural types extend static typing to include a broader set of real-world situations but still support concise code
that catches common coding problems at compile time.
Procedure
1. In the package for your new type, create a Gosu class file with a .gs file extension.
2. In the Gosu editor, change the word class to structure.
Structural types 243
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
3. Just as you would declare on an interface, add property declarations and method signatures:
• To provide data from a variable or property on an instance of this type, use property getter syntax:
• To set the value of a variable or property on an instance of this type, use property setter syntax:
Example
package [Link]
structure DemoStructure{
property get Name() : String
property set Name(n : String)
public function count(s : String) : double
}
This example declares a structural type called DemoStructure that has the following features:
• Name property of type String
• count method, which takes one String parameter and returns a double value
See also
• “Interfaces” on page 171
• “Adding static constant variables to a structural type” on page 244
For structural type definitions, any variables that store state are implicitly static and constant so you can omit the
word static:
Adding a var declaration does not imply the ability to get or set a variable or property on an instance of the type. A
var declaration on a structural type defines a static constant variable on the type. A static constant variable is
conceptually similar to a static variable on a Gosu class. However, as for a variable on an interface, the static
keyword is implicit and the value is read-only. The declaration does not specify the ability to get or set a variable or
property an instance of this type.
For example, note the Age variable in the following example:
package [Link]
structure DemoStructure2 {
property get Name() : String
property set Name(n : String)
public var Age : Integer // Compilation error. A static constant variable requires initialization
}
The var declaration on the structural type creates a static constant variable, which must be initialized, so the
previous code causes a compilation error. Initializing the value of the static constant variable clears the error:
package [Link]
structure DemoStructure2 {
property get Name() : String
property set Name(n : String)
public var AGE : Integer = 18 // OK because the static constant variable is intialized
}
You can add the static modifier in the declaration of the AGE variable, but in structural type declarations, this
modifier is implicit and therefore redundant.
Although you can use property getter and setter syntax to define data to get and set on instances, you do not use this
syntax for static constant variables. Therefore, static constant variables do not require assignment compatibility
between the structural type and other types.
The DemoStructure2 class from the previous example is compatible with the following class:
package [Link]
class MyClass {
public var Name: String
public var UnusedField1: String
public var UnusedField2: String
}
uses [Link].DemoStructure2
uses [Link]
// Set the shared field on the variable of the structural type, and it affects both
[Link] = "John"
print("[Link] is " + [Link])
print("[Link] is " + [Link])
// Set the shared field on variable of type MyClass, and it affects both
[Link] = "Eric"
print("[Link] is " + [Link])
print("[Link] is " + [Link])
// The following line is not valid if you uncomment it. Static constant fields are READ-ONLY.
// [Link] = 40
[Link] is John
[Link] is John
[Link] is Eric
[Link] is Eric
[Link] (a STATIC CONSTANT) is 18
See also
• “Create a structural type with getters, setters, and methods” on page 243
See also
• “Adding static constant variables to a structural type” on page 244
• “Create a structural type with getters, setters, and methods” on page 243
structure HasPublicName {
public function toPublicName() : String
}
Suppose a relevant class does not provide the toPublicName method but exposes the appropriate data using other
methods or properties. You can add a Gosu enhancement to add the desired property on target types, in this case
instances of the [Link] class:
Any instance of [Link] has the toPublicName function and is compatible with the structure that
requires that method:
uses [Link]
// Assign a MyClass to the structural type. This code works because of the Gosu enhancement method.
named = s
See also
• “Enhancements” on page 201
Composition
Gosu provides the language feature called composition by using the delegate keyword in variable definitions.
Composition enables a class to delegate responsibility for implementing an interface to a different object. This
compositional model supports implementation of objects that are proxies for other objects, or encapsulation of
shared code independent of the type inheritance hierarchy.
See also
• “Interfaces” on page 171
• “Classes” on page 147
code. In some cases there does not exist a shared root class other than Object, so it might not be an option to put the
code there. If Gosu supported multiple inheritance, you could encapsulate the shared code in its own class and
classes could inherit from that class in addition to any other supertype.
Fortunately, you can get many of the benefits of multiple inheritance using another design pattern called
composition. Composition encapsulates implementation code for shared behavior such that calling a method on the
main object forwards method invocations to a subobject to handle the methods required by the interface.
Let us use our previous example with clipboard parts and windows. Let us suppose you want to create a subclass of
window but that implements the behaviors associated with a clipboard part. First, create an interface that describes
the required methods that you expect a clipboard-supporting object to support, and call it IClipboardPart. Next,
create an implementation class that implements that interface, and call it ClipboardPart. Next, create a window
subclass that implements the interface and delegates the actual work to a ClipboardPart instance associated with
your window subclass.
The delegation step requires the Gosu keyword delegate within your class variable definitions. Declaring a
delegate is like declaring a special type of class variable.
The delegate keyword has the following syntax:
Optionally, you can use the following syntax that specifies the type:
The INTERFACE_LIST is a list of one or more interface names, with commas separating multiple interfaces.
For example:
In the class constructor, create an instance of an object that implements the interface. For example:
construct() {
_clipboardPart = new ClipboardPart( this )
}
After the constructor runs, Gosu intercepts any method invocations on the object for that interface and forwards the
method invocation to the delegated object.
Example
Let us look at complete code for this example.
The interface:
package test
interface IClipboardPart {
function canCopy() : boolean
function copy() : void
function canPaste() : boolean
function paste() : void
}
package test
construct(owner : Object) {
_myOwner = owner
package test
construct() {
_clipboardPart = new ClipboardPart( this )
}
}
uses [Link]
Pasted!
For example, in the following line, _clipboardPart implements the IClipboardPart interface for the
ClipboardPart class:
Composition 251
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
You might notice that in this example the line does not specify an explicit type for _employee, which represents two
different types, which in this case are interface types. You might wonder about the compile-time type of the
_employee variable. Because the variable must satisfy all requirements of both types, Gosu uses a special type
called a compound type. A literal of a compound type is expressed in Gosu as a list separated by the ampersand
symbol (&). For example:
Typical code does not need to mention a compound type explicitly. However, remember this syntax in case you see
it during debugging code that uses the delegate keyword with multiple interfaces.
See also
• “Compound types” on page 409
You could now use this class and call any method defined on the List interface:
XML files describe complex structured data in a text-based format with strict syntax for data interchange. Gosu can
read or write any XML document. If you have an associated XSD to define the document structure, Gosu parses the
XML using the schema to produce a statically typed tree of XML elements with structured data. Also during
parsing, Gosu can validate the XML against the schema. You can manipulate XML or generate XML without an
XSD file, but use XSDs if possible. Without an XSD, your XML elements do not get programming shortcuts, such
as Gosu properties on each element, nor intelligent static typing.
See also
• “Introduction to the XML element in Gosu” on page 253
<?xml version="1.0"?>
<veh:root xmlns:veh="[Link]
<veh:childelement/>
</veh:root>
This XML code specifies the following properties of the XML document:
• The root element of the document has the name root within the namespace [Link]
vehiclexsd.
• The text xmlns:veh text followed by the URI means that later in the XML document, elements can use the
namespace shortcut veh: to represent the longer URI: [Link]
• The root element has one child element, which has the name childelement and is within the namespace
[Link] However, this XML element specifies the namespace not with
the full URI but with the shortcut prefix veh followed by the colon, which is followed by the local part.
There are three constructors for QName:
• Constructor specifying the namespace URI, local part, and suggested prefix.
• Constructor specifying the namespace URI and local part, with an implicitly empty suggested prefix
• Constructor specifying the local part only, with implicitly empty URI and namespace
QName(String localPart)
You can set the namespace in the QName object to the empty namespace, which technically is the constant
[Link].NULL_NS_URI. The recommended approach for creating QName objects in the empty
namespace is to use the QName constructor that does not take a namespace argument.
To create multiple QName objects in the same namespace, you can use the optional utility class called XmlNamespace.
Whenever you construct an XmlElement, the name is strictly required and must be non-empty.
Other Gosu XML APIs use QName objects for other purposes. For example, attributes on an element are names
defined within a namespace, even if it is the default namespace for the XML document or the empty namespace.
Gosu natively represents both attribute names and element names as QName objects.
You can use XmlElement essentially as untyped nodes, in other words with no explicit XSD for your data format. If
you are not using an XSD and do not provide a backing type, Gosu uses the default backing type
[Link]. All valid backing types are subclass of that AnyType type.
The type instance of an XML element is responsible for most of the element’s behavior but does not contain the
element’s name. You can sometimes ignore which of the XmlElement and its backing type instance supports a
particular functionality. If you are using an XSD, this distinction is useful and sometimes critical.
Nillness of an element
XML has a concept of whether an element is nil. This state is not exactly the same as being null. An element that
is nil must have no child elements, but can have attributes. Additionally, an XSD can define whether an element is
nillable. A nillable element is allowed to be nil.
XMLElement constructor
The constructor on XmlElement that takes a String is a convenience method. The String constructor is equivalent
passing a new QName object with that String as the one-argument constructor to QName. In other words, the
namespace and prefix in the QName are null if you use the String constructor on XmlElement.
The following code creates an in-memory Gosu object that represents an XML element <Root> in the empty
namespace:
In this case, the [Link] property returns an instance of the default type
[Link]. If you instantiate a type instance, typically you use a more
specific subclass of AnyType, either an XSD-based type or a simple type.
See also
• “Creating many qualified names in the same namespace” on page 264
• “Getting data from an XML element” on page 273
• “Accessing the nillness of an element” on page 280
IMPORTANT If you get these properties on an XSD-based element, you must use a dollar sign prefix
for the property name.
See also
• “Accessing XSD type properties” on page 257
• “Accessing the nillness of an element” on page 280
See also
• “XSD-based properties and types” on page 264
Create an XmlElement
Procedure
1. To create a basic XmlElement, decide the element name that you want to use.
2. In a new expression, pass the element name to the constructor as either a QName object or a String. For
example, the following line passes the name as a String:
In this case, the [Link] property returns an instance of the default type
[Link]. If you instantiate a type instance, typically you would use
a more specific subclass of AnyType, either an XSD-based type or a simple type.
3. Optionally set attributes.
4. Optionally add child elements by calling the addChild method with a reference to a child element.
Example
The following Gosu code creates a new XmlElement without an XSD, and then adds child elements:
uses [Link]
uses [Link]
// Print element
[Link]()
print("Namespace of xe = " + xe.$Namespace)
print("Namespace of xe2 = " + xe2.$Namespace)
print("Namespace of xe3 = " + xe3.$Namespace)
<?xml version="1.0"?>
<veh:root xmlns:veh="[Link]
<veh:childelement/>
<childelementWithNoNamespace/>
</veh:root>
Namespace of ex = {[Link]
Namespace of e2 = {[Link]
Namespace of e3 = {}
See also
• “XML attributes” on page 276
• “Getting data from an XML element” on page 273
This requirement affects the following type instance property names that appear on an XML element, listed with
their dollar sign prefix:
• $Attributes
• $Class
• $Children
• $Namespace
• $NamespaceContext
• $Comment
• $QName
• $Text
• $TypeInstance
• $SimpleValue
• $Value – Only for elements with an XSD-defined simple content
• $Nil – Only for XSD-defined nillable elements
Note: If you create an XmlElement element directly, not a subclass, the object is not an XSD type. The
new object is an untyped node that uses the default type instance, which is an instance of the type
AnyType. In such cases, there is no dollar sign prefix because there is no ambiguity between properties
that are part of the type instance and properties on the XSD type.
See also
• “Accessing the nillness of an element” on page 280
Exporting bytes
The bytes method returns an array of bytes (the type byte[]) that contains the UTF-8-encoded bytes in the XML.
Generally speaking, the bytes method is the best approach for serializing the XML.
var ba = [Link]()
The method has no required arguments, but can be customized by passing an optional argument of an
XmlSerializationOptions object.
Code that sends XML with a transport that understands only character data and not byte data must always base-64
encode the bytes to compactly and safely encode binary data.
Note: For example, for PolicyCenter messaging, the payload field in a Message entity is type String.
[Link]()
The method has no required arguments, but can be customized by passing an optional argument of an
XmlSerializationOptions object.
var s = [Link]()
IMPORTANT Although the asUTFString method is helpful for debugging use, the asUTFString
method is not the best way to export XML safely to external systems. Instead, it is usually best to use
the XML element’s bytes method to produce an array of bytes.
The asUTFString method outputs the node as a String value that contains XML, with a header suitable for later
export to UTF-8 or UTF-16 encoding. The generated XML header does not specify the encoding. In the absence of a
specified encoding, all XML parsers must detect the encoding (UTF-8 or UTF-16). The existence of a byte order
mark at the beginning of the document tells the parser what encoding to use.
The method has no required arguments. However, it can be customized by passing an optional argument for an
XmlSerializationOptions object.
WARNING Although the asUTFString method adds an XML header that can specify the
encoding, there is no automatic encoding transformation into bytes. To write this String object to
another system or a file, you must be careful to do the correct encoding transformation on export.
Also be aware that if you use the optional XmlSerializationOptions argument, you could
choose another encoding. However, just like for the default asUTFString method signature,
which assumes UTF-8 encoding, the encoding choice only affects the serialized header, not the
encoding of the output bytes.
In addition, the withEncoding property has a secondary method signature that takes the Java short name for the
encoding. You can set the encoding by either of the following operations.
• Use the withEncoding method and pass a standard Java encoding name as a String, such as "Big5".
• Set the Encoding property to a raw character set object for the encoding. You can use the static method
[Link](ENCODING_NAME) to get the desired static instance of the character set object. For example,
pass "Big5".
See also
• “XML serialization options reference and examples” on page 260
• [Link]
Sort Boolean If true, ensures that the order of children elements of each element match the XSD. true
This is particularly important for sequences. This feature only has an effect on an ele‐
ment if it is based on an XSD type. If the entire graph of XmlElement objects contains
no XSD‐based elements, this property has no effect. If a graph of XML objects con‐
tains a mix of XSD and non‐XSD‐based elements, this feature only applies to the XSD‐
based elements. This is true independent of whether the root node is an XSD‐based
element.
WARNING: For large XML objects with many nested layers, sorting requires significant
computer resources.
XmlDeclaration Boolean If true, writes the XML declaration at the top of the XML document. true
Validate Boolean If true, validates the XML document against the associated XSD. This feature only has false
an effect on an element if it is based on an XSD type. If the entire graph of
XmlElement objects contains no XSD‐based elements, this property has no effect.
GX models created in Studio cannot be invalid. As a result, they do not need to be
validated when serialized to XML.
Encoding Charset The character encoding of the resulting XML data as a [Link] UTF‐8
object. See discussion after this table for tips for setting this property. encod‐
ing
Pretty Boolean If true, Gosu attempts to improve visual layout of the XML with indenting and line true
separators. If you set this to false, then Gosu ignores the values of the properties:
Indent, LineSeparator, AttributeNewLine, AttributeIndent.
The following properties provide options that take effect only if the Pretty property is true:
AttributeIndent int The number of additional indents beyond its original indent for an at‐ 2
tribute.
uses [Link]
// Create an element.
var a = new [Link]()
// Add a comment
a.$Comment = "Hello I am a comment"
For Guidewire application messaging, follow the pattern of the following PolicyCenter Event Fired rule code. It
creates a new message that contains the XML for a contact entity as a String to work with the standard message
payload property. The messaging system requires a String, not an array of bytes. To properly and safely encode
XML into a String, use the syntax:
if ([Link] == "ContactChanged") {
var xml = new [Link]([Link] as Contact)
var strContent = [Link]([Link]())
Your messaging transport code takes the payload String and exports it:
[Link]();
}
All serialization APIs generate XML data for the entire XML hierarchy with that element at the root.
methods begin with the prefix parse. There are multiple methods because Gosu supports parsing from several
different sources of XML data.
IMPORTANT For each source of data, there is an optional method variant that modifies the way Gosu
parses the XML. Gosu encapsulates these options in an instance of the type XmlParseOptions. The
XmlParseOptions specifies additional schemas that resolve schema components for the input instance
XML document. Typical code does not need this. Use this if your XML data contains references to
schema components that are neither directly nor indirectly imported by the schema of the context type.
For example, the following example parses XML contained in a String into an XmlElement object, and then prints
the parsed XML data:
var a = [Link]("<Test123/>")
[Link]()
If you are using an XSD, call the parse method directly on your XSD-based node, which is a subclass of
XmlElement. For example:
var a = [Link](xmlDataString)
parse [Link] Parse XML from a file, with optional parsing options.
[Link],
XmlParseOptions
parse [Link] Parse XML from an InputStream with optional parsing options.
[Link],
XmlParseOptions
parse [Link] Parse XML from a reader, which is an object for reading character streams. Optionally,
[Link], add parsing options.
XmlParseOptions WARNING: Because this uses character data, not bytes, the character encoding is irrele‐
vant. Any encoding header at the top of the file has no effect. It is strongly recommend‐
ed to treat XML as binary data, not as String data. If your code needs to send XML with
a transport that only understands character (not byte) data, always Base64 encode the
bytes. (From Gosu, use the syntax: [Link]([Link]())
parse String Parse XML from a String, with optional parsing options.
String, IMPORTANT: Because this uses character data, not bytes, the character encoding is irrel‐
XmlParseOptions evant. Any encoding header at the top of the file has no effect. It is strongly recom‐
mended to treat XML as binary data, not as String data. If your code needs to send
XML with a transport that only understands character (not byte) data, always Base64
encode the bytes. From Gosu, create the syntax:
[Link]([Link]())
See also
• “Referencing additional schemas during parsing” on page 263
package_for_the_schema.[Link]
To see how and why you would specify additional schemas, suppose you have the following two schemas:
The XSD [Link]:
Notice that the ImportXSD2 XSD extends a type that the ImportXSD1 defines. This definition is analogous to saying
the ImportXSD2 type called TypeFromSchema2 is a subclass of the ImportXSD1 type called TypeFromSchema1.
The following code fails by throwing an exception because the ImportXSD1 references the schema type
ImportXSD2:TypeFromSchema2 and Gosu cannot find that type in the current schema.
// Parse an element defined in the the first schema, but pass an extension to that
// that type that the second schema defines. THIS FAILS without using the AdditionalSchemas feature.
var element = [Link](xsdtext)
The ImportXSD1 XSD type cannot locate the schema called ImportXSD2 even though the specification extends a
type that ImportXSD2 defines.
To provide access to the additional schema, set the AdditionalSchemas property of the XmlParseOptions object to
a list containing one or more SchemaAccess objects. The following code parses XML successfully:
// Parse an element defined in the the first schema, but pass an extension to that
// type that the second schema defines by using the XmlParseOptions.
var element = [Link](xsdtext, options)
You can remap an external namespace or XSD URL to a local XSD using the [Link] file.
See also
• “Using a local XSD for an external namespace or XSD location” on page 287
uses [Link]
var ns = new XmlNamespace("namespaceURI","prefix")
var ex = new XmlElement([Link]("localPartName"))
• Reuse the namespace of an already-created XML element. To get the namespace from an XML element instance,
get its NameSpace property. Then, call the qualify method and pass the local part String:
// Reuse the namespaceURI and prefix from the previously created element.
var xml2 = new XmlElement([Link]("localPart2"))
See also
• “Introduction to the XML element in Gosu” on page 253
PolicyCenter/modules/configuration/gsrc
For example, to load an XSD in the package [Link], put your XSD file at the path:
PolicyCenter/modules/configuration/gsrc/mycompany/schemas
Gosu creates new types in the type system for element declarations in the XSD. Where appropriate, Gosu creates
properties on these types based on the names and structure within the XSD. By using an XSD and the generated
types and properties, your XML-related code is significantly more readable. You can use natural Gosu syntax to
access attributes and child elements using the period operator. For example, access a child element named
ChildName on an element with code like [Link].
The new types are defined in a subpackage that matches the name of the XSD, except in lowercase and with no .xsd
suffix. For example, if the XSD is at the path gsrc/example/[Link] and contains an element called Address,
the new element type is [Link]
If you cannot use an XSD, you can use the basic properties and methods of XmlElement like [Link]
and [Link]("ChildName"). Getting and setting values in this way is harder to understand than using
XML types and properties. This type of XML-related code that does not use XSD types is not type-safe, so Gosu
cannot perform type checking, which can lead to run-time errors.
If you have a reference to the element, you can always reference the backing type. For example, for an element, you
can reference the backing type instance using the $TypeInstance property.
See also
• “XSD generated type examples” on page 268
A common pattern converts a simpleType to simpleContent to add attributes to an element with a simple type. To
support this pattern, Gosu provides the ChildName and ChildName_elem properties for every child element that has
either a simple type or both a complex type and simple content. The property with the _elem suffix on its name
contains the element object instance. The property without the _elem suffix contains the element value. Because of
this design, if you later decide to add attributes to a simpleType element, the change does not require modification
of your existing XML code.
The following table lists XML definitions for child elements and the syntax for accessing an item that the definition
describes. These items can occur anywhere in the schema.
The following table lists the XML definition and the syntax for accessing an XML schema.
See also
• “Automatic insertion into lists” on page 270
• “Referencing additional schemas during parsing” on page 263
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child1"/> <!-- The default type is xsd:anyType. -->
<xsd:element name="Child2" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="person">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="cell" type="phone"/>
<xsd:element name="work" type="phone"/>
<xsd:element name="home" type="phone"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="phone">
<xsd:sequence>
<xsd:element name="areaCode" type="xsd:string"/>
<xsd:element name="mainNumber" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
This XSD supports multiple ways to create and assign the phone numbers.
If you want to create three different phone numbers, use code like this:
[Link] = "415"
[Link] = "555-1213"
[Link] = "416"
[Link] = "555-1214"
[Link] = "417"
[Link] = "555-1215"
If you want to create one phone number to use in multiple elements, use code like this:
[Link].$TypeInstance = p
[Link].$TypeInstance = p
[Link].$TypeInstance = p
[Link] = p // SYNTAX ERROR: cannot assign complex type instance to element type instance
[Link] = p // SYNTAX ERROR: cannot assign complex type instance to element type instance
[Link] = p // SYNTAX ERROR: cannot assign complex type instance to element type instance
Additionally, different element-based types can be mutually incompatible for assignment even if they are associated
with the XSD type definition. For example:
[Link][0] = childElement
If the list does not yet exist for a list property, Gosu creates the list when you do the first insertion.
For example, consider an element containing child elements that represent an address and the child element has the
name Address. If the XSD declares that the element could exist more than once, the [Link] property is a
list of addresses. The following code creates a new Address:
Note: If you use XSDs, Gosu creates intermediate XML elements as needed. Use this feature to
improve the readability of your XML-related Gosu code.
Example XSD
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child1" type="xsd:int" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Code
Output
Before insertion: 0
After insertion: 3
<?xml version="1.0"?>
<Element1>
<Child1>0</Child1>
<Child1>1</Child1>
<Child1>2</Child1>
</Element1>
Example XSD
This code also works with simple types derived by list (xsd:list) such as in the following XSD:
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child1">
<xsd:simpleType>
<xsd:list itemType="xsd:int"/>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Output
Before insertion: 0
After insertion: 3
<?xml version="1.0"?>
<Element1>
<Child1>0 1 2</Child1>
</Element1>
See also
• “XSD-based properties and types” on page 264
Example XSD
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:choice>
<xsd:element name="Child1" type="xsd:int"/>
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="Child2" type="xsd:int"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Code
print( "----------" )
xml.Child1 = null
xml.Child2 = {1, 2, 3, 4}
[Link]()
Output
<?xml version="1.0"?>
<Element1>
<Child1>1</Child1>
</Element1>
----------
<?xml version="1.0"?>
<Element1>
<Child2>1</Child2>
<Child2>2</Child2>
<Child2>3</Child2>
<Child2>4</Child2>
</Element1>
PolicyCenter/modules/configuration/res/[Link]
This one file controls code generation for all XSDs. The file contents look similar to the following:
<?xml version="1.0"?>
<module xmlns="[Link] name="ab-customer-build">
<dependencies>
<dependency name="pl"/>
<dependency name="ab"/>
</dependencies>
<settings>
<setting name="[Link]" value="ab"/>
<setting name="[Link]-gosu-enhancements" value="true"/>
</settings>
<excludes>
<!-- <pattern>path/to/[Link]</pattern> -->
</excludes>
<included-only>
<!-- <pattern>path/to/[Link]</pattern> -->
</included-only>
</module>
Gosu supports modifying the <excludes> and <included-only> elements. All other changes are unsupported.
Procedure
1. To find and edit the XSD code generation configuration file, in Studio, type Ctrl+Shift+N, and then type:
[Link]
2. For any XSDs that do not need code generation in any context, create a pattern in the <excludes> element:
a. Add a <pattern> element to the <excludes> element.
b. As content for the element, type the relative path to the XSD in the source directory including the
package.
The source directory is your gsrc directory for production code or gtest for XSDs that you need only for
GUnit tests. Use forward slashes (/) rather than periods to separate levels in the package hierarchy.
For example, suppose your XSD is at:
PolicyCenter/modules/configuration/gsrc/com/mycompany/schemas/integration/[Link]
<excludes>
<pattern>com/mycompany/schemas/integration/[Link]</pattern>
</excludes>
3. For any XSDs that need code generation but not repeated code generation for XSD <include> elements,
create a pattern in the <included-only> element:
a. Add a <pattern> element to the <included-only> element.
b. As content for the element, type the relative path to the XSD in the source directory including the
package. Use forward slashes (/) rather than periods to separate levels in the package hierarchy. For
example, suppose your XSD is at:
For example, suppose your XSD is at:
PolicyCenter/modules/configuration/gsrc/com/mycompany/schemas/integration/[Link]
<include-only>
<pattern>com/mycompany/schemas/integration/[Link]</pattern>
</include-only>
********************************************************************************
Java enum limit exceeded. Treating xs:enumeration as String
As a result there will not be static typing for this enumeration.
[gw/accelerators/test/common/xsd/test/TestLocationService_CodeExt_2013-[Link]]
[gw/accelerators/test/common/xsd/test/TestLocationService_CodeExt_2013-10-17
/types/simple/[Link]]
3434 entries found
********************************************************************************
See also
• “Introduction to the XML element in Gosu” on page 253
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child1"/> <!-- default type is xsd:anyType -->
<xsd:element name="Child2" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Example
The following Gosu code adds two child elements, sets the value of an element using the Value property and the
SimpleValue property, and then prints the results. In this example, we use XSD types, so we must specify the
special property names with the dollar sign prefix: $Value and $SimpleValue.
uses [Link]
// Create a new CHILD element that is legal in the XSD, and add it as child.
var c1 = new [Link].Element1_Child1()
[Link](c1)
// Create a new CHILD element that is legal in the XSD, and add it as child.
var c2 = new [Link].Element1_Child2()
print("before set: " + c2.$Value) // prints "null" -- it is uninitialized
c2.$SimpleValue = [Link](5)
print("after set with $SimpleValue: " + c2.$Value)
c2.$Value = 7
print("after set with $Value: " + c2.$Value)
print("")
print("")
[Link]()
Children 0[]
Children 2[[Link].Element1_Child1
instance, [Link].Element1_Child2
instance]
<?xml version="1.0"?>
<Element1>
<Child1/>
<Child2>7</Child2>
</Element1>
Note that the Child2 element contains the integer as text data in the serialized XML export. Gosu does not serialize
the simple types to bytes (or a String) until serialization. In this example, the final print statement is what
serializes the element and all its subelements.
one match. Use getChildren if you expect multiple matches. Each of these methods has an alternative signature
that takes a String.
• getChild(QName) – Searches the content list for a single child with the specified QName name. An
alternativealternative method signature takes a String value for the local part name. For that method signature,
Gosu and internally creates a QName with an empty namespace and the specified local part name. This method
requires there to be exactly one child with this name. If there are multiple matches, the method throws an
exception. If there might be multiple matches, use the getChildren method instead.
• getChildren(QName) : List – Searches the content list for all children with the specified QName name. An
alternative method signature takes a String value for the local part name. For that method signature, Gosu
internally creates a QName with an empty namespace and the specified local part name.
Reusing the code from the previous example, add the following lines to get the second child element by its name:
// Get a child using a QName, and "reuse" the namespace of a previous node.
var getChild2FromQName = [Link]([Link]("Child2"))
print([Link]())
<?xml version="1.0"?>
<Child2>5</Child2>
See also
• “XML simple values” on page 277
• “XSD-based properties and types” on page 264
• “Collections” on page 183
XML attributes
Attributes are additional metadata on an element. For example, in the following example an element has the color
and size attributes:
Every type instance contains its attributes, which are XmlSimpleValue instances specified by a name (a QName).
Each XmlElement object contains the following methods and properties related to attributes of the element:
• AttributeNames property – Gets a set of QName objects. The property type is [Link]<QName>.
• getAttributeSimpleValue(QName) – Get an attribute simple value by its name, specified as a QName. Returns a
XmlSimpleValue object. An alternative method signature takes a String instead of a QName. This method
assumes an empty namespace.
• getAttributeValue(QName) : String – Get attribute value by its name, specified as a QName. Returns a
String object. An alternative method signature takes a String instead of a QName. This method assumes an
empty namespace.
• setAttributeSimpleValue(QName , XmlSimpleValue) – Set an attribute simple value by its name (as a
QName) and its value (as a XmlSimpleValue object). An alternative method signature takes a String instead of a
QName. This method assumes an empty namespace.
• setAttributeValue(QName , String) – Set attribute value by its name (as a QName) and its value (as a
XmlSimpleValue object). An alternative method signature takes a String instead of a QName. This method
assumes an empty namespace.
Using the previous example, the following code gets and sets the attributes:
[Link]("color", [Link]("blue"))
var s = [Link]("size")
If you use XSDs for your elements, for typical use, do not use these methods. Instead, use the shortcuts that Gosu
provides. These shortcuts provide a natural and concise syntax for getting and setting attributes.
See also
• “XML simple values” on page 277
• “XSD-based properties and types” on page 264
See also
• “Getting data from an XML element” on page 273
anyURI [Link]
base64Binary [Link]
boolean [Link]
byte [Link]
date [Link]
dateTime [Link]
decimal [Link]
double [Link]
duration [Link]
float [Link]
int [Link]
gDay [Link]
gMonth [Link]
gMonthDay [Link]
gYearMonth [Link]
gYear [Link]
hexBinary byte[]
IDREF [Link]
integer [Link]
long [Link]
QName [Link]
short [Link]
time [Link]
unsignedByte [Link]
unsignedInt [Link]
unsignedLong [Link]
unsignedShort [Link]
Any type derived by union of (T1, T2,... Tn) Greatest common supertype of (T1, T2,... Tn)
Facet validation
A facet is a characteristic of a data type that restricts possible values. For example, setting a minimum value or
matching a specific regular expression.
Gosu represents each facet as an element. Each facet element has a fixed attribute that is a Boolean value. All the
facets for a simple type collectively define the set of legal values for that simple type.
Most schema facets are validated at property setter time. A few facets are not validated until serialization time to
allow incremental construction of lists at run time. This mostly affects facets relating to lengths of lists, and those
that validate QName objects. Gosu cannot validate QName objects at property setting time because there is not enough
information available. Also, the XML Schema specification recommends against applying facets to QName objects at
all.
Example
The following XSD contains defines an attribute that has restricted values.
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:attribute name="Attr1" type="AttrType"/>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="AttrType">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="5"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
The following code demonstrates the facet validation of the attribute that has restricted values.
Example
The following XSD contains defines an element that is nillable.
280 chapter 20: Working with XML in Gosu
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1" type="xsd:int" nillable="true"/>
</xsd:schema>
The following code demonstrates how to set the $Nil property of the element.
<?xml version="1.0"?>
<Element1 xsi:nil="true" xmlns:xsi="[Link]
See also
• “Introduction to the XML element in Gosu” on page 253
Example
The following XSD contains defines multiple nested elements.
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child2" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The following code demonstrates assignment to a nested element that causes automatic creation of an instance of the
intermediary element.
type. Gosu adds default or fixed values to attributes and elements in the XML output stream at the time that Gosu
serializes the Gosu representation of an XML document.
Example
The following example XSD defines an XML element named person. The element definition includes an attribute
definition named os with a default value of “Windows” and an attribute definition named location with a fixed
value of “San Mateo”.
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="person" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="os" type="ostype" default="Windows"/>
<xsd:attribute name="location" type="xsd:string" fixed="San Mateo"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="ostype">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Windows"/>
<xsd:enumeration value="MacOSX"/>
<xsd:enumeration value="Linux"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
The following sample Gosu code creates a new Gosu representation of an XML document based on the preceding
XSD. The code adds two person elements, one for jsmith and one for aanderson. For jsmith, the code adds an os
attribute set to the value Linux. The code does not add an os attribute to aanderson, nor does the code add the
location attribute to either person. Instead, the code relies on the default and fixed values defined in the XSD.
// Gosu adds default and fixed values to the XML document at the time Gosu serializes XML for print.
for (person in [Link]) {
print("${[Link]} (${[Link]}) -> ${[Link]}")
}
[Link]()
When the preceding Gosu code serializes its representation of an XML document, Gosu adds the fixed and default
values to the XML output stream. The printed output shows that the Gosu representation of the XML document does
not contain the value “San Mateo” or “Windows”.
Example
Create the following XSD file at the path gsrc/package/[Link]:
The following code creates an Address property and uses the substitution group hierarchy to cast that property to a
UKAddress:
<?xml version="1.0"?>
<Customer>
<UKAddress/>
</Customer>
The XML Schema specification requires that the XSD type of a substitution group member must be a subtype of the
XSD type of its substitution group head. The reason the example above works is because UKAddress, USAddress
and Address are all of the type xsd:anyType, which is the default when there is no explicit type.
autocreation of intermediary elements. In all of these cases, Gosu permits the children to be out of order in the
XmlElement object graph.
During serialization and only during serialization, Gosu sorts the elements to ensure that the elements conform to the
XSD.
Note that if you use an XSD when you parse XML into an XmlElement, the elements must be in the correct order
according to the XSD. If the child order violates the XSD, Gosu throws an exception during parsing.
Example 1
The following XSD defines three ordered child elements for a complex XML type.
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child1" type="xsd:int"/>
<xsd:element name="Child2" type="xsd:int"/>
<xsd:element name="Child3" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The following code assigns values to the child elements of the parent element:
<?xml version="1.0"?>
<Element1>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
</Element1>
Example 2
The following XSD defines two sets of ordered child elements for a complex XML type. Both sets include some of
the same child elements, but use a different ordering.
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:choice>
<xsd:sequence>
<xsd:element name="A" type="xsd:int"/>
<xsd:element name="B" type="xsd:int"/>
<xsd:element name="C" type="xsd:int"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="B" type="xsd:int"/>
<xsd:element name="C" type="xsd:int"/>
<xsd:element name="A" type="xsd:int"/>
<xsd:element name="Q" type="xsd:int"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The following code assigns values to the child elements of the parent element:
284 chapter 20: Working with XML in Gosu
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
<?xml version="1.0"?>
<Element1>
<A>5</A>
<B>5</B>
<C>5</C>
</Element1>
----------
<?xml version="1.0"?>
<Element1>
<B>5</B>
<C>5</C>
<A>5</A>
<Q>5</Q>
</Element1>
See also
• “Automatic creation of intermediary elements” on page 281
Example
The following XSD defines two distinct strict orderings of the same elements:
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:choice>
<xsd:sequence>
<xsd:element name="A" type="xsd:int"/>
<xsd:element name="B" type="xsd:int"/>
<xsd:element name="C" type="xsd:int"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="C" type="xsd:int"/>
<xsd:element name="B" type="xsd:int"/>
<xsd:element name="A" type="xsd:int"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The following code assigns values to the child elements of the parent element in two different orders, which are both
valid:
print( "----------" )
<?xml version="1.0"?>
<Element1>
<A>5</A>
<B>5</B>
<C>5</C>
</Element1>
----------
<?xml version="1.0"?>
<Element1>
<C>5</C>
<B>5</B>
<A>5</A>
</Element1>
Example
The following XSD defines two distinct strict orderings of the same elements:
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:choice>
<xsd:sequence>
<xsd:element name="A" type="xsd:int"/>
<xsd:element name="B" type="xsd:int"/>
<xsd:element name="C" type="xsd:int"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="C" type="xsd:int"/>
<xsd:element name="B" type="xsd:int"/>
<xsd:element name="A" type="xsd:int"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The following code assigns values to the child elements of the parent element:
<?xml version="1.0"?>
<Element1>
<A>5</A>
<B>5</B>
<C>5</C>
</Element1>
Built‐in schemas
Gosu includes several XSDs in the [Link].* package. The following table lists the built-in XSDs.
The XML XSD, which defines the attributes that begin with the xml: prefix, such as [Link]
xml:lang
XML Schema XSD, which is the XSD that defines the format of an XSD. [Link]
See also
• “The metaschema XSD that defines an XSD” on page 287
Example
The following code parses the metaschema.
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Child" type="Type1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="Type1"/>
</xsd:schema>
Gosu does not provide a way to inject a schema into the type system at run time.
In a slightly different situation, it is common for an XSD to define an external namespace URI without specifying
the external download location for an XSD.
In both cases, Gosu provides a registry file, [Link], that lets you use a local XSD instead. The file is
located in the configuration→res module.
The default configuration includes multiple versions of [Link] located in various modules. The
configuration→res→[Link] instance is the application-level version. The other instances of the file are for
Guidewire internal use only and are not visible in Studio. Their purpose is to remap common W3C XSD files to
local locations so as to avoid unnecessarily connecting to the W3C website.
See also
• “Referencing additional schemas during parsing” on page 263
Use a local XSD for an external namespace URI or XSD location URL
To remap an external namespace to a local location, edit the [Link] file.
Procedure
1. Get a copy of the target external XSD.
2. Place that XSD in the local resources hierarchy.
3. In Studio, open the [Link] file. The file is located in the configuration→res module. Add a
schemalocations element with an xmlns attribute that specifies the local resource location.
4. To the schemalocations element, add a child schema element.
5. Set the element's resourcePath attribute to the fully qualified path to the local XSD. You must use a forward
slash (/), not a period (.), to indicate any subpackage.
6. To cause Gosu to find and remap an external namespace declaration in parsed XSD, set the xmlNamespace
attribute to the external XSD namespace URI. The value starts with http:// so it looks like a quoted URL,
but it is actually a unique ID and not a URL address.
7. To cause Gosu to find and remap an external XSD download location in parsed XSD, set the
externalLocations attribute to the external XSD URL address. This value may also be useful for your own
reference, in case you need to download the latest version of the file.
Example
Sample schemalocations and schema elements are defined in the following example.
<?xml version="1.0"?>
<!-- XML namespaces and external schema locations can be registered in this file to
remap to local resources.
The remappings are used when either an <xsd:import> is encountered without a
<schemaLocation> element or an external schema location is specified. The
"externalLocations" attribute is a space-delimited list of external references to
recognize for a particular schema.
-->
<schemalocations xmlns="[Link]
<schema xmlNamespace="[Link]
resourcePath="gw/plugin/archiving/[Link]"
externalLocations=""/>
<schema xmlNamespace="[Link]
resourcePath="gw/api/importing/[Link]"
externalLocations=""/>
</schemalocations>
Example
Suppose you have this XSD loaded as [Link]:
<xsd:schema xmlns:xsd="[Link]
<xsd:element name="Element1"/>
<xsd:element name="Element2"/>
<xsd:element name="Element3"/>
</xsd:schema>
The following code prints the name of each element in the schema.
Element1
Element2
Element3
The following example uses the XSD of XSDs to print a list of primitive schema types:
[string, boolean, float, double, decimal, duration, dateTime, time, date, gYearMonth,
gYear, gMonthDay, gDay, gMonth, hexBinary, base64Binary, anyURI, QName, NOTATION]
See also
• “Parsing XML data into an XML element” on page 261
• “The metaschema XSD that defines an XSD” on page 287
xsd:anyURI [Link]
xsd:base64Binary byte[]
xsd:boolean [Link]
xsd:byte [Link]
xsd:date [Link]
xsd:dateTime [Link]
xsd:decimal [Link]
xsd:double [Link]
xsd:duration [Link]
xsd:ENTITY [Link]
xsd:ID [Link]
xsd:float [Link]
xsd:gDay [Link]
xsd:gMonth [Link]
xsd:gMonthDay [Link]
xsd:gYear [Link]
xsd:gYearMonth [Link]
xsd:hexBinary byte[]
xsd:IDREF [Link]<[Link]>
xsd:IDREFS [Link]<[Link]<[Link]>>
xsd:int [Link]
xsd:integer [Link]
xsd:language [Link]
xsd:long [Link]
xsd:Name [Link]
xsd:NCName [Link]
xsd:negativeInteger [Link]
xsd:NMTOKEN [Link]
xsd:NMTOKENS [Link]<[Link]>
xsd:nonNegativeInteger [Link]
xsd:nonPositiveInteger [Link]
xsd:normalizedString [Link]
xsd:NOTATION [Link]
xsd:positiveInteger [Link]
xsd:QName [Link]
xsd:short [Link]
xsd:string [Link]
xsd:time [Link]
xsd:token [Link]
xsd:unsignedByte [Link]
xsd:unsignedInt [Link]
xsd:unsignedLong [Link]
xsd:unsignedShort [Link]
Gosu has native support for JavaScript Object Notation (JSON) data format.
This dynamic access can be used to get and set data in a non-type-safe way with little effort.
However, you may want to generate actual JSON data from this type of structure, or parse complex JSON data into a
structure that you can naturally navigate from Gosu. Gosu provides a way of generating a type-safe class called a
structural type from JSON data, which can assist type-safe Gosu coding with JSON data.
See also
• “Structural types” on page 241
• “Dynamic types and expando objects” on page 233
• “Dynamic access to JSON objects” on page 292
• “Structural type-safe access to JSON objects” on page 295
• “Concise dynamic object creation syntax for JSON coding” on page 297
WARNING Dynamic access to JSON data is powerful and convenient but is not type safe. For
example, if you misspell a property name, the Gosu editor does not catch your error at compile
time.
uses [Link]
uses [Link]
// For this example, note that a String literal must use \" to escape quote symbols
//
// {"Name": "Andy Applegate",
// "Age": 29,
// "Hobbies": ["Swimming", "Hiking"]}
//
var jsonText = "{\"Name\": \"Andy Applegate\", \"Age\": 29, \"Hobbies\": [\"Swimming\", \"Hiking\" ] }"
var j : Dynamic = [Link](jsonText)
See also
• “Dynamic types and expando objects” on page 233
See also
• “Useful JSON API methods” on page 299
// Create a URL
var personUrl = new URL( "[Link] )
// Access the URL, parse the JSON text content to a Bindings object, return as [Link].
var person = [Link]
Note that any JSON property that contains an array becomes a standard Java list, which you can use with array index
syntax or loops.
[Link]
Create a URL of this type using the static Gosu enhancement method makeUrl on the [Link] class. Pass a
base URL as the first argument, and the JSON data as the second argument. The JSON data must be a bindings
object like [Link] or anything that implements interface [Link]. A
Gosu expando object, such as the Gosu class Expando, satisfies the Bindings requirement.
The following example Gosu code creates JSON-like data in two ways and generates a URL that uses the JSON data
for query arguments with String and number values. Numbers are coerced to a String to serialize them into text.
uses [Link]
uses [Link]
Note that space characters became + characters. This transformation is part of the process called URL encoding. Be
aware that some special characters may become multiple characters as part of URL encoding.
The previous example used Bindings values that were String objects or numbers. The makeUrl method also
supports values of other complex types:
• If the value is a [Link] object, a Gosu dynamic expando object, or a list, Gosu transforms the
object to JSON String data.
• Any other value is coerced to a String.
Finally, in all cases, the values are URL encoded before becoming part of the final URL.
The following example creates a new URL from a Bindings object with values that include one Bindings object
and one object of list type List<String>:
uses [Link]
uses [Link]
The URL output for this example is harder to read because of URL encoding of special characters such as braces,
comma characters, and new-line characters. Also, multiple + characters represent space characters for each line of
indented JSON.
This example prints the following, which is shown formatted with added new lines in the URL for clarity:
JSON of :Who = {
"FirstName": "Andy",
"LastName": "Applegate"
}
JSON of :Likes = [
"Hiking",
"Football"
]
URL encoding = [Link]
?Who=%7B%0A++%22FirstName%22%3A+%22Andy%22%2C%0A++%22LastName%22%3A+%22Applegate%22%0A%7D
&Likes=%5B%0A++++%22Hiking%22%2C%0A++++%22Football%22%0A++%5D
See also
• “Dynamic type” on page 233
• “Concise dynamic object creation syntax for JSON coding” on page 297.
• “Expando objects” on page 235
• “Useful JSON API methods” on page 299
See also
• “Dynamic access to JSON objects” on page 292
{
"Name": "Andy Applegate",
"Age": 29,
"Address": {
"Number": 123,
"Street": "Main St",
"City": "Foster City",
"State": "CA"
},
"Hobby": [
{
"Category": "Sport",
"Name": "Baseball"
},
{
"Category": "Recreation",
"Name": "Hiking"
}
]
}
4. In the Gosu Scratchpad, take the result of the previous step and call the toStructure method and pass the
following two arguments:
• A name of your new structural type, as a String
• A Boolean that represents whether the structural type is mutable. If you want only property getters but not
setters, pass the value false. If you want property getters and setters, pass the value true.
For example:
5. Print the result, which contains Gosu code for a new structural type based on the structure of your example
JSON data.
For example:
print(sj)
structure Person {
static function fromJson( jsonText: String ): Person {
return [Link]( jsonText ) as Person
}
static function fromJsonUrl( url: String ): Person {
return new [Link]( url ).JsonContent
}
static function fromJsonUrl( url: [Link] ): Person {
return [Link]
}
static function fromJsonFile( file: [Link] ) : Person {
return fromJsonUrl( [Link]().toURL() )
}
property get Address(): Address
property get Hobby(): List<Hobby>
property get Age(): Integer
property get Name(): String
structure Address {
property get Number(): Integer
property get State(): String
property get Street(): String
property get City(): String
}
structure Hobby {
property get Category(): String
property get Name(): String
}
}
6. To use the structural type in other types, you can do either of the following:
• To make a top-level type, copy and paste the structural type declaration into a new .gs file within your
desired package.
• To make an inner type, similar to an inner class in Gosu or Java, copy and paste the structural type
declaration into a class declaration.
See also
• “Parsing JSON from a URL” on page 293
• “Structural type-safe access to JSON objects” on page 295
• “Problematic property names for JSON structural types” on page 296
• “Useful JSON API methods” on page 299
property names. This makes it problematic to represent the structural type representation of this name as a Gosu
property name. JSON also supports object name fields that would be Gosu reserved keywords such as new or class,
and would cause syntax issues in type declaration or API usage.
For example, the following is legal JSON that requires special handling in Gosu structural types:
{
"Space Available": "8",
"new": "true",
"class": 1984
}
For problematic property names in generated structural types, Gosu generates alternative names that satisfy Gosu
property name syntax as follows:
• For illegal characters, Gosu substitutes the underscore character (_).
• For reserved keywords, Gosu reverses the case of the first character. Gosu keywords are case-sensitive, so this
removes the conflict.
In both cases, Gosu preserves the original names in the annotation @[Link].
For the previous example JSON, the generated structural type would include the following property getters and
setters, with the @ActualName annotation as needed:
structure TestStructuralType {
...
@[Link]( "new" )
property get New(): String
@[Link]( "class" )
property get Class(): Integer
@[Link]( "Space Available" )
property get Space_Available(): String
}
WARNING If there were problematic property names due to unusual characters or reserved Gosu
keywords, the name is changed automatically and preserved in the @ActualName annotation.
However, the data preserved by the annotation is unused by the built-in APIs to convert Gosu data
to JSON.
• Gosu supports dynamic non-type-safe access to properties and methods for variables of the type called
[Link]. No declaration of specific property names or method names is required in advance. For
programming contexts of type [Link], a newly instantiated object assumes the default run-time type
of Expando. The Expando class implements the Bindings interface. Gosu adds enhancement methods to this
class to convert to JSON (toJson), XML (toXml), or Gosu object initialization code (toGosu).
When you combine these features, you can create objects with multiple types of data without declaring any specific
structure in advance, and can convert to other formats as needed.
The following Gosu code creates a dynamic complex object and prints it in JSON syntax, XML syntax, and Gosu
object initialization syntax:
Working with JSON in Gosu 297
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
person = new() {
:Name = "John Smith",
:Age = 39,
:Address = new() {
:Number = 123,
:Street = "Main St.",
:City = "Foster City",
:State = "CA"
},
:Hobby = {
new() {
:Category = "Sport",
:Name = "Swimming"
},
new() {
:Category = "Recreation",
:Name = "Hiking"
}
}
}
print("**** To JSON:")
print([Link]())
print("**** To XML:")
print([Link]())
print("**** To Gosu:")
print([Link]())
**** To JSON:
{
"Name": "John Smith",
"Age": 39,
"Address": {
"Number": 123,
"Street": "Main St.",
"City": "Foster City",
"State": "CA"
},
"Hobby": [
{
"Category": "Sport",
"Name": "Swimming"
},
{
"Category": "Recreation",
"Name": "Hiking"
}
]
}
**** To XML:
<object>
<Name>John Smith</Name>
<Age>39</Age>
<Address>
<Number>123</Number>
<Street>Main St.</Street>
<City>Foster City</City>
<State>CA</State>
</Address>
<Hobby>
<li>
<Category>Sport</Category>
<Name>Swimming</Name>
</li>
<li>
<Category>Recreation</Category>
<Name>Hiking</Name>
</li>
</Hobby>
</object>
**** To Gosu:
new Dynamic() {
:Name = "John Smith",
:Age = 39,
:Address = new() {
:Number = 123,
:Street = "Main St.",
:City = "Foster City",
:State = "CA"
},
:Hobby = {
new() {
:Category = "Sport",
:Name = "Swimming"
},
new() {
:Category = "Recreation",
:Name = "Hiking"
}
}
}
Note that for the Gosu initializer syntax serialization, you can evaluate the String data at run time to create a Gosu
object:
See also
• “Optional omission of type name with the new keyword” on page 87
• “Object initializer syntax” on page 88
• “Dynamic types and expando objects” on page 233
[Link] fromJson String Parses JSON data as a String and converts it to the struc‐
tural type. To use natural Gosu syntax for properties of the
result, assign the result to a variable of type
[Link]. For example:
var j : Dynamic = [Link](jsonText)
fromJsonFile [Link] Get JSON data from a File object and convert it to the
structural type. To use natural Gosu syntax for properties of
the result, assign the result to a variable of type
[Link].
Templates
Gosu includes a native template system. Templates are text with embedded Gosu code within a larger block of text.
The embedded Gosu code optionally calculates and generates text in the location in which the code appears in the
template text.
Template overview
Templates are text with embedded Gosu code inside a larger block of text. The embedded Gosu code optionally
calculates and generates text at the location of the code in the template text.
Gosu provides the following mechanisms to use a Gosu template:
• Template syntax inside a text literal – Inside your Gosu code, use template syntax for an in-line String literal
value containing an embedded Gosu expression. Gosu template syntax combines static text that you provide with
dynamic Gosu code that executes at run time and returns a result. Gosu uses the result of the Gosu expression to
produce dynamic output at run time as a String value.
• Scriptlet syntax inside a text literal – Inside your Gosu code, use scriptlet syntax for in-line Gosu statements.
• Separate template file – Define a Gosu template as a separate file that you can execute from other code to
perform an action and generate output. If you use a separate template file, you can use additional features such as
passing custom parameters to your template.
See also
• “Using template files” on page 305
Template expressions
Use the following syntax to embed a Gosu expression in String text:
${ EXPRESSION }
For example, suppose you want to display text with some calculation in the middle of the text:
var mycalc = 1 + 1
var myVariable = "One plus one equals " + mycalc + "."
Instead of this multiple-line code, embed the calculation directly in the String as a template:
Templates 301
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Gosu evaluates your template expression at run time. The expression can include variables or dynamic calculations
that return a value:
At compile time, Gosu uses the built-in type checking system to ensure the embedded expression is valid and type
safe.
If the expression does not return a value of type String, Gosu attempts to coerce the result to the type String.
The result of the scriptlet tag at the beginning of the template does not generate any output. The statement inside the
scriptlet tags creates a variable MyCalc, and assigns the result of a calculation to that variable. The subsequent
expression uses the expression delimiters ${ and } to cause Gosu to retrieve the value of the variable MyCalc, which
is 3.
The scope of the Gosu code continues across scriptlet tags. Use this feature to write advanced logic that uses Gosu
code that you spread across multiple scriptlet tags. For example, the result of the following template code is “x is 5”
if the variable MyCalc has the value 5, otherwise the result is “MyCalc is not 5”:
The if statement controls the flow of execution of later elements in the template. You use this feature to control the
export of static text in the template as well as template expressions.
Scriptlet tags are particularly useful when used with template parameters because you can define conditional logic as
shown in the previous example.
302 chapter 22: Templates
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Use this syntax to iterate across lists, arrays, and other iterable objects. You can combine this syntax with the
expression syntax to generate output from the inner part of your loop. Remember that the scriptlet syntax does not
itself support generating output text.
For example, suppose you set a variable called MyList that contains a List of objects with a Name property. The
following template iterates across the list:
var str = "<% for (i in 1..5) { var odd = (i % 2 == 1) %>${i} is ${ (odd?"odd":"even") }\n<% } %>"
print(str)
1 is odd
2 is even
3 is odd
4 is even
5 is odd
IMPORTANT Gosu has no supported API to generate template output from within a template scriptlet.
Instead, design your template to combine template scriptlets and template expressions using the code
pattern in this topic.
See also
• “Template parameters” on page 307
var s = "Hello\${There"
var s = "Hello\<%There"
If your String uses the initial character of the template sequence, but the next character does not complete that
sequence, you do not need to escape the character. For example:
• To define a variable containing the non-template text "Hello$There", just use:
var s = "Hello$There"
var s = "Hello<There"
var quotedString = "\"This string has quotation marks around it\", is that correct?"
This code creates a String with the following value, including quotation marks:
If you use a template, this rule does not apply between your template-specific opening and closing tags that contain
Gosu code. Instead, use standard Gosu syntax for the code between those open and closing tags.
For example, the following two lines are valid Gosu code:
Note that the first character within the template’s Gosu block is an unescaped quotation mark.
The following code is invalid because of incorrect escaping of internal quotation marks:
In this invalid case, the first character in the template’s Gosu block is an escaped quotation mark.
In the rare case that your Gosu code requires creating a String literal containing a quotation mark character,
remember that the standard Gosu syntax rules apply. You need to escape any quotation marks inside the String
literal. For example, the following is valid Gosu:
var quotedString = "${ "\"This string has quotation marks around it\", is that correct?" }"
Note that the first character in the template’s Gosu block is an unescaped quotation mark. This template generates a
String with the value:
IMPORTANT Be careful with how you escape quotation mark characters within your embedded Gosu
code or other special template blocks.
See also
• “Template overview” on page 301
• “Running Gosu statements in a template scriptlet” on page 302
To create a new template within Studio, in the Project pane within the gsrc section, right-click a package. Next, click
New→Gosu Template. In the New Gosu Template dialog, type a meaningful name, and then click OK.
Rendering to a String
To run a template, get a reference to your template and call the renderToString method of the template. The
renderToString method returns the template results as a String value.
For example, suppose you create a template file [Link] within the package
[Link]. The fully qualified name of the template is [Link].
Use the following code to render your template:
var x = [Link]()
Rendering to a writer
Optionally, you can render the template directly to a Java writer object. Your writer must be an instance of
[Link]. Get a reference to the template and call its render method. Pass the writer as an argument to the
render method.
For example, suppose you create a template file [Link] within the package
[Link]. If the variable myWriter contains an instance of [Link], the following Gosu
statement renders the template to the writer:
[Link](myWriter)
If you use template parameters in your template, put your additional parameters after the writer argument.
See also
• “Template parameters” on page 307
Procedure
1. Using Studio, create a new template. In the Project pane within the gsrc section, right-click a package. Next,
click New→Gosu Template. In the New Gosu Template dialog, type a meaningful name, and then click OK.
For example, the fully qualified name of your template could be
[Link].
2. Use a template scriptlet to create a static array or other iterable object:
a. Use <% to begin your definition and type normal Gosu code to define the object.
b. Before ending the scriptlet, set up a variable with your data to export and optionally perform application
logic.
<% }
}%>
8. If Studio is running a server, you must load the changed file by remaking the project. From the menu, click
Build→Make Project.
9. In Gosu Scratchpad, run the template by using code like the following:
print([Link]())
Result
Running this code produces text like the following:
1 is a number
"Two" is not a number
3.0 is a number
Example
The complete code for this template file example looks like:
See also
• “Template parameters” on page 307
Template parameters
You can pass parameters of any type to your self-contained Gosu template files. The syntax for defining parameters
for a template is:
You can use template parameters in template files, but not in String literals that use template syntax. In a template
file, you can use a parameter in either the template expression syntax (${ and }) or template scriptlet syntax (<% and
%>). The expression syntax always returns a result and generates additional text. The scriptlet syntax executes Gosu
statements.
For example, suppose you create a template file [Link] within the package
[Link]. Edit the file to contain the following lines of code:
In this example, the if statement, including its trailing brace, is within scriptlet tags. The if statement uses the
parameter value at run time to conditionally run elements that appear later in the template. This template exports the
warning to call the human resources department only if the contactHR parameter is true. Use if statements and
other control statements to control the export of static text in the template as well as template expressions.
To run your template, you use the following code:
If you want to export to a character writer, use code like the following:
IMPORTANT Gosu has no supported API to generate template output from within a template scriptlet.
Instead, design your template to combine template scriptlets and template expressions using the code
pattern in this topic.
Procedure
1. Create a template file, for example, [Link].
2. At the top of the template file, create a parameter definition.
For example, the following argument list includes a String argument and a boolean argument:
3. Later in the template, use template tags that use the values of those parameters.
For example:
The person ${ personName } must update their contact information in the company directory.
4. If Studio is running a server, you must load the changed file by remaking the project. From the menu, click
Build→Make Project.
5. To run the template, add your parameters to the call to the renderToString method or after the writer
parameter to the render method.
For example, in the Gosu Scratchpad:
308 chapter 22: Templates
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
CLASSNAME must be a fully qualified class name. You cannot use a package name or hierarchy.
You can use the extends syntax in template files, but not in String literals that use template syntax.
Example
Suppose your template needs to clean up the email address with the sanitizeEmailAddress static method on the
class [Link]. The following template takes one argument that is an email address:
Notice that the class name does not appear immediately before the call to the static method.
See also
• “Modifiers” on page 157
Template comments
You can add comments within your template. Template comments do not affect template output.
The syntax of a template comments is the following:
You can use template comments in template files, but not in String literals that use template syntax.
For example:
My name is John.
Templates 309
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The query builder APIs let you retrieve information from PolicyCenter application databases. The API framework
models features of SQL SELECT statements to make object-oriented Gosu queries.
A query object
Specifies which PolicyCenter entity instances to fetch from the application database
A select object
Specifies how to order and group selected entity instances
The processing cycle of a PolicyCenter query follows these high-level steps:
1. Invoke the static [Link](EntityType) method, which creates a query object.
2. Refine your query object with restrictions.
3. Invoke the select method on your query object, which creates a select object.
4. Refine your select object by ordering the selected items.
5. Iterate your select object with methods that the [Link]<T> interface defines or with a for loop.
The following diagram illustrates the processing cycle of a query.
[Link](entity-type)
query-object
Add restrictions
query-object
[Link]()
select-object
Order by
select-object
The query builder APIs send queries to the application database when your code accesses information from the
result set, not when your code calls the select method. Although your code seems to order results after fetching
data, the query is not performed until you start to access the result set. The application database orders the results
while fetching data. Any action that you take on result objects to return information, such as getting result counts or
starting to iterate the result, triggers query execution in the application database.
JOIN table ON column var table = [Link](entity#foreign-key) Joins a dependent source of information to
the primary source, based on a related col‐
umn or field.
WHERE [Link](entity#field-name, Fetches information that meets specified cri‐
parameters) teria.
[Link](
entity#field-name, parameters)
[Link](entity#field-name,
parameters)
[Link](entity#field-name,
parameters)
[Link](entity#field-name,
parameters)
[Link](entity#field-name,
parameters)
[Link](entity#field-name,
parameters)
GROUP BY Implied by aggregate functions on fields Return results grouped by common values in
a field.
HAVING [Link]() Return results based on values from aggre‐
gate functions.
UNION var union = [Link](query2) Combine items fetched by two separate quer‐
ies into a single result.
Note: You cannot use the union method on
query objects passed as arguments to the
subselect method.
FIRST [Link] Limit the results to the first row, after group‐
ing and ordering.
TOP | LIMIT [Link](int) Limit the results to the first int number of
[Link](int) rows at the top, after grouping and ordering.
These query builder API methods provide
similar functionality in a portable way.
See also
• “Building a simple query” on page 314
• “Making an inner join with the foreign key on the right” on page 337
• “Working with row queries” on page 347
• “Joining a related entity to a query” on page 334
• “Restricting a query with predicates on fields” on page 317
• “Ordering results” on page 363
• “Applying a database function to a column” on page 350
• “Accessing the first item in a result” on page 366
• “Setting the page size for prefetching query results” on page 373
• “Determining if a result will return too many items” on page 367
In response, the relational database returns a result set that contains fetched information. A result set is like a
database table, with columns and rows, that contains the information that you specified with the SELECT statement.
In response to the preceding SQL example code, the relational database returns a result set that has the same
columns and rows as the addresses table.
The following Gosu code constructs and executes a functionally equivalent query to the preceding SQL example.
In response, the PolicyCenter application database returns a result object that contains fetched entity instances. A
result object is like a Gosu collection that contains entity instances of the type that you specified with the make
method and that meets any restrictions that you added. Calling the iterator method in the preceding Gosu code
causes the application database to fetch all Address instances from the application database into the result object.
The query builder API can use a view entity as the primary entity type in the same way as a standard entity. A view
entity can provide straightforward access to a subset of columns on primary and related entities.
See also
• Configuration Guide
In response, the relational database returns a result set with addresses only in the city of Chicago. In the preceding
SQL example, the Boolean expression applies the predicate = "Chicago" to the column city. The expression
asserts that addresses in the result set have “Chicago” as the city.
The following Gosu code constructs and executes a functionally equivalent query to the preceding SQL example.
uses [Link]
In response to the preceding Gosu code, the application database fetches all Address instances from the application
database that are in the city of Chicago.
The following Gosu code sorts the instances in the result object in the same way as the preceding SQL example.
uses [Link]
uses [Link] // Import the class that defines a column
uses [Link] // Import the class that builds a path to a column
See also
• “Ordering results” on page 363
uses [Link]
uses [Link]
uses [Link]
When the preceding code begins the for loop, the application database fetches Address instances in the city of
Chicago and sorts them by postal code. The for loop passes addresses in the result one at a time to the statements
inside the for block. The for block prints each address on a separate line.
Alternatively, the following Gosu code uses an iterator and a while loop to fetch matching Address instances in the
order specified.
uses [Link]
uses [Link]
uses [Link]
There are no consequential functional or performance differences between iterating results with a for loop and
iterating results with an iterator.
See also
• “Restricting query results by using fields on joined entities” on page 343
• “Restricting query results with fields on primary and joined entities” on page 345
See also
• Globalization Guide
With the query builder APIs, you apply predicates to entity fields by using methods on the query object. The
following Gosu code applies the compare method to values in the Name field of Company entity instances to select
the company “Acme Rentals.”
uses [Link]
In the result set, the values in the character field exactly match the comparison value that you provide to the
compare method, including the case of the comparison value. For example, the preceding query builder code selects
only “Acme Rentals,” but not “ACME Rentals.”
Query builder APIs 317
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Note: In configurations that use primary or secondary linguistic sort strength, the preceding query
builder code does not perform a case-sensitive comparison. If either of your PolicyCenter or the
relational database that your PolicyCenter uses have these configurations, the result includes both
“Acme Rentals” and “ACME Rentals.”
See also
• “Comparing a column value with a literal value” on page 327
• “Comparing a typekey column value with a typekey literal” on page 328
• Globalization Guide
The query builder APIs provide the compareIgnoreCase method for case-insensitive comparisons, as the following
Gosu code shows.
uses [Link]
IMPORTANT Your data model definition must specify the column with the attribute
supportsLinguisticSearch set to true. Otherwise, query performance suffers if you include the
column in a compareIgnoreCase predicate method.
See also
• Globalization Guide
With the query builder APIs, you use the between method to apply a range predicate to entity fields. The following
Gosu code applies the between method to values in the Name field of Company entity instances to select companies
with names between the values “Bank” and “Business.”
318 chapter 23: Query builder APIs
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
uses [Link]
The between method performs a case-sensitive comparison of the values in the character field to the comparison
values. For example, the preceding query builder code selects only “Building Renovators,” but not “building
renovators.”
Note: In configurations that use primary or secondary linguistic sort strength, the preceding query
builder code does not perform a case-sensitive comparison. If either of your PolicyCenter or the
relational database that your PolicyCenter uses have these configurations, the result includes both
“Building Renovators” and “building renovators.”
To perform a case-insensitive comparison on a range of values for a character field, use the compareIgnoreCase
method, as the following Gosu code shows.
uses [Link]
See also
• “Handling of null values in a range comparison” on page 325
The query result contains companies with names that begin with “Acme”.
With the query builder APIs, you apply partial comparison predicates that match from the beginnings of character
fields by using the startsWith method on the query object. Test the use of the startsWith method in a realistic
environment. Using the startsWith method as the most restrictive predicate on a query can cause a delay on the
user interface.
The following Gosu code applies the startsWith predicate method to values in the Name field on Company entity
instances.
uses [Link]
The sample code prints the names of companies that begin with “Acme”.
Note: The value false as the third argument of the startsWith method specifies case-sensitive
matching of values. In configurations that use primary or secondary linguistic sort strength, the
preceding query builder code does not perform a case-sensitive comparison. If either your
PolicyCenter application or the relational database that your PolicyCenter uses have these
configurations, the result includes the names of companies that begin with both “Acme” and
“ACME.”
See also
• “Case-insensitive partial comparisons of a character field” on page 321
• Globalization Guide
The query result contains activities with a subject that includes “Review” and that have a particular assigned user.
The following query uses the LIKE operator in the WHERE clause and causes a full table scan because there is no other
restriction on the primary table:
With the query builder APIs, you apply partial comparison predicates that match any portion of character fields by
using the contains method on the query object. Test the use of the contains method in a realistic environment.
Using the contains method as the most restrictive predicate on a query causes a full-table scan in the database
because the query cannot use an index.
WARNING For a query on a large table, using contains as the most restrictive predicate can
cause an unacceptable delay to the user interface.
The following Gosu code applies the contains predicate method to values in the Subject field on the Activity
instance for which a User instance is the assigned user.
uses [Link]
// Query the Activity instances for a particular user based on subject line.
var queryActivity = [Link](Activity)
This Gosu code prints the assigned user and the subject of the activity where the subject of the activity contains
“Review” and the assigned user has a particular public ID.
Note: The value false as the third argument of the contains method specifies case-sensitive
matching of values. In configurations that use primary or secondary linguistic sort strength, the
preceding query builder code does not perform a case-sensitive comparison. If either your
PolicyCenter application or the relational database that your PolicyCenter uses have these
configurations, the result includes the subjects of activities that contain both “Review” and “review.”
See also
• “Case-insensitive partial comparisons of a character field” on page 321
With the query builder APIs, you use the third parameter of the startsWith and contains methods to specify
whether to make the comparison in a case-insensitive way.
• true – Case-insensitive comparisons
• false – Case-sensitive comparisons
IMPORTANT In configurations using primary or secondary linguistic sort strength, query builder code
does not perform a case-sensitive comparison even if you use a value of false for the third parameter.
The following Gosu code applies the contains predicate method to values in the Subject field on the Activity
instance for which a User instance is the assigned user. The code requests a case-insensitive comparison with the
value true in the third parameter.
uses [Link]
// Query the Activity instances for a particular user based on subject line.
var queryActivity = [Link](Activity)
If you choose case-insensitive partial comparisons, Gosu generates an SQL function that depends on your
PolicyCenter and database configuration to implement the comparison predicate. If the data model definition of the
column sets the supportsLinguisticSearch attribute to true, Gosu uses the denormalized version of the column
instead.
See also
• Globalization Guide
% (percent sign)
Represents zero, one, or more characters
_ (underscore)
Represents exactly one character
The query builder API does not support the use of SQL wildcard characters in the startsWith or contains
predicate methods. If you include wildcard characters in the search-term parameter of either method, the query
builder methods escape their special meaning by preceding them with a backslash (\).
You use the initial parameter of the method, dateDiffPart, to specify the unit of measure for the result. You can
specify DAYS, HOURS, SECONDS, or MILLISECONDS. If endDate precedes the startDate, the method returns a negative
value for the interval, instead of a positive value.
uses [Link]
uses [Link]
uses [Link]
uses [Link]
Effect of daylight saving time on the return value of the DateDiff method
The DateDiff method does not adjust for daylight saving, or summer, time. For example, consider a locale in which
daylight saving time ends on the first Sunday in November. A call to the DateDiff method requests the number of
hours between the [Link] values 2017-11-04 12:00 and 2017-11-05 12:00. The method returns an
interval of 24 hours, even though 25 hours separate the two in solar time.
For the datePart parameter, you can specify HOUR, MINUTE, SECOND, DAY_OF_WEEK, DAY_OF_MONTH, MONTH, or YEAR.
When you specify DAY_OF_WEEK as the part to extract, the first day of the week is Monday.
The following Gosu codes uses the DatePart method to extract the day of the month from the due date on activities.
The query builder codes uses the returned numeric value in a comparison predicate to select activities that are due on
the 15th of any month.
uses [Link]
uses [Link]
uses [Link]
uses [Link]
// Order the result by assignment date and iterate the items fetched.
for (activity in ([Link]().orderBy(
[Link]([Link](Activity#AssignmentDate))))) {
print("Assigned on " + [Link] + ": " + [Link])
}
The following Gosu code uses the DateFromTimestamp method to extract the date from the creation timestamp on
activities. The query builder code uses the returned date in a comparison predicate to select activities that were
created some time during the current day.
uses [Link]
uses [Link]
uses [Link]
uses [Link]
uses [Link]
// Order the result by creation date and iterate the items fetched.
for (address in [Link]().orderBy([Link]([Link](Address#CreateTime)))) {
print([Link] + ": " + [Link])
}
uses [Link]
uses [Link]
uses [Link]
uses [Link]
uses [Link]
// Order the result by creation date and iterate the items fetched.
for (address in [Link]().orderBy([Link]([Link](Address#CreateTime)))) {
print([Link] + ": " + [Link])
}
See also
• “Handling of null values in a range comparison” on page 325
uses [Link]
The following Gosu code returns all Address instances where the first address line is known.
uses [Link]
After the bundle with the new Person instance commits, its DateOfBirth and NumDependents properties are null
in the database.
After the bundle with the new Address instance commits, all three address lines are null in the database. Before
PolicyCenter commits String values to the database, it trims leading and trailing spaces. If the result is the empty
string, PolicyCenter coerces the value to null.
Note that for non-null String properties, you must provide at least one non-whitespace character. You cannot work
around a non-null requirement by setting the property to a blank or empty string.
<column
desc="Primary email address associated with the contact."
name="EmailAddress1"
type="varchar">
<columnParam name="size" value="60"/>
<columnParam name="trimwhitespace" value="false"/>
</column>
The parameter controls only whether PolicyCenter trims leading and trailing spaces. You cannot configure whether
PolicyCenter coerces an empty string to null.
See also
• “String variables can have content, be empty, or be null” on page 59
The following example uses a subselect to find users that have created notes of the specified topic types:
The following Gosu code constructs and executes a functionally equivalent query to the preceding SQL example.
uses [Link]
uses [Link]
// Alternatively, use simpler syntax if you do not need to filter the inner query
// [Link](User#ID, [Link], Note#Author )
The subselect method is overloaded with many method signatures for different purposes. The preceding Gosu
code shows two of these method signatures.
The query builder APIs generate an SQL IN clause for the CompareIn method. The query builder APIs generate an
SQL NOT EXISTS clause for the CompareNotIn method. These methods do not accept a null value in the list of
values. A run-time error occurs if you provide a null value in set of comparison values.
Note: The ColumnRef object that the getColumnRef method returns does not implement the
IQueryBuilder interface. You cannot chain the getColumnRef method with other query builder
methods.
For example, you need to query the database for contacts where the primary and secondary email addresses differ.
The following SQL statement compares the two email address columns on a contact row with each other.
The following Gosu code constructs and executes a functionally equivalent query to the preceding SQL statement.
This Gosu code uses the getColumnRef method to retrieve the second email address property.
uses [Link]
var query = [Link](Contact) // Query for contacts where email 1 and email 2 do not match.
[Link](Contact#EmailAddress1, NotEquals, [Link]("EmailAddress2"))
for (contact in result) { // Execute the query and iterate the results
print("public ID '" + [Link] + " with name " + [Link]
+ " and emails " + contact.EmailAddress1 + "," + contact.EmailAddress2)
}
See also
• “Chaining query builder methods” on page 375
IMPORTANT Use the [Link] method with caution. If you are unsure, consult your
database administrator for guidance.
uses [Link]
// Query for addresses by using a Gosu literal to select addresses in Los Angeles.
var query = [Link](Address)
[Link](Address#City, Equals, "Los Angeles")
The code specifies a literal value for the predicate comparison, but the SQL query that the code generates uses the
value "Los Angeles" as a prepared parameter.
uses [Link]
uses [Link]
// Query for addresses by using an SQL literal to select addresses in Los Angeles.
var query = [Link](Address) // Query for addresses.
[Link](Address#City, Equals, [Link]("Los Angeles"))
[Link].TC_OPEN
The Address entity type has a typekey field named State that takes its values from the State typelist. The
following sample code uses the typekey literal for California to select and print all addresses in California.
uses [Link]
Use code completion in Studio to build complete object path expressions for typelist literals. To begin, type
typekey., and then work your way through the typelist names to the typekey code that you need.
See also
• “Typekeys and typelists” on page 64
• Configuration Guide
uses [Link]
uses [Link]
// Define the location of the center point for the distance calculation.
var SAN_MATEO = new SpatialPoint(-122.300, 37.550)
// Specify the spatial point in the address instance and the maximum distance from the center.
[Link](Address.SPATIALPOINT_PROP.get(), SAN_MATEO, 10, UnitOfDistance.TC_MILE)
The second code example uses the withinDistance method in connection with a more complex entity query that
joins a primary entity type with a related entity type. This query joins the Person entity type, which has a
PrimaryAddress property of type Address, with the Address entity type. The query then selects those Person
entity instances with a [Link] property that is within 10 miles of a SpatialPoint
constant representing San Mateo. The second code example is as follows:
uses [Link]
uses [Link]
// Explicitly join the Address entity for the primary address to the Person.
var addressTable = [Link](Person#PrimaryAddress)
// Define the location of the center point for the distance calculation.
var SAN_MATEO = new SpatialPoint(-122.300, 37.550)
// Specify the spatial point in the person's primary address and the maximum distance from the center.
[Link](Address.SPATIALPOINT_PROP.get(), "[Link]", SAN_MATEO, 10,
UnitOfDistance.TC_MILE)
Note: You cannot display the distance between the SpatialPoint property of an entity instance and a
SpatialPoint constant in an entity query. To do so would require a call to the Distance static
method in the DBFunction class, which is incompatible with entity queries. Only a row query can use
a static method in the DBFunction class to return a value. To display distances in conducting a
comparison, see “Using a distance function as a column selection” on page 351.
last_name = "Smith"
first_name = "John
To select the record that you need, both expressions must be true. You need a person’s last name to be “Smith” and
that same person’s first name to be “John.” You do not want only one of the expressions to be true. You do not want
to select people whose last name is “Smith” or first name is “John.”
For other requirements, you need to combine predicate expressions, any of which may be true, to select the items
that you want. For example, to select addresses from Chicago or Los Angeles also generally requires two predicates:
city = "Chicago"
city = "Los Angeles"
To select the addresses that you need, either expression may be true. You want an address to have either “Chicago”
or “Los Angeles” as the city.
With the query builder APIs, you combine predicates by calling predicate methods on the query object one after the
other if all must be true.
You can also use the and method to make the AND combination of the predicates explicit. For example, the following
code is equivalent to the previous example:
See also
• “Using Boolean algebra to combine sets of predicates” on page 331
With the query builder APIs, you combine predicates by calling the or method on the query object if one or more
must be true.
330 chapter 23: Query builder APIs
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
In the syntax specifications, OR_GROUPING_VAR and AND_GROUPING_VAR refer to a grouping variable name that
identifies the OR or AND link mode in each peer group of predicates. Guidewire recommends using a name for the
block parameter variable that indicates one of the following:
• Name describes the linking mode – Use a variable name that specifies the linking mode between predicates in
that group, such as or1 or and1. You cannot call the variable or or and because those words are language
keywords. Add a digit or other unique identifier to the words or or and.
• Name with specific semantic meaning – For example, use carColors for a section that checks for car colors.
• Consider creating multiple subqueries and using a union clause to combine subqueries.
Consider trying your query with both approaches, and then test production performance with a large number of
records.
In theory, you could use method chaining to use a single line of code, rather than using three separate lines. In this
case, chaining might make the code harder to understand.
Examples
For example, the following Gosu code links three predicates together with logical OR. The query returns rows if any
of the three predicates are true for that row.
// Find rows with creation date in the last 10 business days, last name of Newton, or first name of Ray
[Link]( \ or1 -> {
[Link](Person#CreateTime, GreaterThanOrEquals,
[Link]([Link](), -10))
[Link](Person#LastName, Equals, "Newton")
[Link](Person#FirstName, Equals, "Ray")
})
For example, the following Gosu code links three predicates together with logical AND. The query returns rows if all
three predicates are true for that row.
// Find rows with last name of Newton, first name of Ray, and creation date more than 14 days ago
[Link]( \ and1 -> {
[Link](Person#LastName, Equals, "Newton")
[Link](Person#FirstName, Equals, "Ray")
[Link](Person#CreateTime, LessThanOrEquals, [Link]([Link](), -14))
})
This code is functionally equivalent to simple linking of predicates, because the default linking mode is AND. The
following Gosu code shows the use of predicate linking to achieve the same query.
The power of the query building system is the ability to combine AND and OR groupings. For example, suppose we
need to represent the following pseudo-code query predicates:
(CreateTime < 10 business days ago) OR ( (LastName = "Newton") AND (FirstName = "Ray") )
The following code represents this pseudo-code query by using Gosu query builders:
The outer OR contains two items, and the second item is an AND grouping. This structure directly matches the
structure of the parentheses in the pseudo-code.
Similarly, suppose we need to represent the following pseudo-code query predicates:
The following code represents this pseudo-code using Gosu query builders:
[Link]([Link](), -90))
[Link](PolicyPeriod#CancellationDate, NotEquals, Null)
})
[Link]( \ or2 -> {
[Link](PolicyPeriod#BaseState, Equals, Jurisdiction.TC_FR)
[Link](PolicyPeriod#Locked, Equals, true)
})
Each OR contains two items, and the two OR items are combined using the default predicate linking mode of AND.
This structure directly matches the structure of the parentheses in the pseudo-code.
See also
• “Blocks” on page 175
In response to the preceding example SQL statement, the database returns a result set with all the rows in the
companies table that have a primary address. The result set includes columns for the companies and columns for
their primary addresses. The result set does not include companies without a primary address.
For example, the companies and addresses tables have the following rows of information:
companies:
id name primary_address
companies:
id name primary_address
addresses:
id street_address city postal_code
The preceding example SQL statement returns the following result set.
c:1 Hoffman Associates a:1 a:1 123 Main St. White Bluff AB-2450
c:2 Golden Arms Apartments a:2 a:2 45112 E. Maplewood Columbus EF-6370
c:4 North Creek Auto a:3 a:3 3945 12th Ave. Arlington IB-4434
c:5 Jamison & Sons a:4 a:4 930 Capital Way Arlington IR-8775
The columns in the result set are a union of the columns in the companies and addresses tables. The company
named “Industrial Wire and Chain” is not in the result set. That row in the companies table has null as the value for
primary_address, so no row in the addresses table matches.
uses [Link]
Using the sample data shown earlier, the preceding query builder API query produces the following result.
The Company named “Industrial Wire and Chain” is not in the result object. This instance has null as its
primary_address, so no instance of Address matches.
A significant difference from SQL is that the query builder API return only instances of the primary entity type.
With the query builder API, you use dot notation to access information from the joined entity type. For example:
uses [Link]
The preceding Gosu code fetches the Address instance lazily from the database. If the record is not available in the
cache, this code could cause the execution of a query for every company. To reduce the number of database queries,
you can use a row query to retrieve the complete set of rows and the necessary columns from the primary and joined
tables.
See also
• “Working with row queries” on page 347
Inner join
Excludes rows/instances on the left that have no matches on the right.
In SQL, it generally does not matter which side of the join provides the foreign key nor whether the foreign key is
defined in metadata. All that matters is for one side of the join to have a column or property with values that match
values in the column of another table or property.
The query builder API uses different signatures on the join method depending on which side of a join provides the
foreign key.
• join(primaryEntity#column) – Joins two entities that have the foreign key is on left
• join(secondaryEntity#column) – Joins two entities that have the foreign key is on the right.
• join("columnPrimary", table, "columnDependent") – Joins two entities without regard to foreign keys.
With the query builder API, you use the join method to specify an inner join. Use a property reference of the
primary entity and property name as the single parameter if the primary entity has the foreign key. In these cases, the
foreign key is on the left. You specify a property of the primary entity that the Data Dictionary defines as a foreign
key to the dependent entity. The query builder API uses metadata to determine the entity type to which the foreign
key relates.
In the following Gosu code, the primary entity type, Company, has a foreign key, PrimaryAddress, which relates to
the dependent entity type, Address.
Unlike SQL, you do not specify which dependent entity to join, in this case Address. Neither do you specify the
property on the dependent entity, ID. The query builder API uses metadata from the Data Dictionary to provide the
missing information.
With the query builder APIs, you use the join method to specify an inner join. Use a property reference of the
dependent entity and property name as a single parameter if the dependent entity has the foreign key. In these cases,
the foreign key is on the right. The database must have a column that contains the foreign key. The data model
definition of the column must specify foreignkey. You cannot use a column that is a onetoone or edgeForeignKey
type because these types do not use a database column. To confirm that a foreign key uses a database field, in the
Data Dictionary, check that the foreign key does not have “(virtual property)” text after its name.
Query builder APIs 337
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Similarly to SQL, you must specify the dependent entity to join, which in this case is Address. Unlike SQL, you do
not specify the property on the primary entity, ID. The query builder APIs use metadata from the Data Dictionary to
provide the missing information.
uses [Link]
uses [Link]
// -- Select only User instances who last updated addresses in the city of Chicago --
var tableAddress = [Link](Address#UpdateUser)
[Link](Address#City, Equals, "Chicago")
// -- Fetch the User instances with a for loop and print them --
var result = [Link]()
See also
• “Restricting query results by using fields on joined entities” on page 343
• “Working with row queries” on page 347
• “Handling duplicates in joins with the foreign key on the right” on page 341
Test the use of an inner join that you make without regard to foreign keys in a realistic environment. Using this
technique on a query can cause a full-table scan in the database if the query cannot use an index.
WARNING For a query on large tables, using an inner join without regard to foreign keys can
cause an unacceptable delay to the user interface.
With the query builder API, you use the join method with the following signature to make inner joins of entities
without regard to foreign keys in the data model.
The first parameter is the name of a column on the primary entity of the query. The second and third parameters are
the names of the dependent entity and the column that has matching values.
Example
In the following Gosu code, the primary entity Note has no declared foreign key relation with the dependent entity
Contact. An indirect relation exists through their mutual foreign key relations with the User entity. Both entities in
the query have a column that contains the user ID, so the join method can join the Contact entity to the query of the
Note entity.
uses [Link]
// -- fetch the Note instances with a for loop and print them --
var result = [Link]()
The Note entity has no direct relevant foreign key relation to Contact. You cannot use Gosu dot notation to navigate
from notes in the result to properties on the contact.
Making a left outer join with the foreign key on the left
In SQL, you make a left outer join with the LEFT OUTER JOIN keywords. You specify the table that you want to join
to the primary table of the query. The ON keyword lets you specify which columns join the tables. In the following
SQL statement, the foreign key, supervisor, is on the primary table, groups. So, the foreign key is on the left side.
With the query builder APIs, use the outerJoin method with a single parameter if the primary entity has the foreign
key. In these cases, the foreign key is on the left. You specify a property of the primary entity that the Data
Dictionary defines as a foreign key to the dependent entity. The query builder APIs use metadata to determine the
entity type to which the foreign key the relates.
Notice that unlike SQL, you do not specify which dependent entity to join, in this case User. Neither do you specify
the property on the dependent entity, ID. The query builder APIs use metadata from the Data Dictionary to fill in the
missing information.
uses [Link]
uses [Link]
// -- Select only User instances who last updated addresses in the city of Chicago --
var tableAddress = [Link](Address#UpdateUser)
// -- Fetch the User instances with a for loop and print them --
var result = [Link]()
A query that you create by using join or outerJoin with the foreign key on the right of the join often fetches
duplicate instances of the primary entity. For example, the following Gosu code finds users that have updated
addresses.
For the previous example, if multiple Address instances relate to the same User, the result includes duplicates of
that User instance. One instance exists in the result of the join query for each child object of type Address that
relates to that instance.
Duplicate instances of the primary entity in a query result are desirable in some cases. For example, if you intend to
iterate across the result and extract properties from each child object that matches the query, this set of rows is what
you want. In cases for which you need to return a single row from the primary table, you must design and test your
query to ensure this result.
For joins with the foreign key on the right, try to reduce duplicates on the primary table. The best way to reduce
duplicates is to ensure that the secondary table only has one row that matches the entity on the primary table.
If you cannot eliminate duplicates in this way, other approaches can limit duplicates created because of a join:
• Rewrite to use the subselect method approach. For joins with the key on the right, the query optimizer often
performs better with subselect than with join or outerJoin. However, using the join method might perform
better in some cases. For example, consider using join if the dependent entity includes predicates that are not
very selective and return many results. For important queries, Guidewire recommends trying both approaches
under performance testing. If you use join with the foreign key on the right, use the two-parameter method
signature that includes the table name followed by the column name in the joined table.
• Call the withDistinct method on Query to limit the results to distinct results from the join. Pass the value true
as an argument to limit the query results to contain only a single row for each row of the parent table. To turn off
this behavior later, call the method again and pass false as an argument. For example:
• Add predicates to the secondary table to limit what your query matches. For example, only match entities on the
primary table if a related child object has a certain property with a specific value or range of values.
Query builder APIs 341
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The following example adds predicates after the join using properties on the joined table:
See also
• “Working with row queries” on page 347
Because the Contact property exists on the Organization entity type, the following code also joins organizations to
contacts and does not join only company records:
If you want to access company properties or only need to see organizations that have a company as a contact, you
must cast the joined table to Company. Use code like the following lines:
If the column that you use to join the dependent table is specific to a particular subtype of an entity type, the query
builder API performs the more restrictive join. In this case, you do not need to cast the type of the joined table.
uses [Link]
uses [Link]
for (a in result) {
// Use a variable to access properties on the Submission entity type
var sj = [Link] as Submission
print(a + " " + [Link] + " " + [Link] + " " + [Link])
}
Using the query API, the primary entity type of your query is Company, because you want instances of that type in
your result.
The Company entity does not have a City property. That property is on the Address entity. You need to join the
Address entity to your query. You must capture the object reference that the join method returns so that you can
specify predicates on values in Address.
Alternatively, you can chain the join method and call the predicate method on the returned Table object in a single
statement, as the following Gosu code shows. If you use this pattern, you do not need to make a variable for the
Table object.
When you run the query, the result contains companies that have Chicago as the city on their primary addresses. The
following code demonstrates the use of this predicate on a joined entity.
uses [Link]
uses [Link]
The query result of the previous example contains only Company instances. Even though the code includes the
Address entity in the query, the results do not include information from joined entities. The code example uses dot
notation to access information from related Address instances after retrieving Company instances from the result. By
joining Address to the query and applying the predicate, the code ensures that Company instances in the result have
only “Chicago” in the property [Link].
Predicates on the left outer join dependent entity differ from SQL
With the query builder APIs, generally you join a dependent entity to a query only so you can restrict the results
with predicates on the dependent entity. Using the compare method to apply a predicate to a dependent entity that
you join with a left outer join has no effect on the rows that Gosu retrieves.
The ways that SQL queries and Gosu code filter the dependent table rows differ. Gosu fetches the dependent entity
only if necessary, if code that accesses the dependent entity executes. Gosu applies the filter when running the query
on the primary table, not when fetching the dependent table row. The value of a dependent entity property that you
access by using dot notation is null only if there is no matching entity instance regardless of the filter. To retrieve
filtered values from related entities, use a row query.
For example, the following SQL filters the names of group supervisors. If the name does not match, the value for the
supervisor user and contact columns are null.
The following Gosu code shows the effect of dot notation to access information related to the primary entity of an
outer-join query. The code accesses the DisplayName information for the group supervisor from the User entity with
344 chapter 23: Query builder APIs
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
dot notation on Group instances retrieved from the result. The output shows the supervisor name for every group
because Gosu applies the filter on the primary table query, not when print retrieves the property values for related
entities.
uses [Link]
See also
• “Restricting a query with predicates on fields” on page 317
• “Restricting query results with fields on primary and joined entities” on page 345
• “Working with row queries” on page 347
Using the query API, the primary entity type of your query is Company, because you want instances of that type in
your result. You add the predicate that specifies the restriction on the Name property.
The Company entity does not have a City property. That property is on the Address entity. You need to join the
Address entity to your query. You must capture the object reference that the join method returns so that you can
specify predicates on values in Address.
When you run the query, the result contains companies that have Chicago as the city on their primary addresses.
uses [Link]
uses [Link]
// Start a new query with Company as the primary entity and restrict the result by company name.
var queryCompany = [Link](Company).compare(Company#Name, Equals, "Stewart Media")
You can add predicates to the primary entity of a query before or after you join a new entity to the query. For
example, the following code adds a predicate to the primary entity before joining the secondary entity:
uses [Link]
uses [Link]
The following code adds a predicate to the primary entity after joining the secondary entity, and is equivalent to the
previous code example:
uses [Link]
uses [Link]
Using the query API, the primary entity type of your query is Company, because you want instances of that type in
your result.
The Company entity does not have a City property. That property is on the Address entity. You need to join the
Address entity to your query. You must capture the object reference that the join method returns so that you can
specify predicates on values in Address. You use an or block to add the predicate that specifies the restriction on the
Name property in the Company entity. You must use a column reference to access the Name column because that
column is not in the Address entity.
When you run the query, the result contains companies that have Chicago as the city on their primary addresses.
uses [Link]
uses [Link]
See also
• “Restricting a query with predicates on fields” on page 317
• “Restricting query results by using fields on joined entities” on page 343
See also
• “Limitations of row queries” on page 355
• Configuration Guide
See also
• “Applying a database function to a column” on page 350
• “Paths” on page 377
• “Aggregate functions in the query builder APIs” on page 385
[Link]([Link](Contact#ID))
[Link]("ContactID", [Link](Contact#ID))
[Link]([Link](Contact#CreateUser, User#Credential, Credential#UserName))
The following Gosu code sets up a row query that returns the columns Subtype, FirstName, and LastName for all
Person entity instances and prints the values for each row.
uses [Link]
uses [Link]
uses [Link]
Using foreign key properties and type key properties in row queries
Selecting a foreign key or type key property as a column in a row query does not provide access to the properties of
the entity instance or type code. If you select a column that is a foreign key to a record in another database table, the
column provides the identifier value of that record. The type of the foreign key column is
[Link]. If you select a column that is a type key, the column provides the value of the type
code. The type of the type key column is the corresponding typekey class. For example, the type of an address type
typekey is [Link].
The following Gosu code sets up a row query that returns the columns AddressType and CreateUser for all
Address entity instances and prints the values for each row.
uses [Link]
uses [Link]
uses [Link]
The output from this code looks like the following lines.
business null
business 3
...
home 9
...
See also
• “Transforming results of row queries to other types” on page 353
• “Accessing data from virtual properties, arrays, or keys” on page 354
To create a positional column that you reference by number, starting from 0, you use the path method on
QuerySelectColumns. To create a named column, you use the pathWithAlias method. You use methods on the
DBFunction class to apply a database aggregate function to a column. For example, the following Gosu expressions
both select the maximum value in the CreateTime column from the Address table. The second expression gives the
alias NewestAddr to the column.
[Link]([Link]([Link](Address#CreateTime)))
[Link]("NewestAddr", [Link]([Link](Address#CreateTime)))
uses [Link]
uses [Link]
uses [Link]
uses [Link]
The query returns the time of the most recent address creation for each country.
See also
• “Aggregate functions in the query builder APIs” on page 385
uses [Link]
uses [Link]
uses [Link]
uses [Link]
uses [Link]
// Make a query on the Address entity. Remove duplicate entities from the query.
var addressQuery = [Link](Address).withDistinct(true)
// Define the location of the center point for the distance calculation.
var SAN_MATEO = new SpatialPoint(-122.300, 37.550)
// Specify the spatial point in the address instance and the maximum distance from the center.
[Link](Address.SPATIALPOINT_PROP.get(), SAN_MATEO, 10, UnitOfDistance.TC_MILE)
The second code example constructs a row query, personQuery. This query returns the name, primary address, and
distance from San Mateo for all people in the database having a primary address that is within ten miles of San
Mateo. The code example then prints the results of the query.
The call to the Distance method takes the row query, personQuery, as a first parameter. As a second parameter, the
Distance method takes the String name of the location property that pinpoints the primary address of each
identified Person. This String name is "[Link]." The second code example is as
follows:
uses [Link]
uses [Link]
uses [Link]
uses [Link]
uses [Link]
// Explicitly join the Address entity for the primary address to the Person.
var addressTable = [Link](Person#PrimaryAddress)
// Define the location of the center point for the distance calculation.
var SAN_MATEO = new SpatialPoint(-122.300, 37.550)
// Specify the spatial point in the person's primary address and the maximum distance from the center.
[Link](Address.SPATIALPOINT_PROP.get(), "[Link]", SAN_MATEO, 10,
UnitOfDistance.TC_MILE)
IMPORTANT Choose the type that you want for the result carefully. Performance characteristics vary
depending on the type that you choose.
uses [Link]
uses [Link]
uses [Link]
class ShortContact {
var _subType : [Link] as Subtype
var _name : String as Name
construct(st : [Link], n : String){
_subType = st
_name = n
}
}
Sometimes you only need a single column from each entity. In these cases, you use a simpler syntax for the
argument to transformQueryRow. For example, to change the preceding code to retrieve just the PName column
instead of a ShortContact object, use the following line that returns an IQueryResult<Person, String> object.
See also
• “Blocks” on page 175
• “Using generics with collections and blocks” on page 228
• “Setting the page size for prefetching query results” on page 373
uses [Link]
uses [Link]
uses [Link]
To run the preceding code in the Gosu Scratchpad, use the method [Link] instead of
[Link]. Enclose the remaining code in a code block, as shown in the following code.
On your production system, Guidewire strongly recommends that you do not use the Guidewire sys user (System
User), or any other default user, to create a new bundle.
See also
• “Building a simple query” on page 314
See also
• “Transforming results of row queries to other types” on page 353
• “Comparison of entity and row queries” on page 357
• “Performance differences between entity and row queries” on page 370
If you want to use aggregate functions such as Avg, Count, Min, Max, and Sum, be aware of the following:
• MonetaryAmount objects cannot be used in aggregate functions.
• The individual properties [Link] and [Link] are normal properties for
the query builder APIs. For example, you can use Sum on the [Link] property, or use Count on
the [Link] property.
See also
• “Setting the page size for prefetching query results” on page 373
[Link]()
• Row queries – Result objects contain a set of row-like structures with values fetched from or computed by the
relational database. You set up a row query by passing a Gosu array of column selections to the select method.
For example:
[Link]({
[Link]([Link](Person#Subtype)),
[Link]("FName", [Link](Person#FirstName)),
[Link]("LName", [Link](Person#LastName))
})
The preceding sample code sets the primary entity type for the query to Company. Regardless of related entity types
that you join to the primary entity type, the result contains only instances of the primary entity type, Company.
To set up the preceding query as an entity query, call the select method without parameters, as the following Gosu
code shows.
var entityResult = [Link]() // The select method with no arguments sets up an entity query.
The members of results from entity queries are instances of the type from which you make queries. In this example,
the members of entityResult are instances of Company. After you retrieve members from the results of entity
queries, use object path notation to access objects, methods, and properties from anywhere in the object graph of the
retrieved member.
The following Gosu code prints the name and the city of the primary address for each Company in the result. The
Name property is on a Company instance, while the City property is on an Address instance.
356 chapter 23: Query builder APIs
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
for (company in entityResult) { // Members of a result from entity query are entity instances.
print ([Link] + ", " + [Link])
}
The preceding sample code sets the primary entity type for the query to Company. You can join other entity types to
the query and specify restrictions, just like you can with entity queries. Unlike entity queries however, the results of
row queries do not contain entity instances.
The results of row queries contain values selected and computed by the relational database, based on the column
selection array that you pass to the select method. To set up the preceding query as a row query, call the select
method and pass a Gosu array that specifies the columns you want to select for the result.
uses [Link]
uses [Link]
uses [Link]
The members of results from row queries are structures that correspond to the column selection array that you
specify.
After you retrieve a member from the result of a row query, you can only use the values the member contains. You
cannot use object path notation with a retrieved member to access objects, methods, or properties from the domain
graph of the primary entity type of the query.
The following Gosu code prints the company name and the city of the primary address for each Company in the
result. The result member provides the Name column and the City column.
for (company in rowResult) { // Members of a result from a row query are QueryRow objects.
print ([Link]("Name") + ", " +
[Link]("City") + ", " +
[Link](2))
}
You can only access columns from the members of a row result if you specified them in the column selection array.
See also
• “Paths” on page 377
See also
• “Performance differences between entity and row queries” on page 370
See also
• “Using standard query filters in toolbar filters” on page 361
Note: The package [Link] contains predefined standard query filters that you can apply as
needed.
uses [Link]
uses [Link]
Use the addFilter method when you need a single result to have one or more query filters in effect at the same
time.
uses [Link]
uses [Link]
uses [Link]
// Create a standard query filter for addresses added during 2017 or later.
var queryFilter2017Address = new StandardQueryFilter("2017 Addresses",
\ query -> {[Link](Address#CreateTime, GreaterThanOrEquals,
[Link](1, 1, 2017))})
print([Link] + ", " + [Link] + " " + [Link] + " " + [Link])
}
If you add more than one standard query filter to a result, make sure that each filter predicate applies to a different
field in the result. If you add two or more standard query filters with predicates on the same field, Boolean logic
ensures that no item in the result satisfies them all.
uses [Link]
uses [Link]
uses [Link]
uses [Link]
// Create a standard query filter for addresses in the cities of Bloomington or Chicago.
var queryFilterBloomingtonOrChicago = new StandardQueryFilter("Bloomington and Chicago Addresses",
\ query -> {[Link]( \ orCriteria -> {
[Link](Address#City, Equals, "Bloomington")
[Link](Address#City, Equals, "Chicago")
})
})
See also
• “Combining predicates with AND and OR logic ” on page 330
uses [Link]
uses [Link]
uses [Link]
uses [Link]
uses [Link]
[Link]() // Remove any filters added by the subroutine from the result.
processChicago(result)
[Link]() // Remove any filters added by the subroutine from the result.
processEvanston(result)
[Link]() // Remove any filters added by the subroutine from the result.
// Subroutines
Note: The previous code block for the single-line filter option field in the PCF editor contains line
breaks and extra spaces for readability. If you copy and paste this code, remove these line breaks and
spaces to make the code valid.
The toolbar filter uses the first parameters of the filters to provide two options, “All” and “With errors”, in the
toolbar filter drop-down menu.
For single filter options, you can override the text of the drop-down menu of with the label property. For
localization purposes, you must specify the filter name or the label property as a display key, not as a String literal.
new [Link][] {
new [Link]("All", \ q -> {}),
new [Link]("With errors",
\ q -> [Link]("Exceptions", [Link], 0))}
Note: The previous code block for the single-line filters option field in the PCF editor contains line
breaks and extra spaces for readability. If you copy and paste this code, remove these line breaks and
spaces to make the code valid.
The toolbar filter displays the first parameters of the filters, “All” and “With errors”, as options in the toolbar filter
drop-down menu. The drop-down menu displays them together and in the order that you specify in the array
constructor.
Group filter options do not have a label property, so the text of the menu options comes only from the filter names.
For localization purposes, you must specify the filter names as display keys, not as String literals.
[Link]
If you disable filter caching, the list view reverts to the default filter option for entry to the page. You specify the
default filter option by setting the selectOnEntry property on the option to true. Alternatively, you specify the
default filter option by moving the option to the top of the list of options on the Filter Options tab.
Ordering results
By default, SQL Select statements and the query builder APIs return results from the database in no specific order.
Results in this apparently random order might not be useful. SQL and the query builder APIs support specifying the
order of items in the results.
With SQL, the ORDER BY clause specifies how the database sorts fetched data. The following SQL statement sorts
the result set on the postal codes of the addresses.
The following Gosu code uses the orderBy ordering method to sort addresses in the same way as the preceding SQL
example.
uses [Link]
uses [Link]
uses [Link]
var resultAddresses = [Link]() // Execute the query and iterate the ordered results.
The query builder APIs use the object path expressions that you pass to ordering methods to generate the ORDER BY
clause for the SQL query. Gosu does not submit the query to the database until you begin to iterate a result object.
The database fetches the items that match the query predicates, sorts the fetched items according to the ordering
methods, and returns the result items in that order.
Method Description
orderBy Clears all previous ordering, and then orders results by the specified column in ascending order.
orderByDescending Clears all previous ordering, and then orders results by the specified column in descending order.
thenBy Orders by the specified column in ascending order, without clearing previous ordering.
thenByDescending Orders by the specified column in descending order, without clearing previous ordering.
The ordering methods all take an object that implements the IQuerySelectColumn interface in the
[Link] package as their one argument. To create this object, use the following syntax.
[Link]([Link](PrimaryEntity#SimpleProperty))
The [Link] method yields an object access path from the primary entity to a simple, non-foreign-key, database-
backed property. Gosu checks property names against column names in the Data Dictionary. To specify a path to a
property on a dependent table, specify a foreign-key property to the dependent table on the previous table parameter.
For example, the following Gosu code specifies a simple property, the PostalCode on an Address instance.
[Link]([Link](Address#PostalCode))
See also
• “Paths” on page 377
• “Locale sensitivity for ordering query results” on page 364
• Globalization Guide
uses [Link]
uses [Link]
uses [Link]
The following Gosu code constructs and executes a query that is functionally equivalent to the preceding SQL
example.
uses [Link]
uses [Link]
uses [Link]
You can call the ordering methods thenBy and thenByDescending as many times as you need.
Note: In configurations that use primary or secondary linguistic sort strength, the ordering of results is
case-insensitive. If either of your PolicyCenter or the relational database that your PolicyCenter uses
have these configurations, the query result includes ignores the case of String values. For example, in
these configurations, “Building Renovators” and “building renovators” are adjacent in the results.
See also
• “Sorting lists or other comparable collections” on page 190
• “List of enhancement methods on collections” on page 195
• Globalization Guide
uses [Link]
result = [Link]()
if ([Link]) {
...
}
Alternatively, you can test the Count property against zero or iterate a result object inside a while loop with a
counter and then test the counter for zero. Relational query performance often improves if you use the Empty
property.
Unsafe usage:
// Bad example. Do NOT follow this example. Do NOT rely on the result count staying constant!
uses [Link]
// create a query
var query = [Link](User)
Code like the previous example risks throwing array-out-of-bounds errors at run time. Adding a test to avoid the
exception risks losing records from the result.
Instead, iterate across the set and count upward, appending query result entities to an ArrayList.
Safe usage:
uses [Link]
uses [Link]
Calling [Link]() does not snapshot the current value of the result set forever. When you access the
[Link]().Count property, PolicyCenter runs the query but the query results can change quickly. Database
changes could happen in another thread on the current server or on another server in the cluster.
uses [Link]
firstPerson = [Link]().FirstResult
As an alternative, you can iterate a result and stop after retrieving the first item. However, relational query
performance often improves when you use the FirstResult property to access only the first item in a result.
Note: To find the last item in a result, reverse the order of the rows by calling the orderByDescending
method.
uses [Link]
IMPORTANT Do not use the where method on lists, arrays, collections, or sets returned by conversion
methods on result objects. Instead, apply all selection criteria to query objects by using predicate
methods before calling the select method.
Converting a query result to these types executes the database query and iterates across the entire set. The
application pulls all entities into local memory. Because of limitations of memory, database performance, and CPU
performance, never do this conversion for queries of unknown size. Only do this conversion if you are absolutely
certain that the result set size and the size of the object graphs are within acceptable limits. Be sure to test your
assumptions under production conditions.
Query builder APIs 367
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
WARNING Converting a query result to a list or array pulls all the entities into local memory. Do
this conversion only if you are absolutely certain that the result set size and the size of the objects
are small. Otherwise, you risk memory and performance problems.
If you need the results as an array, you can convert to a list and then convert that to an array using Gosu
enhancement methods.
The following example converts queries to different collection-related types, including arrays:
uses [Link]
See also
• “Transforming results of row queries to other types” on page 353
to the database. For example, you use custom batch processing to flag contacts that your users need to call the next
day.
IMPORTANT Entities must not exist in more than one writable bundle at a time.
For example:
At the time the execution context for the preceding code finishes, the application commits all changes made to
addresses in the current bundle to the database.
The Gosu Scratchpad does not have a current bundle, so you must create a new bundle. To run the preceding code in
the Gosu Scratchpad, use the method [Link] instead of [Link].
Enclose the remaining code in a code block:
To see the effects of the preceding code, run the following Gosu code.
See also
• “Bundles and database transactions” on page 387
• Integration Guide
[Link]()
• Row queries – Result objects contain a set of row-like structures with values fetched from or computed by the
relational database. You set up a row query by passing a Gosu array of column selections to the select method.
For example:
[Link]({
[Link]([Link](Person#Subtype)),
[Link]("FName", [Link](Person#FirstName)),
[Link]("LName", [Link](Person#LastName))
})
Some situations require entity queries. For example, in page configuration, you must use entity queries as the data
sources for list views and detail panels. Other situations require row queries. For example, you must use row queries
to produce the results of SQL aggregate queries or outer joins. In yet other cases, you can use either type of query.
For example, you can use either entity or row queries in Gosu code used in batch processing types.
You can reduce the number of queries implicitly executed by row queries if you select specific fields rather than
entity instances. If you specify fields rather than instances, the relational database fetches and computes values in
response to the SQL query that the query builder expression submits to the database.
See also
• “Limitations of row queries” on page 355
uses [Link]
[]
SELECT /* pc:T:Gosu class redefiner; */ FROM pc_contact gRoot WHERE [Link] = 0
The first line shows square brackets ([]) containing the list of variables to bind to the query. In this case, there are
no variables. The remaining lines show the SQL statement. Note that the table for the entity type, pc_contact, has
the table alias gRoot.
After you join a related entity to a query or apply a predicate, use the toString method to see what the query
builder APIs added to the underlying SQL statement.
Note: The toString method returns only an approximation of the SQL statement that PolicyCenter
submits to the application database. The actual SQL statement might differ due to database
optimizations that PolicyCenter applies internally.
uses [Link]
var i = [Link]() // -- write the SQL statement to the system logs here --
while ([Link]()) {
var person = [Link]()
print ([Link] + ", " + [Link] + ": " + person.EmailAddress1)
}
The SQL Select statement for the preceding example looks like the following on standard output.
The statement on your system depends on your relational database and might differ from the preceding example.
Note: Writing to the system logs and to standard output does not occur when Gosu code calls the
withLogSQL method. That logging occurs some time later, when PolicyCenter submits the query to the
relational database.
/* applicationName:ProfilerEntryPoint */
uses [Link]
IMPORTANT Use the withFindRetired method on queries only under exceptional circumstances that
require exposing retired entities.
uses [Link]
Other notes:
• If you plan to modify the entities, you must use a transaction.
• In production code, you must not retrieve too many items and keep references to them. Memory errors and
performance problems can occur. Design your code to limit the result set that your code returns.
IMPORTANT Always test database performance under realistic production conditions before and after
changing any performance tuning settings.
See also
• “Updating entity instances in query results” on page 368
Languages other than English have other character modifications that affect comparison for selection and ordering.
For example, many written European languages have characters with accents and other diacritical marks on a base
letter. Sometimes you want to ignore the differences between base letters with and without diacritics, such as the
differences between “A”, “À”, and “Á”. Asian languages have other concerns, such as single-byte and double-byte
characters or between katakana and hirigani characters in Japanese.
The result of comparing the value of a character field with another character value differs depending on the
language, search collation strength, and database that your PolicyCenter uses. For example, case-insensitive
comparisons produce the same results as case-sensitive comparisons if PolicyCenter has a linguistic search strength
of primary.
Some query API methods support specifying whether to ignore differences between letter case. When you specify
that you want to ignore case, PolicyCenter uses your localization settings to control the results. For each locale
configured in your PolicyCenter instance, you specify which dimensions of difference you want to ignore. For
example, you can configure a locale to ignore case only, to ignore case and accents, or to ignore other dimensions of
difference that are relevant to the locale.
Query performance can suffer when you ignore case in query predicate methods. To improve query performance if
you typically need to ignore case in text comparisons, set the SupportsLinguisticSearch attribute on column
elements in entity definitions. For a column that has the SupportsLinguisticSearch set, PolicyCenter creates a
corresponding denormalization column in addition to the standard column that stores the field values. When
PolicyCenter stores a value in the standard column, PolicyCenter also stores a value in the denormalization column.
PolicyCenter saves a denormalized value by converting the regular value to one that ignores character differences,
based on the dimensions of difference that you specified in your localization settings. When a query applies a
predicate that specifies ignoring the case of a field, PolicyCenter uses the same algorithm that converted values to
store in the denormalization column. The relational database compares the converted bound value to the values in
the denormalization column, not the values in the standard column.
For example, you specify the following query:
uses [Link]
Print the rows that the query returns by adding the following lines:
SELECT /* KeyTable:pc_contact; */
[Link] col0,
[Link] col1
FROM pc_contact gRoot
WHERE [Link] = ?
AND [Link] = 0 [smith (lastname)]
Depending on your PolicyCenter and database settings, you see either no output or output that looks like:
Steve Smith
Kerry Smith
Alice Smith
John Smith
...
To do a case-insensitive text comparison, use the compareIgnoreCase method. This method uses the same
parameters as the compare method. To see the effect on the SQL query of using the compareIgnoreCase method,
change the comparison line in the code to:
374 chapter 23: Query builder APIs
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
SELECT /* KeyTable:pc_contact; */
[Link] col0,
[Link] col1
FROM pc_contact gRoot
WHERE [Link] = ?
AND [Link] = 0 [smith (lastname {linguistic=true})]
The standard column has values like “Smith” and “Menzies”. The denormalization column has corresponding values
like “smith” and “menzies”. The preceding query returns Person entity instances with the last name “Smith” in the
standard column, because it compared the bound value “smith” to the value in the denormalization column.
You see output that looks like:
Steve Smith
Kerry Smith
Alice Smith
John Smith
...
See also
• Globalization Guide
• Configuration Guide
uses [Link]
The following Gosu code is functionally equivalent to the sample code above, but it uses method chaining to
condense the separate statements into one. Because the code uses only the value of result, an
IQueryBeanResult<Person> object, none of the intermediate return objects are necessary.
uses [Link]
When you chain methods, the objects that support the calls in the chain often do not appear explicitly in your code.
In the example above, the [Link] method returns a query object, on which the chained statement calls the join
method. In turn, the join method returns a table object, on which the next method calls the contain method. The
contain method returns a restriction object, which has a select method that returns a result object for the built-up
query. After the single-line statement completes, the query object is discarded and is no longer accessible to
subsequent Gosu code.
Note: Method chaining with the query builder APIs is especially useful for user interface
development. Page configuration format (PCF) files for list view panels have a single-line property
named value, which can be a chained query builder statement that returns a result object.
SELECT *
FROM pc_Address
INNER JOIN ( SELECT Country, MIN(City) MinCity
FROM pc_Address
GROUP BY Country ) MinCityAddress
ON pc_Address.City = [Link];
To create a nested subquery, call the inlineView method on the query. This method returns a query using the new
nested subquery and includes all referenced columns from that query in the select statement. The inlineView
method takes the following arguments:
• joinColumnOnThisTable – The name of the join column (String).
• inlineViewQuery – The query (Query). This argument cannot be the result of any Query method that returns a
Table.
• joinColumnOnViewTable – The name of the join column on the nested query table (String).
The method returns a new query that contains the nested subquery. The return type of the method is a Table object.
Predicates on the secondary table can use columns on the secondary table or the primary table.
For example, suppose you create two queries, an inner query and an outer query:
Next, create a nested subquery from the inner query to add the Address#Country column to the columns that the
outer query returns:
Next, use the City column in a new predicate on the outer query:
[Link](Address#City, Equals,
[Link]([Link]([Link](Address#City))))
This code prints the display name of any Address entity that has a city that matches the city that is alphabetically
first for a particular country. This produces the following SQL statement:
Paths
A path is essentially a type-safe list of property references encapsulated in an object of type [Link].
Each element of the path must have an owning type that is the same type or subtype of the feature type of the
immediately previous element in the path. In other words, starting at element 2, the left side of the literal must match
the right side of the literal in the previous element in the path.
From a programming perspective, Path is an interface. For use with the query builder APIs, the only relevant
implementing class is PersistentPath, which contains only persistent property references.
Making a path
To create a path, use the [Link] class, which has a static method called make. Pass each property
reference in order as separate ordered method arguments. The make method has method signatures that support paths
of length 1, 2, 3, 4, and 5. The make method only works with property references that represent persistent properties.
A persistent property is a property that directly maps to a database field.
The following example creates a path with two property references
Appending a path
You can append a property with the append method:
You must ensure that no element in the path to the leaf is null.
An entity query on the User table can use this method to access the leaf values:
See also
• “Gosu generated documentation (Gosudoc)” on page 46
Type Description
Query A class that represents a query that fetches entities or rows from the application database.
Restriction An interface that represents a Boolean condition or conditions that restricts the set of items that a query
fetches from the application database.
Table An interface that represents an entity type that you add to the query with a join or a subselect.
IQueryBeanResult An interface that represents the results of a query that fetches entities from the application database.
Adding sorting or filters to this item affects the query.
IQueryResult An interface that represents the results of a query that fetches rows from the application database. Add‐
ing sorting or filters to this item affects the query.
select Defines the items to fetch from the application database, according to restrictions IQueryBeanResult or
added to the query. Returns a result object that provides one of the following types IQueryResult
of item:
• Items fetched from a single, root entity type
• Data rows containing specified fields from one or more entity types
subselect Joins a dependent source. For example: Table
var outerQuery = [Link](User) // Returns User Query
var innerQuery = [Link](Note) // Returns Note Query
// Filter the inner query
[Link](Note#Topic, {NoteTopicType.TC_GENERAL,
NoteTopicType.TC_LEGAL})
// Filter the outer query by using a subselect
[Link](User#ID, [Link], noteQuery,
Note#Author )
union Combines all results from two queries into a single result. GroupingQuery
withDistinct Whether to remove duplicate entity instances from the result. Query
Method Description
orderBy Clears all previous ordering, and then orders results by the specified column in ascending order.
orderByDescending Clears all previous ordering, and then orders results by the specified column in descending order.
thenBy Orders by the specified column in ascending order, without clearing previous ordering.
thenByDescending Orders by the specified column in descending order, without clearing previous ordering.
These ordering methods all take an object that implements the IQuerySelectColumn interface as their one
argument.
See also
• “Ordering results” on page 363
• “Locale sensitivity for ordering query results” on page 364
The PropertyReference class provides type-safe access to the properties on the query entity type. You specify a
property reference by using the following syntax:
EntityType#Property
You can use a property reference to filter query results, join to another entity type, order rows in the result set, or
specify a column for a row query. For example, the following line joins the company query to the Address entity
type and returns a Table object:
A Table object provides the same type-safe access to properties on its entity type as a Query object does. For
example, the following lines provide two predicates, one on the query object and one on the table object. These
predicates filter the SQL query that is sent to the database to return only companies with the name “Stewart Media”
that have a primary address in Chicago.
If you have a query that joins entity types, the Query and the Table object can perform type-safe access only for
properties on their own entity type. If you need to compare property values with each other or filter properties on
multiple joined tables to create an OR filter, you must use a ColumnRef object. For example, the following lines
create two predicates on the Table object. These predicates filter the SQL query that is sent to the database to return
companies with either the name “Stewart Media” or a primary address in Chicago.
Some other predicate method signatures take an object that implements the IQueryablePropertyInfo interface as a
parameter.
Type Description
PropertyReference A class that provides a type‐safe reference to a property. Use this class to access properties on the
primary entity of a Query, Table, or Restriction. You can use an instance of this class to create a
join or predicate. You can also use an instance of this class to define a query select column to or‐
der the query results of for a column in a row query. The following lines use property references to
join tables and filter the primary entity of a Query and a Table object.
var queryCompany = [Link](Company)
var tableAddress = [Link](Company#PrimaryAddress)
[Link](Company#Name, Equals, "Stewart Media")
[Link](Address#City, Equals, "Chicago")
ColumnRef A class that specifies a column reference to a property on a dependent entity, or a comparison
property on the primary entity of a Query, Table, or Restriction. A ColumnRef instance does not
provide type safety. The following lines use a column reference for a property on a dependent ta‐
ble:
[Link]( \ or1 -> {
[Link](Address#City, Equals, "Chicago")
[Link]([Link]("Name"), Equals, "Stewart Media")
})
String Some query builder API method signatures accept a String argument. If a signature that uses a
PropertyReference parameter is available, use that type‐safe signature instead.
Type Description
IQueryablePropertyInfo An interface that provides information about a property. Some query builder API method signa‐
tures accept an IQueryablePropertyInfo argument. To create this object, use code like the fol‐
lowing:
var lastNamesArrayList = {"Smith", "Applegate"}
var query = [Link](Person)
[Link](Person.LASTNAME_PROP.get(), lastNamesArrayList)
alias : String An alias for the column name in the row query result. This parameter has no pur‐
pose for a column that you use to order the query results.
path : A path expression that references the column to include in the row query result or
PersistentPath to order the rows in the result set.
dbFunctionWithAlias Creates an SQL expression for ordering query results or to use as a column in a
dbFunction row query. For example, the following lines select columns for a row query and
order the results. You use the same syntax for ordering the results of an entity
query.
var query = [Link](Address)
var results = [Link]({
[Link]([Link]({"length (",
[Link]("[Link]"), ")"}))
}).orderBy([Link]([Link]
({"length(", [Link]("[Link]"), ")"})))
alias : String An alias for the column name in the row query result. This parameter has no pur‐
pose for an expression that you use to order the query results.
func : A DBFunction expression that creates a column to include in the row query result
DBFunction or to order the rows in the result set.
To access a column in the results of a row query, you use the getColumn method to access any column in the row.
The results of a row query do not have a default property. For example, the following code is equivalent to the
previous code for an entity query. The code creates a row query and prints the name of each person in the database
and the name of the user who created that person.
The method that you use to retrieve the value of a column from a row in the result of a row query is the following.
Use one of the parameters in the table. The return value of the method is an Object.
compareIn • Column name (String) Compares the value for this column for each row to a list of non‐
• List of values that could match null objects that you specify. If the column value for a row matches
the database row for the any of them, the query successfully matches that row. For example:
column (Object[]) [Link](Activity#PublicID,
{"default_data:1", default_data:3"})
compareNotIn • Column name (String) Compares the value for this column for each row to a list of non‐
• List of values that could match null objects that you specify. If the column value for a row matches
the database row for that none of them, the query successfully matches that row. For exam‐
column (Object[]) ple:
[Link](Activity#PublicID,
{"default_data:1", default_data:3"})
contains • Column name (String) Checks whether the value in that column for each row contains a
• Contains value (String) specific substring. For example, if the substring is "jo", it will
• Ignore case (Boolean) match the value "anjoy" and "job" but not the values "yo" or
"ji". If you pass true to the final argument, Gosu ignores case dif‐
ferences in its comparison. For example:
[Link](Person#FirstName, "jo",
true /* ignore case */)
Test the use of the contains method in a realistic environment. Us‐
ing the contains method as the most restrictive predicate on a
query causes a full‐table scan in the database because the query
cannot use an index.
WARNING For a query on a large table, using contains as the most
restrictive predicate can cause an unacceptable delay to the user
interface.
or Gosu block that contains a list of Checks whether a value satisfies one or more predicate methods,
predicate methods applied to col‐ such as compare, contains, and between. Only one of the predi‐
umns in the query. cate methods must evaluate to true for the item that contains the
value to be included in the result.
startsWith • Column name (String) Checks whether the value in that column for each row starts with a
• Substring value (String) specific substring. For example, if the substring is "jo", it will
• Ignore case (Boolean) match the value "john" and "joke" but not the values "j" or
"jar". If you pass true to the Boolean argument (the third argu‐
ment), Gosu ignores case differences in its comparison. For exam‐
ple:
[Link](Person#FirstName, "jo",
true /* ignore case */)
Note: If you choose case‐insensitive partial comparisons, Gosu gen‐
erates an SQL function that depends on your PolicyCenter and da‐
tabase configuration to implement the comparison predicate. How‐
ever, if the data model definition of the column specifies the
supportsLinguisticSearch attribute set to true, Gosu uses the
denormalized version of the column, instead.
IMPORTANT Test the use of the startsWith method in a realistic
environment. Using the startsWith method as the most restrictive
predicate on a query can cause a delay on the user interface.
See also
• “Combining predicates with AND and OR logic ” on page 330
• “Comparing column values with each other” on page 326
• “Using set inclusion and exclusion predicates” on page 326
Min Returns the minimum value of all values in a column [Link]([Link](44), GreaterThan,
[Link]([Link]("B")))
Max Returns the maximum value of all values in a column [Link]([Link](44), LessThan,
[Link]([Link]("B")))
See also
• “Comparing the interval between two date and time fields” on page 322
• “Comparing parts of a date and time field” on page 323
• “Comparing the date part of a date and time field” on page 323
• “Comparing a column value with a literal value” on page 327
• “Creating and using an SQL database function” on page 352
Gosu provides APIs to change how changes to Guidewire entity data save to the database. For many programming
tasks in Gosu, such as typical rule set code, you may not need to know how database transactions work. For some
situations, however, you must understand database transactions, for example:
• Adding entities to the current database transaction
• Moving entities from one database transaction to another
• Explicitly saving data to the database (committing a bundle)
• Undo the current database transaction by throwing Gosu exceptions.
WARNING Only commit entity changes at appropriate times or you could cause serious data
integrity issues. In many cases, such as typical Rule sets and PCF code, it is best to rely on default
behavior and not explicitly commit entity data manually.
WARNING Using database transaction APIs has significant effects on application logic and data
integrity. Using APIs incorrectly can adversely affect other application logic that tracks when to
commit changes or undo recent data changes.
The following table lists typical requirements for using the main database transaction APIs.
Bundles and database transactions 387
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Code context Create a new bundle Add entity Commit bundle explic- Notes
with instances to itly for data changes?
runWithNewBundle? bundles be-
fore chang-
ing data?
Code that on‐ No No No If you do not change entity data, you do
ly reads prop‐ not need to use any database transaction
erties APIs.
Rule sets No Yes, for data‐ No
base query IMPORTANT It is dangerous and
results. See unsupported for rule set code to explicitly
the Note col‐ commit any bundle.
umn. Some rule sets, such as validation rules or
pre‐setup rules, have a main object that is
already in the current writable bundle. If
you change only that main entity and its
subobjects, your Gosu rule set code does
not typically require special database trans‐
actions.
PCF code in: No Yes, for data‐ No
base query IMPORTANT In most PCF code, it is
• List views
results. dangerous to create additional bundles or
• View
explicitly commit [Link] PCF
screens
widgets handle database transactions
• Edit automatically. For example, after you
screens enter Edit mode, the application creates a
new bundle. After you click the Save
button, the application commits the
bundle with any data updates. In general,
use the default PCF behaviors.
Code context Create a new bundle Add entity Commit bundle explic- Notes
with instances to itly for data changes?
runWithNewBundle? bundles be-
fore chang-
ing data?
Workflow No. Yes, for data‐ No The bundle for workflow actions is the bun‐
code base query dle that the application uses to load the
results Workflow entity instance.
Custom batch Yes Yes, for data‐ No. The Use the runWithNewBundle API method to
processes base query runWithNewBundle API create a new bundle for your entity data
results method commits the changes.
bundle.
Custom work Yes Yes, for data‐ No. The Use the runWithNewBundle API method to
queues base query runWithNewBundle API create a new bundle for your entity data
results method commits the changes.
bundle.
WARNING Custom work item code
has access to a current bundle.
However, using this bundle for your
own business data changes is
unsupported.
Web services Yes, if the operation Yes, for data‐ No. The Use the runWithNewBundle API method to
modifies data. base query runWithNewBundle API create a new bundle for your entity data
results method commits the changes.
bundle.
See also
• “Adding entity instances to bundles” on page 390
• “Committing a bundle explicitly in very rare cases” on page 393
• “Running code in an entirely new bundle” on page 398
Overview of bundles
To manage database transactions, Guidewire applications group entity instances in groups called bundles. A bundle
is a collection of in-memory entity instances that represent rows in the database. The application transmits and saves
all entity instances in the bundle to the database in one transaction. A bundle includes changed entities, new entities,
and entities to delete from the database. Gosu represents a bundle with the class [Link].
Guidewire refers to the process of sending the entities to the database as committing the bundle to the database. If a
bundle commit attempt completely succeeds, all database changes happen in a single database transaction. If the
commit attempt fails in any way, the entire update fails and Gosu throws an exception.
A bundle is not thread-safe. Be aware of any concurrency issues when accessing entity instances in a bundle or
committing those instances to the database. If multiple users can access the entity instances in a bundle
simultaneously, you must use external synchronization to ensure reading and writing correct data, such as for
property values.
WARNING Use external synchronization to ensure data integrity for concurrent access to entity
instances.
The two basic types of bundles are read-only bundles and writable bundles. A database query places the results of
the query are in a temporary read-only bundle. To change any data, you must copy the contents of a read-only
bundle to a writable bundle.
Not all writable bundles eventually commit to the database. For example:
• A user might start to make data changes in the user interface but abandon the task.
• A user might start to make data changes in the user interface, try to save them, but errors prevent completion.
Eventually, the user might cancel the action before fixing and completing the action.
• A batch process might attempt a database change, but errors prevent completing the action.
• A web service call might attempt a database change, but errors prevent completing the action.
If any code destroys a bundle that has uncommitted changes, no entity data in the database changes.
WARNING The base configuration contains visible usages of the entity instance method
setFieldValue. The setFieldValue method is reserved for Guidewire internal use. Calling this
method can cause serious data corruption or errors in application logic that may not be
immediately apparent. You must obtain explicit prior approval from Guidewire Support to call
setFieldValue as part of a specific approved use.
See also
• “Making an entity instance writable by adding to a bundle” on page 391
• “Adding entity instances to bundles” on page 390
• “Getting the bundle of an existing entity instance” on page 392
• “Getting an entity instance from a public ID or a key” on page 392
• “Creating new entity instances in specific bundles” on page 393
• “Committing a bundle explicitly in very rare cases” on page 393
• “Determining what data changed in a bundle” on page 395
• “Concurrency” on page 417
[Link]()
In batch processes and WS-I web service implementations there is no current bundle. You need to create a new
bundle for your data changes.
uses [Link]
obj = [Link](obj)
IMPORTANT You must save the return result of the add method and use the result for any changes.
Carefully avoid keeping any references to the original entity instance.
The following example gets the current bundle and moves an entity instance to it
uses [Link]
obj = [Link](obj) // Move the object to the new bundle and save the result
obj.Prop1 = "NewValue"
You can choose to delete the object from the database. Take care to avoid dangling references to the deleted object if
you perform this action:
[Link](obj)
In most programming contexts, it is critical to not explicitly commit the bundle after your changes. For example, in
typical Rules and PCF contexts, it is dangerous and unsupported to explicitly commit the bundle. Let PolicyCenter
perform its default bundle commit behavior.
See also
• “Overview of the query builder APIs” on page 311
• “When to use database transaction APIs” on page 387
• “Committing a bundle explicitly in very rare cases” on page 393
• “Removing entity instances from the database” on page 394
• “Running code in an entirely new bundle” on page 398
Be aware that even if the entity instance is unmodified at the time you copy it to the new bundle, problems can occur
later. Only one bundle can try to commit a change to the same entity instance based on the same revision of the
database row. If an entity instance was modified in more than one bundle and both bundles commit, the second
commit fails with a concurrent data change exception.
The failed commit attempt might be in code other than your code, such as PCF user interface code that is editing the
same object.
Gosu attempts to avoid this problem by preventing adding an already-modified entity to a new bundle. In some
cases, user interface code internally refreshes an entity instance, such as when switching from view mode to edit
mode. Refreshing an entity is an internal process that discards a cached version and gets the latest version from the
database. This process reduces the likelihood of concurrent data change exceptions. Gosu does not provide public
API to refresh entity instances.
See also
• “Making an entity instance writable by adding to a bundle” on page 391
See also
• “Making an entity instance writable by adding to a bundle” on page 391
To load an entity by a public ID, use the query builder API. For example:
If you use the query builder API, the entity reference returned is in a read-only bundle. If you need to modify the
data and save changes to the database, you must first add the entity instance to a writable bundle.
392 chapter 24: Bundles and database transactions
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Adding entity instances to bundles” on page 390
• “Query builder APIs” on page 311
No arguments new Note() Constructs a new Note entity in the current bundle. Changes related to the cur‐
rent code submit to the database at the same time as any other changes in the
current bundle. This approach is the typical approach for most programming
contexts, such as rule set code or plugin implementation code. This approach
requires that there be a current bundle.
In some programming contexts, such as batch processes and WS‐I web service
implementations, there is no automatic current bundle.
An entity in‐ new Note(myPolicy) Constructs a new Note entity in the same bundle as a given Policy entity in‐
stance stance. Changes to the Policy are committed to the database at the same time
as the new note, and all other changes in the bundle.
A bundle new Same as previous table row
Note([Link])
See also
• “Using the operator new in object expressions” on page 86
• “Running code in an entirely new bundle” on page 398
WARNING Only commit a bundle if you are sure it is appropriate for that programming context.
Otherwise, you could causes data integrity problems. For example, in Rule sets or PCF code, it is
typically dangerous to commit a bundle explicitly. Contact Customer Support if you have
questions.
For web service implementations that need to change data, use the runWithNewBundle API method. The
runWithNewBundle API method commits the bundle for you when your code completes.
Bundles and database transactions 393
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
If you are sure that committing the bundle is appropriate, use the method [Link](). If the attempt fails,
Gosu throws an exception. The entire commit process fails. The database remains unchanged.
Get the current bundle by calling the getCurrent static method on the Transaction class:
uses [Link]
If you have an entity instance reference, use the [Link] property to get its bundle. Committing a bundle
commits everything in the bundle, not just the instance from which you got the bundle reference. For example:
See also
• “When to use database transaction APIs” on page 387
• “Running code in an entirely new bundle” on page 398
uses [Link]
When the bundle is committed, the entity instance is deleted from the database. If the entity’s data model
configuration declares the entity as Retireable, the entity is not deleted, but is retired instead. The delete method
removes only the specified entity instance from the database, not linked entity instances.
See also
• Configuration Guide
if ([Link]("LossLocation")) {
// Get original entity
var id = [Link]("LossLocation") as Key
var originalAddress = [Link](id)
In contrast, if the [Link]("LossLocation") returns false, then the entity foreign key is
unchanged but that does not mean necessarily that data in a subobject is unchanged. To check properties on
subobjects, you must test specific properties on the subobject using the isFieldChanged method. For example:
if (not [Link]("LossLocation")) {
if ([Link]("City")) {
var origAddLine1 = [Link]("AddressLine1")
}
}
See also
• “Getting an entity instance from a public ID or a key” on page 392
if ([Link]) {
// Your code here...
}
From your rule set code, you can get the set of changed properties on an entity instance using the ChangedFields
property. That property value has the type [Link].
The following example uses a Gosu block that iterates across the set of changed properties:
396 chapter 24: Bundles and database transactions
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
if ([Link]) {
[Link]( \ e -> print("Address has changed property: " + e))
}
See also
• “What are blocks?” on page 175
• “Collections” on page 183
uses [Link]
...
Your Gosu code within the block can add entity instances to the bundle by using the [Link](entity) method.
Remember to save the return result of the add method.
Gosu immediately runs this code synchronously. If the block succeeds with no exceptions, runWithNewBundle
commits the new bundle after your code completes. For the most concise and readable code, Guidewire encourages
you to use this automatic commit behavior rather than committing the bundle explicitly.
If your code detects error conditions, throw an exception from the Gosu block. Gosu discards the bundle and does
not commit the changes.
The following example demonstrates how to create a new bundle to run code that creates a new entity instance and
modifies some fields. The current transaction is an argument to the block.
If you are adding entity instances, in typical code you do not need to use the bundle explicitly. Gosu sets the current
bundle inside the block to this new block automatically. You can use the no-argument version of the new operator for
entity types, which creates the object in the current bundle:
398 chapter 24: Bundles and database transactions
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
[Link]( \b -> {
var me = new MyEntity()
[Link] = firstName
[Link] = lastName
[Link] = address
me.EmailAddress1 = email
[Link] = workPhone
[Link] = primaryPhoneType
[Link] = taxId
[Link] = faxPhone
} )
If you perform database queries, you can use the bundle reference to add entity instances to the new writable bundle.
WARNING Only commit a bundle if you are sure that it is appropriate for that programming
context. Otherwise, you could causes data integrity problems. For example, in Rule sets or PCF
code, it is typically dangerous to commit a bundle explicitly, including with this API. Contact
Customer Support if you have questions.
...
...
This apparently simple block is not self-contained because the code uses customerID, which is the argument to the
myAction method and is declared outside the scope of the block. The ability of a block to use variables from its
creation context is called variable capturing.
In some cases, you need to return information from your block. You can return information by more advanced use of
variable capturing. The following example demonstrates variable capturing by creating a local variable in the outer
scope (myAction) and then setting its value from within the block. The outer scope can use that value as a return
value from the method.
// The local variable "res" and the parameter "customerID" are captured by the block.
// Both variables are shared between the calling function and the block
[Link]( \ bundle -> { res = [Link](customerID, bundle) })
// Return the value that was set in the block using the shared (captured) variable
return res
}
See also
• “Blocks” on page 175
• “Variable scope and capturing variables in blocks” on page 177
• “Adding entity instances to bundles” on page 390
• “Getting changes to entity arrays in the current bundle” on page 397
For the second argument to the method, you can pass either a User entity instance or the user name as a String.
Guidewire strongly recommends that you do not use the Guidewire sys user (System User), or any other default
user, to create a new bundle.
transaction. In one case, the code makes changes to only B, C, and D. There remains one object (A) for which you
did not change properties. Therefore, A is not in the same bundle as B, C, and D. In this case, neither does the
database row for A change nor does its version number increment, which will not be a problem in some cases.
However, suppose the three objects you change are related to the current properties on A. The default behavior may
be undesirable compared to updating A, B, C, and D together:
• You might want to protect against other threads on the current server, including the user interface, from making
concurrent changes on A that make the other changes make no sense.
• You might want to protect against other servers in the PolicyCenter cluster from making concurrent changes on A
that make the other changes make no sense.
• You might want the last modified time of A to match the last modified time of B, C, and D.
• You might want to force preupdate rules to run for object A.
To force PolicyCenter to increment the entity version number ([Link]), update the modified time, and
force preupdate rules to run, call the touch method on the entity instance. The method takes no arguments:
[Link]()
See also
• “Entity instance versioning and the entity touch API” on page 400
• Integration Guide
• System Administration Guide
Type system
Gosu provides several ways to gather information about an object or other type. Use this information to debug or to
determine program behavior at run time.
typeof expression
The example below demonstrates the syntax. The sample typeof expression evaluates to true.
Comparing the retrieved type to a subtype of the retrieved type evaluates to false. For example, the Integer type is
a subclass of the Number class, which itself is a subclass of the Object class. All of the typeof expressions shown
below evaluate to false.
The Type<t> syntax must be used in comparison expressions of entities or typekeys that use the typeof operator.
The expressions shown below evaluate to false because they do not use the required Type<t> syntax.
The example below demonstrates how the run-time type retrieved by the typeof operator can differ from the type
specified when the variable was defined.
The run-time type of a null value is the void type as demonstrated below.
OBJECTtypeis TYPE
The definition of a myVar variable of type Integer is shown below. The Integer type is a subclass of the Number
class, which itself is a subclass of the Object class. Thus, all the typeis expressions shown below evaluate to true.
The following example shows some Type<t> types of a NoteSecurityType typekey. The NoteSecurityType
typekey is a subclass of the Object class. All of the typeis expressions shown below evaluate to true.
Some methods, parameters, and return values use the interface type IType which is analogous to the parameterized
Type<t>.
If the compiler determines that a particular typeis expression can never evaluate to true at run time then a compile
error is generated. This behavior is demonstrated in the following example which generates a compile error because
the Boolean variable can never hold an Integer value.
if (myVar typeis Integer) { print("Compile Error") } // Compile Error, Boolean can never be Integer
expression as TYPE
The expression must be compatible with the type. The following table shows the results of casting a simple numeric
expression into one of the Gosu-supported data types. If you try to cast an expression to an inappropriate type, Gosu
throws an exception.
The as keyword can be used to cast an array type to another compatible array type. For example, String is a
subtype of Object, so an array of type String can be cast to an array of type Object.
The compiler can detect and produce a compilation error when two referenced types are incompatible. For example,
an Integer[] can never be converted to a String[], so the following code statements produce a compilation error.
In some cases, you know that all the objects in an array are of a particular subtype of the defined type of the array. In
other cases, you filter an array to retrieve only objects of a particular subtype. As shown in a preceding code
example, you cannot use the as keyword to convert an array to an array of a subtype. Instead, you can use the Gosu
enhancement method cast to make an array of the subtype. You can then perform operations on the new array that
are specific to the subtype and not available to the parent type. The following code demonstrates how to use the
cast method.
You cannot use the cast method to convert incompatible types. The compiler does not detect this type of error. The
following code produces a run-time error.
Type system 405
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
For example, the following code shows a variable declared as an Object, but automatically downcast to String
when referenced within the if code block.
if ( x typeis String ) {
strlen = [Link] // x automatically downcast to a String which has a length property
}
Note that length is a property on String, not Object. The automatic downcasting of the variable eliminates the
need to explicitly cast it. The following code is equivalent to the previous code, but has an unnecessary explicit cast.
if ( x typeis String ) {
strlen = (x as String).length // Do not need to explicitly cast x as a String
}
Best practice recommends utilizing automatic downcasting when it occurs and eliminating unnecessary explicit
casting.
uses [Link]
The automatic downcast occurs only for the true portion of the ternary expression. In the false portion, the
variable reverts to its original type.
The automatic downcast is terminated and the object is interpreted as being of its original type when any of the
following conditions occurs.
• Reaching the end of the code block’s scope
◦ The end of an if code block
◦ The end of a case code block within a switch statement
◦ The end of the true portion of a ternary conditional expression
• Assigning any value to the variable that you checked with typeis or typeof. This behavior applies only to if
and switch statements.
• Assigning any value to any part of an entity path that you checked with typeis or typeof. This behavior applies
only to if and switch statements.
• An or keyword in a logical expression
• The end of an expression negated with the not keyword
• In a switch statement, a case section does not use automatic downcasting if the previous case section is not
terminated by a break statement. The following switch statement demonstrates this rare behavior.
uses [Link]
When the x object of type Object attempts to access a non-existent Time property, a compile error occurs. To
work around this behavior, explicitly cast the x object to a type Date as shown below.
print( (x as Date).Time ) // Explicitly cast x to type Date to access the Time property
Alternatively, the Type property of a data type can be referenced directly to access the type’s metadata. The
following example demonstrates the appropriate syntax to access the metadata of the ArrayList class.
The output from the example code is identical for both of the demonstrated access methods.
Name = [Link]<[Link]>
Supertype = [Link]<[Link]>
isAssignableFrom(Object) = false
Example method name = clone
The TYPE property is available only on Gosu entity and typekey data types.
From a Gosu language perspective, primitives are different only in subtle ways from object-based types such as
Integer and Boolean. Primitive types can be automatically coerced to non-primitive versions or back again by the
Gosu language in almost all cases. For example, int can be cast to Integer and Boolean cast to boolean. In typical
code, you do not need to know the differences.
The boolean type is a Java primitive which is also called an “unboxed” type. In contrast, Boolean is a class that
implements a “boxed” type of the boolean primitive. A boxed type is a primitive type wrapped in the shell of a
class. Boxed types are useful for code that requires all values to have the common ancestor type Object. For
example, Gosu collection data types typically require members to have types that descend from Object. Thus,
collections can contain Integer and Boolean, but not the primitives int or boolean.
The Gosu boxed types use the Java primitive types. The boxed types are defined in the [Link] package, such as
[Link]. Code execution performance is slightly improved when using a primitive rather than its boxed
version.
There is an important difference between primitive and boxed types when handling uninitialized values. Variables
declared of a primitive type cannot hold the null value. However, null can be assigned to variables of type Object
and any subtype of Object.
Compound types
To implement other features, Gosu supports a special type called a compound type. A compound type combines an
optional base class and additional interfaces. Typical usage of compound types occurs only when Gosu
automatically creates a variable with a compound type because of type inference. In extremely rare cases, Gosu
allows a variable to be declared explicitly with a compound type.
Suppose you use the following code to initialize list values with different types of objects. When used with
initializers, the run-time type is always ArrayList<Object, Object>. The compile-time type depends on what you
pass to the initializer. Gosu infers the type of the result list to be the least upper bound of the components of the list.
If you pass different types of objects, Gosu finds the most specific type that includes all of the items in the list.
If the types implement interfaces, Gosu attempts to preserve commonality of interface support in the list type. This
behavior ensures that your list acts as expected with APIs that rely on support for the interface. In some cases, the
resulting type is a compound type, which combines:
• Zero classes or one class, which might be [Link], if no other common class is found
• One or more interfaces
At compile time, the list and its elements use the compound type. You can use the list and its elements with APIs
that expect those interfaces or the ancestor element.
For example, the following code creates classes that extend a parent class and implement an interface.
interface HasHello {
function hello()
}
class TestParent {
function unusedMethod() {}
}
Using reflection
If you know what type an object is, you can use reflection to learn about the type or perform actions on it. Reflection
means using type introspection to query or modify objects at run time. For example, instead of calling an object
method, you can get a list of methods from its type, or use a String run-time value to call a method by name. You
can get metadata, properties, and functions of a type at run time.
Although each Type object itself has properties and methods on it, the most interesting properties and methods are
on the [Link] object. For example, you can get a type’s complete set of properties and methods at run time
by getting the TypeInfo object.
Only use reflection if there is no other way to do what you need. Avoid using reflection to get properties or call
methods. In almost all cases, you can write Gosu code to avoid reflection. Using reflection dramatically limits how
Gosu and Guidewire Studio can alert you to problems at compile time. Detecting errors at compile time is better
than encountering unexpected behavior at run time.
The following example shows two different approaches for getting the Name property from a type.
[Link]
int
print(propNames)
If the time is currently 5:00 AM, this code prints the following output.
print(methodNames)
This code prints something lines to the following output, which is truncated for brevity.
wait() wait( long, int ) wait( long ) hashCode() getClass() equals( [Link] )
toString() notify() notifyAll() @itype() compareTo( [Link] ) charAt( int )
length() subSequence( int, int ) indexOf( [Link], int ) indexOf( [Link] )
indexOf( int ) indexOf( int, int ) codePointAt( int ) codePointBefore( int )
The following example gets a method by name and then calls that method. This example uses the String class and
its compareTo method, which returns 0, 1, or -1. Paste the following code into the Gosu Scratchpad.
var str: String = "hello" // Explicit declaration of "String" is optional, but is shown for clarity
var obj1: Object = "hello"
var obj2: Object = 2.345
var bool: Boolean = true
// The following line would be a compile error! String is not a subtype or supertype of Boolean.
// tempTypeIs = (bool typeis String)
// For typical uses cases, DO NOT compare types with the == operator
// Using == to compare types returns false if one is a subtype.
// Instead, typically it is best to use the 'typeis' operator
print("Compare a string to object using ==: " + ( (typeof str) == Object ) )
// With that class, you can interate across the native Java fields at run time
for ( field in [Link] ) {
print(field)
}
The IHasJavaClass interface is implemented only by types that have a Java backing class.
Feature literals
Gosu feature literals provide a way to statically refer to a type’s features such as methods and properties. You can
use feature literals to implement some reflection techniques more safely at compile time than in some other
programming languages. Gosu feature literals are validated at compile time, preventing many common errors with
reflection techniques. To refer to the feature of a type or object, you use the # operator after the type or object,
followed by the feature name. The syntax is similar to the feature syntax of the Javadoc @link syntax.
Type system 413
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
You can use feature literals in APIs, such as the following types of layers.
• Mapping layers, where you are mapping between properties of two types
• Data-binding layers
• Type-safe object paths for a query layer
Consider the following Gosu class.
class Employee {
var _boss : Employee as Boss
var _name : String as Name
var _age : int as Age
function greeting() {
print("Hello world")
}
}
Given this class, you can refer to its features by using the # operator.
These variables contain feature literal references. Using these references, you can access the underlying property or
method information. Alternatively, use feature literal references to invoke a method or access a property.
You can define or use Gosu APIs that use feature literals as arguments or return values.
var m = Employee#greeting()
var obj = new Employee()
// Call the method and pass the object with the method feature literal on the left of the period
[Link](obj)
// Test results...
print([Link] + " and age " + [Link])
You do not need to pass the instance into the set method because the code already bound the property reference to
the anEmp variable.
print( [Link] ) // Prints "Joe". Code has not yet invoked the function reference.
// Call the method with specific arguments bound in the feature literal
[Link]()
Using this technique, you can refer to a method invocation with a particular set of arguments. Note that the second
line does not invoke the update function. Instead, it gets a reference that you can use to evaluate the function at a
later time.
The chained feature literal refers to the name of the boss of the object in the anEmp variable.
Concurrency
This topic describes Gosu APIs that protect shared data from access from multiple threads.
In a Guidewire application, some contexts always require proper synchronization. For example, in a plugin
implementation exactly one instance of that plugin exists in the Java virtual machine on each server. Your plugin
code must have the following attributes:
• Your plugin must support multiple simultaneous calls to the same plugin method from different threads. You
must ensure multiple calls to the plugin never access the same shared data. Alternatively, protect access to shared
resources so that two threads never access it simultaneously.
• Your code must support multiple simultaneous calls to a plugin instance. For example, PolicyCenter might call
two different plugin methods at the same time. You must ensure multiple method calls to the plugin never access
the same shared data. Alternatively, protect access to shared resources so that two threads never actually access it
simultaneously.
• Your plugin implementation must support multiple user sessions. Do not assume shared data or temporary
storage is unique to one user request, which is one HTTP request from a single user.
Gosu provides the following types of concurrency APIs to support writing thread-safe code:
Concurrency 417
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Concurrent cache
The Cache class in [Link] declares a cache of values that you can look up quickly and in a thread-
safe way. It declares a concurrent cache similar to a Least Recently Used (LRU) cache. Because the Cache class
uses the Java concurrency libraries, access to the concurrent cache is thread-safe.
WARNING Caches can cause subtle problems. Use caches only as a last resort for
performance.
Support for Java monitor locks, reentrant locks, and custom reentrant objects
Gosu provides access to Java-based classes for monitor locks and reentrant locks in the Java package
[Link]. Gosu using clauses provide access to these classes and properly handle cleanup if
exceptions occur. Gosu also provides a readable syntax for creating custom objects for reentrant object handling.
WARNING Use external synchronization to ensure data integrity for concurrent access to entity
instances in a transaction bundle.
See also
• “Request and session scoped variables” on page 419
• “Concurrent lazy variables” on page 420
• “Concurrent cache” on page 421
• “Concurrency with monitor locks and reentrant objects” on page 422
• “Bundles and database transactions” on page 387
• Integration Guide
The recommended pattern for concurrent use is to store the instance of the variable as a class variable declared with
the static keyword. By using the static keyword on the class, many programming contexts can access the same
session variable or request variable. Use the generics syntax SessionVar<TYPE> when you define the variable. For
example, to store a String object, define the type as SessionVar<String>.
For example:
class MyClass {
static var _varStoredInSession = new SessionVar<String>()
In any other part of the application, you can write code that sets this property:
[Link] = "hello"
In another part of the application, you can write code that gets this property:
print( [Link] )
This example explicitly checks the RequestAvailable property. In business code, for example to support your
batch processes, you must decide what to do if RequestAvailable returns false.
Using RequestVar and SessionVar is strongly recommended, rather than the Java thread local API
[Link]<TYPE>. Because application servers pool their threads, using ThreadLocal increases the
Concurrency 419
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
risk of data remaining forever as a memory leak, because the thread to which you attached it never terminates. Also,
pooled threads can preserve stale data from a previous request, because the server thread pool reuses the thread for
future requests. If you ever use a ThreadLocal, it is critical to be very careful to clean up all code with a try/
finally block. Better practise is to convert that code to use RequestVar and SessionVar.
See also
• “Generics” on page 221
• Integration Guide
The example passes a block as an argument to [Link](...). That block creates a new ArrayList
that is parameterized to the String class. The parameter is a block that creates a new object. In this case, the block
returns a new ArrayList. You can create any object. In your business-use code, this block might be very resource-
intensive in creating or loading this object.
It is best to let Gosu infer the correct type of the block and the result of the make method, as shown in this example.
Using Gosu type inference simplifies your code because you do not need to use explicit Gosu generics syntax to
define the block type, such as the following version:
var i = _lazy.get()
If the block has not yet run, Gosu runs the block when you access the lazy variable. If the block has already run,
Gosu returns the cached value of the lazy variable and does not rerun the block.
A good approach to using a lazy variable is to define the variable as static and then define a property accessor
function to abstract the implementation of the variable. The following code shows an example inside a Gosu class
definition:
class MyClass {
// Lazy variable using a block that calls a resource-intensive operation that retuns a String
var _lazy = [Link]( \-> veryExpensiveMethodThatRetunsAString() )
If any code accesses the property MyLazyString, Gosu calls its property accessor function. The property accessor
always calls the get method on the object. Gosu runs the very expensive method only once, the first time that code
420 chapter 26: Concurrency
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
accesses the lazy variable value. If any code accesses this property again, Gosu uses the cached value and does not
execute the block again. This behavior is useful in cases where you want a system to start quickly and pay only
incremental costs for resource-intensive value calculations.
Concurrent cache
A similar class to the LockingLazyVar class is the Cache class. An instance of this class declares a concurrent cache
of values that you can look up quickly and in a thread-safe way. The cache is similar to a Least Recently Used
(LRU) cache. Because the Cache class uses the Java concurrency libraries, access to the cache is thread-safe. Each
entry in the cache is defined by a key, which is also called an input value. A block uses the value of the key to
calculate the value of the cache entry.
The constructor for a cache requires:
• A name as a String. The implementation uses this name to generate logging for cache misses.
• The size, as a number of slots.
• A block that defines a function to calculate a value from a key. Typically, this calculation is resource-intensive.
Use the key and value types to parameterize the Cache type using Gosu generics syntax. For example, if you need to
pass a String to the cache and get an Integer back, create a new Cache<String, Integer>.
To use the cache, call the get method and pass an input value, which is the key. If the value for the key is in the
cache, get returns that value. If the value is not cached, Gosu calls the block to calculate the value from the key and
then caches the result. On any subsequent call of the get method, the value is the same but Gosu uses the cached
value, if it is still in the cache. If too many items were added to the cache and the required item is unavailable, Gosu
reruns the block to regenerate the value. Gosu then caches the result again.
To use a cache within another class, you can define a static instance of the cache. The static variable definition
defines your block. Because the Cache class uses the Java concurrency libraries, this static implementation is thread-
safe. For example, in your class definition, define a static variable like this:
static var _myCache = new Cache<String, Integer>( "StrToInt", 1000, \ str -> getMyInt( str ) )
To use your cache, get a value from the cache using code like the following. In this example, inputString is a
String variable that may or may not contain a String that you used before with this cache:
The first time you call the get method, Gosu calls the block to generate the Integer value.
On any subsequent call of the get method, the value is the same but Gosu uses the cached value, if it is still in the
cache. If too many items were added to the cache and the required item is unavailable, Gosu reruns the block to
regenerate the value. Gosu then caches the result again in the concurrent cache object.
An even better way to use the cache is to abstract the cache implementation into a property accessor function. A
private static object Cache object, as shown in the previous example, can handle the actual cache. For example,
define a property accessor function such as:
Concurrency 421
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
These code examples are demonstrations that have a simple operation in the block. Typically, the overhead of
maintaining the cache is appropriate if your calculation is resource-intensive and you expect repeated access with
the same input values.
WARNING Incorrect implementation of caching can lead to run-time errors and data corruption.
Only use caches as a last resort for performance issues.
Procedure
1. Decide the key and value types for your cache based on input data.
For example, you need to pass a String and get an Integer back from the cache.
2. Construct a new cache.
For example:
3. To use the cache, call the get method and pass the input value, which is the key. If the value is in the cache,
get returns the value from the cache. If the value is not cached, Gosu calls the block and calculates the value
from the key and then caches the result.
For example:
print([Link]("Hello world")
print([Link]("Hello world")
"HELLO WORLD"
"HELLO WORLD"
Result
In this example, the first call of the get method calls the block to generate the uppercase value. On the second call
of the get method, the value is the same but Gosu uses the cached value.
For Gosu to recognize a valid reentrant object, the object must have at least one of the following attributes:
• The object implements the [Link] interface. For example, the following Java
classes in that package implement this interface: ReentrantLock, ReadWriteLock, Condition.
• You cast the object to the Gosu interface IMonitorLock. You can cast any arbitrary object to IMonitorLock. It is
useful to cast Java monitor locks to this Gosu interface.
• The object implements the Gosu class [Link]. This interface contains two methods with no
arguments: enter and exit. Your implementation code must properly lock or synchronize data access as
appropriate during the enter method and release any locks in the exit method.
For blocks of code that use locks by implementing [Link], a using clause simplifies
the code. The using statement always cleans up the lock, even if the code throws an exception.
uses [Link]
...
function useReentrantLockNew() {
using ( _lock ) {
// Do your main work here
}
}
Similarly, you can cast any object to a monitor lock by adding as IMonitorLock after the object. For example, the
following method code uses the object itself, by using the keyword this, as the monitor lock:
function monitorLock() {
using ( this as IMonitorLock ) {
// Do stuff
}
}
function useReentrantLockOld() {
_lock.lock()
try {
// Do your main work here
}
finally {
[Link]()
}
}
Alternatively, you can do your change in a Gosu block. This approach is not recommended. Returning the value
from a block imposes more restrictions on how you implement return statements. It is typically better to use the
using statement structure shown earlier in this topic.
uses [Link]
...
Concurrency 423
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
See also
• “Object life-cycle management with using clauses” on page 122
• [Link]
• [Link]
Checksums
This topic describes APIs for generating checksums. A checksum is a calculated number to detect modification of
data in transit. Such modification can be either accidental or malicious. For example, you can use a checksum to
detect corrupted stored data or errors in a communication channel. Longer checksums such as 64-bit checksums are
also known as fingerprints.
Overview of checksums
To improve detection of accidental modification of data in transit, you can use checksums. A checksum is a
computed value generated from an arbitrary block of digital source data. To check the integrity of the data at a later
time, recompute the checksum and compare it with the stored checksum. If the checksums do not match, the data
was altered either intentionally or unintentionally. For example, this technique can help detection of physical data
corruption or errors in a communication channel.
Be aware that checksums cannot perfectly protect against intentional corruption by a malicious agent. A malicious
attacker could modify the data in a way that preserves its checksum value or, depending on transport integrity,
substitute a new checksum. To guard against malicious changes, use encryption at the data level with a
cryptographic hash or the transport level, such as SSL/HTTPS.
WARNING Checksums improve detection from accidental modification of data but cannot detect
all intentional corruption by a malicious agent. If you need that level of protection, use encryption
instead of checksums, or in addition to checksums.
You can also use fingerprints to design caching and synchronizing algorithms that check whether data changed since
the last cached copy. You can save the fingerprint of the cached copy and an external system can generate a
fingerprint of its most current data. If you have both fingerprints, compare them to determine if you must
resynchronize the data. To work effectively, the fingerprint algorithm must provide near certainty that a real-world
change would change the fingerprint. Having two different values generate a matching fingerprint is called a
collision. A fingerprint uniquely identifies the data for most practical purposes, although changed data causing a
collision is theoretically possible.
Gosu provides support for 64-bit checksums in the class FP64 in the package [Link].
The FP64 class provides methods for computing 64-bit fingerprints of the following kinds of data:
• String objects
• Character arrays
• Byte arrays
• Input streams
Fingerprints provide a probabilistic guarantee that defines a mathematical upper bound on the probability of a
collision. A collision occurs if two different strings have the same fingerprint. Using 64-bit fingerprints, the odds of
Checksums 425
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
a collision are extremely small. The odds of a collision between two randomly chosen texts a million characters long
are less than 1 in a trillion.
Suppose you have a set S of n distinct strings each of which is at most m characters long. The odds of any two
different strings in S having the same fingerprint is described by the following equation where k is the number of
bits in the fingerprint:
(nm^2) / 2^k
For practical purposes, you can treat fingerprints as uniquely identifying the bytes that produced them. The
following mathematical notation demonstrates this assumption, given two String variables s1 and s2, using
the → symbol to mean “implies”:
Do not fingerprint the value of a fingerprint by fingerprinting the output of the FP64 methods toBytes and
toHexString. Using this type of fingerprint might lead to unexpected collisions. The shorter length of the
fingerprint itself invalidates the probabilistic guarantee that a collision is unlikely to occur.
Creating a fingerprint
To create a fingerprint object, instantiate the [Link].FP64 object and pass one of the supported
object types to the constructor:
• A String object:
var s = "hello"
var f = new FP64(s)
• A character array:
var s = "hello"
var ca : char[] = {s[0], s[1], s[2], s[3], s[4]}
var f = new FP64(ca)
An alternative method signature takes extra parameters for start position and length of the desired series of
characters in the array.
• A byte array:
An alternative method signature takes extra parameters for start position and length of the desired series of byes
in the array.
• A stream object:
var s = "testInputStreamConstructor"
new FP64(new ByteArrayInputStream([Link](s))));
• An input stream:
var s = "testInputStreamConstructor"
new FP64(new StringBuffer(g));
var s = "hello"
var f = new FP64(s)
var f2 = new FP64(f)
Extending fingerprints
The FP64 class provides methods for extending an existing fingerprint by more bytes or characters. This
functionality is useful if the only change to the source data was appending a known series of bytes to the end of the
original String data.
To produce a fingerprint equivalent to the fingerprint of the concatenation of two String objects, you can extend the
fingerprint created from one String using another String. Given the two String variables s1 and s2, the following
is true:
The same logic is true for character arrays, not just String objects.
All operations for extending a fingerprint are destructive. The operations modify the fingerprint object directly, in
place. All operations return the resulting FP64 object, so you can chain method calls together, such as in the
following code:
new FP64("x").extend(foo).extend(92))
If you need to make a copy of a fingerprint, instantiate the FP64 object and use the FP64 object to copy as the
constructor argument:
Checksums 427
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Gosu programs
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
chapter 28
Command‐prompt tool
A Gosu program is a file with a .gsp file extension that you can run directly from a command-prompt tool. You can
run self-contained Gosu programs outside the PolicyCenter server by using the Gosu command-prompt tool. The
Gosu command-prompt tool encapsulates the Gosu language engine.
Accessing entities and other types from the Gosu command‐prompt tool
Gosu programs that you run with the Gosu command-prompt tool cannot access some types available from
PolicyCenter Studio. For example, you cannot access entity types, PCF types, and plugin types. Some types have
different sets of methods because some Gosu enhancements are unavailable in the command-prompt tool.
IMPORTANT Guidewire does not support the import of built-in PolicyCenter application JARs into
Gosu command-prompt tool programs.
To add, edit, delete, or query PolicyCenter entity instances from a Gosu program, implement the majority of your
code as a PolicyCenter WS-I web service. From your Gosu program, read the command-prompt arguments, and then
call the web service.
See also
• “Command-prompt arguments” on page 433
• Integration Guide
Path Purpose
/bin/[Link] The Windows tool that invokes Gosu
Path Purpose
/src/gw/.../*.gs Core Gosu classes
/src/gw/.../*.gsx Core Gosu enhancements
/lib/*.jar Java archive (JAR) files that contain core Gosu libraries
To use the Gosu tool on another computer, copy the entire admin directory to that computer. Ensure that the
computer has a supported version of the Java run time.
IMPORTANT You are licensed to use the Gosu tool only to work with Guidewire applications.
You can change your system’s path to add the Gosu tool bin directory so that the command prompt can find the
gosu command. On Windows, modify the system Path variable by going to the Start menu and choosing Control
Panel→System→Advanced System Settings→Environment Variables. In System variables, choose the Path variable. At the
end of the variable value, type a semicolon and the full path to the bin directory in the Gosu tool directory.
For example, suppose you installed the Gosu shell directory to the path:
C:\gosu\
;C:\gosu\bin
To test this path, close any existing command-prompt windows, and then open a new command-prompt window.
Type the following command:
gosu -help
If the Gosu help information appears, the Gosu tool is installed correctly.
Add more paths to the search path for Java classes or Gosu -classpath path gosu -classpath C:\gosu
classes. Separate paths with semicolons. \projects\libs
Evaluate a Gosu expression at the command prompt. Surround -e expression gosu -e "new
the entire expression with quotation marks. For any quotation -eval expression [Link]()"
mark in the expression, replace it with three quotation marks. gosu -e """"a"""+"""b""""
For other special DOS characters such as > and <, precede
them with a caret (^) symbol.
Print help information for this tool. -h gosu -h
-help
See also
• “Checked arithmetic for add, subtract, and multiply” on page 80
Procedure
1. Create a file called [Link] containing only the following line:
print("Hello World")
gosu [Link]
If you have not yet added the gosu executable folder to your system path, instead type the full path to the gosu
executable.
The tool runs the program.
The program prints the following output:
Hello World
See also
• “Unpacking and installing the Gosu command-prompt tool” on page 431
Command‐prompt arguments
You can access command-prompt arguments to Gosu programs by manipulating raw arguments. You can parse the
full list of arguments from the command line as positional parameters. Alternatively, you can write a custom parser
to identify named options and their values. For example, you can write a parser for an option that has multiple parts
that are separated by space characters, such as -username jsmith. In this example, each of the -username and the
jsmith components is a separate raw argument.
To get the full list of command-prompt arguments as a list of String values, use the RawArgs property of the
[Link] class. This property provides an array of String values. You can access the values in this array in the
same way as any other array. For example, you can use Gosu code like the following lines.
// [Link]
var myArgs = [Link]
Procedure
1. Choose a directory in which to save your command-prompt tool. In this directory, create a subdirectory called
test, which is the package name.
2. Create a Gosu class that defines your properties. The following code defines two properties, one String
property named Name and a boolean property named Hidden:
package test
class Args {
// String argument
static var _name : String as Name = "No name"
3. Save this Gosu class file as the file [Link] in the test directory.
4. Create a Gosu program, using the following code:
uses test.*
var args = [Link]
var numArgs = [Link]
try {
if ([Link]( "-" )) {
if ((arg == "-name") and (i< numArgs-1)) {[Link] = args[i+1]}
if (arg == "-hidden") {[Link] = (i< numArgs-1) and (args[i+1] == "false")?false:true}
}
} catch (Exception) {
print("Error parsing args: " + args)
}
5. Click Save As and save this new command-prompt tool as [Link] in the directory that contains the
test subdirectory.
6. Open a command-prompt window and navigate to the directory that contains [Link].
7. In the command-prompt window, enter the following command
hello John
you are hidden!!!!
Programs
A Gosu program is a file with a .gsp file extension that you can run directly from a command-prompt tool.
You can run self-contained Gosu programs outside the PolicyCenter server by using the Gosu command-prompt
tool. The Gosu shell command-prompt tool encapsulates the Gosu language engine. You can run Gosu programs
directly from the Windows command prompt as an interactive session or run Gosu program files.
The following instructions describe running a basic Gosu program after you install the Gosu command-prompt tool.
These instructions apply only to the command-prompt shell for Gosu. If you are using the Gosu plugin for the
IntelliJ IDEA IDE, to get command-prompt Gosu you must download the full distribution at:
[Link]
See also
• “Command-prompt tool” on page 431
See also
• “Command-prompt arguments” on page 433
• “Create and run a Gosu program that processes arguments” on page 434
#!/usr/bin/env gosu
Programs 437
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
The # character that begins the metaline does not start a comment line in Gosu programs. The # character is not a
valid line-comment start symbol.
print(sum(10, 4, 7));
print(sum(222, 4, 3));
21
229
Testing
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
chapter 30
The GUnit Test Framework enables the writing of tests to exercise Gosu configuration code.
Tests are written in Gosu. You can execute these tests from the command line to include the tests in an automated
continuous integration work flow. You can also execute these tests from Guidewire Studio.
PCServerTestClassBase
Base class for tests that require a running server
PCUnitTestClassBase
Base class for tests that do not need the services provided by a running server
A test class extends one of the base classes. The test class name must end with the suffix Test, as in MySampleTest.
The base class implementation of the framework's setUp method tests for this condition and throws an
IllegalStateException if it is not met.
Store all test class files within the Studio modules/configuration/gtest directory hierarchy. New subdirectories
can be created within the hierarchy to organize test classes for your convenience.
@Suites("UniqueSuiteName")
class MyTestClass extends PCUnitTestClassBase {
...
}
Optionally, the @Suites annotation can be specified on the test class. The @Suites annotation accepts a unique
String argument. All the test classes grouped in a particular suite must specify the same @Suites annotation. An
associated suite class will subsequently be defined that also references the suite's string value.
The following sample source code demonstrates the use of the @Suites annotation. The [Link] file
defines a string constant called SAMPLE_SUITE_NAME. In the [Link] file, the MyTestClass class is defined
with a @Suites annotation that specifies the SAMPLE_SUITE_NAME constant. If other test classes existed in the suite,
each class would specify the same @Suites annotation. Finally, the [Link] file defines a suite class that
references SAMPLE_SUITE_NAME. Details about defining a suite class are described in a subsequent topic.
package [Link]
@Export
class MySuiteNames {
package [Link]
uses [Link]
@Suites(MySuiteNames.SAMPLE_SUITE_NAME)
class MyTestClass extends PCUnitTestClassBase {
...
}
package [Link]
uses [Link]
class MySuiteClass {
// References MySuiteNames.SAMPLE_SUITE_NAME.
// All test classes with a @Suites annotation that references SAMPLE_SUITE_NAME are included in the suite.
// Details of implementing the suite class are described in a subsequent topic.
}
The @Suites annotation is optional. Similarly, a suite class is not required to reference a unique suite name. A suite
class that does not reference a suite name will include all the test classes in the package that do not specify a
@Suites annotation. This "catch all" style of suite grouping can be useful early in the development cycle when only
a small number of tests exists and a logical criteria for grouping them into suites is not yet evident.
Each test class provides the following Gosu constructors.
construct()
construct(name : String)
The name of a framework test method must begin with the string test as in testAddNumbers. When running the
individual tests in a test class, the framework automatically executes each method that begins with the string test.
The following code illustrates the minimal skeletal structure of a test class based on the PCServerTestClassBase
class.
construct(testName : String) {
super(testName)
...
}
function testBasicSystemCheck() {
...
}
function testAnotherServerTest() {
...
}
Core functions
The GUnit Test Framework base classes provide core functions like setUp, beforeMethod, afterMethod, and
tearDown that define the basic skeletal structure of a test. The core functions are called automatically by the
framework as it processes the individual tests in a test class and test suite.
This section presents the core functions in the order in which they are executed when running a series of tests in a
test class and test suite. The following pseudocode further illustrates the execution order of each core function.
afterMethod()
tearDown()
}
afterClass()
}
Constructors
construct()
construct(name : String)
The name property is optional and not used by the framework. It can be used by a test or test suite to identify a
particular test object. If the name is not initialized in the constructor, it can be assigned by calling the object's
setName method.
Method: beforeClass
beforeClass() : void
The beforeClass method is executed a single time before running any of the test methods defined in a particular
test class. In a test suite with multiple test classes, each test class's beforeClass method is executed immediately
before running the tests in the class.
Do not create test instance variables in the beforeClass method; the variables will exist only for the first executed
test. Instead, create instance variables in beforeMethod.
Method: setUp
The setUp method is executed before running each test method defined in a test class. The method typically
configures the test context and creates any data objects required by the test.
A test class can overload the setUp method, but cannot override it.
In the base class implementation, if the test object's class name does not end with the string Test then an
IllegalStateException is thrown.
...
}
Method: beforeMethod
beforeMethod() : void
The beforeMethod method is executed before running each test method defined in the test class.
Method: afterMethod
The afterMethod method is called after each test method completes its execution.
The base class implementation clears all instance variables of the completed test.
Method: tearDown
The tearDown method is called after each test method completes its execution. The method typically performs
clean-up operations.
A test class can overload the tearDown method, but cannot override it.
Method: afterClass
afterClass() : void
The afterClass method is called after the completion of all tests in a test class.
Support functions
The GUnit Test Framework provides several categories of support functions that tests can call to implement a
desired test operation.
Testing environment
The framework provides functions to configure the testing environment and return information about it.
444 chapter 30: GUnit Test Framework
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Method: assert...
The framework provides various methods that assert whether a particular condition exists. Each method's name
begins with the prefix assert followed by the condition tested, as in assertEquals and assertNotZero.
The framework supports all the methods defined by the Assert class in the Java JUnit unit testing framework. The
Assert class provides commonly used methods like assertEquals, assertTrue, and assertFalse. For a complete
list of supported methods, refer to the JUnit Assert class documentation.
In addition, the framework extends the Assert class methods with new methods applicable to testing InsuranceSuite
configuration code. Example methods include assertBigDecimalEquals and assertDateEquals. The framework
assert methods are defined in the PLAssertions class, which is included in the [Link].v3 package.
The following table groups the methods into general categories. For complete details, refer to the PLAssertions
class documentation.
Category Methods
Method: getTestResultsDir
getTestResultsDir() : File
The getTestResultsDir method returns a [Link] object that references the directory where the test results
are stored.
Method: registerPlugin
The registerPlugin method registers a replacement plugin implementation to be used during the class's testing
operations. The method is available only in test classes that extend PCServerTestClassBase.
The pluginInterface argument specifies the plugin to be replaced. The implementation argument references the
plugin implementation to use during the testing operations.
The original plugin implementation is automatically restored at the completion of the class's tests by the base class
implementation of the afterClass method.
Method: setUpMutableSystemClock
setUpMutableSystemClock() : void
The setUpMutableSystemClock method establishes a temporary system clock available for testing purposes. Test
code can adjust the time of the temporary clock without affecting the actual system clock. The method is available
only in test classes that extend PCServerTestClassBase.
Call the setUpMutableSystemClock method in the test class's beforeClass method. The temporary clock is
initialized to the current system day and time. The original system clock is automatically restored by the base class
implementation's afterClass method.
The ChangesCurrentTimeUtil class provides static methods to set and advance the temporary clock. In general,
time is advanced to the future. Reversing time to the past can result in unexpected application behavior and is
strongly discouraged.
The setCurrentTime method sets the temporary system clock to a specified time. The incCurrentTime method
increments the clock by a specified number of milliseconds.
The test argument references the test class. The timeInMillis argument specifies the time in milliseconds to
assign to the clock. The deltaInMillis argument specifies the number of milliseconds to advance the clock.
Logging
The framework provides functions that support logging. The logging functions are based on the [Link]
object. Refer to the SLF4J (Simple Logging Facade for Java) documentation for details.
Method: addLoggingAppender
Method: getLogger
getLogger() : Logger
The getLogger method returns the [Link] object used by the test framework for logging.
Method: setLoggerLevel
uses [Link]
setLoggerLevel(getLogger(), [Link])
A test can log a message by calling the Logger method related to the relevant log level. Refer to the Logger
documentation of the SLF4J documentation for details.
function testMySampleServerTest() {
[Link]("Running sample server test") // Log a message at the INFO level
Method: startLogCapture
The startLogCapture method creates a new logging object that captures subsequent logging events.
The method returns a CapturingLogger object.
uses [Link]
function testMySampleServerTest() {
var logger : CapturingLogger
try {
logger = startLogCapture(getLogger()) // Start capturing the test logger
Miscellaneous
The framework provides several general purpose functions.
Method: getName
getName() : String
The getName method retrieves the value of the object's name property.
The name property can be assigned in the object's constructor or by calling the setName method.
Method: getUniqueSuffixForTest
getUniqueSuffixForTest() : String
The getUniqueSuffixForTest method generates a globally unique string. Possible uses of the string include
avoidance of duplicate keys and as a suffix to the test object's name property.
[Link]("MySampleTest" + [Link]())
[Link]("MySampleTest" + [Link]())
Method: setName
The setName method assigns the value of the name argument to the object's name property.
Method: toString
toString() : String
package [Link]
uses [Link]
uses [Link]
uses [Link]
uses [Link]
class MySuiteClass {
The framework calls the suite method automatically during normal framework processing. The method returns a
JUnit-based Test object. The Test object is managed by the framework and does not need to be manipulated by
test code.
gwb compile
gwb runSuite -Dsuite=[TestSuiteClassName] [optional -D arguments]
The gwb compile command compiles the Gosu test and test suite classes.
The gwb runSuite command runs the tests in a specified test suite. The command accepts the following options.
Each option is prefixed by -D.
Option Description
Option Description
[Link] Directory to store temporary test files. If a relative directory is specified, the location is relative to the
application's root directory. Optional.
Default: The /tmp directory.
Example: -[Link]=build/test-temp
memory Maximum memory in MB to allocate to run tests. Optional.
Default: 768
Example: -Dmemory=2048
Note: Guidewire does not recommend or support the use of classes that extend
[Link] or classes that reside in the [Link].* package in
a production environment. Guidewire provides GUnit as a development test facility only.
As you run tests against code, you need to run these test in the context of a known set of data objects. This set of
objects is generally known as a test fixture. You use Gosu entity builders to create the set of data objects to use in
testing.
Guidewire provides a number of entity “builders” as utility classes to quickly and concisely create objects (entities)
to use as test data. The PolicyCenter base configuration provides builders for the base entities (such as
PolicyBuilder, for example). However, if desired, you can extend the base DataBuilder class to create new or
extended entities. You can commit any test data that you create using builders to the test database using the
[Link] method.
For example, the following builder creates a new Person object with a FirstName property set to “Sean” and a
LastName property set to “Daniels”. It also adds the new object to the default test bundle.
For readability, Guidewire recommends that you place each configuration method call on an indented separate line
starting with the dot. This makes code completion easier. It also makes it simpler to alter a line or paste a new line
into the middle of the chain or to comment out a line.
Gosu builders extend from the base class [Link]. To view a list of valid builder types
in Guidewire PolicyCenter, use the Studio code completion feature. Type [Link]. in the Gosu editor
and Studio displays the list of available builders.
Package completion
As you create an entity builder, you must either use the full package path, or add a uses statement at the beginning
of the test file. However, in general, Guidewire recommends that you place the package path in a uses statement at
the beginning of the file.
uses [Link]
@[Link]
construct(testname : String) {
super(testname)
}
...
function testSomething() {
//perform some test
var account = new AccountBuilder().create()
}
...
}
Guidewire provides certain of the Builder classes in [Link].* and others in [Link].
Verify the package path as you create new builders.
new TypeOfBuilder()
This creates a new builder of the specified type, with the Builder class setting various default properties on the
builder entity. Each entity builder provides different default property values depending on its particular
implementation. For example, to create (or build) a default address, use the following:
To set specific properties to specific values, use the property configuration methods. The following are the types of
property configuration methods, each which serves a different purpose as indicated by the method’s initial word:
as A property that holds only a single state. For example, asSmallBusiness or asAgencyBill.
with The single element or property to be set. For example, the following sets a FirstName property:
withFirstName("Joe")
Use a [Link](...) configuration method to add a single property or value to a builder object. For
example, the following Gosu code creates a new Address object and uses a number of with(...) methods to
initialize properties on the new object. It then uses an asType(...) method to set the address type.
After you create a builder entity, you are responsible for writing that entity to the database as part of a transaction
bundle. In most cases, you must use one of the builder create methods to add the entity to a bundle. Which create
method one you choose depends on your purpose.
To complete the previous example, add a create method at the end.
...
.create()
[Link]( bundle )
[Link]()
[Link]()
Method Description
create() Creates an instance of this builder's entity type in the default bundle. This method does not commit the
bundle. Studio resets the default bundle before every test class and method.
createAndCommit() Creates an instance of this builder’s entity type in the default bundle, and performs a commit of that
default bundle.
create(bundle) Creates an instance of this builder’s entity type, with values determined by prior calls to the entity. The
bundle parameter sets the bundle to use while creating this builder instance.
new PersonBuilder()
.withFirstName("Sean")
.withLastName("Daniels")
.withPrimaryAddress(address)
.create()
[Link]()
In this example, Address and Person share a bundle, so committing [Link] also stores Person in the
database. If you do not need a reference to the Person, then you do not need to store it in a variable.
GUnit resets the default bundle before every test class and method.
uses [Link]
function myTest() {
var person : Person
uses [Link]
Nesting builders
It is possible to nest one builder inside of another by having a method on a builder that takes another builder as an
argument. For example, suppose that you want to create an Account that has an AccountLocation. In this situation,
you might want to do the following:
function myTest(){
var account : Account
[Link]( \ bundle -> {
account = new AccountBuilder().create(bundle)
})
}
There are generally two kinds of accounts: person and company. By default, AccountBuilder creates a person
account. If you want a company account, then you need to assign a company contact as the account holder, as shown
in the following code sample:
uses [Link]
uses [Link]
In this example, passing false to AccountBuilder tells it not to create a default account holder. Instead, you pass in
your own account holder by calling withAccountHolderContact, which takes a ContactBuilder. In this case,
CompanyBuilder suffices. The passed in number 42 seeds the default data with something unique (ideally) and
identifiable.
The following example creates a company account and overrides some of the default values. Anywhere you see
code, it means a seed value. (String variants derive from the given values.) It also illustrates how to nest the results
of one builder inside another.
uses [Link]
uses [Link]
uses [Link]
uses [Link]
var code = 48
The following example takes the previous code and presents it as a single builder that takes other builders as
arguments. While more compact, it also takes more planning and understanding of builders to create. Notice the
successive levels of indenting used to signal the creation of a new (embedded) builder.
uses [Link]
uses [Link]
uses [Link]
uses [Link]
The following MyPersonBuilder class extends the existing PersonBuilder class. The existing PersonBuilder
class contains methods to set a home phone number and mobile phone number. The new extended class contains a
method to set the person’s alternative phone number. As there is no static field for the properties on a type, you must
look up the property by name. Note that you must first define the new property in the data model.
uses [Link]
construct() {
super( true )
}
The PersonBuilder class has two constructors. This code sample uses the one that takes a Boolean that means
create this class withDefaultOfficialID.
456 chapter 31: Using entity builders to create test data
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
Another more slightly complex example would be if you extended the Person object and added a new
PreferredName property. In this case, you might want to extend the PersonBuilder class also and add a
withPreferredName method to populate that field through a builder.
Parameter Description
BuilderEntity Type of entity created by the builder. The create method requires this parameter so that it can return a
strongly‐typed value and, so that other builder methods can declare strongly‐typed parameters.
BuilderType Type of the builder itself. The with methods require this on the DataBuilder class so that it can return a
strongly‐typed builder value (to facilitate the chaining of with methods).
If you choose to extend the DataBuilder class ([Link]), place your newly created
builder class in the [Link] package in the Studio Tests folder. Start any method that you define in
your new builder with one of the following recommended words:
as A property that holds only a single state. For example, asSmallBusiness or asAgencyBill.
with The single element or property to be set. For example, the following sets a FirstName property:
withFirstName("Joe")
Your configuration methods can set properties by calling [Link] and [Link].
You can provide property values as any of the following:
• Simple values.
• Beans to be used as subobjects.
• Other builders, which PolicyCenter uses to create subobjects if it calls your builder's create method.
• Instances of [Link]. For example, an instance that generates a different value to
satisfy uniqueness constraints for each instance constructed.
[Link] and [Link] optionally accept an integer order argument that
determines how PolicyCenter configures that property on the target object. (PolicyCenter processes properties in
ascending order.) If you do not provide an order for a property, Studio uses DataBuilder.DEFAULT_ORDER as the
order for that property. PolicyCenter processes properties with the same order value (for example, all those that do
not have an order) in the order in which they are set on the builder.
In most cases, Guidewire recommends that you omit the order value as you are implement builder configuration
methods. This enables callers of your builder to select the execution order through the order of the configuration
method calls.
Constructors for builders can call set, and similar methods to set up default values. These are useful to satisfy null
constraints so it is possible to commit built objects to the database. However, Guidewire generally recommends that
you limit the number of defaults. This is so that you have the maximum control over the target object.
addPopulator(new AbstractBeanPopulator<MyEntity>(group) {
The AbstractBeanPopulator class automatically converts builders to beans. That is, if you pass a builder to the
constructor of AbstractBeanPopulator, it returns the bean that it builds in the execute method. The following
example illustrates this.
addPopulator(new AbstractBeanPopulator<MyEntity>(groupBuilder) {
Parameter Type
ExtSystem Typekey
UserName String
Parameter Type
Password String
After creating your custom entity and its builder class, you need to test it. To accomplish this, you need to do the
following:
3. Create a test class to exercise and test your new builder. [Link]
To create a new array ExtCredential custom entity, do the following tasks, as shown in the procedure.
• Add the ExtSystem typelist by using the Typelist editor in Guidewire Studio.
• Define the ExtCredential array entity in the ExtCredential, by using the editor in Guidewire Studio.
• Modify the array entity definition to include a foreign key to User in ExtCredential.
• Add an array field to the User entity in [Link].
Procedure
1. Add the ExtSystem typelist.
[Link] Guidewire Studio, navigate to configuration→config→Extensions→Typelist.
b. Right-click Typelist, and then click New→Typelist.
c. In Name, type ExtSystem. Then, click OK.
d. Add a few external system typecodes.
Add SystemOne, SystemTwo, or similar items.
2. Create the ExtCredential entity type.
a. In Guidewire Studio, navigate to configuration→config→Extensions→Entity.
b. Right-click Entity, and then click New→Entity.
c. In Entity, type ExtCredential. Then, click OK.
d. Set the exportable attribute to true.
e. Set the platform attribute to true.
f. Add a typekey with the following attributes:
name
ExtSystem
typelist
ExtSystem
nullok
false
desc
Type of external system
g. Add a column with the following attributes:
name
UserName
Using entity builders to create test data 459
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
type
shorttext
nullok
false
h. Add a column with the following attributes:
name
Password
type
shorttext
nullok
false
i. Add a foreignkey with the following attributes:
name
UserID
fkentity
User
nullok
false
desc
FK back to User
3. Modify the User entity.
a. In Guidewire Studio, in configuration→config→Extensions→Entity, double-click [Link].
b. Add an array with the following attributes:
name
ExtCredentialRetirable
type
ExtCredential
desc
An array of ExtCredential objects
arrayfield
UserID
exportable
false
4. Create an ExtCredentialBuilder class that extends the base DataBuilder class. Place this class in its own
package under configuration and in the gsrc folder.
a. In Guidewire Studio, navigate to configuration→config→gsrc.
b. Right-click gsrc, and then click New→Package.
c. In Enter new package name, type a name for the new package. Then, click OK.
Type AllMyClasses.
d. Right-click AllMyClasses, and then click New→Gosu Class.
e. In Name, type ExtCredentialBuilder. Then, click OK.
460 chapter 31: Using entity builders to create test data
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
package AllMyClasses
uses [Link]
construct() {
super(ExtCredential)
}
package MyTests
uses [Link]
uses [Link]
@[Link]
class ExtCredentialBuilderTest extends [Link] {
function beforeClass () {
[Link]( \ bundle -> {
credential = new ExtCredentialBuilder()
.withType( "SystemOne" )
.withUserName( "Peter Rabbit" )
.withPassword( "carrots" )
.create( bundle )
}
)
}
function testUsername() {
assertEquals("User names do not match.", [Link], "Peter Rabbit")
}
function testPassword() {
assertEquals("Passwords do not match.", [Link], "carrots")
}
}
Result
If you run the ExtCredentialBuilderTest class as defined, the GUnit tester displays green icons, indicating that
the tests were successful.
Gosu style
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
chapter 32
Coding style
This topic lists some recommended coding practices for the Gosu language. These guidelines encourage good
programming practices that improve Gosu readability and encourage code that is error-free, understandable, and
maintainable by other people.
Omit semicolons
Omit semicolons as line terminators, because they are unnecessary in almost all cases. Gosu code looks cleaner
without semicolons.
Semicolons are only needed if you need to separate multiple Gosu statements all written on a single line in a one-
line statement list. This construction is generally not recommended, but is sometimes appropriate for simple
statement lists declared in-line in Gosu block definitions.
Type declarations
Omit the type declaration if you declare variables with an assignment. Instead, use as TYPE where appropriate. The
type declaration is particularly redundant if a value needs coercion to a type that is already included at the end of the
Gosu statement.
The recommended type declaration style is:
Consider the following Gosu code that uses the equals method:
( [Link]( [Link] ) )
( planName == [Link]) )
Although the == and the != comparison operators are more powerful and more convenient than equals(), be aware
of coercions that may occur.
Gosu prevents you from comparing incompatible array types for equality with the == and != operators. For example,
the following code generates a compile-time error because arrays of numbers and strings are incompatible:
If the array types are comparable, Gosu recursively applies implicit coercion rules on the array’s elements. For
example, the following code evaluates to true because a Number is a subclass of Object, so Gosu compares the
individual elements of the table:
You can also compare objects by using the === and !== operators.
Capitalization conventions
The following table lists conventions for capitalization of various Gosu language elements:
Because Gosu is case-sensitive, you must access existing types exactly as they are declared, including correct
capitalization. Capitalization in the middle of a name is also important.
Use the Gosu editor’s code completion feature to enter the names of types and properties correctly. This ensures
standard capitalization.
Some entity and typelist APIs are case insensitive if they take a String value for the name of an entity, a property,
or a typecode. However, best practice is to pass the name exactly as declared.
Although Gosu supports public variables for compatibility with other languages, the standard Gosu style is to use
public properties backed by private variables rather than public variables. Gosu syntax supports creating the local
variable and the public property on the same line by using the as keyword followed by the property name.
For example, in your Gosu classes that define class variables, use this variable declaration syntax:
This line declares a private variable called _firstname, which Gosu exposes as a public property called FirstName.
Do not create a public variable, like the following line:
public var FirstName : String // Do not do this. Public variable scope is not Gosu standard style.
For example, the following example declares a variable as an Object, but downcasts the type to String in a block
of code within an if statement.
Because of downcasting, the following code is valid:
if ( x typeis String ) {
strlen = [Link]
}
This code works because the typeis inference is effective immediately and propagates to adjacent expressions.
Note that length is a property on String, not Object. By using typeis to downcast from Object to String, you
do not need an additional cast around the variable x. The following code is equivalent but has an unnecessary cast:
if ( x typeis String ) {
strlen = (x as String).length // "length" is a property on String, not Object
}
Use automatic downcasting to write readable, concise Gosu code. Do not write Gosu code with unnecessary casts.
See also
• “Equality expressions” on page 81
• “Properties” on page 151
• “Basic type checking” on page 403
Coding style 467
Guidewire PolicyCenter 10.0.0 Gosu Reference Guide
In Gosu, property access defaults to being null-safe, meaning if earlier parts of a property path evaluate to null, the entire expression returns null without throwing an exception. On the other hand, method calls are not inherently null-safe; Gosu throws a null-pointer exception (NPE) if the object on which the method is called is null. To perform null-safe method calls, Gosu provides the ?. operator, which returns null if the preceding object evaluates to null .
The Gosu query builder API allows developers to perform queries similar to SQL SELECT statements but in an object-oriented way. Using methods like Query.make() and select(), developers can define the entity type, add restrictions, and specify ordering, akin to SQL clauses such as SELECT, WHERE, and ORDER BY. The main advantage is the seamless integration of database queries within Gosu's type-safe environment, allowing developers to write more readable and maintainable query codes directly in Gosu .
Gosu enhances Java types by providing built-in extensions, which improve code readability and maintainability. By transforming Java getter and setter methods into properties, Gosu simplifies object interaction, allowing developers to access these properties directly without explicit method calls. This leads to more intuitive and streamlined Gosu code, enhancing clarity and reducing verbosity .
Gosu's seamless integration with Java types allows Gosu code to instantiate Java classes, implement Java interfaces, and manipulate Java objects as if they were native Gosu objects. This interoperability lets developers enhance existing Java applications with Gosu's scripting capabilities and concise syntax without needing to rewrite Java code, thus saving time and resources .
The null-safe default operator (?:) in Gosu aids in managing default values by providing an alternative value if the left expression evaluates to null. This operator is particularly useful for ensuring that certain variables are assigned meaningful default values instead of null, thereby simplifying null-related conditional logic .
Gosu designs APIs around null-safe property paths by encouraging the use of properties instead of public instance variables. By exposing data as properties, it leverages Gosu's null-safe handling to avoid null-pointer exceptions. This approach separates the implementation from interaction layers, allowing for more robust and maintainable APIs. Developers can thus design logic that inherently utilizes null safety, enhancing the reliability of the API .
Gosu enhances the handling of collections by providing features such as blocks, which can be used for operations like sorting with concise syntax. For example, Gosu's sortBy function simplifies sorting logic by using blocks to define the sorting key, which reduces code verbosity compared to Java's equivalent implementations using anonymous classes .
Using CDATA sections in XML handling with Gosu allows inclusion of special characters without escaping them, which prevents problems such as unescaped '<' or '&' characters. This feature improves the robustness of XML data handling by minimizing errors in data interpretation and transmission, making the XML integration in Gosu applications more reliable .
Gosu object initializers simplify the code by reducing the repetition of the object variable name. In a standard Java pattern, each property assignment requires explicitly referencing the object variable. Gosu allows initialization using a single statement that includes all property assignments, making it more concise and readable .
Null-safe operators in Gosu, such as the ?. operator for property and method access, or the ?[] for index operations, prevent null-pointer exceptions by evaluating to null if the object or index is null. This enhances error handling by avoiding runtime exceptions, making the code more robust against null references .