Old Notifications Tutorial
Version 9.3 by Vincent Massol on 2017/09/01
Contents
This tutorial uses the old notification mechanism to listen to events (now deprecated in XWiki 2.0). You should follow it if you're using a version of XWiki Enterprise prior to 2.0.
In order to listen to events you need to write 2 pages:
- A page containing a Groovy class that registers against the XWiki Event Manager and that has the method to be called when the event happens.
- Another page that parses the Groovy page and loads it in the Groovy context.
Groovy Notification Class
Your Groovy needs to extend the com.xpn.xwiki.notify.XWikiDocChangeNotificationInterface as shown below.
/* Groovy Class #* */
import com.xpn.xwiki.api.*;
import com.xpn.xwiki.notify.*;
import com.xpn.xwiki.*;
import com.xpn.xwiki.doc.*;
public class MyGroovyClass implements XWikiDocChangeNotificationInterface
{
def xwiki;
def rule;
public MyGroovyClass()
{
this.rule = new DocChangeRule(this);
}
public void init(xwiki)
{
this.xwiki = xwiki;
xwiki.getXWiki().getNotificationManager().addGeneralRule(this.rule);
}
public void cleanup()
{
xwiki.getXWiki().getNotificationManager().removeGeneralRule(this.rule);
}
public void notify(XWikiNotificationRule rule, XWikiDocument newdoc, XWikiDocument olddoc,
int event, XWikiContext context)
{
// Do some action here.
}
}
/* *# */
In this example we've used a DocChangeRule rule. There are also other rules.
Calling the Groovy Class
#set($mygroovyclass = $xwiki.parseGroovyFromPage("MySpace.MyGroovyClass"))
$mygroovyclass.init($xwiki)
Example: IRC notification on document change
- Step 1: Groovy Class
/* Groovy Class #* */ import org.jibble.pircbot.*; import java.util.*; import com.xpn.xwiki.api.*; import com.xpn.xwiki.notify.*; import com.xpn.xwiki.*; import com.xpn.xwiki.doc.*; public class XWikiBot extends PircBot implements XWikiDocChangeNotificationInterface { def xwiki; def channel; def rule; public XWikiBot() { this.setName("xwikibot"); this.rule = new DocChangeRule(this); } public void init(xwiki, channel) { this.xwiki = xwiki; this.channel = channel; xwiki.getXWiki().getNotificationManager().addGeneralRule(this.rule); } public void cleanup() { xwiki.getXWiki().getNotificationManager().removeGeneralRule(this.rule); } public void notify(XWikiNotificationRule rule, XWikiDocument newdoc, XWikiDocument olddoc, int event, XWikiContext context) { sendMessage(this.channel, newdoc.getFullName() + " was modified - " + newdoc.getExternalURL("view", context)); } } /* *# */
- Step 2: Add the PircBot JAR as an attachment to the MySpace.MyGroovyClass page created in step 1.
- Step 3: Calling page
## Start by looking for a bot in the servlet context #set ($sc = $context.getContext().getEngineContext().getServletContext()) ## If the bot isn't in the servlet context, start the bot and put in the context #set ($bot = $sc.getAttribute("ircbot")) #if (!$bot) Bot is not started, starting it... #set($bot = $xwiki.parseGroovyFromPage("MySpace.MyGroovyClass", "MySpace.MyGroovyClass")) #set ($channel = "#xwiki") $bot.init($xwiki, $channel) $bot.connect("irc.freenode.net") $bot.joinChannel($channel) $sc.setAttribute("ircbot", $bot) Bot started! ## If the parameter passed is stop then stop the bot #elseif ($request.action && $request.action == "stop") $bot.cleanup() $bot.disconnect() $sc.setAttribute("ircbot", null) Bot disconnected! #else Bot already started, doing nothing... #end
- Step 4: Creating a Scheduler job so that the Bot is restarted automatically if the server is restarted for example.
Create a Scheduler job, set it to run every 5 minutes for example and use the following Groovy script in the job:
// Start by looking for a bot in the servlet context def sc = context.getEngineContext().getServletContext() // If the bot isn't in the servlet context, start the bot and put in the context def bot = sc.getAttribute("ircbot") if (bot == null) { // Bot is not started, starting it... bot = xwiki.parseGroovyFromPage("MySpace.MyGroovyClass", "MySpace.MyGroovyClass") def channel = "#xwiki" bot.init(xwiki, channel) bot.connect("irc.freenode.net") bot.joinChannel(channel) sc.setAttribute("ircbot", bot) // Bot started! }