Featured Post

JSF Portlets with JBOSS Portal Server (JSR 286)

I am going to discusss about JSF+PORTAL (JSR 286) integration with JBOSS
PORTAL
prerequisite is as followes

How JBOSS IPC is working with JSF 1.2 and Jboss portals

When you define publiching event and processing event in portlet.xml
portlets are tightly coupled with events in JSR 286
here two ways are there to achieve IPC
- Public Render Parameters
- Events
- PortalNodeEventListener

Prerequisite
- Basic Knowledge of Portal
- Basic Knowldge of JBOSS Appserver
-Basic Understanding of JSF


Jars Required :

antlr.jar
asm.jar
bsh.jar
cglib.jar
commons-beanutils-1.7.0.jar
commons-codec-1.3.jar
commons-codec.jar
commons-collections-3.1.jar
commons-collections.jar
commons-digester.jar
commons-discovery-0.2.jar
commons-fileupload-1.1.jar
commons-fileupload-1.2.jar
commons-httpclient.jar
commons-io-1.1.jar
commons-lang-2.1.jar
commons-logging.jar
dom4j.jar
hibernate3.jar
hsqldb.jar
mail.jar
portletbridge-api-2.0.0.BETA.jar
portletbridge-impl-2.0.0.BETA.jar

Environment :

- JBOSS AS BUNDLE 4.3 +PORTAL 2.6.7
- Eclipse Ganymede 3.4.2 latest one would be better (Eclipse 3.6 Helios )
- java 1.6
- Maven 3.0 or ANT
- JSF 1.2 optional My Faces
- Portlet bridge 2.0 and portlet tld 2.0

Portlet 1

package com.test;

import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.PortletException;
import javax.portlet.faces.GenericFacesPortlet;

import org.jboss.logging.Logger;

public class MyPortlet extends GenericFacesPortlet {

private static Logger logger = Logger.getLogger(MyPortlet.class);

protected void doView(javax.portlet.RenderRequest request,
javax.portlet.RenderResponse response)
throws javax.portlet.PortletException,
java.io.IOException {

super.doView(request, response);
}

/*public void processAction(ActionRequest request, ActionResponse
response)
throws PortletException, IOException {

String firstName = request.getParameter("firstName");
logger.info("MyPortlet:processAction() method has been
called"+firstName);
firstName=(firstName==null?"Sitaram":firstName);

response.setEvent(MyEvent.qNAME, new MyEvent(firstName,
firstName,
firstName));
//request.getPortletSession().setAttribute("employee", new
MyEvent(firstName,firstName,firstName));

//response.sendRedirect("/portal/portal/default/Test+Second+portlet");

}*/

}

Portlet 2:

package com.test;

import java.io.IOException;

import javax.faces.context.FacesContext;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.faces.GenericFacesPortlet;

import org.jboss.logging.Logger;

public class YourPortlet extends GenericFacesPortlet {

private static Logger logger = Logger.getLogger(YourPortlet.class);
private MyEvent myEvent;

protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
// TODO Auto-generated method stub
logger.info("YourPortlet : doView() Method has been called");
// Writer writer=response.getWriter();
//String elExpression = "#{Login}";
//ELContext elContext =
FacesContext.getCurrentInstance().getELContext();
//ValueExpression valueExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(
//elContext, elExpression, Login.class);
//Login pSession = (Login)
valueExpression.getValue(elContext);
//logger.info("User id :-> "+ pSession.getUserName());
//writer.append("You Entered this:---->
"+myEvent.getFirstName()+":"+myEvent.getLastName()+":"+myEvent.getEmail());

logger.info(getBridgeClassName()+":----------> THIS IS BRIDGE
CLASSNAME");
try {
org.jboss.portletbridge.AjaxPortletBridge
abj=(org.jboss.portletbridge.AjaxPortletBridge)Class.forName("org.jboss.portletbridge.AjaxPortletBridge").newInstance();
logger.info("<------Class Instance for
org.jboss.portletbridge.AjaxPortletBridge has been created ----->");
abj.init(getPortletConfig());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.doView(request, response);

}

//@Override
/*public void processEvent(EventRequest request, EventResponse
response)
throws PortletException, IOException {
// TODO Auto-generated method stub
/* logger.info("YourPortlet : processEvent Method has been
called");

Event event=request.getEvent();
myEvent=(MyEvent)event.getValue();
String firstName=myEvent.getFirstName();
String lastName=myEvent.getLastName();
String email=myEvent.getEmail();

logger.info("YourPortlet : processEvent Method has been
called"+firstName+":"+lastName+":"+email);
*/
//}*/

}

Event Handler :

This is responsible for Handling Events when you click action in Portlets

package com.test;

import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
import javax.portlet.Event;
import javax.portlet.faces.BridgeEventHandler;
import javax.portlet.faces.event.EventNavigationResult;

import org.jboss.logging.Logger;


/**
* @author <a href="mailto:whales@redhat.com">Wesley Hales</a>
* @version $Revision: 630 $
*/
public class BookingEventHandler implements BridgeEventHandler
{

String firstName,lastName,email;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
private static Logger
logger=Logger.getLogger(BookingEventHandler.class);
public EventNavigationResult handleEvent(FacesContext context, Event
event)
{
logger.info("BookingEventHandler:handleEvent method has been
called"+event.getName());


context.getExternalContext().getSessionMap().put(event.getName(),event.getValue());

//throw new NullPointerException("Hey null");


MyEvent myEvent= (MyEvent)event.getValue();
setFirstName(myEvent.getFirstName());
setLastName(myEvent.getLastName());
setEmail(myEvent.getEmail());

logger.info("FirstName:---->"+getFirstName());
logger.info("Lats Name:---->"+getLastName());
logger.info("Email:---->"+getEmail());

String elExpression = "#{Login}";
ELContext elContext =
FacesContext.getCurrentInstance().getELContext();
ValueExpression valueExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(
elContext, elExpression, Login.class);
Login ll=new Login();
ll.setUserName(getFirstName());
ll.setPassword(getLastName());
ll.setEmail(getEmail());
valueExpression.setValue(elContext,ll);
//valueExpression.setValue(elContext,getLastName());
//valueExpression.setValue(elContext,getEmail());

return new EventNavigationResult("/jsf/view.jsp","personPage");


}


}

You need to define PayLoad which is responsible for holding data from o2ne
portlet to another portlet

package com.test;

import java.io.Serializable;


import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;

@XmlRootElement
public class MyEvent implements Serializable {

private String firstName;
private String lastName ;
private String email;
public static QName qNAME=new
QName("urn:jboss:portal:samples:myevent","MyEvent");

public MyEvent(String firstName,String lastName,String email)
{
this.email=email;
this.firstName=firstName;
this.lastName=lastName;
}

public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}

}

Deployment Descriptors for JBOSS

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web=
"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>PortalTest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>

<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>

<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>


<context-param>
<param-name>javax.portlet.faces.RENDER_POLICY</param-name>
<param-value>NEVER_DELEGATE</param-value>
</context-param>

</web-app>

portlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0">

<portlet>
<portlet-name>YourPortlet</portlet-name>
<display-name>JBoss JSF Portlet YourPortlet</display-name>
<portlet-class>
com.test.YourPortlet
</portlet-class>
<!-- <init-param>-->
<!-- <name>javax.portlet.faces.BridgeImplClass</name>-->
<!-- <value>org.apache.myfaces.portlet
.faces.bridge.BridgeImpl</value>-->
<!-- </init-param>-->
<init-param>
<name>javax.portlet.faces.defaultViewId.view</name>
<value>/jsf/view1.jsp</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.edit</name>
<value>/jsf/edit.jsp</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.help</name>
<value>/jsf/help.jsp</value>
</init-param>
<init-param>
<name>javax.portlet.faces.autoDispatchEvents</name>
<value>true</value>
</init-param>
<init-param>
<name>javax.portlet.faces.bridgeEventHandler</name>
<value>com.test.BookingEventHandler</value>
</init-param>

<init-param>
<name>javax.portlet.faces.preserveActionParams</name>
<value>true</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-mode>EDIT</portlet-mode>
<portlet-mode>HELP</portlet-mode>
</supports>
<portlet-info>
<title>YourPortlet</title>
</portlet-info>
<supported-processing-event>
<qname xmlns:jbp="urn:jboss:portal:samples:myevent">jbp:MyEvent</
qname>
</supported-processing-event>
<supported-public-render-parameter>zipcode</
supported-public-render-parameter>
</portlet>
<portlet>
<portlet-name>MyPortlet</portlet-name>
<display-name>JBoss JSF Portlet MyPortlet</display-name>
<portlet-class>
javax.portlet.faces.GenericFacesPortlet
</portlet-class>
<init-param>
<name>javax.portlet.faces.defaultViewId.view</name>
<value>/jsf/view.jsp</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.edit</name>
<value>/jsf/edit.jsp</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.help</name>
<value>/jsf/help.jsp</value>
</init-param>
<init-param>
<name>javax.portlet.faces.autoDispatchEvents</name>
<value>true</value>
</init-param>


<init-param>
<name>javax.portlet.faces.preserveActionParams</name>
<value>true</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-mode>EDIT</portlet-mode>
<portlet-mode>HELP</portlet-mode>
</supports>
<portlet-info>
<title>MyPortlet</title>
</portlet-info>
<supported-publishing-event>
<qname xmlns:jbp="urn:jboss:portal:samples:myevent">jbp:MyEvent</
qname>
</supported-publishing-event>

<supported-public-render-parameter>zipcode</
supported-public-render-parameter>

</portlet>
<event-definition>
<qname xmlns:jbp="urn:jboss:portal:samples:myevent">jbp:MyEvent</
qname>
<value-type>com.test.MyEvent</value-type>
</event-definition>
<public-render-parameter>
<identifier>hotelName</identifier>
<qname xmlns:j="http://jboss.org/params">j:zipcode</qname>
</public-render-parameter>

</portlet-app>

portlet-instances.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE deployments PUBLIC
"-//JBoss Portal//DTD Portlet Instances 2.6//EN"
"http://www.jboss.org/portal/dtd/portlet-instances_2_6.dtd">
<deployments>
<deployment>
<instance>
<instance-id>YourPortletInstanceA</instance-id>
<portlet-ref>YourPortlet</portlet-ref>
</instance>
</deployment>
<deployment>
<instance>
<instance-id>MyPortletInstanceA</instance-id>
<portlet-ref>MyPortlet</portlet-ref>
</instance>
</deployment>
</deployments>

jboss-portlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE portlet-app PUBLIC
"-//JBoss Portal//DTD JBoss Portlet 2.6//EN"
"http://www.jboss.org/portal/dtd/jboss-portlet_2_6.dtd">
<portlet-app>
<portlet>
<portlet-name>YourPortlet</portlet-name>
<header-content></header-content>
</portlet>
<portlet>
<portlet-name>MyPortlet</portlet-name>
<header-content></header-content>
</portlet>
</portlet-app>

jboss-app.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-app PUBLIC
"-//JBoss Portal//DTD JBoss Web Application 2.6//EN"
"http://www.jboss.org/portal/dtd/jboss-app_2_6.dtd">
<jboss-app>
<app-name>portalTestApp</app-name>

</jboss-app>

default-object.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE deployments PUBLIC
"-//JBoss Portal//DTD Portal Object 2.6//EN"
"http://www.jboss.org/portal/dtd/portal-object_2_6.dtd">
<deployments>
<deployment>
<parent-ref>default</parent-ref>
<if-exists>overwrite</if-exists>
<page>
<page-name>MyPortlet-YourPortlet-Mixed</page-name>

<window>
<window-name>MyPortletInstanceA</window-name>
<instance-ref>MyPortletInstanceA</instance-ref>
<region>center</region>
<height>1</height>

</window>
<window>
<window-name>YourPortletInstanceA</window-name>
<instance-ref>YourPortletInstanceA</instance-ref>
<region>center</region>
<height>1</height>

</window>

</page>
</deployment>
<deployment>
<parent-ref>default</parent-ref>
<if-exists>overwrite</if-exists>
<page>
<page-name>Test Meeee</page-name>

<window>
<window-name>YourPortletInstanceA</window-name>
<instance-ref>YourPortletInstanceA</instance-ref>
<region>center</region>
<height>1</height>

</window>

</page>
</deployment>
</deployments>

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:bridge="http://myfaces.apache.org/portletbridge"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<managed-bean>
<managed-bean-name>Login</managed-bean-name>
<managed-bean-class>com.test.Login</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>persondetails</managed-bean-name>
<managed-bean-class>com.test.persondetails</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>Validation</managed-bean-name>
<managed-bean-class>com.test.Validation</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>myEvent</managed-bean-name>
<managed-bean-class>com.test.BookingEventHandler</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>/jsf/view.jsp</from-view-id>
<navigation-case>
<from-outcome>personPage</from-outcome>
<to-view-id>/jsf/PersonDetails.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>failur</from-outcome>
<to-view-id>/jsf/Failur.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/jsf/Failur.jsp</from-view-id>
<navigation-case>
<from-outcome>back</from-outcome>
<to-view-id>/jsf/view.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/jsf/PersonDetails.jsp</from-view-id>
<navigation-case>
<from-outcome>info</from-outcome>
<to-view-id>/jsf/info.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<validator>
<validator-id>validEmailId</validator-id>
<validator-class>com.test.Validation</validator-class>
</validator>
<application>
<view-handler>org.jboss.portletbridge.application.PortletViewHandler</
view-handler>
<state-manager>org.jboss.portletbridge.application.PortletStateManager</
state-manager>
<application-extension>
<bridge:public-parameter-mappings>
<bridge:public-parameter-mapping>
<parameter>MyPortlet:zipcode</parameter>
<model-el>#{Login.zipcode}</model-el>
</bridge:public-parameter-mapping>
</bridge:public-parameter-mappings>
</application-extension>

</application>
</faces-config>
view.jsp

<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="c"%>
<c:view>
<html>
<head>
<title>Login PAGE</title>
</head>
<body leftmargin="50" topmargin="50" bgcolor="#B0E0E6">
<h:form>
<table>
<c:facet name="header">
<h:outputText value="Login Page:" />
</c:facet>
<tr>
<td><h:outputText value="User Name: "></h:outputText></td>
<td><h:inputText id="uname" value="#{Login.userName}" required="true"/>
<font color="#FF0000"><h:message for="uname"></h:message></font></td></tr>

<tr>
<td><h:outputText value="Password: "></h:outputText></td>
<td><h:inputSecret id="pwd" value="#{Login.password}"
required="true"></h:inputSecret>
<font color="#FF0000"><h:message for="pwd"></h:message></font></td></tr>

<tr><td><h:outputText value="Email: "></h:outputText></td>
<td><h:inputText id="email1" value="#{Login.email}" required="true">
<c:validator validatorId="validEmailId"/></h:inputText>
<font color="#FF0000"><h:message for="email1"></h:message></font></td></tr>


<tr><td>&nbsp</td>
<td width="250"><h:commandButton id="bt" value="Login"
actionListener="#{Login.processAction}"
action="#{Login.nextPage}"></h:commandButton></td></tr>

</table>
</h:form>
</body>
</html>
</c:view>

You have to write Login.java which is referenced in the above jsp page
would be looking like this

public Object getResponse(){
return
FacesContext.getCurrentInstance().getExternalContext().getResponse();
}

public void publishParameter(ActionEvent ae)
{
logger.info("Login:publishParameter called ");
if(getResponse() instanceof ActionResponse)
{
logger.info("Login:publishParameter ActionResponse ");
ActionResponse
stateResponse=(ActionResponse)getResponse();
stateResponse.setRenderParameter("zipcode", "hey my zip
code");
}
}

public void processAction(ActionEvent arg0) throws
AbortProcessingException {
logger.info("Login:processAction method has been called");
String elExpression = "#{Login}";
ELContext elContext =
FacesContext.getCurrentInstance().getELContext();
ValueExpression valueExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(
elContext, elExpression, Login.class);
Login pSession = (Login) valueExpression.getValue(elContext);
logger.info("User id :-> "+ pSession.getUserName());
if(getResponse() instanceof StateAwareResponse)
{
logger.info("Login:processAction StateAwareResponse ");
StateAwareResponse
response=(StateAwareResponse)getResponse();
response.setEvent(MyEvent.qNAME, new
MyEvent(pSession.getUserName(), pSession.getPassword(),
pSession.getEmail()));
}


}

P.S: I put importent statements in bold please observe above xmls
carefully for crucial changes

Thanks
Sitaram.PV
SEO-JAVA Technical Blogger

This e-Mail may contain proprietary and confidential information and is sent for the intended recipient(s) only. If by an addressing or transmission error this mail has been misdirected to you, you are requested to delete this mail immediately. You are also hereby notified that any use, any form of reproduction, dissemination, copying, disclosure, modification, distribution and/or publication of this e-mail message, contents or its attachment other than by its intended recipient/s is strictly prohibited.

Visit us at http://www.polaris.co.in

Comments