/******************************************************************************* * Copyright (c) 2005, 2013 Cognos Incorporated, IBM Corporation and others. * 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: * Cognos Incorporated - initial API and implementation * IBM Corporation - bug fixes and enhancements *******************************************************************************/ package org.eclipse.equinox.internal.cm; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.cm.*; import org.osgi.service.log.LogService; import org.osgi.util.tracker.ServiceTracker; /** * EventDispatcher is responsible for delivering Configuration Events to ConfigurationListeners. * The originating ConfigAdmin ServiceReference is needed when delivering events. This reference * is made available by the service factory before returning the service object. */ public class EventDispatcher { final ServiceTracker<ConfigurationListener, ConfigurationListener> tracker; final ServiceTracker<SynchronousConfigurationListener, SynchronousConfigurationListener> syncTracker; private final SerializedTaskQueue queue = new SerializedTaskQueue("ConfigurationListener Event Queue"); //$NON-NLS-1$ /** @GuardedBy this */ private ServiceReference<ConfigurationAdmin> configAdminReference; final LogTracker log; public EventDispatcher(BundleContext context, LogTracker log) { this.log = log; tracker = new ServiceTracker<ConfigurationListener, ConfigurationListener>(context, ConfigurationListener.class, null); syncTracker = new ServiceTracker<SynchronousConfigurationListener, SynchronousConfigurationListener>(context, SynchronousConfigurationListener.class, null); } public void start() { tracker.open(); syncTracker.open(); } public void stop() { tracker.close(); syncTracker.close(); synchronized (this) { configAdminReference = null; } } synchronized void setServiceReference(ServiceReference<ConfigurationAdmin> reference) { if (configAdminReference == null) configAdminReference = reference; } public void dispatchEvent(int type, String factoryPid, String pid) { final ConfigurationEvent event = createConfigurationEvent(type, factoryPid, pid); if (event == null) return; ServiceReference<SynchronousConfigurationListener>[] syncRefs = syncTracker.getServiceReferences(); if (syncRefs != null) { for (ServiceReference<SynchronousConfigurationListener> ref : syncRefs) { SynchronousConfigurationListener syncListener = syncTracker.getService(ref); if (syncListener != null) { try { syncListener.configurationEvent(event); } catch (Throwable t) { log.log(LogService.LOG_ERROR, t.getMessage(), t); } } } } ServiceReference<ConfigurationListener>[] refs = tracker.getServiceReferences(); if (refs == null) return; for (int i = 0; i < refs.length; ++i) { final ServiceReference<ConfigurationListener> ref = refs[i]; queue.put(new Runnable() { public void run() { ConfigurationListener listener = tracker.getService(ref); if (listener == null) { return; } try { listener.configurationEvent(event); } catch (Throwable t) { log.log(LogService.LOG_ERROR, t.getMessage(), t); } } }); } } private synchronized ConfigurationEvent createConfigurationEvent(int type, String factoryPid, String pid) { if (configAdminReference == null) return null; return new ConfigurationEvent(configAdminReference, type, factoryPid, pid); } }