Bug 117154 uniform API for obtaining the 'default' extension registry
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesOSGiUtils.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesOSGiUtils.java
index 9229064..37cc6a6 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesOSGiUtils.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesOSGiUtils.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.core.internal.preferences;
-import org.eclipse.equinox.registry.IExtensionRegistry;
import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.service.debug.DebugOptions;
@@ -25,7 +24,6 @@
* @since org.eclipse.equinox.preferences 1.0
*/
public class PreferencesOSGiUtils {
- private ServiceTracker registryTracker = null;
private ServiceTracker logTracker = null;
private ServiceTracker initTracker = null;
private ServiceTracker debugTracker = null;
@@ -58,9 +56,6 @@
return;
}
- registryTracker = new ServiceTracker(context, IExtensionRegistry.class.getName(), null);
- registryTracker.open();
-
initTracker = new ServiceTracker(context, ILegacyPreferences.class.getName(), null);
initTracker.open(true);
@@ -95,10 +90,6 @@
}
void closeServices() {
- if (registryTracker != null) {
- registryTracker.close();
- registryTracker = null;
- }
if (initTracker != null) {
initTracker.close();
initTracker = null;
@@ -125,13 +116,6 @@
}
}
- public IExtensionRegistry getExtensionRegistry() {
- if (registryTracker != null)
- return (IExtensionRegistry) registryTracker.getService();
- PrefsMessages.message("Registry tracker is not set"); //$NON-NLS-1$
- return null;
- }
-
public ILegacyPreferences getLegacyPreferences() {
if (initTracker != null)
return (ILegacyPreferences) initTracker.getService();
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java
index 67dbb25..7b25977 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java
@@ -95,8 +95,8 @@
if (ELEMENT_SCOPE.equalsIgnoreCase(elements[j].getName()))
scopeAdded(elements[j]);
}
- PreferencesOSGiUtils.getDefault().getExtensionRegistry().addRegistryChangeListener(this, IPreferencesConstants.RUNTIME_NAME);
- PreferencesOSGiUtils.getDefault().getExtensionRegistry().addRegistryChangeListener(this, IPreferencesConstants.PREFERS_NAME);
+ RegistryFactory.getRegistry().addRegistryChangeListener(this, IPreferencesConstants.RUNTIME_NAME);
+ RegistryFactory.getRegistry().addRegistryChangeListener(this, IPreferencesConstants.PREFERS_NAME);
}
private void initializeModifyListeners() {
@@ -108,8 +108,8 @@
if (ELEMENT_MODIFIER.equalsIgnoreCase(elements[j].getName()))
addModifyListener(elements[j]);
}
- PreferencesOSGiUtils.getDefault().getExtensionRegistry().addRegistryChangeListener(this, IPreferencesConstants.RUNTIME_NAME);
- PreferencesOSGiUtils.getDefault().getExtensionRegistry().addRegistryChangeListener(this, IPreferencesConstants.PREFERS_NAME);
+ RegistryFactory.getRegistry().addRegistryChangeListener(this, IPreferencesConstants.RUNTIME_NAME);
+ RegistryFactory.getRegistry().addRegistryChangeListener(this, IPreferencesConstants.PREFERS_NAME);
}
static void log(IStatus status) {
@@ -1127,7 +1127,7 @@
private final static IExtension[] emptyExtensionArray = new IExtension[0];
public static IExtension[] getPrefExtensions() {
- IExtensionRegistry registry = PreferencesOSGiUtils.getDefault().getExtensionRegistry();
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
IExtension[] extensionsOld = emptyExtensionArray;
IExtension[] extensionsNew = emptyExtensionArray;
// "old"
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java
index c81005f..4bc0cc1 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java
@@ -1098,4 +1098,8 @@
currentConfigurationElement.setParentType(parent instanceof ConfigurationElement ? RegistryObjectManager.CONFIGURATION_ELEMENT : RegistryObjectManager.EXTENSION);
}
+ public void setCompatibilityStrategy(ICompatibilityStrategy strategy) {
+ compatibilityStrategy = strategy;
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/IRegistryConstants.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/IRegistryConstants.java
index ce605b0..130990d 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/IRegistryConstants.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/IRegistryConstants.java
@@ -26,6 +26,7 @@
public static final String PROP_NO_LAZY_CACHE_LOADING = "eclipse.noLazyRegistryCacheLoading"; //$NON-NLS-1$
public static final String PROP_CHECK_CONFIG = "osgi.checkConfiguration"; //$NON-NLS-1$
public static final String PROP_NO_REGISTRY_CACHE = "eclipse.noRegistryCache"; //$NON-NLS-1$
+ public static final String PROP_DEFAULT_REGISTRY = "eclipse.createRegistry"; //$NON-NLS-1$
// OSGI system properties
public static final String PROP_NL = "osgi.nl"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/RegistryMessages.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/RegistryMessages.java
index 66e9f3e..e245e6f 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/RegistryMessages.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/RegistryMessages.java
@@ -28,6 +28,7 @@
public static String meta_unableToCreateCache;
public static String meta_unableToReadCache;
public static String registry_no_default;
+ public static String registry_default_exists;
// parsing/resolve
public static String parse_error;
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/messages.properties b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/messages.properties
index b0cf8bd..9acabd8 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/messages.properties
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/messages.properties
@@ -18,6 +18,7 @@
meta_unableToCreateCache = Unable to create output stream for registry cache.
meta_unableToReadCache = Unable to create input stream for registry cache.
registry_no_default = Extension tracker was unable to obtain Eclipse extension registry.
+registry_default_exists = Extension registry provider is already set.
### parsing/resolve
parse_error = Parsing error: \"{0}\".
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java
index 7932ce3..eff2382 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java
@@ -10,31 +10,57 @@
*******************************************************************************/
package org.eclipse.core.internal.registry.osgi;
+import java.io.File;
+import java.util.Hashtable;
import org.eclipse.core.internal.registry.IRegistryConstants;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.equinox.registry.*;
+import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
+import org.osgi.framework.*;
import org.osgi.util.tracker.ServiceTracker;
/**
- * The extension registry bundle manager class.
+ * The extension registry bundle. This activator will create the default OSGi registry
+ * unless told otherwise by setting the following system property to false:
+ * <code>eclipse.createRegistry=false</code>
+ *
+ * The default registry will be stopped on the bundle shutdown.
+ *
+ * @see IRegistryConstants#PROP_DEFAULT_REGISTRY
*/
public class Activator implements BundleActivator {
private static BundleContext bundleContext;
/**
+ * Location of the default registry relative to the configuration area
+ */
+ private static final String STORAGE_DIR = "org.eclipse.core.runtime"; //$NON-NLS-1$
+
+ /**
+ * Access key to the default registry
+ */
+ private Object registryKey = new Object();
+
+ private IExtensionRegistry defaultRegistry = null;
+ private ServiceRegistration registryRegistration;
+ private RegistryProviderOSGI defaultProvider;
+
+ /**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
bundleContext = context;
processCommandLine();
+ startRegistry();
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
+ stopRegistry();
bundleContext = null;
}
@@ -68,4 +94,29 @@
}
}
+ public void startRegistry() throws CoreException {
+ // see if the customer suppressed the creation of default registry
+ String property = bundleContext.getProperty(IRegistryConstants.PROP_DEFAULT_REGISTRY);
+ if (property != null && property.equalsIgnoreCase("false"))
+ return;
+
+ Location configuration = OSGIUtils.getDefault().getConfigurationLocation();
+ File theStorageDir = new File(configuration.getURL().getPath() + '/' + STORAGE_DIR);
+ EquinoxRegistryStrategy registryStrategy = new EquinoxRegistryStrategy(theStorageDir, configuration.isReadOnly(), registryKey);
+ defaultRegistry = RegistryFactory.createRegistry(registryStrategy, registryKey);
+
+ registryRegistration = Activator.getContext().registerService(IExtensionRegistry.class.getName(), defaultRegistry, new Hashtable());
+ defaultProvider = new RegistryProviderOSGI();
+ // Set the registry provider and specify this as a default registry:
+ RegistryFactory.setRegistryProvider(defaultProvider);
+ }
+
+ private void stopRegistry() {
+ if (defaultRegistry != null) {
+ defaultProvider.release();
+ registryRegistration.unregister();
+ defaultRegistry.stop(registryKey);
+ }
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/OSGIUtils.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/OSGIUtils.java
index ea9e8d9..b967371 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/OSGIUtils.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/OSGIUtils.java
@@ -27,6 +27,7 @@
public class OSGIUtils {
private ServiceTracker debugTracker = null;
private ServiceTracker bundleTracker = null;
+ // XXX platfromTracker is misspelt.
private ServiceTracker platfromTracker = null;
private ServiceTracker configurationLocationTracker = null;
@@ -52,6 +53,8 @@
* Print a debug message to the console.
* Pre-pend the message with the current date and the name of the current thread.
*/
+ // XXX be careful using this method. In general you should try to log first and then if
+ // debug is on print to system out.
public static void message(String message) {
StringBuffer buffer = new StringBuffer();
buffer.append(new Date(System.currentTimeMillis()));
@@ -65,7 +68,7 @@
private void initServices() {
BundleContext context = Activator.getContext();
if (context == null) {
- message("PreferencesUtils called before plugin started"); //$NON-NLS-1$
+ message("Registry OSGIUtils called before plugin started"); //$NON-NLS-1$
return;
}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryProviderOSGI.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryProviderOSGI.java
new file mode 100644
index 0000000..08fd658
--- /dev/null
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryProviderOSGI.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.core.internal.registry.osgi;
+
+import org.eclipse.equinox.registry.IExtensionRegistry;
+import org.eclipse.equinox.registry.IRegistryProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
+
+public final class RegistryProviderOSGI implements IRegistryProvider {
+
+ private ServiceTracker registryTracker = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.equinox.registry.IRegistryProvider#getRegistry()
+ */
+ public IExtensionRegistry getRegistry() {
+ if (registryTracker == null) {
+ BundleContext context = Activator.getContext();
+ if (context == null) {
+ // XXX should not print to system out. Have to at least try and log.
+ OSGIUtils.message(this.getClass().getName() + ": plugin context is not set"); //$NON-NLS-1$
+ return null;
+ }
+ registryTracker = new ServiceTracker(context, IExtensionRegistry.class.getName(), null);
+ registryTracker.open();
+ }
+ return (IExtensionRegistry) registryTracker.getService();
+ }
+
+ /**
+ * Release OSGi tracker
+ */
+ public void release() {
+ if (registryTracker != null) {
+ registryTracker.close();
+ registryTracker = null;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java
index 5d2067d..580b9f0 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java
@@ -22,6 +22,8 @@
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.equinox.registry.IRegistryProvider;
+import org.eclipse.equinox.registry.RegistryFactory;
import org.eclipse.equinox.registry.spi.RegistryStrategy;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
@@ -39,6 +41,10 @@
* - Performs registry validation based on the time stamps of the plugin.xml / fragment.xml files
* - XML parser is obtained via an OSGi service
*
+ * XXX really?!!
+ * Only one registry with OSGI strategy can be instantied in the running application.
+ * @see RegistryFactory#setRegistryProvider(IRegistryProvider)
+ *
* @since org.eclipse.equinox.registry 1.0
*
*/
@@ -123,6 +129,7 @@
return RegistryStrategy.processChangeEvent(listenerInfos, deltas, registry);
}
}
+
/* (non-Javadoc)
* @see org.eclipse.equinox.registry.spi.RegistryStrategy#scheduleChangeEvent(java.lang.Object[], java.util.Map, java.lang.Object)
@@ -142,8 +149,11 @@
Bundle contributingBundle = getContributingBundle(contributingBundleId);
if (contributingBundle == null) // When restored from disk the underlying bundle may have been uninstalled
throw new IllegalStateException("Internal error in extension registry. The bundle corresponding to this contribution has been uninstalled."); //$NON-NLS-1$
- if (OSGIUtils.getDefault().isFragment(contributingBundle))
- return OSGIUtils.getDefault().getHosts(contributingBundle)[0];
+ if (OSGIUtils.getDefault().isFragment(contributingBundle)) {
+ Bundle[] hosts = OSGIUtils.getDefault().getHosts(contributingBundle);
+ if (hosts != null)
+ return hosts[0];
+ }
return contributingBundle;
}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/equinox/registry/IRegistryProvider.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/equinox/registry/IRegistryProvider.java
new file mode 100644
index 0000000..2a7e791
--- /dev/null
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/equinox/registry/IRegistryProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.registry;
+
+/**
+ * Implement this interface to specify the default extension registry.
+ *
+ * @see RegistryFactory#getRegistry()
+ * @see RegistryFactory#setRegistryProvider(IRegistryProvider)
+ *
+ * <b>This is an experimental API. It might change in future.</b>
+ *
+ * @since org.eclipse.equinox.registry 1.0
+ */
+public interface IRegistryProvider {
+
+ /**
+ * Returns the "default" extension registry.
+ * @return an extension registry
+ */
+ public IExtensionRegistry getRegistry();
+}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/equinox/registry/RegistryFactory.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/equinox/registry/RegistryFactory.java
index 94ec1fd..ecc0f90 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/equinox/registry/RegistryFactory.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/equinox/registry/RegistryFactory.java
@@ -11,12 +11,13 @@
package org.eclipse.equinox.registry;
import java.io.File;
-import org.eclipse.core.internal.registry.ExtensionRegistry;
+import org.eclipse.core.internal.registry.*;
import org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI;
+import org.eclipse.core.runtime.*;
import org.eclipse.equinox.registry.spi.RegistryStrategy;
/**
- * Use this class to create an extension registry.
+ * Use this class to create or obtain an extension registry.
*
* This class is not intended to be subclassed or instantiated.
*
@@ -24,6 +25,8 @@
*/
public final class RegistryFactory {
+ private static IRegistryProvider defaultRegistryProvider;
+
/**
* Creates an extension registry.
*
@@ -31,11 +34,27 @@
* @param token - control token for the registry. Keep it to access controlled methods of the
* registry
* @return - new extension registry
+ * @throws CoreException in case if registry start conditions are not met. The exception's status
+ * message provides additional details.
*/
- public static IExtensionRegistry createExtensionRegistry(RegistryStrategy strategy, Object token) {
+ public static IExtensionRegistry createRegistry(RegistryStrategy strategy, Object token) {
return new ExtensionRegistry(strategy, token);
}
-
+
+ /**
+ * Returns the existing extension registry specified by the registry provider.
+ * May return null is the provider has not been set or registry was not created.
+ *
+ * @return existing extension registry or null
+ */
+ // XXX the team style is to put test filters first then do the work. So here the if would
+ // be == null then return null. Then the return of getRegistry().
+ public static IExtensionRegistry getRegistry() {
+ if (defaultRegistryProvider != null)
+ return defaultRegistryProvider.getRegistry();
+ return null;
+ }
+
/**
* Creates registry strategy that can be used in OSGi world. It provides the following functionality:
* - Event scheduling is done using Eclipse job scheduling mechanism
@@ -53,4 +72,25 @@
public static RegistryStrategy createOSGiStrategy(File storageDir, boolean cacheReadOnly, Object token) {
return new RegistryStrategyOSGI(storageDir, cacheReadOnly, token);
}
+
+ /**
+ * Use this method to specify the default registry provider. The default registry provider
+ * is immutable in the sense that it can be set only once during the application runtime.
+ * Attempts to change the default registry provider will cause CoreException.
+ *
+ * @see #getRegistry()
+ *
+ * <b>This is an experimental API. It might change in future.</b>
+ *
+ * @param provider - extension registry provider
+ * @throws CoreException - default registry provider was already set for this application
+ */
+ public static void setRegistryProvider(IRegistryProvider provider) throws CoreException {
+ if (defaultRegistryProvider != null) {
+ Status status = new Status(IStatus.ERROR, RegistryMessages.OWNER_NAME, IRegistryConstants.PLUGIN_ERROR, RegistryMessages.registry_default_exists, null);
+ throw new CoreException(status);
+ }
+ defaultRegistryProvider = provider;
+ }
+
}