JSR-286 Support



ColdFusion 9 also supports JSR-286 specifications. In portlets there are three types of requests: action, event, and render. A portlet first handles an action request, and then an event request, and only after that, it would render any request.

Some of the capabilities of JSR-286 include the following:

Publishing and Processing Events

To define an event, you would have to declare it in portlet.xml

<event-definition> 
<qname xmlns:cf="http://adobe.com/coldfusion/portlet/example">cf:HelloEvent 
</qname> 
    <value-type>java.lang.String</value-type> 
</event-definition>

This code defines an event named cf:HelloEvent, where cf refers to the namespace and HelloEvent is the local name. Its type is defined by the <value-type> tag. These event definitions require you to use qname to uniquely identify the event.

Now add the events to specific portlets, which are either going to publish (generate) an event or process (consume) an event. You add this information to portlet.xml as well.

<supported-publishing-event> tag is used to publish an event.

Publishing an event (Event producer)

<portlet> 
… 
<supported-publishing-event> 
<qname xmlns:cf="http://adobe.com/coldfusion/portlet/example">cf:HelloEvent</qname> 
</supported-publishing-event> 
…     
</portlet>

Processing an event (event consumer)

<portlet> 
…. 
<supported-processing-event> 
<qname xmlns:cf="http://adobe.com/coldfusion/portlet/example">cf:HelloEvent</qname> 
</supported-processing-event> 
….. 
</portlet>

Portlet definition can have both publishing and processing tags. portlet.xml file has event definition, publishing event, and processing event tags, as its portlets create and consume events.

Initiate events in portlet (CFC)

You publish events in the processAction() method of the portlet code by calling setEvent() on the ActionResponse object. This setEvent() method takes two parameters: the QName of the event object and the type of object defined in portlet.xml.

Following is an example of processAction() method.

<cffunction name="processAction" returntype="void" access="public" output="false" hint="Called by the portlet container to allow the portlet to process an action request."> 
        <cfargument name="actionRequest" type="any" required="true" hint="A javax.portlet.ActionRequest java object"> 
        <cfargument name="actionResponse" type="any" required="true" hint="A javax.portlet.ActionResponse java object"> 
        <cfset super.processAction(arguments.actionRequest, arguments.actionResponse)> 
        <!--- send event notification ---> 
        <cftry> 
            <cfset arguments.actionResponse.setEvent("HelloEvent", request.portlet.parameters.event_value)> 
            <cfcatch type="any"> 
                <cflog file="simple-event-portlet" type="error" text="processAction() threw exception: #cfcatch.message#"> 
            </cfcatch> 
        </cftry> 
</cffunction>

Capture events in processEvent() method:

<cffunction name="processEvent" returntype="void" access="public" output="false" hint="Called by the portlet container requesting the portlet to process a specific event."> 
        <cfargument name="eventRequest" type="any" required="true" hint="A javax.portlet.EventRequest java object"> 
        <cfargument name="eventResponse" type="any" required="true" hint="A javax.portlet.EventResponse java object"> 
    <cfset var e = StructNew()> 
    <cftry> 
        <cfset e.name = arguments.eventRequest.getEvent().getName()> 
        <cfset e.value = arguments.eventRequest.getEvent().getValue()> 
    <cfif NOT IsDefined("application.EventReceivingPortletEvents")> 
        <cfset application.EventReceivingPortletEvents = ArrayNew(1)> 
    </cfif> 
        <cfset ArrayAppend(application.EventReceivingPortletEvents,e)> 
            <cfcatch type="any"> 
                 
            </cfcatch> 
    </cftry> 
</cffunction>

Using filters

Filter definition and mapping in portlet.xml

<filter> 
    <filter-name>Example ColdFusion Filter</filter-name> 
    <filter-class>coldfusion.portlet.ColdFusionPortletFilter</filter-class> 
    <lifecycle>RENDER_PHASE</lifecycle> 
    <lifecycle>EVENT_PHASE</lifecycle> 
    <lifecycle>RESOURCE_PHASE</lifecycle> 
    <lifecycle>ACTION_PHASE</lifecycle> 
    <init-param> 
        <name>cfcName</name> 
        <value>portlets.filter.ExampleFilter</value> 
    </init-param> 
</filter> 

Add filter mapping, that filter applied to particular portlet.

<!-- Applies Example Filter to All Portlets --> 
    <filter-mapping> 
        <filter-name>Example ColdFusion Filter</filter-name> 
        <portlet-name>*</portlet-name> 
    </filter-mapping> 

ExampleFilter.cfc:

The following is the ExampleFilter.cfc mentioned in the portlet.xml.

<cfcomponent extends="CFIDE.portlets.filter.ColdFusionPortletFilter"> 
        <cffunction name="doRenderFilter" returntype="void"> 
        <cfargument name="renderRequest"> 
        <cfargument name="renderResponse"> 
        <cfargument name="filterChain"> 
        <cflog file="portlet-filter" type="information" text="doRenderFilter() invoked"> 
        <!--- call the next filter in the chain ---> 
        <cfset arguments.filterChain.doFilter(arguments.renderRequest, arguments.renderResponse)> 
    </cffunction> 
    <cffunction name="doActionFilter" returntype="void"> 
        <cfargument name="actionRequest"> 
        <cfargument name="actionResponse"> 
        <cfargument name="filterChain"> 
        <cflog file="portlet-filter" type="information" text="doActionFilter() invoked"> 
        <!--- call the next filter in the chain ---> 
        <cfset arguments.filterChain.doFilter(arguments.actionRequest, arguments.actionResponse)> 
    </cffunction> 
    <cffunction name="doResourceFilter" returntype="void"> 
        <cfargument name="resourceRequest"> 
        <cfargument name="resourceResponse"> 
        <cfargument name="filterChain"> 
        <cflog file="portlet-filter" type="information" text="doResourceFilter() invoked"> 
        <!--- call the next filter in the chain ---> 
        <cfset arguments.filterChain.doFilter(arguments.resourceRequest, arguments.resourceResponse)> 
    </cffunction> 
    <cffunction name="doEventFilter" returntype="void"> 
        <cfargument name="eventRequest"> 
        <cfargument name="eventResponse"> 
        <cfargument name="filterChain"> 
        <cflog file="portlet-filter" type="information" text="doEventFilter() invoked"> 
        <!--- call the next filter in the chain ---> 
        <cfset arguments.filterChain.doFilter(arguments.eventRequest, arguments.eventResponse)> 
    </cffunction> 
</cfcomponent>