public final class ServletTimerImpl implements ServletTimer, Runnable { private static final Logger LOG = OSGiLogger.getLogger(ServletTimer.class, BundleLogger.getStaticLogger()); private static final int UUID_LENGTH = 40; private RunnableTimerTask timerTask; private final ApplicationSessionImpl appSession; private final String id; private final Serializable info; private final boolean repeatingTimer; private long scheduledExecutionTime; private long delay; private long period; private long numInvocations; private boolean fixedDelay; private long firstExecution; private TimerListener listener; /** * Constructor for non-repeating timer. * * @param info Information about the timer * @param delay Delay until execution * @param listener Listener that will get timeout events. */ public ServletTimerImpl( Serializable info, long delay, TimerListener listener, ApplicationSessionImpl appSession) { this(info, delay, false, 0, listener, appSession); } /** * Constructor for repeating times * * @param info Information about the timer * @param delay Delay until first execution * @param fixedDelay Whether fixed delay mode should be used * @param period Period between execution * @param listener Listener that will get timeout events. */ public ServletTimerImpl( Serializable info, long delay, boolean fixedDelay, long period, TimerListener listener, ApplicationSessionImpl appSession) { this.id = UUID.randomUUID(UUID_LENGTH); this.info = info; this.delay = delay; this.scheduledExecutionTime = delay + System.currentTimeMillis(); this.fixedDelay = fixedDelay; this.period = period; this.listener = listener; this.appSession = appSession; this.numInvocations = 0; this.firstExecution = 0; this.repeatingTimer = (period > 0); this.timerTask = new RunnableTimerTask(this); } public void cancel() { LOG.debug("removeServletTimer"); appSession.removeServletTimer(this); LOG.debug("cancel timerTask"); timerTask.cancel(); } public ApplicationSession getApplicationSession() { return appSession; } public String getId() { return id; } public Serializable getInfo() { return info; } public synchronized long getTimeRemaining() { return scheduledExecutionTime - System.currentTimeMillis(); } public synchronized long scheduledExecutionTime() { return this.scheduledExecutionTime; } public RunnableTimerTask getServletTimerTask() { return timerTask; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Info = ") .append(info) .append(System.getProperty("line.separator")) .append("Scheduled execution time = "); synchronized (this) { sb.append(scheduledExecutionTime); } sb.append(System.getProperty("line.separator")); sb.append("Time now = ") .append(System.currentTimeMillis()) .append(System.getProperty("line.separator")); sb.append("ApplicationSession = ") .append(appSession) .append(System.getProperty("line.separator")); sb.append("Delay = ").append(delay).append(System.getProperty("line.separator")); return sb.toString(); } /** Helper to calculate when next execution time is. */ private synchronized void estimateNextExecution() { if (fixedDelay) { scheduledExecutionTime = period + System.currentTimeMillis(); } else { if (firstExecution == 0) { // save timestamp of first execution firstExecution = scheduledExecutionTime; } long now = System.currentTimeMillis(); long executedTime = (numInvocations * period); numInvocations++; scheduledExecutionTime = firstExecution + executedTime; if (LOG.isDebugEnabled()) { LOG.debug("next execution estimated to run at " + scheduledExecutionTime); LOG.debug("current time is " + now); } } } public void run() { long run = System.currentTimeMillis(); // PORTAGE chgt de classLoader pour le currentThread // ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { // ClassLoader cl = listener.getClass().getClassLoader(); // Thread.currentThread().setContextClassLoader(cl); LOG.debug("Call timeout"); listener.timeout(this); } catch (Throwable e) { LOG.error("An unexpected exception happened in the timer callback", e); } finally { // Thread.currentThread().setContextClassLoader(oldClassLoader); if (repeatingTimer) { LOG.debug("Reset repeating servlet timer"); estimateNextExecution(); } else { LOG.debug("Cancel servlet timer"); // this non-repeating timer is now "ready" // and should not be included in the list of active timers // The application may already have canceled() the timer though cancel(); // dont bother about return value.... } } run = System.currentTimeMillis() - run; if (run > 500) { LOG.error( appSession.getId() + ": The servlet timer has taken more than 500 ms to be handled: " + run + " ms"); } } }
/** Manages reading and writing of configurations on the file system. */ public final class ConfigurationAdminManager { private static final Logger LOG = OSGiLogger.getLogger(ConfigurationAdminManager.class, BundleLogger.getStaticLogger()); private final BundleContext context; private final Set /* <String> */ bundleLocations; private final Map /* <String, List<ServiceReference>> */ pidToServiceReferences; private final ConfigurationDictionaryManager configurationDictionaryManager; private final AsyncDispatcher asyncDispatcher; private ServiceReference cmRef; /** * Sorted list of ServiceReferences to ConfigurationPlugins. */ private final List preModificationPlugins; /** * Sorted list of ServiceReferences to ConfigurationPlugins. */ private final List modifyingPlugins; /** * Sorted list of ServiceReferences to ConfigurationPlugins. */ private final List postModificationPlugins; /** * Mapping of a ServiceReference to its ranking (Integer). */ private final Map /* <Long, Integer> */ pluginRankings; public ConfigurationAdminManager(BundleContext context, File etcConfigDir, File usrConfigDir) throws IOException { this.context = context; this.bundleLocations = new HashSet /* <String> */(); this.pidToServiceReferences = new HashMap /* <String, List<ServiceReference>> */(); this.configurationDictionaryManager = new ConfigurationDictionaryManager(etcConfigDir, usrConfigDir); this.preModificationPlugins = new ArrayList(); this.modifyingPlugins = new ArrayList(); this.postModificationPlugins = new ArrayList(); this.pluginRankings = new HashMap /* <Long, Integer> */(); this.asyncDispatcher = new AsyncDispatcher(); } public synchronized void setCmRef(ServiceReference cmRef) { this.cmRef = cmRef; } /** * Adds a bundle location to the list of known locations. * * @param location The bundle location to add */ public synchronized void addedBundle(String location) { bundleLocations.add(location); } /** * Removes and unbinds a bundle location from the list of known locations. * * @param location The bundle location to remove */ public synchronized void removedBundle(String location) { bundleLocations.remove(location); String filter = "&((" + ConfigurationAdmin.SERVICE_BUNDLELOCATION + "=" + location + ")(" + CMConstants.SERVICE_DYNAMICLOCATION + "=" + Boolean.TRUE + "))"; try { List /* <Configuration> */ configurations = getConfigurations(filter, null, false); Iterator it = configurations.iterator(); while (it.hasNext()) { Configuration configuration = (Configuration) it.next(); ConfigurationDictionary dictionary = (ConfigurationDictionary) configuration.getProperties(); setBundleLocation(configuration.getPid(), configuration.getFactoryPid(), null, dictionary); } } catch (IOException e) { LOG.error("Error while unbinding configurations bound to " + location, e); } catch (InvalidSyntaxException e) { LOG.error("Error while unbinding configurations bound to " + location, e); } } /** * Registers a new incoming ManagedServiceFactory * * @param serviceReference The reference to the managed service factory */ public synchronized void registeredManagedServiceFactory(ServiceReference serviceReference) { String[] factoryPids = getServicePids(serviceReference); if (factoryPids == null) { String bundleLocation = serviceReference.getBundle().getLocation(); LOG.error( "ManagedServiceFactory is registering without a " + ConfigurationAdmin.SERVICE_FACTORYPID + ": " + bundleLocation); } else { registerPidsAndCheck(serviceReference, factoryPids); if (LOG.isDebugEnabled()) { LOG.debug( "ManagedServiceFactory registered: " + ArrayUtils.toString(factoryPids, "[", "]", ", ")); } try { updateManagedServiceFactory(serviceReference, factoryPids); } catch (IOException e) { LOG.error("Error while notifying services.", e); } } } /** * Unregisters a ManagedServiceFactory * * @param serviceReference The reference to the managed service factory */ public synchronized void unregisteredManagedServiceFactory(ServiceReference serviceReference) { unregisterPids(serviceReference); } /** * Registers a new incoming ManagedService * * @param serviceReference The reference to the managed service */ public synchronized void registeredManagedService(ServiceReference serviceReference) { String[] servicePids = getServicePids(serviceReference); if (servicePids == null) { String bundleLocation = serviceReference.getBundle().getLocation(); LOG.error( "ManagedService is registering without a " + Constants.SERVICE_PID + ": " + bundleLocation); } else { registerPidsAndCheck(serviceReference, servicePids); if (LOG.isDebugEnabled()) { LOG.debug("ManagedService registered: " + ArrayUtils.toString(servicePids, "[", "]", ", ")); } try { updateManagedService(serviceReference, servicePids); } catch (IOException e) { LOG.error("Error while notifying services.", e); } } } /** * Unregisters a ManagedService * * @param serviceReference The reference to the managed service */ public synchronized void unregisteredManagedService(ServiceReference serviceReference) { unregisterPids(serviceReference); } /** * Registers a new incoming ConfigurationPlugin * * @param serviceReference The reference to the configuration plugin */ public synchronized void registeredConfigurationPlugin(ServiceReference serviceReference) { Object rankingProperty = serviceReference.getProperty(ConfigurationPlugin.CM_RANKING); if (rankingProperty == null) { rankingProperty = new Integer(0); } else if (rankingProperty.getClass() != Integer.class) { rankingProperty = new Integer(0); } Long serviceId = (Long) serviceReference.getProperty(Constants.SERVICE_ID); if (serviceId == null) { LOG.error("Missing service id for a ConfigurationPlugin"); } else { int ranking = ((Integer) rankingProperty).intValue(); pluginRankings.put(serviceId, rankingProperty); insertPluginReference(serviceReference, ranking); } } /** * Modifies an already registered ConfigurationPlugin * * @param serviceReference The reference to the configuration plugin */ public synchronized void modifiedConfigurationPlugin(ServiceReference serviceReference) { Object rankingProperty = serviceReference.getProperty(ConfigurationPlugin.CM_RANKING); if (rankingProperty == null) { rankingProperty = new Integer(0); } else if (rankingProperty.getClass() != Integer.class) { rankingProperty = new Integer(0); } Long serviceId = (Long) serviceReference.getProperty(Constants.SERVICE_ID); if (serviceId == null) { LOG.error("Missing service id for a ConfigurationPlugin"); return; } int ranking = ((Integer) rankingProperty).intValue(); int oldRanking = ((Integer) pluginRankings.get(serviceId)).intValue(); if (ranking != oldRanking) { removePluginReference(serviceId, oldRanking); pluginRankings.put(serviceId, rankingProperty); insertPluginReference(serviceReference, ranking); } } /** * Unregisters a ConfigurationPlugin * * @param serviceReference The reference to the managed service */ public synchronized void unregisteredConfigurationPlugin(ServiceReference serviceReference) { Object rankingProperty = serviceReference.getProperty(ConfigurationPlugin.CM_RANKING); if (rankingProperty == null) { rankingProperty = new Integer(0); } else if (rankingProperty.getClass() != Integer.class) { rankingProperty = new Integer(0); } Long serviceId = (Long) serviceReference.getProperty(Constants.SERVICE_ID); if (serviceId == null) { LOG.error("Missing service id for a ConfigurationPlugin"); return; } int ranking = ((Integer) rankingProperty).intValue(); pluginRankings.remove(serviceId); removePluginReference(serviceId, ranking); } public synchronized Configuration createFactoryConfiguration( String factoryPid, String location, boolean checkLocation) throws IOException { if (checkLocation) { ConfigurationDictionary dictionary = configurationDictionaryManager.loadOne(factoryPid); String locationFactoryPidIsBoundTo = null; if (dictionary != null && dictionary.size() > 0) { locationFactoryPidIsBoundTo = dictionary.getLocation(); } if (locationFactoryPidIsBoundTo != null && !location.equals(locationFactoryPidIsBoundTo)) { throw new SecurityException("Not owner of the factoryPid"); } } // TODO should check and ensure availability String pid = factoryPid + "-" + UUID.randomUUID(8); return new ConfigurationImpl(this, location, factoryPid, pid); } public synchronized Configuration getConfiguration( String servicePid, String location, boolean checkLocation) throws IOException { ConfigurationDictionary dictionary = configurationDictionaryManager.load(servicePid); if (checkLocation) { String locationPidIsBoundTo = null; if (dictionary != null && dictionary.size() > 0) { locationPidIsBoundTo = dictionary.getLocation(); } if (locationPidIsBoundTo != null && !location.equals(locationPidIsBoundTo)) { throw new SecurityException("Not owner of the servicePid"); } } ConfigurationImpl configuration = null; if (dictionary == null) { configuration = new ConfigurationImpl(this, location, null, servicePid); } else { configuration = new ConfigurationImpl(this, dictionary); } return configuration; } /** * Gets all configurations that matches the given filter * * @param filterString The filter to match * @param callingBundleLocation The location from which the list was done (could be null) * @param checkLocation Whether to check the location * @return An array of matching configurations */ public synchronized Configuration[] listConfigurations( String filterString, String callingBundleLocation, boolean checkLocation) throws IOException, InvalidSyntaxException { List matchingConfigurations = getConfigurations(filterString, callingBundleLocation, checkLocation); Configuration[] configurations = null; if (matchingConfigurations.size() > 0) { configurations = new Configuration[matchingConfigurations.size()]; configurations = (Configuration[]) matchingConfigurations.toArray(configurations); } return configurations; } public synchronized void update( String factoryPid, String servicePid, ConfigurationDictionary dictionary) throws IOException { configurationDictionaryManager.save(servicePid, dictionary); ConfigurationDictionary newDictionary = configurationDictionaryManager.load(servicePid); updateTargetServicesMatching( servicePid, factoryPid, newDictionary.getLocation(), newDictionary); if (cmRef == null) { LOG.error("update: Could not get service reference for event delivery"); } else { sendConfigurationEvent( new ConfigurationEvent(cmRef, ConfigurationEvent.CM_UPDATED, factoryPid, servicePid)); } } /** * Deletes the configuration from configuration admin * * @param configuration Configuration to delete * @throws IOException If any problem occurs while deleting the configuration */ public synchronized void delete(ConfigurationImpl configuration, String servicePid) throws IOException { ConfigurationDictionary dictionary = configurationDictionaryManager.load(servicePid); String factoryPid = (String) dictionary.get(ConfigurationAdmin.SERVICE_FACTORYPID); String location = dictionary.getLocation(); configurationDictionaryManager.delete(servicePid); dictionary = configurationDictionaryManager.load(servicePid); updateTargetServicesMatching(servicePid, factoryPid, location, dictionary); if (cmRef == null) { LOG.error("delete: Could not get service reference"); } else { sendConfigurationEvent( new ConfigurationEvent( cmRef, (dictionary != null) ? ConfigurationEvent.CM_UPDATED : ConfigurationEvent.CM_DELETED, factoryPid, servicePid)); } } /** * Call all applicable ConfigurationPlugins given a pid and a dictionary. * * @param dictionary The configuration dictionary to be modified. * @return The description of what the method returns. */ public synchronized ConfigurationDictionary callPlugins( ServiceReference targetServiceReference, String servicePid, ConfigurationDictionary dictionary) { callPlugins(targetServiceReference, servicePid, dictionary, preModificationPlugins, false); dictionary = callPlugins(targetServiceReference, servicePid, dictionary, modifyingPlugins, true); callPlugins(targetServiceReference, servicePid, dictionary, postModificationPlugins, false); return dictionary; } public synchronized void setBundleLocation( String servicePid, String factoryPid, String location, ConfigurationDictionary dictionary) { String currentLocation = dictionary.getLocation(); boolean currentDynamic = dictionary.isDynamic(); String newLocation = location; boolean newDynamic = (location != null); if (location == null) { dictionary.setLocation(null); ServiceReference[] serviceReferences = null; if (factoryPid == null) { serviceReferences = getTargetServiceReferences(ManagedService.class, servicePid); } else { serviceReferences = getTargetServiceReferences(ManagedServiceFactory.class, factoryPid); } if (serviceReferences != null && serviceReferences.length > 0) { newLocation = serviceReferences[0].getBundle().getLocation(); dictionary.setLocation(newLocation); } dictionary.setDynamic(true); } else { dictionary.setLocation(location); dictionary.setDynamic(false); } if (EqualsUtils.isNotEqual(currentLocation, newLocation) || currentDynamic == newDynamic) { try { update(factoryPid, servicePid, dictionary); } catch (IOException e) { LOG.error("Cannot update configuration"); dictionary.setLocation(currentLocation); dictionary.setDynamic(currentDynamic); } } } public synchronized void delete(String servicePid) { configurationDictionaryManager.delete(servicePid); } public synchronized void stop() { asyncDispatcher.stop(); } private String[] getServicePids(ServiceReference serviceReference) { Object prop = serviceReference.getProperty(Constants.SERVICE_PID); if (prop == null) { return null; } else if (prop instanceof String) { return new String[] {(String) prop}; } else if (prop instanceof String[]) { return (String[]) prop; } else if (prop instanceof Collection) { return (String[]) ((Collection) prop).toArray(new String[((Collection) prop).size()]); } else { return new String[0]; } } private void sendConfigurationEvent(ConfigurationEvent event) { ServiceReference[] serviceReferences = null; try { serviceReferences = context.getServiceReferences(ConfigurationListener.class.getName(), null); } catch (InvalidSyntaxException ignored) { } if (serviceReferences != null) { // we have listeners asyncDispatcher.send(new ListenerEvent(context, serviceReferences, event)); } } private void sendUpdateEvent( ServiceReference serviceReference, String servicePid, String factoryPid, ConfigurationDictionary dictionary) { asyncDispatcher.send( new UpdateEvent(this, context, serviceReference, servicePid, factoryPid, dictionary)); } private boolean isUnrealBundleLocation(String bundleLocation) { return bundleLocation != null && !bundleLocations.contains(bundleLocation); } private ConfigurationDictionary bindLocationIfNecessary( ServiceReference[] servicePids, ConfigurationDictionary dictionary) throws IOException { if (servicePids == null || servicePids.length == 0) { return dictionary; } String configLocation = dictionary.getLocation(); LOG.info(ArrayUtils.toString(servicePids, "[", "]", ", ")); if (configLocation != null) { LOG.info(configLocation + " " + configLocation.getClass()); } Enumeration e = dictionary.keys(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); LOG.info(key + " -> " + dictionary.get(key)); } if (isUnrealBundleLocation(configLocation)) { if (dictionary.isDynamic()) { configLocation = null; dictionary.setLocation(null); } } if (configLocation == null) { String pid = (String) dictionary.get(Constants.SERVICE_PID); String serviceLocation = servicePids[0].getBundle().getLocation(); dictionary.setLocation(serviceLocation); configurationDictionaryManager.save(pid, dictionary); } return dictionary; } private ServiceReference[] filterOnMatchingLocations( ServiceReference[] serviceReferences, String configLocation) { if (serviceReferences.length == 1) { String serviceLocation = serviceReferences[0].getBundle().getLocation(); if (locationsMatch(serviceLocation, configLocation)) { return serviceReferences; } LOG.error( "The bundle " + serviceLocation + " has registered a ManagedService(Factory) for a pid bound to " + configLocation); return new ServiceReference[0]; } List list = new ArrayList(); for (int i = 0; i < serviceReferences.length; ++i) { String serviceLocation = serviceReferences[i].getBundle().getLocation(); if (locationsMatch(serviceLocation, configLocation)) { list.add(serviceReferences[i]); } else { LOG.error( "The bundle " + serviceLocation + " has registered a ManagedService(Factory) for a pid bound to " + configLocation); } } ServiceReference[] matching = new ServiceReference[list.size()]; matching = (ServiceReference[]) list.toArray(matching); return matching; } private boolean locationsMatch(String serviceLocation, String configLocation) { if (configLocation == null) { return false; } else if (configLocation.equals(serviceLocation)) { return true; } else { return false; } } private void registerPidsAndCheck(ServiceReference serviceReference, String[] servicePids) { for (int i = 0; i < servicePids.length; ++i) { String servicePid = servicePids[i]; List /* <ServiceReference> */ serviceReferences = (List) pidToServiceReferences.get(servicePid); if (serviceReferences != null) { LOG.error( "Multiple ManagedServices registered with same pid (" + servicePid + "): " + ((ServiceReference) serviceReferences.get(0)).getBundle().getLocation() + " and " + serviceReference.getBundle().getLocation()); } else { serviceReferences = new ArrayList /* <ServiceReference> */(); pidToServiceReferences.put(servicePid, serviceReferences); } serviceReferences.add(serviceReference); } } private void unregisterPids(ServiceReference serviceReference) { Iterator /* <Entry<String, List<ServiceReference>>> */ it = pidToServiceReferences.entrySet().iterator(); Entry /* <String, List<ServiceReference>> */ entry = null; List /* <ServiceReference> */ serviceReferences = null; List /* <String> */ toRemove = new ArrayList(); while (it.hasNext()) { entry = (Entry) it.next(); serviceReferences = (List) entry.getValue(); if (serviceReferences.remove(serviceReference)) { if (serviceReferences.size() == 0) { toRemove.add(entry.getKey()); } } } Iterator /* <String> */ toRemoveIt = toRemove.iterator(); while (toRemoveIt.hasNext()) { pidToServiceReferences.remove(toRemoveIt.next()); } } private void updateTargetServicesMatching( String servicePid, String factoryPid, String location, ConfigurationDictionary dictionary) throws IOException { if (factoryPid == null) { updateManagedServicesMatching(servicePid, location, dictionary); } else { updateManagedServiceFactoriesMatching(servicePid, factoryPid, location, dictionary); } } private void updateManagedServiceFactoriesMatching( String servicePid, String factoryPid, String bundleLocation, ConfigurationDictionary dictionary) throws IOException { ServiceReference[] srs = getTargetServiceReferences(ManagedServiceFactory.class, factoryPid); if (dictionary == null) { updateManagedServiceFactories(srs, servicePid, factoryPid, bundleLocation); } else { updateManagedServiceFactories(srs, servicePid, factoryPid, dictionary); } } private void updateManagedServiceFactories( ServiceReference[] srs, String servicePid, String factoryPid, ConfigurationDictionary cd) throws IOException { ConfigurationDictionary bound = bindLocationIfNecessary(srs, cd); String boundLocation = bound.getLocation(); ServiceReference[] filtered = filterOnMatchingLocations(srs, boundLocation); for (int i = 0; i < filtered.length; ++i) { sendUpdateEvent(filtered[i], servicePid, factoryPid, bound); } } private void updateManagedServiceFactories( ServiceReference[] serviceReferences, String servicePid, String factoryPid, String boundLocation) { ServiceReference[] filtered = filterOnMatchingLocations(serviceReferences, boundLocation); for (int i = 0; i < filtered.length; ++i) { sendUpdateEvent(filtered[i], servicePid, factoryPid, null); } } private void updateManagedServiceFactory(ServiceReference serviceReference, String[] factoryPids) throws IOException { for (int j = 0; j < factoryPids.length; ++j) { String factoryPid = factoryPids[j]; List /* <ConfigurationDictionary> */ cds = configurationDictionaryManager.loadAll(factoryPid); if (cds != null && cds.size() > 0) { ServiceReference[] srs = new ServiceReference[] {serviceReference}; Iterator /* <ConfigurationDictionary> */ it = cds.iterator(); ConfigurationDictionary dictionary = null; while (it.hasNext()) { dictionary = (ConfigurationDictionary) it.next(); String servicePid = (String) dictionary.get(Constants.SERVICE_PID); updateManagedServiceFactories(srs, servicePid, factoryPid, dictionary); } } } } private void updateManagedServicesMatching( String servicePid, String bundleLocation, ConfigurationDictionary dictionary) throws IOException { ServiceReference[] srs = getTargetServiceReferences(ManagedService.class, servicePid); if (dictionary == null) { updateManagedServices(srs, servicePid, bundleLocation); } else { updateManagedServices(srs, servicePid, dictionary); } } private void updateManagedServices( ServiceReference[] serviceReferences, String servicePid, String boundLocation) { ServiceReference[] filtered = filterOnMatchingLocations(serviceReferences, boundLocation); for (int i = 0; i < filtered.length; ++i) { sendUpdateEvent(filtered[i], servicePid, null, null); } } private void updateManagedServices( ServiceReference[] serviceReferences, String servicePid, ConfigurationDictionary dictionary) throws IOException { ConfigurationDictionary bound = bindLocationIfNecessary(serviceReferences, dictionary); String boundLocation = bound.getLocation(); ServiceReference[] filtered = filterOnMatchingLocations(serviceReferences, boundLocation); for (int i = 0; i < filtered.length; ++i) { sendUpdateEvent(filtered[i], servicePid, null, bound); } } private void updateManagedService(ServiceReference serviceReference, String[] servicePids) throws IOException { for (int j = 0; j < servicePids.length; ++j) { String servicePid = servicePids[j]; ServiceReference[] srs = new ServiceReference[] {serviceReference}; ConfigurationDictionary cd = configurationDictionaryManager.load(servicePid); if (cd == null) { for (int i = 0; i < srs.length; ++i) { sendUpdateEvent(srs[i], servicePid, null, null); } } else { cd = bindLocationIfNecessary(srs, cd); String boundLocation = cd.getLocation(); srs = filterOnMatchingLocations(srs, boundLocation); for (int i = 0; i < srs.length; ++i) { sendUpdateEvent(srs[i], servicePid, null, cd); } } } } private ServiceReference[] getTargetServiceReferences(Class serviceClass, String servicePid) { String filter = "(" + Constants.SERVICE_PID + "=" + servicePid + ")"; try { ServiceReference[] srs = context.getServiceReferences(serviceClass.getName(), filter); return srs == null ? new ServiceReference[0] : srs; } catch (InvalidSyntaxException e) { LOG.error("Faulty ldap filter " + filter, e); return new ServiceReference[0]; } } /** * * Insert a ServiceReference to a ConfigurationPlugin in the correct * list based on its * ranking. * * * * @param serviceReference The ServiceReference. * * @param ranking The ranking the ServiceReference. */ private void insertPluginReference(ServiceReference serviceReference, int ranking) { if (ranking < 0) { insertPluginReference(serviceReference, ranking, preModificationPlugins); } else if (0 <= ranking && ranking <= 1000) { insertPluginReference(serviceReference, ranking, modifyingPlugins); } else { insertPluginReference(serviceReference, ranking, postModificationPlugins); } } /** * * Insert a ServiceReference in a list sorted on cm.ranking property. * * * * @param serviceReference The ServiceReference. * * @param pluginsList The list. */ private void insertPluginReference( ServiceReference serviceReference, int ranking, List pluginsList) { int i; for (i = 0; i < pluginsList.size(); ++i) { ServiceReference nextReference = (ServiceReference) pluginsList.get(i); Long serviceId = (Long) nextReference.getProperty(Constants.SERVICE_ID); Integer rankingOfNextReference = (Integer) pluginRankings.get(serviceId); if (ranking < rankingOfNextReference.intValue()) { break; } } pluginsList.set(i, serviceReference); } /** * * Remove a ServiceReference to a ConfigurationPlugin given * a service.id and a ranking. * * * * @param serviceId The service.id of the ConfigurationPlugin. * * @param ranking The ranking of the ConfigurationPlugin. */ private void removePluginReference(Object serviceId, int ranking) { if (ranking < 0) { removePluginReference(serviceId, preModificationPlugins); } else if (0 <= ranking && ranking <= 1000) { removePluginReference(serviceId, modifyingPlugins); } else { removePluginReference(serviceId, postModificationPlugins); } } private void removePluginReference(Object serviceId, List pluginsList) { for (int i = 0; i < pluginsList.size(); ++i) { ServiceReference serviceReference = (ServiceReference) pluginsList.get(i); Long currentId = (Long) serviceReference.getProperty(Constants.SERVICE_ID); if (currentId.equals(serviceId)) { pluginsList.remove(i); return; } } } /** * * Call all plugins contained in a list and * optionally allow modifications. * * * * @param targetServiceReference Reference to the target ManagedService(Factory). * * @param servicePid The service PID corresponding to the current configuration * @param dictionary The configuration dictionary to process. * * @param plugins list of references to ConfigurationPlugins. * * @param allowModification Should modifications to the configuration dictionary be allowed. * * * @return The modified configuration dictionary. */ private ConfigurationDictionary callPlugins( ServiceReference targetServiceReference, String servicePid, ConfigurationDictionary dictionary, List plugins, boolean allowModification) { ConfigurationDictionary currentDictionary = dictionary; Iterator it = plugins.iterator(); while (it.hasNext()) { ServiceReference pluginReference = (ServiceReference) it.next(); // Only call the plugin if no cm.target is specified or if it // matches the pid of the target service String cmTarget = (String) pluginReference.getProperty(ConfigurationPlugin.CM_TARGET); if (cmTarget == null || cmTarget.equals(servicePid)) { ConfigurationPlugin plugin = (ConfigurationPlugin) context.getService(pluginReference); if (plugin == null) { continue; } ConfigurationDictionary dictionaryCopy = new ConfigurationDictionary(dictionary); try { plugin.modifyConfiguration(targetServiceReference, dictionaryCopy); if (allowModification) { currentDictionary = dictionaryCopy; } } catch (Exception exception) { LOG.error("[CM] Exception thrown by plugin: " + exception.getMessage()); } } } return currentDictionary; } private List /* <Configuration> */ getConfigurations( String filterString, String callingBundleLocation, boolean checkLocation) throws IOException, InvalidSyntaxException { Filter filter = (filterString != null) ? context.createFilter(filterString) : null; Iterator /* <String> */ pids = configurationDictionaryManager.listPids(); List /* <Configuration> */ matchingConfigurations = new ArrayList(); while (pids.hasNext()) { String pid = (String) pids.next(); ConfigurationDictionary config = configurationDictionaryManager.load(pid); if (filter == null) { matchingConfigurations.add(new ConfigurationImpl(this, config)); } else { if (filter.matchCase(config.toSearchableProperties())) { if (!checkLocation) { matchingConfigurations.add(new ConfigurationImpl(this, config)); } else { if (callingBundleLocation.equals(config.getLocation())) { matchingConfigurations.add(new ConfigurationImpl(this, config)); } } } } } return matchingConfigurations; } }
public final class AsyncDispatcher implements Runnable { private static final Logger LOG = OSGiLogger.getLogger(AsyncDispatcher.class, BundleLogger.getStaticLogger()); /** * The queue of updates. */ private final CircularArray /* <Runnable> */ queue; private boolean end; /** * The thread running this object. */ private Thread thread; public AsyncDispatcher() { this.end = false; this.thread = null; this.queue = new CircularArray /* <Runnable> */(32); } /** Override of Thread.run(). */ public void run() { boolean localEnd = false; while (!end && !localEnd) { try { Runnable runnable = (Runnable) queue.take(5000L); if (runnable == null) { detachCurrentThread(); localEnd = true; } else { runnable.run(); } } catch (RuntimeException e) { LOG.error("Error while delivering async message", e); } catch (InterruptedException e) { LOG.error("Error while delivering async message", e); } } } public void send(Runnable runnable) { queue.offer(runnable); attachNewThreadIfNeccesary(); } public synchronized void stop() { end = true; if (thread != null) { thread.interrupt(); try { thread.join(); } catch (InterruptedException e) { LOG.error("Received an interrupted exception while waiting for async thread completion"); } } } private synchronized void attachNewThreadIfNeccesary() { if (thread == null) { thread = new Thread(this); thread.start(); } } private synchronized void detachCurrentThread() { thread = null; } }
public final class TimerServiceImpl extends Timer implements TimerService { private static final Logger LOG = OSGiLogger.getLogger(TimerService.class, BundleLogger.getStaticLogger()); public ServletTimer createTimer( ServletContext context, long delay, boolean isPersistent, Serializable info) { throw new UnsupportedOperationException(); } public ServletTimer createTimer( ServletContext context, long delay, long period, boolean fixedDelay, boolean isPersistent, Serializable info) { throw new UnsupportedOperationException(); } public ServletTimer createTimer( ApplicationSession appSession, long delay, boolean isPersistent, Serializable info) { if (LOG.isDebugEnabled()) { LOG.debug( "Create timer for application " + appSession.getApplicationName() + " (delay=" + delay + ", persistent=" + isPersistent + ")"); } ApplicationSessionImpl applicationSessionImpl = (ApplicationSessionImpl) appSession; applicationSessionImpl.checkValid(); if (!applicationSessionImpl.hasTimerListener()) { throw new IllegalStateException( "No Timer listeners have been configured for this application "); } TimerListener listener = applicationSessionImpl.getServletContextInternal().getTimerListener(); ServletTimerImpl servletTimer = createTimerLocally(listener, delay, isPersistent, info, applicationSessionImpl); return servletTimer; } public ServletTimer createTimer( ApplicationSession appSession, long delay, long period, boolean fixedDelay, boolean isPersistent, Serializable info) { if (period < 1) { throw new IllegalArgumentException("Period should be greater than 0"); } if (LOG.isDebugEnabled()) { LOG.debug( "Create timer for application " + appSession.getApplicationName() + " (delay=" + delay + ", period=" + period + ", fixedDelay=" + fixedDelay + ", persistent=" + isPersistent + ")"); } ApplicationSessionImpl applicationSessionImpl = (ApplicationSessionImpl) appSession; applicationSessionImpl.checkValid(); if (applicationSessionImpl.getServletContextInternal().getTimerListener() == null) { throw new IllegalStateException( "No Timer listeners have been configured for this application "); } TimerListener timerListener = applicationSessionImpl.getServletContextInternal().getTimerListener(); ServletTimerImpl servletTimer = createTimerLocally( timerListener, delay, period, fixedDelay, isPersistent, info, applicationSessionImpl); return servletTimer; } /** * @param listener * @param delay * @param isPersistent * @param info * @param applicationSession * @return */ private ServletTimerImpl createTimerLocally( TimerListener listener, long delay, boolean isPersistent, Serializable info, ApplicationSessionImpl applicationSession) { ServletTimerImpl servletTimer = new ServletTimerImpl(info, delay, listener, applicationSession); super.schedule(servletTimer.getServletTimerTask(), delay); applicationSession.addServletTimer(servletTimer); if (isPersistent) { persist(servletTimer); } return servletTimer; } /** * @param listener * @param delay * @param period * @param fixedDelay * @param isPersistent * @param info * @param applicationSession * @return */ private ServletTimerImpl createTimerLocally( TimerListener listener, long delay, long period, boolean fixedDelay, boolean isPersistent, Serializable info, ApplicationSessionImpl applicationSession) { final ServletTimerImpl servletTimer = new ServletTimerImpl(info, delay, fixedDelay, period, listener, applicationSession); if (fixedDelay) { super.schedule(servletTimer.getServletTimerTask(), delay, period); } else { super.scheduleAtFixedRate(servletTimer.getServletTimerTask(), delay, period); } applicationSession.addServletTimer(servletTimer); if (isPersistent) { persist(servletTimer); } return servletTimer; } /** @param st */ private void persist(ServletTimerImpl st) { // TODO - implement persistance } public void stop() { super.cancel(); if (LOG.isDebugEnabled()) { LOG.debug("Stopped timer service " + this); } } public void start() { if (LOG.isDebugEnabled()) { LOG.debug("Started timer service " + this); } } }