IBM WebSphere Developer Technical Journal: Accelerated JSF development for XML-based SOA using Rational Application Developer and WebSphere Application Server -- Part 2

Extending and customizing an SDO solution

This is Part 2 in a series that presents a solution that accelerates presentation development of XML-based Service Oriented Architechture (SOA) applications. This solution includes an Eclipse feature that enables the generation of statically typed Service Data Objects (SDO) for an XSD Schema, and provides a runtime framework for using SDOs in the transformation of presentation element data to and from XML data. Part 2 enhances the solution developed in Part 1.

Narinder Makin, Software Architect, IBM Rational SOA tools, IBM

Narinder Makin is a software engineer at IBM Research Triangle Part Lab in Durham, North Carolina. He is a developer of J2EE and SOA/SDO tools for the Rational Application Developer team.



Daimar Hernandez (daimarh@us.ibm.com), Staff Software Engineer, IBM, PVT Team

Daimar Hernandez is a software engineer at IBM Research Triangle Park Lab in Durham, North Carolina. She is a developer in the PVT team for the Rational Application Developer team.



26 January 2005

Also available in Chinese

Introduction

This five-part article series presents a solution that accelerates presentation development of XML-based SOA applications, and includes an Eclipse feature that enables the generation of statically typed service data objects (SDO) for an XSD Schema, and a runtime framework for the transformation of presentation element data to/from XML data using SDOs. In Part 1 of this five-part series, we walked through the development of a simple JavaServer™ Faces (JSF) application using the supplied plug-in set that communicates to a service per the specified XML schema. The application scenario we used makes one service invocation that sends one XML request and receives one XML response, and illustrates the master-detail view of data objects along with pagination and sorting capabilities.

In Part 2, we will enhance the solution developed in Part 1 to include the create, update, and delete functions, and include customizations to the generated SDOs with local variable addition and basic transformations. We will illustrate a scenario of multiple schema models, multiple requests/responses for a single page, and will show the JSF dropdown control binding for XML data.

IBM® Rational® Application Developer V6 and Websphere® Application Server V6 are required to take advantage of this transformation feature. This article also assumes familiarity with Rational Application Developer's JSF page designer.


Installing the XSD SDO Transform feature

To install the XSD SDO Transform feature, follow the steps detailed in Part 1.


Scenario

Our scenario extends the insurance application developed in Part 1 to include create, update, and delete functions, local variable additions, plus basic transformations and dropdown bindings. In this scenario:

  • We assume that XYZ Insurance Comany has many brokers registered to it.
  • Each broker has many clients, and each client has many policies registered with that broker.
  • The insurance company exposes broker services via a standard BrokerService schema (Listing 1), and a valid codes service as a validCodesService schema (Listing 2) to retrieve, for example, valid state codes.
  • Any communication from the broker is an XML request/response that complies to the schema definitions in Listings 1 and 2. (These listings are also available in the xsd_sdo_soa_part2_listings.zip download file.)

Listing 1. BrokerService.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http:///xyz.brokerservice.ecore"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="http:///xyz.brokerservice.ecore">
	<xsd:annotation>
		<xsd:documentation xml:lang="en">
   			Broker Service Schema for xyz.com.
   			Copyright 2004 ibm.com. All rights reserved.
  		</xsd:documentation>
	</xsd:annotation>
	<xsd:element name="brokerService" type="brokerServiceType"/>
	<xsd:complexType name="brokerServiceType">
		<xsd:sequence>
			<xsd:element minOccurs="0" name="broker" type="brokerType"/>
			<xsd:element minOccurs="0" name="error" type="errorType"/>
		</xsd:sequence>
	</xsd:complexType>
	<xsd:complexType name="brokerType">
		<xsd:sequence>
			<xsd:element minOccurs="0" ref="firstName"/>
			<xsd:element minOccurs="0" ref="lastName"/>
			<xsd:element minOccurs="0" name="loginName" type="xsd:string"/>
			<xsd:element minOccurs="0" name="loginPassword" type="xsd:string"/>
			<xsd:element maxOccurs="unbounded" minOccurs="0" name="client" 
				type="clientType"/>
		</xsd:sequence>
		<xsd:attribute name="brokerId" type="xsd:string" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="clientType">
		<xsd:sequence>
			<xsd:element minOccurs="0" ref="firstName"/>
			<xsd:element minOccurs="0" ref="lastName"/>
			<xsd:element minOccurs="0" name="dateOfBirth" type="xsd:date"/>
			<xsd:element minOccurs="0" name="currentAddress" type="addressType"/>
			<xsd:element minOccurs="0" name="permanentAddress" type="addressType"/>
			<xsd:element maxOccurs="unbounded" minOccurs="0" name="policy" 
				type="policyType"/>
		</xsd:sequence>
		<xsd:attribute name="clientId" type="xsd:string" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="addressType">
		<xsd:sequence>
			<xsd:element name="street" type="xsd:string"/>
			<xsd:element name="city" type="xsd:string"/>
			<xsd:element name="state" type="xsd:string"/>
			<xsd:element name="zip" type="xsd:string"/>
			<xsd:element name="country" type="xsd:string"/>
		</xsd:sequence>
	</xsd:complexType>
	<xsd:complexType name="policyType">
		<xsd:sequence>
			<xsd:element name="policyName" type="xsd:string"/>
			<xsd:element name="policyStartDate" type="xsd:date"/>
			<xsd:element name="policyEndDate" type="xsd:date"/>
			<xsd:element name="policyAmount" type="xsd:string"/>
			<xsd:element name="policyDescription" type="xsd:string"/>
		</xsd:sequence>
		<xsd:attribute name="policyId" type="xsd:string" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="errorType">
		<xsd:sequence>
			<xsd:element name="errorCode" type="xsd:string"/>
			<xsd:element name="errorDescription" type="xsd:string"/>
		</xsd:sequence>
	</xsd:complexType>
	<xsd:element name="firstName" type="xsd:string"/>
	<xsd:element name="lastName" type="xsd:string"/>
</xsd:schema>
Figure 1. BrokerService Schema Model
BrokerService Schema Model

Listing 2. ValidCodesService.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http:///xyz.validcodesservice.ecore"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="http:///xyz.validcodesservice.ecore">
	<xsd:annotation>
		<xsd:documentation xml:lang="en">
   			Valid Codes Service Schema for xyz.com.
   			Copyright 2004 ibm.com. All rights reserved.
  		</xsd:documentation>
	</xsd:annotation>
	<xsd:element name="validCodesService" type="validCodesServiceType"/>
	<xsd:complexType name="validCodesServiceType">
		<xsd:sequence>
			<xsd:element minOccurs="0" name="stateList" 
				type="stateListType"/>
			<xsd:element minOccurs="0" name="policyCodeList" 
				type="policyCodeListType"/>
		</xsd:sequence>
	</xsd:complexType>
	
	<xsd:complexType name="stateListType">
		<xsd:sequence>
			<xsd:element maxOccurs="unbounded" minOccurs="0" name="state" 
				type="stateType"/>
		</xsd:sequence>
	</xsd:complexType>
	
		<xsd:complexType name="stateType">
		<xsd:sequence>
			<xsd:element name="shortName" type="xsd:string"/>
			<xsd:element name="fullName" type="xsd:string"/>
		</xsd:sequence>
	</xsd:complexType>
	
		<xsd:complexType name="policyCodeListType">
		<xsd:sequence>
			<xsd:element maxOccurs="unbounded" minOccurs="0" 
				name="policyCode" type="policyCodeType"/>
		</xsd:sequence>
	</xsd:complexType>
			<xsd:complexType name="policyCodeType">
		<xsd:sequence>
			<xsd:element name="shortName" type="xsd:string"/>
			<xsd:element name="fullName" type="xsd:string"/>
		</xsd:sequence>
	</xsd:complexType>
	
</xsd:schema>
Figure 2. ValidCodesService schema model
ValidCodesService schema model

BrokerUpdate Scenario

This scenario enhances an existing brokerupdate.jsp JavaServer Faces JSP page with new functionality. This page already sends the request for broker detail (brokerDetailRequest.xml, in Part 1) and receives a response with all the clients of the broker and their policies (brokerDetailResponse.xml, in Part 1). The page will also now invoke the valid codes service to retrieve the valid code values as an XML response (allValidCodesResponse.xml, Listing 5), as well as enable create, update, and delete operations on policies, illustrating behavior in addition to behavior from the generated SDO for the basic transformations. Changes are sent as brokerUpdateRequest.xml (Listing 3) to the service, and a response for the success or failure is received as brokerUpdateResponse.xml (Listing 4). The brokersummary.jsp page is then displayed after retrieving the updated changes from the service.

Figure 3. BrokerUpdate Request/Response message flow
BrokerUpdate Request/Response message flow

Listing 3. brokerUpdateRequest.xml

<?xml version="1.0" encoding="UTF-8"?>
<brokerService xmlns="http:///xyz.brokerservice.ecore"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<broker brokerId="000-00-9999">
	<firstName>Narinder</firstName>
	<lastName>Makin</lastName>
	<client clientId="001-00-9999">
		<firstName>Dan</firstName>
		<lastName>Moore</lastName>
		<dateOfBirth>1967-08-13</dateOfBirth>
		<currentAddress>
			<street>113 Oak Pine St.</street>
			<city>Santa Clara</city>
			<state>LA</state>
			<zip>91929</zip>
			<country>US</country>
		</currentAddress>
		<permanentAddress>
			<street>123 Demi Lane</street>
			<city>Cary</city>
			<state>NC</state>
			<zip>22999</zip>
			<country>US</country>
		</permanentAddress>
		<policy policyId="L000000000">
			<policyName>Life</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>200000.00</policyAmount>
			<policyDescription>Life Insurance</policyDescription>
		</policy>
		<policy policyId="H000000000">
		<policyName>House</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>20000.00</policyAmount>
			<policyDescription>Home Insurance</policyDescription>
		</policy>
		<policy policyId="C000000001">
		<policyName>Car 1</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>15000.00</policyAmount>
			<policyDescription>Car Insurance - Ferrari 2004 - 
Primary Car </policyDescription>
		</policy>
		<policy policyId="C000000002">
		<policyName>Car 2</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>5000.00</policyAmount>
			<policyDescription>Car Insurance - Lexus 2003 - 
Secondary Car </policyDescription>
		</policy>
		<policy policyId="B000000002">
		<policyName>Restaurant</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>25000.00</policyAmount>
			<policyDescription>Business Insurance - 
Restaurant</policyDescription>
		</policy>
		<policy policyId="B000000003">
		<policyName>Golf Course</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>25000.00</policyAmount>
			<policyDescription>Second Business Insurance - 
Golf Course</policyDescription>
		</policy>
	</client>
	<client clientId="002-00-9999">
		<firstName>Tom</firstName>
		<lastName>Cross</lastName>
		<dateOfBirth>1970-11-11</dateOfBirth>
		<currentAddress>
			<street>113 Duke St.</street>
			<city>Shelton</city>
			<state>CT</state>
			<zip>08989</zip>
			<country>US</country>
		</currentAddress>
		<permanentAddress>
			<street>123 Lex Lane</street>
			<city>Fairfield</city>
			<state>NY</state>
			<zip>09833</zip>
			<country>US</country>
		</permanentAddress>
		<policy policyId="L100000000">
			<policyName>Life</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>100000.00</policyAmount>
			<policyDescription>Life Insurance</policyDescription>
		</policy>
		<policy policyId="H100000000">
			<policyName>House</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>2000.00</policyAmount>
			<policyDescription>Home Insurance</policyDescription>
		</policy>
		<policy policyId="C100000001">
			<policyName>Car 1</policyName>
			<policyStartDate>2004-01-01</policyStartDate>
			<policyEndDate>2005-01-01</policyEndDate>
			<policyAmount>2000.00</policyAmount>
			<policyDescription>Car Insurance - Camry 2004 - 
Primary Car </policyDescription>
		</policy>
	</client>
</broker>
</brokerService>

Listing 4. brokerUpdateResponse.xml

<?xml version="1.0" encoding="UTF-8"?>
<brokerService xmlns="http:///xyz.brokerservice.ecore"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<broker brokerId="099-99-9999"/>
	<error>
		<errorCode>0</errorCode>
		<errorDescription>Success: The changes have been successfully 
			applied to the policy.</errorDescription>
	</error>
</brokerService>

Listing 5. allValidCodesResponse.xml

<?xml version="1.0" encoding="UTF-8"?>
<validCodesService xmlns="http:///xyz.validcodesservice.ecore"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<stateList>
		<state>
			<shortName>CT</shortName>
			<fullName>Connecticut</fullName>
		</state>
		<state>
			<shortName>LA</shortName>
			<fullName>Los Angelas</fullName>
		</state>
		<state>
			<shortName>NC</shortName>
			<fullName>North Carolina</fullName>
		</state>
		<state>
			<shortName>CA</shortName>
			<fullName>California</fullName>
		</state>
		<state>
			<shortName>NH</shortName>
			<fullName>New Hampshire</fullName>
		</state>
		<state>
			<shortName>VA</shortName>
			<fullName>Virginia</fullName>
		</state>
	</stateList>
	<policyCodeList>
		<policyCode>
			<shortName>H</shortName>
			<fullName>House</fullName>
		</policyCode>
		<policyCode>
			<shortName>C</shortName>
			<fullName>Car</fullName>
		</policyCode>
		<policyCode>
			<shortName>B</shortName>
			<fullName>Business</fullName>
		</policyCode>
	</policyCodeList>	
</validCodesService>

Application design flow

Figure 4 depicts the application design flow for this scenario.

Figure 4. Application design flow
Application design flow

Runtime architecture

Upon page request, the following occurs (Figure 5):

  1. The JSF runtime invokes the BrokerUpdateRoot bean.
  2. BrokerUpdateRoot preloads the data by sending brokerDetailRequest.xml to the BrokerService.
  3. BrokerService sends the response as brokerDetailResponse.xml, which is passed to XMLTransformServiceFactory.
  4. The XML is transformed to SDOs wrapped in the BrokerUpdateRoot bean.
  5. The JSF runtime invokes the ValidCodesServiceRoot bean.
  6. ValidCodesServiceRoot Java™ bean preloads the data by invoking the ValidCodesService.
  7. ValidCodesService sends response as allValidCodesResponse.xml, which is passed to XMLTransformServiceFactory.
  8. The XML is transformed to SDOs wrapped in the ValidCodesServiceRoot bean.
  9. JSF runtime renders the controls with data.
  10. XMLTransformServiceFactory is invoked from the bean. The SDO instance is passed to the XMLTransformServiceFactory, converting it to brokerUpdateRequest.xml, which is sent to the BrokerService.
  11. The brokerUpdateResponse.xml received as a response, and processed into the SDOs wrapped in the BrokerUpdateRoot bean.
Figure 5. Runtime architecture
Runtime architecture

Implementing the solution

The steps to implement the solution are described in detail in the next sections:

  1. Import project interchange
  2. Create SDO package from XSD schema
  3. Add additional attributes and behavior to the generated SDOs
  4. Add a new root bean wrapper
  5. Update existing root bean wrapper
  6. Add command method to page code
  7. Bean additions to the page data
  8. Update control bindings on the page to the SDO types in the page data
  9. Run brokerdetail.jsp.
  1. Import project interchange

    Import the project interchange xsd_sdo_soa_xml_tutorial.zip download file into the Application Developer workspace. As a result, the following projects will be imported (Figure 6):

    • XYZInsuranceEAR: The enterprise application project that contains all the other projects as modules or utilities.
    • XYZInsuranceWeb: The dynamic Web project for the application where all the JSF JSP pages will be created. The WebContent folder of this project contains the BrokerService.xsd schema and sample data files in a Schema folder. For the sake of simplicity, in this example the schema and the SDO packages are part of the WebProject. If sharing the same SDOs across multiple Web projects is desired, you can create a separate Java project for the SDO packages. The SDO packages are constructed in the same project where the XML Schema resides. The brokerupdate.jsp, brokersummary.jsp, BrokerUpdateRoot.java and BrokerSummaryRoot.java components are already created for this exercise.
    • XYZInsuranceService: Contains the Java class implementation for the broker service and the valid codes service. The service loads and sends the appropriate XML response based on the service method request. This basic implementation is provided to simulate the service behavior; its implementation is beyond the scope of this article.
    • XYZInsuranceServiceProxy: Contains a basic implementation of ServiceProxy for invoking the broker service.
    Figure 6. Imported tutorial project interchange
    Imported tutorial project interchange
  2. Create SDO package from XSD schema

    In Application Developer, right-click on ValidCodesService.xsd, then select Create SDO Package (Figure 7).

    Figure 7. Create SDO Package
    Create SDO Package

    As a result, the artifacts shown in Figure 8 will be generated.

    Figure 8. Generated SDO Packages
    Generated SDO Packages

    The name of the package is derived from the targetNamespace defined in the schema declaration in the XSD (Figure 9).

    Figure 9. TargetNamespace declaration
    TargetNamespace declaration
  3. Add additional attributes and behavior to the generated SDOs

    You can modify the generated SDOs to include specialized variables or behavior. Any added methods or variables that are not annotated with @generated tags will not be replaced when the SDOs are regenerated for the same schema namespace. You can also mark such files as non-derived so that project "clean" does delete these files.

    1. Add the get/set methods to the policy SDO interface, xyz.brokerservice.PolicyType:

      /**
       * Get the value for selected
       */
      boolean getSelected();
      /**
       * Set the value for selected
       */
      void setSelected(boolean selected);
    2. Add the following attribute and methods to the policy SDO implementation class, xyz.brokerservice.impl.PolicyTypeImpl:

      /**
       * add selected attribute as local variable.
       */
      protected boolean selected = false;
      /**
       * Get the value for selected
       */
      public boolean getSelected(){
      	return selected;
        }
      /**
       * Set the value for selected
       */
      public void setSelected(boolean selected){
      	this.selected = selected;
        }
    3. Add the get method to the client SDO interface, xyz.brokerservice.ClientType:

      /**
       * TotalPolicyAmount is computed by summation of the client's Policy Amounts
       */
        double getTotalPolicyAmount();
    4. Add the following method to the client SDO implementation class, xyz.brokerservice.impl.ClientTypeImpl; the following method demonstrates the basic transformation capabilities:

      /**
       * totalPolicyAmount is computed by summation of the client's Policy Amounts
       */
      public double getTotalPolicyAmount(){
      	double totalPolicyAmount = 0.00;
      	for(int index=0; index < getPolicy().size(); ++index){
      		PolicyType policyType = (PolicyType)getPolicy().get(index);
      		if(policyType.getPolicyAmount() != null){
      		   double temp = 0.00;
      		   try{
      		      temp = Double.parseDouble(policyType.getPolicyAmount());
      		   }catch(NumberFormatException ex){
      
      		   }
      			totalPolicyAmount += temp;
      		}
      	}
      	return totalPolicyAmount;
      }
    5. Mark the changed files as non-derived to preserve the changes during project "clean" (Figure 10).
    Figure 10. Change derive property
    Change derive property
  4. Add a new root bean wrapper

    The ValidCodesServiceRoot.java file contains registration of the schema namespace URI, a property for the valid codes service and its get/set methods. All the valid codes are loaded lazily by invoking the valid codes service. Add the ValidCodesServiceRoot.java Java class in the brokerservice.root package:

    package brokerservice.root;
    import org.eclipse.emf.ecore.EPackage;
    import proxy.ValidCodesServiceProxy;
    import xyz.validcodesservice.DocumentRoot;
    import xyz.validcodesservice.ValidCodesServiceType;
    import xyz.validcodesservice.ValidcodesservicePackage;
    import dw.ibm.etools.xsd.sdo.xmltransformservice.XMLTransformServiceFactory;
    
    public class ValidCodesServiceRoot extends BaseRoot{
    	protected ValidCodesServiceType validCodesServiceRoot;
    	static{
    		EPackage.Registry.INSTANCE.put(
    				ValidcodesservicePackage.eINSTANCE.getNsURI()
    				, ValidcodesservicePackage.eINSTANCE);
    	}
    	protected void loadValidCodesResponse(String response){
    
    		DocumentRoot docRoot=
    		 (DocumentRoot) XMLTransformServiceFactory.INSTANCE.load(response);
    		validCodesServiceRoot =  docRoot.getValidCodesService();
    	}
    	public ValidCodesServiceType getValidCodesServiceRoot() {
    		if(validCodesServiceRoot == null){
    			preLoadValidCodes();
    		}
    		return validCodesServiceRoot;
    	}
    	public void setValidCodesServiceRoot(
    			ValidCodesServiceType validCodesServicetRoot) {
    		this.validCodesServiceRoot = validCodesServicetRoot;
    	}
    	protected void preLoadValidCodes(){
    	    String response = ValidCodesServiceProxy.invoke(
    	    			ValidCodesServiceProxy.ALL_REQUEST);
    	    loadValidCodesResponse(response);
    	}
    }
  5. Update existing root bean wrapper

    Update the existing BrokerUpdateRoot.java Java class in the brokerservice.root package with the corresponding download file provided, or update the file with following additions:

    1. The following method sends the updates to the service to update the broker information, using a framework API to convert the data object to an XML string. The second argument of the convert API ensures that all the empty attributes are not part of the serialized XML. You can use the other implementation of the convert API, if such element declarations are accepted by the receiving side's XML processor.

      public void applyPolicyChanges(){
      		//unset all the features that are empty
      	    String xmlData = XMLTransformServiceFactory.INSTANCE.convert
      			((DataObject)brokerServiceRoot, true);
      	    String response =
      	    	BrokerServiceProxy.invoke(xmlData,
      	    			BrokerServiceProxy.BROKERUPDATE_REQUEST);
      	    loadBrokerDetailUpdateResponse(response);
      	}
    2. The response returned from the service invocation is loaded using the load API call. Any elements that were not part of the schema when the SDO packages were created will be recorded by the load call. When this data object is serialized to XML using the convert API, these elements are written back.

      protected void loadBrokerDetailUpdateResponse(String response){
      		DocumentRoot docRoot=
      		  (DocumentRoot) XMLTransformServiceFactory.INSTANCE.load(response);
      		BrokerServiceType brokerdetailUpdateRespRoot =  
      		  docRoot.getBrokerService();
      		//set the error type
      		brokerServiceRoot.setError(brokerdetailUpdateRespRoot.getError());
      	}
    3. This method adds a new policy to the client's existing policy list. The createPolicy method in the ClientType creates a new PolicyType object and adds to the existing Policy list.

      public void addNewPolicy(ClientType clientType){
      		clientType.createPolicy();
      	}
    4. This method deletes the selected policies from client's existing policy list.

      public void deleteSelectedPolicy(ClientType clientType){
                      for(int index=clientType.getPolicy().size()-1; index >= 0; --index){
                              PolicyType policyType = ((PolicyType)clientType.getPolicy().
      					get(index));
                              if(policyType.getSelected()){
                                      clientType.getPolicy().remove(policyType);
                              }
                      }
              }
  6. Add command method to page code

    Edit the Brokerupdate.java page code file for brokerupdate.jsp and add the following methods to be used as the command actions. (The control data accessors used in the methods are defined in next step.)

    1. This action invokes the addNewPolicy method on the BrokerUpdateRoot.class to add a new policy row to the existing policy list. The current row of the Client is retrieved using the rowData for the Client datatable.

      public String doAddNewPolicyAction(){
      	this.getVarBrokerUpdateRootBean().addNewPolicy
      		((ClientType)getTable1().getRowData());
      	//returning empty string re-displays the page with same data binding
      	return "";
      }
    2. This action invokes the deleteSelectedPolicy method on the BrokerUpdateRoot.class to delete the selected policies from the existing policy list.

      public String doDeleteSelectedPolicyAction(){
      		this.getVarBrokerUpdateRootBean().deleteSelectedPolicy
      			((ClientType)getTable1().getRowData());
      		return "";
      	}
    3. This action reflects the Java bean with any data changes, provided for illustration purposes only. In an actual application, you would either include some processing here, or not require this method at all.

      public String doUpdatePolicyAction(){
      		return "";
      	}
    4. This action invokes the applyPolicyChanges method on the BrokerUpdateRoot.class to send the updated data to the service. The varBrokerUpdateRootBean, a session scope JSF managed bean from the session, is removed from the session, such that the bean is repopulated from new data on the next invocation.

      public String doApplyPolicyChangesAction(){
      		this.getVarBrokerUpdateRootBean().applyPolicyChanges();
      		this.sessionScope.remove("varBrokerUpdateRootBean");
      		//a navigation rule is defined for this return
      		return "applyChanges";
      	}
  7. Bean additions to the page data
    1. Configure the varBrokerUpdateRootBean in the page data to be a JSF managed bean, and set the scope as session (Figure 11). This will cache the bean instance for the lifetime of the user session. Any create, update, or delete operation of policy is thus maintained in the session unless they are applied by the Apply Changes action.
      Figure 11. Configure Java Bean in Page Data
      Configure Java Bean in Page Data
    2. Add the varValidCodesRootBean in the page data to be a JSF managed bean and set the scope as application. This will cache the bean instance for the lifetime of application instance.
      Figure 12. Configure Java Bean in Page Data
      Configure Java Bean in Page Data
  8. Update control bindings on the page to the SDO types in the page data
    1. Select the Policy data table and add a new column in its properties (Figure 13). Rename the column as "Delete" and move it to be the first in the list.
      Figure 13. Column Addition
      Column Addition
    2. Drag a checkbox from the control palette and add it to the new table column (Figure 14).
      Figure 14. Checkbox Addition
      Checkbox Addition
    3. Drag the "selected" attribute from the policy SDO defined in the page data view and drop it on the checkbox in the Policy data table (Figure 15).
      Figure 15. Checkbox binding
      Checkbox binding
    4. Add a command button to the policy data table and change the label of the button to "Add New Policy" (Figure 16). Enable the showing of the footer area for the policy data table so that you can place the command button.
      Figure 16. Command button addition
      Command button addition
    5. Bind this command button to doAddNewPolicyAction (Figure 17). If the "action" property is not being displayed, show all the properties for the data table.
      Figure 17. Bind command to action
      Bind command to action
    6. Add a command button to the policy data table, change the label of the button to "Delete Selected Policy" (Figure 18), and bind this button to the doDeleteSelectedPolicyAction (Figure 19).
      Figure 18. Command button addition
      Command button addition
      Figure 19. Bind command to action
      Bind command to action
    7. Add a command button to the policy data table, change the label of the button to "Update Policy" (Figure 20), and bind this button to the doUpdatePolicyAction (Figure 21).
      Figure 20. Command button addition
      Command button addition
      Figure 21. Bind command to action
      Bind command to action
    8. Add a command button to the client data table, change the label of the button to "Apply Changes" (Figure 22), then bind this button to the doApplyPolicyChangesAction (Figure 23). (Enable the showing of the footer area of the table to place the command button.)
      Figure 22. Command button addition
      Command button addition
      Figure 23. Bind command to action
      Bind command to action
    9. Add a rule to go to the brokersummary.jsp that reflects the policy changes (Figure 24).
      Figure 24 Add outcome rule
      Add outcome rule
    10. Add a new "TotalPolicyAmount" column to the client data table, before "policy". Drag a JSF outputtext control and drop in the new column (Figure 25).
      Figure 25 Column Addition
      Column Addition
    11. Drag the totalPolicyAmount from the varBrokerServiceRootBean page data (Figure 26) and drop on to the outputtext control (Figure 27).
      Figure 26. Page Data
      Page Data
      Figure 27. Control Binding
      Control Binding
    12. Add a new "State" column to the client data table, before policy. Drag a JSF dropdown control and drop in the new column (Figure 28).
      Figure 28. Dropdown Addition
      Dropdown Addition
    13. Drag fullName from the varValidCodesRootBean in the page data (Figure 29) and drop it onto the dropdown control (Figure 30).
      Figure 29. Page Data
      Page Data
      Figure 30. Dropdown binding
      Dropdown binding
  9. Run the brokerupdate.jsp
    1. In Application Developer, right-click on brokerupdate.jsp and select Run On Server. (If you are not prompted to start the server, start the server and then add the XYZInsuranceEAR project to the server before running the page.)
    2. The URL for the page in the test container is (or will be similar to): http://localhost:9080/XYZInsuranceWeb/faces/brokerupdate.jsp.
      Figure 31. brokerupdate.jsp
      brokerupdate.jsp
    3. Use the buttons on the page to execute different actions (Figure 32).
      Figure 32. brokerupdate.jsp
      brokerupdate.jsp

Conclusion

In Part 2 of this article series, we described an accelerated JSF development solution for a XML-based SOA application. The solution provided an Eclipse feature and framework utilities for use at design time to transform the XML Schema to a Java package containing static service data objects, and, at run time, to transform XML instance documents to and from these SDOs. SDOs wrapped as JavaBeans were used with JavaServer Faces for presentation development. This article also provided the general steps for extending the basic scenario of an insurance application with create, update, and delete functions, local variable additions, basic transformations, and dropdown bindings. These enhancements resulted in a scenario of multiple schema models and multiple requests and responses for a single page.

Also upcoming in this series:

  • Part 3 will describe the advanced techniques for manipulating the generated SDOs and customizing the XML-SDO transformer. It also provides utilities for the aggregate methods (sum, mean, average, and so on) that operate generically on the SDO objects and collections.
  • Part 4 will focus on portlet development for the XML-based SOA that uses the XSDO SDO transform feature, addressing JSR 168 portlet creation, parameter passing across portlets, and setting the target portlet view dynamically on a portlet action in any other portlet.
  • Part 5 will discuss localizing JSF and portlet applications for the XML-based SOA that uses the XSDO SDO transform feature, and will address the localizing static and dynamic content that is displayed based on the preferred locale.

Downloads

DescriptionNameSize
Download file 1xsd_sdo_soa_xml_sample.zip  ( HTTP | FTP )766 KB
Download file 2xsd_sdo_soa_xml_tutorial.zip  ( HTTP | FTP )738 KB
Download file 3xsdsdotransform-feature.zip  ( HTTP | FTP )50 KB
Download file 4XYZInsuranceEAR.zip  ( HTTP | FTP )764 KB
Download file 5xsd_sdo_soa_part1_listings.zip  ( HTTP | FTP )8 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=33367
ArticleTitle=IBM WebSphere Developer Technical Journal: Accelerated JSF development for XML-based SOA using Rational Application Developer and WebSphere Application Server -- Part 2
publish-date=01262005