- The Benefits of Inter-Portlet Communication
- The WebSphere Property Broker
- Creating a Service Provider
- Testing the Service Provider
- Creating a List Portlet
- Creating a Detail Portlet
- Configuring the WebSphere Property Broker
- Alternative Communication Methods
- When to Use Inter-Portlet Communication
- Summary
- Important Points
Creating a Service Provider
To provide data to your list and detail portlets, you should create a service provider model. This model will contain operations to retrieve a list of loans and retrieve details on a particular loan, which is consumed by the list and detail models. The service provider is the singular access point for loans information in your application, and it makes your application easier to maintain.
Before you can begin the steps in this section, you need a WPF project, which houses the service provider model and the other models in this chapter. If you have a project from a previous chapter, you can use that. If you don't, you should create a new WPF project. For more information on creating projects, see Chapter 1, "Introduction to WebSphere Portlet Factory." The project is published as a WAR file and deployed to a portal server, and you should also deploy the application to a local application server for testing. You can use the portal server if it is running on your local machine. If not, it is recommended that you use the IBM WebSphere Application Server Community Edition server (WAS CE) that comes with WPF.
After you have a project set up, you need to add the service provider model. The service provider uses the following builders to provide its functionality:
- Service Definition
- Variable
- Simple Schema Generator
- Action List
- Method
- Service Operation (x2)
Note that although the order of builder calls is usually not important, some of the builder calls in this chapter need to be in a specific order. This is because some of the builder calls require certain things to be built by the time their build methods run when the WebApp is regenerated. In this example, the Variable builder call must precede the Simple Schema Generator builder call to create a schema based on the variable built by the Variable builder call, and the Simple Schema Generator must precede the Service Operations because the Service Operations require the schema to use for their results. Also, the Action List must precede the first Service Operation, and the Method must precede the second Service Operation, or you will get errors indicating that these resources are unavailable.
Creating a Model
Create a new model called loansService in your project under the folder WEB-INF/models/chapter09. Because you will store your data in an XML variable, rather than get it from a database, you need to create the service provider manually. To do this, the model should be based on the Empty template, which creates a model with no builder calls in it. For more information on creating models, see the example in Chapter 1.
Defining the Service
Add a Service Definition builder call to the model by selecting Service Definition from the Builder Palette. You can open the Builder Palette by clicking the icon in the Outline view. Then, press OK. Name the builder call loansService and expand the Testing Support section at the bottom of the builder call, and then enable the box for Add Testing Support. WPF now automatically generates test pages for the operations in your service every time the model is regenerated. Save the builder call when you are finished.
Adding Loan Data
The next step is to add your sample data for the service provider. Add a Variable builder call to the model and name it loans. Change the Type input to XML and enter in the following XML into the Initial Value input:
<Loans xmlns="http://com.ibm.CooperativeExample"> <Loan> <LoanID>00001</LoanID> <Item>The Gullible Traveler</Item> <LoanedTo>Malcolm Johnson</LoanedTo> <DueDate>11/05/2007</DueDate> </Loan> <Loan> <LoanID>00002</LoanID> <Item>A Traveling Aunt</Item> <LoanedTo>Samuel Russell</LoanedTo> <DueDate>11/11/2007</DueDate> </Loan> <Loan> <LoanID>00003</LoanID> <Item>An Interminable Journey</Item> <LoanedTo>Joseph Jones</LoanedTo> <DueDate>12/22/2007</DueDate> </Loan> </Loans>
Save the builder call when you are finished. Next, add a Simple Schema Generator builder call to the model. This builder call is used to automatically generate a schema based on the Variable builder call, which is then used to define the structure of the result sets for the Service Operation builder calls. Name the builder call loansSchema, and for the Sample Data input, select 'loans' from the drop-down list. This is the variable you created earlier. Save the builder call when you are finished.
Adding an Action to Retrieve a List of Loans
Now, add an Action List builder call to the model. The Action List defines the action to be called when the retrieveLoansList service operation is consumed, which you create in a later step. Name the Action List getLoans and change the return type to IXml. IXml is a WPF interface used to access and manipulate XML. For more information on IXml, see Chapter 9, "Using Web Services and Manipulating XML."
Open the Select Action dialog for the first row in the Actions input, which you do by clicking on the ellipsis button on the first row of the Actions input. Select Special, Return, then select the loans Variable from under the Variables section and press OK. The action should appear in the Action List as follows:
Return!${Variables/loans/Loans}
When the Action List is called, this action returns the entire Loans variable created by the Variable builder. Save the builder call when you are finished.
Specifying the getLoansList Operation
Next, you create the first operation for the loansService service. This operation returns a list of loans (by calling the getLoansList Action List). Add a Service Operation builder call to the model and make sure the Service Operation Properties section is expanded. Select loansService for the Data Service input, which links the operation to the loansService service created by the Service Definition builder call.
The Operation Name input defines how the operation is referred to by consumers. Change this input to getLoansList—there is no problem with this being the same name as your Action List. The Action To Call input defines what happens when the operation is consumed. This input should be changed to point to your Action List (getLoansList). Note that the Operation Description input is left blank, because it appears only to service consumers when the service provider is defined as a Web service.
Make sure 'No inputs' is selected for the Input Structure Handling input in the Operation Inputs section of the builder call. This specifies that the operation has no inputs—consumers have only to specify that they want to consume the operation to retrieve the loans list.
Expand the Operation Results section of the builder call and select Specify Result Schema for the Result Structure Handling input. This enables you to manually specify the structure of the results to be returned from the operation. For the Result Field Mapping input, select the topmost element in the Loans schema (Loans). The Loans element contains a list of Loan elements and is returned from the getLoansList Action List. The input should read loansSchema/Loans when you are finished. Make sure the Result Field Mapping input is set to Automatic, which automatically maps results from the called action to the result returned from the service operation.
Save the builder call when you are finished.
Adding a Method to Retrieve a Specific Loan
Add a Method builder call to the model and name it getLoanFromID. This method returns a particular loan based on a loan ID argument and is called whenever the getLoanDetail operation is consumed. A Method builder call is used, rather than an Action List, because some IXml manipulation is required to link loanIDs to loans.
Expand the Arguments section of the builder call and add a single argument called loanID of type String. This argument corresponds to a particular loan, and you access it from the method defined in the Method Body Input.
Change the Return Type of the builder call to IXml, and then enter in the following code into the Method Body input:
{ //cycle through loans variable to get each loan IXml loans = webAppAccess.getVariables().getXml("loans"); for (IXml loan = loans.getFirstChildElement(); loan !=null; loan = loan.getNextSiblingElement()) { //look for match on loanID element if ( loan.getText("Loan/LoanID").equals(loanID) ) //match found, return the current loan return loan; } //no match found, return empty loan return XmlUtil.create("Loan"); }
This code cycles through each of the loan elements in the loans list, and checks to see whether the loan ID of the element matches the loan ID passed in to the method. For more information on the use of IXml, see Chapter 9. Save the builder call when you are finished.
Specifying the getLoanDetail Operation
The final builder call for the service provider is another Service Operation builder call. This builder call defines a second operation for the loansService service, which displays details for a particular loan (by calling the getLoanFromID Method). Add a Service Operation builder call to the model and point the Data Service input to loansService. Change the Operation Name to getLoanDetail, and the Action To Call to getLoanFromID. This creates a new operation on the loansService service called getLoanDetail, which runs the getLoanFromID method when consumed.
In the Operation Inputs section of the builder call, select 'Use structure from called action' for the Input Structure Handling input and make sure the Input Field Mapping input is set to Automatic. This specifies that the inputs to the operation are defined by the getLoanFromID Method, and should be automatically mapped to the inputs in getLoanFromID.
Fill out the Operation Results section of the builder call the same as the Operation Results section in the previous Service Operation builder call, which specifies that the structure of the results to be returned from the operation is defined by the Loan element in the Loans schema. Save the builder call when you are finished.
You have now finished building your service provider. The next section discusses how you can test your service provider before moving on to create the list portlet and detail portlet.