There are several challenges when working with the Script Engine, including debugging and logging. One approach to overcome these challenges is to develop custom Java utilities that can be called from your scripts. These utilities can write to a custom log file or the Liferay log file. You can also place breakpoints in your utility code and step through it using your favorite debugger.
Liferay’s use of Spring and PortletBeanLocatorUtil
makes calling these Java
utilities from your script easy, regardless of the scripting language you’re
using.
Let’s begin by creating a Liferay Hook project. If you’re using Liferay IDE or Liferay Developer Studio, select File → New → Liferay Project. Name the project script-utils and accept the display name generated by the wizard. Be sure to select Hook for the Plugin Type and then select Finish.
Figure 18.1: Creating a new utilities project is easy if you use Liferay IDE or Liferay Developer Studio.
You’re using a Liferay Hook Plugin to deploy your utility, but you’re not using
any of the typical hook features. You just need a way to make your code
available to the portal and the Hook Plugin is the least obtrusive way to do
this. This means you don’t need to add anything to the liferay-hook.xml
file.
Instead, you’ll begin by adding your utility code.
You’ll be following the Dependency Injection design pattern so begin by creating
the interface. Right click on the docroot/WEB-INF/src
folder and select New
→ Interface. You’ll create your interface in the com.liferay.sample
package. Name it ScriptUtil
.
Figure 18.2: Create a new Java Interface which you'll later implement.
Next, add two methods to the interface.
package com.liferay.samples;
public interface ScriptUtil {
public String operationOne();
public String operationTwo(String name);
}
Next, create the implementation class. Right click on the docroot/WEB-INF/src
folder and select New → Class. Create the interface in the
com.liferay.sample
package and name it ScriptUtilImpl
. Be sure to select
com.liferay.sample.ScripUtil
as the Interface.
Figure 18.3: Create a new Java Class that implements the interface you created earlier.
Next, add implementations for the two methods.
package com.liferay.samples;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
public class ScriptUtilImpl implements ScriptUtil {
@Override
public String operationOne() {
return "Hello out there!";
}
@Override
public String operationTwo(String name) {
_log.debug("Inside of Operation Two");
return "Hello " + name + "!";
}
private static Log _log = LogFactoryUtil.getLog(ScriptUtilImpl.class);
}
Liferay makes extensive use of the Spring Framework and you’ll be using it here
to inject your implementation class into the application. Spring needs a bean
definition which you’ll declare in an XML file named applicationContext.xml
.
Create this file in the docroot/WEB-INF/
directory and add the following code:
<?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="com.liferay.sample.ScriptUtil" class="com.liferay.sample.ScriptUtilImpl" />
</beans>
Upon deployment, you’ll need the portal to create a BeanLocator
for your
plugin. The BeanLocator
reads the bean definitions you provided.
If you’re adding your utility to a Service Builder enabled plugin, then you’ll
already have a BeanLocator
and you can skip this step. Since this Hook plugin
is not already using Service Builder, you’ll need to define a context loader
listener in our Hook to provide a BeanLocator
. Open the
docroot/WEB-INF/web.xml
file and replace its contents with the following code:
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<listener>
<listener-class>com.liferay.portal.kernel.spring.context.PortletContextLoaderListener</listener-class>
</listener>
</web-app>
Save all of the changes you’ve made and deploy the hook. Once the hook has been
deployed successfully, the ScriptUtil
can be used in your script engine code.
To see the ScriptUtil
code in action, navigate back to the control panel
→ Server Administration → Script. Change the script type to Groovy
and enter the following script:
myUtil =
com.liferay.portal.kernel.bean.PortletBeanLocatorUtil.locate("script-utils-hook",
"com.liferay.samples.ScriptUtil")
println(myUtil.operationOne())
println(myUtil.operationTwo("Joe Bloggs"))
You should see the results of your script displayed right under the script.