/*******************************************************************************
* Copyright (c) 2012 RelationWare, Benno Luthiger
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* RelationWare, Benno Luthiger
******************************************************************************/
package org.ripla.useradmin.internal;
import org.eclipse.osgi.framework.eventmgr.CopyOnWriteIdentityMap;
import org.eclipse.osgi.framework.eventmgr.EventDispatcher;
import org.eclipse.osgi.framework.eventmgr.EventManager;
import org.eclipse.osgi.framework.eventmgr.ListenerQueue;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.UserAdmin;
import org.osgi.service.useradmin.UserAdminEvent;
import org.osgi.service.useradmin.UserAdminListener;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* UserAdminEventProducer is responsible for sending out UserAdminEvents to all
* UserAdminListeners.
*
* @author Luthiger
*/
public class UserAdminEventProducer extends ServiceTracker implements
EventDispatcher {
private static final Logger LOG = LoggerFactory
.getLogger(UserAdminEventProducer.class);
static protected final String USER_ADMIN_LISTENER_CLASS = "org.osgi.service.useradmin.UserAdminListener"; //$NON-NLS-1$
protected transient ServiceReference<? extends UserAdmin> userAdmin;
/** List of UserAdminListeners */
protected transient CopyOnWriteIdentityMap<ServiceReference<UserAdmin>, ServiceReference<UserAdmin>> listeners;
/** EventManager for event delivery. */
protected transient EventManager eventManager;
public UserAdminEventProducer(
final ServiceReference<? extends UserAdmin> inUserAdminRef,
final BundleContext inContext) {
super(inContext, USER_ADMIN_LISTENER_CLASS, null);
userAdmin = inUserAdminRef;
final ThreadGroup eventGroup = new ThreadGroup("Ripla User Admin"); //$NON-NLS-1$ // NOPMD by Luthiger on 07.09.12 00:26
eventGroup.setDaemon(true);
eventManager = new EventManager(
"UserAdmin Event Dispatcher", eventGroup); //$NON-NLS-1$
listeners = new CopyOnWriteIdentityMap<ServiceReference<UserAdmin>, ServiceReference<UserAdmin>>();
open();
}
@Override
public void close() {
super.close();
listeners.clear();
eventManager.close();
userAdmin = null; // NOPMD by Luthiger on 07.09.12 00:25
}
public void generateEvent(final int inType, final Role inRole) {
if (userAdmin != null) {
final UserAdminEvent lEvent = new UserAdminEvent(userAdmin, inType,
inRole);
/* queue to hold set of listeners */
final ListenerQueue<ServiceReference<UserAdmin>, ServiceReference<UserAdmin>, UserAdminEvent> queue = new ListenerQueue<ServiceReference<UserAdmin>, ServiceReference<UserAdmin>, UserAdminEvent>(
eventManager);
/* add set of UserAdminListeners to queue */
queue.queueListeners(listeners.entrySet(), this);
/* dispatch event to set of listeners */
queue.dispatchEventAsynchronous(0, lEvent);
}
}
/**
* A service is being added to the <tt>ServiceTracker</tt> object.
*
* <p>
* This method is called before a service which matched the search
* parameters of the <tt>ServiceTracker</tt> object is added to it. This
* method should return the service object to be tracked for this
* <tt>ServiceReference</tt> object. The returned service object is stored
* in the <tt>ServiceTracker</tt> object and is available from the
* <tt>getService</tt> and <tt>getServices</tt> methods.
*
* @param inReference
* Reference to service being added to the
* <tt>ServiceTracker</tt> object.
* @return The service object to be tracked for the
* <tt>ServiceReference</tt> object or <tt>null</tt> if the
* <tt>ServiceReference</tt> object should not be tracked.
*/
public UserAdmin addingService(final ServiceReference<UserAdmin> inReference) {
final UserAdmin outService = (UserAdmin) super
.addingService(inReference);
listeners.put(inReference, inReference);
return outService;
}
/**
* A service tracked by the <tt>ServiceTracker</tt> object has been removed.
*
* <p>
* This method is called after a service is no longer being tracked by the
* <tt>ServiceTracker</tt> object.
*
* @param inReference
* Reference to service that has been removed.
* @param inService
* The service object for the removed service.
*/
@Override
public void removedService(final ServiceReference inReference,
final Object inService) {
listeners.remove(inService);
super.removedService(inReference, inService);
}
/**
* This method is the call back that is called once for each listener. This
* method must cast the EventListener object to the appropriate listener
* class for the event type and call the appropriate listener method.
*
* @param inListener
* This listener must be cast to the appropriate listener class
* for the events created by this source and the appropriate
* listener method must then be called.
* @param inListenerObject
* This is the optional object that was passed to
* ListenerList.addListener when the listener was added to the
* ListenerList.
* @param inEventAction
* This value was passed to the EventQueue object via one of its
* dispatchEvent* method calls. It can provide information (such
* as which listener method to call) so that this method can
* complete the delivery of the event to the listener.
* @param inEventObject
* This object was passed to the EventQueue object via one of its
* dispatchEvent* method calls. This object was created by the
* event source and is passed to this method. It should contain
* all the necessary information (such as what event object to
* pass) so that this method can complete the delivery of the
* event to the listener.
*/
@Override
public void dispatchEvent(final Object inListener,
final Object inListenerObject, final int inEventAction,
final Object inEventObject) {
if (userAdmin == null) {
return;
}
final UserAdminListener lUserAdminListener = (UserAdminListener) inListener;
try {
lUserAdminListener.roleChanged((UserAdminEvent) inEventObject);
}
catch (final Throwable t) { // NOPMD by Luthiger on 07.09.12 00:25
LOG.error("Error encountered while dispatching the event!", t);
}
}
}