KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > plugin > AbstractUIPlugin


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.plugin;
12
13 import java.io.BufferedReader JavaDoc;
14 import java.io.File JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.io.InputStream JavaDoc;
17 import java.io.InputStreamReader JavaDoc;
18 import java.net.MalformedURLException JavaDoc;
19 import java.net.URL JavaDoc;
20
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.core.runtime.IPluginDescriptor;
24 import org.eclipse.core.runtime.Platform;
25 import org.eclipse.core.runtime.Plugin;
26 import org.eclipse.core.runtime.preferences.InstanceScope;
27 import org.eclipse.jface.dialogs.DialogSettings;
28 import org.eclipse.jface.dialogs.IDialogSettings;
29 import org.eclipse.jface.preference.IPreferenceStore;
30 import org.eclipse.jface.resource.ImageDescriptor;
31 import org.eclipse.jface.resource.ImageRegistry;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.SWTError;
34 import org.eclipse.swt.widgets.Display;
35 import org.eclipse.ui.IWorkbench;
36 import org.eclipse.ui.PlatformUI;
37 import org.eclipse.ui.internal.WWinPluginAction;
38 import org.eclipse.ui.internal.util.BundleUtility;
39 import org.eclipse.ui.preferences.ScopedPreferenceStore;
40 import org.osgi.framework.Bundle;
41 import org.osgi.framework.BundleContext;
42 import org.osgi.framework.BundleEvent;
43 import org.osgi.framework.BundleListener;
44
45 /**
46  * Abstract base class for plug-ins that integrate with the Eclipse platform UI.
47  * <p>
48  * Subclasses obtain the following capabilities:
49  * </p>
50  * <p>
51  * Preferences
52  * <ul>
53  * <li> The platform core runtime contains general support for plug-in
54  * preferences (<code>org.eclipse.core.runtime.Preferences</code>).
55  * This class provides appropriate conversion to the older JFace preference
56  * API (<code>org.eclipse.jface.preference.IPreferenceStore</code>).</li>
57  * <li> The method <code>getPreferenceStore</code> returns the JFace preference
58  * store (cf. <code>Plugin.getPluginPreferences</code> which returns
59  * a core runtime preferences object.</li>
60  * <li> Subclasses may reimplement <code>initializeDefaultPreferences</code>
61  * to set up any default values for preferences using JFace API. In this
62  * case, <code>initializeDefaultPluginPreferences</code> should not be
63  * overridden.</li>
64  * <li> Subclasses may reimplement
65  * <code>initializeDefaultPluginPreferences</code> to set up any default
66  * values for preferences using core runtime API. In this
67  * case, <code>initializeDefaultPreferences</code> should not be
68  * overridden.</li>
69  * <li> Preferences are also saved automatically on plug-in shutdown.
70  * However, saving preferences immediately after changing them is
71  * strongly recommended, since that ensures that preference settings
72  * are not lost even in the event of a platform crash.</li>
73  * </ul>
74  * Dialogs
75  * <ul>
76  * <li> The dialog store is read the first time <code>getDialogSettings</code>
77  * is called.</li>
78  * <li> The dialog store allows the plug-in to "record" important choices made
79  * by the user in a wizard or dialog, so that the next time the
80  * wizard/dialog is used the widgets can be defaulted to better values. A
81  * wizard could also use it to record the last 5 values a user entered into
82  * an editable combo - to show "recent values". </li>
83  * <li> The dialog store is found in the file whose name is given by the
84  * constant <code>FN_DIALOG_STORE</code>. A dialog store file is first
85  * looked for in the plug-in's read/write state area; if not found there,
86  * the plug-in's install directory is checked.
87  * This allows a plug-in to ship with a read-only copy of a dialog store
88  * file containing initial values for certain settings.</li>
89  * <li> Plug-in code can call <code>saveDialogSettings</code> to cause settings to
90  * be saved in the plug-in's read/write state area. A plug-in may opt to do
91  * this each time a wizard or dialog is closed to ensure the latest
92  * information is always safe on disk. </li>
93  * <li> Dialog settings are also saved automatically on plug-in shutdown.</li>
94  * </ul>
95  * Images
96  * <ul>
97  * <li> A typical UI plug-in will have some images that are used very frequently
98  * and so need to be cached and shared. The plug-in's image registry
99  * provides a central place for a plug-in to store its common images.
100  * Images managed by the registry are created lazily as needed, and will be
101  * automatically disposed of when the plug-in shuts down. Note that the
102  * number of registry images should be kept to a minimum since many OSs
103  * have severe limits on the number of images that can be in memory at once.
104  * </ul>
105  * <p>
106  * For easy access to your plug-in object, use the singleton pattern. Declare a
107  * static variable in your plug-in class for the singleton. Store the first
108  * (and only) instance of the plug-in class in the singleton when it is created.
109  * Then access the singleton when needed through a static <code>getDefault</code>
110  * method.
111  * </p>
112  * <p>
113  * See the description on {@link Plugin}.
114  * </p>
115  */

116 public abstract class AbstractUIPlugin extends Plugin {
117
118     /**
119      * The name of the dialog settings file (value
120      * <code>"dialog_settings.xml"</code>).
121      */

122     private static final String JavaDoc FN_DIALOG_SETTINGS = "dialog_settings.xml"; //$NON-NLS-1$
123

124     /**
125      * Storage for dialog and wizard data; <code>null</code> if not yet
126      * initialized.
127      */

128     private DialogSettings dialogSettings = null;
129
130     /**
131      * Storage for preferences.
132      */

133     private ScopedPreferenceStore preferenceStore;
134
135     /**
136      * The registry for all graphic images; <code>null</code> if not yet
137      * initialized.
138      */

139     private ImageRegistry imageRegistry = null;
140
141     /**
142      * The bundle listener used for kicking off refreshPluginActions().
143      *
144      * @since 3.0.1
145      */

146     private BundleListener bundleListener;
147     
148     /**
149      * Creates an abstract UI plug-in runtime object for the given plug-in
150      * descriptor.
151      * <p>
152      * Note that instances of plug-in runtime classes are automatically created
153      * by the platform in the course of plug-in activation.
154      * <p>
155      *
156      * @param descriptor the plug-in descriptor
157      * @see Plugin#Plugin(org.eclipse.core.runtime.IPluginDescriptor descriptor)
158      * @deprecated
159      * In Eclipse 3.0 this constructor has been replaced by
160      * {@link #AbstractUIPlugin()}. Implementations of
161      * <code>MyPlugin(IPluginDescriptor descriptor)</code> should be changed to
162      * <code>MyPlugin()</code> and call <code>super()</code> instead of
163      * <code>super(descriptor)</code>.
164      * The <code>MyPlugin(IPluginDescriptor descriptor)</code> constructor is
165      * called only for plug-ins which explicitly require the
166      * org.eclipse.core.runtime.compatibility plug-in (or, as in this case,
167      * subclasses which might).
168      */

169     public AbstractUIPlugin(IPluginDescriptor descriptor) {
170         super(descriptor);
171     }
172
173     /**
174      * Creates an abstract UI plug-in runtime object.
175      * <p>
176      * Plug-in runtime classes are <code>BundleActivators</code> and so must
177      * have an default constructor. This method is called by the runtime when
178      * the associated bundle is being activated.
179      * <p>
180      * For more details, see <code>Plugin</code>'s default constructor.
181      *
182      * @see Plugin#Plugin()
183      * @since 3.0
184      */

185     public AbstractUIPlugin() {
186         super();
187     }
188
189     /**
190      * Returns a new image registry for this plugin-in. The registry will be
191      * used to manage images which are frequently used by the plugin-in.
192      * <p>
193      * The default implementation of this method creates an empty registry.
194      * Subclasses may override this method if needed.
195      * </p>
196      *
197      * @return ImageRegistry the resulting registry.
198      * @see #getImageRegistry
199      */

200     protected ImageRegistry createImageRegistry() {
201         
202         //If we are in the UI Thread use that
203
if(Display.getCurrent() != null) {
204             return new ImageRegistry(Display.getCurrent());
205         }
206         
207         if(PlatformUI.isWorkbenchRunning()) {
208             return new ImageRegistry(PlatformUI.getWorkbench().getDisplay());
209         }
210         
211         //Invalid thread access if it is not the UI Thread
212
//and the workbench is not created.
213
throw new SWTError(SWT.ERROR_THREAD_INVALID_ACCESS);
214     }
215     
216     /**
217      * Returns the dialog settings for this UI plug-in.
218      * The dialog settings is used to hold persistent state data for the various
219      * wizards and dialogs of this plug-in in the context of a workbench.
220      * <p>
221      * If an error occurs reading the dialog store, an empty one is quietly created
222      * and returned.
223      * </p>
224      * <p>
225      * Subclasses may override this method but are not expected to.
226      * </p>
227      *
228      * @return the dialog settings
229      */

230     public IDialogSettings getDialogSettings() {
231         if (dialogSettings == null) {
232             loadDialogSettings();
233         }
234         return dialogSettings;
235     }
236
237     /**
238      * Returns the image registry for this UI plug-in.
239      * <p>
240      * The image registry contains the images used by this plug-in that are very
241      * frequently used and so need to be globally shared within the plug-in. Since
242      * many OSs have a severe limit on the number of images that can be in memory at
243      * any given time, a plug-in should only keep a small number of images in their
244      * registry.
245      * <p>
246      * Subclasses should reimplement <code>initializeImageRegistry</code> if they have
247      * custom graphic images to load.
248      * </p>
249      * <p>
250      * Subclasses may override this method but are not expected to.
251      * </p>
252      *
253      * @return the image registry
254      */

255     public ImageRegistry getImageRegistry() {
256         if (imageRegistry == null) {
257             imageRegistry = createImageRegistry();
258             initializeImageRegistry(imageRegistry);
259         }
260         return imageRegistry;
261     }
262
263     /**
264      * Returns the preference store for this UI plug-in.
265      * This preference store is used to hold persistent settings for this plug-in in
266      * the context of a workbench. Some of these settings will be user controlled,
267      * whereas others may be internal setting that are never exposed to the user.
268      * <p>
269      * If an error occurs reading the preference store, an empty preference store is
270      * quietly created, initialized with defaults, and returned.
271      * </p>
272      * <p>
273      * <strong>NOTE:</strong> As of Eclipse 3.1 this method is
274      * no longer referring to the core runtime compatibility layer and so
275      * plug-ins relying on Plugin#initializeDefaultPreferences
276      * will have to access the compatibility layer themselves.
277      * </p>
278      *
279      * @return the preference store
280      */

281     public IPreferenceStore getPreferenceStore() {
282         // Create the preference store lazily.
283
if (preferenceStore == null) {
284             preferenceStore = new ScopedPreferenceStore(new InstanceScope(),getBundle().getSymbolicName());
285
286         }
287         return preferenceStore;
288     }
289
290     /**
291      * Returns the Platform UI workbench.
292      * <p>
293      * This method exists as a convenience for plugin implementors. The
294      * workbench can also be accessed by invoking <code>PlatformUI.getWorkbench()</code>.
295      * </p>
296      * @return IWorkbench the workbench for this plug-in
297      */

298     public IWorkbench getWorkbench() {
299         return PlatformUI.getWorkbench();
300     }
301
302     /**
303      * Initializes a preference store with default preference values
304      * for this plug-in.
305      * <p>
306      * This method is called after the preference store is initially loaded
307      * (default values are never stored in preference stores).
308      * </p>
309      * <p>
310      * The default implementation of this method does nothing.
311      * Subclasses should reimplement this method if the plug-in has any preferences.
312      * </p>
313      * <p>
314      * A subclass may reimplement this method to set default values for the
315      * preference store using JFace API. This is the older way of initializing
316      * default values. If this method is reimplemented, do not override
317      * <code>initializeDefaultPluginPreferences()</code>.
318      * </p>
319      *
320      * @param store the preference store to fill
321      *
322      * @deprecated this is only called if the runtime compatibility layer is
323      * present. See {@link #initializeDefaultPluginPreferences}.
324      */

325     protected void initializeDefaultPreferences(IPreferenceStore store) {
326         // spec'ed to do nothing
327
}
328
329     /**
330      * The <code>AbstractUIPlugin</code> implementation of this
331      * <code>Plugin</code> method forwards to
332      * <code>initializeDefaultPreferences(IPreferenceStore)</code>.
333      * <p>
334      * A subclass may reimplement this method to set default values for the core
335      * runtime preference store in the standard way. This is the recommended way
336      * to do this. The older
337      * <code>initializeDefaultPreferences(IPreferenceStore)</code> method
338      * serves a similar purpose. If this method is reimplemented, do not send
339      * super, and do not override
340      * <code>initializeDefaultPreferences(IPreferenceStore)</code>.
341      * </p>
342      *
343      * @deprecated this is only called if the runtime compatibility layer is
344      * present. See the deprecated comment in
345      * {@link Plugin#initializeDefaultPluginPreferences}.
346      *
347      * @see #initializeDefaultPreferences
348      * @since 2.0
349      */

350     protected void initializeDefaultPluginPreferences() {
351         // N.B. by the time this method is called, the plug-in has a
352
// core runtime preference store (no default values)
353

354         // call loadPreferenceStore (only) for backwards compatibility with Eclipse 1.0
355
loadPreferenceStore();
356         // call initializeDefaultPreferences (only) for backwards compatibility
357
// with Eclipse 1.0
358
initializeDefaultPreferences(getPreferenceStore());
359     }
360
361     /**
362      * Initializes an image registry with images which are frequently used by the
363      * plugin.
364      * <p>
365      * The image registry contains the images used by this plug-in that are very
366      * frequently used and so need to be globally shared within the plug-in. Since
367      * many OSs have a severe limit on the number of images that can be in memory
368      * at any given time, each plug-in should only keep a small number of images in
369      * its registry.
370      * </p><p>
371      * Implementors should create a JFace image descriptor for each frequently used
372      * image. The descriptors describe how to create/find the image should it be needed.
373      * The image described by the descriptor is not actually allocated until someone
374      * retrieves it.
375      * </p><p>
376      * Subclasses may override this method to fill the image registry.
377      * </p>
378      * @param reg the registry to initalize
379      *
380      * @see #getImageRegistry
381      */

382     protected void initializeImageRegistry(ImageRegistry reg) {
383         // spec'ed to do nothing
384
}
385
386     /**
387      * Loads the dialog settings for this plug-in.
388      * The default implementation first looks for a standard named file in the
389      * plug-in's read/write state area; if no such file exists, the plug-in's
390      * install directory is checked to see if one was installed with some default
391      * settings; if no file is found in either place, a new empty dialog settings
392      * is created. If a problem occurs, an empty settings is silently used.
393      * <p>
394      * This framework method may be overridden, although this is typically
395      * unnecessary.
396      * </p>
397      */

398     protected void loadDialogSettings() {
399         dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
400

401         // bug 69387: The instance area should not be created (in the call to
402
// #getStateLocation) if -data @none or -data @noDefault was used
403
IPath dataLocation = getStateLocationOrNull();
404         if (dataLocation != null) {
405             // try r/w state area in the local file system
406
String JavaDoc readWritePath = dataLocation.append(FN_DIALOG_SETTINGS)
407                     .toOSString();
408             File JavaDoc settingsFile = new File JavaDoc(readWritePath);
409             if (settingsFile.exists()) {
410                 try {
411                     dialogSettings.load(readWritePath);
412                 } catch (IOException JavaDoc e) {
413                     // load failed so ensure we have an empty settings
414
dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
415
}
416                 
417                 return;
418             }
419         }
420
421         // otherwise look for bundle specific dialog settings
422
URL JavaDoc dsURL = BundleUtility.find(getBundle(), FN_DIALOG_SETTINGS);
423         if (dsURL == null) {
424             return;
425         }
426
427         InputStream JavaDoc is = null;
428         try {
429             is = dsURL.openStream();
430             BufferedReader JavaDoc reader = new BufferedReader JavaDoc(
431                     new InputStreamReader JavaDoc(is, "utf-8")); //$NON-NLS-1$
432
dialogSettings.load(reader);
433         } catch (IOException JavaDoc e) {
434             // load failed so ensure we have an empty settings
435
dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
436
} finally {
437             try {
438                 if (is != null) {
439                     is.close();
440                 }
441             } catch (IOException JavaDoc e) {
442                 // do nothing
443
}
444         }
445     }
446
447     /**
448      * Loads the preference store for this plug-in.
449      * The default implementation looks for a standard named file in the
450      * plug-in's read/write state area. If no file is found or a problem
451      * occurs, a new empty preference store is silently created.
452      * <p>
453      * This framework method may be overridden, although this is typically
454      * unnecessary.
455      * </p>
456      *
457      * @deprecated As of Eclipse 2.0, a basic preference store exists for all
458      * plug-ins. This method now exists only for backwards compatibility.
459      * It is called as the plug-in's preference store is being initialized.
460      * The plug-ins preferences are loaded from the file regardless of what
461      * this method does.
462      */

463     protected void loadPreferenceStore() {
464         // do nothing by default
465
}
466
467     /**
468      * Refreshes the actions for the plugin.
469      * This method is called from <code>startup</code>.
470      * <p>
471      * This framework method may be overridden, although this is typically
472      * unnecessary.
473      * </p>
474      */

475     protected void refreshPluginActions() {
476         // If the workbench is not started yet, or is no longer running, do nothing.
477
if (!PlatformUI.isWorkbenchRunning()) {
478             return;
479         }
480
481         // startup() is not guaranteed to be called in the UI thread,
482
// but refreshPluginActions must run in the UI thread,
483
// so use asyncExec. See bug 6623 for more details.
484
Display.getDefault().asyncExec(new Runnable JavaDoc() {
485             public void run() {
486                 WWinPluginAction.refreshActionList();
487             }
488         });
489     }
490
491     /**
492      * Saves this plug-in's dialog settings.
493      * Any problems which arise are silently ignored.
494      */

495     protected void saveDialogSettings() {
496         if (dialogSettings == null) {
497             return;
498         }
499
500         try {
501             IPath path = getStateLocationOrNull();
502             if(path == null) {
503                 return;
504             }
505             String JavaDoc readWritePath = path
506                     .append(FN_DIALOG_SETTINGS).toOSString();
507             dialogSettings.save(readWritePath);
508         } catch (IOException JavaDoc e) {
509             // spec'ed to ignore problems
510
} catch (IllegalStateException JavaDoc e) {
511             // spec'ed to ignore problems
512
}
513     }
514
515     /**
516      * Saves this plug-in's preference store.
517      * Any problems which arise are silently ignored.
518      *
519      * @see Plugin#savePluginPreferences()
520      * @deprecated As of Eclipse 2.0, preferences exist for all plug-ins. The
521      * equivalent of this method is <code>Plugin.savePluginPreferences</code>.
522      * This method now calls <code>savePluginPreferences</code>, and exists only for
523      * backwards compatibility.
524      */

525     protected void savePreferenceStore() {
526         savePluginPreferences();
527     }
528
529     /**
530      * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
531      * method does nothing. Subclasses may extend this method, but must send
532      * super first.
533      * <p>
534      * WARNING: Plug-ins may not be started in the UI thread.
535      * The <code>startup()</code> method should not assume that its code runs in
536      * the UI thread, otherwise SWT thread exceptions may occur on startup.'
537      * @deprecated
538      * In Eclipse 3.0, <code>startup</code> has been replaced by {@link Plugin#start(BundleContext context)}.
539      * Implementations of <code>startup</code> should be changed to extend
540      * <code>start(BundleContext context)</code> and call <code>super.start(context)</code>
541      * instead of <code>super.startup()</code>. Like <code>super.startup()</code>,
542      * <code>super.stop(context)</code> must be called as the very first thing.
543      * The <code>startup</code> method is called only for plug-ins which explicitly require the
544      * org.eclipse.core.runtime.compatibility plug-in; in contrast,
545      * the <code>start</code> method is always called.
546      */

547     public void startup() throws CoreException {
548         // this method no longer does anything
549
// the code that used to be here in 2.1 has moved to start(BundleContext)
550
super.startup();
551     }
552
553     /**
554      * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
555      * method does nothing. Subclasses may extend this method, but must send
556      * super first.
557      * @deprecated
558      * In Eclipse 3.0, <code>shutdown</code> has been replaced by {@link Plugin#stop(BundleContext context)}.
559      * Implementations of <code>shutdown</code> should be changed to extend
560      * <code>stop(BundleContext context)</code> and call <code>super.stop(context)</code>
561      * instead of <code>super.shutdown()</code>. Unlike <code>super.shutdown()</code>,
562      * <code>super.stop(context)</code> must be called as the very <b>last</b> thing rather
563      * than as the very first thing. The <code>shutdown</code> method is called
564      * only for plug-ins which explicitly require the
565      * org.eclipse.core.runtime.compatibility plug-in;
566      * in contrast, the <code>stop</code> method is always called.
567      */

568     public void shutdown() throws CoreException {
569         // this method no longer does anything interesting
570
// the code that used to be here in 2.1 has moved to stop(BundleContext),
571
// which is called regardless of whether the plug-in being instantiated
572
// requires org.eclipse.core.runtime.compatibility
573
super.shutdown();
574     }
575
576     /**
577      * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
578      * method refreshes the plug-in actions. Subclasses may extend this method,
579      * but must send super <b>first</b>.
580      * {@inheritDoc}
581      *
582      * @since 3.0
583      */

584     public void start(BundleContext context) throws Exception JavaDoc {
585         super.start(context);
586         final BundleContext fc = context;
587         // Should only attempt refreshPluginActions() once the bundle
588
// has been fully started. Otherwise, action delegates
589
// can be created while in the process of creating
590
// a triggering action delegate (if UI events are processed during startup).
591
// Also, if the start throws an exception, the bundle will be shut down.
592
// We don't want to have created any delegates if this happens.
593
// See bug 63324 for more details.
594
bundleListener = new BundleListener() {
595             public void bundleChanged(BundleEvent event) {
596                 if (event.getBundle() == getBundle()) {
597                     if (event.getType() == BundleEvent.STARTED) {
598                         // We're getting notified that the bundle has been started.
599
// Make sure it's still active. It may have been shut down between
600
// the time this event was queued and now.
601
if (getBundle().getState() == Bundle.ACTIVE) {
602                             refreshPluginActions();
603                         }
604                         fc.removeBundleListener(this);
605                     }
606                 }
607             }
608         };
609         context.addBundleListener(bundleListener);
610         // bundleListener is removed in stop(BundleContext)
611
}
612
613     /**
614      * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
615      * method saves this plug-in's preference and dialog stores and shuts down
616      * its image registry (if they are in use). Subclasses may extend this
617      * method, but must send super <b>last</b>. A try-finally statement should
618      * be used where necessary to ensure that <code>super.shutdown()</code> is
619      * always done.
620      * {@inheritDoc}
621      *
622      * @since 3.0
623      */

624     public void stop(BundleContext context) throws Exception JavaDoc {
625         try {
626             if (bundleListener != null) {
627                 context.removeBundleListener(bundleListener);
628             }
629             saveDialogSettings();
630             savePreferenceStore();
631             preferenceStore = null;
632             imageRegistry = null;
633         } finally {
634             super.stop(context);
635         }
636     }
637
638     /**
639      * Creates and returns a new image descriptor for an image file located
640      * within the specified plug-in.
641      * <p>
642      * This is a convenience method that simply locates the image file in
643      * within the plug-in (no image registries are involved). The path is
644      * relative to the root of the plug-in, and takes into account files
645      * coming from plug-in fragments. The path may include $arg$ elements.
646      * However, the path must not have a leading "." or path separator.
647      * Clients should use a path like "icons/mysample.gif" rather than
648      * "./icons/mysample.gif" or "/icons/mysample.gif".
649      * </p>
650      *
651      * @param pluginId the id of the plug-in containing the image file;
652      * <code>null</code> is returned if the plug-in does not exist
653      * @param imageFilePath the relative path of the image file, relative to the
654      * root of the plug-in; the path must be legal
655      * @return an image descriptor, or <code>null</code> if no image
656      * could be found
657      * @since 3.0
658      */

659     public static ImageDescriptor imageDescriptorFromPlugin(String JavaDoc pluginId,
660             String JavaDoc imageFilePath) {
661         if (pluginId == null || imageFilePath == null) {
662             throw new IllegalArgumentException JavaDoc();
663         }
664
665         // if the bundle is not ready then there is no image
666
Bundle bundle = Platform.getBundle(pluginId);
667         if (!BundleUtility.isReady(bundle)) {
668             return null;
669         }
670
671         // look for the image (this will check both the plugin and fragment folders
672
URL JavaDoc fullPathString = BundleUtility.find(bundle, imageFilePath);
673         if (fullPathString == null) {
674             try {
675                 fullPathString = new URL JavaDoc(imageFilePath);
676             } catch (MalformedURLException JavaDoc e) {
677                 return null;
678             }
679         }
680
681         if (fullPathString == null) {
682             return null;
683         }
684         return ImageDescriptor.createFromURL(fullPathString);
685     }
686     
687     /**
688      * FOR INTERNAL WORKBENCH USE ONLY.
689      *
690      * Returns the path to a location in the file system that can be used
691      * to persist/restore state between workbench invocations.
692      * If the location did not exist prior to this call it will be created.
693      * Returns <code>null</code> if no such location is available.
694      *
695      * @return path to a location in the file system where this plug-in can
696      * persist data between sessions, or <code>null</code> if no such
697      * location is available.
698      * @since 3.1
699      */

700     private IPath getStateLocationOrNull() {
701         try {
702             return getStateLocation();
703         } catch (IllegalStateException JavaDoc e) {
704             // This occurs if -data=@none is explicitly specified, so ignore this silently.
705
// Is this OK? See bug 85071.
706
return null;
707         }
708     }
709     
710 }
711
Popular Tags