KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > runtime > Plugin


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.core.runtime;
12
13 import java.io.*;
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.lang.reflect.Method JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.util.Map JavaDoc;
18 import org.eclipse.core.internal.runtime.*;
19 import org.eclipse.osgi.util.NLS;
20 import org.osgi.framework.*;
21
22 /**
23  * The abstract superclass of all plug-in runtime class
24  * implementations. A plug-in subclasses this class and overrides
25  * the appropriate life cycle methods in order to react to the life cycle
26  * requests automatically issued by the platform.
27  * For compatibility reasons, the methods called for those life cycle events
28  * vary, please see the "Constructors and life cycle methods" section below.
29  *
30  * <p>
31  * Conceptually, the plug-in runtime class represents the entire plug-in
32  * rather than an implementation of any one particular extension the
33  * plug-in declares. A plug-in is not required to explicitly
34  * specify a plug-in runtime class; if none is specified, the plug-in
35  * will be given a default plug-in runtime object that ignores all life
36  * cycle requests (it still provides access to the corresponding
37  * plug-in descriptor).
38  * </p>
39  * <p>
40  * In the case of more complex plug-ins, it may be desirable
41  * to define a concrete subclass of <code>Plugin</code>.
42  * However, just subclassing <code>Plugin</code> is not
43  * sufficient. The name of the class must be explicitly configured
44  * in the plug-in's manifest (<code>plugin.xml</code>) file
45  * with the class attribute of the <code>&ltplugin&gt</code> element markup.
46  * </p>
47  * <p>
48  * Instances of plug-in runtime classes are automatically created
49  * by the platform in the course of plug-in activation. For compatibility reasons,
50  * the constructor used to create plug-in instances varies, please see the "Constructors
51  * and life cycle methods" section below.
52  * </p><p>
53  * The concept of bundles underlies plug-ins. However it is safe to regard plug-ins
54  * and bundles as synonyms.
55  * </p>
56  * <p>
57  * <b>Clients must never explicitly instantiate a plug-in runtime class</b>.
58  * </p>
59  * <p>
60  * A typical implementation pattern for plug-in runtime classes is to
61  * provide a static convenience method to gain access to a plug-in's
62  * runtime object. This way, code in other parts of the plug-in
63  * implementation without direct access to the plug-in runtime object
64  * can easily obtain a reference to it, and thence to any plug-in-wide
65  * resources recorded on it. An example for Eclipse 3.0 follows:
66  * <pre>
67  * package myplugin;
68  * public class MyPluginClass extends Plugin {
69  * private static MyPluginClass instance;
70  *
71  * public static MyPluginClass getInstance() { return instance; }
72  *
73  * public void MyPluginClass() {
74  * super();
75  * instance = this;
76  * // ... other initialization
77  * }
78  * // ... other methods
79  * }
80  * </pre>
81  * In the above example, a call to <code>MyPluginClass.getInstance()</code>
82  * will always return an initialized instance of <code>MyPluginClass</code>.
83  * </p>
84  * <p>
85  * <b>Constructors and life cycle methods</b>
86  * </p><p>
87  * If the plugin.xml of a plug-in indicates &lt;?eclipse version="3.0"?&gt; and its prerequisite
88  * list includes <code>org.eclipse.core.runtime</code>, the default constructor of the plug-in
89  * class is used and {@link #start(BundleContext)} and {@link #stop(BundleContext)} are
90  * called as life cycle methods.
91  * </p><p>
92  * If the plugin.xml of a plug-in indicates &lt;?eclipse version="3.0"?&gt; and its prerequisite list includes
93  * <code>org.eclipse.core.runtime.compatibility</code>, the {@link #Plugin(IPluginDescriptor)}
94  * constructor is used and {@link #startup()} and {@link #shutdown()} are called as life cycle methods.
95  * Note that in this situation, start() is called before startup() and stop() is called
96  * after shutdown.
97  * </p><p>
98  * If the plugin.xml of your plug-in does <b>not</b> indicate &lt;?eclipse version="3.0"?&gt; it is therefore
99  * not a 3.0 plug-in. Consequently the {@link #Plugin(IPluginDescriptor)} is used and {@link #startup()} and
100  * {@link #shutdown()} are called as life cycle methods.
101  * </p><p>
102  * Since Eclipse 3.0 APIs of the Plugin class can be called only when the Plugin is in an active state, i.e.,
103  * after it was started up and before it is shutdown. In particular, it means that Plugin APIs should not
104  * be called from overrides of {@link #Plugin()}.
105  * </p>
106  */

107 public abstract class Plugin implements BundleActivator {
108
109     /**
110      * String constant used for the default scope name for legacy
111      * Eclipse plug-in preferences. The value of <code>PLUGIN_PREFERENCE_SCOPE</code> should
112      * match the InstanceScope's variable SCOPE from org.eclipse.core.runtime.preferences.
113      * The value is copied in this file to prevent unnecessary activation of
114      * the Preferences plugin on startup.
115      *
116      * @since 3.0
117      */

118     public static final String JavaDoc PLUGIN_PREFERENCE_SCOPE = "instance"; //$NON-NLS-1$
119

120     /**
121      * The bundle associated this plug-in
122      */

123     private Bundle bundle;
124
125     /**
126      * The debug flag for this plug-in. The flag is false by default.
127      * It can be set to true either by the plug-in itself or in the platform
128      * debug options.
129      */

130     private boolean debug = false;
131
132     /** The plug-in descriptor.
133      * @deprecated Marked as deprecated to suppress deprecation warnings.
134      */

135     private IPluginDescriptor descriptor;
136
137     /**
138      * The base name (value <code>"preferences"</code>) for the file which is used for
139      * overriding default preference values.
140      *
141      * @since 2.0
142      * @see #PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME
143      */

144     public static final String JavaDoc PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME = "preferences"; //$NON-NLS-1$
145

146     /**
147      * The name of the file (value <code>"preferences.ini"</code>) in a
148      * plug-in's (read-only) directory that, when present, contains values that
149      * override the normal default values for this plug-in's preferences.
150      * <p>
151      * The format of the file is as per <code>java.io.Properties</code> where
152      * the keys are property names and values are strings.
153      * </p>
154      *
155      * @since 2.0
156      */

157     public static final String JavaDoc PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME = PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME + ".ini"; //$NON-NLS-1$
158

159     /**
160      * The preference object for this plug-in; initially <code>null</code>
161      * meaning not yet created and initialized.
162      *
163      * @since 2.0
164      */

165     private Preferences preferences = null;
166
167     /**
168      * Creates a new plug-in runtime object. This method is called by the platform
169      * if this class is used as a <code>BundleActivator</code>. This method is not
170      * needed/used if this plug-in requires the org.eclipse.core.runtime.compatibility plug-in.
171      * Subclasses of <code>Plugin</code>
172      * must call this method first in their constructors.
173      *
174      * The resultant instance is not managed by the runtime and
175      * so should be remembered by the client (typically using a Singleton pattern).
176      * <b>Clients must never explicitly call this method.</b>
177      * </p>
178      * <p>
179      * Note: The class loader typically has monitors acquired during invocation of this method. It is
180      * strongly recommended that this method avoid synchronized blocks or other thread locking mechanisms,
181      * as this would lead to deadlock vulnerability.
182      * </p>
183      *
184      * @since 3.0
185      */

186     public Plugin() {
187         super();
188     }
189
190     /**
191      * Creates a new plug-in runtime object for the given plug-in descriptor.
192      * <p>
193      * Instances of plug-in runtime classes are automatically created
194      * by the platform in the course of plug-in activation.
195      * <b>Clients must never explicitly call this method.</b>
196      * </p>
197      * <p>
198      * Note: The class loader typically has monitors acquired during invocation of this method. It is
199      * strongly recommended that this method avoid synchronized blocks or other thread locking mechanisms,
200      * as this would lead to deadlock vulnerability.
201      * </p>
202      *
203      * @param descriptor the plug-in descriptor
204      * @see #getDescriptor()
205      * @deprecated
206      * In Eclipse 3.0 this constructor has been replaced by {@link #Plugin()}.
207      * Implementations of <code>MyPlugin(IPluginDescriptor descriptor)</code> should be changed to
208      * <code>MyPlugin()</code> and call <code>super()</code> instead of <code>super(descriptor)</code>.
209      * The <code>MyPlugin(IPluginDescriptor descriptor)</code> constructor is called only for plug-ins
210      * which explicitly require the org.eclipse.core.runtime.compatibility plug-in.
211      */

212     public Plugin(IPluginDescriptor descriptor) {
213         Assert.isNotNull(descriptor);
214         Assert.isTrue(!CompatibilityHelper.hasPluginObject(descriptor), NLS.bind(Messages.plugin_deactivatedLoad, this.getClass().getName(), descriptor.getUniqueIdentifier() + " is not activated")); //$NON-NLS-1$
215
this.descriptor = descriptor;
216
217         // on plugin start, find and start the corresponding bundle.
218
bundle = InternalPlatform.getDefault().getBundle(descriptor.getUniqueIdentifier());
219         try {
220             InternalPlatform.start(bundle);
221         } catch (BundleException e) {
222             String JavaDoc message = NLS.bind(Messages.plugin_startupProblems, descriptor.getUniqueIdentifier());
223             IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, message, e);
224             InternalPlatform.getDefault().log(status);
225         }
226     }
227
228     /**
229      * Returns a URL for the given path. Returns <code>null</code> if the URL
230      * could not be computed or created.
231      *
232      * @param path path relative to plug-in installation location
233      * @return a URL for the given path or <code>null</code>
234      * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)}
235      */

236     public final URL JavaDoc find(IPath path) {
237         return FileLocator.find(bundle, path, null);
238     }
239
240     /**
241      * Returns a URL for the given path. Returns <code>null</code> if the URL
242      * could not be computed or created.
243      *
244      * @param path file path relative to plug-in installation location
245      * @param override map of override substitution arguments to be used for
246      * any $arg$ path elements. The map keys correspond to the substitution
247      * arguments (eg. "$nl$" or "$os$"). The resulting
248      * values must be of type java.lang.String. If the map is <code>null</code>,
249      * or does not contain the required substitution argument, the default
250      * is used.
251      * @return a URL for the given path or <code>null</code>
252      * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)}
253      */

254     public final URL JavaDoc find(IPath path, Map JavaDoc override) {
255         return FileLocator.find(bundle, path, override);
256     }
257
258     /**
259      * Returns the plug-in descriptor for this plug-in runtime object.
260      *
261      * @return the plug-in descriptor for this plug-in runtime object
262      * @deprecated
263      * <code>IPluginDescriptor</code> was refactored in Eclipse 3.0.
264      * The <code>getDescriptor()</code> method may only be called by plug-ins
265      * which explicitly require the org.eclipse.core.runtime.compatibility plug-in.
266      * See the comments on {@link IPluginDescriptor} and its methods for details.
267      */

268     public final IPluginDescriptor getDescriptor() {
269         if (descriptor != null)
270             return descriptor;
271
272         return initializeDescriptor(bundle.getSymbolicName());
273     }
274
275     /**
276      * Returns the log for this plug-in. If no such log exists, one is created.
277      *
278      * @return the log for this plug-in
279      * XXX change this into a LogMgr service that would keep track of the map. See if it can be a service factory.
280      */

281     public final ILog getLog() {
282         return InternalPlatform.getDefault().getLog(bundle);
283     }
284
285     /**
286      * Returns the location in the local file system of the
287      * plug-in state area for this plug-in.
288      * If the plug-in state area did not exist prior to this call,
289      * it is created.
290      * <p>
291      * The plug-in state area is a file directory within the
292      * platform's metadata area where a plug-in is free to create files.
293      * The content and structure of this area is defined by the plug-in,
294      * and the particular plug-in is solely responsible for any files
295      * it puts there. It is recommended for plug-in preference settings and
296      * other configuration parameters.
297      * </p>
298      * @throws IllegalStateException, when the system is running with no data area (-data @none),
299      * or when a data area has not been set yet.
300      * @return a local file system path
301      * XXX Investigate the usage of a service factory (see also platform.getStateLocation)
302      */

303     public final IPath getStateLocation() throws IllegalStateException JavaDoc {
304         return InternalPlatform.getDefault().getStateLocation(bundle, true);
305     }
306
307     /**
308      * Returns the preference store for this plug-in.
309      * <p>
310      * Note that if an error occurs reading the preference store from disk, an empty
311      * preference store is quietly created, initialized with defaults, and returned.
312      * </p>
313      * <p>
314      * Calling this method may cause the preference store to be created and
315      * initialized. Subclasses which reimplement the
316      * <code>initializeDefaultPluginPreferences</code> method have this opportunity
317      * to initialize preference default values, just prior to processing override
318      * default values imposed externally to this plug-in (specified for the product,
319      * or at platform start up).
320      * </p>
321      * <p>
322      * After settings in the preference store are changed (for example, with
323      * <code>Preferences.setValue</code> or <code>setToDefault</code>),
324      * <code>savePluginPreferences</code> should be called to store the changed
325      * values back to disk. Otherwise the changes will be lost on plug-in
326      * shutdown.
327      * </p>
328      *
329      * @return the preference store
330      * @see #savePluginPreferences()
331      * @see Preferences#setValue(String, String)
332      * @see Preferences#setToDefault(String)
333      * @since 2.0
334      * XXX deprecate since this does not leverage the config, project scopes, etc...
335      */

336     public final Preferences getPluginPreferences() {
337         if (preferences != null) {
338             if (InternalPlatform.DEBUG_PLUGIN_PREFERENCES)
339                 InternalPlatform.message("Plugin preferences already loaded for: " + bundle.getSymbolicName()); //$NON-NLS-1$
340
return preferences;
341         }
342
343         if (InternalPlatform.DEBUG_PLUGIN_PREFERENCES)
344             InternalPlatform.message("Loading preferences for plugin: " + bundle.getSymbolicName()); //$NON-NLS-1$
345

346         // Performance: isolate PreferenceForwarder into an inner class so that it mere presence
347
// won't force the PreferenceForwarder class to be loaded (which triggers Preferences plugin
348
// activation).
349
final Bundle bundleCopy = bundle;
350         final Preferences[] preferencesCopy = new Preferences[1];
351         Runnable JavaDoc innerCall = new Runnable JavaDoc() {
352             public void run() {
353                 preferencesCopy[0] = new org.eclipse.core.internal.preferences.legacy.PreferenceForwarder(this, bundleCopy.getSymbolicName());
354             }
355         };
356         innerCall.run();
357         preferences = preferencesCopy[0];
358         return preferences;
359     }
360
361     /**
362      * Saves preferences settings for this plug-in. Does nothing if the preference
363      * store does not need saving.
364      * <p>
365      * Plug-in preferences are <b>not</b> saved automatically on plug-in shutdown.
366      * </p>
367      *
368      * @see Preferences#store(OutputStream, String)
369      * @see Preferences#needsSaving()
370      * @since 2.0
371      * XXX deprecate call flush on the node for this bundle on the instance scope
372      */

373     public final void savePluginPreferences() {
374         // populate the "preferences" instvar. We still might
375
// need to save them because someone else might have
376
// made changes via the OSGi APIs.
377
getPluginPreferences();
378
379         // Performance: isolate PreferenceForwarder and BackingStoreException into
380
// an inner class to avoid class loading (and then activation of the Preferences plugin)
381
// as the Plugin class is loaded.
382
final Preferences preferencesCopy = preferences;
383         Runnable JavaDoc innerCall = new Runnable JavaDoc() {
384             public void run() {
385                 try {
386                     ((org.eclipse.core.internal.preferences.legacy.PreferenceForwarder) preferencesCopy).flush();
387                 } catch (org.osgi.service.prefs.BackingStoreException e) {
388                     IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, Messages.preferences_saveProblems, e);
389                     InternalPlatform.getDefault().log(status);
390                 }
391             }
392         };
393         innerCall.run();
394     }
395
396     /**
397      * Initializes the default preferences settings for this plug-in.
398      * <p>
399      * This method is called sometime after the preference store for this
400      * plug-in is created. Default values are never stored in preference
401      * stores; they must be filled in each time. This method provides the
402      * opportunity to initialize the default values.
403      * </p>
404      * <p>
405      * The default implementation of this method does nothing. A subclass that needs
406      * to set default values for its preferences must reimplement this method.
407      * Default values set at a later point will override any default override
408      * settings supplied from outside the plug-in (product configuration or
409      * platform start up).
410      * </p>
411      * @since 2.0
412      * @deprecated
413      * This method has been refactored in the new preference mechanism
414      * to handle the case where the runtime compatibility layer does not exist. The
415      * contents of this method should be moved to the method named
416      * <code>initializeDefaultPreferences</code> in a separate subclass of
417      * {@link org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer}.
418      * This class should be contributed via the
419      * <code>org.eclipse.core.runtime.preferences</code> extension point.
420      * <pre>
421      * &lt;extension point=&quo;org.eclipse.core.runtime.preferences&quo;&gt;
422      * &lt;initializer class=&quo;com.example.MyPreferenceInitializer&quo;/&gt;
423      * &lt;/extension&gt;
424      * ...
425      * package com.example;
426      * public class MyPreferenceInitializer extends AbstractPreferenceInitializer {
427      * public MyPreferenceInitializer() {
428      * super();
429      * }
430      * public void initializeDefaultPreferences() {
431      * Preferences node = new DefaultScope().getNode("my.plugin.id");
432      * node.put(key, value);
433      * }
434      * }
435      * </pre>
436      */

437     protected void initializeDefaultPluginPreferences() {
438         // default implementation of this method - spec'd to do nothing
439
}
440
441     /**
442      * Internal method. This method is a hook for
443      * initialization of default preference values.
444      * It should not be called by clients.
445      *
446      * @since 3.0
447      */

448     public final void internalInitializeDefaultPluginPreferences() {
449         initializeDefaultPluginPreferences();
450     }
451
452     /**
453      * Returns whether this plug-in is in debug mode.
454      * By default plug-ins are not in debug mode. A plug-in can put itself
455      * into debug mode or the user can set an execution option to do so.
456      * <p>
457      * Note that the plug-in's debug flag is initialized when the
458      * plug-in is started. The result of calling this method before the plug-in
459      * has started is unspecified.
460      * </p>
461      *
462      * @return whether this plug-in is in debug mode
463      * XXX deprecate use the service and cache as needed
464      */

465     public boolean isDebugging() {
466         return debug;
467     }
468
469     /**
470      * Returns an input stream for the specified file. The file path
471      * must be specified relative this the plug-in's installation location.
472      *
473      * @param file path relative to plug-in installation location
474      * @return an input stream
475      * @exception IOException if the given path cannot be found in this plug-in
476      *
477      * @see #openStream(IPath,boolean)
478      * @deprecated use {@link FileLocator#openStream(Bundle, IPath, boolean)}
479      */

480     public final InputStream openStream(IPath file) throws IOException {
481         return FileLocator.openStream(bundle, file, false);
482     }
483
484     /**
485      * Returns an input stream for the specified file. The file path
486      * must be specified relative to this plug-in's installation location.
487      * Optionally, the path specified may contain $arg$ path elements that can
488      * be used as substitution arguments. If this option is used then the $arg$
489      * path elements are processed in the same way as {@link #find(IPath, Map)}.
490      * <p>
491      * The caller must close the returned stream when done.
492      * </p>
493      *
494      * @param file path relative to plug-in installation location
495      * @param substituteArgs <code>true</code> to process substitution arguments,
496      * and <code>false</code> for the file exactly as specified without processing any
497      * substitution arguments.
498      * @return an input stream
499      * @exception IOException if the given path cannot be found in this plug-in
500      * @deprecated use {@link FileLocator#openStream(Bundle, IPath, boolean)}
501      */

502     public final InputStream openStream(IPath file, boolean substituteArgs) throws IOException {
503         return FileLocator.openStream(bundle, file, substituteArgs);
504     }
505
506     /**
507      * Sets whether this plug-in is in debug mode.
508      * By default plug-ins are not in debug mode. A plug-in can put itself
509      * into debug mode or the user can set a debug option to do so.
510      * <p>
511      * Note that the plug-in's debug flag is initialized when the
512      * plug-in is started. The result of calling this method before the plug-in
513      * has started is unspecified.
514      * </p>
515      *
516      * @param value whether or not this plug-in is in debug mode
517      * XXX deprecate use the service and cache as needed
518      */

519     public void setDebugging(boolean value) {
520         debug = value;
521     }
522
523     /**
524      * Shuts down this plug-in and discards all plug-in state.
525      * <p>
526      * This method should be re-implemented in subclasses that need to do something
527      * when the plug-in is shut down. Implementors should call the inherited method
528      * to ensure that any system requirements can be met.
529      * </p>
530      * <p>
531      * Plug-in shutdown code should be robust. In particular, this method
532      * should always make an effort to shut down the plug-in. Furthermore,
533      * the code should not assume that the plug-in was started successfully,
534      * as this method will be invoked in the event of a failure during startup.
535      * </p>
536      * <p>
537      * Note 1: If a plug-in has been started, this method will be automatically
538      * invoked by the platform when the platform is shut down.
539      * </p>
540      * <p>
541      * Note 2: This method is intended to perform simple termination
542      * of the plug-in environment. The platform may terminate invocations
543      * that do not complete in a timely fashion.
544      * </p>
545      * <b>Clients must never explicitly call this method.</b>
546      * <p>
547      *
548      * @exception CoreException if this method fails to shut down
549      * this plug-in
550      * @deprecated
551      * In Eclipse 3.0 this method has been replaced by {@link Plugin#stop(BundleContext context)}.
552      * Implementations of <code>shutdown()</code> should be changed to override
553      * <code>stop(BundleContext context)</code> and call <code>super.stop(context)</code>
554      * instead of <code>super.shutdown()</code>.
555      * The <code>shutdown()</code> method is called only for plug-ins which explicitly require the
556      * org.eclipse.core.runtime.compatibility plug-in.
557      */

558     public void shutdown() throws CoreException {
559         if (CompatibilityHelper.initializeCompatibility() == null)
560             return;
561         Throwable JavaDoc exception = null;
562         Method JavaDoc m;
563         try {
564             m = descriptor.getClass().getMethod("doPluginDeactivation", new Class JavaDoc[0]); //$NON-NLS-1$
565
m.invoke(descriptor, null);
566         } catch (SecurityException JavaDoc e) {
567             exception = e;
568         } catch (NoSuchMethodException JavaDoc e) {
569             exception = e;
570         } catch (IllegalArgumentException JavaDoc e) {
571             exception = e;
572         } catch (IllegalAccessException JavaDoc e) {
573             exception = e;
574         } catch (InvocationTargetException JavaDoc e) {
575             exception = e;
576         }
577         if (exception == null)
578             return;
579         String JavaDoc message = NLS.bind(Messages.plugin_shutdownProblems, descriptor.getUniqueIdentifier());
580         IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, message, exception);
581         InternalPlatform.getDefault().log(status);
582     }
583
584     /**
585      * Starts up this plug-in.
586      * <p>
587      * This method should be overridden in subclasses that need to do something
588      * when this plug-in is started. Implementors should call the inherited method
589      * to ensure that any system requirements can be met.
590      * </p>
591      * <p>
592      * If this method throws an exception, it is taken as an indication that
593      * plug-in initialization has failed; as a result, the plug-in will not
594      * be activated; moreover, the plug-in will be marked as disabled and
595      * ineligible for activation for the duration.
596      * </p>
597      * <p>
598      * Plug-in startup code should be robust. In the event of a startup failure,
599      * the plug-in's <code>shutdown</code> method will be invoked automatically,
600      * in an attempt to close open files, etc.
601      * </p>
602      * <p>
603      * Note 1: This method is automatically invoked by the platform
604      * the first time any code in the plug-in is executed.
605      * </p>
606      * <p>
607      * Note 2: This method is intended to perform simple initialization
608      * of the plug-in environment. The platform may terminate initializers
609      * that do not complete in a timely fashion.
610      * </p>
611      * <p>
612      * Note 3: The class loader typically has monitors acquired during invocation of this method. It is
613      * strongly recommended that this method avoid synchronized blocks or other thread locking mechanisms,
614      * as this would lead to deadlock vulnerability.
615      * </p>
616      * <b>Clients must never explicitly call this method.</b>
617      * <p>
618      *
619      * @exception CoreException if this plug-in did not start up properly
620      * @deprecated
621      * In Eclipse 3.0 this method has been replaced by {@link Plugin#start(BundleContext context)}.
622      * Implementations of <code>startup()</code> should be changed to extend
623      * <code>start(BundleContext context)</code> and call <code>super.start(context)</code>
624      * instead of <code>super.startup()</code>.
625      * The <code>startup()</code> method is called only for plug-ins which explicitly require the
626      * org.eclipse.core.runtime.compatibility plug-in.
627      */

628     public void startup() throws CoreException {
629     }
630
631     /**
632      * Returns a string representation of the plug-in, suitable
633      * for debugging purposes only.
634      */

635     public String JavaDoc toString() {
636         String JavaDoc name = bundle.getSymbolicName();
637         return name == null ? new Long JavaDoc(bundle.getBundleId()).toString() : name;
638     }
639
640     /**
641      * Starts up this plug-in.
642      * <p>
643      * This method should be overridden in subclasses that need to do something
644      * when this plug-in is started. Implementors should call the inherited method
645      * at the first possible point to ensure that any system requirements can be met.
646      * </p>
647      * <p>
648      * If this method throws an exception, it is taken as an indication that
649      * plug-in initialization has failed; as a result, the plug-in will not
650      * be activated; moreover, the plug-in will be marked as disabled and
651      * ineligible for activation for the duration.
652      * </p>
653      * <p>
654      * Plug-in startup code should be robust. In the event of a startup failure,
655      * the plug-in's <code>shutdown</code> method will be invoked automatically,
656      * in an attempt to close open files, etc.
657      * </p>
658      * <p>
659      * Note 1: This method is automatically invoked by the platform
660      * the first time any code in the plug-in is executed.
661      * </p>
662      * <p>
663      * Note 2: This method is intended to perform simple initialization
664      * of the plug-in environment. The platform may terminate initializers
665      * that do not complete in a timely fashion.
666      * </p>
667      * <p>
668      * Note 3: The class loader typically has monitors acquired during invocation of this method. It is
669      * strongly recommended that this method avoid synchronized blocks or other thread locking mechanisms,
670      * as this would lead to deadlock vulnerability.
671      * </p>
672      * <p>
673      * Note 4: The supplied bundle context represents the plug-in to the OSGi framework.
674      * For security reasons, it is strongly recommended that this object should not be divulged.
675      * </p>
676      * <p>
677      * Note 5: This method and the {@link #stop(BundleContext)} may be called from separate threads,
678      * but the OSGi framework ensures that both methods will not be called simultaneously.
679      * </p>
680      * <b>Clients must never explicitly call this method.</b>
681      *
682      * @param context the bundle context for this plug-in
683      * @exception Exception if this plug-in did not start up properly
684      * @since 3.0
685      */

686     public void start(BundleContext context) throws Exception JavaDoc {
687         bundle = context.getBundle();
688
689         String JavaDoc symbolicName = bundle.getSymbolicName();
690         if (symbolicName != null) {
691             String JavaDoc key = symbolicName + "/debug"; //$NON-NLS-1$
692
String JavaDoc value = InternalPlatform.getDefault().getOption(key);
693             this.debug = value == null ? false : value.equalsIgnoreCase("true"); //$NON-NLS-1$
694
}
695
696         initializeDescriptor(symbolicName);
697     }
698
699     /**
700      * @deprecated Marked as deprecated to suppress deprecation warnings.
701      */

702     private IPluginDescriptor initializeDescriptor(String JavaDoc symbolicName) {
703         if (CompatibilityHelper.initializeCompatibility() == null)
704             return null;
705
706         //This associate a descriptor to any real bundle that uses this to start
707
if (symbolicName == null)
708             return null;
709
710         IPluginDescriptor tmp = CompatibilityHelper.getPluginDescriptor(symbolicName);
711
712         //Runtime descriptor is never set to support dynamic re-installation of compatibility
713
if (!symbolicName.equals(Platform.PI_RUNTIME))
714             descriptor = tmp;
715
716         CompatibilityHelper.setPlugin(tmp, this);
717         CompatibilityHelper.setActive(tmp);
718         return tmp;
719     }
720
721     /**
722      * Stops this plug-in.
723      * <p>
724      * This method should be re-implemented in subclasses that need to do something
725      * when the plug-in is shut down. Implementors should call the inherited method
726      * as late as possible to ensure that any system requirements can be met.
727      * </p>
728      * <p>
729      * Plug-in shutdown code should be robust. In particular, this method
730      * should always make an effort to shut down the plug-in. Furthermore,
731      * the code should not assume that the plug-in was started successfully,
732      * as this method will be invoked in the event of a failure during startup.
733      * </p>
734      * <p>
735      * Note 1: If a plug-in has been automatically started, this method will be automatically
736      * invoked by the platform when the platform is shut down.
737      * </p>
738      * <p>
739      * Note 2: This method is intended to perform simple termination
740      * of the plug-in environment. The platform may terminate invocations
741      * that do not complete in a timely fashion.
742      * </p>
743      * <p>
744      * Note 3: The supplied bundle context represents the plug-in to the OSGi framework.
745      * For security reasons, it is strongly recommended that this object should not be divulged.
746      * </p>
747      * <p>
748      * Note 4: This method and the {@link #start(BundleContext)} may be called from separate threads,
749      * but the OSGi framework ensures that both methods will not be called simultaneously.
750      * </p>
751      * <b>Clients must never explicitly call this method.</b>
752      *
753      * @param context the bundle context for this plug-in
754      * @exception Exception if this method fails to shut down this plug-in
755      * @since 3.0
756      */

757     public void stop(BundleContext context) throws Exception JavaDoc {
758         // sub-classes to override
759
}
760
761     /**
762      * Returns the bundle associated with this plug-in.
763      *
764      * @return the associated bundle
765      * @since 3.0
766      */

767     public final Bundle getBundle() {
768         return bundle;
769     }
770 }
771
Popular Tags