You are looking at documentation for an older release. Not what you want? See the current release documentation.
eXo Platform provides you with a notification system that allows you to extend in 2 mechanisms:
The extensibility of notification channels, such as by email, directly on-site or through pushing.
The extensibility of notification types, such as connection invitation, space activities.
This section will walk you through a complete sample extension that instructs you how to:
create a new notification channel that pushes notification information to the console panel.
create a new notification type that informs when one user in your network changes her/his profile.
First you need to create a new Maven project with the overall structure:
And now, continue with the detailed steps:
Under pom.xml
Add the following dependencies to the pom.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.acme.samples</groupId>
<artifactId>console-notification</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>lib</module>
<module>config</module>
<module>webapp</module>
</modules>
<properties>
<org.exoplatform.depmgt.version>10-SNAPSHOT</org.exoplatform.depmgt.version>
<org.exoplatform.kernel.version>2.4.9-GA</org.exoplatform.kernel.version>
<org.exoplatform.core.version>2.5.9-GA</org.exoplatform.core.version>
<!--GateIn project's dependencies-->
<org.gatein.portal.version>3.5.10.Final</org.gatein.portal.version>
<!--Platform project's dependencies-->
<org.exoplatform.social.version>4.2.x-SNAPSHOT</org.exoplatform.social.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Import versions from platform project -->
<dependency>
<groupId>org.exoplatform</groupId>
<artifactId>maven-depmgt-pom</artifactId>
<version>${org.exoplatform.depmgt.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.social</groupId>
<artifactId>social</artifactId>
<version>${org.exoplatform.social.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- To be replaced by an import of GateIn Portal parent POM -->
<dependency>
<groupId>org.gatein.portal</groupId>
<artifactId>exo.portal.component.portal</artifactId>
<version>${org.gatein.portal.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Under config folder
Create a pom.xml
file and two configuration.xml
files under config
folder as below:
Add the following information to config/pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.acme.samples</groupId>
<artifactId>console-notification</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>console-notification-config</artifactId>
<packaging>jar</packaging>
<build>
<finalName>console-notification-config</finalName>
</build>
</project>
Add the below configuration to conf/configuration.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.exoplatform.org/xml/ns/kernel_1_2.xsd http://www.exoplatform.org/xml/ns/kernel_1_2.xsd"
xmlns="http://www.exoplatform.org/xml/ns/kernel_1_2.xsd">
<external-component-plugins>
<!-- The full qualified name of the PortalContainerConfig -->
<target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
<component-plugin>
<!-- The name of the plugin -->
<name>Add PortalContainer Definitions</name>
<!-- The name of the method to call on the PortalContainerConfig in order to register the PortalContainerDefinitions -->
<set-method>registerChangePlugin</set-method>
<!-- The full qualified name of the PortalContainerDefinitionPlugin -->
<type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
<priority>102</priority>
<init-params>
<values-param>
<name>apply.specific</name>
<value>portal</value>
</values-param>
<object-param>
<name>addDependencies</name>
<object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
<!-- The name of the portal container -->
<field name="dependencies">
<collection type="java.util.ArrayList">
<value>
<!--The context name of the portal extension-->
<string>console-notification-webapp</string>
</value>
</collection>
</field>
</object>
</object-param>
</init-params>
</component-plugin>
</external-component-plugins>
</configuration>
Add the following configuration to portal/configuration.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.exoplatform.org/xml/ns/kernel_1_2.xsd http://www.exoplatform.org/xml/ns/kernel_1_2.xsd"
xmlns="http://www.exoplatform.org/xml/ns/kernel_1_2.xsd">
<external-component-plugins>
<target-component>org.exoplatform.social.core.manager.IdentityManager</target-component>
<component-plugin>
<name>SocialProfileListener</name>
<set-method>registerProfileListener</set-method>
<type>com.acme.samples.notification.SocialProfileListener</type>
</component-plugin>
</external-component-plugins>
<external-component-plugins>
<target-component>org.exoplatform.commons.api.notification.channel.ChannelManager</target-component>
<component-plugin profiles="all">
<name>console.channel</name>
<set-method>register</set-method>
<type>com.acme.samples.notification.ConsoleChannel</type>
<description>Register the console channel to manager.</description>
</component-plugin>
</external-component-plugins>
<external-component-plugins>
<target-component>org.exoplatform.commons.api.notification.service.setting.PluginContainer</target-component>
<component-plugin>
<name>notification.plugins</name>
<set-method>addPlugin</set-method>
<type>com.acme.samples.notification.plugin.UpdateProfilePlugin</type>
<description>Initial information for plugin.</description>
<init-params>
<object-param>
<name>template.UpdateProfilePlugin</name>
<description>The template of UpdateProfilePlugin</description>
<object
type="org.exoplatform.commons.api.notification.plugin.config.PluginConfig">
<field name="pluginId">
<string>UpdateProfilePlugin</string>
</field>
<field name="resourceBundleKey">
<string>UINotification.label.UpdateProfilePlugin</string>
</field>
<field name="order">
<string>11</string>
</field>
<field name="defaultConfig">
<collection type="java.util.ArrayList">
<value>
<string>Instantly</string>
</value>
</collection>
</field>
<field name="groupId">
<string>general</string>
</field>
<field name="bundlePath">
<string>locale.notification.template.Notification</string>
</field>
</object>
</object-param>
</init-params>
</component-plugin>
</external-component-plugins>
</configuration>
Register | |
Register new plugin | |
Register new plugin
|
Under lib folder
Create another project under lib
folder with the pom.xml
file as below:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.acme.samples</groupId>
<artifactId>console-notification</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>console-notification-lib</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.social</groupId>
<artifactId>social-component-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.core</groupId>
<artifactId>exo.core.component.organization.api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.social</groupId>
<artifactId>social-component-common</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>console-notification-lib</finalName>
</build>
</project>
Implement the class UpdateProfilePlugin.java
as follows:
package com.acme.samples.notification.plugin;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import org.exoplatform.commons.api.notification.NotificationContext;
import org.exoplatform.commons.api.notification.model.ArgumentLiteral;
import org.exoplatform.commons.api.notification.model.NotificationInfo;
import org.exoplatform.commons.api.notification.plugin.BaseNotificationPlugin;
import org.exoplatform.commons.utils.CommonsUtils;
import org.exoplatform.commons.utils.ListAccess;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.social.core.identity.model.Identity;
import org.exoplatform.social.core.identity.model.Profile;
import org.exoplatform.social.core.manager.RelationshipManager;
public class UpdateProfilePlugin extends BaseNotificationPlugin {
public final static ArgumentLiteral<Profile> PROFILE = new ArgumentLiteral<Profile>(Profile.class, "profile");
private static final Log LOG = ExoLogger.getLogger(UpdateProfilePlugin.class);
public final static String ID = "UpdateProfilePlugin";
public UpdateProfilePlugin(InitParams initParams) {
super(initParams);
}
@Override
public String getId() {
return ID;
}
@Override
public boolean isValid(NotificationContext ctx) {
return true;
}
@Override
protected NotificationInfo makeNotification(NotificationContext ctx) {
Profile profile = ctx.value(PROFILE);
Set<String> receivers = new HashSet<String>();
RelationshipManager relationshipManager = CommonsUtils.getService(RelationshipManager.class);
Identity updatedIdentity = profile.getIdentity();
ListAccess<Identity> listAccess = relationshipManager.getConnections(updatedIdentity);
try {
Identity[] relationships = relationshipManager.getConnections(updatedIdentity).load(0, listAccess.getSize());
for(Identity i : relationships) {
receivers.add(i.getRemoteId());
}
} catch (Exception ex) {
LOG.error(ex.getMessage(), ex);
}
return NotificationInfo.instance()
.setFrom(updatedIdentity.getRemoteId())
.to(new ArrayList<String>(receivers))
.setTitle(updatedIdentity.getProfile().getFullName() + " updated his/her profile.<br/>")
.key(getId());
}
}
This class extends | |
The |
Implement the class SocialProfileListener.java
as below:
package com.acme.samples.notification;
import org.exoplatform.commons.api.notification.NotificationContext;
import org.exoplatform.commons.api.notification.model.PluginKey;
import org.exoplatform.commons.notification.impl.NotificationContextImpl;
import org.exoplatform.social.core.identity.model.Profile;
import org.exoplatform.social.core.profile.ProfileLifeCycleEvent;
import org.exoplatform.social.core.profile.ProfileListenerPlugin;
import com.acme.samples.notification.plugin.UpdateProfilePlugin;
public class SocialProfileListener extends ProfileListenerPlugin {
@Override
public void avatarUpdated(ProfileLifeCycleEvent event) {
Profile profile = event.getProfile();
NotificationContext ctx = NotificationContextImpl.cloneInstance().append(UpdateProfilePlugin.PROFILE, profile);
ctx.getNotificationExecutor().with(ctx.makeCommand(PluginKey.key(UpdateProfilePlugin.ID))).execute(ctx);
}
@Override
public void experienceSectionUpdated(ProfileLifeCycleEvent event) {
Profile profile = event.getProfile();
NotificationContext ctx = NotificationContextImpl.cloneInstance().append(UpdateProfilePlugin.PROFILE, profile);
ctx.getNotificationExecutor().with(ctx.makeCommand(PluginKey.key(UpdateProfilePlugin.ID))).execute(ctx);
}
@Override
public void contactSectionUpdated(ProfileLifeCycleEvent event) {
Profile profile = event.getProfile();
NotificationContext ctx = NotificationContextImpl.cloneInstance().append(UpdateProfilePlugin.PROFILE, profile);
ctx.getNotificationExecutor().with(ctx.makeCommand(PluginKey.key(UpdateProfilePlugin.ID))).execute(ctx);
}
@Override
public void createProfile(ProfileLifeCycleEvent event) {
Profile profile = event.getProfile();
NotificationContext ctx = NotificationContextImpl.cloneInstance().append(UpdateProfilePlugin.PROFILE, profile);
ctx.getNotificationExecutor().with(ctx.makeCommand(PluginKey.key(UpdateProfilePlugin.ID))).execute(ctx);
}
}
This class extends
|
Implement the class ConsoleChannel.java
to have the following code:
package com.acme.samples.notification;
import java.io.Writer;
import org.exoplatform.commons.api.notification.NotificationContext;
import org.exoplatform.commons.api.notification.channel.AbstractChannel;
import org.exoplatform.commons.api.notification.channel.template.AbstractTemplateBuilder;
import org.exoplatform.commons.api.notification.channel.template.TemplateProvider;
import org.exoplatform.commons.api.notification.model.ChannelKey;
import org.exoplatform.commons.api.notification.model.MessageInfo;
import org.exoplatform.commons.api.notification.model.NotificationInfo;
import org.exoplatform.commons.api.notification.model.PluginKey;
import org.exoplatform.commons.notification.lifecycle.SimpleLifecycle;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
public class ConsoleChannel extends AbstractChannel {
private static final Log LOG = ExoLogger.getLogger(ConsoleChannel.class);
private final static String ID = "CONSOLE_CHANNEL";
private final ChannelKey key = ChannelKey.key(ID);
public ConsoleChannel() {
super(new SimpleLifecycle());
}
@Override
public String getId() {
return ID;
}
@Override
public ChannelKey getKey() {
return key;
}
@Override
public void dispatch(NotificationContext ctx, String userId) {
LOG.info(String.format("CONSOLE:: %s will receive the message from pluginId: %s",
userId,
ctx.getNotificationInfo().getKey().getId()));
}
@Override
public void registerTemplateProvider(TemplateProvider provider) {}
@Override
protected AbstractTemplateBuilder getTemplateBuilderInChannel(PluginKey key) {
return new AbstractTemplateBuilder() {
@Override
protected MessageInfo makeMessage(NotificationContext ctx) {
return null;
}
@Override
protected boolean makeDigest(NotificationContext ctx, Writer writer) {
return false;
}
};
}
}
This concrete class extends | |
The |
Under webapp folder
Create a new Maven project inside webapp
folder with the following pom.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.acme.samples</groupId>
<artifactId>console-notification</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>console-notification-webapp</artifactId>
<packaging>war</packaging>
<build>
<finalName>console-notification-webapp</finalName>
</build>
</project>
Add the following configurations to WEB-INF/web.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
metadata-complete="true"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>console-notification-webapp</display-name>
<filter>
<filter-name>ResourceRequestFilter</filter-name>
<filter-class>org.exoplatform.portal.application.ResourceRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ResourceRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
display-name
- should be the same as the context name of the portal extension.
Open Notification_en.properties
file to add this text:
###########################################
# UpdateProfilePlugin #
###########################################
# For UI
UINotification.title.UpdateProfilePlugin= Someone updates profile
UINotification.label.UpdateProfilePlugin= Someone updates profile
This is a resource bundle for English language. The value of UINotification.title.UpdateProfilePlugin
and UINotification.label.UpdateProfilePlugin
will be used to display as English name of the new notification type through user interface.
Testing
Go up to the parent project's folder and build it with the command: mvn clean install.
Copy the generated jar and war files into the corresponding deployment folders where you unpacked the eXo Platform installation.
Start eXo Platform and you will see your new functions appear in Notification Settings:
Log in as a user and update avatar or experience (remember to enable notification plugins first by an administrator).
Now, a message informing about this activity will be pushed to all notification channels, for instance:
directly on-site:
or on the console, there will be a message for each user who is connecting with the above user, such as:
James will receive the message from pluginId: UpdateProfilePlugin