Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "Scout/HowTo/3.9/Client notifications"
(New page: {{ScoutPage|cat=HowTo 3.9}} This how-to describes how to implement client notifications as described on the Client Notification Concept page. = S...) |
m |
||
Line 12: | Line 12: | ||
org.eclipse.minicrm.shared.CreateNotificationPermission | org.eclipse.minicrm.shared.CreateNotificationPermission | ||
org.eclipse.minicrm.shared.notification.XxxxNotification (one for each event, where Xxxx is the name of the event) | org.eclipse.minicrm.shared.notification.XxxxNotification (one for each event, where Xxxx is the name of the event) | ||
− | org.eclipse.minicrm.shared.services.process. | + | org.eclipse.minicrm.shared.services.process.INotificationService |
'''server''' | '''server''' | ||
Line 18: | Line 18: | ||
org.eclipse.minicrm.server\plugin.xml | org.eclipse.minicrm.server\plugin.xml | ||
org.eclipse.minicrm.server.services.custom.security.AccessControlService | org.eclipse.minicrm.server.services.custom.security.AccessControlService | ||
− | org.eclipse.minicrm.server. | + | org.eclipse.minicrm.server.NotificationService |
'''client''' | '''client''' | ||
Line 69: | Line 69: | ||
} | } | ||
</pre> | </pre> | ||
− | <br> '''org.eclipse.minicrm.shared.services.process. | + | <br> '''org.eclipse.minicrm.shared.services.process.INotificationService''' |
Create the skeleton for this interface: | Create the skeleton for this interface: | ||
<pre>@InputValidation(IValidationStrategy.NO_CHECK.class) | <pre>@InputValidation(IValidationStrategy.NO_CHECK.class) | ||
− | public interface | + | public interface INotificationService extends IService { |
} | } | ||
</pre> | </pre> | ||
Line 84: | Line 84: | ||
'''org.eclipse.minicrm.server\plugin.xml''' | '''org.eclipse.minicrm.server\plugin.xml''' | ||
− | In the extension section that contains the services, add the | + | In the extension section that contains the services, add the NotificationService: |
<service | <service | ||
factory="org.eclipse.scout.rt.server.services.ServerServiceFactory" | factory="org.eclipse.scout.rt.server.services.ServerServiceFactory" | ||
− | class="org.eclipse.minicrm.server.services.process. | + | class="org.eclipse.minicrm.server.services.process.NotificationService" |
session="org.eclipse.minicrm.server.ServerSession"> | session="org.eclipse.minicrm.server.ServerSession"> | ||
</service> | </service> | ||
Line 116: | Line 116: | ||
} | } | ||
− | '''org.eclipse.minicrm.server. | + | '''org.eclipse.minicrm.server.NotificationService''' |
Create the skeleton of this class: | Create the skeleton of this class: | ||
− | <pre>public class | + | <pre>public class NotificationService extends AbstractService implements INotificationService { |
− | private static IScoutLogger logger = ScoutLogManager.getLogger( | + | private static IScoutLogger logger = ScoutLogManager.getLogger(NotificationService.class); |
private final static long TIMEOUT = 1000 * 60 * 10; // 10min | private final static long TIMEOUT = 1000 * 60 * 10; // 10min | ||
} | } | ||
Line 140: | Line 140: | ||
'''org.eclipse.minicrm.client\plugin.xml''' | '''org.eclipse.minicrm.client\plugin.xml''' | ||
− | In the extension section that contains the services and proxies, add the service for the notification consumer service and the proxy for the | + | In the extension section that contains the services and proxies, add the service for the notification consumer service and the proxy for the NotificationService interface: |
<service | <service | ||
Line 149: | Line 149: | ||
<proxy | <proxy | ||
factory="org.eclipse.scout.rt.client.services.ClientProxyServiceFactory" | factory="org.eclipse.scout.rt.client.services.ClientProxyServiceFactory" | ||
− | class="org.eclipse.minicrm.shared.services.process. | + | class="org.eclipse.minicrm.shared.services.process.INotificationService"> |
</proxy> | </proxy> | ||
Line 249: | Line 249: | ||
In order to trigger a client notification (either from another client or from the server), use the following line: | In order to trigger a client notification (either from another client or from the server), use the following line: | ||
− | <pre> SERVICES.getService( | + | <pre> SERVICES.getService(INotificationService.class).sendXxxx(/* optional parameters */); |
</pre> | </pre> |
Latest revision as of 08:26, 3 July 2013
The Scout documentation has been moved to https://eclipsescout.github.io/.
This how-to describes how to implement client notifications as described on the Client Notification Concept page.
Summary
The following classes need to be changed or added to support this:
shared
org.eclipse.minicrm.shared\META-INF\MANIFEST.MF org.eclipse.minicrm.shared.CreateNotificationPermission org.eclipse.minicrm.shared.notification.XxxxNotification (one for each event, where Xxxx is the name of the event) org.eclipse.minicrm.shared.services.process.INotificationService
server
org.eclipse.minicrm.server\plugin.xml org.eclipse.minicrm.server.services.custom.security.AccessControlService org.eclipse.minicrm.server.NotificationService
client
org.eclipse.minicrm.client\plugin.xml org.eclipse.minicrm.client.ClientSession org.eclipse.minicrm.client.ui.desktop.Desktop org.eclipse.minicrm.client.services.IMyNotificationConsumerService org.eclipse.minicrm.client.services.MyNotificationConsumerService
The changes in detail are as follows:
org.eclipse.minicrm.shared\META-INF\MANIFEST.MF
Add the notification package to the exported packages:
Export-Package: org.eclipse.minicrm.shared, org.eclipse.minicrm.shared.notification, ... remaining packages ...
org.eclipse.minicrm.shared.CreateNotificationPermission
Create this file with the content as follows:
public class CreateNotificationPermission extends BasicPermission { private static final long serialVersionUID = 0L; public CreateNotificationPermission() { super(CreateNotificationPermission.class.getName()); } }
org.eclipse.minicrm.shared.notification.XxxxNotification
Create a notification class for each distinct event you want to be able to signal. Optionally, add members and a constructor if you need to pass information with the notification:
public class MessageNotification extends AbstractClientNotification { private static final long serialVersionUID = 1L; /* optional private members */ /* optional constructor */ public MessageNotification(/* parameters as needed */) { super(); /* assigning parameters to private members as needed */ } @Override public boolean coalesce(IClientNotification existingNotification) { return false; } }
org.eclipse.minicrm.shared.services.process.INotificationService
Create the skeleton for this interface:
@InputValidation(IValidationStrategy.NO_CHECK.class) public interface INotificationService extends IService { }
For each event that you want to notify independently, add a method (corresponding to the notifications above; add parameters if needed):
public void sendXxxx(/* optional parameters */) throws ProcessingException;
server
org.eclipse.minicrm.server\plugin.xml
In the extension section that contains the services, add the NotificationService:
<service factory="org.eclipse.scout.rt.server.services.ServerServiceFactory" class="org.eclipse.minicrm.server.services.process.NotificationService" session="org.eclipse.minicrm.server.ServerSession"> </service>
org.eclipse.minicrm.server.services.custom.security.AccessControlService
In the method execLoadPermissions() add the permission to create notifications and wrap the whole remainder of the class (defining user based permissions) in a check for null:
protected Permissions execLoadPermissions() { Permissions permissions = new Permissions(); permissions.add(new RemoteServiceAccessPermission("*.shared.*", "*")); permissions.add(new CreateNotificationPermission()); if (ServerSession.get().getPersonNr() != null) { // backdoor: the first user may do everything? if (ServerSession.get().getPersonNr().equals(1L)) { logger.warn("backdoor used: person nr 1 was granted all permissions"); permissions.add(new AllPermission()); } else { try { ... remaining code ... } } } return permissions; }
org.eclipse.minicrm.server.NotificationService
Create the skeleton of this class:
public class NotificationService extends AbstractService implements INotificationService { private static IScoutLogger logger = ScoutLogManager.getLogger(NotificationService.class); private final static long TIMEOUT = 1000 * 60 * 10; // 10min }
For each method that was added to the interface, add the implementation:
@Override public void sendXxxx(/* parameters as needed */) throws ProcessingException { if (!ACCESS.check(new CreateNotificationPermission())) { throw new VetoException(TEXTS.get("AuthorizationFailed")); } logger.info("queue 'Xxxx' notification on server"); IClientNotificationService service = SERVICES.getService(IClientNotificationService.class); service.putNotification(new XxxxNotification(/* parameters as needed */), new AllUserFilter(TIMEOUT)); }
client
org.eclipse.minicrm.client\plugin.xml
In the extension section that contains the services and proxies, add the service for the notification consumer service and the proxy for the NotificationService interface:
<service factory="org.eclipse.scout.rt.client.services.ClientServiceFactory" class="org.eclipse.minicrm.client.services.MyNotificationConsumerService" session="org.eclipse.minicrm.client.ClientSession"> </service> <proxy factory="org.eclipse.scout.rt.client.services.ClientProxyServiceFactory" class="org.eclipse.minicrm.shared.services.process.INotificationService"> </proxy>
org.eclipse.minicrm.client.ui.desktop.Desktop
Add the following method, allowing access to the Desktop object:
public static Desktop get() { return (Desktop) ClientSyncJob.getCurrentSession().getDesktop(); }
Add other getters to objects you might need in your NotificationConsumerService.
org.eclipse.minicrm.client.ClientSession
Modify the execLoadSession() method to enable client notifications:
@Override public void execLoadSession() throws ProcessingException { setServiceTunnel(new HttpServiceTunnel(this, getBundle().getBundleContext().getProperty("server.url"))); //pre-load all known code types CODES.getAllCodeTypes(org.eclipse.minicrm.shared.Activator.PLUGIN_ID); // turn client notification polling on getServiceTunnel().setClientNotificationPollInterval(2000L); IMyNotificationConsumerService notificationHandlerService = SERVICES.getService(IMyNotificationConsumerService.class); SERVICES.getService(IClientNotificationConsumerService.class).addClientNotificationConsumerListener(this, notificationHandlerService); setDesktop(new Desktop()); }
Modify the execStoreSession() method to end client notifiaction:
@Override public void execStoreSession() throws ProcessingException { ClientSession.get().getServiceTunnel().setClientNotificationPollInterval(-1); }
org.eclipse.minicrm.client.services.IMyNotificationConsumerService
Create this empty interface:
public interface IMyNotificationConsumerService extends IService, IClientNotificationConsumerListener { }
org.eclipse.minicrm.client.services.MyNotificationConsumerService
Create the notification consumer class. Add a block for each event you have defined in the shared project:
public class MyNotificationConsumerService extends AbstractService implements IMyNotificationConsumerService { private static IScoutLogger logger = ScoutLogManager.getLogger(MyNotificationConsumerService.class); @Override public void handleEvent(ClientNotificationConsumerEvent e, boolean sync) { logger.info("received client notification event for user '" + ClientSyncJob.getCurrentSession().getUserId() + "'"); final IClientNotification notification = e.getClientNotification(); final IClientSession session = ClientSyncJob.getCurrentSession(); // deal with notification in async jobs to prevent blocking of the model thread if (notification instanceof XxxxNotification) { new ClientAsyncJob("async wrapper (Xxxx)", session) { @Override protected void runVoid(IProgressMonitor monitor) throws Throwable { new ClientSyncJob("Xxxx", session) { @Override protected void runVoid(IProgressMonitor monitor1) throws Throwable { Desktop desktop = Desktop.get(); if (desktop != null) { /* do whatever is needed to react to this event */ } } }.schedule(); } }.schedule(); } else if (notification instanceof XxxxNotification) { new ClientAsyncJob("async wrapper (Xxxx)", session) { @Override protected void runVoid(IProgressMonitor monitor) throws Throwable { new ClientSyncJob("Xxxx", session) { @Override protected void runVoid(IProgressMonitor monitor1) throws Throwable { Desktop desktop = Desktop.get(); if (desktop != null) { /* do whatever is needed to react to this event */ } } }.schedule(); } }.schedule(); } } }
Triggering an event
In order to trigger a client notification (either from another client or from the server), use the following line:
SERVICES.getService(INotificationService.class).sendXxxx(/* optional parameters */);