The WebSphere Portal Server has concept of
NavigationSelectionModel
SPI that you can use to know about the current page.This SPI is used by the theme to know the page which should be displayed to the user. I built a PageNameFilter
that makes use of the NavigationSelectionModel
to find out where the page is getting rendered and passing it to the portlet as value of com.webspherenotes.filter.pageName
request attribute, so that it works on both local portlet as well as cases when the portlet is getting consumed as WSRP (in case of WSRP, it will give you name of the page where portlet is getting consumed)
package com.webspherenotes.portlet.filter;
import java.io.IOException;
import java.util.Locale;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.portal.ModelException;
import com.ibm.portal.content.ContentNode;
import com.ibm.portal.model.NavigationSelectionModelHome;
import com.ibm.portal.model.NavigationSelectionModelProvider;
import com.ibm.portal.navigation.NavigationNode;
import com.ibm.portal.navigation.NavigationSelectionModel;
public class PageNameFilter implements RenderFilter{
private static final Logger logger = LoggerFactory.getLogger(PageNameFilter.class);
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("Entering PageNameFilter.doFilter()");
String pageName = getPageTitle(request, response);
System.out.println("Page Name inside PageNameFilter " + pageName);
PageNameRenderRequestWrapper pageNameRequestWrapper = new PageNameRenderRequestWrapper(request);
pageNameRequestWrapper.setPageName(pageName);
filterChain.doFilter(pageNameRequestWrapper, response);
logger.debug("Exiting PageNameFilter.doFilter()");
}
private String getPageTitle(PortletRequest request, PortletResponse response){
try {
if (navigationSelectionModelHome != null) {
NavigationSelectionModelProvider provider =
navigationSelectionModelHome.getNavigationSelectionModelProvider();
NavigationSelectionModel model =
provider.getNavigationSelectionModel((ServletRequest)request, (ServletResponse)response);
NavigationNode navigationNode = (NavigationNode) model.getSelectedNode();
ContentNode contentNode = navigationNode.getContentNode();
if( contentNode.getObjectID().getUniqueName() != null){
logger.debug("The portlet is getting rendered on " + contentNode.getObjectID().getUniqueName());
}else{
logger.debug("The portlet is getting rendered on " + contentNode.getObjectID());
}
String pageTitle = contentNode.getTitle(request.getLocale());
if(pageTitle == null){
pageTitle = contentNode.getTitle(new Locale("en"));
if(pageTitle == null){
pageTitle = contentNode.getObjectID().getUniqueName();
if(pageTitle == null)
pageTitle = contentNode.getObjectID().toString();
}
}
return pageTitle;
}
} catch (ModelException e) {
logger.error("Error in PageNameFilter.getPageTitle() " + e.getMessage(),e);
}
return null;
}
private NavigationSelectionModelHome navigationSelectionModelHome;
public void init(FilterConfig filterConfig) throws PortletException {
try {
InitialContext context = new InitialContext();
navigationSelectionModelHome = (NavigationSelectionModelHome) context
.lookup(NavigationSelectionModelHome.JNDI_NAME);
} catch (NamingException e) {
logger.error("Error in PageNameFilter.init() " + e.getMessage(),e);
}
}
public void destroy() {
}
}
The
PageNameFilter
implements RenderFilter
and in the doFilter()
method it is passing control to getPageTitle
method to get title of the page in the current locale or English. The getPageTitle
, method is making use of the NavigationSelectionModel
and callings its model.getSelectedNode()
to first get the users current page and then reading the contentNode
of the page from it.I had to create
PageNameRenderRequestWrapper
that will override the actual RenderRequest
and pass pageName
as request attribute. This is how my PageNameRenderRequestWrapper
looks like
package com.webspherenotes.portlet.filter;
import java.util.Enumeration;
import java.util.Vector;
import javax.portlet.RenderRequest;
public class PageNameRenderRequestWrapper extends javax.portlet.filter.RenderRequestWrapper{
private String pageName;
public static final String PAGENAME_ATTRIBUTE ="com.webspherenotes.filter.pageName";
public PageNameRenderRequestWrapper(RenderRequest request) {
super(request);
}
public Object getAttribute(String name) {
if(name.equals(PAGENAME_ATTRIBUTE)){
return pageName;
}
return super.getAttribute(name);
}
public Enumeration getAttributeNames() {
Enumeration originalAttributeEnum = super.getAttributeNames();
Vector wrappedEnum = new Vector();
while(originalAttributeEnum.hasMoreElements()){
wrappedEnum.add(originalAttributeEnum.nextElement());
}
wrappedEnum.add(PAGENAME_ATTRIBUTE);
return wrappedEnum.elements();
}
public String getPageName() {
return pageName;
}
public void setPageName(String pageName) {
this.pageName = pageName;
}
}
Inside the portlet you can read
com.webspherenotes.filter.pageName
request attribute to get name of the page where portlet is getting rendered
Hello!
ReplyDeleteI'm trying to use this classes in my websphere portlet, but I'm not sure how to call them. They look exactly as what I need, and my guess is I should use the doFilter method, passing the RenderRequest and RenderResponse. But I don't understand where should I get FilterChain. Please, could you post a little example on how to use them. That would be great.
Thanks a lot :)
Thanks a lot :)
You dont have to call the doFilter() method explicitly. You should define your filter class in portlet.xml and then portlet container will call its doFilter() method. Take a look at http://wpcertification.blogspot.com/2010/05/hello-portletfilter-sample.html for details
ReplyDeleteThis comment has been removed by the author.
ReplyDeletehmmm I've have problems with some import, I think!
ReplyDeleteNavigationSelectionModelHome.JNDI_NAME doesn't exist even if the class itself is loaded :(
I'm using RAD 8 to target portal 6.1.0.33; any Ideas? Thanks!
Matteo
Thanks for info....
ReplyDeleteSEO Company in Bangalore