All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.core.runtime.Plugin Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Lars Vogel  - Bug 476403, 478769, 490586
 *     Christoph Läubrich - remove reference to InternalPlatform.getDefault().log
 *******************************************************************************/
package org.eclipse.core.runtime;

import java.io.*;
import java.net.URL;
import java.util.Map;
import org.eclipse.core.internal.runtime.*;
import org.eclipse.core.runtime.preferences.*;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.osgi.framework.*;
import org.osgi.util.tracker.ServiceTracker;

/**
 * The abstract superclass of all plug-in runtime class implementations. A
 * plug-in subclasses this class and overrides the appropriate life cycle
 * methods in order to react to the life cycle requests automatically issued by
 * the platform. For compatibility reasons, the methods called for those life
 * cycle events vary, please see the "Constructors and life cycle methods"
 * section below.
 *
 * 

* Conceptually, the plug-in runtime class represents the entire plug-in rather * than an implementation of any one particular extension the plug-in declares. * A plug-in is not required to explicitly specify a plug-in runtime class; if * none is specified, the plug-in will be given a default plug-in runtime object * that ignores all life cycle requests (it still provides access to the * corresponding plug-in descriptor). *

*

* In the case of more complex plug-ins, it may be desirable to define a * concrete subclass of Plugin. However, just subclassing * Plugin is not sufficient. The name of the class must be * explicitly configured in the plug-in's manifest (plugin.xml) * file with the class attribute of the <plugin> element * markup. *

*

* Instances of plug-in runtime classes are automatically created by the * platform in the course of plug-in activation. For compatibility reasons, the * constructor used to create plug-in instances varies, please see the * "Constructors and life cycle methods" section below. *

*

* The concept of bundles underlies plug-ins. However it is safe to regard * plug-ins and bundles as synonyms. *

*

* Clients must never explicitly instantiate a plug-in runtime class. *

*

* A typical implementation pattern for plug-in runtime classes is to provide a * static convenience method to gain access to a plug-in's runtime object. This * way, code in other parts of the plug-in implementation without direct access * to the plug-in runtime object can easily obtain a reference to it, and thence * to any plug-in-wide resources recorded on it. An example for Eclipse 3.0 * follows: *

* *
 * package myplugin;
 *
 * public class MyPluginClass extends Plugin {
 * 	private static MyPluginClass instance;
 *
 * 	public static MyPluginClass getInstance() {
 * 		return instance;
 * 	}
 *
 * 	public void MyPluginClass() {
 * 		super();
 * 		instance = this;
 * 		// ... other initialization
 * 	}
 * 	// ... other methods
 * }
 * 
*

* In the above example, a call to MyPluginClass.getInstance() will * always return an initialized instance of MyPluginClass. *

*

* Constructors and life cycle methods *

*

* If the plugin.xml of a plug-in indicates <?eclipse version="3.0"?> and * its prerequisite list includes org.eclipse.core.runtime, the * default constructor of the plug-in class is used and * {@link #start(BundleContext)} and {@link #stop(BundleContext)} are called as * life cycle methods. *

*

* Since Eclipse 3.0 APIs of the Plugin class can be called only when the Plugin * is in an active state, i.e., after it was started up and before it is * shutdown. In particular, it means that Plugin APIs should not be called from * overrides of {@link #Plugin()}. *

*/ public abstract class Plugin implements BundleActivator { /** * String constant used for the default scope name for legacy * Eclipse plug-in preferences. The value of PLUGIN_PREFERENCE_SCOPE should * match the InstanceScope's variable SCOPE from org.eclipse.core.runtime.preferences. * The value is copied in this file to prevent unnecessary activation of * the Preferences plugin on startup. * * @since 3.0 */ public static final String PLUGIN_PREFERENCE_SCOPE = "instance"; //$NON-NLS-1$ /** * The bundle associated this plug-in */ private Bundle bundle; private volatile IPath stateLocation; /** * The debug flag for this plug-in. The flag is false by default. * This flag is only used when the DebugOptions service is not available. */ private boolean debug = false; /** * DebugOptions service tracker */ private ServiceTracker debugTracker = null; /** * The base name (value "preferences") for the file which is used for * overriding default preference values. * * @since 2.0 * @see #PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME */ public static final String PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME = "preferences"; //$NON-NLS-1$ /** * The name of the file (value "preferences.ini") in a * plug-in's (read-only) directory that, when present, contains values that * override the normal default values for this plug-in's preferences. *

* The format of the file is as per java.io.Properties where * the keys are property names and values are strings. *

* * @since 2.0 */ public static final String PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME = PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME + ".ini"; //$NON-NLS-1$ /** * The preference object for this plug-in; initially null * meaning not yet created and initialized. * * @since 2.0 * @deprecated */ @Deprecated private Preferences preferences = null; /** * Creates a new plug-in runtime object. This method is called by the platform * if this class is used as a BundleActivator. This method is not * needed/used if this plug-in requires the org.eclipse.core.runtime.compatibility plug-in. * Subclasses of Plugin * must call this method first in their constructors. * * The resultant instance is not managed by the runtime and * so should be remembered by the client (typically using a Singleton pattern). * Clients must never explicitly call this method. *

* Note: The class loader typically has monitors acquired during invocation of this method. It is * strongly recommended that this method avoid synchronized blocks or other thread locking mechanisms, * as this would lead to deadlock vulnerability. *

* * @since 3.0 */ public Plugin() { super(); } /** * Returns a URL for the given path. Returns null if the URL * could not be computed or created. * * @param path path relative to plug-in installation location * @return a URL for the given path or null * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)} */ @Deprecated public final URL find(IPath path) { return FileLocator.find(getBundle(), path, null); } /** * Returns a URL for the given path. Returns null if the URL * could not be computed or created. * * @param path file path relative to plug-in installation location * @param override map of override substitution arguments to be used for * any $arg$ path elements. The map keys correspond to the substitution * arguments (eg. "$nl$" or "$os$"). The resulting * values must be of type java.lang.String. If the map is null, * or does not contain the required substitution argument, the default * is used. * @return a URL for the given path or null * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)} */ @Deprecated public final URL find(IPath path, Map override) { return FileLocator.find(getBundle(), path, override); } /** * Returns the log for this plug-in. If no such log exists, one is created. * Hint: instead of caling this method, consider using * {@link ILog#of(Class)} instead that is independent from implementing a * {@link Plugin} * * @return the log for this plug-in */ public final ILog getLog() { return ILog.of(getBundle()); } /** * Returns the location in the local file system of the * plug-in state area for this plug-in. * If the plug-in state area did not exist prior to this call, * it is created. *

* The plug-in state area is a file directory within the * platform's metadata area where a plug-in is free to create files. * The content and structure of this area is defined by the plug-in, * and the particular plug-in is solely responsible for any files * it puts there. It is recommended for plug-in preference settings and * other configuration parameters. *

* @throws IllegalStateException when the system is running with no data area (-data @none), * or when a data area has not been set yet. * @return a local file system path * XXX Investigate the usage of a service factory (see also platform.getStateLocation) */ public final IPath getStateLocation() throws IllegalStateException { if (stateLocation == null) { // cache the value to avoid repeated java.io.File.mkdirs() // does not matter if the value is computed twice in parallel stateLocation = InternalPlatform.getDefault().getStateLocation(getBundle(), true); } return stateLocation; } /** * Returns the preference store for this plug-in. *

* Note that if an error occurs reading the preference store from disk, an empty * preference store is quietly created, initialized with defaults, and returned. *

*

* Calling this method may cause the preference store to be created and * initialized. Subclasses which reimplement the * initializeDefaultPluginPreferences method have this opportunity * to initialize preference default values, just prior to processing override * default values imposed externally to this plug-in (specified for the product, * or at platform start up). *

*

* After settings in the preference store are changed (for example, with * Preferences.setValue or setToDefault), * savePluginPreferences should be called to store the changed * values back to disk. Otherwise the changes will be lost on plug-in shutdown. *

* * @return the preference store * @see #savePluginPreferences() * @see Preferences#setValue(String, String) * @see Preferences#setToDefault(String) * @since 2.0 * @deprecated Replaced by {@link IEclipsePreferences}. Preferences are now * stored according to scopes in the {@link IPreferencesService}. * The return value of this method corresponds to a combination of * the {@link InstanceScope} and the {@link DefaultScope}. To set * preferences for your plug-in, use * InstanceScope.INSTANCE.getNode(<yourPluginId>). * To set default preferences for your plug-in, use * DefaultScope.INSTANCE.getNode(<yourPluginId>). * To lookup an integer preference value for your plug-in, use * Platform.getPreferencesService().getInt(<yourPluginId>, <preferenceKey>, <defaultValue>, null). * Similar methods exist on {@link IPreferencesService} for * obtaining other kinds of preference values (strings, booleans, * etc). */ @Deprecated public final Preferences getPluginPreferences() { final Bundle bundleCopy = getBundle(); if (preferences != null) { if (InternalPlatform.DEBUG_PLUGIN_PREFERENCES) InternalPlatform.message("Plugin preferences already loaded for: " + bundleCopy.getSymbolicName()); //$NON-NLS-1$ return preferences; } if (InternalPlatform.DEBUG_PLUGIN_PREFERENCES) InternalPlatform.message("Loading preferences for plugin: " + bundleCopy.getSymbolicName()); //$NON-NLS-1$ // Performance: isolate PreferenceForwarder into an inner class so that it mere presence // won't force the PreferenceForwarder class to be loaded (which triggers Preferences plugin // activation). final Preferences[] preferencesCopy = new Preferences[1]; Runnable innerCall = () -> preferencesCopy[0] = new org.eclipse.core.internal.preferences.legacy.PreferenceForwarder( this, bundleCopy.getSymbolicName()); innerCall.run(); preferences = preferencesCopy[0]; return preferences; } /** * Saves preferences settings for this plug-in. Does nothing if the preference * store does not need saving. *

* Plug-in preferences are not saved automatically on plug-in shutdown. *

* * @see Preferences#store(OutputStream, String) * @see Preferences#needsSaving() * @since 2.0 * @deprecated Replaced by InstanceScope.getNode(<bundleId>).flush() */ @Deprecated public final void savePluginPreferences() { if (InternalPlatform.getDefault().isRunning()) { Location instance = InternalPlatform.getDefault().getInstanceLocation(); if (instance == null || !instance.isSet()) // If the instance area is not set there is no point in getting or setting the preferences. // There is nothing to save in this case. return; // populate the "preferences" instance variable. We still might // need to save them because someone else might have // made changes via the OSGi APIs. getPluginPreferences(); // Performance: isolate PreferenceForwarder and BackingStoreException into // an inner class to avoid class loading (and then activation of the Preferences plugin) // as the Plugin class is loaded. final Preferences preferencesCopy = preferences; Runnable innerCall = () -> { try { ((org.eclipse.core.internal.preferences.legacy.PreferenceForwarder) preferencesCopy).flush(); } catch (org.osgi.service.prefs.BackingStoreException e) { IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, Messages.preferences_saveProblems, e); RuntimeLog.log(status); } }; innerCall.run(); } } /** * Initializes the default preferences settings for this plug-in. *

* This method is called sometime after the preference store for this * plug-in is created. Default values are never stored in preference * stores; they must be filled in each time. This method provides the * opportunity to initialize the default values. *

*

* The default implementation of this method does nothing. A subclass that needs * to set default values for its preferences must reimplement this method. * Default values set at a later point will override any default override * settings supplied from outside the plug-in (product configuration or * platform start up). *

* @since 2.0 * @deprecated * This method has been refactored in the new preference mechanism * to handle the case where the runtime compatibility layer does not exist. The * contents of this method should be moved to the method named * initializeDefaultPreferences in a separate subclass of * {@link org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer}. * This class should be contributed via the * org.eclipse.core.runtime.preferences extension point. *
	 * 	<extension point="org.eclipse.core.runtime.preferences">
	 *			<initializer class="com.example.MyPreferenceInitializer"/>
	 *		</extension>
	 *		...
	 *		package com.example;
	 *		public class MyPreferenceInitializer extends AbstractPreferenceInitializer {
	 *			public MyPreferenceInitializer() {
	 *				super();
	 *			}
	 *			public void initializeDefaultPreferences() {
	 *				Preferences node = new DefaultScope().getNode("my.plugin.id");
	 *				node.put(key, value);
	 *			}
	 *		}
	 * 
*/ @Deprecated protected void initializeDefaultPluginPreferences() { // default implementation of this method - spec'd to do nothing } /** * Internal method. This method is a hook for * initialization of default preference values. * It should not be called by clients. * * @since 3.0 * @deprecated */ @Deprecated public final void internalInitializeDefaultPluginPreferences() { initializeDefaultPluginPreferences(); } /** * Returns whether this plug-in is in debug mode. * By default plug-ins are not in debug mode. A plug-in can put itself * into debug mode or the user can set an execution option to do so. *

* Note that the plug-in's debug flag is initialized when the * plug-in is started. The result of calling this method before the plug-in * has started is unspecified. *

* * @return whether this plug-in is in debug mode * XXX deprecate use the service and cache as needed */ public boolean isDebugging() { Bundle debugBundle = getBundle(); if (debugBundle == null) return debug; String key = debugBundle.getSymbolicName() + "/debug"; //$NON-NLS-1$ // first check if platform debugging is enabled final DebugOptions debugOptions = getDebugOptions(); if (debugOptions == null) return debug; // if platform debugging is enabled, check to see if this plugin is enabled for debugging return debugOptions.isDebugEnabled() ? InternalPlatform.getDefault().getBooleanOption(key, false) : false; } /** * Returns an input stream for the specified file. The file path * must be specified relative this the plug-in's installation location. * * @param file path relative to plug-in installation location * @return an input stream * @exception IOException if the given path cannot be found in this plug-in * * @see #openStream(IPath,boolean) * @deprecated use {@link FileLocator#openStream(Bundle, IPath, boolean)} */ @Deprecated public final InputStream openStream(IPath file) throws IOException { return FileLocator.openStream(getBundle(), file, false); } /** * Returns an input stream for the specified file. The file path * must be specified relative to this plug-in's installation location. * Optionally, the path specified may contain $arg$ path elements that can * be used as substitution arguments. If this option is used then the $arg$ * path elements are processed in the same way as {@link #find(IPath, Map)}. *

* The caller must close the returned stream when done. *

* * @param file path relative to plug-in installation location * @param substituteArgs true to process substitution arguments, * and false for the file exactly as specified without processing any * substitution arguments. * @return an input stream * @exception IOException if the given path cannot be found in this plug-in * @deprecated use {@link FileLocator#openStream(Bundle, IPath, boolean)} */ @Deprecated public final InputStream openStream(IPath file, boolean substituteArgs) throws IOException { return FileLocator.openStream(getBundle(), file, substituteArgs); } /** * Sets whether this plug-in is in debug mode. * By default plug-ins are not in debug mode. A plug-in can put itself * into debug mode or the user can set a debug option to do so. *

* Note that the plug-in's debug flag is initialized when the * plug-in is started. The result of calling this method before the plug-in * has started is unspecified. *

* * @param value whether or not this plug-in is in debug mode * XXX deprecate use the service and cache as needed */ public void setDebugging(boolean value) { Bundle debugBundle = getBundle(); if (debugBundle == null) { this.debug = value; return; } String key = debugBundle.getSymbolicName() + "/debug"; //$NON-NLS-1$ final DebugOptions options = getDebugOptions(); if (options == null) this.debug = value; else { if (!options.isDebugEnabled()) options.setDebugEnabled(true); options.setOption(key, value ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); } } /** * Returns the DebugOptions instance * * @since 3.5 * @return Either the DebugOptions instance or null if this plug-in does not have a bundle */ private DebugOptions getDebugOptions() { Bundle debugBundle = getBundle(); if (debugBundle == null) return null; if (debugTracker == null) { BundleContext context = debugBundle.getBundleContext(); if (context == null) return null; debugTracker = new ServiceTracker<>(context, DebugOptions.class.getName(), null); debugTracker.open(); } return this.debugTracker.getService(); } /** * As the org.eclipse.core.runtime.compatibility plug-in has been removed in * Eclipse 4.6 this method is not supported anymore. * * In Eclipse 3.0 this method has been replaced by * {@link Plugin#stop(BundleContext context)}. Implementations of * shutdown() should be changed to override * stop(BundleContext context) and call * super.stop(context) instead of super.shutdown() * . * * The shutdown() method was called only for plug-ins which * explicitly required the org.eclipse.core.runtime.compatibility plug-in. * It is not called anymore. * * @throws CoreException Never thrown as method as no longer called. * * @deprecated */ @Deprecated public void shutdown() throws CoreException { // intentionally left empty } /** * As the org.eclipse.core.runtime.compatibility plug-in has been removed in * Eclipse 4.6 this method is not supported anymore. * * In Eclipse 3.0 this method has been replaced by * {@link Plugin#start(BundleContext context)}. Implementations of * startup() should be changed to extend * start(BundleContext context) and call * super.start(context) instead of * super.startup(). * * The startup() method was called only for plug-ins which * explicitly required the org.eclipse.core.runtime.compatibility plug-in. * It is not called anymore. * * @throws CoreException Never thrown as method as no longer called. * * @deprecated */ @Deprecated public void startup() throws CoreException { // intentionally left empty } /** * Returns a string representation of the plug-in, suitable * for debugging purposes only. */ @Override public String toString() { Bundle myBundle = getBundle(); if (myBundle == null) return ""; //$NON-NLS-1$ String name = myBundle.getSymbolicName(); return name == null ? String.valueOf(myBundle.getBundleId()) : name; } /** * Starts up this plug-in. *

* This method should be overridden in subclasses that need to do something * when this plug-in is started. Implementors should call the inherited method * at the first possible point to ensure that any system requirements can be met. *

*

* If this method throws an exception, it is taken as an indication that * plug-in initialization has failed; as a result, the plug-in will not * be activated; moreover, the plug-in will be marked as disabled and * ineligible for activation for the duration. *

*

* Note 1: This method is automatically invoked by the platform * the first time any code in the plug-in is executed. *

*

* Note 2: This method is intended to perform simple initialization * of the plug-in environment. The platform may terminate initializers * that do not complete in a timely fashion. *

*

* Note 3: The class loader typically has monitors acquired during invocation of this method. It is * strongly recommended that this method avoid synchronized blocks or other thread locking mechanisms, * as this would lead to deadlock vulnerability. *

*

* Note 4: The supplied bundle context represents the plug-in to the OSGi framework. * For security reasons, it is strongly recommended that this object should not be divulged. *

*

* Note 5: This method and the {@link #stop(BundleContext)} may be called from separate threads, * but the OSGi framework ensures that both methods will not be called simultaneously. *

* Clients must never explicitly call this method. * * @param context the bundle context for this plug-in * @exception Exception if this plug-in did not start up properly * @since 3.0 */ @Override public void start(BundleContext context) throws Exception { bundle = context.getBundle(); } /** * Stops this plug-in. *

* This method should be re-implemented in subclasses that need to do something * when the plug-in is shut down. Implementors should call the inherited method * as late as possible to ensure that any system requirements can be met. *

*

* Plug-in shutdown code should be robust. In particular, this method * should always make an effort to shut down the plug-in. Furthermore, * the code should not assume that the plug-in was started successfully. *

*

* Note 1: If a plug-in has been automatically started, this method will be automatically * invoked by the platform when the platform is shut down. *

*

* Note 2: This method is intended to perform simple termination * of the plug-in environment. The platform may terminate invocations * that do not complete in a timely fashion. *

*

* Note 3: The supplied bundle context represents the plug-in to the OSGi framework. * For security reasons, it is strongly recommended that this object should not be divulged. *

*

* Note 4: This method and the {@link #start(BundleContext)} may be called from separate threads, * but the OSGi framework ensures that both methods will not be called simultaneously. *

* Clients must never explicitly call this method. * * @param context the bundle context for this plug-in * @exception Exception if this method fails to shut down this plug-in * @since 3.0 */ @Override public void stop(BundleContext context) throws Exception { if (this.debugTracker != null) { this.debugTracker.close(); this.debugTracker = null; } // sub-classes to override } /** * Returns the bundle associated with this plug-in. * * @return the associated bundle * @since 3.0 */ public final Bundle getBundle() { if (bundle != null) return bundle; ClassLoader cl = getClass().getClassLoader(); if (cl instanceof BundleReference) return ((BundleReference) cl).getBundle(); return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy