Sie sind auf Seite 1von 38

A Contribute White Paper September 2010

Interportlet communication with ADF portlets

Interportlet Communication with ADF portlets

1. Table of Contents
2. 3. 4. 4.1 4.2 Introduction..................................................................................................................................... 3 Prerequisites.................................................................................................................................... 3 Building the portlets ........................................................................................................................ 4 Creating the Portlet Application.................................................................................................. 4 Creating the Sending Portlets.................................................................................................. 5 Creating the portlet ......................................................................................................... 5 What just happened ...................................................................................................... 11 Building the SendingPortlet........................................................................................... 12

4.2.1 4.2.2 4.2.3 4.3

Creating the Receiving Portlet............................................................................................... 15 Creating the portlet ....................................................................................................... 15 Building the portlet ....................................................................................................... 16

4.3.1 4.3.2 4.4

Deploying the provider.......................................................................................................... 18 Creating a deployment Profile ...................................................................................... 18 Setting the Context root of the provider....................................................................... 19 Deploying the provider .................................................................................................. 19

4.4.1 4.4.2 4.4.3 5.

Creating the Consuming application ............................................................................................. 22 5.1 5.2 Oracle Composer ................................................................................................................... 22 Creating the application ........................................................................................................ 22 Creating the page .......................................................................................................... 23 Register the producer to the application ...................................................................... 27 Adding portlets to the page........................................................................................... 28

5.2.1 5.2.2 5.2.3 5.3

Wiring portlets together at runtime ..................................................................................... 30 Testing the portlets ....................................................................................................... 32

5.3.1 5.4

Wiring portlets together at design time................................................................................ 33 Creating design.jspx....................................................................................................... 33 Page Definitions............................................................................................................. 34 Finalizing design.jsxp ..................................................................................................... 37

5.4.1 5.4.2 5.4.3 6. 7.

Final thoughts ................................................................................................................................ 38 Code from the sending portlet does not seem to be invoked ...................................................... 38

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

2. Introduction
In a modern Enterprise 2.0 portal you will find the need to let 2 portlets communicate with each other. Because you are working with webcenter, the change is big you also are creating ADF portlets instead of normal JSP portlets.

Webcenter currently does not implement the JSR286 standard which describes how to communicate between portlets. Instead of JSR286, Oracle has chosen to implement their own system to build interportlet communication (IPC) using an extension on the portlet.xml called oracle-portlet.xml. In this white paper I will describe how to build ADF portlets and how to wire them together using the Oracle extension on JSR 168.

3. Prerequisites
In order to build the examples from this white paper you will need the latest JDeveloper (version 11.1.1.3 at the moment of writing) with the webcenter extension installed. You can check if you have the webcenter extension installed from the about window in the help menu. Look in the extensions tab for webcenter extensions. If you have not yet installed the extensions you can download them from within JDeveloper. In the help menu open the check for updates window. When you have the list of available downloads, look for webcenter and make sure they are checked. JDeveloper will then download the extensions and install them. After the installation process you will need to restart JDeveloper.

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

4. Building the portlets


In this section I will give a step by step manual on how to build ADF portlets that can be wired together. In each part I will also give additional information on what really happens so you understand the mechanics behind portlets.

4.1 Creating the Portlet Application


From JDeveloper create a new Portlet Producing application.

Picture 1: Create Portlet Producing application

In the next window name the application IPCPortlets or something you like. Choose a directory for the portlet and a default prefix for packages that will be created. Click finish. As you can see you will have an application with a single project called Portlets:

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

Picture 2: IPCPortlet Application

This is the project were we will build the portlets.

4.2 Creating the Sending Portlets


After the application has been created, we will create a first portlet. This portlet will be the sending portlet. We will enable it for IPC and add a parameter so it can communicate with another portlet. After the portlet has been created we will add some custom code to set the value of the parameter.

4.2.1

Creating the portlet

In JDeveloper right click the Portlet project and select New. This will open the new dialog window. From the web tier, select Portlets. In the right hand side, select Standards-based Java Portlet (JSR168):

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

Picture 3: Create JSR168 portlet

When you click the OK button it will open the Create JSR168 Java Portlet dialog window. This wizard is an easy way to create portlet. Using this interface we can enter all the necessary data for our portlet.

Step 1: General Portlet Information In this window we can enter the general information like the portlet name, class and package. Make sure the Enable inter-portlet communication using Oracle WSRP V2 extensions is enabled. If you forget this checkbox, you will not be able to add parameter to communicate with other portlet. We will call this portlet SendingPortlet. The class of the portlet can also be SendingPortlet. The default package can stay unchanged. Off course, check the Enable inter-portlet communication checkbox:

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

Picture 4: General portlet information

As you notice, from the moment you enable the inter portlet communication. We will have an additional step in the wizard called Portlet Navigation Parameters. In that step we will add the parameters to wire portlets together.

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

Step 2: Additional Portlet Information In the next step we can add additional portlet information. By default the values will be copied from the portlet name we entered in step 1. No need to modify anything about that:

Picture 5: Additional portlet information

Step 3: Content types and Portlet Modes In this step we will need to tell JDeveloper we want to create ADF portlets instead of JSP portlets. This step is also intended to define the different portlet modes and content types supported by the portlet. By default JDeveloper will add the View and Edit mode. First select the View mode and make sure you also select Generate ADF-Faces JSPX. This is a very important step because otherwise we will not have an ADF portlet but a regular JSP portlet. Do the same for the edit mode:

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

Picture 6: Content types and portlet modes

Step 4: Customization Preferences In this step we can define preferences that the user can change using the edit mode. For this portlet we have no need in additional preferences so we can just click the next button. Step 5: Security Roles In this step you can map J2EE roles to the portlet so these are available inside the portlet. For this portlet there is no need to specify security roles. Step 6: Caching options In this step we can specify whether or not the portlet need to be cached and how long the caching should last. No need to specify caching for this portlet Step 7: Initialization parameters In this step we can add initialization parameters. We dont need them in this portlet so just click next.

Yannick Ongena | www.contribute.be

Interportlet Communication with ADF portlets

Step 8: Portlet Navigation Parameters This is again a very important step for our portlet. If you do not have this step, make sure you checked the Enable inter portlet communication as described in Step 1. Navigation parameters are the parameters we can use to wire portlets together. It is based upon the WSRP 2.0 standard. The WSRP1.0 standard does not support navigation parameters so when we use navigation parameters we must be sure we use the WSRP2.0 version but this will be discussed in more detail when we build the consuming application. In the wizard, click the Add button. Change the name of the parameter from name0 to param1. The name of the parameter is important. You can set it to anything you like but we will need the name in our code to set the parameter. The label and hint are not really used here.

Picture 7: Portlet navigation parameters

Now we have done everything needed to create the portlet. Click the Finish button and the portlet will be created.

Yannick Ongena | www.contribute.be

10

Interportlet Communication with ADF portlets

4.2.2

What just happened

As you might noticed, JDeveloper created a lot of files for you. Portlet.xml One of the most important files is the portlet.xml. You can find it in the Web content/WEB-INF folder. This is a file needed from the JSR168 standard to describe the portlet. As you can see, this file contains most of the information we entered from the wizard. It contains the portlet-name, portletclass. Which modes there are available. As you can see, from the <support> part, only the edit mode is available. This is because the view mode is mandatory and we dont need to add it as a supported mode. JDeveloper also added the init-param for the JSPX page for each mode. Oracle-portlet.xml This file can also be found in the WEB-INF folder. It contains the extensions to provide inter portlet communication. When you open it you will see that there is an entry for the SendingPortlet portlet. The name from the Oracle-portlet.xml must match the portlet-name from the portlet.xml. If these are not the same, the extension will not work. The most important part of this file is the navigation-parameters part:
<navigation-parameters> <name>param1</name> <type xmlns:xsd="http://www.w3.org/2001/XMLSchema">xsd:string</type> <label xml:lang="en-US">label0</label> <hint xml:lang="en-US">hint0</hint> </navigation-parameters>

View.jspx and edit.jspx From the Web Content/SendingPortlet/html folder you will find the view.jspx and the edit.jspx. These pages are the actual pages we can build our portlet on. The view.jspx is the page that will be shown in the view mode and the edit.jspx in the edit mode. JDeveloper already created the edit.jspx for us based upon the preference parameters from step 4. For each preference we will add their, JDeveloper will add a field so we can modify them in the edit mode. SendingPortlet.java From the Application Source/portlet folder we will have the SendingPortlet.java file. This is the actual portlet class. Normally we will not need to edit this file. As you can see, this class extends the ADFBridgePortlet. As you also might see, the SendingPortlet class is the one defined in the portlet.xml at the portlet-class section. Yannick Ongena | www.contribute.be 11

Interportlet Communication with ADF portlets

SendingPortletBacking.java In the application source/portlet.backing folder you will notice the SendingPortletBacking.java. This is the backing bean for our portlet. JDeveloper also added an entry in the faces-config.xml for this file:
<managed-bean> <managed-bean-name>sendingportletbacking</managed-bean-name> <managed-bean-class>portlet.backing.SendingPortletBacking</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>

4.2.3

Building the SendingPortlet

JDeveloper created a nice skeleton for our portlet but we still need to build it. Every file is available for us. We only need to add some code and design the view.jspx. Our SendingPortlet will have a single textfield were we can enter a value. When we press a submit button, the value of that textfield will be stored in the navigation parameter. This is the only functionality needed. We dont need to add code wire portlets together. The wiring of the portlets always happens in the consuming portlet. The portlet only need to provide the events for the navigation parameters. View.jspx 1) In JDeveloper double click the view.jspx file from the Web content/SendingPortlet/html folder. 2) From the component palette on your right, find the Panel Form Layout and drop it on the page. 3) Then find the InputText (the ADF Faces inputtext, not the JSF.HTML) and drop it inside the Panel Form layout. 4) Change the label of the inputText to Parameter. 5) Change the value of the inputText to: #{sendingportletbacking.parameter} 6) Drop a commandButton in the footer of the Panel Form layout Your page should look something like this:

Yannick Ongena | www.contribute.be

12

Interportlet Communication with ADF portlets

Dont bother if there is a red border around the textfield. This is because we havent added the getParameter and setParameter function in our backing bean. We will be doing that in a moment. This is the code from the view.jspx in case you have any problem:
<?xml version='1.0' encoding='windows-1252'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"> <jsp:directive.page contentType="text/html;charset=windows-1252"/>

<f:view> <af:document> <af:form> <af:panelFormLayout id="pfl1"> <f:facet name="footer"> <af:commandButton text="Submit" id="cb1"/> </f:facet> <af:inputText label="Parameter" id="it1" value="#{sendingportletbacking.parameter}"/> </af:panelFormLayout> </af:form> </af:document> </f:view> </jsp:root>

SendingPortletBacking.java We still need to write the most important part of our code: writing the navigation-parameter. Open the SendingPortletBacking.java from the Application Source/portlet.backing folder. At the end of the class, add following code:

Yannick Ongena | www.contribute.be

13

Interportlet Communication with ADF portlets

private String param; public void setParameter(String value) { param = value; System.out.println("Set param"); ActionResponse res = (ActionResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); res.setRenderParameter("param1", value); }

public String getParameter() { return param; }

The setParameter will be called when we press the submit button from our form in the view.jspx because we have bound the value of the inputText to that property in our backing bean. From the setter we need to set the navigation parameter. It does not sound logic but navigation parameters are stored in the RenderParameters of the ActionResponse of the portlet. We can get the ActionResponse from the externalContext of our FacesContext. One very important thing to know is that the ActionResponse is only available with a full page refresh. This mean that our submit button can not have the partialSubmit property to true or the inputText can not have the autoSubmit to true because if you do, you will get errors because the ActionResponse is not available during a partial page refresh. The setRenderParameter takes a value pair as a parameter. The first parameter is the name of the parameter. This one must match the name of the navigation-parameter from the oracle-portlet.xml. The second parameter is the value of the parameter. In our case it is the value we entered in the inputText.

This portlet should now be ready. We have created the view.jspx so we can enter the value of the parameter and we have written to code to set the navigation parameter. Our next step is to build the portlet that will receive the value of the parameter.

Yannick Ongena | www.contribute.be

14

Interportlet Communication with ADF portlets

4.3 Creating the Receiving Portlet


4.3.1 Creating the portlet

Creating the Receiving portlet is similar to building the SendingPortlet. From JDeveloper right click on the Portlets portject and select New from the menu. From the Web tier select Portlets and select Standards-based Java portlet. Step 1: General Portlet information Name: ReceivingPortlet Class: ReceivingPortlet Package: portlet Make sure you check the Enable inter portlet communication checkbox. Step 2: Additional Portlet information Dont change anything here Step 3: Content types and portlet modes Select view and select generate ADF-Faces JSPX from the right hand side TO the same for edit. Step 4: Customization preferences Dont change anything here Step 5: Security Role Dont change anything here Step 6: Caching options: Dont change anything here Step 7: Initialization parameters Dont change anything here Step 8: Portlet Navigation Parameters If you dont see this step, make sure you have enabled the inter portlet communication from step 1. In this step we will add the parameter that we will use to receive the parameter from the other portlet. Click the Add button and change the name of the parameter to receivingParam. Notice that you can

Yannick Ongena | www.contribute.be

15

Interportlet Communication with ADF portlets

chose any name you want but you will need the name in the code later on to get the value from the parameter map. So if you change the name here, make sure you use that name in the code. After the parameter has been added, you can press the Finish button. The same files as described in 3.2.2 are created and updated. Oracle-portlet.xml and portlet.xml are updated. You will see an additional entry for the receivingPortlet. You will also see that there is a view.jspx and an edit.jspx file. A backing bean is also created for the receiving portlet and that will be used to write our code to retrieve the parameter. 4.3.2 Building the portlet

Like in the sendingPortlet we need to build the view.jspx and add some code to the backing bean. View.jspx In JDeveloper double click on view.jspx in the Web Content/ReceivingPortlet/html folder. Add a Panel Form Layout were you add an outputText. Change the value of the outputText to #{receivingportletbacking.parameter} This is the complete code of the view.jspx for the receivingPortlet:
<?xml version='1.0' encoding='windows-1252'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"> <jsp:directive.page contentType="text/html;charset=windows-1252"/> <f:view> <af:document> <af:form> <af:panelFormLayout id="pfl1"> <f:facet name="footer"/> Value: <af:outputText value="#{receivingportletbacking.parameter}" id="ot1"/> </af:panelFormLayout> </af:form> </af:document> </f:view> </jsp:root>

Yannick Ongena | www.contribute.be

16

Interportlet Communication with ADF portlets

ReceivingPortletBacking.java In JDeveloper double click on receivingPortletBacking.java from the Application source/portlet.Backing folder. Add following code to the end of the class:
public String getParameter() { PortletRequest req = (PortletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest(); System.out.println("Getting param"); return req.getParameter("receiveParam"); }

You can access the navigation parameters from the parameter map from the PortletRequest. The PortletRequest is available from the externalContext from the FacesContext. The getParameter function will take a single parameter being the name of the parameter you want to read. Make sure that this must be the same as provided in the oracle-portlet.xml.

Now we have build the 2 portlets. As you might notice, we havent wired the portlets together. We just have provided a way to set a parameter and in antoher portlet, get the value of a parameter. We havent provided a link between those portlets. The link between portlets is made from a consuming portlet which we will be building in a moment. We first need to deploy our portlets so they are available to our consuming application.

Yannick Ongena | www.contribute.be

17

Interportlet Communication with ADF portlets

4.4 Deploying the provider


If you are used to ADF application you can easily test your application by right clicking a JSPX page and select run. Portlets, however are not that easily to test. Portlets are not standalone but need to be consumed in another application. Therefore we cant just run our portlet. We need to deploy it to the integrated weblogic server or to a standalone server. In this white paper we will use the integrated server of JDeveloper. 4.4.1 Creating a deployment Profile

In order to deploy our portlets we first need to create a deployment profile. From JDeveloper, right click on the Portlet project and select New. Under General select Deployment Profile and from the list on the right hand side select War file:

Picture 8: Create WAR file

Give the profile a name for example IPCPortlets. The next window provides the information about the profile. You dont need to change anything about it so just press the OK button.

Yannick Ongena | www.contribute.be

18

Interportlet Communication with ADF portlets

After that you will see the project properties window. You can also change the URL for the provider. The default one that JDeveloper creates is a large one and not that user friendly so we are going to change it. 4.4.2 Setting the Context root of the provider

From the left hand side select Java EE Application. The url that will be uses is the one entered in Java EE Web Context Root. For example we can enter IPCPortlets. When we deploy the application, the provider will be available thru that URL.

Picture 9: Setting Context Root

4.4.3

Deploying the provider

After the deployment profile has been created and the context root has been set, we can finally deploy the provider. Make sure the integrated weblogic server is running. You can run it from the Run menu and select Start server instance.

Yannick Ongena | www.contribute.be

19

Interportlet Communication with ADF portlets

If its the first time you start the integrated server, it can take up to 10 minutes because the domain needs to be created and the webcenter extension needs to be installed on it. You can see that the startup is finished when you see something like this in your server log:
<Server started in RUNNING mode> IntegratedWebLogicServer startup time: 83397 ms. IntegratedWebLogicServer started.

In JDeveloper right click your Portlets project and select Deploy, and then select your deployment profile. From the deployment window select Deploy to Application Server and select IntegratedWebLogicServer. Press finish. You will see following popup:

Picture 10: Deploy a portlet

You see this message because JDeveloper has detected that you are deploying portlets. Webcenter exposes their portlets using WSRP (webservice for remote portlets). Therefore a lot of extra files need to be created. All the webservice descriptors need to be created. That would be a lot of work if we would create them manually. By selecting Yes in this popup, JDeveloper will create all those file for us so our provider is available using WSRP. When you click the OK button, the deployment will start. IN your log window you will see the deploy tab were you can follow the deployment process. When you see following message, the deployment has been completed:

Yannick Ongena | www.contribute.be

20

Interportlet Communication with ADF portlets

[02:43:10 PM] The following URL context root(s) were defined and can be used as a starting point to test your application: [02:43:10 PM] http://localhost:7101/IPCPortlets-Portlets [02:43:10 PM] Elapsed time for deployment: 19 seconds [02:43:10 PM] ---- Deployment finished. ----

As you see, there is a starting point available for your provider. Copy/paste this link into a browser. You will see following page:

At the bottom you have 2 links. One for the WSRP v1 WSDL and one for WSRP v2. Click on the WSRP v2 WSDL link and you will the WSDL for our provider. We will need that link in our consuming application so keep your browser open on the WSRP v2 WSDL.

Yannick Ongena | www.contribute.be

21

Interportlet Communication with ADF portlets

5. Creating the Consuming application


After we have deployed our portlets we need an application that will consume those portlets. The consuming application is a very important part of building interportlet communication. It is these applications that will wire portlets together. In webcenter there is no way to make portlets communicate without configuring the consuming application. We need to define which portlets are communicating which each other.

5.1 Oracle Composer


With the webcenter framework we have a component called the Composer to do runtime changes. The composer is the edit mode of a page. We can change the layout of the page, add portlets or other components. The composer also let us change some page properties like the title and it will let to create page parameters at runtime. The composer component is the heart of our webcenter application.

5.2 Creating the application


In order to use the composer component we need to create a WebCenter application. In JDeveloper open the File menu and select New so the new gallery dialog opens. From the general part, select Applications. In the right hand side select Webcenter application.

Picture 11: Webcenter application

Yannick Ongena | www.contribute.be

22

Interportlet Communication with ADF portlets

From the New application window, give the application a name like ConsumingIPC. Press finish in order to create the application. The application will automatically import all the needed libraries for webcenter. We need to create a page that will have runtime editor capabilities. 5.2.1 Creating the page

From JDeveloper right click the ViewController project and select New. From the New gallery in the Web Tier part select JSF. In the right hand side select JSPX page:

Picture 12: New JSPX page

Name the page index.jspx. For now we are selecting a prebuilt template from JDeveloper so we have a basic layout. Select Page Template and select Oracle Three Column Layout from the dropdownlist:

Yannick Ongena | www.contribute.be

23

Interportlet Communication with ADF portlets

Picture 13: Creating index.jspx

When clicking OK, the page will be created and JDeveloper will open the page in design view. Now we can add the Composer component. From the Component Palette, select Oracle Composer from the dropdown list:

Picture 14: Oracle composer

Yannick Ongena | www.contribute.be

24

Interportlet Communication with ADF portlets

A first thing you always need to add to a page with runtime capabilities is the Page Customizations. This component defines a region within your page that can be changed at runtime using the composer. If you do not add this component, your page will not render so its very important you never forget to add this component. Drop the Page Customization component to the center fragment of the page. Its the center part of the 3 part page. After this we will also add a Layout Customizable. Drop the Layout customizable inside the Page Customizable. A last thing we need, is a Change mode button so we change from view mode to edit mode. The edit mode will render the composer component and give us the possibility to add portlets. Drop the Change mode button in the header section (just next to the oracle logo). Your page should now look something like this:

Below you can find the complete code of the page:

Yannick Ongena | www.contribute.be

25

Interportlet Communication with ADF portlets

<?xml version='1.0' encoding='UTF-8'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:af="http://xmlns.oracle.com/adf/faces/rich" xmlns:pe="http://xmlns.oracle.com/adf/pageeditor" xmlns:cust="http://xmlns.oracle.com/adf/faces/customizable"> <jsp:directive.page contentType="text/html;charset=UTF-8"/> <f:view> <af:document id="d1"> <af:form id="f1"> <af:pageTemplate viewId="/oracle/templates/threeColumnTemplate.jspx" id="pt1"> <f:facet name="center"> <pe:pageCustomizable id="pageCustomizable1"> <cust:panelCustomizable id="panelCustomizable1" layout="scroll"> <pe:layoutCustomizable id="layoutCustomizable1"> <cust:panelCustomizable id="panelCustomizable2"/> <f:facet name="contentA"> <cust:panelCustomizable id="panelCustomizable3"/> </f:facet> <f:facet name="contentB"> <cust:panelCustomizable id="panelCustomizable4"/> </f:facet> </pe:layoutCustomizable> </cust:panelCustomizable> <f:facet name="editor"> <pe:pageEditorPanel id="pep1"/> </f:facet> </pe:pageCustomizable> </f:facet>

Yannick Ongena | www.contribute.be

26

Interportlet Communication with ADF portlets

<f:facet name="header"> <pe:changeModeButton id="cmb1"/> </f:facet> <f:facet name="end"/> <f:facet name="start"/> <f:facet name="branding"/> <f:facet name="copyright"/> <f:facet name="status"/> </af:pageTemplate> </af:form> </af:document> </f:view> </jsp:root>

5.2.2

Register the producer to the application

Now that we have added runtime customizations to our page, we still need to register our provider we build in section 3. In webcenter we need to register a WSRP producer. This is a standard that describes how to access portlets using webservices. In JDeveloper in the Application Resources part, right click the connections folder. From the popup menu select WSRP producer. In the popup, give the producer a name for example IPC. In the next window we need to provide the WSRP URL. Remember the WSRP v2 WSDL we looked at in the end of section 3? The url looks something like this: http://localhost:7101/IPCPortlets-Portlets/portlets/wsrp2?WSDL It is that URL that we need to enter in the WSDL URL. Make sure you have selected the WSRP V2 URL because if you use the V1, you wont be able to wire portlets together. After that JDeveloper will get the WSDL and analyze it. This can take a few seconds. After that you just can press the Finish button. If everything goes well, you should see the producer in the Application Resources and when you open it, you should be able to see what portlets the producer holds: Yannick Ongena | www.contribute.be 27

Interportlet Communication with ADF portlets

Picture 15: Adding producer

This is it. The application is finished. We will add and wire the portlets together at runtime so now is a good time to run the page. In the ViewController/Web Content folder right click index.jspx and select run. 5.2.3 Adding portlets to the page

When your page has been loaded into your browser, you will see an empty page. When you click the edit button, the composer component will be loaded and we can start editing the page. When in editing mode, press the Add Content button from the first region:

Yannick Ongena | www.contribute.be

28

Interportlet Communication with ADF portlets

Picture 16: Add content

When you press that button, the Resource Catalog will open. Here we can select which component we want to add. As you can see, we have a section for the Portlet Producers. Open it and you will see the provider we registered in JDeveloper. Every producer you register during design time in JDeveloper, will be available at runtime this way. Open the IPC producer and add the SendingPortlet

Picture 17: Resource Catalog

When we press the add button, you will see that the portlet will appear in the region. Close the resource catalog and do the same in the second region but add the ReceivingPortlet. After this, your page should look something like this:

Picture 18: Portlets added

Yannick Ongena | www.contribute.be

29

Interportlet Communication with ADF portlets

5.3 Wiring portlets together at runtime


Now that we have added the portlets, we only need to wire them together. First we need to find out the ID of our sending portlet. This can be done using by going to the properties of the sendingPortlet. You can open the properties by clicking the pencil button on the portlet:

Picture 19: Potlet properties

In the Display Options you will find a field Id. It starts with portlet and then a large number. This is the Id (including the portlet part). In my case, the portlet ID of the SendingPortlet is: portlet2987078008 as you can see from the image below:

Picture 20: Portlet ID

Yannick Ongena | www.contribute.be

30

Interportlet Communication with ADF portlets

We need to copy that id because we need it later on. Now we need to tell the receiving portlet it needs to listen to the sendingPortlet and we also need to link the receiving parameter to the sending parameter. Open the properties for the sending portlet. From the Parameters tab you will see the Receive Param which we have defined during the creation of the receivingPortlet. Click on the icon on the right of the field and select Expression builder. This will open the expression builder so we easily select the parameter. From the expression builder you notice that in the first section the page parameter is selected. From the second dropdown list we need to select the correct parameter. You need to select the parameter from the sendingPortlet. The IDs of those parameters are build with the ID of the portlet, and underscore and then the name of the parameter. In my case, the ID of the sendingPortlet was portlet2987078008 so the page parameter of his parameter will be named portlet2987078008_param1. You must select the one that correspond with the parameter of your sendingPortlet. Thats why we need to know the ID of the portlet.

Picture 21: Expression builder

Click OK to close the Expression builder. Now we bound the receiveParam to the param1 of the sendingPortlet.

The only thing we still need to do is tell the receivingPortlet it will listen to the sendingPortlet for changes. If we dont do that, the portlet will not be notified when the sendingPortlet changes his value. This must be done in the Display Options tab of the receivingPortlet. In regular ADF application. Components can have a partialTrigger. When you set the partialTrigger, the component will listen to the component you enter as a partialTrigger. If the state changes, the component will also render itself again. The same principal goes here. We need to set the partialTrigger of the receivingPortlet to the sendingPortlet so the receivingPortlet listens to changes of the sendingPortlet. Yannick Ongena | www.contribute.be 31

Interportlet Communication with ADF portlets

In the display options tab we need to enter the ID of the sendingPortlet. Thats why we need to copy the ID from the Display Options tab from the SendingPortlet.

Picture 22: Display options ReceivingPortlet

The image above shows the Display Options tab of the ReceivingPortlet. As you can see I have pasted the ID of the sendingPortlet in the partialTrigger field. 5.3.1 Testing the portlets

We just wired the portlets together and they should be able to communicate which each other. Close the composer component by clicking the Close button in the top right corner. This will bring you back to the normal view mode of the page. Now you can enter a value in the sendingPortlet and press the submit button. If everything goes well you should see the value of the parameter in the receivingPortlet.

Picture 23:Portlets communicating

Yannick Ongena | www.contribute.be

32

Interportlet Communication with ADF portlets

5.4 Wiring portlets together at design time


In 5.3 we discussed how we can wire portlets together at runtime. JDeveloper lets you also add portlets at runtime. This way you dont need to have a Page Customizable component on your page. You also dont need the composer component when adding portlets at design time. 5.4.1 Creating design.jspx

We will create a new page were we will add the portlets at design time. Then I will discuss how to wire the portlets together just the way we did at runtime so they can communicate together. As you will notice, the idea of wiring the portlets is the same. You bind the parameter of one portlets to the other and set the partialTrigger of one portlet. In JDeveloper right click the ViewController project and select new. From the New Gallery select JSF in the Web tier. From the right hand side select JSF Page. Call your new page design.jspx and select the Oracle three Column Layout:

Picture 24: design.jspx

Yannick Ongena | www.contribute.be

33

Interportlet Communication with ADF portlets

We already have registered the producer to the application. If you have not done that already, follow the steps in 5.5.2. Drag & drop the SendingPortlet from the producer to the center section of the page. After that, drop the receivingPortlet to the end section. Your page will look something like this:

Picture 25: design.jspx

5.4.2

Page Definitions

When you look at the source of desing.jspx you will notice that a portlet is added like this:
<adfp:portlet value="#{bindings.SendingPortlet1_1}" id="portlet1"/>

You notice that the value of the portlet is bound to the bindings object. We can take a look at the bindings by right clicking on the page and select Go to page definition. The page definition of design.jspx will look like this:

Yannick Ongena | www.contribute.be

34

Interportlet Communication with ADF portlets

Picture 26: Bindings of design.jspx

In the executables part we will find 2 entries for the portlets. The wiring of the portlets will take place here. We can not wire the portlets together using this view, we need to go to the source of the page definition. Right click on SendingPortlet1_1 and select Go to Source from the menu. Now we see the actual content of the page definition. You will see the entry for the portlet parameter. As you also might notice, for each portletparameter, their will be a page parameter corresponding to the portlet parameter. :
<variableIterator id="variables"> <variable Name="SendingPortlet1_1_param1" Type="java.lang.Object"/> <variable Name="ReceivingPortlet1_1_receiveParam" Type="java.lang.Object"/> </variableIterator>

In the portlet definition you will find a reference from the parameter to the page variable:
<parameters> <parameter name="param1" pageVariable="SendingPortlet1_1_param1"/> </parameters>

So the SendingParameter has a parameter called param1 and is bound to the page parameter called SendingPortlet1_1_param1. The receivingPortlet has a parameter called receiveParam and is bound to the page parameter ReceivingPortlet1_1_receiveParam. As we did with the portlets in runtime, we need to bind the parameter of the receivingPortlet to the parameter of the sendingPortlet. In the page definition, this is done by pointing the parameter of the receivingPortlet to the page parameter of the sendingPortlet. This is the portlet part of the receivingPortlet from the page definition: Yannick Ongena | www.contribute.be 35

Interportlet Communication with ADF portlets

<portlet id="ReceivingPortlet1_1" portletInstance="/oracle/adf/portlet/IPC/ap/Ei1283599080662default_e39060f3_012a_1000_8002_c0a82a01e32d" class="oracle.adf.model.portlet.binding.PortletBinding" retainPortletHeader="false" xmlns="http://xmlns.oracle.com/portlet/bindings"> <parameters> <parameter name="receiveParam" pageVariable="ReceivingPortlet1_1_receiveParam"/> </parameters> <events> <event name="ReceivingPortlet1_1_Event" eventType="ParametersChange"/> </events> </portlet>

We need to modify the parameter part and change the pageVariable. Replace ReceivingPortlet1_1_receiveParam by SendingPortlet1_1_param1 so the portlet part of the receivingPortlet looks like this now:
<portlet id="ReceivingPortlet1_1" portletInstance="/oracle/adf/portlet/IPC/ap/Ei1283599080662default_e39060f3_012a_1000_8002_c0a82a01e32d" class="oracle.adf.model.portlet.binding.PortletBinding" retainPortletHeader="false" xmlns="http://xmlns.oracle.com/portlet/bindings"> <parameters> <parameter name="receiveParam" pageVariable="SendingPortlet1_1_param1"/> </parameters> <events> <event name="ReceivingPortlet1_1_Event" eventType="ParametersChange"/> </events> </portlet>

Yannick Ongena | www.contribute.be

36

Interportlet Communication with ADF portlets

What we have done now is telling the portlet that the value of the parameter is stored in the sendingPortlet1_1param1 page variable instead of his own one. This way, when the sending portlet sets the value of his parameter, the receiving portlet will also get that value because it is pointing to the same page variable. The key idea of linking portlets is that the receiving portlet and sending portlet have at least one parameter that is bound to the same page parameter. 5.4.3 Finalizing design.jsxp

After we have linked the portlet parameter to together we only need to set the partialTrigger from the receivingPortlet. We can do this by selecting the ReceivingPortlet on the design.jsxp in JDeveloper. In the property Inspector you will find the PartialTrigger property. Click the icon next to the input field and click the Edit link. This will open a popup were you can select a component . In the left hand side you can select Portlet1 from the facet (center). After you have selected it, click the move to the right (>) button and press the OK button:

Picture 27:design.jspx: partial trigger

Now we have set the partialTrigger of the receivingPortlet. This way, the receiving portlet will refresh itself after the sendingPortlet has been refreshed or the submit button has been pressed in the

Yannick Ongena | www.contribute.be

37

Interportlet Communication with ADF portlets

sendingPortlet. Because the submit button will invoke the setParameter from the sendingPortlet, the navigation parameter will be set and the receivingPortlet will pick up the changes value. You can now test the application by right clicking the design.jspx and select Run from the popup menu.

6. Final thoughts
The key idea on wiring portlets together is having navigation parameter that are bound to the same page parameter. The portlet that must receive a parameter from another portlet must be bound to the same page parameter as the sending portlet. A second thing to do is to set the partialTrigger from the receiving portlet to the sending portlet so the receiving portlet will also refresh when the sending portlet has been changed. In design time you need to do this from the page definition while at runtime you need to go to edit mode and set the value of the receiving parameter to the page parameter of the sending portlet.

7. Code from the sending portlet does not seem to be invoked


It can happen that when you test the portlet and click the submit button, nothing happen. If so, check the server logs. If you copied the code from these examples you will have output telling you when the parameter has been set. In the SendingPortletBacking.java from the portlet project we have added following code in order to set the navigation parameter:
public void setParameter(String value) { param = value; System.out.println("Set param"); ActionResponse res = (ActionResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); res.setRenderParameter("param1", value); }

As you see I have added a System.out.println. Everytime you press the submit button, you must see the set param message in the server output. The receiving portlet has the same but it outputs the get param message. If your server log shows the get param message but never shows the setParam than you might think on changing your browser. At the moment of writing this white paper (September 2010), there is an issue with the event handler of commandButtons who do not use a partial submit. The code from these buttons are never invoked. It appears to be a browser issue. Test with another browser for example firefox or IE and see if the problem stil occurs. Perhaps this issue will get resolve in a later version of webcenter. Yannick Ongena | www.contribute.be 38