13.5 Sample scenario

 < Day Day Up > 

In this section, a sample scenario is provided to illustrate how to develop cooperative portlets using the programmatic approach.

13.5.1 Declarative source cooperative portlet

In this scenario, you will implement a combined scenario where the source cooperative portlet uses the declarative approach to interact with a target cooperative portlet using the programmatic approach. The sample scenario is shown in Figure 13-4.

Figure 13-4. A sample scenario using a combined approach

graphics/13fig04.gif

Creating the HRPortlet portlet application project

In this section, the source cooperative portlet from Chapter 12, "Cooperative portlets" on page 371 will be used. Follow these steps if you do not have this portlet project in your workspace:

  1. If not already running, start the IBM WebSphere Studio Site Developer, click Start -> Programs -> IBM WebSphere Studio -> Site Developer 5.0 .

  2. Select File -> New -> Portlet Application Project .

    Note : If you do not see this option, select File -> New -> Other and click Portlet Development and Portlet Application Project .

  3. In the Define Portlet Project window, enter HRPortlet for the project name . Click Next .

    Figure 13-5. Define the Portlet Project

    graphics/13fig05.jpg

  4. In the J2EE Settings Page, click Next to take the default values.

  5. In the Portlet Settings Page, select Change code generation options and enter HRPortlet for the Class prefix. Click Finish to generate the framework for your project.

    Figure 13-6. Portlet Settings

    graphics/13fig06.jpg

  6. If you have any other portlets in the DefaultEAR project, remove them at this time.

Importing the HRPortlet portlet

The HRPortlet portlet from Chapter 12, "Cooperative portlets" on page 371 will be used as a base for this scenario. This portlet will be enabled to act as a source cooperative portlet in this scenario. You will need to import this portlet if it is not in your workspace.

Follow these steps to import this portlet if it is not in your workspace:

  1. Import the WAR file by selecting File -> Import .

  2. Select WAR file and click Next .

  3. In the Import Resources from a WAR File window, enter the following information:

    1. WAR file: browse to C:\LabFiles\C2A\solutions\HRPortlet.war .

      Note : The sample scenario included in this chapter requires that you download the sample code available as additional materials. See Appendix C, "Additional material" on page 543.

    2. Web project: select Existing . In the box that pops up, select HRPortlet and click OK .

    3. Context root: this will change to /HRPortlet .

    4. In Options, select the Overwrite existent resources without warning check box.

    5. Click Finish to import the WAR file.

  4. Make sure the web.xml descriptor has been updated with the c2a wrapper.

  5. Make sure the PortletView.jsp has been updated with the c2a tags and c2a tag library. See Example 13-2.

    Example 13-2. C2a library and tags
     <%@ page contentType="text/html" import="java.util.*, hrportlet.*"%> <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %>  <%@ taglib uri="/WEB-INF/tld/c2a.tld" prefix="C2A" %>  ...................................................  <TD>   <P><C2A:encodeProperty   name='<%=results.getColumnName(col).toString()+\"Param\"%>'   namespace="http://www.ibm.com/wps/c2a/examples/hrdetails"   type="<%=results.getColumnName(col)%>"   value="<%=results.getCacheValueAt(row, col).toString()%>" />   <%=results.getCacheValueAt(row, col)%>   </P>   </TD>  
  6. Save your files (or press Ctrl-S to save the files).

13.5.2 Enabling the portlet for target C2A programmatic

In this section, you will import a second copy of the HRPortlet and update it to support Click-to Action as a target cooperative portlet using the programmatic approach. This target portlet will execute a fixed SQL statement with a variable where clause.

The code for the target portlet class must meet the following requirements:

  • The action must be implemented either as a portlet action or a Struts action. For portlet actions, you should use the simple action Strings rather than the deprecated PortletAction class.

  • Portlet actions must accept a single parameter. The parameter may appear as a request parameter, a request attribute, a session attribute, or an action attribute (deprecated), as specified in the action declaration or registration.

    The HRPortlet is already prepared for this situation, so only a few changes are needed in the portlet class code. Figure 13-7 illustrates the target cooperative portlet for this sample scenario.

    Figure 13-7. Cooperative portlets - programmatic sample scenario (target portlet)

    graphics/13fig07.gif

Creating a target portlet application project

To import a second version of the HRPortlet, create a portlet application project as follows :

  1. In the Portlet perspective, choose File -> New -> Portlet Application Project from the main menu.

  2. In the Create a Portlet Project window, enter DepartmentDetailsPortlet as the project name and select Create empty portlet . Click Next .

    Figure 13-8. Create portlet project DepartmentDetailsPortlet

    graphics/13fig08.jpg

  3. In the J2EE Settings Page, select the Existing radio button for the Enterprise application project and enter DefaultEAR as its name. Click Finish to create the portlet project.

    Figure 13-9. J2EE Settings Page

    graphics/13fig09.jpg

  4. Click OK if you receive the Repair Service Configuration message indicating that the project will be added to DefaultEAR.

Figure 13-10. Repair Server Configuration message

graphics/13fig10.jpg

Importing the original portlet application
  1. From the main menu, select File -> Import to import the original HRPortlet.

  2. Choose WAR file , click Next and configure as follows:

    1. Browse to the location of the HRPortlet.war file in

       c:\LabFiles\AdvC2A\HRPortlet.war. 

      Note : The sample scenario included in this chapter requires that you download the sample code available as additional materials. See Appendix C, "Additional material"on page 543.

    2. As the Web Project, select the existing Web project DepartmentDetailsPortlet .

    3. Select Overwrite existing resources without warning and click Finish .

    Figure 13-11. Import a second version of HRPortlet (target c2a portlet)

    graphics/13fig11.jpg

  3. Since the HRPortlet and DepartmentDetailsPortlet portlet applications use the same UID, a warning message will appear in the task pane.

    Figure 13-12. Duplicate UID messages

    graphics/13fig12.jpg

  4. To fix this problem, expand DepartmentDetailsPortlet/Web Content/WEB-INF in the J2EE Navigator view. Double-click portlet.xml .

    Figure 13-13. Selecting portlet.xml

    graphics/13fig13.jpg

  5. In the portlet deployment descriptor editor, select Portlet Application and change the last digit of the UID for this portlet application. For example, in this sample scenario, the last digit was 6 and it was changed to 7.

    Figure 13-14. Changing a digit in portlet application UID

    graphics/13fig14.gif

  6. In a similar way, select Concrete Portlet Application and change the last digit before the last dot of the UID to give it the same value as in the previous step.

    Figure 13-15. Changing digit in concrete portlet application UID

    graphics/13fig15.gif

  7. Save your changes. The warning messages in the Tasks view should disappear.

Importing pbportlet.jar

Import the property broker (pbportlet.jar) file into the DepartmentDetailsPortlet project.

  1. Select File -> Import -> File system .

  2. For example, for the directory browse to:

     C:\Program Files\ibm\WebSphere Studio\runtimes\portal_v50\pb\lib 
  3. Select pbportlet.jar .

  4. For the destination, select the folder DepartmentDetailsPortlet/Web Content/WEB-INF/lib .

    Figure 13-16. Import the property broker jar file (pbportlet.jar)

    graphics/13fig16.jpg

  5. Click Finish .

Updating the web.xml descriptor

Update the Web deployment descriptor by changing the servlet class to PortletWrapper and including the c2a-application-portlet-class parameter.

  1. In the J2EE Navigator view, expand DepartmentDetailsPortlet and double-click Web Deployment Descriptor .

  2. Switch to the Servlets tab and select the hrportlet.HRPortlet servlet (Figure 13-18 on page 432).

  3. In the Details area, click the Browse... button to change the servlet class (Figure 13-18 on page 432).

  4. In the Servlet selection dialog, select the PortletWrapper class from the com.ibm.wps.pb.wrapper package and click OK .

    Figure 13-17. Adding PortletWrapper

    graphics/13fig17.jpg

  5. In the Initialization area, click the Add... button to add a new parameter.

  6. Enter a parameter name of c2a-application-portlet-class and a parameter value of hrportlet.HRPortlet . The final editor should look as shown in Figure 13-18 on page 432.

    Figure 13-18. Web Deployment Descriptor for the target cooperative portlet

    graphics/13fig18.jpg

  7. Save your files (or press Ctrl-S to save the file) and close the deployment descriptor editor.

Updating the DepartmentDetailsPortlet

In this section, you will update the portlet to act as a target C2A portlet using the programmatic approach. The DepartmentDetailsPortlet is a copy of the HRPortlet and it will register the DEPT_NO property by using the property broker API instead of a WSDL file used in the declarative approach.

Follow these steps to update the portlet class to publish the property and create call back methods to recognize the property changes:

  1. Open the file DepartmentDetailsPortlet/Java Source/hrportlet/HRPortlet.java.

  2. Update the class definition so it implements the PropertyListener and EventPhaseListener interfaces.

     public class HRPortlet extends PortletAdapter implements PropertyListener, EventPhaseListener, ActionListener 

    Note : The setProperties method of the PropertyListener interface receives updates of property values. To register properties, you will use the beginEventPhase method of the EventPhaseListener interface, since only during the event phase is it possible to register and unregister properties.

  3. Insert the following two new class attributes so the code looks like this:

     public class HRPortlet extends PortletAdapter implements PropertyListener, EventPhaseListener, ActionListener { PropertyBrokerService pbService; PortletConfig portletConfig; 

    Note : pbService is an interface to the property broker and portletConfig stores the portlet config.

  4. Update the init method so it looks as shown in Example 13-3.

    Example 13-3. Update init method to obtain portlet configuration
     public void init(PortletConfig portletConfig) throws   UnavailableException {         super.init(portletConfig);  this.portletConfig=portletConfig;  } 
  5. Insert the initConcrete method shown in Example 13-4 to initialize the property broker attribute.

    Example 13-4. Initialize property broker
      public void initConcrete(PortletSettings settings)   throws UnavailableException {   try {   pbService =   (PropertyBrokerService) getPortletConfig()   .getContext()   .getService(   PropertyBrokerService.class);   } catch (PortletServiceUnavailableException e) {   throw new UnavailableException("Could not locate   PropertyBrokerService.");   } catch (PortletServiceNotFoundException e) {   throw new UnavailableException("Could not locate   PropertyBrokerService.");   }   }  
  6. For simplicity, create the registerPropertiesIfNecessary method to register the property we are interested in.

    Note : This method performs the same as the WSDL file when using the declarative approach. Notice also that you need to specify a direction of Property.IN . In addition, actions are not registered (which is possible using the registerActions method) in this scenario. In other words, this portlet will be invoked by the property broker using the setProperties method instead of actionPerformed.

    Example 13-5. registerPropertiesIfNecessary method
      private void registerPropertiesIfNecessary(PortletRequest request)   throws PropertyBrokerServiceException {   PortletSettings settings = request.getPortletSettings();   Property[] properties = pbService.getProperties(request, settings);   if (properties == null  properties.length == 0) {   PortletContext context = getPortletConfig().getContext();   //not registered, register now   properties = new Property[1];   properties[0] = PropertyFactory.createProperty(settings);   properties[0].setName("DEPT_NOParam");   properties[0].setDirection(Property.IN);   properties[0].setType("DEPT_NO");   properties[0].setNamespace("http://www.ibm.com/wps/c2a/examples/hrdetails");   properties[0].setTitleKey("HRDetails.Department");   properties[0].setDescriptionKey(   "Display department details");   pbService.registerProperties(request, settings, properties);   }   }  
  7. Add the beginEventPhase and endEventPhase methods which are call back methods called during the event phase.

    Example 13-6. The beginEventPhase methods registers the property if necessary
      public void beginEventPhase(PortletRequest request) {   try {   registerPropertiesIfNecessary(request);   }   catch (Throwable e) {   e.printStackTrace();   }   }   public void endEventPhase(PortletRequest request) {   }  
  8. Add the setProperties method. Using this method, the class is notified about property changes.

    Example 13-7. setProperties updates the sql statement
      public void setProperties(   PortletRequest request,   PropertyValue[] properties) {   PortletSession session = request.getPortletSession();   HRPortletSessionBean sessionBean = getSessionBean(request);   for (int i = 0; i < properties.length; i++) {   System.out.println(properties[i].toString());   if (properties[i].getProperty().getName().equals("DEPT_NOParam")) {   String value = (String)properties[i].getValue();   if (value.equals("*"))   sessionBean.setSqlString("select * from department");   else   sessionBean.setSqlString(   "select * from department where deptno='"   + value   + "'");   }   }   }  
  9. Right-click anywhere in the Java editor and select Source -> Organize Imports to include the missing import statements. In the Organize Imports dialog, choose to import the com.ibm.wps.pb.property.Property class.

    Figure 13-19. The Organize Imports dialog.

    graphics/13fig19.jpg

  10. Save and close the HRPortlet.java file.

13.5.3 Running the cooperative portlets

Execute the following steps to run the cooperative portlets scenario:

  1. To run a project in the WebSphere Studio Site Developer Test Environment, it is necessary to add the portlet project to the test environment. You can use a previously created test server or you can create a new server. Follow these steps:

    1. Click the Server Configuration tab (on the navigator panel).

    2. Expand the Servers tree.

    3. Right-click WebSphere Portal V5.0 Test Environment or Test Environment .

    4. If needed, click Add -> DefaultEAR to add your project to the Test Environment.

    Figure 13-20. Adding a project to the Test Environment

    graphics/13fig20.jpg

  2. If the Cloudscape sample database has not been populated , run the batch file to populate the test database to be used in this scenario. Click c:\LabFiles\Cloudscape\CreateCloudTable.bat to do this.

    Note : The sample scenario included in this chapter requires that you download the sample code available as additional materials. See Appendix C, "Additional material" on page 543.

    Figure 13-21. Populating test database

    graphics/13fig21.gif

  3. Next, click the J2EE Navigator tab to see your project again.

  4. Right-click HRPortlet . Then click Run on Server . This will load your project into the Test Environment so that you can view it in the WebSphere Studio Site Developer internal Web browser. It may take a minute or two for this process to complete.

  5. You will now see your newly created portlets project running in the Web browser.

  6. Switch to Edit mode in HRPortlet (c2a source portlet).

  7. Enter the following information and click Submit .

    - Database: jdbc:db2j:C:\LabFiles\Cloudscape\WSSAMPLE .

    - User: db2admin

    - Password: db2admin

    - SQL: select * from jobs

    Figure 13-22. HRPortlet portlet in Edit mode

    graphics/13fig22.gif

  8. The HRPortlet now displays the jobs table, including a cooperative portlet menu in the DEPT_NO column. Before you can use this menu, you have to configure the data source in DepartmentDetailsPortlet.

    Figure 13-23. HRPortlet displays a cooperative menu in the DEPT_NO column

    graphics/13fig23.jpg

  9. Switch to Edit mode in DepartmentDetailsPortlet (c2a target portlet).

  10. Enter the following information and click Submit . It is not necessary to enter an SQL command here, because it is built during the processing of the cooperative menu.

    - Database: jdbc:db2j:C:\LabFiles\Cloudscape\WSSAMPLE

    - User: db2admin

    - Password: db2admin

    Note : There is no need to enter an SQL statement (optional).

  11. In the source portlet View mode, click the c2a icon in the DEPT_NO column, for example before C01 or A00.

  12. Click the c2a menu again to send the changed property to C2A.

Figure 13-24. Cooperative portlets

graphics/13fig24.gif

13.5.4 Wire portlets

In this section, you will wire the source and target portlets for C2A. Follow these steps:

  1. Select one of the C2A menu items but this time press the Ctrl key during the selection.

  2. A new dialog opens asking whether to Automate the action in future . Select Yes .

    Figure 13-25. Pressing Ctrl key during menu selection to create a wire

    graphics/13fig25.gif

  3. Click Yes to activate the wire.

  4. Try other departments again.

  5. Press the Ctrl key again when using C2A to disable the wire.

Note : Wiring can also be accomplished by using the C2A wiring tool.

13.5.5 Enabling HRPortlet for programmatic source C2A

In this section, you will be required to enhance the source C2A portlet application to implement the programmatic approach. Figure 13-26 on page 441 illustrates the source cooperative portlet for this sample scenario.

Figure 13-26. Cooperative portlets - programmatic sample scenario (source portlet)

graphics/13fig26.gif

You will update HRPortlet to change property data using the programmatic approach. You will also insert a button in the HRPortlet page to offer the display of department details in the DepartmentDetailsPortlet (C2A target portlet).

Notice that in this portlet, you will need to register the DEPT_NO property using the Property.OUT direction. In addition, the update of the property will be done in the actionPerformed method.

Note : For this scenario, you may want to copy and paste the code provided in the folder c:\LabFiles\AdvC2A\snippets\HRPortlet(source)\. The sample scenario included in this chapter requires that you download the sample code available as additional materials. See Appendix C, "Additional material" on page 543.

Proceed as follows to update the HRPortlet:

  1. Open the file HRPortlet/Java Source/hrportlet/HRPortlet.java.

  2. Update the class definition so it implements the EventPhaseListener interface:

     public class HRPortlet extends PortletAdapter implements EventPhaseListener, ActionListener { 

    Note : The beginEventPhase method of the EventPhaseListener interface is used to register the output properties; this is because it is only possible to register and unregister properties during the event phase.

  3. At the beginning of this class, insert two new class attributes so the code looks like this:

     public class HRPortlet extends PortletAdapter implements EventPhaseListener, ActionListener { PropertyBrokerService pbService; PortletConfig portletConfig; 

    Note : pbService is an interface to the property broker and portletConfig stores the portlet configuration.

  4. Change the init method so it looks as follows:

     public void init(PortletConfig portletConfig) throws   UnavailableException {         super.init(portletConfig);         this.portletConfig=portletConfig;      } 
  5. Add the following initConcrete method to initialize the property broker attribute.

    Example 13-8. The initConcrete method initializes the property broker attribute
      public void initConcrete(PortletSettings settings)   throws UnavailableException {   try {   pbService =   (PropertyBrokerService) getPortletConfig()   .getContext()   .getService(   PropertyBrokerService.class);   } catch (PortletServiceUnavailableException e) {   throw new UnavailableException("Could not locate   PropertyBrokerService.");   } catch (PortletServiceNotFoundException e) {   throw new UnavailableException("Could not locate   PropertyBrokerService.");   }   }  
  6. For simplicity, you will now add a new method called registerPropertiesIfNecessary to register the property we are interested in.

    Example 13-9. Register a new output property
      private void registerPropertiesIfNecessary(PortletRequest request)   throws PropertyBrokerServiceException {   PortletSettings settings = request.getPortletSettings();   Property[] properties = pbService.getProperties(request, settings);   if (properties == null  properties.length == 0) {   PortletContext context = getPortletConfig().getContext();   //not registered, register now   properties = new Property[1];   properties[0] = PropertyFactory.createProperty(settings);   properties[0].setName("DEPT_NOParam");   properties[0].setDirection(Property.OUT);   properties[0].setType("DEPT_NO");   properties[0].setNamespace("http://www.ibm.com/wps/c2a/examples/hrdetails");   properties[0].setTitleKey("HRDetails.Department");   properties[0].setDescriptionKey(   "Display department details");   pbService.registerProperties(request, settings, properties);   }   }  
  7. Implement the eventPhaseListener interface by inserting the beginEventPhase and endEventPhase methods, which are callback methods invoked during the event phase. The beginEventPhase invokes the method to register the output property DEPT_NOParam.

    Note : The endEventPhase method does nothing in this scenario but needs to be included in the interface.

      public void beginEventPhase(PortletRequest request) {   try {   registerPropertiesIfNecessary(request);   }   catch (Throwable e) {   e.printStackTrace();   }   }   public void endEventPhase(PortletRequest request) {   }  
  8. For simplicity, insert a new method with name changeProperty to notify the broker about a changed property value. This method uses the changedProperties method to notify property changes.

    Example 13-11. Notify the broker of a property value change
      private void changeProperty(PortletRequest request, String value) {/   System.out.println("send data");   PortletSettings settings = request.getPortletSettings();   if (pbService != null) {   try {   Property p = PropertyFactory.createProperty(settings);   p.setName("DEPT_NOParam");   p.setDirection(Property.OUT);   p.setType("DEPT_NO");   p.setNamespace("http://www.ibm.com/wps/c2a/examples/hrdetails");   PropertyValue[] pva = new PropertyValue[1];   pva[0] = PropertyFactory.createPropertyValue(p, value);   pbService.changedProperties(request, getPortletConfig(), pva);   } catch (Exception e) {   e.printStackTrace();   }   }   }  
  9. At the end of the actionPerformed method, include the following code to invoke the internal changeProperty method and notify the output property change.

    Example 13-12. Invoke method to notify the property value change
      if (actionString.equals("DisplayAllDepartmentDetails")) {   this.changeProperty(request, "*")  ;  }  
  10. Right-click anywhere in the Java editor and select Source -> Organize Imports to include the missing import statements. In the Organize Imports dialog, choose to import the com.ibm.wps.pb.property.Property class.

    Figure 13-27. The Organize Imports dialog

    graphics/13fig27.jpg

  11. Save and close the updated source cooperative portlet HRPortlet.java file.

  12. Update the HRPortletView.jsp to insert a new action button offering to display department details from all departments. Open the HRPortletView.jsp file and insert the following code at the end of the file and before the </BODY> tag.

    Note : The action name is DisplayAllDepartmentDetails and it will be processed in the actionPerformed method. See Example 13-13 on page 445.

    Example 13-13. New button to offer display of all department details
      <p align="center">   <FORM method="post"   action="<portletAPI:createReturnURI><portletAPI:URIAction   name='DisplayAllDepartmentDetails'/></portletAPI:createReturnURI>"">   <INPUT type="submit" name="submit" value="Display all department details">   </FORM>   </p>  
  13. Optionally, preview the JSP and see the new button.

  14. Save and close the file.

13.5.6 Running the programmatic source portlet

Follow these steps to run the updated scenario:

  1. Right-click HRPortlet and select Run on Server .

  2. Click the Display all department details button. The DepartmentDetailsPortlet displays all department details, as shown in Figure 13-28.

    Figure 13-28. Department Details Portlet displays details from all departments

    graphics/13fig28.gif

  3. A portlet wire is required. Try the Display all department details button before and after adding the portlet wire.

    Important:

    The method changedProperties() will only trigger events on wired targets. If no wires exist for the published properties, it has no effect.

 < Day Day Up > 


IBM WebSphere Portal V5 A Guide for Portlet Application Development
IBM Websphere Portal V5: A Guide for Portlet Application Development
ISBN: 0738498513
EAN: 2147483647
Year: 2004
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net