RedirectURLGeneratorFactory Service

WebSphere Portal SPI has a RedirectURLGeneratorFactoryService that can be called only from the processAction() method and used for creating URLs to either portal page or portlet. So far if i wanted to create a URL pointing to a page, only method that i knew was to create a URL mapping and then redirect to that URL

I wanted to try how RedirectURLGeneratorFactoryService works so i created a sample portlet that makes use of this service for redirecting to either a page or portlet, you can download the sample code from here

Important Note: I could use the RedirectURLGeneratorFactoryService to create URL to page and that worked but i am not able to get it working to target a portlet, I am not sure if its because i am not using it right or this is a issue with the WPS 6.1.5 version that i am using

This is how my RedirectServicePortlet.java looks like

package com.webspherenotes.portlet;

import java.io.IOException;

import javax.naming.CompositeName;
import javax.naming.InitialContext;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import com.ibm.portal.ModelException;
import com.ibm.portal.ObjectID;
import com.ibm.portal.content.ContentModel;
import com.ibm.portal.content.ContentPage;
import com.ibm.portal.content.LayoutControl;
import com.ibm.portal.content.LayoutModel;
import com.ibm.portal.model.ContentModelHome;
import com.ibm.portal.model.PortletModelHome;
import com.ibm.portal.portlet.service.PortletServiceHome;
import com.ibm.portal.portlet.service.state.RedirectURLGeneratorFactoryService;
import com.ibm.portal.portletmodel.PortletModel;
import com.ibm.portal.portletmodel.PortletWindow;
import com.ibm.portal.state.EngineURL;
import com.ibm.portal.state.RedirectURLGenerator;
import com.ibm.portal.state.exceptions.StateException;

public class RedirectServicePortlet extends GenericPortlet {

RedirectURLGeneratorFactoryService redirectionURLGeneratorFactoryService;

ContentModelHome contentModelHome;
PortletModelHome portletModelHome;

public void init() throws PortletException {
System.out.println("Entering RedirectServicePortlet.init()");
try {
InitialContext ctx = new InitialContext();
final PortletServiceHome redirectServiceHome = (PortletServiceHome) ctx
.lookup("portletservice/com.ibm.portal.portlet.service.state.RedirectURLGeneratorFactoryService");
redirectionURLGeneratorFactoryService = (RedirectURLGeneratorFactoryService) redirectServiceHome
.getPortletService(RedirectURLGeneratorFactoryService.class);

contentModelHome = (ContentModelHome) ctx
.lookup(ContentModelHome.JNDI_NAME);
portletModelHome = (PortletModelHome) ctx
.lookup(PortletModelHome.JNDI_NAME);
} catch (NamingException e) {
e.printStackTrace(System.out);
}
System.out.println("Exiting RedirectServicePortlet.init()");
}

protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering RedirectServicePortlet.doView()");
response.setContentType("text/html");
getPortletContext().getRequestDispatcher("/index.jsp").include(request,
response);
System.out.println("Exiting RedirectServicePortlet.doView()");

}

public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
System.out.println("Entering RedirectServicePortlet.processAction()");
try {
RedirectURLGenerator redirectURLGenerator = redirectionURLGeneratorFactoryService
.getURLGenerator(request, response);
if(request.getParameter("action").equals("portlet")){
ObjectID portletWindowObjectId = getPortletWindowID(request, response,
"com.webspherenotes.popup.static", "com.webspherenotes.popup.control");
System.out.println("Control object Id " + portletWindowObjectId);
EngineURL portletRedirectURL = redirectURLGenerator
.createPortletURL(portletWindowObjectId);
System.out.println("After creating URL " + portletRedirectURL.toString());
response.sendRedirect(portletRedirectURL.toString());
}else{
ObjectID pageObjectId = getObjectID("com.webspherenotes.popup.static");
EngineURL pageRedirectURL = redirectURLGenerator.createPageURL(pageObjectId);
System.out.println("After creating URL " + pageRedirectURL.toString());
response.sendRedirect(pageRedirectURL.toString());
}

} catch (StateException e) {
e.printStackTrace(System.out);
}
System.out.println("Exiting RedirectServicePortlet.processAction()");
}

private ObjectID getPortletWindowID(PortletRequest request,
PortletResponse response, String pageUniqueName,
String controlUniqueName) {
try {
ContentModel contentModel = contentModelHome
.getContentModelProvider().getContentModel(
(ServletRequest) request,
(ServletResponse) response);
ContentPage contentPage = (ContentPage) contentModel.getLocator()
.findByUniqueName(pageUniqueName);
System.out.println("Content Page " + contentPage);
LayoutModel layoutModel = contentModel.getLayoutModel(contentPage);
LayoutControl layoutControl = (LayoutControl) layoutModel
.getLocator().findByUniqueName(controlUniqueName);
System.out.println("Layout Control " + layoutControl);
PortletModel portletModel = portletModelHome
.getPortletModelProvider().getPortletModel(contentPage,
(ServletRequest) request,
(ServletResponse) response);
PortletWindow portletWindow = portletModel
.getPortletWindow(layoutControl);
System.out.println("Porltet Window " + portletWindow);
return portletWindow.getObjectID();
} catch (ModelException e) {
e.printStackTrace();
}
return null;
}

private ObjectID getObjectID(String uniqueNameStr) {
try {
InitialContext ctx = new InitialContext();
final Name uniqueName = new CompositeName("portal:uniquename");
uniqueName.add(uniqueNameStr);
ObjectID oidForUniqueName = (ObjectID) ctx.lookup(uniqueName);
return oidForUniqueName;
} catch (InvalidNameException e) {
e.printStackTrace(System.out);
} catch (NamingException e) {
e.printStackTrace(System.out);
}
return null;
}
}


In the doView() method of the portlet i am forwarding control to a JSP that displays two actionURLs, when user clicks on either of this URL the control will go to processAction() method and in side that method i check if name of the action parameter is page, i am getting ObjectID of a page which has uniquename com.webspherenotes.popup.static, then calling redirectURLGenerator.createPageURL(pageObjectId); method to create redirect URL to the page. Finally i am calling ActionResponse.sendRedirect() method to redirect to the page URL,

If you click other Redirect to portlet then the processAction() method will try to find a PortletWindow for a com.webspherenotes.popup.control LayoutControl on the com.webspherenotes.popup.static page. Then i am calling redirectURLGenerator.createPortletURL(portletWindowObjectId) method for creating URL to a portlet on a page and then redirecting it. THe URL is getting created but clicking on it does not redirect