Calling Liferay Services from XSL Journal Templates

Recently I was again asked how to call a more complex Liferay service using XSL.

Here is an example of getting CalEvents from XSL and printing the list. The first thing you might find is that the iteration is rather strange. That's because XSL has no notion of arrays or lists, other than nodelists that is. So we have to get around that by creating a template construct to represent our loop logic.

<?xml version="1.0"?>
<xsl:stylesheet 
	version="1.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:getterUtil="xalan://com.liferay.portal.kernel.util.GetterUtil"
	xmlns:java="http://xml.apache.org/xalan/java"
	xmlns:calEventLocalServiceUtil="xalan://com.liferay.portlet.calendar.service.CalEventLocalServiceUtil"
	xmlns:calFactoryUtil="xalan://com.liferay.portal.kernel.util.CalendarFactoryUtil"
	xmlns:userLocalServiceUtil="xalan://com.liferay.portal.service.UserLocalServiceUtil"
	exclude-result-prefixes="java" 
	extension-element-prefixes="getterUtil userLocalServiceUtil">

	<xsl:output method="html" omit-xml-declaration="yes"/>
	<xsl:param name="groupId" />
	<xsl:param name="locale" />
		
	<xsl:template match="/">

		<xsl:variable name="remote-user" select="/root/request/remote-user" />
		
		<xsl:text>Remote User: </xsl:text>
		<xsl:value-of select="$remote-user" />
		
		<div class="separator"><!--//--></div>
		
		<xsl:choose>
			<xsl:when test="$remote-user != ''">
				<xsl:variable name="user" select="userLocalServiceUtil:getUserById(getterUtil:getLong($remote-user))" />
				<xsl:variable name="timeZone" select="java:getTimeZone($user)" />
				<xsl:variable name="calendar" select="calFactoryUtil:getCalendar($timeZone, $locale)" />
				<xsl:variable name="events" select="calEventLocalServiceUtil:getEvents($groupId, $calendar)" />
	
				<xsl:value-of select="java:size($events)" />
				<xsl:text> events were found.</xsl:text>
				<br/><br/>

				<xsl:call-template name="for.loop">
					<xsl:with-param name="i" select="'0'" />
					<xsl:with-param name="count" select="java:size($events)" />
					<xsl:with-param name="list" select="$events" />
				</xsl:call-template>

			</xsl:when>
			<xsl:otherwise>
				<xsl:text>Hello! Please log in.</xsl:text>
			</xsl:otherwise>
		</xsl:choose>

	</xsl:template>

	<!-- This is what you customize to tailor your output per item. -->
	<xsl:template name="do.item">
		<xsl:param name="i" />

		<!-- 'item' is an object in the list -->
		<xsl:param name="item" />
		
		<xsl:value-of select="java:getTitle($item)" />
		<br/>
 	 </xsl:template>

	<!-- Don't touch bellow code. -->
	<xsl:template name="for.loop">
		<xsl:param name="i" />
		<xsl:param name="count" />
		<xsl:param name="list" />

		<xsl:if test="$i &lt; $count">
  	 	 	<xsl:call-template name="do.item">
 	 	 	 	<xsl:with-param name="i" select="$i" />
 	 	 	 	<xsl:with-param name="item" select="java:get($list, $i)" />
 	 	 	</xsl:call-template>
		</xsl:if>
 
 		<xsl:if test="$i &lt; $count">
  	 	 	<xsl:call-template name="for.loop">
 	 	 	 	<xsl:with-param name="i" select="$i + 1" />
  	 	 	 	<xsl:with-param name="count" select="$count" />
  	 	 	 	<xsl:with-param name="list" select="$list" />
 	 	 	</xsl:call-template>
 	 	 </xsl:if>
 	 </xsl:template>

</xsl:stylesheet>

There is no need to change the for.loop template. Only change the do.item template to operate on your list item. The for.loop can be re-used and in fact could be placed in a utility template and included rather than embedded.

Another thing you might ask is where did groupId and locale parameters come from. Well, those are two params automatically included in all our Journal XSL templates. You can just use them.

Blogs
Which other params are automatically included in all our Journal XSL templates?
This [editted] does NOT work... :/
Can you describe with some detail the problem you are having?

We use xerces2-j/xalan as the default xml libraries, so if you follow the techniques for java interaction as define by those libraries everything described above should work fine.
I am getting t be invoked when the Extension function: '{xalan://com.liferay.portal.kernel.util.CalendarFactoryUtil}getCalendar' can not be invoked when the XMLConstants.FEATURE_SECURE_PROCESSING feature is set to true.