Part 4 of this five-part article series continues the presentation of a solution that accelerates presentation development of XML based Service-Oriented Architechture (SOA) applications. In this series:
- Part 1 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.
- Part 2 enhanced the solution from Part 1 to include create, update, and delete functions, plus customizations to the generated Serviec Data Objects (SDO) with local variable addition and basic transformations.
- Part 3 highlighted different techniques that are commonly used for manipulating SDO instances when building an XML-based SOA application.
- In Part 4, we will focus on portlet development for the XML-based SOA application, using the sample insurance application scenario referenced throughout this series.
Portlets provide a powerful means of managed and configurable content delivery. They can be developed as reusable, encapsulated presentation components that can be customized based on end user requirements. An application service provider can deliver these reusable assets to their customers, who can then customize, personalize, and configure these assets according to their own requirements in a managed server environment. To provide these configurable assets, the server component needs to be loosely coupled to the content of these portlets.
The same architecture presented in the first three parts of the series fits seamlessly into portlet presenatation development and demonstrates that the architecture can be scaled to numerous types of presentation delivery mechanisms. This article will address the configuration and architectural issues involved when marrying SDO usage with portlets.
This article is not intended to teach portlet development, which can be addressed using the product documentation or other onlines sources provided in the Resources section. Rather, this article primarily addresses the issues related to portlet development using SDOs for an XML-based SOA. It also outlines the basics of creating a portlet, and how to share artifacts, portlet project types, portlet states, and data between portlets, which are some of the fundamental requirements when building the portlets driven by SDOs.
To follow this article, you will need IBM Rational Application Developer V6 (hereafter referred to as Application Developer) and IBM WebSphere Portal, Version 5.1or later. This article also assumes familiarity with Rational Application Developer's JavaServer Faces (JSF) page designer.
Installing the XSD SDO Transform feature
To install the XSD SDO Transform feature, follow the steps detailed in Part 1.
XSD SDO Transform feature contents
The XSD SDO Transform feature contains artifacts for generating the SDO package from an XSD schema, and framework components to transform an SDO package instance to/from an XML instance document:
- Create SDO Package action
This action on the XSD resources generates the SDO package from an XSD schema (Figure 1).
Figure 1. Create SDO Package

- XMLTransformServiceFactory.java
This class provides the APIs to transform an SDO package instance to/from XML instance document.
The scenario we will use in this article uses the insurance application developed in Part 1 and Part 2. In this scenario:
- We assume that XYZ Insurance Company 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, Figure 2), and a valid codes service as validCodesService schema (Listing 2, Figure 3), which retrieves the valid values.
- Any communication from the broker is an XML request/response that complies to the schema definitions.
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:element minOccurs="0" name="ssn"/> </xsd:sequence> <xsd:attribute name="clientId" type="xsd:string" use="required"/> <xsd:attribute name="securityToken" type="xsd:string" use="optional"/> </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 2. 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 3. ValidCodes Service Schema Model
As mentioned earlier, portlet presentation is much more sophisticated than a pure JSF Web application. Let's analyze the solution supplied with this article, which has some pre-built portlets with content that is loosely coupled with the back end services. The solution supplied is a project interchange file that contains the portlets (which will be described later). We will import the project interchange that contains the supplied portlets and address these key issues involved in the development of the solution:
- Solution contents
- Portlet creation
- Portlet view creation
- Navigation links
- Portlet state
- Pagination
- Dropdown binding
- Passing data within portlet views
- Sharing data across portlets
- Intercepting a portlet action
- Run the XYZInsurance portlet project.
Import the project interchange xsd_sdo_soa_xml_sample.zip download file into the Application Developer workspace. As a result, the following included projects will be imported (Figure 4):
- XYZInsuranceEAR: The enterprise application project that contains all the other projects as modules or utilities.
- XYZInsurancePortlet: The JSR 168 portlet project with all the portlets and JSF JSPs present. The WebContent folder of this project contains the BrokerService.xsd and ValidCodesService.xsd schemas, and sample data files in a Schema folder. For the sake of simplicity, in this example the SDO packages are already created and are part of the portal project.
- 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 4. Imported tutorial project interchange
In the required libraries of the imported project interchange, emf.jar is added along with the xsdsdotransform.jar. This provides the required level of Eclipse Modeling Framework (EMF) and Service Data Object (EMF-SDO) runtime libraries (Figure 5). The version of these runtimes that this article requires for XML-SDO transformation plug-in are not packaged with WebSphere Portal V5.0.2.x or V5.1. At a minimum, Version 2.1 of the EMF-SDO runtime is required for the XSD SDO transform feature. You will need to add the supported JARs manually to the projects that target these versions of WebSphere Portal. You can get the required JARs listed below either by downloading them from the Eclipse Modeling Framework Web site, or use the emf.jar file from the Websphere Application Server V6.0 runtime folder:
- commonj.sdo.jar
- common.resources.jar
- common.jar
- xsd.resources.jar
- xsd.jar
- ecore.jar
- ecore.change.jar
- ecore.xmi.jar
Figure 5. EMF-SDO runtime addition
The imported Web project XYZInsurancePortlet is a Portlet JSR 168 project. When creating a portlet application, a choice needs to be made on the type of portlet project. Application Developer supports creating portlet projects for:
- the IBM portlet API as "Portlet Project"
- the JSR 168 portlet API as "Portlet Project (JSR 168)".
Portlets that conform to the JSR 168 specification can be deployed to any JSR 168-compliant portal and provides portability to the portlet application instead of locking it into WebSphere Application Server. Cross-platform requirements may be a key factor for choosing an application service provider to deploy the same application to multiple clients.
Application Developer supports Faces portlet development based on the JSR 168 specification. Snippets are supported for common tasks, like encoding namespaces, changing window modes, line mimimize and maximize, and so on. However, click-to-action cooperative behavior and portlet messaging are not supported in JSR 168 Faces portlets.
For new portlets, consider using JSR 168 portlet projects when supported features for this project type are sufficient for the portlet's needs, or when the portlet is expected to be published as a Web Service for Remote Portlets (WSRP) service. Some JSR 168 portlet API custom tags (for example, <namespace> and <actionURL>) cannot be used within the <view> tag of a Faces portlet JSP file in JSR 168 projects. (Refer to Application Developer help when creating these projects and to learn about differences between these project types.)
The imported projects contain multiple portlets that share JSF JSPs and use property broker for portlet communication. Listed below are descriptions of the portlets and their corresponding views.
Sample portlet views (as JSF JSPs):
- BrokerSummary: Sends the broker summary request (brokerSummaryRequest.xml), and receives a response containing the broker's clients and their policies (brokerSummaryResponse.xml). The XML responses are processed in a session managed page root wrapper bean (BrokerDetailRoot) that is used to render the data in the controls on the page.
- BrokerSummaryNew: Similar to BrokerSummary, displayed when a new policy is added.
- BrokerDetail: Sends the broker detail request (brokerDetailRequest.xml), and receives a response containing all the broker's clients and their policies (brokerDetailResponse.xml).The XML response is processed into a session managed page root wrapper bean (BrokerDetailRoot) that is used to render the data in the controls on the page.
- AddPolicy: Enables adding a new policy for an existing client by sending a request (addPolicyRequest.xml), and receives an XML response (addPolicyResponse.xml) for the success or failure of the requested changes. The XML responses are processed in a page root wrapper bean (AddPolicyRoot) that is used to process the updates along with the session managed page root wrapper bean (BrokerDetailRoot).
- SearchPolicy: Enables selecting the maximum policy amount from a dropdown menu populated with a static list of values and a dynamic list of states from validCodesService. This view shows usage of the static and dynamic list-driven dropdown control. Values selected are passed to the SearchPolicyResult page.
- SearchPolicyResult: Sends the request for policy search based on the maximum amount parameter (policySearchRequest.xml), and receives a response with matching policies (policySearchResult.xml). The response is processed in a page root bean wrapper (SearchPolicyResultRoot), which processes (policySearchResult.xml) and renders the result.
- BrokerSummaryHelp: Provides help for the BrokerSummary portlet.
Sample portlets:
- BrokerSummaryPortlet: Primary view is BrokerSummary. The refresh command link refreshes the content by invoking the service.
- BrokerDetailPortlet: Primary view is BrokerDetail and links to AddPolicy. When a new policy is added, BrokerSummaryPortlet is notified to refresh the summary contents with the changes, and the BrokerSummaryNew view is displayed. Multiple data is passed to the portlet using the property broker as a AddPolicyDataMessage.
- SearchPolicyPortlet: Primary view is SearchPolicy and links to SearchPolicyResult.
To create a new JSR 168 portlet:
- In Application Developer, open the New Portlet dialog (Figure 6).
- Select the portlet Project name, XYZInsurancePortlet, assign the Default name prefix
BrokerSummaryPortlet, and identify the new portlet as a Faces portlet (JSR 168), so that the Faces portlet framework libraries are added to the project (if they not present already).
Figure 6. Create a new portlet
- Next, confirm the Portlet name, select the default Internationalization Locale, and select Change the code generation options to override the default names, as in Figure 7.
Figure 7. Portlet settings
- As a result of these steps, the artifacts shown in Figure 13-10 will be generated.
Figure 8. Generated artifacts
Use the New Faces JSP File dialog (Figure 9) to create a Faces JSP for each of the Sample portlet views (link) listed above. For each JSP, be sure to specify Portlet for the Model field. This ensures that the appropriate portlet tag libraries are initialized and used in the JSF presentation. When completed, the new Faces JSPs should appear within the project as they do in Figure 10.
Figure 9. Create Faces JSPs
Figure 10. Create Faces JSPs
Application Developer provides the ability to configure the deployment descriptor for the portlets, just as it does for an EJB or Web project, with a supplied easy-to-use editor. You can also modify the configuration of each portlet using the editor (rather than modifying the portlet deployment descriptor as source) to, for example, change the portlet views created in the previous section by adding initialization parameters for different modes, such as view, edit, help, and configure. (Figure 12)
Figure 11. Update portlet deployment descriptor
Figure 12. Update portlet deployment descriptor
Any multipage presentation requires navigational access from one page to another, and portlets provide navigation controls to ease navatigation development. Navigation links can be added within a portlet that uses link control, but a special consideration is made when supplying a URL value in a navaigation link control: As in our scenario, the link URL is defined without the dot(.) as "/BrokerSummary.jsp". This is different than developing a pure JSF Web application page, which requires the dot(.) in the navigation links. (This requirement may be removed in the future releases of the product.)
Figure 13. Link addition
As a powerful content delivery mechanism, portlet presentations provide a way to configure the state of the portlet within the same presentation page. The state of individual portlets can either be maximized or minimized, thus providing the user with a more personalized view of the content of interest. To achieve this, portlet presentation delivery is divided into two phases: an action phase and a render phase:
- When a presentation page with a portlet is requested, portlets enter the render phase and the content is displayed.
- When any action is invoked on a portlet, the portlet enters the action phase, and the action method on the corresponding portlet is invoked.
There are limitations to what APIs are available in the action vs. render phases that require special considerations in the development of the portlets. The request and the response objects that are created and available are different for each phase. The code sample in Figure 14 shows how, for a JSR 168 portlet project, when a portlet is in action phase, window state can be changed using the ActionResponse. As in our scenario, if the end user is working on viewing the policy details for all clients and then adds the new policy, he may maximize the BrokerDetailPortlet to have a better user experience with better utilization of the view area. The BrokerDetail.jsp page shows the usage of these APIs to change the window state.
Figure 14. Code snippet for changing window state
To present a large set of data in manageable sets, the requirement is often to present only a subset of data per page. Pager controls provided in JSF are used to paginate between these sets of data in the JSF pages being used as portlet views. A special consideration is made when using the pager function and click-to-action functionality together in a Faces JSP page. In such a case, use the simple pager or the goto pager controls, as shown in Figure 15, rather than the deluxe or Web style pager controls, since these are not currently supported in WebSphere Portal.
Figure 15. Pager controls
Dropdowns are commonly used in the presentation, whether it is portlet or just a JSF Web page. The values of the dropdown can either be dynamically retrieved by service invocation, or they can be in a statically defined list with the control. Our scenario uses a static list within a portlet view. SearchPolicyPortlet provides a means of searching the policies based on the Policy amount, and the static list of the policy values is provided in the dropdown of the SearchPolicy.jsp, as shown in the following figures:
Figure 16. Static list
Figure 17. Static list dropdown
8. Passing data within portlet views
There is almost always a need to pass data from one view to another within the views of a portlet. Data can be passed using the request or the session, or you can even define a hidden variable on the form to pass the data. For example:
- In the BrokerDetail.jsp page (Figure 18), the clientId is passed to the AddPolicy.jsp page (Figure 19) using the request parameter.
- The value of the request variable is cached as the selectedClientId attribute in the page bean root wrapper AddPolicyRoot.
- The hidden variable on the form (Figure 20) is used to persist this value between different command actions on the page.
- The text5 property in the BrokerDetail.java page code is exposed to the page data by making the getText5 API as public.
- In the SearchPolicy.jsp page, the selected value from the dropdown is passed as a request parameter to the next page within the portlet (Figures 21 and 22).
Figure 18. Passing data within portlet views using request parameter in BrokerDetail.jsp
Figure 19. Retreiving request parameter on page load in AddPolicy.jsp
Figure 20. Caching data within portlet views using hidden variables in AddPolicy.jsp
Figure 21. Passing data as request attribute in SearchPolicy.jsp
Figure 22. Retreiving request attribute in SearchPolicyResult.jsp on load
9. Sharing data across portlets
The previous section showed how data can be shared within the views of a single portlet. A need may also arise for sharing data across different portlets. As in our scenario, when a new policy is added using the AddPolicy view in the BrokerDetailPortlet, the BrokerSummary view in the BrokerSummaryPortlet should be updated to reflect the newly added policy for the customer. The bean that is serving the BrokerSummary view should then request the new data from the service. To communicate this to the BrokerSummaryPortlet, a message or a parameter needs to be passed from the BrokerDetailPortlet to the BrokerSummaryPortlet, thus creating a requirement to share data across portlets.
Portlets that share data are called cooperative portlets. Sharing data between portlets can be achieved in a variety of ways:
- Click-to-action: With this delivery method, users can transfer data with a simple click from a source portlet to one or more target portlets; the target(s) react to the action and display a new view with the results. You can also broadcast the property to all portlets on the page that have declared an action associated with a matching input property. Click-to-Action is currently supported in WebSphere Portal V5.0.2.x and V5.1 with portal projects that use WebSphere Portal APIs.
- Property broker: The WebSphere Property Broker can be used to transfer data across the portlets. The passing portlet is the source portlet and the receiving portlet is the target portlet. Any portlet can be a source or a target. Property broker communication only supports the passing of one property, but you can define this property as a complex data type to pass multiple data. Property broker sharing is supported in WebSphere Portal V5.0.2.x and V5.1 for portal projects that use WebSphere APIs, and in WebSphere Portal V5.1 for JSR 168 portal project types. The property broker mechanism requires the "wiring" of portlets (described later).
- Messaging: Messaging is supported for data communication in both versions of WebSphere Portal specified above, but only for portlet projects that use WebSphere APIs.
- Session: Data can be shared across portlets using the application scope session attribute. The additional PortletSession property for scope determines if the scope of the session is to be across the portlets defined in the application, or if it is only to be shared within the pages inside a portlet.
The solution supplied with this article illustrates the property broker mechanism that uses a single property to communicate multiple data attributes across the portlets:
- In the doAddPolicy action in AddPolicy.jsp, the RefreshView, NextView, and WindowState attributes are passed as a request attribute (NextViewData) to BrokerSummaryPortlet whenever a new policy is added in the BrokerDetailPortlet.
- The doUpdateView action is invoked on the brokerSummary.jsp view in the BrokerSummaryPortlet, and NextViewData is parsed for the multiple attributes.
- The Java bean is updated with the data from the BrokerService only when RefreshView attribute is true and NextView attribute determines the view to be shown.
- The state of the window is determined based on the WindowState attribute.
These steps illustrate the configuration of the property broker for the data passing:
- Enable the source portlet that contains the view that will pass the data. (Figure 23)
Figure 23. Enable source portlet
- Specify a Data type name that will be used to refer to the passed data. You can also select the list of existing data types as they are created.
- The boundTo attribute specifies the mechanism that will be used to specify the data that needs to be passed.
- As a result, a <SourcePortlet>.wsdl file is generated in the webcontent\wsdl folder that contains the data type definition as WSDL syntax.
Figure 24. Source portlet specification
- Make sure that the action name and the caption are defined in the WSDL that is generated for the source portlet specification. The caption value is used to identify the action when specifying the wiring (described later). Supply these values if they are not present.
<operation name="BrokerDetailPortletportlet"> <portlet:action name="UpdateView" caption="Update View" type="standard" /> <output> <portlet:param name="NextViewData" partname="NextViewData_Output" boundTo="request-attribute"
caption="NextViewData"/> </output> </operation>
- On the action where the parameter needs to be passed, an additional request-parameter com.ibm.portal.propertybroker.action needs to be defined for the action to be invoked. The name used here is the same as the name specified in the source portlet WSDL specification. This parameter is used by the property broker service to invoke the specified action.
Figure 25. Pass source parameters
- The data can then be set in the container, as specified by the boundTo attribute in the source portlet specification. In this example, the data is set in the RequestScope as a request attribute in the action code that is invoked.
public String doAddPolicyAction(){ this.getVarAddPolicyRootBean().addPolicy (this.getVarBrokerDetailRootBean().getBrokerServiceRoot()); this.sessionScope.remove("varBrokerDetailRootBean"); setNextViewData(); return "addPolicy"; } public void setNextViewData(){ //newViewOutcomeName:RefreshView:WindowState String nextViewData = "newView:true:maximized"; this.getRequestScope().put("NextViewData", nextViewData); }
- Enable the target portlet that contains the views that will receive the data that is passed.
Figure 26. Enable target portlet
- Browse the view on which action is invoked and the data specified is passed. The boundTo attribute in the target portlet can be different that what the source portlet had specified; this defines the container in which the passed data will be sent. The names for the parameter or the action can be different than what was specified in the source portlet.
Figure 27. Browse the action
Figure 28. Target portlet specification
- A WSDL is generated in the webcontent\wsdl folder for the target portlet specification that defines the action invoked and the data to be received. The caption name is used when defining the wiring between the portlets (described later). The portlet parameter that is specified can be retrieved in the action that is invoked on the view, as per the container specified by the boundTo attribute. In this example, the NextViewData can be retrieved from a request scope attribute.
<operation name="BrokerDetailPortletportlet"> <portlet:action name="UpdateView" caption="Update View" type="standard" /> <output> <portlet:param name="NextViewData" partname="NextViewData_Output" boundTo="request-attribute"
caption="NextViewData"/> </output> </operation>
- In BrokerSummary.java, the NextViewData can be retrieved and processed from as a request scope attribute.
public String doUpdateViewAction(){ return processNextViewData(); } public String processNextViewData(){ String newViewOutcome=""; //newViewOutcomeName:RefreshView:WindowState String nextViewData = (String)this.getRequestScope().get("NextViewData"); if(nextViewData != null && nextViewData.length() > 0){ String[] params = nextViewData.split(":"); if(params != null && params.length > 0){ newViewOutcome = params[0]; if(params.length > 1){ if(Boolean.getBoolean(params[1]) == true){ //remove the key to get updated data from service this.getSessionScope().remove ("varBrokerSummaryRootBean"); } if(params.length > 2){ //set the window state setWindowState(params[2]); } } } }else{ this.getSessionScope().remove("varBrokerSummaryRootBean"); return "view"; } return newViewOutcome; } public void setWindowState(String windowState) { ActionResponse actionResponse = (ActionResponse) getFacesContext().getExternalContext().getResponse(); try { if(windowState == "maximized"){ actionResponse.setWindowState(WindowState.MAXIMIZED); } else if(windowState == "minimized"){ actionResponse.setWindowState(WindowState.MINIMIZED); } else if(windowState == "normal"){ actionResponse.setWindowState(WindowState.NORMAL); } } catch (WindowStateException e) { logException(e); } }
You can also use the complex data passing technique to share multiple attributes, as illustrated in Passing complex data between coperative portlets.
10. Intercepting a portlet action
In the previous example, the action was invoked on the portlet view that was being displayed on the target portlet. Once the view is changed from brokerSummary to brokerSummaryNew, any new policy addition cannot be refreshed in the brokerSummaryPortlet. Another application requirement may be such that the source portlet has no knowledge of the view being displayed on the target portlet. In such a case, the target action code cannot be placed in a view. The portlet class needs to be subclassed and the action needs to be intercepted before the existing view is rendered. The view name determined from the data passed to the portlet action can then be set as the view to be displayed:
- In the <TargetPortlet>.wsdl file, define the action name as
UpdateView. This name is used to intercept the action in the portlet subclass.<operation name="BrokerSummaryPortletportlet"> <portlet:action name="UpdateView" type="standard" caption="Update View" description="Update View Action" /> <input> <portlet:param name="NextViewData" partname="NextViewData_Input" boundTo="request-attribute" /> </input> </operation>
- In the subclass created for the portlet, intercept the action and check the com.ibm.portal.propertybroker.action request parameter for the action name. If the action name is UpdateView, update the session parameter com.ibm.faces.portlet.page.view for the view name as determined from the data retrieved from the action parameter.
public void processAction(ActionRequest request, ActionResponse response) throws PortletException { String actionName = (String)request.getParameter("com.ibm.portal.propertybroker.action"); if (actionName != null && actionName.equals("UpdateView")) { // passed value is something like 'viewName1:true:maximized' in the parameter String nextViewData= (String) request.getAttribute("NextViewData"); if(nextViewData != null && nextViewData.length() > 0){ String viewName = null; int i = nextViewData.indexOf(':'); if (i >= 0) viewName = nextViewData.substring(0, i); if(viewName != null){ //change the portletView to be displayed request.getPortletSession().setAttribute ("com.ibm.faces.portlet.page.view", viewName ); } } } - In the page code for the view that is expecting the NextViewData data, retreive the parameters in the view to be displayed in the target portlet as a RequestScope parameter. You may choose to write a common utility class with the methods that perform the changes based on the data, such that it could be reused accross the views.
public BrokerSummaryRoot getVarBrokerSummaryRootBean() { if (varBrokerSummaryRootBean == null) { varBrokerSummaryRootBean = (BrokerSummaryRoot) getFacesContext() .getApplication().createValueBinding( "#{varBrokerSummaryRootBean}").getValue( getFacesContext()); } String nextViewData= (String) request.getAttribute("NextViewData"); //process data return varBrokerSummaryRootBean; }
11. Run the XYZInsurance portlet project
- Since different runtime versions of the EMF must be used with the XSD SDO Transform feature, the applications using the transform feature that are deployed on WebSphere Portal V5.0.2.x or V5.1 are required to be set with the PARENT_LAST classloader policy and APPLICATION WAR classloader policy isolation. Figure 29 shows the section in the WebSphere Portal configuration that can be used to set this classloader configuraton. If not done, then an older version of the EMF framework supplied with the portal server is loaded from the global classpath. This version is not compatible to the one required by the generated SDOs used by the XSD SDO transform feature, and therefore may cause run time failure of the application.
Figure 29. WebSphere Portal application classloader configuration
- To configure the Universal Test Environment (UTE), install WebSphere Portal V5.1 with the Test environment installation option selected. The WebSphere Portal stub in the installed runtime of your workspace should point to the installed portal server UTE location. As a result, the WebSphere Portal V5.1 test environment will display as a choice for the target server runtime (Figure 30). Any project targetted to this stub as runtime will be configured to use this test environment. Be sure to target your JSR 168 portlet projects to the WebSphere Portal V5.1 server to use cooperative portlets.
Figure 30. WebSphere Portal V5.1 stub configuration as test environment
- Since our scenario uses the property broker implementation for data sharing across portlets, additional configurational steps (creating portlet wires, as illustrated in next step) need to be taken to enable portlet communication. Wires can be created and configured using the portal server admin console. To enable the wiring configuration in the portal server admin console, ensure that Enable base portlets for portal administration and customization is checked in the Portal Options in your WebSphere Portal configuration (Figure 31).
Figure 31. Portal options
- To wire the portlets for property broker communication across portlets, perform these steps every time the server is started:
- Select the XYZInsurance application, right-click and select Run On Server.
- Select Edit Page (Figure 32) then select the Wires page to define the wires for data transfer between portlets.
Figure 32. Wiring page
- Add the wires between BrokerDetail and the BrokerSummary portlet. (Figures 33 and 34)
Figure 33. Create wires for data passing
Figure 34. Created wire
- Select the XYZInsurance application, right-click and select Run On Server. Figures 35, 36 and 37 show all the portlets present in the solution.
Figure 35. Summary portlet
Figure 36. Detail portlet
Figure 37. Search portlet
Part 4 of this article series was dedicated to analyzing the insurance application scenario that was developed using portable JSR 168 portlets for a loosely coupled XML-based SOA. Also described were the issues involved in the configuration of WebSphere Portal for the differences in the required EMF runtime. This article focused on data sharing within portlet views and across portlets, and described the steps involved in sharing multiple data attributes with a single property via property broker.
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.
| Description | Name | Size | Download method |
|---|---|---|---|
| Download file 1 | xsd_sdo_soa_xml_sample.zip | 4.8 MB | FTP |
| Download file 2 | xsdsdotransform-feature.zip | 52 KB | FTP |
Information about download methods
- IBM developerWorks Rational
- An Introduction to Service Data Objects
- Introduction to Service Data Objects: Next generation data programming in the Java environment
- JSF Central
- JavaServer Faces Sun Web site
- The case for portlets: How to decide of portlets are your best option
- Portlet application programming, Part 1: Introduction to portlet structure and programming
- To learn more, visit the developerWorks WebSphere Studio zone, the developerWorks WebSphere Application Server zone, and the developerWorks WebSphere Portal zone. You'll find technical documentation, how-to articles, education, downloads, product information, technical support resources, and more.
- Browse for books on these and other technical topics.
- WebSphere forums.
Product-specific forums where you can ask questions and share your opinions with other WebSphere users.
- developerWorks blogs. Ongoing, free-form columns by software experts, with space for you to add your comments.
Comments (Undergoing maintenance)





