Best Practice
Best Practice
PolicyCenter®
Guidewire Claim Portal, Guidewire Policyholder Portal, Guidewire Spotlight, Gosu, Adapt and succeed, and the
Guidewire logo are trademarks, service marks, or registered trademarks of Guidewire Software, Inc. in the
United States and/or other countries.
All other trademarks are the property of their respective owners.
This material is confidential and proprietary to Guidewire and subject to the confidentiality terms in the
applicable license agreement and/or separate nondisclosure agreement.
Guidewire products are protected by one or more United States patents.
Product Name: Guidewire PolicyCenter
Product Release: 9.0.0
Document Name: PolicyCenter Best Practices Guide
Document Revision: 24-June-2016
PolicyCenter 9.0.0 Best Practices Guide
Contents
About PolicyCenter Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Conventions in This Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1 Data Model Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Entity Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Observe General Entity Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Add a Prefix or Suffix to Entity Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Use Singular for Field Names Except for Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Add ID as a Suffix to Column Names for Foreign Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Typelist Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Observe Typelist Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Add a Suffix to New Typelists and Typecode Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Data Model Best Practices Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2 User Interface Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Page Configuration Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Modify Base PCF Files Whenever Possible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Add a Suffix to New PCF Files to Avoid Name Conflicts . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Display Keys Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Use Display Keys to Display Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Use Existing Display Keys Whenever Possible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Observe Display Key Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Add a Suffix to New Display Keys to Avoid Name Conflicts . . . . . . . . . . . . . . . . . . . . . . . . . 17
Organize Display Keys by Page Configuration Component. . . . . . . . . . . . . . . . . . . . . . . . . . . 17
User Interface Performance Best Practices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Avoid Post on Change and Client Reflection for Page Refreshes . . . . . . . . . . . . . . . . . . . . . . 17
Avoid Repeated Calculations of Expensive Widget Values . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Avoid Expensive Calculations of Widget Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Use Application Permission Keys for Visibility and Editability . . . . . . . . . . . . . . . . . . . . . . . 19
User Interface Best Practices Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3 Rules Best Practices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Rules Naming Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Observe Rule Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Observe Operating System Length Restrictions on Rule Names . . . . . . . . . . . . . . . . . . . . . . . 23
Get and Display Rule Names in Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Assign a Dedicated Rules Librarian to Manage Rule Names . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Rules Performance Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Purge Unused and Obsolete Rules Before Upgrading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Rules Best Practices Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Contents 3
PolicyCenter 9.0.0 Best Practices Guide
4 Contents
PolicyCenter 9.0.0 Best Practices Guide
Contents 5
PolicyCenter 9.0.0 Best Practices Guide
6 Contents
PolicyCenter 9.0.0 Best Practices Guide
Document Purpose
InsuranceSuite Guide If you are new to Guidewire InsuranceSuite applications, read the InsuranceSuite Guide for
information on the architecture of Guidewire InsuranceSuite and application integrations.
The intended readers 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 intended readers are everyone who works with PolicyCenter.
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 implementation engineers who must merge base application changes
into existing PolicyCenter application extensions and integrations.
Configuration Upgrade Guide Describes how to upgrade your PolicyCenter configuration from a previous major version.
The intended readers are system administrators and implementation engineers who must
merge base application changes into existing PolicyCenter application extensions and inte-
grations. The Configuration Upgrade Guide is published with the Upgrade Tools, and is
available on the Guidewire Resource Portal.
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. Consult 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 admin-
istrators responsible for managing security, backups, logging, importing user data, or appli-
cation monitoring.
Configuration Guide The primary reference for configuring initial implementation, data model extensions, and
user interface (PCF) files. 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 generated at any time to reflect the current PolicyCenter configuration. The intended
readers are configuration 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 configuration engineers.
Globalization Guide Describes how to configure PolicyCenter for a global environment. Covers globalization top-
ics such as global regions, languages, date and number formats, names, currencies,
addresses, and phone numbers. The intended readers are configuration engineers who
localize PolicyCenter.
Rules Guide Describes business rule methodology and the rule sets in PolicyCenter Studio. The
intended readers are business analysts who define business processes, as well as pro-
grammers who write business rules in Gosu.
Document Purpose
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.
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 external systems and extending application behavior with custom pro-
gramming code. The intended readers are system architects and the integration program-
mers who write web services code or plugin 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 language, 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
implementation 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 read-
ers are business analysts and implementation engineers who customize the product model
and design new lines of business.
Support
For assistance with this software release, contact Guidewire Customer Support:
• At the Guidewire Resource Portal – http://guidewire.custhelp.com
• By email – support@guidewire.com
• By phone – +1-650-356-4955
9
PolicyCenter 9.0.0 Best Practices Guide
10 Chapter :
chapter 1
The PolicyCenter data model comprises metadata definitions of data entities that persist in the PolicyCenter
application database. Metadata definition files let you define the tables, columns, and indexes in the relational
database that supports your application. Typelist definitions let you define sets of allowed codes for specific
typekey fields on entities.
This topic includes:
• “Entity Best Practices” on page 11
• “Typelist Best Practices” on page 13
• “Data Model Best Practices Checklist” on page 13
See also
• “The PolicyCenter Data Model” on page 163 in the Configuration Guide
Adding the suffix ID to the column names of foreign keys helps database administrators identify columns in the
database that Guidewire uses as foreign keys.
If you add a foreign key as an extension to a base entity, follow the best practice of adding a prefix or suffix to the
name. For example:
<foreignkey
columnName="Policy_ExtID"
...
name="Policy_Ext"/>
See also
• “Working with Typelists” on page 265 in the Configuration Guide
Typelist Names begin with a capital letter. Medial capitals separate ActivityCategory
words.
Code Names contains only lower-case letters. Underscores (_) approval_pending
separate words.
Name Each word in a name begins with a capital letter. Spaces sep- Approval Pending
arate words.
PolicyCenter uses page configuration format (PCF) files to render the PolicyCenter application. PCF files
contain metadata definitions of the navigation, visual components, and data sources of the user interface. Display
keys provide the static text that visual components of the user interface display.
This topic includes:
• “Page Configuration Best Practices” on page 15
• “Display Keys Best Practices” on page 16
• “User Interface Performance Best Practices” on page 17
• “User Interface Best Practices Checklist” on page 20
See also
• “Using the PCF Editor” on page 311 in the Configuration Guide
See also
• “Using the Display Keys Editor” on page 151 in the Configuration Guide
• “Localizing Display Keys” on page 44 in the Globalization Guide
PolicyCenter represents display keys in a hierarchical name space. A period (.) separates display key names in
the paths of the display key hierarchy. For example:
Validation.Contact.ContactDetail
Generally, you specify text values for display key names that are leaves on the display keys resource tree. Gener-
ally, you do not specify text values for display key names that are parts of the path to a leaf display key. In the
preceding example, the display keys Validation and Validation.Contact have no text values, because they are
parts of a display key path. The display key ContactDetail has a text value, Contact Detail, because it is a leaf
display key with no child display keys beyond it.
You want to add a display key for the text Delete Contact. Add a new display key named DeleteContact_Ext.
Validation.Contact.ContactDetail
Validation.Contact.DeleteContact_Ext
Validation.Contact.NewContact
You can change the text for base display keys to change the text that the base configuration of the application
displays. Guidewire recommends that you use the base configuration display keys for this purpose so the base
configuration PCF files can just make use of the new values. If you add display keys with the suffix _Ext with
the intention of using them in the base configuration, the base configuration PCF files must be altered to use
them.
If a page with this range input widget has any postOnChange fields, PolicyCenter potentially evaluates the
expression multiple times for each postOnChange edit that a user makes.
The following modified sample code improves performance. It assigns a performance intensive expression to a
page variable and assigns the variable to the widget value.
Variables
...
initialValue |someExpensiveMethod()
name |expensiveResult
--------------------------------
Input: myInput
...
value |expensiveResult
Although PolicyCenter evaluates page variable with recalculateOnRefresh set to true for each postOnChange
edit, page variables can yield performance improvements compared to widget values. If several widgets use the
same expression for their values, using a page variable reduces the number of evaluations by a factor equal to the
number widgets that use it. For example, the valueRange of a range input used for drop-down lists in a list view
column are evaluated at least once for each row.
The following modified sample code improves performance. It assigns a performance intensive expression to a
page variable. PolicyCenter evaluates page variables only once before it displays a page, regardless how many
contexts under which it evaluates widget properties on the page.
Variables
...
initialValue |activity.someExpensiveMethod()
name |expensiveResult
--------------------------------
Input: myInput
...
id |myInput
...
visible |expensiveResult
Application permission keys evaluate the current user against general system permissions and the access control
lists of specific entity instances.
“Avoid Post on Change and Client Reflection for Page Refreshes” on page 17
PolicyCenter rules comprise hierarchies of conditions and actions that implement complex business logic. As a
best practice, Guidewire recommends that you edit rules by using the Rules editor in Guidewire Studio.
This topic includes:
• “Rules Naming Best Practices” on page 21
• “Rules Performance Best Practices” on page 24
• “Rules Best Practices Checklist” on page 25
See also
• “Rules: A Background” on page 11 in the Rules Guide
IMPORTANT Guidewire truncates Identifier values that exceed eight characters if you include the
actions.ShortRuleName property in rule actions to display rule names in messages that you log or
display. Guidewire also truncates Identifier values that exceed eight characters in automatic log
messages if you enable the RuleExecution logging category and set the server run mode to Debug.
• Begin Identifier with up to four capital letters to identify the rule set or parent rule of which the rule is a
member.
• End Identifier with at least four numerals to identify the ordinal position of the rule within the hierarchy of
rules in the set.
• For Description values, keep them simple, short, and consistent in their conventions.
• Limit the total length of rule names to 60 characters.
For example:
CV000100 - Future loss date
The rule set contains four root rules, with identifiers CV001000, CV002000, CV003000, and CV004000. The
numbers at the end of the identifiers, 1000, 2000, 3000 and 4000, are units of one thousand. This spread of
numbers lets you add new root rules between existing ones without renumbering. You want identifier numbers
for rules in a set to remain in sequential order to mimic the order of rules within the fully expanded set.
For example, you want to add a rule between CV002000 and CV003000. Assign the new rule the identifier
CV002500.
Claim Validation Rules
CV001000 - Future loss date
CV002000 - Policy expiration date after effective date
CV002500 - Not Set: Coverage in question
CV003000 - Injury diagnosis validity dates
The spread of numbers for child rules of a root parent rule generally are units of one hundred. This spread of
numbers lets you add new child rules between existing ones without renumbering. Most importantly, the
numbers of child rules must fall between the numbers of their parent rule and the sibling rule that follows their
parent. In this example, the numbers for child rules satisfy both conventions.
The parent and child naming convention applies to another, third level of children. For example, you want to add
two new child rules to the rule CVI03100 - Workmens’s Compensation. Begin the child identifiers with CVIW, a
code to identify “Claim Validation Injury Workmen’s Compensation” rules. At the third level of a rule set hier-
archy, the spread of numbers for the child rules generally are units of ten.
Claim Validation Rules
...
CV003000 - Injury
CVI03100 - Workmen’s Compensation
CVIW3110 - Claimant exists
CVIW3120 - Not Set: Injury description
CV103900 - Default
CV004000 - Expected recovery exceeds 100
Rule Actions:
producerCode.rejectField("ProducerCodeRoles", null, null, "loadsave",
"A role is required for producer code" + producerCode.Code + "."
)
As written, the rejection message that the rule action displays makes it difficult to determine exactly which rule
caused an update to fail. To help identify the specific rule in the rejection message, use the
actions.getRule().DisplayName property to include the identifier portion of the rule name in the message.
Rule Actions:
producerCode.rejectField("ProducerCodeRoles", null, null, "loadsave",
"A role is required for producer code " + producerCode.Code +
". Rule: " + actions.getRule().DisplayName.substring(8)
)
By including the rule display name in the rule action, users see the following statement in the Validation window
when the rule action executes.
A role is required for producer code ACME235. Rule: PCV01000
Note: In actual practice, Guidewire recommends that you make all String values into display keys.
Gosu is a general-purpose programming language built on top of the Java Virtual Machine. PolicyCenter uses
Gosu as its common programming language.
This topic includes:
• “Gosu Naming and Declaration Best Practices” on page 27
• “Gosu Commenting Best Practices” on page 30
• “Gosu Coding Best Practices” on page 32
• “Gosu Performance Best Practices” on page 38
• “Use Comparison Methods Instead of the Where Method” on page 43
• “Gosu Best Practices Checklist” on page 45
See also
• “Gosu Introduction” on page 15 in the Gosu Reference Guide
Variable names Name variables in mixed case, with an initial lower case letter nextPolicyNumber
and a medial capital for each internal word. Name variables firstName
mnemonically so that someone reading your code can under- recordFound
stand and easily remember what your variables represent.
Do not use single letters such as “x” for variable names,
except for short-lived variables, such as loop counts.
Function names Compose function names in verb form. Name functions in getClaim_Ext()
mixed case, with an initial lower case letter and medial capi- getWageLossExposure_Ext()
tals for each internal word. Add the suffix _Ext to the ends of
function names to avoid future naming conflicts if Guidewire
adds or changes base functions.
Class name Compose class names in noun form. Name classes in mixed StringUtility_Ext
case, with an initial upper case and medial capitals for each MathUtility_Ext
internal word. Add the suffix _Ext to the ends of class names
to avoid future naming conflicts if Guidewire adds or changes
base classes.
Avoid declaring public variables, as the following sample Gosu code does.
public var FirstName : String // Do not declare a public variable.
For general information, see “Properties” on page 187 in the Gosu Reference Guide.
If you want a new function that operates on single instances of an entity type, declare the new function in a sepa-
rate class extension to that entity type.
For example, you want a new function to suspend a policy. Name your new function suspend. Do not declare the
function as static with a Policy instance as its parameter. Instead, declare the function as an extension of the
Policy class, so callers can invoke the method directly on a Policy instance. For example:
if policy.suspend() {
// Do something to suspend the policy.
}
The following table lists conventions for capitalization of various Gosu language elements:
Gosu keywords Always specify Gosu keywords correctly as they are declared, typically if
lowercase.
type names, including uppercase first character DateUtil
class names Claim
local variable names lowercase first character myClaim
Some entity and typelist APIs are case insensitive if they take String values for the name of an entity, a property,
or a typecode. However, it is best write your code as if they are case sensitive.
See also
• “Case Sensitivity” on page 25 in the Gosu Reference Guide
Comment Placement
As a commenting best practice, always place block comments before every class and method that you write.
Briefly describe the class or method in the block comment. For comments that you place within methods, use any
of the commenting styles to help clarify the logic of your code.
Block Comments
Block comments provide descriptions of libraries and functions. A block comment begins with a slash followed
by an asterisk (/*). A block comment ends with an asterisk followed by a slash (*/). To improve readability,
place an asterisk (*) at the beginnings of new lines within a block comment.
/*
* This is a block comment.
* Use block comments at the beginnings of files and before
* classes and functions.
*/
Place block comments at the beginnings of files, classes, and functions. Optionally, place block comments within
methods. Indent block comments within functions to the same level as the code that they describe.
Javadoc Comments
Javadoc comments provide descriptions of classes and methods. A Javadoc comment begins with a slash
followed by two asterisks (/**). A Javadoc comment ends with a single asterisk followed by a slash (*/).
/**
* Describe method here--what it does and who calls it.
* How to Call: provide an example of how to call this method
* @param parameter description (for methods only)
* @return return description (for methods only)
* @see reference to any other methods,
* the convention is
* <class-name>#<method-name>
*/
Block comments that you format using Javadoc conventions allow automated Javadoc generation.
Single-line Comments
Single-line comments provide descriptions of one or more statements within a function or method. A single-line
comment begins with double slashes (//) as the first two characters two non-whitepsace characters on a line.
// Handle the condition
if (condition) {
...
}
If you cannot fit your comment on a single line, use a block comment, instead.
Trailing Comments
Trailing comments provide very brief descriptions about specific lines of code. A trailing comment begins with
double slashes (//) following the code that the comment describes. Separate the double slashes from the code
with at least two spaces.
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 in a block of code, indent them all to a common alignment.
In the preceding example, compilation fails due to an unclosed comment. The following example avoids compi-
lation errors by inserting a space between the slash and the first asterisk.
/*
The dividing line does not start a nested block comment and causes no compiler error.
// **********************************************************************************
*/
Math operators have a natural order of precedence, which controls the order of incremental computations in
compound computations if parentheses are absent. The following sample Gosu code makes explicit the operator
order of precedence in the computation without parentheses in the preceding example.
premium = rate + (limit * 10.5) + (deductible / autoGrade) - 15 // natural order of precedence
• Surround every logical block, even single-statement blocks, with curly braces ({}).
• Put the opening curly braces ({) on the same line that starts the block.
• Put the closing curly brace (}) on the line after the last statement in the block, aligned with the starting
column of the block.
if(premium <= 1000) { // Put opening curly brace on line that starts the block.
print("The premium is " + premium) // Surround even single-line blocks with curly braces.
} // Put closing curly brace on line after last statement.
Also, check variables for null before you call methods on variables:
function addGroup (aUser : User, : aGroupUser : GroupUser) {
if (aUser != null) { // Check for null to avoid a null pointer if you call methods on the variable.
aUser.addToGroup(aGroupUser)
}
}
Consider the following issues If you do not check variables for null:
• Accessing a property on a variable may use null-safe property access, which can cause null pointer exceptions
in later code that handles only non-null values.
• Calling a method on a variable risks a null pointer exception.
The following sample Gosu code uses the explicit null safe operator ?. to check for null to avoid a null pointer
exception while calling a method. If aUser is null, Gosu does not call the method addToGroup, and the entire
expression aUser?.addToGroup(aGroupUser) evaluates to null.
function addGroup (aUser : User, aGroupUser: GroupUser) {
aUser?.addToGroup(aGroupUser) // An explicit null-safe operator returns null if aUser is null.
}
The following sample Gosu code uses the explicit null-safe operator ?[] to check for null to avoid a null pointer
exception while accessing an array. If strings[] is null, the entire expression strings?[index] evaluates to
null. However, the null-safe operator does not avoid out-of-bounds exceptions if strings[] is non-null and the
value of index exceeds the array length.
function getOneString (strings : String[], index : int) : String {
return = strings?[index] // An explicit null-safe operator evaluates to null if an array is null.
}
See also
• For more information about null-safe operators, see “Handling Null Values In Expressions” on page 84 in the
Gosu Reference Guide.
Gosu requires semicolons only if you place multiple statements on a single line. As a best practice, Guidewire
generally recommends against placing multiple statements on a single line. Exceptions include simple statement
lists declared in-line within Gosu blocks.
// Include semicolons with multiple statements on a single line.
var adder = \ x : Number, y : Number -> { print("I added!"); return x + y; }
As a best practice, Guidewire recommends that you rewrite your Gosu code with comparison operators instead of
equals methods to make your code type safe and easier to read.
if (activitySubject == row.Name.text) { // This is expression is null safe and easier to read.
...
}
Gosu implicitly coerces "1" to an integer value of 1, without explicit casting. Implicit coercion is convenient and
powerful, but it can cause unexpected results if used without caution.
Gosu produces compiler warnings for implicit coercions. As a best practice, Guidewire recommends that you
take these warnings seriously. If you want the coercion, explicitly cast the operand on the right by using an
as Type expression. If you do not want the coercion, rewrite your code to avoid the implicit coercion.
For example, the following expression compares a date value to a string representation of a date value.
(dateValue == "2011-11-15")
Because Gosu coerces of the string "2011-11-15" to a date, rewrite the code with an explicit type cast.
(dateValue == "2011-11-15" as DateTime)
The automatic downcasting of typeis expressions is particularly valuable for if statements and similar Gosu
flow of control structures. Within the code block of an if statement, you can omit explicitly casting the object as
its subtype. Gosu confirms that the object is the more specific subtype and considers it be the subtype within the
if code block.
The following sample Gosu code shows a pattern for how to use a typeis expression with an if statement.
var variableName : TypeName // Declare a variable as a high-level type.
The following sample Gosu code follows the pattern and declares a variable as an Object. The if condition
downcasts the variable to its more specific subtype, String.
var x : Object = "nice" // Declare a String variable as type Object.
var strlen = 0
Because Gosu propagates the downcasting from the if condition into the if code block, the expression x.length
is valid. The length property is on String, not Object.
The following sample Gosu code is equivalent to the preceding example, but it redundantly casts the variable as
a String within the if code block.
var x : Object = "nice" // Declare a String variable as type Object.
var strlen = 0
For general information, see “Basic Type Checking” on page 360 in the Gosu Reference Guide.
As a best practice, Guidewire recommends that you verify the conditional operators in your conditional expres-
sions to be certain that you fully satisfy the requirements for your loop control logic. For example, <, >, or =
might need to be <=, >=, or !=.
As a best practice, Guidewire recommends that you interrupt loop execution as early as possible with continue
or break commands.
Notice that the loop stops executing on the fourth iteration, when i equals 4.
Notice that the loop continues through all nine iterations, but it interrupts the fourth iteration, when i equals 4.
for (x in 5) {
if (x == 3) {
threeFound = threeFound + 1 // The loop keeps iterating after third one is found.
}
return threeFound >= 1 // The function returns long after third one is found.
}
The following modified sample code is more efficient. The function returns a result as soon as it detects the affir-
mative condition.
public function foundThree() : boolean {
for (x in 5) {
if (x == 3) {
return true // The function returns as soon as the third one is found.
}
return false
}
See also
• “Query Builder APIs” on page 127 in the Gosu Reference Guide
Concatenation (+) on a variable with a literal Slower var aString : String = "Test"
aString = aString + " Test"
Concatenation (+) on a variable with a variable Slowest var aString : String = "Test"
var anotherString : String = " Test"
aString = aString + anotherString
Whenever you use the and operator, place the condition that is most likely to fail or the least performance inten-
sive earliest in the compound expression. Use the following formula to help you determine which condition to
place first, based on the condition with the lowest value.
(100 - failurePercentage) * (performanceCost)
For example, you have a condition that you expect to fail 99% of the time, with an estimated performance cost of
10,000 per evaluation. You have another condition that you expect to fail only 1% of the time, with an estimated
performance cost of 100 per evaluation. According to the formula, place the second condition earliest because it
has the lowest score.
(100 - 99) * 10,000 = 10,000
(100 - 1) * 100 = 9,999
You rarely have accurate figures for the failure percentages or performance costs of specific condition. Use the
formula to develop an educated guess about which condition to place earliest. In general, give preference to less
performance intensive condition. If the performance costs are roughly equal, give preference to condition with a
higher percentage of likely failures.
Whenever you use the or operator, place the condition that is most likely to succeed earliest in compound expres-
sions.
The following modified sample code improves performance. It calls a performance intensive method once and
saves the value in a local variable. It then uses the variable twice to test which value the method returns.
var expensiveValue = policy.expensiveMethod() // Save the value of an expensive call.
for (x in 5) {
if (x == 3 and period.Active) { // Evaulate a constant expression redunantly within a loop.
print("x == 3 on active period")
}
In the preceding example, Gosu evaluates the expression period.Active at least twice unnecessarily. The
following modified sample code improves performance.
var period : PolicyPeriod
}
}
}
The following sample Gosu code is a better solution. The code is more efficient because it loops through the
array once only. It produces appropriate results because it reports the duplicate value once only.
var array = new int[]{1, 2, 3, 4, 3} // An array with a duplicated value
var hashSet = new java.util.HashSet() // Declare an empty hash set, which prohibits
// duplicate values
computeA()
computeB()
computeC()
}
function computeA() {
var expensiveResult = expensiveCall() // Make the expensive call once.
//do A stuff on expensiveResult
}
function computeB() {
var expensiveResult = expensiveCall() // Make the same expensive call twice.
//do B stuff on expensiveResult
}
function computeC() {
var expensiveResult = expensiveCall() // Make the same expensive call three times.
//do C stuff on expensiveResult
}
The following modified sample code improves performance. It pulls the expensive method call up to the main
routine, which calls it once. Then, it passes the cached result down to the lower-level routines, as a context vari-
able.
function computeSomething() { // Performance improves with an expensive call pulled up.
computeA(expensiveResult)
computeB(expensiveResult)
computeC(expensiveResult)
}
Most likely this was not what the developer intended. Determine the most efficient means of acquiring just the
data that you need. For example, rewrite the preceding example to use a query builder expression that fetches a
more focused set of addresses from the application database.
For more general information, see “Query Builder APIs” on page 127 in the Gosu Reference Guide.
Accessing the entity array does not incidentally query the relational database. The application database caches
them whenever it loads a parent entity from the relational database.
Calling a Finder method does incidentally query the relational database. However, the application database does
not cache finder arrays. Only your code keeps the array in memory.
To avoid repeated, redundant calls that incidentally query the database, Guidewire recommends as a best practice
that you cache the results once in a local array variable. Then, pass the local array variable to lower level routines
to operate on the same results. This design approach is an example of pulling up. For more information, see “Pull
Up Multiple Performance Intensive Method Calls” on page 41.
The following modified sample Gosu code improves performance. It finds only relevant policies to process with
the compare method:
var targetPolicy : Policy
var claimQuery = Query.make(Claim) // Performance improves because the query loads few claims.
for (address in resultIterator) { // Iterate the the qualifying addresses in result object.
print (address.AddressLine1 + ", " + address.City + ", " + address.PostalCode)
The preceding sample code performs efficiently, because the database selects the Chicago addresses. The sample
code also uses the application cache efficiently, because it loads only the Chicago addresses into application
memory.
for (address in resultContainer ) { // Iterate the second container with the qualifying addresses.
print (address.AddressLine1 + ", " + address.City + ", " + address.PostalCode)
Returning all addresses to the application uses the cache inefficiently by loading it with unwanted addresses.
Converting the result to a collection uses the application heap inefficiently by loading the collection with
unwanted addressees. Calling the where method on the collection to select only addresses in Chicago performs
the selection much less efficiently than the database.
IMPORTANT Guidewire recommends the query builder APIs instead of find expressions to fetch
items from the application database whenever possible, especially for new code. For more information,
see “Query Builder APIs” on page 127 in the Gosu Reference Guide.
The following sample Gosu code uses the Count property on a query builder API result object.
uses gw.api.database.Query
The following sample Gosu code uses the Count property on a find expression query object.
var policyPeriodQuery = find(p in PolicyPeriod) // Find all policy periods.
print("Number of policy periods: " + policyPeriodQuery.Count)
Use Empty Properties If You Want to Know whether Anything Was Found
If you want to know only whether a result or query object fetched anything from the application database, use the
Empty property instead of the Count property. The value of the Empty property returns to your Gosu code faster,
because the evaluation stops as soon as it counts at least one fetched item. In contrast, the value of the Count
property returns to your Gosu only after counting all fetched items.
The following sample Gosu code uses the Count property on a query builder API result object.
uses gw.api.database.Query
The following sample Gosu code uses the Count property on a find expression query object.
var policyPeriodQuery = find(p in PolicyPeriod) // Find all policy periods.
The following sample Gosu code improves performance by comparing Activity.Pattern.Code with an activity
pattern code in the conditional expression.
if (Activity.ActivityPattern.Code == "MyActivityPatternCode") { // Comparisons of activity pattern
... // codes generally avoid a
} // database read.
Never localize activity pattern codes. These codes are intended for use in Gosu expressions, not for display in
error messages of the application user interface.
See also
• To learn how to add a column of localized pattern codes to the ActivityPattern entity type, see “Localized
Columns in Entities” on page 63 in the Globalization Guide.
The following modified sample code improves performance. It instantiates the plugin within application scope,
so the plugin must initialize itself only once, regardless of the number of executions of code that call it.
static var XPRPlugin = new com.acme.pc.webservices.plugin.VehiclePlugin() // higher performance
“Use Query Builder APIs instead of Find Expressions in New Code” on page 38
“Use Count Properties on Query Builder Results and Find Queries” on page 44
An upgrade of your PolicyCenter installation comprises automated and manual procedures. The ways in which
your configure your PolicyCenter installation help determine the ease or difficulty of the procedures for future
upgrades.
This topic includes:
• “Upgradability Best Practices” on page 47
• “Upgrade Best Practices Checklist” on page 49
See also
• “Planning Your PolicyCenter Upgrade” on page 11 in the Upgrade Guide
If the file changes in a future release, you will notice that the file was copied. You then can decide whether to
replicate the changes in the new file in your copy of the base version of the file. Especially if the change
enhances the base file or fixes a defect, you may want to apply the same changes to your copy of the file.
To confirm that you changed all existing code to use your copied function, temporarily rename the original func-
tion and then compile your entire project to check for compilation errors. After you remove all calls to the orig-
inal function, consider commenting out the original function to prevent developers in the future from using it
accidentally.
If the function changes in a future release, you will notice that the function was copied. You then can decide
whether to replicate the changes in your copy of the base function. Especially if the change enhances the function
or fixes a defect, you may want to apply the same changes to your copy of the function.
3. Add a comment to the top of the restored base file or function to state that the file or function was copied.
For example:
<!-- This file was copied to SomeBaseScreen_ExtDV.pcf -->
4. Make your additional major changes to the copy of the file or function.
Guidewire Rating Management provides a set of tools to manage and maintain rating in PolicyCenter. Guidewire
recommends a number of best practices for Rating Management.
See also
• “Rating Management Concepts” on page 559 in the Application Guide
• “Configuring Rating Management” on page 583 in the Configuration Guide
Component names are not required to be unique, but the identifying code must be unique. For easy identification,
Guidewire recommends that you use the same value for both component name and code.
Rating Management
component Naming convention Example
Package Name
Follow these conventions for policy line package name:
• Use capital letters, such as CP or PA for Commercial Property or Personal Auto policy lines, respectively.
• If the rating component applies to all lines of business, use ALL.
Descriptive Name
Follow these general naming conventions for DescriptiveName:
• Use mixed case with the first letter of each word capitalized.
• Do not use spaces.
Rate Books
For DescriptiveName:
• If you have multiple rate books per policy line, then add underwriting company, jurisdiction, or offering
codes to differentiate the books.
• It is not necessary to append the words book or rate book.
Rate Routine
Append _rr to easily identify rate routine codes as distinct from rate table codes.
For DescriptiveName:
• For a rate routine that calculates premium for a specific coverage, use the coverage code.
For example, a rate routine that calculates premium for Comprehensive coverage (PAComprehensiveCov is
the code) on a Personal Auto policy can be named: PAComprehensiveCov_rr.
• If a coverage has different rate routines that calculate premium for different types of risks, append the risk
type to the rate routine names. To use fewer characters, you can abbreviate the risk type.
For example, a rate routine that calculates premium for Collision coverage for occasional drivers (abbreviate
to OD) in a Personal Auto policy can be named: PACollisionOD_rr. The default rate routine for Collision cov-
erage can be named: PACollision_rr.
• If a rate routine applies to multiple coverages, then create a descriptive name. The name can be based on the
covered object. Add the word Coverages at the end.
For example, a rate routine that calculates premium for certain coverages with a covered object of
PersonalVehicle can be named: PAPersonalVehicleCoverages_rr.
Rate Table
In DescriptiveName, do not include the word table. When doing a rate table lookup in a rate routine,
PolicyCenter displays table: before the name.
Rate tables do not have a version field. However, you can copy a rate table and create the equivalent of a new
version by including a version number in the name and code.
If you plan on versioning, then use a versioning identifier as a suffix. This can be a version number or additional
information that helps you identify the version, such as _v2 or _ISO2015. You can choose to add a version
number beginning with the second version.