/*******************************************************************************
* Copyright (c) 2000, 2010 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.ui.plugin;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
/**
* 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 IDialogSettings dialogSettings = null;
// //
// /**
// * Storage for preferences.
// */
// private ScopedPreferenceStore preferenceStore;
//
// //
// // /**
// // * The registry for all graphic images; <code>null</code> if not yet
// // * initialized.
// // */
// // private ImageRegistry imageRegistry = null;
// //
// // /**
// // * The bundle listener used for kicking off refreshPluginActions().
// // *
// // * @since 3.0.1
// // */
// // private BundleListener bundleListener;
// //
// // /**
// // * 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(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() {
// //
// // // If we are in the UI Thread use that
// // if (Display.getCurrent() != null) {
// // return new ImageRegistry(Display.getCurrent());
// // }
// //
// // if (PlatformUI.isWorkbenchRunning()) {
// // return new ImageRegistry(PlatformUI.getWorkbench().getDisplay());
// // }
// //
// // // Invalid thread access if it is not the UI Thread
// // // and the workbench is not created.
// // throw new SWTError(SWT.ERROR_THREAD_INVALID_ACCESS);
// // }
// //
// // /**
// // * 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>
* <strong>NOTE:</strong> As of Eclipse 3.1 this method is no longer
* referring to the core runtime compatibility layer and so plug-ins relying
* on Plugin#initializeDefaultPreferences will have to access the
* compatibility layer themselves.
* </p>
*
* @return the preference store
*/
public IPreferenceStore getPreferenceStore() {
// // Create the preference store lazily.
// if (preferenceStore == null) {
// // preferenceStore = new ScopedPreferenceStore(new InstanceScope(),
// // getBundle().getSymbolicName());
// preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
// "blabla");
//
// }
// return preferenceStore;
return null;
}
//
// //
// // /**
// // * 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 initialize
// // *
// // * @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$
// //
// // // bug 69387: The instance area should not be created (in the call to
// // // #getStateLocation) if -data @none or -data @noDefault was used
// // IPath dataLocation = getStateLocationOrNull();
// // if (dataLocation != null) {
// // // try r/w state area in the local file system
// // String readWritePath = dataLocation.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$
// // }
// //
// // return;
// // }
// // }
// //
// // // otherwise look for bundle specific dialog settings
// // 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 started yet, or is no longer running, do
// // // nothing.
// // if (!PlatformUI.isWorkbenchRunning()) {
// // 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 {
// // IPath path = getStateLocationOrNull();
// // if (path == null) {
// // return;
// // }
// // String readWritePath = path.append(FN_DIALOG_SETTINGS).toOSString();
// // dialogSettings.save(readWritePath);
// // } catch (IOException e) {
// // // spec'ed to ignore problems
// // } catch (IllegalStateException 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);
// // final BundleContext fc = context;
// // // Should only attempt refreshPluginActions() once the bundle
// // // has been fully started. Otherwise, action delegates
// // // can be created while in the process of creating
// // // a triggering action delegate (if UI events are processed during
// // // startup).
// // // Also, if the start throws an exception, the bundle will be shut
// down.
// // // We don't want to have created any delegates if this happens.
// // // See bug 63324 for more details.
// // bundleListener = new SynchronousBundleListener() {
// // public void bundleChanged(BundleEvent event) {
// // if (event.getBundle() == getBundle()) {
// // if (event.getType() == BundleEvent.STARTED) {
// // // We're getting notified that the bundle has been
// // // started.
// // // Make sure it's still active. It may have been shut
// // // down between
// // // the time this event was queued and now.
// // if (getBundle().getState() == Bundle.ACTIVE) {
// // refreshPluginActions();
// // }
// // fc.removeBundleListener(this);
// // }
// // }
// // }
// // };
// // context.addBundleListener(bundleListener);
// // // bundleListener is removed in stop(BundleContext)
// // }
// //
// // /**
// // * The <code>AbstractUIPlugin</code> implementation of this {@link
// Plugin}
// // * 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.stop()</code> is
// // * always done. {@inheritDoc}
// // *
// // * @since 3.0
// // */
// // public void stop(BundleContext context) throws Exception {
// // try {
// // if (bundleListener != null) {
// // context.removeBundleListener(bundleListener);
// // }
// // saveDialogSettings();
// // savePreferenceStore();
// // preferenceStore = null;
// // if (imageRegistry != null)
// // imageRegistry.dispose();
// // 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. It will now query the ISharedImages registry first. 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();
}
IWorkbench workbench = PlatformUI.isWorkbenchRunning() ? PlatformUI
.getWorkbench() : null;
ImageDescriptor imageDescriptor = workbench == null ? null : workbench
.getSharedImages().getImageDescriptor(imageFilePath);
if (imageDescriptor != null)
return imageDescriptor; // found in the shared images
// 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) {
// try {
// fullPathString = new URL(imageFilePath);
// } catch (MalformedURLException e) {
return null;
}
//
// }
// //
// // return ImageDescriptor.createFromURL(fullPathString);
// // }
// //
// // /**
// // * FOR INTERNAL WORKBENCH USE ONLY.
// // *
// // * Returns the path to a location in the file system that can be used
// to
// // * persist/restore state between workbench invocations. If the location
// // did
// // * not exist prior to this call it will be created. Returns
// // * <code>null</code> if no such location is available.
// // *
// // * @return path to a location in the file system where this plug-in can
// // * persist data between sessions, or <code>null</code> if no such
// // * location is available.
// // * @since 3.1
// // */
// // private IPath getStateLocationOrNull() {
// // try {
// // return getStateLocation();
// // } catch (IllegalStateException e) {
// // // This occurs if -data=@none is explicitly specified, so ignore
// // // this silently.
// // // Is this OK? See bug 85071.
// // return null;
// // }
// // }
}