1
votes

I have a JSR-168 portlet application running on WebSphere Portal 6.0.
In the application's portlet.xml file, a specific portlet is defined as follows:

<portlet>
        <portlet-name>Individual Portlet</portlet-name>
        <display-name>Individual Portlet</display-name>
        <display-name xml:lang="en">
            Individual Portlet
        </display-name>
        <portlet-class>
            com.companyname.util.hibernate.MHFacesHibernatePortlet
        </portlet-class>
        <init-param>
            <name>com.ibm.faces.portlet.page.view</name>
            <value>/TEIndividual/TEIndividualView.jsp</value>
        </init-param>
        <init-param>
            <name>wps.markup</name>
            <value>html</value>
        </init-param>
        <expiration-cache>0</expiration-cache>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>view</portlet-mode>
        </supports>

        <resource-bundle>
            resources.nl.IndividualPortletResource
        </resource-bundle>
        <portlet-info>
            <title>Individual Portlet</title>
        </portlet-info>
        <portlet-preferences>
            <preference>
                <name>portletType</name>
                <value>individual</value>
            </preference>
            <preference>
                <name>wmmAttribSalesmanId</name>
                <value>facsimileTelephoneNumber</value>
            </preference>
        </portlet-preferences>
    </portlet>

Note that it defines a parameter named "com.ibm.faces.portlet.page.view" with the value "/TEIndividual/TEIndividualView.jsp", which is the initial JSP used when the portlet is rendered.
I need to conditionally change the value of that parameter based on the result of a database query.

I think this might involve a redirect somewhere in the MHFacesHibernatePortlet class.
Is that correct, and what method of the class should I modify?

Edit, with more info and source code for two classes...

I've added code for the MHFacesHibernatePortlet class below, and also the MHFacesPortlet class which it extends.

In the application's portlet.xml file, multiple portlets are all configured to use the MHFacesHibernatePortlet class, but each portlet uses a different initial JSP. The "Individual Portlet" above is just one example.

I need to conditionally change the initial JSP only for some of the portlets, so I have some code that should be able to check the JSP name against a list of the ones I want to change, then run a Hibernate query, then change the JSP name only if necessary.

I saw in MHFacesPortlet.processAction that it reads the relevant parameter and passes it to request.getPortletSession().setAttribute() under some conditions, so I tried to put my code there and change the homeJsp variable, but that didn't work. After adding some logging I found that processAction isn't even called when I go to a page with one of these portlets.

Source for the MHFacesHibernatePortlet class:

package com.companyname.util.hibernate;

import java.io.IOException;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.companyname.util.portlet.MHFacesPortlet;

public class MHFacesHibernatePortlet extends MHFacesPortlet {
    /*
     * (non-Javadoc)
     *
     * @see com.ibm.faces.webapp.FacesGenericPortlet#doConfigure(javax.portlet.RenderRequest,
     *      javax.portlet.RenderResponse)
     */
    public void doConfigure(RenderRequest arg0,RenderResponse arg1)
    throws PortletException,IOException {
        super.doConfigure(arg0,arg1);
        try {
            HibernateUtil.commitTransaction();
        } finally {
            HibernateUtil.closeSession();
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest,
     *      javax.portlet.RenderResponse)
     */
    public void doView(RenderRequest arg0,RenderResponse arg1)
    throws PortletException,IOException {
        super.doView(arg0,arg1);
        // Close and commit open hibernate transactions
        try {
            HibernateUtil.commitTransaction();
        } finally {
            HibernateUtil.closeSession();
        }
    }
}

Source for the MHFacesPortlet class:

package com.companyname.util.portlet;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import com.ibm.faces.webapp.FacesGenericPortlet;

public class MHFacesPortlet extends FacesGenericPortlet {
    private static final String FACES_CURRENT_PAGE_STUB="com.ibm.faces.portlet.page.";

    /** parameter used to fire an extended action */
    public static final String PARAMETER_EXTENDED_ACTION="extAction";

    /** Action to reset view mode of the portlet */
    public static final String ACTION_VIEW_MODE_RESET="viewReset";

    public MHFacesPortlet() {
        super();
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest,
     *      javax.portlet.ActionResponse)
     */
    public void processAction(ActionRequest request,ActionResponse response)
    throws PortletException {
        // Check if we need to process an extended action
        String extendedAction=(String)request
            .getParameter(PARAMETER_EXTENDED_ACTION);

        if (extendedAction!=null&&!extendedAction.equals("")) {
            // Reset view mode
            if (extendedAction.equals(ACTION_VIEW_MODE_RESET)) {
                PortletMode portletMode=request.getPortletMode();
                String modeString=null;
                if (portletMode.equals(PortletMode.EDIT)) modeString="edit";
                else if (portletMode.equals(PortletMode.VIEW)) modeString="view";
                else if (portletMode.equals(PortletMode.HELP)) modeString="help";
                else modeString=portletMode.toString();

                String homeJsp=getPortletConfig().getInitParameter(
                    FACES_CURRENT_PAGE_STUB+modeString);
                request.getPortletSession().setAttribute(
                    FACES_CURRENT_PAGE_STUB+modeString,homeJsp);
            }

        }

        //delegate to ibm faces
        super.processAction(request,response);
    }
}
1
To properly answer this, we'd need to see the source of MHFacesHibernatePortlet. (Given the init-param/name of com.ibm.faces..., I'm guessing that this portlet class must extend a base IBM portlet class.)ziesemer
Added some information and source code. Tried a change (in processAction method) which had no effect.Scott Leis
Scott - please see my updated answer.ziesemer

1 Answers

1
votes

This shouldn't involve a redirect, as much as changing the JSP that the portlet dispatches to.

As I commented to your question, it would really be helpful to see the source of MHFacesHibernatePortlet. However, at a minimum, within MHFacesHibernatePortlet, you could override init(PortletConfig config), then conditionally change the value of the init parameter that is used. This could follow the approach of adding a filter around the passed-in PortletConfig that is overridden to return an alternate value for getInitParameter if called with the same com.ibm.faces.portlet.page.view key name - then calling super.init(...) with your filter implementation. However, this will not work if you need to return different JSPs to different portlet requests, as this init param will be used for all requests serviced by the portlet instance.

However, the better approach would be to see where the custom portlet (or one of its parents) is referring to this init param, and putting your custom logic there instead.


Update (following your updated comments):

For changing the initial (view) JSP, you need to override doView, not processAction. See http://publib.boulder.ibm.com/infocenter/radhelp/v6r0m1/index.jsp?topic=%2Fcom.ibm.etools.portal.doc%2Ftopics%2Ftnoactionmode.html for a specific example on how to accomplish this:

Changing a JSF portlet page without a JSF action

You can change a page in a Faces portlet using a Faces action outcome and the navigation rules.

If you want to change a page without using a Faces action, you can set a JSP file path to the one of the following session attributes:

...

For example, you can create a subclass of your Faces portlet and set the session attribute in the doView() method to change the page in some conditions:

public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
  if (...) {
    request.getPortletSession().setAttribute("com.ibm.faces.portlet.page.view", "/MyPage.jsp");
  }

  super.doView(request, response);
}