Old Notifications Tutorial
Last modified by Vincent Massol on 2020/01/28
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 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.
}
}
/* *# */
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)
$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!
}