JavaserverFaces (JSF) and JSR 286 Eventing in WebSphere Portal 6.1

I’m aware that lots of people had worked on this in the past and come up with solutions, but I could not find a single site that gave the complete solution in one place. Googling came up with lots of tutorials and answers. I have tried to put the complete solution below as much as I know.

Lets set the scene

  1. There are two JavaserverFaces (JSF) based portlets in one page, SourcePortlet and TargetPortlet
  2. The IDE or the Integrated Development Environment is Rational Application Developer 7.5.4.
  3. The Portal environment is WebSphere 6.1.0.2 running on WAS 7.0.0.1
  4. The backend JDK is 1.6 (that gets shipped with WAS 7.0.0.1)
  5. The JSF Version is 1.2 and the Servlet Spec is 2.5
  6. We have an input text field in the source portlet which takes a value and publishes it. The Target portlet has an output text field which displays it.

Important steps or points are highlighted in RED.

  • Launch RAD and go into a new workspace of your choice
  • Open Window  -> Preferences. Under General -> Capabilities, ensure that the required capabilities are enabled. For my workspace, I just enabled all to prevent confusion. Click Apply and Ok.
  • Switch to the Web Development Perspective. Click on the File Menu -> New Portlet Project.
  • Specify the following Details
    • Project Name: TestingEvents
    • Target Runtime: WebSphere Portal 6.1 on WAS 7
    • Portlet API: JSR 286 Portlet
    • Create a Portlet: enabled
    • Portlet Name: TestingEventsSource
    • Portlet Type: Faces Portlet
    • Click on Show advanced settings
    • Ensure that JavaServer Faces version is set to 1.2 and Dynamic Web Module is set to 2.5. Click Ok.
    • Click Next
    • Enable the Checkbox “Generate a custom portlet class” and specify the following details
      • Package Prefix: com.test.portlets.events.testing
      • Class Prefix: TestingEventsSourcePortlet
    •  Click Next and Finish.
    • This will open the TestingEventsSourceView.jsp file. Close this file.
    • In the Exnterprise Explorer view, Expand JavaResources -> src -> pagecode. Open the TestingEventsSourceView.java file
    • Add a private String variable called sourceText.
    • Generate getters and setters for this attribute.
    • Reopen TestingEventsSourceView.jsp
    • Select “Place content here” in the Design mode of the jsp and delete.
    • Switch to Palette view in RAD. Drag and drop an Input field and a Button – Command component onto the JSP
    • From the Page Data view expand Page Bean and drag sourceText to the input text field.
    • Click on the submit button and switch to the Properties view.
    • Under the Action or outcome, click on the edit button and select code an action. This will open the QuickEdit view automatically. Click on the area where it displays the “Insert a code snippet or write your script here”. It will load the Java View for the buton Command event.
    • Change return “”; to return “success”;
    • Click on the submit button again and switch to the Properties view.
    • Under the “The outcome returned by the action determines which rule in the map is followed:” section, click on the Add rule button.
    • Specify the following:
      • Page: TestingEventsSourceView.jsp
      • The outcome named: success
      • This rule is used by: This action only: #{pc_TestingEventsSourceView.doButton1Action}
    • Leave other settings as they are and click Ok.
    • Close the JSP.
    • In the Enterprise explorer view, right click on Portlet Deployment Descriptor and select new Portlet.
    • Specify the following:
      • Portlet name: TestingEventsTargetPortlet
    • Click Next
    • Make the “Generate a custom portlet class” enabled. Specify the following
      • Package Prefix: com.test.portlets.events.testing
      • Class Prefix: TestingEventsTargetPortlet
    •  Click Next and Finish. 
    • This will open the TestingEventsTargetPortletView.jsp. Close this file.
    • In the Enterprise explorer view, expand Java Resources -> pagecode. Open the TestingEventsTargetPortletView.java file
    • Add a private String Java variable called targetText. Generate getters and setters.
    • Reopen TestingEventsTargetPortletView.jsp. Select the “Place content here” text in the design mode of the jsp and delete.
    • Drag and drop and output component from the JSF palette view.
    • From the Page Data view, expand Page Bean. Drag and drop targetText on the output box. Save and close the JSP.

    This completes Stage 1.  Onto stage 2 where we configure the source and target portlets to publish and receive JSR 286 events.

    • Under the Enterprise explorer view, expand Portlet Deployment Descriptor. 
    • Right click on the TestingEventsSource and click on Event -> Enable this portlet to publish events.
    • Specify the following:
      • Event name: http://com.test.portlets.events#TestingEvent
      • Custom Namespace: enabled
      • Value type: java.lang.String
    • Click Finish.
    • Right click on TestingEventsTargetPortlet and click on Event -> Enable this portlet to process events.
    • Specify the following:
      • Event name: http://com.test.portlets.events#TestingEvent
      • Custom Namespace: enabled
      • Value type: java.lang.String
    • Click Finish.

    This completes Stage 2. Onto stage 3 where we code the publish and process events. Remember we are sending events from the source portlet by reading the value from the JavaServer Faces managed bean which is linked to the sourceText field and sending the message to the target portlet which receives the event and sets the targetText value in the managed bean which again is read by the JSP and displayed on the page.

    • In the Enterprise explorer view, under Java Resouces -> src -> com.test.portlets.events.testing, open the TestingEventsSourcePortlet.java file.
    • Copy and paste the following functions

     /**
         * Return the managed bean with the given name
         *
         * @param mgdBeanName   the name of the managed bean to retrieve
         * @return
         */  
        protected Object getManagedBean( String mgdBeanName, FacesContext context ) {
            String expression = “#{” + mgdBeanName + “}”;
            return resolveExpression(expression, context);
        }  

        /**
         * Return the result of the resolved expression
         *
         * @param expression
         * @return
         */
        protected Object resolveExpression(String expression, FacesContext context ) {
            Object value = null;
            if ((expression.indexOf(“#{“) != -1)
                && (expression.indexOf(“#{“) < expression.indexOf(‘}’))) {
                System.out.println(“getFacesContext 00000–“);
                value =    context.getApplication().getExpressionFactory().createValueExpression(
                        context.getELContext(), expression, Object.class).getValue(context.getELContext());
            } else {
                value = expression;
            }
            return value;
        }

    • Change the processAction(ActionRequest request, ActionResponse response) to the following

    public void processAction(ActionRequest request, ActionResponse response) throws PortletException {
            super.processAction(request, response);
           
          QName name = new QName(“http://com.test.portlets.events”,
                    “TestingEvent”);

            PortletRequestWrapper request1 = new com.ibm.faces.portlet.httpbridge.PortletRequestWrapper(
                    request);
            PortletResponseWrapper response1 = new com.ibm.faces.portlet.httpbridge.PortletResponseWrapper(
                    response);
            Lifecycle lifecycle = getLifecycle(request1);
            FacesContext facesContext = getFacesContext(request1, response1,
                    lifecycle);

            Object value = getManagedBean(“pc_TestingEventsSourceView”,
                    facesContext);

            if (value instanceof TestingEventsSourceView) {
                TestingEventsSourceView srcView = (TestingEventsSourceView) value;

                response.setEvent(name, srcView.getSourceText());
            } else {
                System.out.println(“Object is not a managed bean instance”);
            }
           
        }

    •   Open TestingEventsTargetPortlet.java and paste the following functions

    /**
         * Return the managed bean with the given name
         *
         * @param mgdBeanName   the name of the managed bean to retrieve
         * @return
         */  
        protected Object getManagedBean( String mgdBeanName, FacesContext context ) {
            String expression = “#{” + mgdBeanName + “}”;
            return resolveExpression(expression, context);
        }  

        /**
         * Return the result of the resolved expression
         *
         * @param expression
         * @return
         */
        protected Object resolveExpression(String expression, FacesContext context ) {
            Object value = null;
            if ((expression.indexOf(“#{“) != -1)
                && (expression.indexOf(“#{“) < expression.indexOf(‘}’))) {
                System.out.println(“getFacesContext 00000–“);
                value =    context.getApplication().getExpressionFactory().createValueExpression(
                        context.getELContext(), expression, Object.class).getValue(context.getELContext());
            } else {
                value = expression;
            }
            return value;
        }

    •  Copy and paste the following code.

    @Override
        public void processEvent(EventRequest request, EventResponse response)
                throws PortletException, IOException {
            super.processEvent(request, response);
            String eventRcv = null;
            eventRcv = request.getEvent().getValue().toString();
           
            PortletRequestWrapper request1 = new com.ibm.faces.portlet.httpbridge.PortletRequestWrapper(request);
            PortletResponseWrapper response1 = new com.ibm.faces.portlet.httpbridge.PortletResponseWrapper(response);
            Lifecycle lifecycle = getLifecycle(request1);
            FacesContext getFacesContext = getFacesContext(request1, response1, lifecycle);

            Object value = getManagedBean(“pc_EventsTargetView”, getFacesContext);
           
            if(value instanceof TestingEventsTargetPortletView){
                TestingEventsTargetPortletView eventTarget = (TestingEventsTargetPortletView)value;
                if(eventRcv !=null){
                    eventTarget.setTargetText(eventRcv);
                }else{
                    System.out.println(“eventRcv is null”);
                }
            }else{
                System.out.println(“object is not instance of managed bean “);
            }
           
            //FacesContext getFacesContext = FacesContext.getCurrentInstance();
           
        }

    • Save and close. 

    Now onto stage 3. Publish both portlets on to the server either using RAD or by exporting the project into a WAR and installing using the Portal Admin console.

    In Stage 4, wire the source and target portlets. Test the events.