|
From: <mwl...@us...> - 2008-03-21 17:40:26
|
Revision: 676
http://cishell.svn.sourceforge.net/cishell/?rev=676&view=rev
Author: mwlinnem
Date: 2008-03-21 10:39:47 -0700 (Fri, 21 Mar 2008)
Log Message:
-----------
Initial import. Preference Service needs this.
Added Paths:
-----------
branches/user_prefs/org.eclipse.equinox.cm/.classpath
branches/user_prefs/org.eclipse.equinox.cm/.cvsignore
branches/user_prefs/org.eclipse.equinox.cm/.project
branches/user_prefs/org.eclipse.equinox.cm/.settings/
branches/user_prefs/org.eclipse.equinox.cm/META-INF/
branches/user_prefs/org.eclipse.equinox.cm/META-INF/MANIFEST.MF
branches/user_prefs/org.eclipse.equinox.cm/about.html
branches/user_prefs/org.eclipse.equinox.cm/build.properties
branches/user_prefs/org.eclipse.equinox.cm/plugin.properties
branches/user_prefs/org.eclipse.equinox.cm/src/
branches/user_prefs/org.eclipse.equinox.cm/src/org/
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/Activator.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationEventAdapter.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/EventDispatcher.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/LogTracker.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceTracker.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/PluginManager.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/SerializedTaskQueue.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/reliablefile/
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/reliablefile/ReliableFile.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/reliablefile/ReliableFileInputStream.java
branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/reliablefile/ReliableFileOutputStream.java
Added: branches/user_prefs/org.eclipse.equinox.cm/.classpath
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/.classpath (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/.classpath 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/OSGi%Minimum-1.1"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Property changes on: branches/user_prefs/org.eclipse.equinox.cm/.classpath
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/user_prefs/org.eclipse.equinox.cm/.cvsignore
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/.cvsignore (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/.cvsignore 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1 @@
+bin
Property changes on: branches/user_prefs/org.eclipse.equinox.cm/.cvsignore
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/user_prefs/org.eclipse.equinox.cm/.project
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/.project (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/.project 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.cm</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
Property changes on: branches/user_prefs/org.eclipse.equinox.cm/.project
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/user_prefs/org.eclipse.equinox.cm/META-INF/MANIFEST.MF
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/META-INF/MANIFEST.MF (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/META-INF/MANIFEST.MF 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %bundleName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.equinox.cm
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.equinox.internal.cm.Activator
+Import-Package: org.osgi.framework;version="1.3.0",
+ org.osgi.service.cm;version="1.2.0",
+ org.osgi.service.log;version="1.3.0",
+ org.osgi.service.event;version="1.0"; resolution:=optional,
+ org.osgi.util.tracker;version="1.3.1"
+Export-Package: org.eclipse.equinox.internal.cm;x-internal:=true,
+ org.eclipse.equinox.internal.cm.reliablefile;x-internal:=true
+Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.1,
+ CDC-1.0/Foundation-1.0,
+ J2SE-1.3
Property changes on: branches/user_prefs/org.eclipse.equinox.cm/META-INF/MANIFEST.MF
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/user_prefs/org.eclipse.equinox.cm/about.html
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/about.html (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/about.html 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>January 30, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
Property changes on: branches/user_prefs/org.eclipse.equinox.cm/about.html
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/user_prefs/org.eclipse.equinox.cm/build.properties
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/build.properties (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/build.properties 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html,\
+ plugin.properties
+src.includes = about.html
Property changes on: branches/user_prefs/org.eclipse.equinox.cm/build.properties
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/user_prefs/org.eclipse.equinox.cm/plugin.properties
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/plugin.properties (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/plugin.properties 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2007 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+bundleName = Configuration Admin (Incubation)
+providerName = Eclipse.org
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/Activator.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/Activator.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/Activator.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Cognos Incorporated, IBM Corporation
+ * 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
+ * Chris Aniszczyk <zx...@us...> - bug 209294
+ *******************************************************************************/
+package org.eclipse.equinox.internal.cm;
+
+import org.osgi.framework.*;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * Activator start the ConfigurationAdminFactory but also handles passing in the Service
+ * Registration needed by Asynch threads. Asynch threads are controlled by ConfigurationAdminFactory
+ * start and stop. It requires some care to handle pending events as the service is registered before
+ * activating the threads. (see EventDispatcher)
+ */
+public class Activator implements BundleActivator {
+ private static final String EVENT_ADMIN_CLASS = "org.osgi.service.event.EventAdmin"; //$NON-NLS-1$
+ private LogTracker logTracker;
+ private ServiceRegistration registration;
+ private ConfigurationAdminFactory factory;
+ private ConfigurationEventAdapter eventAdapter;
+ private static BundleContext bundleContext;
+
+ private static synchronized void setBundleContext(BundleContext context) {
+ bundleContext = context;
+ }
+
+ public static synchronized String getProperty(String key) {
+ if (bundleContext != null)
+ return bundleContext.getProperty(key);
+
+ return null;
+ }
+
+ public void start(BundleContext context) throws Exception {
+ setBundleContext(context);
+ logTracker = new LogTracker(context, System.err);
+ logTracker.open();
+ if (checkEventAdmin()) {
+ eventAdapter = new ConfigurationEventAdapter(context);
+ eventAdapter.start();
+ }
+ factory = new ConfigurationAdminFactory(context, logTracker);
+ factory.start();
+ context.addBundleListener(factory);
+ registration = context.registerService(ConfigurationAdmin.class.getName(), factory, null);
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ registration.unregister();
+ registration = null;
+ context.removeBundleListener(factory);
+ factory.stop();
+ factory = null;
+ if (eventAdapter != null) {
+ eventAdapter.stop();
+ eventAdapter = null;
+ }
+ logTracker.close();
+ logTracker = null;
+ setBundleContext(null);
+ }
+
+ private static boolean checkEventAdmin() {
+ // cannot support scheduling without the event admin package
+ try {
+ Class.forName(EVENT_ADMIN_CLASS);
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+}
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 java.security.Permission;
+import java.util.Dictionary;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ConfigurationPermission;
+import org.osgi.service.log.LogService;
+
+/**
+ * ConfigurationAdminFactory provides a Configuration Admin ServiceFactory but more significantly
+ * launches the whole implementation.
+ */
+
+public class ConfigurationAdminFactory implements ServiceFactory, BundleListener {
+
+ private final Permission configurationPermission = new ConfigurationPermission("*", ConfigurationPermission.CONFIGURE); //$NON-NLS-1$
+ private final EventDispatcher eventDispatcher;
+ private final PluginManager pluginManager;
+ private final LogService log;
+ private final ManagedServiceTracker managedServiceTracker;
+ private final ManagedServiceFactoryTracker managedServiceFactoryTracker;
+ private final ConfigurationStore configurationStore;
+
+ public ConfigurationAdminFactory(BundleContext context, LogService log) {
+ this.log = log;
+ configurationStore = new ConfigurationStore(this, context);
+ eventDispatcher = new EventDispatcher(context, log);
+ pluginManager = new PluginManager(context);
+ managedServiceTracker = new ManagedServiceTracker(this, configurationStore, context);
+ managedServiceFactoryTracker = new ManagedServiceFactoryTracker(this, configurationStore, context);
+ }
+
+ void start() {
+ eventDispatcher.start();
+ pluginManager.start();
+ managedServiceTracker.open();
+ managedServiceFactoryTracker.open();
+ }
+
+ void stop() {
+ managedServiceTracker.close();
+ managedServiceFactoryTracker.close();
+ eventDispatcher.stop();
+ pluginManager.stop();
+ }
+
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ ServiceReference reference = registration.getReference();
+ eventDispatcher.setServiceReference(reference);
+ return new ConfigurationAdminImpl(this, configurationStore, bundle);
+ }
+
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ // do nothing
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ if (event.getType() == BundleEvent.UNINSTALLED)
+ configurationStore.unbindConfigurations(event.getBundle());
+ }
+
+ public void checkConfigurationPermission() throws SecurityException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(configurationPermission);
+ }
+
+ void log(int level, String message) {
+ log.log(level, message);
+ }
+
+ void log(int level, String message, Throwable exception) {
+ log.log(level, message, exception);
+ }
+
+ void dispatchEvent(int type, String factoryPid, String pid) {
+ eventDispatcher.dispatchEvent(type, factoryPid, pid);
+ }
+
+ void notifyConfigurationUpdated(ConfigurationImpl config, boolean isFactory) {
+ if (isFactory)
+ managedServiceFactoryTracker.notifyUpdated(config);
+ else
+ managedServiceTracker.notifyUpdated(config);
+ }
+
+ void notifyConfigurationDeleted(ConfigurationImpl config, boolean isFactory) {
+ if (isFactory)
+ managedServiceFactoryTracker.notifyDeleted(config);
+ else
+ managedServiceTracker.notifyDeleted(config);
+ }
+
+ void modifyConfiguration(ServiceReference reference, Dictionary properties) {
+ pluginManager.modifyConfiguration(reference, properties);
+ }
+}
\ No newline at end of file
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 java.io.IOException;
+import org.osgi.framework.*;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * ConfigurationAdminImpl provides the ConfigurationAdmin service implementation
+ */
+class ConfigurationAdminImpl implements ConfigurationAdmin {
+
+ private final ConfigurationAdminFactory configurationAdminFactory;
+ private final Bundle bundle;
+ private final ConfigurationStore configurationStore;
+
+ public ConfigurationAdminImpl(ConfigurationAdminFactory configurationAdminFactory, ConfigurationStore configurationStore, Bundle bundle) {
+ this.configurationAdminFactory = configurationAdminFactory;
+ this.configurationStore = configurationStore;
+ this.bundle = bundle;
+ }
+
+ public Configuration createFactoryConfiguration(String factoryPid) throws IOException {
+ checkPID(factoryPid);
+ return configurationStore.createFactoryConfiguration(factoryPid, bundle.getLocation());
+ }
+
+ public Configuration createFactoryConfiguration(String factoryPid, String location) throws IOException {
+ checkPID(factoryPid);
+ this.configurationAdminFactory.checkConfigurationPermission();
+ return configurationStore.createFactoryConfiguration(factoryPid, location);
+ }
+
+ public Configuration getConfiguration(String pid) throws IOException {
+ checkPID(pid);
+ Configuration config = configurationStore.getConfiguration(pid, bundle.getLocation());
+ if (config.getBundleLocation() != null && !config.getBundleLocation().equals(bundle.getLocation()))
+ this.configurationAdminFactory.checkConfigurationPermission();
+ return config;
+ }
+
+ public Configuration getConfiguration(String pid, String location) throws IOException {
+ checkPID(pid);
+ this.configurationAdminFactory.checkConfigurationPermission();
+ return configurationStore.getConfiguration(pid, location);
+ }
+
+ public Configuration[] listConfigurations(String filterString) throws IOException, InvalidSyntaxException {
+ if (filterString == null)
+ filterString = "(" + Constants.SERVICE_PID + "=*)"; //$NON-NLS-1$ //$NON-NLS-2$
+
+ try {
+ this.configurationAdminFactory.checkConfigurationPermission();
+ } catch (SecurityException e) {
+ filterString = "(&(" + ConfigurationAdmin.SERVICE_BUNDLELOCATION + "=" + bundle.getLocation() + ")" + filterString + ")"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+ }
+ return configurationStore.listConfigurations(FrameworkUtil.createFilter(filterString));
+ }
+
+ private void checkPID(String pid) {
+ if (pid == null)
+ throw new IllegalArgumentException("PID cannot be null"); //$NON-NLS-1$
+ }
+}
\ No newline at end of file
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Vector;
+import java.util.Map.Entry;
+
+/**
+ * ConfigurationDictionary holds the actual configuration data and meets the various comparison
+ * requirements of the Configuration Admin Service specification.
+ */
+
+public class ConfigurationDictionary extends Dictionary implements Serializable {
+
+ private static final long serialVersionUID = -3583299578203095532L;
+ private static final Collection simples = Arrays.asList(new Class[] {String.class, Integer.class, Long.class, Float.class, Double.class, Byte.class, Short.class, Character.class, Boolean.class});
+ private static final Collection simpleArrays = Arrays.asList(new Class[] {String[].class, Integer[].class, Long[].class, Float[].class, Double[].class, Byte[].class, Short[].class, Character[].class, Boolean[].class});
+ private static final Collection primitiveArrays = Arrays.asList(new Class[] {long[].class, int[].class, short[].class, char[].class, byte[].class, double[].class, float[].class, boolean[].class});
+
+ static class CaseInsensitiveStringComparator implements Comparator, Serializable {
+ private static final long serialVersionUID = 6501536810492374044L;
+
+ public int compare(Object o1, Object o2) {
+ return ((String) o1).compareToIgnoreCase((String) o2);
+ }
+ }
+
+ protected final Map configurationProperties = Collections.synchronizedMap(new TreeMap(new CaseInsensitiveStringComparator()));
+
+ private static void validateValue(Object value) {
+ Class clazz = value.getClass();
+
+ // Is it in the set of simple types
+ if (simples.contains(clazz))
+ return;
+
+ // Is it an array of primitives or simples
+ if (simpleArrays.contains(clazz) || primitiveArrays.contains(clazz))
+ return;
+
+ // Is it a vector of simples
+ if (clazz == Vector.class) {
+ Vector valueVector = (Vector) value;
+ for (Iterator it = valueVector.iterator(); it.hasNext();) {
+ Class containedClazz = it.next().getClass();
+ if (!simples.contains(containedClazz)) {
+ throw new IllegalArgumentException(containedClazz.getName() + " in " + Vector.class.getName()); //$NON-NLS-1$
+ }
+ }
+ return;
+ }
+ throw new IllegalArgumentException(clazz.getName());
+ }
+
+ public Enumeration elements() {
+ return new Enumeration() {
+ final Iterator valuesIterator = configurationProperties.values().iterator();
+
+ public boolean hasMoreElements() {
+ return valuesIterator.hasNext();
+ }
+
+ public Object nextElement() {
+ return valuesIterator.next();
+ }
+ };
+ }
+
+ public Object get(Object key) {
+ if (key == null)
+ throw new NullPointerException();
+ return configurationProperties.get(key);
+ }
+
+ public boolean isEmpty() {
+ return configurationProperties.isEmpty();
+ }
+
+ public Enumeration keys() {
+ return new Enumeration() {
+ Iterator keysIterator = configurationProperties.keySet().iterator();
+
+ public boolean hasMoreElements() {
+ return keysIterator.hasNext();
+ }
+
+ public Object nextElement() {
+ return keysIterator.next();
+ }
+ };
+ }
+
+ public Object put(Object key, Object value) {
+ if (key == null || value == null)
+ throw new NullPointerException();
+
+ // Will throw an illegal argument exception if not a valid configuration property type
+ validateValue(value);
+
+ return configurationProperties.put(key, value);
+ }
+
+ public Object remove(Object key) {
+ if (key == null)
+ throw new NullPointerException();
+ return configurationProperties.remove(key);
+ }
+
+ public int size() {
+ return configurationProperties.size();
+ }
+
+ ConfigurationDictionary copy() {
+ ConfigurationDictionary result = new ConfigurationDictionary();
+ for (Iterator it = configurationProperties.entrySet().iterator(); it.hasNext();) {
+ Entry entry = (Entry) it.next();
+ Object key = entry.getKey();
+ Object value = entry.getValue();
+ if (value.getClass().isArray()) {
+ int arrayLength = Array.getLength(value);
+ Object copyOfArray = Array.newInstance(value.getClass().getComponentType(), arrayLength);
+ System.arraycopy(value, 0, copyOfArray, 0, arrayLength);
+ result.configurationProperties.put(key, copyOfArray);
+ } else if (value instanceof Vector)
+ result.configurationProperties.put(key, ((Vector) value).clone());
+ else
+ result.configurationProperties.put(key, value);
+ }
+ return result;
+ }
+}
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationEventAdapter.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationEventAdapter.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationEventAdapter.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.cm;
+
+import java.util.Hashtable;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ConfigurationEventAdapter implements ConfigurationListener {
+ // constants for Event topic substring
+ public static final String TOPIC = "org/osgi/service/cm/ConfigurationEvent"; //$NON-NLS-1$
+ public static final char TOPIC_SEPARATOR = '/';
+ // constants for Event types
+ public static final String CM_UPDATED = "CM_UPDATED"; //$NON-NLS-1$
+ public static final String CM_DELETED = "CM_DELETED"; //$NON-NLS-1$
+ // constants for Event properties
+ public static final String CM_FACTORY_PID = "cm.factoryPid"; //$NON-NLS-1$
+ public static final String CM_PID = "cm.pid"; //$NON-NLS-1$
+ public static final String SERVICE = "service"; //$NON-NLS-1$
+ public static final String SERVICE_ID = "service.id"; //$NON-NLS-1$
+ public static final String SERVICE_OBJECTCLASS = "service.objectClass"; //$NON-NLS-1$
+ public static final String SERVICE_PID = "service.pid"; //$NON-NLS-1$
+
+ private final BundleContext context;
+ private ServiceRegistration configListenerRegistration;
+ private final ServiceTracker eventAdminTracker;
+
+ public ConfigurationEventAdapter(BundleContext context) {
+ this.context = context;
+ eventAdminTracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
+ }
+
+ public void start() throws Exception {
+ eventAdminTracker.open();
+ configListenerRegistration = context.registerService(ConfigurationListener.class.getName(), this, null);
+ }
+
+ public void stop() throws Exception {
+ configListenerRegistration.unregister();
+ configListenerRegistration = null;
+ eventAdminTracker.close();
+ }
+
+ public void configurationEvent(ConfigurationEvent event) {
+ EventAdmin eventAdmin = (EventAdmin) eventAdminTracker.getService();
+ if (eventAdmin == null) {
+ return;
+ }
+ String typename = null;
+ switch (event.getType()) {
+ case ConfigurationEvent.CM_UPDATED :
+ typename = CM_UPDATED;
+ break;
+ case ConfigurationEvent.CM_DELETED :
+ typename = CM_DELETED;
+ break;
+ default : // do nothing
+ return;
+ }
+ String topic = TOPIC + TOPIC_SEPARATOR + typename;
+ ServiceReference ref = event.getReference();
+ if (ref == null) {
+ throw new RuntimeException("ServiceEvent.getServiceReference() is null"); //$NON-NLS-1$
+ }
+ Hashtable properties = new Hashtable();
+ properties.put(CM_PID, event.getPid());
+ if (event.getFactoryPid() != null) {
+ properties.put(CM_FACTORY_PID, event.getFactoryPid());
+ }
+ putServiceReferenceProperties(properties, ref);
+ Event convertedEvent = new Event(topic, properties);
+ eventAdmin.postEvent(convertedEvent);
+ }
+
+ public void putServiceReferenceProperties(Hashtable properties, ServiceReference ref) {
+ properties.put(SERVICE, ref);
+ properties.put(SERVICE_ID, ref.getProperty(org.osgi.framework.Constants.SERVICE_ID));
+ Object o = ref.getProperty(org.osgi.framework.Constants.SERVICE_PID);
+ if ((o != null) && (o instanceof String)) {
+ properties.put(SERVICE_PID, o);
+ }
+ Object o2 = ref.getProperty(org.osgi.framework.Constants.OBJECTCLASS);
+ if ((o2 != null) && (o2 instanceof String[])) {
+ properties.put(SERVICE_OBJECTCLASS, o2);
+ }
+ }
+}
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 java.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.*;
+
+/**
+ * ConfigurationImpl provides the Configuration implementation.
+ * The lock and unlock methods are used for synchronization. Operations outside of
+ * ConfigurationImpl that expect to have control of the lock should call checkLocked
+ */
+class ConfigurationImpl implements Configuration {
+
+ private final ConfigurationAdminFactory configurationAdminFactory;
+ private final ConfigurationStore configurationStore;
+ /** @GuardedBy this*/
+ private String bundleLocation;
+ private final String factoryPid;
+ private final String pid;
+ private ConfigurationDictionary dictionary;
+ /** @GuardedBy this*/
+ private boolean deleted = false;
+ /** @GuardedBy this*/
+ private Bundle boundBundle;
+ /** @GuardedBy this*/
+ private int lockedCount = 0;
+ /** @GuardedBy this*/
+ private Thread lockHolder = null;
+
+ public ConfigurationImpl(ConfigurationAdminFactory configurationAdminFactory, ConfigurationStore configurationStore, String factoryPid, String pid, String bundleLocation) {
+ this.configurationAdminFactory = configurationAdminFactory;
+ this.configurationStore = configurationStore;
+ this.factoryPid = factoryPid;
+ this.pid = pid;
+ this.bundleLocation = bundleLocation;
+ }
+
+ public ConfigurationImpl(ConfigurationAdminFactory configurationAdminFactory, ConfigurationStore configurationStore, Dictionary dictionary) {
+ this.configurationAdminFactory = configurationAdminFactory;
+ this.configurationStore = configurationStore;
+ pid = (String) dictionary.get(Constants.SERVICE_PID);
+ factoryPid = (String) dictionary.get(ConfigurationAdmin.SERVICE_FACTORYPID);
+ bundleLocation = (String) dictionary.get(ConfigurationAdmin.SERVICE_BUNDLELOCATION);
+ updateDictionary(dictionary);
+ }
+
+ protected synchronized void lock() {
+ Thread current = Thread.currentThread();
+ if (lockHolder != current) {
+ boolean interrupted = false;
+ try {
+ while (lockedCount != 0)
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ // although we don't handle an interrupt we should still
+ // save and restore the interrupt for others further up the stack
+ interrupted = true;
+ }
+ } finally {
+ if (interrupted)
+ current.interrupt(); // restore interrupted status
+ }
+ }
+ lockedCount++;
+ lockHolder = current;
+ }
+
+ protected synchronized void unlock() {
+ Thread current = Thread.currentThread();
+ if (lockHolder != current)
+ throw new IllegalStateException("Thread not lock owner"); //$NON-NLS-1$
+
+ lockedCount--;
+ if (lockedCount == 0) {
+ lockHolder = null;
+ notify();
+ }
+ }
+
+ protected synchronized void checkLocked() {
+ Thread current = Thread.currentThread();
+ if (lockHolder != current)
+ throw new IllegalStateException("Thread not lock owner"); //$NON-NLS-1$
+ }
+
+ protected boolean bind(Bundle bundle) {
+ try {
+ lock();
+ if (boundBundle == null && (bundleLocation == null || bundleLocation.equals(bundle.getLocation())))
+ boundBundle = bundle;
+ return (boundBundle == bundle);
+ } finally {
+ unlock();
+ }
+ }
+
+ protected void unbind(Bundle bundle) {
+ try {
+ lock();
+ if (boundBundle == bundle)
+ boundBundle = null;
+ } finally {
+ unlock();
+ }
+ }
+
+ public void delete() throws IOException {
+ try {
+ lock();
+ checkDeleted();
+ deleted = true;
+ configurationAdminFactory.notifyConfigurationDeleted(this, factoryPid != null);
+ configurationAdminFactory.dispatchEvent(ConfigurationEvent.CM_DELETED, factoryPid, pid);
+ } finally {
+ unlock();
+ }
+ configurationStore.removeConfiguration(pid);
+ }
+
+ private void checkDeleted() {
+ if (deleted)
+ throw new IllegalStateException("deleted"); //$NON-NLS-1$
+ }
+
+ public String getBundleLocation() {
+ try {
+ lock();
+ checkDeleted();
+ if (bundleLocation != null)
+ return bundleLocation;
+ if (boundBundle != null)
+ return boundBundle.getLocation();
+ return null;
+ } finally {
+ unlock();
+ }
+ }
+
+ protected String getFactoryPid(boolean checkDeleted) {
+ try {
+ lock();
+ if (checkDeleted)
+ checkDeleted();
+ return factoryPid;
+ } finally {
+ unlock();
+ }
+ }
+
+ public String getFactoryPid() {
+ return getFactoryPid(true);
+ }
+
+ protected String getPid(boolean checkDeleted) {
+ try {
+ lock();
+ if (checkDeleted)
+ checkDeleted();
+ return pid;
+ } finally {
+ unlock();
+ }
+ }
+
+ public String getPid() {
+ return getPid(true);
+ }
+
+ public Dictionary getProperties() {
+ try {
+ lock();
+ checkDeleted();
+ if (dictionary == null)
+ return null;
+
+ Dictionary copy = dictionary.copy();
+ copy.put(Constants.SERVICE_PID, pid);
+ if (factoryPid != null)
+ copy.put(ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid);
+
+ return copy;
+ } finally {
+ unlock();
+ }
+ }
+
+ protected Dictionary getAllProperties() {
+ try {
+ lock();
+ if (deleted)
+ return null;
+ Dictionary copy = getProperties();
+ if (copy != null && bundleLocation != null)
+ copy.put(ConfigurationAdmin.SERVICE_BUNDLELOCATION, getBundleLocation());
+ return copy;
+ } finally {
+ unlock();
+ }
+ }
+
+ public void setBundleLocation(String bundleLocation) {
+ try {
+ lock();
+ checkDeleted();
+ configurationAdminFactory.checkConfigurationPermission();
+ this.bundleLocation = bundleLocation;
+ } finally {
+ unlock();
+ }
+ }
+
+ public void update() throws IOException {
+ try {
+ lock();
+ checkDeleted();
+ if (dictionary == null)
+ dictionary = new ConfigurationDictionary();
+ configurationStore.saveConfiguration(pid, this);
+ configurationAdminFactory.notifyConfigurationUpdated(this, factoryPid != null);
+ } finally {
+ unlock();
+ }
+ }
+
+ public void update(Dictionary properties) throws IOException {
+ try {
+ lock();
+ checkDeleted();
+ updateDictionary(properties);
+ configurationStore.saveConfiguration(pid, this);
+ configurationAdminFactory.notifyConfigurationUpdated(this, factoryPid != null);
+ configurationAdminFactory.dispatchEvent(ConfigurationEvent.CM_UPDATED, factoryPid, pid);
+ } finally {
+ unlock();
+ }
+ }
+
+ private void updateDictionary(Dictionary properties) {
+ ConfigurationDictionary newDictionary = new ConfigurationDictionary();
+ Enumeration keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ if (newDictionary.get(key) == null)
+ newDictionary.put(key, properties.get(key));
+ else
+ throw new IllegalArgumentException(key + " is already present or is a case variant."); //$NON-NLS-1$
+ }
+ newDictionary.remove(Constants.SERVICE_PID);
+ newDictionary.remove(ConfigurationAdmin.SERVICE_FACTORYPID);
+ newDictionary.remove(ConfigurationAdmin.SERVICE_BUNDLELOCATION);
+
+ dictionary = newDictionary;
+ }
+
+ public boolean equals(Object obj) {
+ return pid.equals(((Configuration) obj).getPid());
+ }
+
+ public int hashCode() {
+ return pid.hashCode();
+ }
+
+ protected boolean isDeleted() {
+ try {
+ lock();
+ return deleted;
+ } finally {
+ unlock();
+ }
+ }
+}
\ No newline at end of file
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 java.io.*;
+import java.util.*;
+import org.eclipse.equinox.internal.cm.reliablefile.*;
+import org.osgi.framework.*;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.log.LogService;
+
+/**
+ * ConfigurationStore manages all active configurations along with persistence. The current
+ * implementation uses a filestore and serialization of the configuration dictionaries to files
+ * identified by their pid. Persistence details are in the constructor, saveConfiguration, and
+ * deleteConfiguration and can be factored out separately if required.
+ */
+class ConfigurationStore {
+
+ private final ConfigurationAdminFactory configurationAdminFactory;
+ private static final String STORE_DIR = "store"; //$NON-NLS-1$
+ private static final String PID_EXT = ".pid"; //$NON-NLS-1$
+ private final Map configurations = new HashMap();
+ private int createdPidCount = 0;
+ private final File store;
+
+ public ConfigurationStore(ConfigurationAdminFactory configurationAdminFactory, BundleContext context) {
+ this.configurationAdminFactory = configurationAdminFactory;
+ store = context.getDataFile(STORE_DIR);
+ if (store == null)
+ return; // no persistent store
+
+ store.mkdir();
+ File[] configurationFiles = store.listFiles();
+ for (int i = 0; i < configurationFiles.length; ++i) {
+ String configurationFileName = configurationFiles[i].getName();
+ if (!configurationFileName.endsWith(PID_EXT))
+ continue;
+
+ InputStream ris = null;
+ ObjectInputStream ois = null;
+ boolean deleteFile = false;
+ try {
+ ris = new ReliableFileInputStream(configurationFiles[i]);
+ ois = new ObjectInputStream(ris);
+ Dictionary dictionary = (Dictionary) ois.readObject();
+ ConfigurationImpl config = new ConfigurationImpl(configurationAdminFactory, this, dictionary);
+ configurations.put(config.getPid(), config);
+ } catch (IOException e) {
+ String message = e.getMessage();
+ String pid = configurationFileName.substring(0, configurationFileName.length() - 4);
+ String errorMessage = "{Configuration Admin - pid = " + pid + "} could not be restored." + ((message == null) ? "" : " " + message); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ configurationAdminFactory.log(LogService.LOG_ERROR, errorMessage);
+ deleteFile = true;
+ } catch (ClassNotFoundException e) {
+ configurationAdminFactory.log(LogService.LOG_ERROR, e.getMessage());
+ } finally {
+ if (ois != null) {
+ try {
+ ois.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (ris != null) {
+ try {
+ ris.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ if (deleteFile) {
+ ReliableFile.delete(configurationFiles[i]);
+ configurationFiles[i].delete();
+ }
+ }
+ }
+
+ public void saveConfiguration(String pid, ConfigurationImpl config) throws IOException {
+ if (store == null)
+ return; // no persistent store
+
+ config.checkLocked();
+ File configFile = new File(store, pid + PID_EXT);
+ OutputStream ros = null;
+ ObjectOutputStream oos = null;
+ try {
+ configFile.createNewFile();
+ ros = new ReliableFileOutputStream(configFile);
+ oos = new ObjectOutputStream(ros);
+ oos.writeObject(config.getAllProperties());
+ } finally {
+ if (oos != null) {
+ try {
+ oos.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (ros != null) {
+ try {
+ ros.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ public synchronized void removeConfiguration(String pid) {
+ configurations.remove(pid);
+ if (store == null)
+ return; // no persistent store
+ File configFile = new File(store, pid + PID_EXT);
+ ReliableFile.delete(configFile);
+ configFile.delete();
+ }
+
+ public synchronized Configuration getConfiguration(String pid, String location) {
+ Configuration config = (Configuration) configurations.get(pid);
+ if (config == null) {
+ config = new ConfigurationImpl(configurationAdminFactory, this, null, pid, location);
+ configurations.put(pid, config);
+ }
+ return config;
+ }
+
+ public synchronized Configuration createFactoryConfiguration(String factoryPid, String location) {
+ String pid = factoryPid + "-" + new Date().getTime() + "-" + createdPidCount++; //$NON-NLS-1$ //$NON-NLS-2$
+ ConfigurationImpl config = new ConfigurationImpl(configurationAdminFactory, this, factoryPid, pid, location);
+ configurations.put(pid, config);
+ return config;
+ }
+
+ public synchronized ConfigurationImpl findConfiguration(String pid) {
+ return (ConfigurationImpl) configurations.get(pid);
+ }
+
+ public synchronized ConfigurationImpl[] getFactoryConfigurations(String factoryPid) {
+ List resultList = new ArrayList();
+ for (Iterator it = configurations.values().iterator(); it.hasNext();) {
+ ConfigurationImpl config = (ConfigurationImpl) it.next();
+ String otherFactoryPid = config.getFactoryPid();
+ if (otherFactoryPid != null && otherFactoryPid.equals(factoryPid))
+ resultList.add(config);
+ }
+ return (ConfigurationImpl[]) resultList.toArray(new ConfigurationImpl[0]);
+ }
+
+ public synchronized Configuration[] listConfigurations(Filter filter) {
+ List resultList = new ArrayList();
+ for (Iterator it = configurations.values().iterator(); it.hasNext();) {
+ ConfigurationImpl config = (ConfigurationImpl) it.next();
+ Dictionary properties = config.getAllProperties();
+ if (properties != null && filter.match(properties))
+ resultList.add(config);
+ }
+ int size = resultList.size();
+ return size == 0 ? null : (Configuration[]) resultList.toArray(new Configuration[size]);
+ }
+
+ public synchronized void unbindConfigurations(Bundle bundle) {
+ for (Iterator it = configurations.values().iterator(); it.hasNext();) {
+ ConfigurationImpl config = (ConfigurationImpl) it.next();
+ config.unbind(bundle);
+ }
+ }
+}
\ No newline at end of file
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/EventDispatcher.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/EventDispatcher.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/EventDispatcher.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+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 tracker;
+ private final SerializedTaskQueue queue = new SerializedTaskQueue("ConfigurationListener Event Queue"); //$NON-NLS-1$
+ /** @GuardedBy this */
+ private ServiceReference configAdminReference;
+ final LogService log;
+
+ public EventDispatcher(BundleContext context, LogService log) {
+ this.log = log;
+ tracker = new ServiceTracker(context, ConfigurationListener.class.getName(), null);
+ }
+
+ public void start() {
+ tracker.open();
+ }
+
+ public void stop() {
+ tracker.close();
+ synchronized (this) {
+ configAdminReference = null;
+ }
+ }
+
+ synchronized void setServiceReference(ServiceReference 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[] refs = tracker.getServiceReferences();
+ if (refs == null)
+ return;
+
+ for (int i = 0; i < refs.length; ++i) {
+ final ServiceReference ref = refs[i];
+ queue.put(new Runnable() {
+ public void run() {
+ ConfigurationListener listener = (ConfigurationListener) 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);
+ }
+}
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/LogTracker.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/LogTracker.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/LogTracker.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2007 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.cm;
+
+import java.io.PrintStream;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * LogTracker class. This class encapsulates the LogService
+ * and handles all issues such as the service coming and going.
+ */
+
+public class LogTracker extends ServiceTracker implements LogService {
+ /** LogService interface class name */
+ protected final static String clazz = "org.osgi.service.log.LogService"; //$NON-NLS-1$
+
+ /** PrintStream to use if LogService is unavailable */
+ private final PrintStream out;
+
+ /**
+ * Create new LogTracker.
+ *
+ * @param context BundleContext of parent bundle.
+ * @param out Default PrintStream to use if LogService is unavailable.
+ */
+ public LogTracker(BundleContext context, PrintStream out) {
+ super(context, clazz, null);
+ this.out = out;
+ }
+
+ /*
+ * ----------------------------------------------------------------------
+ * LogService Interface implementation
+ * ----------------------------------------------------------------------
+ */
+
+ public void log(int level, String message) {
+ log(null, level, message, null);
+ }
+
+ public void log(int level, String message, Throwable exception) {
+ log(null, level, message, exception);
+ }
+
+ public void log(ServiceReference reference, int level, String message) {
+ log(reference, level, message, null);
+ }
+
+ public synchronized void log(ServiceReference reference, int level, String message, Throwable exception) {
+ ServiceReference[] references = getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ for (int i = 0; i < size; i++) {
+ LogService service = (LogService) getService(references[i]);
+ if (service != null) {
+ try {
+ service.log(reference, level, message, exception);
+ } catch (Exception e) {
+ // TODO: consider printing to System Error
+ }
+ }
+ }
+
+ return;
+ }
+
+ noLogService(level, message, exception, reference);
+ }
+
+ /**
+ * The LogService is not available so we write the message to a PrintStream.
+ *
+ * @param level Logging level
+ * @param message Log message.
+ * @param throwable Log exception or null if none.
+ * @param reference ServiceReference associated with message or null if none.
+ */
+ protected void noLogService(int level, String message, Throwable throwable, ServiceReference reference) {
+ if (out != null) {
+ synchronized (out) {
+ // Bug #113286. If no log service present and messages are being
+ // printed to stdout, prepend message with a timestamp.
+ String timestamp = getDate(new Date());
+ out.print(timestamp + " "); //$NON-NLS-1$
+
+ switch (level) {
+ case LOG_DEBUG : {
+ out.print("Debug"); //$NON-NLS-1$
+ break;
+ }
+ case LOG_INFO : {
+ out.print("Info"); //$NON-NLS-1$
+ break;
+ }
+ case LOG_WARNING : {
+ out.print("Warning"); //$NON-NLS-1$
+ break;
+ }
+ case LOG_ERROR : {
+ out.print("Error"); //$NON-NLS-1$
+ break;
+ }
+ default : {
+ out.print("["); //$NON-NLS-1$
+ out.print("Unknown Log Level"); //$NON-NLS-1$
+ out.print("]"); //$NON-NLS-1$
+ break;
+ }
+ }
+ out.print(": "); //$NON-NLS-1$
+ out.println(message);
+
+ if (reference != null) {
+ out.println(reference);
+ }
+
+ if (throwable != null) {
+ throwable.printStackTrace(out);
+ }
+ }
+ }
+ }
+
+ // from EclipseLog to avoid using DateFormat -- see bug 149892#c10
+ private String getDate(Date date) {
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ StringBuffer sb = new StringBuffer();
+ appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-');
+ appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-');
+ appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' ');
+ appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':');
+ appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':');
+ appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.');
+ appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb);
+ return sb.toString();
+ }
+
+ private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) {
+ pad = pad - 1;
+ if (pad == 0)
+ return buffer.append(Integer.toString(value));
+ int padding = (int) Math.pow(10, pad);
+ if (value >= padding)
+ return buffer.append(Integer.toString(value));
+ while (padding > value && padding > 1) {
+ buffer.append('0');
+ padding = padding / 10;
+ }
+ buffer.append(value);
+ return buffer;
+ }
+}
Added: branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java
===================================================================
--- branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java (rev 0)
+++ branches/user_prefs/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java 2008-03-21 17:39:47 UTC (rev 676)
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 java.util.*;
+import java.util.Map.Entry;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * ManagedServiceFactoryTracker tracks... ManagedServiceFactory(s) and notifies them about related configuration changes
+ */
+class ManagedServiceFactoryTracker extends ServiceTracker {
+
+ final ConfigurationAdminFactory configurationAdminFactory;
+ private final ConfigurationStore configurationStore;
+ private final Map managedServiceFactories = new HashMap();
+ private final Map managedServiceFactoryReferences = new HashMap();
+ private final SerializedTaskQueue queue = new SerializedTaskQueue("ManagedServiceFactory Update Queue"); //$NON-NLS-1$
+
+ public ManagedServiceFactoryTracker(ConfigurationAdminFactory configurationAdminFactory, ConfigurationStore configurationStore, BundleContext context) {
+ super(context, ManagedServiceFactory.class.getName(), null);
+ this.configurationAdminFactory = configurationAdminFactory;
+ this.configurationStore = configurationStore;
+ }
+
+ protected void notifyDeleted(ConfigurationImpl config) {
+ config.checkLocked();
+ String factoryPid = config.getFactoryPid(false);
+ ServiceReference reference = getManagedServiceFactoryReference(factoryPid);
+ if (reference != null && config.bind(reference.getBundle()))
+ asynchDeleted(getManagedServiceFactory(factoryPid), config.getPid(false));
+ }
+
+ protected void notifyUpdated(ConfigurationImpl config) {
+ config.checkLocked();
+ String factoryPid = config.getFactoryPid();
+ ServiceReference reference = getManagedServiceFactoryReference(factoryPid);
+ if (reference != null && config.bind(reference.getBundle())) {
+ Dictionary properties = config.getProperties();
+ configurationAdminFactory.modifyConfiguration(reference, properties);
+ asynchUpdated(getManagedServiceFactory(factoryPid), config.getPid(), properties);
+ }
+ }
+
+ public Object addingService(ServiceReference reference) {
+ String factoryPid = (String) reference.getProperty(Constants.SERVICE_PID);
+ if (factoryPid == null)
+ return null;
+
+ ManagedServiceFactory service = (...
[truncated message content] |