Bug 55065 [RCP] early startup mechanism needs to use reflect if compatibility is not available
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
index 7980879..24c56ba 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
@@ -16,6 +16,8 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@@ -24,26 +26,14 @@
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IPluginDescriptor;
-import org.eclipse.core.runtime.IPluginRegistry;
+import org.eclipse.core.runtime.IPlatform;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.BusyIndicator;
-import org.eclipse.swt.graphics.DeviceData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.CommandResolver;
import org.eclipse.jface.action.IAction;
@@ -61,7 +51,15 @@
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.window.WindowManager;
-
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.graphics.DeviceData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IDecoratorManager;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
@@ -93,13 +91,6 @@
import org.eclipse.ui.contexts.ContextManagerEvent;
import org.eclipse.ui.contexts.IContextManagerListener;
import org.eclipse.ui.contexts.IWorkbenchContextSupport;
-import org.eclipse.ui.intro.IIntroPart;
-import org.eclipse.ui.keys.KeySequence;
-import org.eclipse.ui.keys.KeyStroke;
-import org.eclipse.ui.keys.SWTKeySupport;
-import org.eclipse.ui.progress.IProgressService;
-import org.eclipse.ui.themes.IThemeManager;
-
import org.eclipse.ui.internal.activities.ws.WorkbenchActivitySupport;
import org.eclipse.ui.internal.commands.ws.WorkbenchCommandSupport;
import org.eclipse.ui.internal.contexts.ws.WorkbenchContextSupport;
@@ -117,6 +108,13 @@
import org.eclipse.ui.internal.themes.FontDefinition;
import org.eclipse.ui.internal.themes.ThemeElementHelper;
import org.eclipse.ui.internal.themes.WorkbenchThemeManager;
+import org.eclipse.ui.intro.IIntroPart;
+import org.eclipse.ui.keys.KeySequence;
+import org.eclipse.ui.keys.KeyStroke;
+import org.eclipse.ui.keys.SWTKeySupport;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.themes.IThemeManager;
+import org.osgi.framework.Bundle;
/**
* The workbench class represents the top of the Eclipse user interface. Its
@@ -1312,17 +1310,17 @@
}
/**
- * Returns an array of all plugins that extend the <code>org.eclipse.ui.startup</code>
- * extension point.
+ * Returns an array with the ids of all plugins that extend the
+ * <code>org.eclipse.ui.startup</code> extension point.
*/
- public IPluginDescriptor[] getEarlyActivatedPlugins() {
- IPluginRegistry registry = Platform.getPluginRegistry();
- IExtensionPoint point =
- registry.getExtensionPoint(PlatformUI.PLUGIN_ID, IWorkbenchConstants.PL_STARTUP);
+ public String[] getEarlyActivatedPlugins() {
+ IExtensionPoint point = Platform.getExtensionRegistry()
+ .getExtensionPoint(PlatformUI.PLUGIN_ID,
+ IWorkbenchConstants.PL_STARTUP);
IExtension[] extensions = point.getExtensions();
- IPluginDescriptor result[] = new IPluginDescriptor[extensions.length];
+ String[] result = new String[extensions.length];
for (int i = 0; i < extensions.length; i++) {
- result[i] = extensions[i].getDeclaringPluginDescriptor();
+ result[i] = extensions[i].getNamespace();
}
return result;
}
@@ -1334,67 +1332,23 @@
*/
private void startPlugins() {
Runnable work = new Runnable() {
- IPreferenceStore store = getPreferenceStore();
- final String pref =
- store.getString(IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
+ final String disabledPlugins = getPreferenceStore()
+ .getString(IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
+
public void run() {
- IPluginRegistry registry = Platform.getPluginRegistry();
- IExtensionPoint point =
- registry.getExtensionPoint(
- PlatformUI.PLUGIN_ID,
- IWorkbenchConstants.PL_STARTUP);
- IExtension[] extensions = point.getExtensions();
- for (int i = 0; i < extensions.length; i++) {
- IExtension extension = extensions[i];
- // Look for the class attribute in the startup element
- // first
- IConfigurationElement[] configElements = extension.getConfigurationElements();
- // There should only be one configuration element and it
- // should
- // be named "startup".
- IConfigurationElement startupElement = null;
- for (int j = 0; j < configElements.length && startupElement == null; j++) {
- if (configElements[j].getName().equals(IWorkbenchConstants.TAG_STARTUP)) {
- startupElement = configElements[j];
- }
- }
- final IConfigurationElement startElement = startupElement;
- final String startupName;
- if (startElement != null) {
- // This will cause startupName to be null if
- // the class attribute does not exist.
- startupName = startElement.getAttribute(IWorkbenchConstants.TAG_CLASS);
- } else {
- startupName = null;
- }
- // If the startup element doesn't specify a class, use the
- // plugin class
- final IPluginDescriptor pluginDescriptor =
- extension.getDeclaringPluginDescriptor();
- SafeRunnable code = new SafeRunnable() {
- public void run() throws Exception {
- String id =
- pluginDescriptor.getUniqueIdentifier()
- + IPreferenceConstants.SEPARATOR;
- if (pref.indexOf(id) < 0) {
- IStartup startup = null;
- if (startupName == null) {
- Plugin plugin = pluginDescriptor.getPlugin();
- startup = (IStartup) plugin;
- } else {
- startup =
- (IStartup) WorkbenchPlugin.createExtension(
- startElement,
- IWorkbenchConstants.TAG_CLASS);
- }
- startup.earlyStartup();
- }
- }
- public void handleException(Throwable exception) {
- WorkbenchPlugin.log("Unhandled Exception", new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, "Unhandled Exception", exception)); //$NON-NLS-1$ //$NON-NLS-2$
- }
- };
- Platform.run(code);
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IConfigurationElement[] configElements = registry
+ .getConfigurationElementsFor(PlatformUI.PLUGIN_ID,
+ IWorkbenchConstants.PL_STARTUP);
+
+ for (int i = 0; i < configElements.length; ++i) {
+ IConfigurationElement startElement = configElements[i];
+
+ // if the plugin is not in the set of disabled plugins, then
+ // execute the code to start it
+ String id = startElement.getDeclaringExtension().getNamespace();
+ if (disabledPlugins.indexOf(id) == -1)
+ Platform.run(new EarlyStartupRunnable(startElement));
}
}
};
@@ -1404,6 +1358,105 @@
}
/**
+ * A utility class used to call #earlyStartup on the proper instance for a
+ * given configuration element. The process is made complicated since
+ * attributes that were optional in 2.1 are manadatory in 3.0.
+ */
+ private static class EarlyStartupRunnable extends SafeRunnable {
+ private static final String EXTENSION_CLASS = "org.eclipse.core.internal.registry.Extension"; //$NON-NLS-1$
+ private static final String PLUGIN_DESC_CLASS = "org.eclipse.core.internal.plugins.PluginDescriptor"; //$NON-NLS-1$
+
+ private static final String GET_PLUGIN_METHOD = "getPlugin"; //$NON-NLS-1$
+ private static final String GET_DESC_METHOD = "getDeclaringPluginDescriptor"; //$NON-NLS-1$
+
+ private IConfigurationElement startElement;
+ private String pluginId;
+
+ public EarlyStartupRunnable(IConfigurationElement startElement) {
+ this.startElement = startElement;
+ this.pluginId = startElement.getDeclaringExtension().getNamespace();
+ }
+
+ public void run() throws Exception {
+ Object executableExtension = getExecutableExtension();
+
+ // make sure the extension implements IStartup
+ if (executableExtension != null
+ && executableExtension instanceof IStartup)
+ ((IStartup) executableExtension).earlyStartup();
+ else {
+ IStatus status = new Status(IStatus.ERROR, pluginId, 0,
+ "startup class must implement org.eclipse.ui.IStartup", //$NON-NLS-1$
+ null);
+ WorkbenchPlugin.log("Bad extension specification", status); //$NON-NLS-1$
+ }
+ }
+
+ public void handleException(Throwable exception) {
+ IStatus status = new Status(IStatus.ERROR, pluginId, 0,
+ "Unable to execute early startup code for an extension", //$NON-NLS-1$
+ exception);
+ WorkbenchPlugin.log("Unhandled Exception", status); //$NON-NLS-1$
+ }
+
+ /**
+ * The class attribute of the startup element was optional for pre-3.0
+ * plugins (the declaring plugin's object would silently be used
+ * instead). In 3.0 this attribute is mandatory, but 2.1 plugins should
+ * still be able to run in the compatibility mode. So, if the attribute
+ * is missing, then reflection is used to see if the compatibility
+ * bundle can be located and used to access the plugin object.
+ *
+ * @return an executable extension for this startup element or null if
+ * an extension (or plugin) could not be found
+ */
+ private Object getExecutableExtension() throws CoreException {
+ String startupClass = startElement
+ .getAttribute(IWorkbenchConstants.TAG_CLASS);
+
+ if (startupClass != null && startupClass.length() > 0)
+ return WorkbenchPlugin.createExtension(startElement,
+ IWorkbenchConstants.TAG_CLASS);
+
+ // otherwise see if the compat bundle is running
+ Bundle compatBundle = Platform
+ .getBundle(IPlatform.PI_RUNTIME_COMPATIBILITY);
+ if (compatBundle == null)
+ return null;
+
+ // use reflection to try to access the plugin object
+ IExtension extension = startElement.getDeclaringExtension();
+ try {
+ // IPluginDescriptor pluginDesc =
+ // extension.getDeclaringPluginDescriptor();
+ Class extensionClass = compatBundle.loadClass(EXTENSION_CLASS);
+ Method getDescMethod = extensionClass.getDeclaredMethod(
+ GET_DESC_METHOD, new Class[0]);
+ Object pluginDesc = getDescMethod.invoke(extension,
+ new Object[0]);
+ if (pluginDesc == null)
+ return null;
+
+ // Plugin plugin = pluginDesc.getPlugin();
+ Class pluginDescClass = compatBundle.loadClass(PLUGIN_DESC_CLASS);
+ Method getPluginMethod = pluginDescClass.getDeclaredMethod(
+ GET_PLUGIN_METHOD, new Class[0]);
+ return getPluginMethod.invoke(pluginDesc, new Object[0]);
+ } catch (ClassNotFoundException e) {
+ handleException(e);
+ } catch (IllegalAccessException e) {
+ handleException(e);
+ } catch (InvocationTargetException e) {
+ handleException(e);
+ } catch (NoSuchMethodException e) {
+ handleException(e);
+ }
+
+ return null;
+ }
+ }
+
+ /**
* Internal method for running the workbench UI. This entails processing
* and dispatching events until the workbench is closed or restarted.
*
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/StartupPreferencePage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/StartupPreferencePage.java
index 6474b94..86741d3 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/StartupPreferencePage.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/StartupPreferencePage.java
@@ -10,18 +10,26 @@
*******************************************************************************/
package org.eclipse.ui.internal.dialogs;
-import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.help.WorkbenchHelp;
-import org.eclipse.ui.internal.*;
+import org.eclipse.ui.internal.IHelpContextIds;
+import org.eclipse.ui.internal.IPreferenceConstants;
+import org.eclipse.ui.internal.Workbench;
+import org.eclipse.ui.internal.WorkbenchMessages;
+import org.osgi.framework.Constants;
public class StartupPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
private Table pluginsList;
@@ -58,17 +66,17 @@
return composite;
}
private void populatePluginsList() {
- IPluginDescriptor descriptors[] = workbench.getEarlyActivatedPlugins();
+ String descriptors[] = workbench.getEarlyActivatedPlugins();
IPreferenceStore store = workbench.getPreferenceStore();
String pref = store.getString(IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
if(pref == null)
pref = new String();
for (int i = 0; i < descriptors.length; i++) {
- IPluginDescriptor desc = descriptors[i];
+ String desc = descriptors[i];
TableItem item = new TableItem(pluginsList,SWT.NONE);
- item.setText(desc.getLabel());
+ item.setText((String) Platform.getBundle(desc).getHeaders().get(Constants.BUNDLE_NAME));
item.setData(desc);
- String id = desc.getUniqueIdentifier() + IPreferenceConstants.SEPARATOR;
+ String id = desc + IPreferenceConstants.SEPARATOR;
item.setChecked(pref.indexOf(id) < 0);
}
}
@@ -95,8 +103,7 @@
TableItem items[] = pluginsList.getItems();
for (int i = 0; i < items.length; i++) {
if(!items[i].getChecked()) {
- IPluginDescriptor descriptor = (IPluginDescriptor)items[i].getData();
- preference.append(descriptor.getUniqueIdentifier());
+ preference.append((String)items[i].getData());
preference.append(IPreferenceConstants.SEPARATOR);
}
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryManager.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryManager.java
index 33f46a0..ce70e46 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryManager.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryManager.java
@@ -122,10 +122,10 @@
IExtension ext = delta.getExtension();
// Get the name of the plugin that is adding this extension. The
// name of the plugin that adds the extension point is us.
- String pluginId = ext.getDeclaringPluginDescriptor().getUniqueIdentifier();
+ String pluginId = ext.getNamespace();
add(buildNewCacheObject(delta), pluginId);
}
-
+
public void add(Object element, String pluginId) {
if (element == null)
// Nothing to add, so just return.
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewRegistry.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewRegistry.java
index a970c89..b22de0c 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewRegistry.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewRegistry.java
@@ -92,7 +92,7 @@
dirtyViews = true;
ViewRegistryElement element = new ViewRegistryElement();
element.addViewDescriptor(desc);
- add(element, desc.getConfigurationElement().getDeclaringExtension().getDeclaringPluginDescriptor().getUniqueIdentifier());
+ add(element, desc.getConfigurationElement().getDeclaringExtension().getNamespace());
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.registry.aaRegistryCacheaa#buildNewCacheObject(org.eclipse.core.runtime.IExtensionDelta)