IBM Cúram Social Program Management
Customizing Cúram address format
Jayaram Mani, Senior Software Engineer, IBM Cúram, Platform Group. [email protected] McCormack, Software Tester, IBM Cúram, Platform Group. [email protected] Delahunty, Architect, IBM Cúram, Platform Group. [email protected]
© Copyright International Business Machines Corporation 2015.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
CONTENTS
Table of Contents Contents.....................................................................................................................................3
1 Introduction...............................................................................................................................5
2 Building Cúram with the sample code.....................................................................................6
3 Sample custom address layout................................................................................................8
4 Implementing the custom address.........................................................................................10
4.1 Define the address format and locale mapping..............................................................104.1.1 Define the address format and elements.............................................................104.1.2 Associate the address format with locale.............................................................11
4.2 Define values for the address labels...............................................................................114.3 Add codetable entries for address format type and element types................................12
4.3.1 Add a codetable entry for the address format......................................................124.3.2 Add a codetable entry for each address element................................................12
4.4 Provide the environment variables.................................................................................124.5 Implement the AddressFormat SPI class.......................................................................124.5.1 Abstract methods.........................................................................................................16
getTagArray.................................................................................................................16 getAddressAsList........................................................................................................16 validateAddress...........................................................................................................17 getShortFormat...........................................................................................................17 getLongFormat............................................................................................................17 parseFieldsToData......................................................................................................18 storeElements.............................................................................................................19
4.5.2 Default implemented methods.....................................................................................19 getFirstLine..................................................................................................................19 getSecondLine............................................................................................................20 getCountry...................................................................................................................21 getCity.........................................................................................................................21 getState.......................................................................................................................22
4.6 Implement files for Guice binding...................................................................................224.6.1 Create Module class....................................................................................................224.6.2 Create MODULECLASSNAME.dmx file......................................................................22
5 Searching the custom address..............................................................................................23
5.1 Model facade class to interface with the client page......................................................235.2 Implement the facade class............................................................................................235.3 Implement the participant search key validation class...................................................245.3.1 Abstract class to validate address search key.............................................................245.3.2 Search key validation class for each participant type.................................................245.4 Add a custom error message..........................................................................................245.5 Implement files for Guice binding...................................................................................25
5.6 Implement/override client uim/vim files and properties .......................................25 Appendix.................................................................................................................................27
Sample Code.......................................................................................................................27 A. Updating curam-config.xml sample.................................................................................27
I. Define the address format sample............................................................................27 II. Associate the format with locale sample..................................................................28
B. Define values for the address labels sample..................................................................28 C. Adding codetable entries sample....................................................................................28
I. Add a codetable entry for the address format sample..............................................28 II. Add codetable entries for each address element sample........................................29
D. Provide the environment variables sample.....................................................................31 E. AdressFormat implementation class sample..................................................................32
I. validateAddress sample............................................................................................32 II. getShortFormat sample...........................................................................................33 III. getLongFormat sample...........................................................................................35 IV. parseFieldsToData sample.....................................................................................37 V. storeElements sample.............................................................................................39
F. Implementation of Guice binding sample.........................................................................40 I. Create Module class sample.....................................................................................40 II. Create MODULECLASSNAME.dmx file sample.....................................................40
G. Custom error message sample.......................................................................................40 H. Static block code for search Guice binding sample........................................................41 I. Client UIM/VIM and properties sample.............................................................................42
I. UIM/VIM file interface and field snippet sample........................................................42 II. Properties file snippet sample..................................................................................43
References.............................................................................................................................44
1 Introduction
Cúram Version 6.0.5.8 introduced an API that allows to create custom address formats insidethe Cúram application.
This article documents an example of using the API to implement the Belgium address format.
Details of the address format are in the 3rd section of this article.
The example in this article implements create, edit, validate, and search function on the customaddress.
The ability to customize the address format of Cúram was introduced in version 6.0.5.8. The codesamples were tested on IBM Cúram 6.0.5.8.
2 Building Cúram with the sample code
Sample code can be found as a zip file in the Appendix section of this document. The samplecode is customized to implement the Belgian address format.
Steps to generate the Belgium address format by using sample code:
• Unzip and place the files in their respective custom folders.
• Go to the EJBServer path, run “build.bat server” to generate and build server files.
• Once the server build completes successfully, run “build.bat database” to generate database.
• Go to the webclient path, run “build.bat client” to generate and build client files.
• Launch the Cúram application, navigate to the Register Person page, and register a new person to viewthe new Belgium address format.
Target path for files in the zip.
PATH FILE
\\EJBServer\components\custom\codetable CT_AddressElementType.ctxCT_AddressLayoutType.ctx
\\EJBServer\components\custom\data\initial MODULECLASSNAME.dmx
\\EJBServer\components\custom\message CustomSearch.xmlCustomAddress.xml
\\EJBServer\components\custom\model Custom.emx
\\EJBServer\components\custom\properties Environment.xml
\\EJBServer\components\custom\source\custom\impl CustomAddressModule.javaCustomSearchModule.java
\\EJBServer\components\custom\source\curam\custom\search
CustomSearchKeyValidator.java
\\EJBServer\components\custom\source\curam\custom\search\impl
CustomAllParticipantSearchKeyValidator.javaCustomEduInstSearchKeyValidator.javaCustomEmployerSearchKeyValidator.javaCustomExtPartySearchKeyValidator.javaCustomInfoProSearchKeyValidator.javaCustomPersonSearchKeyValidator.javaCustomProdProSearchKeyValidator.javaCustomServSupSearchKeyValidator.javaCustomUtilitySearchKeyValidator.java
\\EJBServer\components\custom\source\curam\custom\address\impl
AddressFormatBE.java
\\EJBServer\components\custom\source\curam\custom\facade\impl
CustomSearch.java
\\webclient\components\custom CDEJResources.propertiescuram-config.xml
\\webclient\components\custom\customsearch EducationalInstitute_searchCriteriaView.propertiesEducationalInstitute_searchCriteriaView.vimEmployer_searchCriteriaView.properties
Employer_search1.uimExternalParty_searchCriteriaView.propertiesExternalParty_searchCriteriaView.vimInformationProvider_searchCriteriaView.propertiesInformationProvider_searchCriteriaView.vimParticipant_searchCriteriaView.propertiesParticipant_searchCriteriaView.vimPerson_searchCriteriaView.propertiesPerson_search1.uimProductProvider_searchCriteriaView.propertiesProductProvider_searchCriteriaView.vimServiceSupplier_searchCriteriaView.propertiesServiceSupplier_searchCriteriaView.vimUtility_searchCriteriaView.propertiesUtility_searchCriteriaView.vim
3 Sample custom address layout
Fields Data type Mandatory Searchable
Street Name Text Y Y
Street Number Text Y Y
Box Number Text N N
Institution Text N N
Building Text N N
City Text Y Y
Post Code Numeric <xxxx> Y N
Country Code Table Y N
Table 1: Belgium address format field, data type
A screen shot of the Belgian address format on the Register Person and Search page.
Illustration 1: Register Person wizard with Belgium address format
Illustration 2: Person Search page with Belgium address format
4 Implementing the custom address
This section describes how the address formats can be customized based on requirements.The mandatory customization points are listed:
• 4.1 - Define the address field and locale mapping.
• 4.2 - Define values for the address labels.
• 4.3 - Add codetable entries for the address format type and element types.
• 4.4 - Provide the environment variables.
• 4.5 - Implement the abstract SPI AddressFormat class.
• 4.6 - Implement files for Guice binding.
4.1 Define the address format and locale mappingFile to create: curam-config.xml
Create curam-config.xml file in /webclient/components/custom folder.
This file defines configuration of the Cúram client pages. Address format name, addresselements, and local mapping to the address format are defined in this file.
The configurations that are defined are used to render the address field in participant create,address evidence edit and search pages.
Address configuration is defined in the <ADDRESS_CONFIG> element.
4.1.1 Define the address format and elements
The address format defines the address elements, identifies the mandatory address elementsand codetable entries for address elements.
The address format is defined in the <ADDRESS_FORMAT> element. It must contain themandatory attributes NAME and COUNTRY_CODE. <ADDRESS_FORMAT> is defined as achild of <ADDRESS_CONFIG>.
Attribute Name Required Default Description
NAME Yes Name that is used to refer the address format.
COUNTRY_CODE Yes Country code of the address format, which must have value from the code table COUNTRY. Example: Belgium country code is BE.
Table 2: Attributes of the ADDRESS_FORMAT
Address elements are defined in the <ADDRESS_ELEMENT> tag. It must contain themandatory attributes LABEL and NAME and can contain the optional attributesMANDATORY and CODETABLE. <ADDRESS_ELEMENT> is defined as child of<ADDRESS_FORMAT>
Attribute Name Required Default Description
LABEL Yes Used by the UI, rendered to display theLabel of the address element.
NAME Yes Name of the address element that is used to create the name and value pair.
MANDATORY No Must be set with TRUE if the address element is mandatory, UI renders this address element with *, and validation is applied to check whether value is entered for the address element.
CODETABLE No Must be set to the code table name, UIrenders the value list for this element from the code table.
Table 3: Attributes of the ADDRESS_ELEMENT
For sample code, see Appendix A.I
4.1.2 Associate the address format with locale
Map the address format to the locales deployed, by using the <LOCALE_MAPPING> tag.The tag must contain the mandatory attributes ADDRESS_FORMAT_NAME and LOCALE.
Attribute Name Required Default Description
ADDRESS_FORMAT_NAME Yes Name of the address format to map to locale.
LOCALE Yes Locale code to map.
Table 4: Attributes of the LOCALE_MAPPING
For sample code, see Appendix A.II
4.2 Define values for the address labelsFile to create: CDEJResources.properties
Create CDEJResources.properties in /webclient/components/custom folder.
This property file is used to set the labels for the configuration that is defined in curam-config.xml.
Define the address label values in this file. The properties are used to render the labels for theaddress field in participant create, address evidence edit and search page.
For sample code, see Appendix B
4.3 Add codetable entries for address format type and element types
4.3.1 Add a codetable entry for the address format
File to create: CT_AddressLayoustType.ctx
Create CT_AddressLayoutType.ctx in /EJBServer/components/custom/codetable folder.
This codetable contains the address layout types. Provide the value, set as default, anddescription for the new address format.
For sample code, see Appendix C.I
4.3.2 Add a codetable entry for each address element
File to create: CT_AddressElementType.ctx
Create CT_AddressElementType.ctx in /EJBServer/components/custom/codetable folder.
This codetable contains the address element types. Define the codetable entries for each address element that is used in the new address format.
For Belgium address format, address elements are STREET, NUMBER, POBOX, INSTITUTION, BUILDING, CITY, COUNTRY, POSTCODE.
For sample code, see Appendix C.II
4.4 Provide the environment variablesFile to be updated: Environment.xml
Update Environment.xml in /EJBServer/components/custom/properties folder.
Environment.xml contains application properties and default values for the Cúram application.
Set the default address format environment variable ENV_ADDRESS_LAYOUT with thenew address format name.
Set the short format address environment variable ENV_ADDRESSSTRINGFORMAT with elements from the new address format.
Example "STREET, NUMBER, POBOX, INSTITUTION, BUILDING, CITY, COUNTRY, POSTCODE"
For sample code, see Appendix D
4.5 Implement the AddressFormat SPI classFile to create: AddressFormatBE.java
Create AddressFormatBE.java, sub class of the AddressFormat class in/EJBServer/components/custom/source folder.
Implement the methods of AddressFormat class in AddressFormatBE class based on the newaddress requirement. Two tables provide list of abstract methods and list of methods that havedefault implementations. Default implementations may be overridden to meet specific addressrequirements.
Further explanation and sample code for each methods are provided after the table.
List of abstract methods that require implementation.
Method Description
String[] getTagArray() Return address tags as array of strings
AddressLineList getAddressAsList(final OtherAddressData otherAddressData)
Must implement to return address value of each addressline as list. Address passed as a string inotherAddressData argument, list is created from the stringaddress data and returned to the called method.
void validateAddress(final ValidateAddressResult validateAddressResult, final OtherAddressData otherAddressData)
Requires implementation to validate the content of thereceived address. The address is passed as an unparsedstring in the OtherAddressData argument. Validationfailures should be thrown as AppException.
OtherAddressData getShortFormat(final OtherAddressData addressDataString)
Must implement to return short format of the address.Short format of the address is used, for example, inparticipant search result, in participant context panels andon the participant evidence page.
OtherAddressData getLongFormat(final OtherAddressData addressDataString)
Must implement to return long format of the address.Long format of the address is used, for example, invalidations and by the financial component for contactdetails.
OtherAddressData parseFieldsToData(AddressFieldDetails addressFieldDetails)
Must implement to parse address fields to address datastring. AddressFieldDetails parameter holds the value foreach line of the address, this method returns addressstring with new line delimited from theAddressFieldDetails.
void storeElements(final AddressDtls details)
Must implement to store address elements for addresssearch. Each line of the address is stored inAddressElement table, which is used in participant searchbased on address.
Table 5: Abstract methods in AddressFormat class that need implementation
List of methods that has default implementation.
Note: Override these methods if require specific implementation based on new address format.
Method Description
AddressElementStruct getFirstLine(final OtherAddressData addressDataString)
Default implementation returns the value ofADDRESSELEMENTTYPE.LINE1 from the new linedelimited OtherAddressData string. If the new addressformat has different address element as first line, then thismethod should be overridden to get the first line.
AddressElementStruct getSecondLine(final OtherAddressData addressDataString
Default implementation returns the value ofADDRESSELEMENTTYPE.LINE2 from the new linedelimited OtherAddressData string. If the new addressformat has different address element as second line, thenthis method should be overridden to get the second line.
AddressElementStruct getCountry(final OtherAddressData addressDataString)
Default implementation returns the value ofADDRESSELEMENTTYPE.COUNTRY from the new linedelimited OtherAddressData string. If no country in thenew address format, this method will return empty string,no need to override this method. If the new addressformat has different address element as country, then thismethod should be overridden to get the country value.
AddressElementStruct getCity(final OtherAddressData addressDataString)
Default implementation returns the value ofADDRESSELEMENTTYPE.CITY from the new linedelimited OtherAddressData string. If no city in the newaddress format, this method will return empty string, noneed to override this method. If the new address formathas different address element as city, then this methodshould be overridden to get the city value.
AddressElementStruct getState(final OtherAddressData addressDataString)
Default implementation returns the value ofADDRESSELEMENTTYPE.STATE from the new linedelimited OtherAddressData string. If no state in the newaddress format, this method will return empty string, noneed to override this method. If the new address formathas different address element as state, then this methodshould be overridden to get the state value.
Table 6: Methods in AddressFormat class already implemented
OtherAddressData
Through out this guide and the sample code you will see references to the OtherAddressData object. The Address infrastructure relies heavily on this object. In most cases the address widget constructs and passes this object to the address infrastructure and it does not need to be considered. However, some per-existing features such as registration pages and create pages, that include address fields, need to construct the object to replicate the job of the address widget. The format of the object is a little strange at first look but worth understanding before starting to work with Addresses. Below the OtherAddressData object is deconstructed.
The OtherAddressData object stores the Address information in a single field 'addressData'.
The 'addressData' field is a string.
The value of the addressData string must adhere to a schema which is explained below.
The value includes address header information, stored in the first 6 lines.
The value includes address details stored in lines 7 onwards.
The format of the string is 'newline delimited'. Each line is explained below.
The table uses an example address 'west street, 12, 145, , kings court, test city, BE, 12345'.
Line No. Field Value Description
1 WidgetVersion 1 This field is unused and can be default to 1.
2 AddressID 0 AddressID from Address table, 0 unless modifyingan existing address.
3 AddressLayoutType BE Corresponds to the value of the 'name' attribute ofthe configured address (See section 4.1.1)
4 CountryCode BE Corresponds to the value of the 'country' attributeof the configured address (See section 4.1.1)
5 ModifiableInd 1 0 or 1 (true/false). Used by the address widget todetermine if address can be modified.
6 VersionNo 0 Default to 0. Used for optimistic locking duringaddress updates.
7 Address Element STREET=west street The first line corresponds to the 'STREET' elementdescribed in the address config (See section 4.1.1)
8 Address Element NUMBER=12 The second line corresponds to the 'NUMBER'element described in the address config (Seesection 4.1.1)
9 Address Element POBOX=145 Etc... the order of address elements is notimportant, as long as the correct value maps to theelement name.
10 Address Element INSTITUT=
11 Address Element BUILDING=kings court
12 Address Element POSTCODE=12345
13 Address Element CITY=test city
14 Address Element COUNTRY=BE
Example Belgium address format stored in the DB, this address data is used to explain theimplementation and sample code.
1
-1963569437525139456
BE
BE
1
1
STREET=west street
NUMBER=12
POBOX=145
INSTITUT=
BUILDING=kings court
POSTCODE=12345
CITY=test city
COUNTRY=BE
4.5.1 Abstract methods
• getTagArray
Argument : no arguments
Return : String
Return address tags as array of strings, address tags are defined in Cúram as codetableADDRESSELEMENTTYPE.
Example, Belgium address format address tags
return new String[]{
ADDRESSELEMENTTYPE.STREET, ADDRESSELEMENTTYPE.NUMBER,
ADDRESSELEMENTTYPE.POBOX, ADDRESSELEMENTTYPE.INSTITUTION,
ADDRESSELEMENTTYPE.BUILDING, ADDRESSELEMENTTYPE.POSTCODE,
ADDRESSELEMENTTYPE.CITY, ADDRESSELEMENTTYPE.COUNTRY };
• getAddressAsList
Argument : OtherAddressData
Return : AddressLineList
Provide implementation to return value of each address line in a list format.
Given an address in OtherAddressData format and a map with address element to codetable,this method returns the address as a list.
When converting OtherAddressData to address list, elementToCodeTableMap is used to lookup the address element that has codetable reference. Value from the codetable added to theaddress list.
If no codetable reference for the address then pass an empty elementToCodeTableMap to themethod.
Example, Belgium address format Country field has codetable reference
private final Map<String, String> elementToCodeTableMap = new HashMap<String, String>() {
{
put(ADDRESSELEMENTTYPE.COUNTRY, ADDRESSCOUNTRY.TABLENAME);
}
};getAddressAsList method implementation, call getAddressAsList super class method passing OtherAddressData and elementToCodeTableMap
public AddressLineList getAddressAsList(OtherAddressData otherAddressData)throws AppException, InformationalException {
return getAddressAsList(otherAddressData, elementToCodeTableMap);
}
• validateAddress
Argument : ValidateAddressResult, OtherAddressData
Return : void
Provide implementation to validate the address.
Given an address in OtherAddressData format, validate the address lines based on theaddress format requirement.
Any validation failure must be thrown as AppException with appropriate validation errormessage.
Once the validation is successful assign the address data to ValidateAddressResult.
For sample code, see Appendix E.I
• getShortFormat
Argument : OtherAddressData
Return : OtherAddressData
Provide implementation to return a short format of address.
This method uses environment variable "ENV_ADDRESSSTRINGFORMAT" to frame shortformat of the address. The Short format of the address is used, for example, in participantsearch result, in participant context panels and on the participant evidence page.
Given an address in OtherAddressData format and environment variable“ENV_ADDRESSSTRINGFORMAT”. Replace the address element in the environment variablewith respective value.
Example, Belgium address format environment variable "ENV_ADDRESSSTRINGFORMAT"assigned with "STREET, NUMBER, POBOX, INSTITUT, BUILDING, CITY, POSTCODE"
Short format address based on the Belgium address is "west street, 12, 145, kings court, testcity, 12345", here INSTITUT value is empty so the tag is removed and COUNTRY tag is notincluded in the environment variable so that is not added to the result short format string.
For sample code, see Appendix E.II
• getLongFormat
Argument : OtherAddressData
Return : OtherAddressData
Provide implementation to return long format of the address.
The long format of the address is used, for example, in validations and by the financialcomponent for contact details.
Given an address in OtherAddressData format, get address data as list by calling methodgetAddressAsList. Return address list from getAddressAsList is iterated to create the requiredlong format.
Example, Belgium address long format
west street, 12
145, kings court
test city, Belgium, 12345
For sample code, see Appendix E.III
• parseFieldsToData
Argument : AddressFieldDetails
Return : OtherAddressData
Provide implementation to parse address fields into an OtherAddressData object.
This method is a convenience for converting the struct curam.core.struct.AddressFieldDetailsto an OtherAddressData object. The AddressFieldDetails object is used in a number oflocations in the OOTB code including a number of registration wizards. The usages depend onthe AddressFormat.parseDataToField method to translate AddressFieldDetails into anOtherAddressData object for further processing. Importantly though, the AddressFieldDetailsstruct is a legacy construct tied to the UK and US address formats, and is embedded in someareas of the application. It is not redefined by your address customization, it has a predefinedset of fields that may not match the address elements you have defined in your customaddress. In order for the OOTB code to continue to work, without significant customization ofscreens and facade classes you will need to work with the existing AddressFieldDetails structto marshal the AddressFieldDetails into the correct OtherAddressData format. Please follow theBelgium address example in Appendix to see how this can be achieved.
Format for OtherAddressData
WidgetVersion
AddressID
AddressLayoutType
CountryCode
ModifiableInd
VersionNo
AddressLines
Example, Belgium address format AddressFieldDetails
AddressFieldDetails.addressLine1="west street"
AddressFieldDetails.addressLine2="12"
AddressFieldDetails.addressLine3="145"
AddressFieldDetails.addressLine4=""
AddressFieldDetails.addressLine5="kings court"
AddressFieldDetails.city="test city"
AddressFieldDetails.countryCode="BE"
AddressFieldDetails.postalCode="12345"
Formatted OtherAddressData
1
0 (AddressId assigned with zero in the initial stage)
BE
BE
1
0 (VersionNo assigned with zero in the initial stage)
STREET=west street
NUMBER=12
POBOX=145
INSTITUT=
BUILDING=kings court
POSTCODE=12345
CITY=test city
COUNTRY=BE
For sample code, see Appendix E.IV
• storeElements
Argument : AddressDtls
Return : void
Provide implementation that will store address lines for searching.
Each line of the address is stored as a row in the AddressElement table. The stored addresswill be used in participant searches that are based on address.
Use the storeElement function to store each address element required for searching.
For sample code, see Appendix E.V
4.5.2 Default implemented methods
• getFirstLine
Argument : OtherAddressData
Return : AddressElementStruct
Default implementation returns the value of ADDRESSELEMENTTYPE.LINE1 fromOtherAddressData.
If the new address format has different address element as first line, then this method shouldbe overridden to get the first line.
Example, Belgium address format, say STREET, NUMBER as first line
final StringBuffer elementString = new StringBuffer();
// parse the OtherAddressData to addressMapList <tag><value> pair
final AddressMapList addressMapList = addressDataObj.parseDataToMap(otherAddressData);
final AddressMap addressMap = new AddressMap();
// Assign address element to find
addressMap.name = ADDRESSELEMENTTYPE.STREET;
ElementDetails elementDetails;
// Find the address element
elementDetails = addressDataObj.findElement(addressMapList, addressMap);
// If element found append to string buffer.
if(elementDetails.elementFound && !elementDetails.elementValue.isEmpty()) {
elementString.append(elementDetails.elementValue);
elementString.append(CuramConst.gkComma);
elementString.append(CuramConst.gkSpace);
}
// Assign address element to find
addressMap.name = ADDRESSELEMENTTYPE.NUMBER;
// Find the address element
elementDetails = addressDataObj.findElement(addressMapList, addressMap);
// If element found append to string buffer.
if(elementDetails.elementFound && !elementDetails.elementValue.isEmpty()) {
elementString.append(elementDetails.elementValue);
}
// Assign and return the final address string
addressElementStruct.addressElementString = elementString.toString();
• getSecondLine
Argument : OtherAddressData
Return : AddressElementStruct
Default implementation returns the value of ADDRESSELEMENTTYPE.LINE2 fromOtherAddressData.
If the new address format has different address element as second line, then this methodshould be overridden to get the second line.
Example, Belgium address format, say POBOX, INSTITUTION, BUILDING as second line
final StringBuffer elementString = new StringBuffer();
// parse the OtherAddressData to addressMapList <tag><value> pair
final AddressMapList addressMapList = addressDataObj.parseDataToMap(otherAddressData);
final AddressMap addressMap = new AddressMap();
// Assign address element to find
addressMap.name = ADDRESSELEMENTTYPE.POBOX;
ElementDetails elementDetails;
// Find the address element
elementDetails = addressDataObj.findElement(addressMapList, addressMap);
// If element found append to string buffer.
if(elementDetails.elementFound && !elementDetails.elementValue.isEmpty()) {
elementString.append(elementDetails.elementValue);
elementString.append(CuramConst.gkComma);
elementString.append(CuramConst.gkSpace);
}
// Assign address element to find
addressMap.name = ADDRESSELEMENTTYPE.INSTITUTION;
// Find the address element
elementDetails = addressDataObj.findElement(addressMapList, addressMap);
// If element found append to string buffer.
if(elementDetails.elementFound && !elementDetails.elementValue.isEmpty()) {
elementString.append(elementDetails.elementValue);
elementString.append(CuramConst.gkComma);
elementString.append(CuramConst.gkSpace);
}
// Assign address element to find
addressMap.name = ADDRESSELEMENTTYPE.BUILDING;
// Find the address element
elementDetails = addressDataObj.findElement(addressMapList, addressMap);
// If element found append to string buffer.
if(elementDetails.elementFound && !elementDetails.elementValue.isEmpty()) {
elementString.append(elementDetails.elementValue);
} addressElementStruct.addressElementString = elementString.toString();
• getCountry
Argument : OtherAddressData
Return : AddressElementStruct
Default implementation returns the value of ADDRESSELEMENTTYPE.COUNTRY fromOtherAddressData.
If no COUNTRY address element in the new address format, this method will return emptystring, no need to override this method.
If the new address format has different address element as country, then this method should beoverridden to get the country value.
• getCity
Argument : OtherAddressData
Return : AddressElementStruct
Default implementation returns the value of ADDRESSELEMENTTYPE.CITY fromOtherAddressData.
If no CITY address element in the new address format, this method will return empty string, noneed to override this method.
If the new address format has different address element as city, then this method should beoverridden to get the city value.
• getState
Argument : OtherAddressData
Return : AddressElementStruct
Default implementation returns the value of ADDRESSELEMENTTYPE.STATE from the newline delimited OtherAddressData string.
If no STATE address element in the new address format, this method will return empty string,no need to override this method.
If the new address format has different address element as state, then this method should beoverridden to get the state value.
4.6 Implement files for Guice binding
4.6.1 Create Module classFile to create: CustomAddressModule.java
Create CustomAddressModule.java class in /EJBServer/components/custom/source folder.
This module class is used to bind the address layout name to the AddressFormat classimplemented in the section 4.5.
For sample code, see Appendix F.I
4.6.2 Create MODULECLASSNAME.dmx fileFile to create: MODULECLASSNAME.dmx
Create MODULECLASSNAME.dmx file in /EJBServer/components/custom/data/initial folder.
In Cúram Guice module classes are initialized when the Cúram application starts. Initialization is done by updating the reference of the Guice module class in the table “ModuleClassName”. When the Cúram application starts, the class name from the table is used to initialize the Guice binding.
Add the CustomAddressModule class name in the dmx file.
For sample code, see Appendix F.II
5 Searching the custom address
Participant search involves address fields to narrow down the participant search result. Thereare two places in Cúram where participants are searched based on address. One in the participantregister wizard and another in participant search page.
Participant register wizard contains two pages, search page fields to search participant alreadyregistered, register page to enter new participant details to register the participant. Customizing this forthe custom address format can be done is two ways.
First approach to make use of out of the box search fields on the participant wizard. OOTBaddress search has 3 fields AddressLine1, AddressLine2 and City. Map the address fields to therespective elements of the custom address format in the facade class (CustomSearch.java). Whenmoving from search page to the register page on the wizard, address data from the search page arecarried to the registered page using “parseFieldsToData” method.
Second approach create custom UIM/VIM for the wizard page with required address fields.Create facade class to handle the wizard actions. Map the address fields to the respective elements ofthe custom address format in the facade class. When moving from search page to the register pageon the wizard, address data from the search page are carried to the registered page using“parseFieldsToData” method.
In the below sample implementation first approach is used. Search Belgium address formatwith 3 address fields AddressLine1, AddressLine2, and City mapped to Street, Number and City.
Section describes how the participant search based on the new address format can becustomized. The mandatory customization points are listed:
• 5.1 - Model facade class to interface with the client page.
• 5.2 - Implement the facade class.
• 5.3 - Implement the participant search key validation class.
• 5.4 - Add a custom error message.
• 5.5 - Implement files for Guice binding.
• 5.6 - Implement/override client uim/vim files and properties.
5.1 Model facade class to interface with the client pageFile to be updated: Custom.emx
Create necessary struct and facade model in the Custom model package.
For, the Belgium format “CustomSearch” facade model is created.
Once the struct and facade interface are created in the model, generate the class files fromthe model. The struct and facade is the interaction point for the client pages and server-sidecode.
Note: For information on how to model with RSA a link to the Cúram knowledge center isprovided in the reference section.
5.2 Implement the facade classFile to create: CustomSearch.java
Create CustomSearch.java class in /EJBServer/components/custom/source/facade/implfolder.
Implement the CustomSearch class for the facade interface model. This class must implementall the methods that are defined in the interface that is generated from the model.
5.3 Implement the participant search key validation class
5.3.1 Abstract class to validate address search keyFile to create: CustomSearchKeyValidator.java
Create CustomSearchKeyValidator class in /EJBServer/components/custom/source folder.
Abstract CustomSearchKeyValidator class extends the SearchKeyValidator class and must override the method “validateAddressSearchKey”.
This method is used by all the participant search key validator to validate the address search field.
5.3.2 Search key validation class for each participant typeFiles to be created:
CustomAllParticipantSearchKeyValidator.java
CustomEduInstSearchKeyValidator.java
CustomEmployerSearchKeyValidator.java
CustomExtPartySearchKeyValidator.java
CustomInfoProSearchKeyValidator.java
CustomPersonSearchKeyValidator.java
CustomProdProSearchKeyValidator.java
CustomServSupSearchKeyValidator.java
CustomUtilitySearchKeyValidator.java
Create these classes in /EJBServer/components/custom/source folder.
All these classes extend the CustomSearchKeyValidator class and implements theirrespective interface. All the class files have to implement the method “validateSearchKey”.
These classes are used to validate the search key for the respective participant types.These classes are mapped to the participant type by Guice binding, further discussed inthe Guice binding section.
5.4 Add a custom error messageFile to create: CustomSearch.xml
Create CustomSearch.xml file in /EJBServer/components/custom/message folder.
Add an error message for the address format validation. When the validation fails thesemessages are wrapped along with exception. On the client side, these messages areunwrapped and displayed on the client page to provide meaningful information to the user.
For sample code, see Appendix G
5.5 Implement files for Guice binding File to create: CustomSearchModule.java
Create CustomSearchModule class in /EJBServer/components/custom/source folder.
This module class binds the participant types to the custom search key validation implementation class, as implemented in the section 5.3.2.
CustomSearchModule class must extend curam.core.impl.Module class and override themethod “bindSearchKeyValidator”.
A static block of code is used to initialize the Guice biding. Static code has to be included inthe server initializing class, if any, or else can be included in the CustomSearch class that isimplemented in the section 5.2.
For sample code, see Appendix H
5.6 Implement/override client uim/vim files and properties Files to be created:
EducationalInstitute_searchCriteriaView.properties
EducationalInstitute_searchCriteriaView.vim
Employer_search1.uim
Employer_searchCriteriaView.properties
ExternalParty_searchCriteriaView.properties
ExternalParty_searchCriteriaView.vim
InformationProvider_searchCriteriaView.properties
InformationProvider_searchCriteriaView.vim
Participant_searchCriteriaView.properties
Participant_searchCriteriaView.vim
Person_search1.uim
Person_searchCriteriaView.properties
ProductProvider_searchCriteriaView.properties
ProductProvider_searchCriteriaView.vim
ServiceSupplier_searchCriteriaView.properties
ServiceSupplier_searchCriteriaView.vim
Utility_searchCriteriaView.properties
Utility_searchCriteriaView.vim
Create these files in /webclient/components/custom folder.
These files are used to create client pages. Create UIM and VIM page based on the required fields and interface with the struct and facade classes that are implemented in the previous section. Properties files hold the value for the label from UIM and VIM files.
For sample code, see Appendix I.I (UIM/VIM file snippet)
For sample code, see Appendix I.II (Properties file)
APPENDIX
Sample Code
A. Updating curam-config.xml sample
I. Define the address format sample
<ADDRESS_FORMAT
COUNTRY_CODE="BE"
NAME="BE"
>
<ADDRESS_ELEMENT
LABEL="Address.Label.Street"
MANDATORY="TRUE"
NAME="STREET"
/>
<ADDRESS_ELEMENT
LABEL="Address.Label.Number"
MANDATORY="TRUE"
NAME="NUMBER"
/>
<ADDRESS_ELEMENT
LABEL="Address.Label.Box"
NAME="POBOX"
/>
<ADDRESS_ELEMENT
LABEL="Address.Label.Institution"
NAME="INSTITUTION"
/>
<ADDRESS_ELEMENT
LABEL="Address.Label.Building"
NAME="BUILDING"
/>
<ADDRESS_ELEMENT
CODETABLE="Postcode"
LABEL="Address.Label.Postcode"
MANDATORY="TRUE"
NAME="POSTCODE"
/>
<ADDRESS_ELEMENT
LABEL="Address.Label.City"
MANDATORY="TRUE"
NAME="CITY"
/>
<ADDRESS_ELEMENT
CODETABLE="Country"
LABEL="Address.Label.Country"
MANDATORY="TRUE"
NAME="COUNTRY"
/>
</ADDRESS_FORMAT>
II. Associate the format with locale sample
<LOCALE_MAPPING
ADDRESS_FORMAT_NAME="BE"
LOCALE="nl_BE"
/>
<LOCALE_MAPPING
ADDRESS_FORMAT_NAME="BE"
LOCALE="en_US"
/>
<LOCALE_MAPPING
ADDRESS_FORMAT_NAME="BE"
LOCALE="fr"
/>
B. Define values for the address labels sample
Address.Label.Street=Street
Address.Label.Number=Number
Address.Label.Box=Box
Address.Label.Institution=Institution
Address.Label.Building=Building
Address.Label.Postcode=Postcode
Address.Label.City=City
Address.Label.Country=Country
C. Adding codetable entries sample
I. Add a codetable entry for the address format sample
<code
default="false"
java_identifier="BE"
status="ENABLED"
value="BE"
>
<locale
language="en"
sort_order="0"
>
<description>Belgium</description>
<annotation/>
</locale>
</code>
II. Add codetable entries for each address element sample
<code
default="false"
java_identifier="STREET"
status="ENABLED"
value="STREET"
>
<locale
language="en"
sort_order="0"
>
<description>Street</description>
<annotation/>
</locale>
</code>
<code
default="false"
java_identifier="NUMBER"
status="ENABLED"
value="NUMBER"
>
<locale
language="en"
sort_order="0"
>
<description>Number</description>
<annotation/>
</locale>
</code>
<code
default="false"
java_identifier="POBOX"
status="ENABLED"
value="POBOX"
>
<locale
language="en"
sort_order="0"
>
<description>Post Box</description>
<annotation/>
</locale>
</code>
<code
default="false"
java_identifier="INSTITUTION"
status="ENABLED"
value="INSTITUTION"
>
<locale
language="en"
sort_order="0"
>
<description>Institution</description>
<annotation/>
</locale>
</code>
<code
default="false"
java_identifier="BUILDING"
status="ENABLED"
value="BUILDING"
>
<locale
language="en"
sort_order="0"
>
<description>Building</description>
<annotation/>
</locale>
</code>
<code
default="false"
java_identifier="POSTCODE"
status="ENABLED"
value="POSTCODE"
>
<locale
language="en"
sort_order="0"
>
<description>Postcode</description>
<annotation/>
</locale>
</code>
<code
default="false"
java_identifier="CITY"
status="ENABLED"
value="CITY"
>
<locale
language="en"
sort_order="0"
>
<description>City</description>
<annotation/>
</locale>
</code>
<code
default="false"
java_identifier="COUNTRY"
status="ENABLED"
value="COUNTRY"
>
<locale
language="en"
sort_order="0"
>
<description>Country</description>
<annotation/>
</locale>
</code>
D. Provide the environment variables sample
<environment>
<type name="dynamic_properties">
<section
code="ADDRESS"
name="Application - Address settings"
>
<variable
constant="ENV_ADDRESSSTRINGFORMAT"
default="STREET, NUMBER, POBOX, INSTITUT, BUILDING, CITY, COUNTRY,POSTCODE"
displayname="Address String Format"
name="curam.address.addressStringFormat"
onlyin="all"
type="STRING"
>
<comment>The format of the address displayed as a single line of text. The following values can be entered to display
the different parts of the address. ADD1, ADD2, ADD3, ADD4, ADD5, ADI, UNITNO, STRNUMBER, STRNOSFX, STRNAME, STRTYPE, STRDIR, CITY, DISTRICT, PROV, POSTCODE, COUNTRY, STATE, USCOUNTY AND ZIP</comment>
<doccomment>The format of the address displayed as a single line of text.</doccomment>
</variable>
<variable
constant="ENV_ADDRESS_LAYOUT"
default="BE"
displayname="Address Layout"
name="curam.address.addressLayout"
onlyin="all"
type="STRING"
>
<comment>The address layout</comment>
<doccomment>The address layout</doccomment>
</variable>
</section>
</type>
</environment>
E. AdressFormat implementation class sample
I. validateAddress sample
@Override
protected void validateAddress(ValidateAddressResult validateAddressResult, OtherAddressData otherAddressData)
throws AppException, InformationalException {
// AddressData object
final curam.core.intf.AddressData addressDataObj = curam.core.fact.AddressDataFactory.newInstance();
// Parse address data to Map <tag>,<value> pair
final AddressMapList addressMapList = addressDataObj.parseDataToMap(otherAddressData);
// get address tag details
final AddressTagDetails addressTagDetails = getAddressTagsForLayout();
if (addressTagDetails.addressTags.length() > 0) {
// validate the address tags
addressDataObj.validateTags(addressMapList, addressTagDetails);
}
final AddressMap addressMap = new AddressMap();
addressMap.name = ADDRESSELEMENTTYPE.NUMBER;
// find value to the address element
ElementDetails elementDetails =
addressDataObj.findElement(addressMapList, addressMap);
if(elementDetails.elementFound && elementDetails.elementValue.length() > 0) {
try {
Integer number = Integer.parseInt(elementDetails.elementValue);
} catch (NumberFormatException e) {
// throw AppException with validation error message when validation fails
curam.core.sl.infrastructure.impl.ValidationManagerFactory.getManager().throwWithLookup(new AppException(CUSTOMADDRESS.ERR_ADDRESS_XFV_NUMBER), curam.core.sl.infrastructure.impl.ValidationManagerConst.kSetOne, 0);
}
}
validateAddressResult.addressMapList.assign(addressMapList);
}
II. getShortFormat sample
@Override
public OtherAddressData getShortFormat(OtherAddressData addressDataString)
throws AppException, InformationalException {
// AddresData object
final curam.core.intf.AddressData addressDataObj = AddressDataFactory.newInstance();
final AddressString addressString = new AddressString();
// Get ENV_ADDRESSSTRINGFORMAT property value
addressString.addressString = (Configuration.getProperty(
EnvVars.ENV_ADDRESSSTRINGFORMAT));
if (addressString.addressString == null) {
addressString.addressString = (Configuration.getProperty(
EnvVars.ENV_ADDRESSSTRINGFORMAT_DEFAULT));
}
// Replace comma with pipe character
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(
addressString.addressString.replace(CuramConst.gkComma,
CuramConst.gkPipeComma));
stringBuilder.append(CuramConst.gkPipeDelimiter);
addressString.addressString = stringBuilder.toString();
// Convert address data string into <name><value> pairs vector.
final AddressMapList addressMapList = addressDataObj.parseDataToMapWithDelimiter(
addressDataString);
// Iterate through the addressMap vector replace the address element
// with the value if value is not empty or remove the address element
// if value is empty in addressString
for (int i = 0; i < addressMapList.dtls.size(); i++) {
if (addressMapList.dtls.item(i).value.isEmpty()) {
// Remove address element tag for empty address value
int intTagPosStart = addressString.addressString.indexOf(
addressMapList.dtls.item(i).name);
if (intTagPosStart >= CuramConst.gkZero) {
int intTagPosEnd = intTagPosStart;
addressString.addressString = addressString.addressString.replace(
addressMapList.dtls.item(i).name, CuramConst.gkEmpty);
if (intTagPosEnd < addressString.addressString.length()) {
while (!Character.isLetterOrDigit(
addressString.addressString.charAt(intTagPosEnd))) {
intTagPosEnd++;
}
} else {
while ((intTagPosStart > 0)
&& (CuramConst.gkPipeDelimiterChar
== addressString.addressString.charAt(
intTagPosStart - CuramConst.gkOne)
|| CuramConst.gkCommaDelimiterChar
== addressString.addressString.charAt(
intTagPosStart - CuramConst.gkOne)
|| CuramConst.gkSpaceChar
== addressString.addressString.charAt(
intTagPosStart - CuramConst.gkOne))) {
intTagPosStart--;
}
}
addressString.addressString = addressString.addressString.substring(
CuramConst.gkZero, intTagPosStart)
+ addressString.addressString.substring(intTagPosEnd);
}
} else {
// Replace the address element with value
addressString.addressString = addressString.addressString.replace(
addressMapList.dtls.item(i).name, addressMapList.dtls.item(i).value);
}
}
III.getLongFormat sample
@Override
public OtherAddressData getLongFormat(OtherAddressData addressDataString)
throws AppException, InformationalException {
// buffer for string concatenation
final StringBuffer formatBuffer = new StringBuffer();
if (addressDataString.addressData.length() > 0) {
// get address lines depending on
// particular layout address
final AddressLineList addressLineList = getAddressAsList(addressDataString);
// Frame address as
// STREET NUMBER
// POBOX INSTITUTION BUILDING
// CITY COUNTRY POSTCODE
int i = 0;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length()
+ CuramConst.gkSpace.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
formatBuffer.append(CuramConst.gkSpace);
}
i = 1;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length()
+ CuramConst.gkNewLine.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
formatBuffer.append(CuramConst.gkNewLine);
}
i = 2;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length()
+ CuramConst.gkSpace.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
formatBuffer.append(CuramConst.gkSpace);
}
i = 3;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length()
+ CuramConst.gkSpace.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
formatBuffer.append(CuramConst.gkSpace);
}
i = 4;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length()
+ CuramConst.gkNewLine.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
formatBuffer.append(CuramConst.gkNewLine);
}
i = 5;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length()
+ CuramConst.gkSpace.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
formatBuffer.append(CuramConst.gkSpace);
}
i = 6;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length()
+ CuramConst.gkSpace.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
formatBuffer.append(CuramConst.gkSpace);
}
i = 7;
if (addressLineList.dtls.item(i).addressString.length() > 0) {
formatBuffer.ensureCapacity(
addressLineList.dtls.item(i).addressString.length());
formatBuffer.append(addressLineList.dtls.item(i).addressString);
}
addressDataString.addressData = formatBuffer.toString();
}
return addressDataString;
}
IV.parseFieldsToData sample
@Override
public OtherAddressData parseFieldsToData(
AddressFieldDetails addressFieldDetails) throws AppException,
InformationalException {
OtherAddressData addressData = new OtherAddressData();
String sModifiableInd = CuramConst.gkEmpty;
String sPostCode;
String sCountry;
StringBuffer formatBuffer = new StringBuffer();
// get Postal code
if (addressFieldDetails.postalCode.length() > 0) {
sPostCode = addressFieldDetails.postalCode;
} else {
sPostCode = CuramConst.gkEmpty;
}
// get Country
if (addressFieldDetails.countryCode.length() > 0) {
sCountry = addressFieldDetails.countryCode;
} else {
sCountry = CuramConst.gkEmpty;
}
if (addressFieldDetails.modifiableInd) {
sModifiableInd = CuramConst.gkModifiableIndex;
} else {
sModifiableInd = CuramConst.gkStringZero;
}
formatBuffer.ensureCapacity(
CuramConst.gkNewLine.length() * 11 + CuramConst.gkStringZero.length() * 2
+ kEqualsLen * 6 + AddressUtil.kWidgetVersion.length()
+ curam.codetable.ADDRESSLAYOUTTYPE.BE.length()
+ addressFieldDetails.countryCode.length() + sModifiableInd.length()
+ curam.codetable.ADDRESSELEMENTTYPE.STREET.length()
+ addressFieldDetails.addressLine1.length()
+ curam.codetable.ADDRESSELEMENTTYPE.NUMBER.length()
+ addressFieldDetails.addressLine2.length()
+ curam.codetable.ADDRESSELEMENTTYPE.POBOX.length()
+ addressFieldDetails.addressLine3.length()
+ curam.codetable.ADDRESSELEMENTTYPE.INSTITUTION.length()
+ addressFieldDetails.addressLine4.length()
+ curam.codetable.ADDRESSELEMENTTYPE.BUILDING.length()
+ addressFieldDetails.addressLine5.length()
+ curam.codetable.ADDRESSELEMENTTYPE.POSTCODE.length()
+ sPostCode.length() + curam.codetable.ADDRESSELEMENTTYPE.CITY.length()
+ addressFieldDetails.city.length()
+ curam.codetable.ADDRESSELEMENTTYPE.COUNTRY.length()
+ addressFieldDetails.countryCode.length());
formatBuffer.append(AddressUtil.kWidgetVersion);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(CuramConst.gkStringZero);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSLAYOUTTYPE.BE);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(addressFieldDetails.countryCode);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(sModifiableInd);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(CuramConst.gkStringZero);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.STREET);
formatBuffer.append(kEquals);
formatBuffer.append(addressFieldDetails.addressLine1);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.NUMBER);
formatBuffer.append(kEquals);
formatBuffer.append(addressFieldDetails.addressLine2);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.POBOX);
formatBuffer.append(kEquals);
formatBuffer.append(addressFieldDetails.addressLine3);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.INSTITUTION);
formatBuffer.append(kEquals);
formatBuffer.append(addressFieldDetails.addressLine4);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.BUILDING);
formatBuffer.append(kEquals);
formatBuffer.append(addressFieldDetails.addressLine5);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.POSTCODE);
formatBuffer.append(kEquals);
formatBuffer.append(sPostCode);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.CITY);
formatBuffer.append(kEquals);
formatBuffer.append(addressFieldDetails.city);
formatBuffer.append(CuramConst.gkNewLine);
formatBuffer.append(curam.codetable.ADDRESSELEMENTTYPE.COUNTRY);
formatBuffer.append(kEquals);
formatBuffer.append(sCountry);
addressData.addressData = formatBuffer.toString();
return addressData;
}
V. storeElements sample
@Override
public void storeElements(AddressDtls details) throws AppException,
InformationalException {
// Address data object, map list and other address data structs.
final curam.core.intf.AddressData addressDataObj = curam.core.fact.AddressDataFactory.newInstance();
final OtherAddressData otherAddressData = new OtherAddressData();
otherAddressData.addressData = details.addressData;
// Parse OtherAddressData to addressMapList <tag><value> pair
final AddressMapList addressMapList = addressDataObj.parseDataToMap(otherAddressData);
final AddressElementDtls addressElementDtls = new AddressElementDtls();
// Set the AddressID
addressElementDtls.addressID = details.addressID;
final AddressMap addressMap = new AddressMap();
// Set the address element required to be stored for searching
addressMap.name = ADDRESSELEMENTTYPE.STREET;
// call super class storeElement to store the address value
storeElement(addressMapList, addressElementDtls, addressMap);
addressMap.name = ADDRESSELEMENTTYPE.NUMBER;
storeElement(addressMapList, addressElementDtls, addressMap);
addressMap.name = ADDRESSELEMENTTYPE.CITY;
storeElement(addressMapList, addressElementDtls, addressMap);
addressMap.name = ADDRESSELEMENTTYPE.INSTITUTION;
storeElement(addressMapList, addressElementDtls, addressMap);
addressMap.name = ADDRESSELEMENTTYPE.BUILDING;
storeElement(addressMapList, addressElementDtls, addressMap);
addressMap.name = ADDRESSELEMENTTYPE.POSTCODE;
storeElement(addressMapList, addressElementDtls, addressMap);
}
F. Implementation of Guice binding sample
I. Create Module class sample
@Override
public void configure() {
bindAddressFormat();
}
protected void bindAddressFormat() {
final MapBinder<String, AddressFormat> addressFormatBinder = MapBinder.newMapBinder(binder(),
String.class, AddressFormat.class);
addressFormatBinder.addBinding(ADDRESSLAYOUTTYPE.BE).
toInstance(new AddressFormatBE());
}
II. Create MODULECLASSNAME.dmx file sample
<table name="ModuleClassName">
<column
name="moduleClassName"
type="text"
/>
<row>
<attribute name="moduleClassName">
<value>curam.custom.impl.CustomAddressModule</value>
</attribute>
</row>
</table>
G. Custom error message sample
<messages package="curam.message">
<message name="ERR_SEARCH_FV_ADDRESS_STREET_SHORT">
<locale language="en">Street field must contain at least %1n alphanumeric characters.</locale>
</message>
<message name="ERR_SEARCH_FV_ADDRESS_NUMBER_SHORT">
<locale language="en">Number field must contain at least %1n alphanumeric characters.</locale>
</message>
<message name="ERR_SEARCH_FV_CITY_SHORT">
<locale language="en">City field must contain at least %1n alphanumeric characters.</locale>
</message>
</messages>
H. Static block code for search Guice binding sample
static class GuiceTransaction
implements BizTransaction
{
public String getName()
{
return "Transaction for boot-strapping Guice modules";
}
public boolean transactional()
{
return true;
}
}
static {
TransactionInfo localTransaction = null;
if (!Configuration.runningInAppServer())
{
TransactionInfo.backUpTransactionInfo();
localTransaction = TransactionInfo.setTransactionInfo(TransactionInfo.TransactionType.kOnline, new GuiceTransaction(), null, null);
}
try
{
if (localTransaction != null) {
localTransaction.begin();
}
if (TransactionInfo.getInformationalManager() == null) {
TransactionInfo.setInformationalManager();
}
final Map<Class<? extends Module>, Module> overrides = new HashMap<Class<? extends Module>, Module>();
overrides.put(curam.core.impl.Module.class,
new curam.custom.impl.CustomSearchModule());
GuiceWrapper.setUpInjector(overrides);
if (localTransaction != null)
{
localTransaction.commit();
localTransaction.closeConnection();
}
TransactionInfo.restoreTransactionInfo();
} catch (Exception e)
{
if (localTransaction != null)
{
localTransaction.rollback();
localTransaction.closeConnection();
}
TransactionInfo.restoreTransactionInfo();
throw new RuntimeException(e);
}
}
I. Client UIM/VIM and properties sample
I. UIM/VIM file interface and field snippet sample
<SERVER_INTERFACE
CLASS="CustomSearch"
NAME="ACTION"
OPERATION="searchPerson"
PHASE="ACTION"
/>
<FIELD LABEL="Field.Label.AddressLineOne">
<CONNECT>
<TARGET
NAME="ACTION"
PROPERTY="key$addressDtls$addressLine1"
/>
</CONNECT>
</FIELD>
<FIELD LABEL="Field.Label.AddressLineTwo">
<CONNECT>
<TARGET
NAME="ACTION"
PROPERTY="key$addressDtls$addressLine2"
/>
</CONNECT>
</FIELD>
<FIELD LABEL="Field.Label.City">
<CONNECT>
<TARGET
NAME="ACTION"
PROPERTY="key$addressDtls$city"
/>
</CONNECT>
</FIELD>
II. Properties file snippet sample
Field.Label.AddressLineOne=Street
Field.Label.AddressLineOne.Help=Street of the educational institution's address.
Field.Label.AddressLineTwo=Number
Field.Label.AddressLineTwo.Help=Street number of the person's address.
REFERENCES
Further information about IBM Cúram Social Program Management is available in IBM Knowledge Centre.
®
© Copyright IBM Corporation 2011IBM United States of AmericaProduced in the United States of America US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product,program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of this document does not grant you any license to these patents. You can send license inquiries, in writing, to:
IBM Director of LicensingIBM CorporationNorth Castle DriveArmonk, NY 10504-1785 U.S.A.
The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law:INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PAPER “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimerof express or implied warranties in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes may be made periodically to the information herein; these changes may be incorporated in subsequent versions of the paper. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this paper at any time without notice.
Any references in this document to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk.
IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to:
IBM Director of LicensingIBM Corporation4205 South Miami BoulevardResearch Triangle Park, NC 27709 U.S.A.
All statements regarding IBM's future direction or intent are subject to change or withdrawal without notice, and represent goals and objectives only.
This information is for planning purposes only. The information herein is subject to change before the products described become available.
If you are viewing this information softcopy, the photographs and color illustrations may not appear.
TrademarksIBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business Machines Corporation in the United States, other countries, or both. If these and other IBM trademarked terms are marked on their first occurrence in this information with a trademark symbol (® or ™), these symbols indicate U.S. registered or common law trademarks ownedby IBM at the time this information was published. Such trademarks may also be registered or common law trademarks in other countries. A current list of IBM trademarks is available on the web at "Copyright and trademark information" at http://www.ibm.com/legal/copytrade.shtml.