How GroupSpace Uses IPC to Create Interportlet Links
Pages: 1, 2, 3, 4

Portlet configuration

The portlet configuration file (the .portlet file) must be setup with the appropriate IPC and meta data to participate in this framework. The code described in this section must be added to each portlet's configuration file that could potentially respond to the various content links. For example, in GroupSpace, this code exists in the Issues portlet and the GroupNotes portlet config files, as well as in all other portlets that can handle displaying the details of the various GroupSpace content types.

A backingFile attribute must be added to the <netuix:portlet> element. The fully qualified class name of the backing file that was described in the Backing file section is set here.

backingFile="fully qualified class name of the backing file"

The following metadata entries are added as children to the <netuix:portlet> element:

<netuix:meta name="gsLink_contentType" content="ISSUE"/>
<netuix:meta name="gsLink_idAttrName" content="contentId"/>

This metadata provides the mechanism to add information to the portlet pertaining to what content type it can handle (see line 18 of the Backing file section sample code). It also indicates the name of the attribute that it expects the content id to be set (see line 15 of the Event handler section sample code). This content id is referring to the string that uniquely identifies the content whose link was initially clicked.

The following IPC-related elements are then added:

<netuix:handleCustomEvent eventLabel="linkClickedEvent" 
        event="gsLink_linkClickedEvent" onlyIfDisplayed="false">
    <netuix:invokeBackingFileMethod method="gsLink_evalLinkHandler"/>
</netuix:handleCustomEvent>
<netuix:handleCustomEvent eventLabel="showDetailsEvent" 
        event="gsLink_showDetailsEvent" onlyIfDisplayed="false"
        fromSelfInstanceOnly="true">
    <netuix:activatePage/>
    <netuix:invokePageFlowAction action="selectContent"/>
</netuix:handleCustomEvent>

Two event handlers are configured for the portlet. The first handler is executed when the linkClickedEvent is triggered at line 65 of the Backing file section sample code. This event indicates that a link has been clicked. The action is to invoke the backing file method gsLink_evalLinkHandler(), which is shown in the Event handler section sample code.

The next handler is executed when the showDetailsEvent is triggered at line 32 of the Event handler section sample code. This handler only responds to events generated from itself. So this will execute only in the portlet that has been determined capable of displaying information about the specific content type. This handler performs two actions. It first activates the current page that contains the portlet. It then invokes a specific pageflow action. In this case, the action is selectContent. The Pageflow action section provides more detail about this action.

For more information about these IPC event handlers, please see the Interportlet Communication documentation in the Portlet Development guide.

Pageflow action

It is the responsibility of the portlet developer to provide a designated action that will be executed when a link is clicked. This action will have access to the id that uniquely identifies the content via a request attribute. It was placed into the request as shown in line 22 of the sample code in the Event handler section. The attribute name for the id in the request is set in the portlet metadata as shown in the Portlet configuration section.

In the GroupSpace application, this action contains the logic required to obtain the specific content information from the underlying content management system based on the unique id. It then forwards to a JSP page that displays the detailed information about this content.

JSP tag

The final piece in this framework is the JSP tag. This tag makes it very easy for users to create these links on the various JSP pages in the portlets. This tag consists of two files: a JSP 2.0 .tag file, and a Java class file that acts as a separate helper class. The helper class separates the logic in building the URL so that it can be easily accessed outside of the JSP tag.

Here is code for the .tag file:

1  <%@ tag import="com.bea.apps.groupspace.taglib.content.ContentDetailsLinkHelper"%>
2
3  <%@ taglib uri="#" prefix="fmt"%>
4
5  <%@ attribute name="contentId" type="java.lang.String" required="true"%>
6  <%@ attribute name="contentType" type="java.lang.String" required="true"%>
7  <%@ attribute name="target" type="java.lang.String" required="false"%>
8  <%@ attribute name="replacePath" type="java.lang.String" required="false"%>
9
10 <fmt:bundle basename="com.bea.apps.groupspace.Common">
11   <fmt:message key="gsLink_baseMessage" var="gsLink_baseMessage"/>
12 </fmt:bundle>
13
14 <%
15     String contentId = (String) pageContext.getAttribute("contentId");
16     String contentType = (String) pageContext.getAttribute("contentType");
17     String target = (String) pageContext.getAttribute("target");
18     String replacePath = (String )pageContext.getAttribute("replacePath");
19
20     ContentDetailsLinkHelper helper = new ContentDetailsLinkHelper(request, 
21         response, contentId, contentType,
22         target, replacePath, null);
23 %>
24
25 <script type="text/javascript"&gt;
26     var gsLink_detailsEventHandled = 
27         <%=request.getAttribute("gsLink_detailsEventHandled")%>;
28     if (gsLink_detailsEventHandled == false) {
29         gsLink_linkNotHandledMessage = "${gsLink_baseMessage}";
30     }
31 </script>
32
33 <%
34     if (ContentDetailsLinkHelper.TARGET_OPENER.equals(target)) {
35 %>
36 <a href="#" 
37     onclick='javascript:window.opener.location.href="<%=helper.getHref()%>";
38     return false;'><jsp:doBody/></a>
39 <%
40     } else {
41 %>
42 <a href="<%=helper.getHref()%>"><jsp:doBody/></a>
43 <%
44     }
45 %>

The tag takes a total of four attributes, but only two are required. The content id and the content type are the only necessary attributes. An optional "target" attribute can be included if the URL should open in a specified target window. The "replacePath" attribute allows the user to replace the path part of the generated URL.

Lines 10 to 12 set a message that can be displayed when no portlet is found to handle the content type. This is handled in the JavaScript in lines 25 to 31.

Line 20 delegates to the helper class to generate the URL. Finally, lines 32 to 41 generate the HTML output for the link.

Here is code for the helper class:

1  public ContentDetailsLinkHelper(HttpServletRequest request, 
2                                  HttpServletResponse response,
3                                  String contentId, 
4                                  String contentType, 
5                                  String target, 
6                                  String replacePath, 
7                                  String linkText) {
8
9    try {
10     AsyncContentContext.push(request).setAsyncContentDisabled(true);
11             
12     this.contentId = contentId;
13     this.contentType = contentType;
14     this.target = target;
15     this.replacePath = replacePath;
16     this.linkText = linkText;
17
18     PagePresentationContext context = 
19         PagePresentationContext.getPagePresentationContext(request);
20     PortletPresentationContext portletContext = 
21         PortletPresentationContext.getPortletPresentationContext(request);
22            
23     PostbackURL contentDetailsLink_url = 
24         PostbackURL.createPostbackURL(request, response);
25     contentDetailsLink_url.addParameter("gsLink_linkClicked", 
26         "true");
27     contentDetailsLink_url.addParameter("gsLink_contentType", 
28         contentType);
29     contentDetailsLink_url.addParameter("gsLink_contentId", 
30         contentId);
31
32     if (context != null && context.getInstanceId() != null) {
33       contentDetailsLink_url.addParameter("gsLink_currentPageId", 
34           context.getInstanceId());
35     }
36            
37     if (portletContext != null && portletContext.getInstanceId() != null) {
38       contentDetailsLink_url.addParameter("gsLink_currentPortletId", 
39           portletContext.getInstanceId());
40     }
41             
42     if (replacePath != null) {
43       contentDetailsLink_url.setPath(replacePath);
44     }
45
46     href = contentDetailsLink_url.toString();
47
48   } finally {
49     AsyncContentContext.pop(request);
50   }
51 }
52
53 public String getHref() {
54   return href;
55 }

The constructor of this class handles the logic for creating the URL. Line 10 disables async content if the request was generated from a portlet that is using that configuration. This is important since the link framework relies on IPC. These URLs must be generated as full portal requests so that IPC will get executed. For more information about this, see Asynchronous Content Rendering and IPC.

The PostbackURL class is used to generate the base URL. Lines 23 to 40 add all the necessary parameters to the request. If the "replacePath" parameter was supplied, the path to the generated URL is replaced in line 43.

Finally, the resulting href for the HTML anchor tag is created and exposed via the getHref property.

Pages: 1, 2, 3, 4

Next Page »