| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.plugin; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.net.URL; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Plugin; |
| import org.eclipse.core.runtime.Preferences; |
| import org.eclipse.jface.dialogs.DialogSettings; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.preference.IPersistentPreferenceStore; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.resource.ImageRegistry; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.ListenerList; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.util.SafeRunnable; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.WWinPluginAction; |
| import org.eclipse.ui.internal.Workbench; |
| import org.eclipse.ui.internal.util.BundleUtility; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| |
| /** |
| * Abstract base class for plug-ins that integrate with the Eclipse platform UI. |
| * <p> |
| * Subclasses obtain the following capabilities: |
| * </p> |
| * <p> |
| * Preferences |
| * <ul> |
| * <li> The platform core runtime contains general support for plug-in |
| * preferences (<code>org.eclipse.core.runtime.Preferences</code>). |
| * This class provides appropriate conversion to the older JFace preference |
| * API (<code>org.eclipse.jface.preference.IPreferenceStore</code>).</li> |
| * <li> The method <code>getPreferenceStore</code> returns the JFace preference |
| * store (cf. <code>Plugin.getPluginPreferences</code> which returns |
| * a core runtime preferences object.</li> |
| * <li> Subclasses may reimplement <code>initializeDefaultPreferences</code> |
| * to set up any default values for preferences using JFace API. In this |
| * case, <code>initializeDefaultPluginPreferences</code> should not be |
| * overridden.</li> |
| * <li> Subclasses may reimplement |
| * <code>initializeDefaultPluginPreferences</code> to set up any default |
| * values for preferences using core runtime API. In this |
| * case, <code>initializeDefaultPreferences</code> should not be |
| * overridden.</li> |
| * <li> Preferences are also saved automatically on plug-in shutdown. |
| * However, saving preferences immediately after changing them is |
| * strongly recommended, since that ensures that preference settings |
| * are not lost even in the event of a platform crash.</li> |
| * </ul> |
| * Dialogs |
| * <ul> |
| * <li> The dialog store is read the first time <code>getDialogSettings</code> |
| * is called.</li> |
| * <li> The dialog store allows the plug-in to "record" important choices made |
| * by the user in a wizard or dialog, so that the next time the |
| * wizard/dialog is used the widgets can be defaulted to better values. A |
| * wizard could also use it to record the last 5 values a user entered into |
| * an editable combo - to show "recent values". </li> |
| * <li> The dialog store is found in the file whose name is given by the |
| * constant <code>FN_DIALOG_STORE</code>. A dialog store file is first |
| * looked for in the plug-in's read/write state area; if not found there, |
| * the plug-in's install directory is checked. |
| * This allows a plug-in to ship with a read-only copy of a dialog store |
| * file containing initial values for certain settings.</li> |
| * <li> Plug-in code can call <code>saveDialogSettings</code> to cause settings to |
| * be saved in the plug-in's read/write state area. A plug-in may opt to do |
| * this each time a wizard or dialog is closed to ensure the latest |
| * information is always safe on disk. </li> |
| * <li> Dialog settings are also saved automatically on plug-in shutdown.</li> |
| * </ul> |
| * Images |
| * <ul> |
| * <li> A typical UI plug-in will have some images that are used very frequently |
| * and so need to be cached and shared. The plug-in's image registry |
| * provides a central place for a plug-in to store its common images. |
| * Images managed by the registry are created lazily as needed, and will be |
| * automatically disposed of when the plug-in shuts down. Note that the |
| * number of registry images should be kept to a minimum since many OSs |
| * have severe limits on the number of images that can be in memory at once. |
| * </ul> |
| * <p> |
| * For easy access to your plug-in object, use the singleton pattern. Declare a |
| * static variable in your plug-in class for the singleton. Store the first |
| * (and only) instance of the plug-in class in the singleton when it is created. |
| * Then access the singleton when needed through a static <code>getDefault</code> |
| * method. |
| * </p> |
| * <p> |
| * See the description on {@link Plugin}. |
| * </p> |
| */ |
| public abstract class AbstractUIPlugin extends Plugin { |
| |
| /** |
| * The name of the dialog settings file (value |
| * <code>"dialog_settings.xml"</code>). |
| */ |
| private static final String FN_DIALOG_SETTINGS = "dialog_settings.xml"; //$NON-NLS-1$ |
| |
| /** |
| * Storage for dialog and wizard data; <code>null</code> if not yet |
| * initialized. |
| */ |
| private DialogSettings dialogSettings = null; |
| |
| /** |
| * Storage for preferences. |
| */ |
| private CompatibilityPreferenceStore preferenceStore; |
| |
| /** |
| * The registry for all graphic images; <code>null</code> if not yet |
| * initialized. |
| */ |
| private ImageRegistry imageRegistry = null; |
| |
| /** |
| * Internal implementation of a JFace preference store atop a core runtime |
| * preference store. |
| * |
| * @since 2.0 |
| */ |
| private class CompatibilityPreferenceStore implements IPersistentPreferenceStore { |
| |
| /** |
| * Flag to indicate that the listener has been added. |
| */ |
| private boolean listenerAdded = false; |
| |
| /** |
| * The underlying core runtime preference store; <code>null</code> if it |
| * has not been initialized yet. |
| */ |
| private Preferences prefs = null; |
| |
| /** |
| * Identity list of old listeners (element type: |
| * <code>org.eclipse.jface.util.IPropertyChangeListener</code>). |
| */ |
| private ListenerList listeners = new ListenerList(); |
| |
| /** |
| * Indicates whether property change events should be suppressed |
| * (used in implementation of <code>putValue</code>). Initially |
| * and usually <code>false</code>. |
| * |
| * @see IPreferenceStore#putValue |
| */ |
| private boolean silentRunning = false; |
| |
| /** |
| * Creates a new instance for the this plug-in. |
| */ |
| public CompatibilityPreferenceStore() { |
| // Important: do not call initialize() here |
| // due to heinous reentrancy problems. |
| } |
| |
| /** |
| * Initializes this preference store. |
| */ |
| void initialize() { |
| // ensure initialization is only done once. |
| if (this.prefs != null) { |
| return; |
| } |
| // here's where we first ask for the plug-in's core runtime |
| // preferences; |
| // note that this causes this method to be reentered |
| this.prefs = getPluginPreferences(); |
| // avoid adding the listener a second time when reentered |
| if (!this.listenerAdded) { |
| // register listener that funnels everything to firePropertyChangeEvent |
| this |
| .prefs |
| .addPropertyChangeListener( |
| new Preferences |
| .IPropertyChangeListener() { |
| public void propertyChange( |
| Preferences.PropertyChangeEvent event) { |
| if (!silentRunning) { |
| firePropertyChangeEvent( |
| event.getProperty(), |
| event.getOldValue(), |
| event.getNewValue()); |
| } |
| } |
| }); |
| this.listenerAdded = true; |
| } |
| } |
| |
| /** |
| * Returns the underlying preference store. |
| * |
| * @return the underlying preference store |
| */ |
| private Preferences getPrefs() { |
| if (prefs == null) { |
| // although we try to ensure initialization is done eagerly, |
| // this cannot be guaranteed, so ensure it is done here |
| initialize(); |
| } |
| return prefs; |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void addPropertyChangeListener(final IPropertyChangeListener listener) { |
| listeners.add(listener); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void removePropertyChangeListener(IPropertyChangeListener listener) { |
| listeners.remove(listener); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void firePropertyChangeEvent( |
| String name, |
| Object oldValue, |
| Object newValue) { |
| |
| // efficiently handle case of 0 listeners |
| if (listeners.isEmpty()) { |
| // no one interested |
| return; |
| } |
| |
| // important: create intermediate array to protect against listeners |
| // being added/removed during the notification |
| final Object[] list = listeners.getListeners(); |
| final PropertyChangeEvent event = |
| new PropertyChangeEvent(this, name, oldValue, newValue); |
| Platform.run(new SafeRunnable(JFaceResources.getString("PreferenceStore.changeError")) { //$NON-NLS-1$ |
| public void run() { |
| for (int i = 0; i < list.length; i++) { |
| ((IPropertyChangeListener) list[i]).propertyChange( |
| event); |
| } |
| } |
| }); |
| |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public boolean contains(String name) { |
| return getPrefs().contains(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public boolean getBoolean(String name) { |
| return getPrefs().getBoolean(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public boolean getDefaultBoolean(String name) { |
| return getPrefs().getDefaultBoolean(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public double getDefaultDouble(String name) { |
| return getPrefs().getDefaultDouble(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public float getDefaultFloat(String name) { |
| return getPrefs().getDefaultFloat(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public int getDefaultInt(String name) { |
| return getPrefs().getDefaultInt(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public long getDefaultLong(String name) { |
| return getPrefs().getDefaultLong(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public String getDefaultString(String name) { |
| return getPrefs().getDefaultString(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public double getDouble(String name) { |
| return getPrefs().getDouble(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public float getFloat(String name) { |
| return getPrefs().getFloat(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public int getInt(String name) { |
| return getPrefs().getInt(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public long getLong(String name) { |
| return getPrefs().getLong(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public String getString(String name) { |
| return getPrefs().getString(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public boolean isDefault(String name) { |
| return getPrefs().isDefault(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public boolean needsSaving() { |
| return getPrefs().needsSaving(); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void putValue(String name, String value) { |
| try { |
| // temporarily suppress event notification while setting value |
| silentRunning = true; |
| getPrefs().setValue(name, value); |
| } finally { |
| silentRunning = false; |
| } |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setDefault(String name, double value) { |
| getPrefs().setDefault(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setDefault(String name, float value) { |
| getPrefs().setDefault(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setDefault(String name, int value) { |
| getPrefs().setDefault(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setDefault(String name, long value) { |
| getPrefs().setDefault(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setDefault(String name, String value) { |
| getPrefs().setDefault(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setDefault(String name, boolean value) { |
| getPrefs().setDefault(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setToDefault(String name) { |
| getPrefs().setToDefault(name); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setValue(String name, double value) { |
| getPrefs().setValue(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setValue(String name, float value) { |
| getPrefs().setValue(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setValue(String name, int value) { |
| getPrefs().setValue(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setValue(String name, long value) { |
| getPrefs().setValue(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setValue(String name, String value) { |
| getPrefs().setValue(name, value); |
| } |
| |
| /* (non-javadoc) |
| * Method declared on IPreferenceStore |
| */ |
| public void setValue(String name, boolean value) { |
| getPrefs().setValue(name, value); |
| } |
| /** |
| * @see org.eclipse.jface.preference.IPersistentPreferenceStore#save() |
| */ |
| public void save() throws IOException { |
| AbstractUIPlugin.this.savePreferenceStore(); |
| } |
| |
| } |
| |
| /** |
| * Creates an abstract UI plug-in runtime object for the given plug-in |
| * descriptor. |
| * <p> |
| * Note that instances of plug-in runtime classes are automatically created |
| * by the platform in the course of plug-in activation. |
| * <p> |
| * |
| * @param descriptor the plug-in descriptor |
| * @see Plugin#Plugin(org.eclipse.core.runtime.IPluginDescriptor descriptor) |
| * @deprecated |
| * In Eclipse 3.0 this constructor has been replaced by |
| * {@link #AbstractUIPlugin()}. Implementations of |
| * <code>MyPlugin(IPluginDescriptor descriptor)</code> should be changed to |
| * <code>MyPlugin()</code> and call <code>super()</code> instead of |
| * <code>super(descriptor)</code>. |
| * The <code>MyPlugin(IPluginDescriptor descriptor)</code> constructor is |
| * called only for plug-ins which explicitly require the |
| * org.eclipse.core.runtime.compatibility plug-in (or, as in this case, |
| * subclasses which might). |
| */ |
| public AbstractUIPlugin(org.eclipse.core.runtime.IPluginDescriptor descriptor) { |
| super(descriptor); |
| } |
| |
| /** |
| * Creates an abstract UI plug-in runtime object. |
| * <p> |
| * Plug-in runtime classes are <code>BundleActivators</code> and so must |
| * have an default constructor. This method is called by the runtime when |
| * the associated bundle is being activated. |
| * <p> |
| * For more details, see <code>Plugin</code>'s default constructor. |
| * |
| * @see Plugin#Plugin() |
| * @since 3.0 |
| */ |
| public AbstractUIPlugin() { |
| super(); |
| } |
| |
| /** |
| * Returns a new image registry for this plugin-in. The registry will be |
| * used to manage images which are frequently used by the plugin-in. |
| * <p> |
| * The default implementation of this method creates an empty registry. |
| * Subclasses may override this method if needed. |
| * </p> |
| * |
| * @return ImageRegistry the resulting registry. |
| * @see #getImageRegistry |
| */ |
| protected ImageRegistry createImageRegistry() { |
| return new ImageRegistry(); |
| } |
| /** |
| * Returns the dialog settings for this UI plug-in. |
| * The dialog settings is used to hold persistent state data for the various |
| * wizards and dialogs of this plug-in in the context of a workbench. |
| * <p> |
| * If an error occurs reading the dialog store, an empty one is quietly created |
| * and returned. |
| * </p> |
| * <p> |
| * Subclasses may override this method but are not expected to. |
| * </p> |
| * |
| * @return the dialog settings |
| */ |
| public IDialogSettings getDialogSettings() { |
| if (dialogSettings == null) |
| loadDialogSettings(); |
| return dialogSettings; |
| } |
| /** |
| * Returns the image registry for this UI plug-in. |
| * <p> |
| * The image registry contains the images used by this plug-in that are very |
| * frequently used and so need to be globally shared within the plug-in. Since |
| * many OSs have a severe limit on the number of images that can be in memory at |
| * any given time, a plug-in should only keep a small number of images in their |
| * registry. |
| * <p> |
| * Subclasses should reimplement <code>initializeImageRegistry</code> if they have |
| * custom graphic images to load. |
| * </p> |
| * <p> |
| * Subclasses may override this method but are not expected to. |
| * </p> |
| * |
| * @return the image registry |
| */ |
| public ImageRegistry getImageRegistry() { |
| if (imageRegistry == null) { |
| imageRegistry = createImageRegistry(); |
| initializeImageRegistry(imageRegistry); |
| } |
| return imageRegistry; |
| } |
| /** |
| * Returns the preference store for this UI plug-in. |
| * This preference store is used to hold persistent settings for this plug-in in |
| * the context of a workbench. Some of these settings will be user controlled, |
| * whereas others may be internal setting that are never exposed to the user. |
| * <p> |
| * If an error occurs reading the preference store, an empty preference store is |
| * quietly created, initialized with defaults, and returned. |
| * </p> |
| * <p> |
| * Subclasses should reimplement <code>initializeDefaultPreferences</code> if |
| * they have custom graphic images to load. |
| * </p> |
| * |
| * @return the preference store |
| */ |
| public IPreferenceStore getPreferenceStore() { |
| // Create the preference store lazily. |
| if (preferenceStore == null) { |
| // must assign field before calling initialize(), since |
| // this method can be reentered during initialization |
| preferenceStore = new CompatibilityPreferenceStore(); |
| // force initialization |
| preferenceStore.initialize(); |
| } |
| return preferenceStore; |
| } |
| |
| /** |
| * Returns the Platform UI workbench. |
| * <p> |
| * This method exists as a convenience for plugin implementors. The |
| * workbench can also be accessed by invoking <code>PlatformUI.getWorkbench()</code>. |
| * </p> |
| * @return IWorkbench the workbench for this plug-in |
| */ |
| public IWorkbench getWorkbench() { |
| return PlatformUI.getWorkbench(); |
| } |
| |
| /** |
| * Initializes a preference store with default preference values |
| * for this plug-in. |
| * <p> |
| * This method is called after the preference store is initially loaded |
| * (default values are never stored in preference stores). |
| * </p> |
| * <p> |
| * The default implementation of this method does nothing. |
| * Subclasses should reimplement this method if the plug-in has any preferences. |
| * </p> |
| * <p> |
| * A subclass may reimplement this method to set default values for the |
| * preference store using JFace API. This is the older way of initializing |
| * default values. If this method is reimplemented, do not override |
| * <code>initializeDefaultPluginPreferences()</code>. |
| * </p> |
| * |
| * @param store the preference store to fill |
| * |
| * @deprecated this is only called if the runtime compatibility layer is |
| * present. See {@link #initializeDefaultPluginPreferences}. |
| */ |
| protected void initializeDefaultPreferences(IPreferenceStore store) { |
| // spec'ed to do nothing |
| } |
| |
| /** |
| * The <code>AbstractUIPlugin</code> implementation of this |
| * <code>Plugin</code> method forwards to |
| * <code>initializeDefaultPreferences(IPreferenceStore)</code>. |
| * <p> |
| * A subclass may reimplement this method to set default values for the core |
| * runtime preference store in the standard way. This is the recommended way |
| * to do this. The older |
| * <code>initializeDefaultPreferences(IPreferenceStore)</code> method |
| * serves a similar purpose. If this method is reimplemented, do not send |
| * super, and do not override |
| * <code>initializeDefaultPreferences(IPreferenceStore)</code>. |
| * </p> |
| * |
| * @deprecated this is only called if the runtime compatibility layer is |
| * present. See the deprecated comment in |
| * {@link Plugin#initializeDefaultPluginPreferences}. |
| * |
| * @see #initializeDefaultPreferences |
| * @since 2.0 |
| */ |
| protected void initializeDefaultPluginPreferences() { |
| // N.B. by the time this method is called, the plug-in has a |
| // core runtime preference store (no default values) |
| |
| // call loadPreferenceStore (only) for backwards compatibility with Eclipse 1.0 |
| loadPreferenceStore(); |
| // call initializeDefaultPreferences (only) for backwards compatibility |
| // with Eclipse 1.0 |
| initializeDefaultPreferences(getPreferenceStore()); |
| } |
| |
| /** |
| * Initializes an image registry with images which are frequently used by the |
| * plugin. |
| * <p> |
| * The image registry contains the images used by this plug-in that are very |
| * frequently used and so need to be globally shared within the plug-in. Since |
| * many OSs have a severe limit on the number of images that can be in memory |
| * at any given time, each plug-in should only keep a small number of images in |
| * its registry. |
| * </p><p> |
| * Implementors should create a JFace image descriptor for each frequently used |
| * image. The descriptors describe how to create/find the image should it be needed. |
| * The image described by the descriptor is not actually allocated until someone |
| * retrieves it. |
| * </p><p> |
| * Subclasses may override this method to fill the image registry. |
| * </p> |
| * @param reg the registry to initalize |
| * |
| * @see #getImageRegistry |
| */ |
| protected void initializeImageRegistry(ImageRegistry reg) { |
| // spec'ed to do nothing |
| } |
| |
| /** |
| * Loads the dialog settings for this plug-in. |
| * The default implementation first looks for a standard named file in the |
| * plug-in's read/write state area; if no such file exists, the plug-in's |
| * install directory is checked to see if one was installed with some default |
| * settings; if no file is found in either place, a new empty dialog settings |
| * is created. If a problem occurs, an empty settings is silently used. |
| * <p> |
| * This framework method may be overridden, although this is typically |
| * unnecessary. |
| * </p> |
| */ |
| protected void loadDialogSettings() { |
| dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$ |
| |
| // try r/w state area in the local file system |
| String readWritePath = |
| getStateLocation().append(FN_DIALOG_SETTINGS).toOSString(); |
| File settingsFile = new File(readWritePath); |
| if (settingsFile.exists()) { |
| try { |
| dialogSettings.load(readWritePath); |
| } catch (IOException e) { |
| // load failed so ensure we have an empty settings |
| dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$ |
| } |
| } else { |
| URL dsURL = BundleUtility.find(getBundle(), FN_DIALOG_SETTINGS); |
| if(dsURL == null) |
| return; |
| |
| InputStream is = null; |
| try { |
| is = dsURL.openStream(); |
| BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8")); //$NON-NLS-1$ |
| dialogSettings.load(reader); |
| } catch (IOException e) { |
| // load failed so ensure we have an empty settings |
| dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$ |
| } finally { |
| try { |
| if (is != null) |
| is.close(); |
| } catch (IOException e) { |
| // do nothing |
| } |
| } |
| } |
| } |
| |
| /** |
| * Loads the preference store for this plug-in. |
| * The default implementation looks for a standard named file in the |
| * plug-in's read/write state area. If no file is found or a problem |
| * occurs, a new empty preference store is silently created. |
| * <p> |
| * This framework method may be overridden, although this is typically |
| * unnecessary. |
| * </p> |
| * |
| * @deprecated As of Eclipse 2.0, a basic preference store exists for all |
| * plug-ins. This method now exists only for backwards compatibility. |
| * It is called as the plug-in's preference store is being initialized. |
| * The plug-ins preferences are loaded from the file regardless of what |
| * this method does. |
| */ |
| protected void loadPreferenceStore() { |
| // do nothing by default |
| } |
| |
| /** |
| * Refreshes the actions for the plugin. |
| * This method is called from <code>startup</code>. |
| * <p> |
| * This framework method may be overridden, although this is typically |
| * unnecessary. |
| * </p> |
| */ |
| protected void refreshPluginActions() { |
| // If the workbench is not created yet, do nothing. |
| if (Workbench.getInstance() == null) |
| return; |
| |
| // startup() is not guaranteed to be called in the UI thread, |
| // but refreshPluginActions must run in the UI thread, |
| // so use asyncExec. See bug 6623 for more details. |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| WWinPluginAction.refreshActionList(); |
| } |
| }); |
| } |
| |
| /** |
| * Saves this plug-in's dialog settings. |
| * Any problems which arise are silently ignored. |
| */ |
| protected void saveDialogSettings() { |
| if (dialogSettings == null) { |
| return; |
| } |
| |
| try { |
| String readWritePath = |
| getStateLocation().append(FN_DIALOG_SETTINGS).toOSString(); |
| dialogSettings.save(readWritePath); |
| } catch (IOException e) { |
| // spec'ed to ignore problems |
| } |
| } |
| |
| /** |
| * Saves this plug-in's preference store. |
| * Any problems which arise are silently ignored. |
| * |
| * @see Plugin#savePluginPreferences() |
| * @deprecated As of Eclipse 2.0, preferences exist for all plug-ins. The |
| * equivalent of this method is <code>Plugin.savePluginPreferences</code>. |
| * This method now calls <code>savePluginPreferences</code>, and exists only for |
| * backwards compatibility. |
| */ |
| protected void savePreferenceStore() { |
| savePluginPreferences(); |
| } |
| |
| /** |
| * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code> |
| * method does nothing. Subclasses may extend this method, but must send |
| * super first. |
| * <p> |
| * WARNING: Plug-ins may not be started in the UI thread. |
| * The <code>startup()</code> method should not assume that its code runs in |
| * the UI thread, otherwise SWT thread exceptions may occur on startup.' |
| * @deprecated |
| * In Eclipse 3.0, <code>startup</code> has been replaced by {@link Plugin#start(BundleContext context)}. |
| * Implementations of <code>startup</code> should be changed to extend |
| * <code>start(BundleContext context)</code> and call <code>super.start(context)</code> |
| * instead of <code>super.startup()</code>. Like <code>super.startup()</code>, |
| * <code>super.stop(context)</code> must be called as the very first thing. |
| * The <code>startup</code> method is called only for plug-ins which explicitly require the |
| * org.eclipse.core.runtime.compatibility plug-in; in contrast, |
| * the <code>start</code> method is always called. |
| */ |
| public void startup() throws CoreException { |
| // this method no longer does anything |
| // the code that used to be here in 2.1 has moved to start(BundleContext) |
| super.startup(); |
| } |
| |
| /** |
| * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code> |
| * method does nothing. Subclasses may extend this method, but must send |
| * super first. |
| * @deprecated |
| * In Eclipse 3.0, <code>shutdown</code> has been replaced by {@link Plugin#stop(BundleContext context)}. |
| * Implementations of <code>shutdown</code> should be changed to extend |
| * <code>stop(BundleContext context)</code> and call <code>super.stop(context)</code> |
| * instead of <code>super.shutdown()</code>. Unlike <code>super.shutdown()</code>, |
| * <code>super.stop(context)</code> must be called as the very <b>last</b> thing rather |
| * than as the very first thing. The <code>shutdown</code> method is called |
| * only for plug-ins which explicitly require the |
| * org.eclipse.core.runtime.compatibility plug-in; |
| * in contrast, the <code>stop</code> method is always called. |
| */ |
| public void shutdown() throws CoreException { |
| // this method no longer does anything interesting |
| // the code that used to be here in 2.1 has moved to stop(BundleContext), |
| // which is called regardless of whether the plug-in being instantiated |
| // requires org.eclipse.core.runtime.compatibility |
| super.shutdown(); |
| } |
| |
| /** |
| * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code> |
| * method refreshes the plug-in actions. Subclasses may extend this method, |
| * but must send super <b>first</b>. |
| * {@inheritDoc} |
| * |
| * @since 3.0 |
| */ |
| public void start(BundleContext context) throws Exception { |
| super.start(context); |
| refreshPluginActions(); |
| } |
| |
| /** |
| * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code> |
| * method saves this plug-in's preference and dialog stores and shuts down |
| * its image registry (if they are in use). Subclasses may extend this |
| * method, but must send super <b>last</b>. A try-finally statement should |
| * be used where necessary to ensure that <code>super.shutdown()</code> is |
| * always done. |
| * {@inheritDoc} |
| * |
| * @since 3.0 |
| */ |
| public void stop(BundleContext context) throws Exception { |
| try { |
| saveDialogSettings(); |
| savePreferenceStore(); |
| preferenceStore = null; |
| imageRegistry = null; |
| } |
| finally { |
| super.stop(context); |
| } |
| } |
| |
| /** |
| * Creates and returns a new image descriptor for an image file located |
| * within the specified plug-in. |
| * <p> |
| * This is a convenience method that simply locates the image file in |
| * within the plug-in (no image registries are involved). The path is |
| * relative to the root of the plug-in, and takes into account files |
| * coming from plug-in fragments. The path may include $arg$ elements. |
| * However, the path must not have a leading "." or path separator. |
| * Clients should use a path like "icons/mysample.gif" rather than |
| * "./icons/mysample.gif" or "/icons/mysample.gif". |
| * </p> |
| * |
| * @param pluginId the id of the plug-in containing the image file; |
| * <code>null</code> is returned if the plug-in does not exist |
| * @param imageFilePath the relative path of the image file, relative to the |
| * root of the plug-in; the path must be legal |
| * @return an image descriptor, or <code>null</code> if no image |
| * could be found |
| * @since 3.0 |
| */ |
| public static ImageDescriptor imageDescriptorFromPlugin(String pluginId, |
| String imageFilePath) { |
| if (pluginId == null || imageFilePath == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // if the bundle is not ready then there is no image |
| Bundle bundle = Platform.getBundle(pluginId); |
| if (!BundleUtility.isReady(bundle)) |
| return null; |
| |
| // look for the image (this will check both the plugin and fragment folders |
| URL fullPathString = BundleUtility.find(bundle, imageFilePath); |
| if (fullPathString == null) |
| return null; |
| |
| return ImageDescriptor.createFromURL(fullPathString); |
| } |
| } |