ProcessEvent annotation

This is how the default implementation of the processEvent() method in GenricPortlet looks like,

public void processEvent(EventRequest request, EventResponse response) throws PortletException, IOException {
String eventName = request.getEvent().getQName().toString();
try {
// check for exact match
Method eventMethod = processEventHandlingMethodsMap.get(eventName);
if (eventMethod != null) {
eventMethod.invoke(this, request, response);
return;
} else {
// Search for the longest possible matching wildcard annotation
int endPos = eventName.indexOf('}');
int dotPos = eventName.lastIndexOf('.');
while (dotPos > endPos) {
String wildcardLookup = eventName.substring(0, dotPos + 1);
eventMethod = processEventHandlingMethodsMap.get(wildcardLookup);
if (eventMethod != null) {
eventMethod.invoke(this, request, response);
return;
}
if (dotPos == 0) {
break;
}
dotPos = eventName.lastIndexOf('.', dotPos - 1);
}
}
} catch (Exception e) {
throw new PortletException(e);
}
// if no event processing method was found just keep render params
response.setRenderParameters(request);
}


First it tries to figure out if there is a method with @ProcessEvent annotation, that matches current event, if yes it forwards control to that method if not it sets the current render parameters as new render parameters.

You can annotate a method use ProcessEvent annotation using two different approaches

  • Using QName: You can specify the fully qualified name of the event using "{" + Namespace URI + "}" + local part format. Ex. @ProcessEvent(qname="{http://wpcertification.blogspot.com}hello")

  • Using local Name:For using only the local part of the event name and leverage the default namespace defined in the portlet deployment descriptor with the default-namespace element the following alternative is provided: @ProcessEvent (name=), where the event name is only the local part.



You can download the sample portlet that i built to demonstrate how to use @ProcessEvent from here


package com.webspherenotes.portlet.jsr286;

import java.io.IOException;

import javax.portlet.Event;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.ProcessEvent;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import com.webspherenotes.portlet.events.Contact;

public class ProcessEventAnnotationPortlet extends GenericPortlet {

protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering ProcessActionAnnotationPortlet.doView()");
response.setContentType("text/html");
Contact contact = (Contact) request.getPortletSession().getAttribute(
"contact");
if (contact != null) {
response.getWriter().println(
"First Name " + contact.getFirstName() + "
Last Name "
+ contact.getLastName() + "
Email "
+ contact.getEmail());
} else {
response.getWriter().println("Contact not found in session ");
}
System.out.println("Exiting ProcessActionAnnotationPortlet.doView()");
}

//@ProcessEvent(name = "hello")
@ProcessEvent(qname="{http://wpcertification.blogspot.com}hello")
public void handleContactEvent(EventRequest request, EventResponse response)
throws PortletException, IOException {
System.out
.println("Entering ProcessActionAnnotationPortlet.handleContactEvent()");
Event event = request.getEvent();
System.out.println("Event Name " + event.getName());
System.out.println("Event Value " + event.getValue());
Contact contact = (Contact) event.getValue();
System.out.println("Contact First Name " + contact.getFirstName());
System.out.println("Contact Last Name " + contact.getLastName());
System.out.println("Contact Email " + contact.getEmail());
request.getPortletSession().setAttribute("contact", contact);
System.out
.println("Entering ProcessActionAnnotationPortlet.handleContactEvent()");
}

}


The ProcessEventAnnotationPortlet can act as target of hello event. It has a handleContactEvent method that can be used for handling the hello event. I can annotate it using either only local name like this @ProcessEvent(name = "hello") or using fully qualified name like this @ProcessEvent(qname="{http://wpcertification.blogspot.com}hello")

This is the portlet.xml for my Sample portlet

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0" 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">
<portlet>
<portlet-name>ProcessEventAnnotationPortlet</portlet-name>
<display-name>Process Event Annotation Portlet</display-name>
<portlet-class>com.webspherenotes.portlet.jsr286.ProcessEventAnnotationPortlet</portlet-class>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>edit</portlet-mode>
</supports>
<portlet-info>
<title>Process Event Annotation Portlet</title>
<short-title>Process Event Annotation Portlet</short-title>
<keywords>Process Event Annotation Portlet</keywords>
</portlet-info>
<supported-processing-event>
<name>hello</name>
</supported-processing-event>

</portlet>
<default-namespace>http://wpcertification.blogspot.com</default-namespace>
<event-definition>
<name>hello</name>
<value-type>com.webspherenotes.portlet.events.Contact</value-type>
</event-definition>

</portlet-app>