Blogs
Last post I talked about creating a wrapper to expose core functionality out to plugins. This time I'm going to leverage the same technique to allow you to make a custom tool available to Velocity templates without the need to edit any core classes.
The first step is to write your Tool or a wrapper for your tool following the Dependency Injection pattern.
Let's start with the interface:
package com.mytool;
public interface MyTool {
public String operationOne();
public String operationTwo(String name);
}
The util class:
package com.mytool;
public class MyToolUtil {
public static MyTool getMyTool() {
return _myTool;
}
public String operationOne() {
return getMyTool().operationOne();
}
public String operationTwo(String name) {
return getMyTool().operationTwo(name);
}
public void setMyTool(MyTool myTool) {
_myTool = myTool;
}
private static MyTool _myTool;
}
The implementation class:
package com.mytool;
public class MyToolImpl implements MyTool {
public String operationOne() {
return "Hello out there!";
}
public String operationTwo(String name) {
return "Hello " + name + "!";
}
}
Finally, we need to wire it all together. To do that create a src/META-INF/ext-spring.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="velocityUtilInterceptor" class="com.liferay.portal.spring.aop.BeanInterceptor"> <property name="exceptionSafe" value="true" /> </bean> <bean id="baseVelocityUtil" abstract="true"> <property name="interceptorNames"> <list> <value>velocityUtilInterceptor</value> </list> </property> </bean> <bean id="com.mytool.MyTool" class="com.mytool.MyToolImpl" /> <bean id="com.mytool.MyToolUtil" class="com.mytool.MyToolUtil"> <property name="myTool" ref="com.mytool.MyTool" /> </bean> <bean id="com.mytool.MyToolUtil.velocity" class="org.springframework.aop.framework.ProxyFactoryBean" parent="baseVelocityUtil"> <property name="target" ref="com.mytool.MyTool" /> </bean> </beans>
Now we're ready to use our tool in a Velocity template:
#set ($myTool = $utilLocator.findTool('com.mytool.MyToolUtil'))
$myTool.operationOne()
$myTool.operationTwo('Ray')
If you happened to define this in a ServiceBuilder enabled plugin, you will have to specify the 'contextPathName' of the plugin so that the appropriate classloader is used to lookup your tool. For example, the context path name of your plugin being "my-tool-portlet", then:
#set ($myTool = $utilLocator.findTool('my-tool-portlet', 'com.mytool.MyToolUtil'))
$myTool.operationOne()
$myTool.operationTwo('Ray')
Enjoy!

