Elipse plugin or Bundle & OSGI
Develop and register service,
lookup and use service!
Android Design on service's publish-find-bind model.
- What is OSGi(Open Service Gateway Initiative)?: http://www.osgi.org/Technology/WhatIsOSGi
- http://dz.prosyst.com/pdoc/mBS_R5_SDK_7.3.0_beta/getting_started/introduction.html
One simple example:
Service:
package org.serc.helloworld;
public interface Hello
{
void sayHello();
} package org.serc.helloworld.impl;
public class HelloImpl implements Hello
{
final String helloString;
public HelloImpl(String helloString){
this.helloString= helloString;
}
public void sayHello(){
System.out.println(this.helloString);
}
} package org.serc.helloworld.activator;
public class Activator implements BundleActivator {
private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
public void start(BundleContext ctx) {//only register one service just now
registrations.add(ctx.registerService(Hello.class.getName(),new HelloImpl("Hello, OSGi"), null));
}
public void stop(BundleContext ctx) {
for(ServiceRegistration registration : registrations) {
System.out.println("unregistering:"+ registration);
registration.unregister();
}
}
}
//MANIFEST
Bundle-ManifestVersion:2
Bundle-SymbolicName:org.serc.helloworld
Bundle-Version:1.0
Bundle-Activator:org.serc.helloworld.activator.Activator
Import-Package:org.osgi.framework
Export-Package:org.serc.helloworld;version="1.0" //the package which will be used by other bundle
Client:
package org.serc.helloworld.client;
public class HelloUser implements BundleActivator {
public void start(BundleContext ctx) { //ctx is created by runtime kernel, framwork entity
ServiceReference ref = ctx.getServiceReference(Hello.class.getName());//now get a service reference which implement Hello
if(ref != null) {
Hello hello = null;
try{
hello= (Hello) ctx.getService(ref);//get reference
if(hello != null)
hello.sayHello();
else
System.out.println("Service:Hello---objectnull");
}
catch (RuntimeException e) {
e.printStackTrace();
}
finally{
ctx.ungetService(ref);
hello= null;
}
}
else {
System.out.println("Service:Hello---notexists");
}
}
public void stop(BundleContext ctx) throws Exception {
}
}
//
Bundle-ManifestVersion:2
Bundle-SymbolicName:org.serc.helloworld.client
Bundle-Version:1.0
Bundle-Activator:org.serc.helloworld.client.HelloUser //Bundle luncher
Import-Package:org.serc.helloworld;version="[1.0,2.0)",org.osgi.framework //the package which is used by this bundle
- Bundle
- Words with same meaning:parcel,package,bunch,plug-in;A collection of things wrapped or boxed together;a collection of things wrapped or boxed together
- The mechanics for supporting plug-ins are implemented using the OSGi framework. From this standpoint, a plug-in is the same thing as an OSGi bundle. The bundle and its associated classes specify and implement the process for Java class-loading, prequisite management, and the bundle's life-cycle. For the rest of this discussion, we use the terms plug-in and bundle interchangeably, unless discussing a particular class in the framework.
Underneath every plug-in lies an OSGi bundle managed by the framework. The Bundle is the OSGi unit of modularity. Fundamentally, a bundle is just a collection of files (resources and code) installed in the platform. Each bundle has its own Java class loader, and includes protocol for starting, stopping, and uninstalling itself. From the Eclipse platform point of view, Bundle is merely an implementation class. Plug-in developers do not extend the bundle class, but use Plugin or other BundleActivator implementations to represent the plug-in.
- Plugin:
The Plugin class represents a plug-in that is running in the platform. It is a convenient place to centralize the life-cycle aspects and overall semantics of a plug-in. A plug-in can implement specialized functionality for the start and stop aspects of its life-cycle. Each life-cycle method includes a reference to a BundleContext which can supply additional information.
The start portion of the life-cycle is worth particular discussion. We've seen already that information about a plug-in can be obtained from the plug-in's manifest file without ever running any of the plug-in's code. Typically, some user action in the workbench causes a chain of events that requires the starting of a plug-in. From an implementation point of view, a plug-in is never started until a class contained in the plug-in needs to be loaded.
The start method has been a convenient place to implement initialization and registration behavior for a plug-in. However, it is important to realize that your plug-in can be started in many different circumstances. Something as simple as obtaining an icon to decorate an object can cause one of your plug-in's classes to be loaded, thus starting your plug-in. Over-eager initialization can cause your plug-in's code and data to be loaded long before it is necessary. Therefore, it's important to look closely at your plug-in's initialization tasks and consider alternatives to performing initialization at start-up.
- Registration activities such as registering listeners or starting background threads are appropriate during plug-in start-up if they can be performed quickly. However, it is advisable to trigger these actions as part of accessing the plug-in's data if the registration activities have side-effects such as initializing large data structures or performing unrelated operations.
- Initialization of data is best done lazily, when the data is first accessed, rather than automatically in the start-up code. This ensures that large data structures are not built until they are truly necessary.
Bundle Context:Life-cycle management is where the OSGi "bundle" terminology and the platform's "plug-in" terminology meet. When your plug-in is started, it is given a reference to a BundleContext from which it can obtain information related to the plug-in. The BundleContext can also be used to find out about other bundles/plug-ins in the system.
BundleContext.getBundles() can be used to obtain an array of all bundles in the system. Listeners for BundleEvent can be registered so that your plug-in is aware when another bundle has a change in its life-cycle status. See the javadoc for BundleContext and BundleEvent for more information.Prior to 3.0, a plug-in registry (IPluginRegistry) was provided to supply similar information. For example, it could be queried for the plug-in descriptors of all plug-ins in the system. This registry is now deprecated and BundleContext should be used for this purpose. The platform registry is now used exclusively for information about extensions and extension points.TheBundleContext
object is only valid during the execution of its context bundle; that is, during the period from when the context bundle is in theSTARTING
,STOPPING
, andACTIVE
bundle states. If theBundleContext
object is used subsequently, anIllegalStateException
must be thrown.The
BundleContext
object must never be reused after its context bundle is stopped.TwoBundleContext
objects are equal if they both refer to the same execution context of a bundle.The Framework is the only entity that can create
BundleContext
objects and they are only valid within the Framework that created them.
public interface Comparable<T> { //generic in Java
public int compareTo(T o);
}package org.osgi.framework;
public interface Bundle extends Comparable<Bundle> {
int UNINSTALLED = 0x00000001;
int INSTALLED = 0x00000002;
int RESOLVED = 0x00000004;
int STARTING = 0x00000008;
int STOPPING = 0x00000010;
int ACTIVE = 0x00000020;
int START_TRANSIENT = 0x00000001;
int START_ACTIVATION_POLICY = 0x00000002;
int STOP_TRANSIENT = 0x00000001;
int SIGNERS_ALL = 1;
int SIGNERS_TRUSTED = 2;
int getState();
void start(int options) throws BundleException;
void start() throws BundleException;
void stop(int options) throws BundleException;
void stop() throws BundleException;
void update(InputStream input) throws BundleException;
void update() throws BundleException;
void uninstall() throws BundleException;
Dictionary<String, String> getHeaders();
long getBundleId();
String getLocation();
ServiceReference<?>[] getRegisteredServices();
ServiceReference<?>[] getServicesInUse();
boolean hasPermission(Object permission);
URL getResource(String name);
Enumeration<String> getEntryPaths(String path);
URL getEntry(String path);
long getLastModified();
Enumeration<URL> findEntries(String path, String filePattern, boolean recurse);
BundleContext getBundleContext();
Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType);
Version getVersion();
<A> A adapt(Class<A> type);
File getDataFile(String filename);
}public interface BundleReference {
public Bundle getBundle();
}package org.osgi.framework;
public interface BundleContext extends BundleReference {
String getProperty(String key);
Bundle getBundle();
Bundle installBundle(String location, InputStream input) throws BundleException;
Bundle installBundle(String location) throws BundleException;
Bundle getBundle(long id);
Bundle[] getBundles();
void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException;
void addServiceListener(ServiceListener listener);
void removeServiceListener(ServiceListener listener);
void addBundleListener(BundleListener listener);
void removeBundleListener(BundleListener listener);
void addFrameworkListener(FrameworkListener listener);
void removeFrameworkListener(FrameworkListener listener);
ServiceRegistration<?> registerService(String clazz, Object service, Dictionary<String, ?> properties);
<S> ServiceRegistration<S> registerService(Class<S> clazz, S service, Dictionary<String, ?> properties);
ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
ServiceReference<?>[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
ServiceReference<?> getServiceReference(String clazz);
<S> ServiceReference<S> getServiceReference(Class<S> clazz);
<S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter) throws InvalidSyntaxException;
<S> S getService(ServiceReference<S> reference);
boolean ungetService(ServiceReference<?> reference);
File getDataFile(String filename);
Filter createFilter(String filter) throws InvalidSyntaxException;
Bundle getBundle(String location);
}- BundleActivator
- The BundleActivator interface defines the start and stop behavior implemented in Plugin. Although the Plugin class is a convenient place to implement this function, a plug-in developer has complete freedom to implement the interface for BundleActivator in any class appropriate for the plug-in's design. In fact, your plug-in need not implement this interface at all if it does not have specific life-cycle management needs.
public interface BundleActivator {
public void start(BundleContext context) throws Exception;
public void stop(BundleContext context) throws Exception;
}- Plugin
/*******************************************************************************
* Copyright (c) 2000, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Julian Chen - fix for bug #92572, jclRM
* Benjamin Cabe <benjamin.cabe@anyware-tech.com> - fix for bug 265532
*******************************************************************************/
package org.eclipse.core.internal.runtime; import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.eclipse.core.internal.preferences.exchange.ILegacyPreferences;
import org.eclipse.core.internal.preferences.exchange.IProductPreferencesService;
import org.eclipse.core.internal.preferences.legacy.InitLegacyPreferences;
import org.eclipse.core.internal.preferences.legacy.ProductPreferencesService;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.equinox.internal.app.*;
import org.eclipse.equinox.internal.app.Activator;
import org.eclipse.equinox.log.*;
import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
import org.eclipse.osgi.service.resolver.PlatformAdmin;
import org.osgi.framework.*;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.util.tracker.ServiceTracker; /**
* Bootstrap class for the platform. It is responsible for setting up the
* platform class loader and passing control to the actual application class
*/
public final class InternalPlatform { private static final String[] ARCH_LIST = {Platform.ARCH_PA_RISC, //
Platform.ARCH_PPC, //
Platform.ARCH_SPARC, //
Platform.ARCH_X86, //
Platform.ARCH_AMD64, //
Platform.ARCH_IA64, //
Platform.ARCH_IA64_32}; // debug support: set in loadOptions()
public static boolean DEBUG = false;
public static boolean DEBUG_PLUGIN_PREFERENCES = false; static boolean splashEnded = false;
private static boolean initialized;
private static final String KEYRING = "-keyring"; //$NON-NLS-1$
private static String keyringFile; //XXX This is not synchronized
private static Map logs = new HashMap(5); private static final String[] OS_LIST = {Platform.OS_AIX, Platform.OS_HPUX, Platform.OS_LINUX, Platform.OS_MACOSX, Platform.OS_QNX, Platform.OS_SOLARIS, Platform.OS_WIN32};
private static String password = ""; //$NON-NLS-1$
private static final String PASSWORD = "-password"; //$NON-NLS-1$ private static final String PLUGIN_PATH = ".plugin-path"; //$NON-NLS-1$ public static final String PROP_APPLICATION = "eclipse.application"; //$NON-NLS-1$
public static final String PROP_ARCH = "osgi.arch"; //$NON-NLS-1$
public static final String PROP_CONFIG_AREA = "osgi.configuration.area"; //$NON-NLS-1$
public static final String PROP_CONSOLE_LOG = "eclipse.consoleLog"; //$NON-NLS-1$
public static final String PROP_DEBUG = "osgi.debug"; //$NON-NLS-1$
public static final String PROP_DEV = "osgi.dev"; //$NON-NLS-1$ // OSGI system properties. Copied from EclipseStarter
public static final String PROP_INSTALL_AREA = "osgi.install.area"; //$NON-NLS-1$
public static final String PROP_NL = "osgi.nl"; //$NON-NLS-1$
public static final String PROP_OS = "osgi.os"; //$NON-NLS-1$ // Eclipse System Properties
public static final String PROP_PRODUCT = "eclipse.product"; //$NON-NLS-1$
public static final String PROP_WS = "osgi.ws"; //$NON-NLS-1$
public static final String PROP_ACTIVATE_PLUGINS = "eclipse.activateRuntimePlugins"; //$NON-NLS-1$ private static final InternalPlatform singleton = new InternalPlatform(); private static final String[] WS_LIST = {Platform.WS_CARBON, Platform.WS_COCOA, Platform.WS_GTK, Platform.WS_MOTIF, Platform.WS_PHOTON, Platform.WS_WIN32, Platform.WS_WPF};
private Path cachedInstanceLocation; // Cache the path of the instance location
private ServiceTracker configurationLocation = null;
private BundleContext context; private Map groupProviders = new HashMap(3);
private ServiceTracker installLocation = null;
private ServiceTracker instanceLocation = null; private Plugin runtimeInstance; // Keep track of the plugin object for runtime in case the backward compatibility is run. private ServiceRegistration legacyPreferencesService = null;
private ServiceRegistration customPreferencesService = null; private ServiceTracker environmentTracker = null;
private ServiceTracker logTracker = null;
private ServiceTracker bundleTracker = null;
private ServiceTracker debugTracker = null;
private ServiceTracker contentTracker = null;
private ServiceTracker preferencesTracker = null;
private ServiceTracker userLocation = null;
private ServiceTracker groupProviderTracker = null;
private ServiceTracker logReaderTracker = null;
private ServiceTracker extendedLogTracker = null; private IProduct product; public static InternalPlatform getDefault() {
return singleton;
} /**
* Private constructor to block instance creation.
*/
private InternalPlatform() {
super();
} /**
* @see Platform#addLogListener(ILogListener)
*/
public void addLogListener(ILogListener listener) {
assertInitialized();
RuntimeLog.addLogListener(listener);
} private void assertInitialized() {
//avoid the Policy.bind if assertion is true
if (!initialized)
Assert.isTrue(false, Messages.meta_appNotInit);
} /**
* @see Platform#endSplash()
*/
public void endSplash() {
synchronized (this) {
if (splashEnded)
return; // do not do this more than once
splashEnded = true;
}
IApplicationContext applicationContext = getApplicationContext();
if (applicationContext != null)
applicationContext.applicationRunning();
} /**
* @see Platform#getAdapterManager()
*/
public IAdapterManager getAdapterManager() {
assertInitialized();
return AdapterManager.getDefault();
} /**
* XXX Use the Environment info service. Need to see how to set the value of the app args.
*/
public String[] getApplicationArgs() {
return CommandLineArgs.getApplicationArgs();
} public boolean getBooleanOption(String option, boolean defaultValue) {
String value = getOption(option);
if (value == null)
return defaultValue;
return value.equalsIgnoreCase("true"); //$NON-NLS-1$
} public Bundle getBundle(String symbolicName) {
PackageAdmin packageAdmin = getBundleAdmin();
if (packageAdmin == null)
return null;
Bundle[] bundles = packageAdmin.getBundles(symbolicName, null);
if (bundles == null)
return null;
//Return the first bundle that is not installed or uninstalled
for (int i = 0; i < bundles.length; i++) {
if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
return bundles[i];
}
}
return null;
} public BundleContext getBundleContext() {
return context;
} /**
* Returns the bundle id of the bundle that contains the provided object, or
* <code>null</code> if the bundle could not be determined.
*/
public String getBundleId(Object object) {
if (object == null)
return null;
PackageAdmin packageAdmin = getBundleAdmin();
if (packageAdmin == null)
return null;
Bundle source = packageAdmin.getBundle(object.getClass());
if (source != null && source.getSymbolicName() != null)
return source.getSymbolicName();
return null;
} public IBundleGroupProvider[] getBundleGroupProviders() {
Object[] objectArray = groupProviderTracker.getServices();
if (objectArray == null) // getServices may return null; but we can not.
return new IBundleGroupProvider[0];
IBundleGroupProvider[] result = new IBundleGroupProvider[objectArray.length];
System.arraycopy(objectArray, 0, result, 0, objectArray.length);
return result;
} public void registerBundleGroupProvider(IBundleGroupProvider provider) {
// get the bundle context and register the provider as a service
ServiceRegistration registration = getBundleContext().registerService(IBundleGroupProvider.class.getName(), provider, null);
// store the service registration (map provider -> registration)
synchronized (groupProviders) {
groupProviders.put(provider, registration);
}
} public void unregisterBundleGroupProvider(IBundleGroupProvider provider) {
// get the service reference (map provider -> reference)
ServiceRegistration registration;
synchronized (groupProviders) {
registration = (ServiceRegistration) groupProviders.remove(provider);
}
if (registration == null)
return;
// unregister the provider
registration.unregister();
} public Bundle[] getBundles(String symbolicName, String version) {
PackageAdmin packageAdmin = getBundleAdmin();
if (packageAdmin == null)
return null;
Bundle[] bundles = packageAdmin.getBundles(symbolicName, version);
if (bundles == null)
return null;
// optimize for common case; length==1
if (bundles.length == 1 && (bundles[0].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0)
return bundles;
//Remove all the bundles that are installed or uninstalled
Bundle[] selectedBundles = new Bundle[bundles.length];
int added = 0;
for (int i = 0; i < bundles.length; i++) {
if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
selectedBundles[added++] = bundles[i];
}
}
if (added == 0)
return null; //return an array of the correct size
Bundle[] results = new Bundle[added];
System.arraycopy(selectedBundles, 0, results, 0, added);
return results;
} public String[] getCommandLineArgs() {
return CommandLineArgs.getAllArgs();
} public Location getConfigurationLocation() {
assertInitialized();
return (Location) configurationLocation.getService();
} /**
* Lazy initialize ContentTypeManager - it can only be used after the registry is up and running
*/
public IContentTypeManager getContentTypeManager() {
return contentTracker == null ? null : (IContentTypeManager) contentTracker.getService();
} public EnvironmentInfo getEnvironmentInfoService() {
return environmentTracker == null ? null : (EnvironmentInfo) environmentTracker.getService();
} public Bundle[] getFragments(Bundle bundle) {
PackageAdmin packageAdmin = getBundleAdmin();
if (packageAdmin == null)
return null;
return packageAdmin.getFragments(bundle);
} public FrameworkLog getFrameworkLog() {
return logTracker == null ? null : (FrameworkLog) logTracker.getService();
} public Bundle[] getHosts(Bundle bundle) {
PackageAdmin packageAdmin = getBundleAdmin();
if (packageAdmin == null)
return null;
return packageAdmin.getHosts(bundle);
} public Location getInstallLocation() {
assertInitialized();
return (Location) installLocation.getService();
} public URL getInstallURL() {
Location location = getInstallLocation();
// it is pretty much impossible for the install location to be null. If it is, the
// system is in a bad way so throw and exception and get the heck outta here.
if (location == null)
throw new IllegalStateException("The installation location must not be null"); //$NON-NLS-1$
return location.getURL();
} public Location getInstanceLocation() {
assertInitialized();
return (Location) instanceLocation.getService();
} /**
* @see Platform#getLocation()
*/
public IPath getLocation() throws IllegalStateException {
if (cachedInstanceLocation == null) {
Location location = getInstanceLocation();
if (location == null)
return null;
// This makes the assumption that the instance location is a file: URL
File file = new File(location.getURL().getFile());
cachedInstanceLocation = new Path(file.toString());
}
return cachedInstanceLocation;
} /**
* Returns a log for the given plugin. Creates a new one if needed.
* XXX change this into a LogMgr service that would keep track of the map. See if it can be a service factory.
* It would contain all the logging methods that are here.
* Relate to RuntimeLog if appropriate.
* The system log listener needs to be optional: turned on or off. What about a system property? :-)
*/
public ILog getLog(Bundle bundle) {
Log result = (Log) logs.get(bundle);
if (result != null)
return result;
ExtendedLogService logService = (ExtendedLogService) extendedLogTracker.getService();
Logger logger = logService == null ? null : logService.getLogger(bundle, PlatformLogWriter.EQUINOX_LOGGER_NAME);
result = new Log(bundle, logger);
ExtendedLogReaderService logReader = (ExtendedLogReaderService) logReaderTracker.getService();
logReader.addLogListener(result, result);
logs.put(bundle, result);
return result;
} /**
* Returns the object which defines the location and organization
* of the platform's meta area.
*/
public DataArea getMetaArea() {
// TODO: deprecate?
return MetaDataKeeper.getMetaArea();
} public String getNL() {
return getBundleContext().getProperty(PROP_NL);
} /**
* Unicode locale extensions are defined using command line parameter -nlExtensions,
* or the system property "osgi.nl.extensions".
*/
public String getNLExtensions() {
String nlExtensions = PlatformActivator.getContext().getProperty("osgi.nl.extensions"); //$NON-NLS-1$
if (nlExtensions == null)
return ""; //$NON-NLS-1$
if (!nlExtensions.startsWith("@")) //$NON-NLS-1$
nlExtensions = '@' + nlExtensions;
return nlExtensions;
} /**
* @see Platform
*/
public String getOption(String option) {
DebugOptions options = getDebugOptions();
if (options != null)
return options.getOption(option);
return null;
} public String getOS() {
return getBundleContext().getProperty(PROP_OS);
} public String getOSArch() {
return getBundleContext().getProperty(PROP_ARCH);
} public PlatformAdmin getPlatformAdmin() {
if (context == null)
return null;
ServiceReference platformAdminReference = context.getServiceReference(PlatformAdmin.class.getName());
if (platformAdminReference == null)
return null;
return (PlatformAdmin) context.getService(platformAdminReference);
} //TODO I guess it is now time to get rid of that
/*
* This method is retained for R1.0 compatibility because it is defined as API.
* Its function matches the API description (returns <code>null</code> when
* argument URL is <code>null</code> or cannot be read).
*/
public URL[] getPluginPath(URL pluginPathLocation /*R1.0 compatibility*/
) {
InputStream input = null;
// first try and see if the given plugin path location exists.
if (pluginPathLocation == null)
return null;
try {
input = pluginPathLocation.openStream();
} catch (IOException e) {
//fall through
} // if the given path was null or did not exist, look for a plugin path
// definition in the install location.
if (input == null)
try {
URL url = new URL("platform:/base/" + PLUGIN_PATH); //$NON-NLS-1$
input = url.openStream();
} catch (MalformedURLException e) {
//fall through
} catch (IOException e) {
//fall through
} // nothing was found at the supplied location or in the install location
if (input == null)
return null;
// if we found a plugin path definition somewhere so read it and close the location.
URL[] result = null;
try {
try {
result = readPluginPath(input);
} finally {
input.close();
}
} catch (IOException e) {
//let it return null on failure to read
}
return result;
} /**
*
*/
public IPreferencesService getPreferencesService() {
return preferencesTracker == null ? null : (IPreferencesService) preferencesTracker.getService();
} /*
* XXX move this into the app model.
*/
public IProduct getProduct() {
if (product != null)
return product;
EclipseAppContainer container = Activator.getContainer();
IBranding branding = container == null ? null : container.getBranding();
if (branding == null)
return null;
Object brandingProduct = branding.getProduct();
if (!(brandingProduct instanceof IProduct))
brandingProduct = new Product(branding);
product = (IProduct) brandingProduct;
return product;
} public IExtensionRegistry getRegistry() {
return RegistryFactory.getRegistry();
} /**
* XXX deprecate and use NLS or BundleFinder.find()
*/
public ResourceBundle getResourceBundle(Bundle bundle) {
return ResourceTranslator.getResourceBundle(bundle);
} /**
* XXX deprecate and use NLS or BundleFinder.find()
*/
public String getResourceString(Bundle bundle, String value) {
return ResourceTranslator.getResourceString(bundle, value);
} /**
* XXX deprecate and use NLS or BundleFinder.find()
*/
public String getResourceString(Bundle bundle, String value, ResourceBundle resourceBundle) {
return ResourceTranslator.getResourceString(bundle, value, resourceBundle);
} /**
* This method is only used to register runtime once compatibility has been started.
*/
public Plugin getRuntimeInstance() {
return runtimeInstance;
} private IApplicationContext getApplicationContext() {
ServiceReference[] ref;
try {
ref = context.getServiceReferences(IApplicationContext.class.getName(), "(eclipse.application.type=main.thread)"); //$NON-NLS-1$
} catch (InvalidSyntaxException e) {
return null;
}
if (ref == null || ref.length == 0)
return null;
// assumes the application context is available as a service
IApplicationContext result = (IApplicationContext) context.getService(ref[0]);
if (result != null) {
context.ungetService(ref[0]);
return result;
}
return null;
} /**
* XXX Investigate the usage of a service factory
*/
public IPath getStateLocation(Bundle bundle) {
return getStateLocation(bundle, true);
} public IPath getStateLocation(Bundle bundle, boolean create) throws IllegalStateException {
assertInitialized();
IPath result = getMetaArea().getStateLocation(bundle);
if (create)
result.toFile().mkdirs();
return result;
} public long getStateTimeStamp() {
PlatformAdmin admin = getPlatformAdmin();
return admin == null ? -1 : admin.getState(false).getTimeStamp();
} public Location getUserLocation() {
assertInitialized();
return (Location) userLocation.getService();
} public String getWS() {
return getBundleContext().getProperty(PROP_WS);
} private void initializeAuthorizationHandler() {
try {
AuthorizationHandler.setKeyringFile(keyringFile);
AuthorizationHandler.setPassword(password);
} catch (NoClassDefFoundError e) {
// The authorization fragment is not available. If someone tries to use that API, an error will be logged
}
} /*
* Finds and loads the options file
*/
void initializeDebugFlags() {
// load runtime options
DEBUG = getBooleanOption(Platform.PI_RUNTIME + "/debug", false); //$NON-NLS-1$
if (DEBUG) {
DEBUG_PLUGIN_PREFERENCES = getBooleanOption(Platform.PI_RUNTIME + "/preferences/plugin", false); //$NON-NLS-1$
}
} public boolean isFragment(Bundle bundle) {
PackageAdmin packageAdmin = getBundleAdmin();
if (packageAdmin == null)
return false;
return (packageAdmin.getBundleType(bundle) & PackageAdmin.BUNDLE_TYPE_FRAGMENT) > 0;
} /*
*XXX do what you want to do. track osgi, track runtime, or whatever.
*/
public boolean isRunning() {
try {
return initialized && context != null && context.getBundle().getState() == Bundle.ACTIVE;
} catch (IllegalStateException e) {
return false;
}
} /**
* Returns a list of known system architectures.
*
* @return the list of system architectures known to the system
* XXX This is useless
*/
public String[] knownOSArchValues() {
return ARCH_LIST;
} /**
* Returns a list of known operating system names.
*
* @return the list of operating systems known to the system
* XXX This is useless
*/
public String[] knownOSValues() {
return OS_LIST;
} /**
* Returns a list of known windowing system names.
*
* @return the list of window systems known to the system
* XXX This is useless
*/
public String[] knownWSValues() {
return WS_LIST;
} /**
* Notifies all listeners of the platform log. This includes the console log, if
* used, and the platform log file. All Plugin log messages get funnelled
* through here as well.
*/
public void log(final IStatus status) {
// TODO: deprecate?
RuntimeLog.log(status);
} private void processCommandLine(String[] args) {
if (args == null || args.length == 0)
return; for (int i = 0; i < args.length; i++) {
// check for args with parameters
if (i == args.length - 1 || args[i + 1].startsWith("-")) //$NON-NLS-1$
continue;
String arg = args[++i]; // look for the keyring file
if (args[i - 1].equalsIgnoreCase(KEYRING))
keyringFile = arg;
// look for the user password.
if (args[i - 1].equalsIgnoreCase(PASSWORD))
password = arg;
}
} private URL[] readPluginPath(InputStream input) {
Properties ini = new Properties();
try {
ini.load(input);
} catch (IOException e) {
return null;
}
Vector result = new Vector(5);
for (Enumeration groups = ini.propertyNames(); groups.hasMoreElements();) {
String group = (String) groups.nextElement();
for (StringTokenizer entries = new StringTokenizer(ini.getProperty(group), ";"); entries.hasMoreElements();) { //$NON-NLS-1$
String entry = (String) entries.nextElement();
if (!entry.equals("")) //$NON-NLS-1$
try {
result.addElement(new URL(entry));
} catch (MalformedURLException e) {
//intentionally ignore bad URLs
System.err.println("Ignoring plugin: " + entry); //$NON-NLS-1$
}
}
}
return (URL[]) result.toArray(new URL[result.size()]);
} /**
* @see Platform#removeLogListener(ILogListener)
*/
public void removeLogListener(ILogListener listener) {
assertInitialized();
RuntimeLog.removeLogListener(listener);
} /**
* This method is only used to register runtime once compatibility has been started.
*/
public void setRuntimeInstance(Plugin runtime) {
runtimeInstance = runtime;
} /**
* Internal method for starting up the platform. The platform is not started with any location
* and should not try to access the instance data area.
*
* Note: the content type manager must be initialized only after the registry has been created
*/
public void start(BundleContext runtimeContext) {
this.context = runtimeContext;
openOSGiTrackers();
splashEnded = false;
processCommandLine(getEnvironmentInfoService().getNonFrameworkArgs());
initializeDebugFlags();
initialized = true;
getMetaArea();
initializeAuthorizationHandler();
startServices(); // See if need to activate rest of the runtime plugins. Plugins are "gently" activated by touching
// a class from the corresponding plugin(s).
boolean shouldActivate = !"false".equalsIgnoreCase(context.getProperty(PROP_ACTIVATE_PLUGINS)); //$NON-NLS-1$
if (shouldActivate) {
// activate Preferences plugin by creating a class from it:
new org.eclipse.core.runtime.preferences.DefaultScope();
// activate Jobs plugin by creating a class from it:
org.eclipse.core.runtime.jobs.Job.getJobManager();
}
} /**
* Shutdown runtime pieces in this order:
* Content[auto shutdown] -> Preferences[auto shutdown] -> Registry -> Jobs
* The "auto" shutdown takes place before this code is executed
*/
public void stop(BundleContext bundleContext) {
assertInitialized();
stopServices(); // should be done after preferences shutdown
initialized = false;
closeOSGITrackers();
context = null;
} private void openOSGiTrackers() {
Filter filter = null;
try {
filter = context.createFilter(Location.INSTANCE_FILTER);
} catch (InvalidSyntaxException e) {
// ignore this. It should never happen as we have tested the above format.
}
instanceLocation = new ServiceTracker(context, filter, null);
instanceLocation.open(); try {
filter = context.createFilter(Location.USER_FILTER);
} catch (InvalidSyntaxException e) {
// ignore this. It should never happen as we have tested the above format.
}
userLocation = new ServiceTracker(context, filter, null);
userLocation.open(); try {
filter = context.createFilter(Location.CONFIGURATION_FILTER);
} catch (InvalidSyntaxException e) {
// ignore this. It should never happen as we have tested the above format.
}
configurationLocation = new ServiceTracker(context, filter, null);
configurationLocation.open(); try {
filter = context.createFilter(Location.INSTALL_FILTER);
} catch (InvalidSyntaxException e) {
// ignore this. It should never happen as we have tested the above format.
}
installLocation = new ServiceTracker(context, filter, null);
installLocation.open(); if (context != null) {
logTracker = new ServiceTracker(context, FrameworkLog.class.getName(), null);
logTracker.open();
} if (context != null) {
bundleTracker = new ServiceTracker(context, PackageAdmin.class.getName(), null);
bundleTracker.open();
} if (context != null) {
contentTracker = new ServiceTracker(context, IContentTypeManager.class.getName(), null);
contentTracker.open();
} if (context != null) {
preferencesTracker = new ServiceTracker(context, IPreferencesService.class.getName(), null);
preferencesTracker.open();
} try {
filter = context.createFilter("(objectClass=" + IBundleGroupProvider.class.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
} catch (InvalidSyntaxException e) {
// ignore this, it should never happen
}
groupProviderTracker = new ServiceTracker(context, filter, null);
groupProviderTracker.open(); logReaderTracker = new ServiceTracker(context, ExtendedLogReaderService.class.getName(), null);
logReaderTracker.open(); extendedLogTracker = new ServiceTracker(context, ExtendedLogService.class.getName(), null);
extendedLogTracker.open(); environmentTracker = new ServiceTracker(context, EnvironmentInfo.class.getName(), null);
environmentTracker.open(); debugTracker = new ServiceTracker(context, DebugOptions.class.getName(), null);
debugTracker.open();
} private void startServices() {
// The check for getProduct() is relatively expensive (about 3% of the headless startup),
// so we don't want to enforce it here.
customPreferencesService = context.registerService(IProductPreferencesService.class.getName(), new ProductPreferencesService(), new Hashtable()); // Only register this interface if compatibility is installed - the check for a bundle presence
// is a quick test that doesn't consume much.
if (getBundle(CompatibilityHelper.PI_RUNTIME_COMPATIBILITY) != null)
legacyPreferencesService = context.registerService(ILegacyPreferences.class.getName(), new InitLegacyPreferences(), new Hashtable());
} private void stopServices() {
if (legacyPreferencesService != null) {
legacyPreferencesService.unregister();
legacyPreferencesService = null;
}
if (customPreferencesService != null) {
customPreferencesService.unregister();
customPreferencesService = null;
}
} private PackageAdmin getBundleAdmin() {
return bundleTracker == null ? null : (PackageAdmin) bundleTracker.getService();
} private DebugOptions getDebugOptions() {
return debugTracker == null ? null : (DebugOptions) debugTracker.getService();
} private void closeOSGITrackers() {
if (preferencesTracker != null) {
preferencesTracker.close();
preferencesTracker = null;
}
if (contentTracker != null) {
contentTracker.close();
contentTracker = null;
}
if (debugTracker != null) {
debugTracker.close();
debugTracker = null;
}
if (bundleTracker != null) {
bundleTracker.close();
bundleTracker = null;
}
if (logTracker != null) {
logTracker.close();
logTracker = null;
}
if (groupProviderTracker != null) {
groupProviderTracker.close();
groupProviderTracker = null;
}
if (environmentTracker != null) {
environmentTracker.close();
environmentTracker = null;
}
if (logReaderTracker != null) {
logReaderTracker.close();
logReaderTracker = null;
}
if (extendedLogTracker != null) {
extendedLogTracker.close();
extendedLogTracker = null;
}
if (installLocation != null) {
installLocation.close();
installLocation = null;
}
if (userLocation != null) {
userLocation.close();
userLocation = null;
}
if (configurationLocation != null) {
configurationLocation.close();
configurationLocation = null;
}
if (instanceLocation != null) {
instanceLocation.close();
instanceLocation = null;
}
} /**
* Print a debug message to the console.
* Pre-pend the message with the current date and the name of the current thread.
*/
public static void message(String message) {
StringBuffer buffer = new StringBuffer();
buffer.append(new Date(System.currentTimeMillis()));
buffer.append(" - ["); //$NON-NLS-1$
buffer.append(Thread.currentThread().getName());
buffer.append("] "); //$NON-NLS-1$
buffer.append(message);
System.out.println(buffer.toString());
} public static void start(Bundle bundle) throws BundleException {
int originalState = bundle.getState();
if ((originalState & Bundle.ACTIVE) != 0)
return; // bundle is already active
try {
// attempt to activate the bundle
bundle.start(Bundle.START_TRANSIENT);
} catch (BundleException e) {
if ((originalState & Bundle.STARTING) != 0 && (bundle.getState() & Bundle.STARTING) != 0)
// This can happen if the bundle was in the process of being activated on this thread, just return
return;
throw e;
}
}
}
InternalPlatform
package org.eclipse.core.runtime;
public abstract class Plugin implements BundleActivator {
public static final String PLUGIN_PREFERENCE_SCOPE = "instance";
private Bundle bundle;
private boolean debug = false;
private ServiceTracker debugTracker = null;
private IPluginDescriptor descriptor;
public static final String PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME = "preferences"; //$NON-NLS-1$
public static final String PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME = PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME + ".ini"; //$NON-NLS-1$
private Preferences preferences = null;
public Plugin() {
super();
}
public Plugin(IPluginDescriptor descriptor) {
Assert.isNotNull(descriptor);
Assert.isTrue(!CompatibilityHelper.hasPluginObject(descriptor), NLS.bind(Messages.plugin_deactivatedLoad, this.getClass().getName(), descriptor.getUniqueIdentifier() + " is not activated")); //$NON-NLS-1$
this.descriptor = descriptor; // on plugin start, find and start the corresponding bundle.
bundle = InternalPlatform.getDefault().getBundle(descriptor.getUniqueIdentifier());
try {
InternalPlatform.start(bundle);
} catch (BundleException e) {
String message = NLS.bind(Messages.plugin_startupProblems, descriptor.getUniqueIdentifier());
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, message, e);
InternalPlatform.getDefault().log(status);
}
}
public final URL find(IPath path) {
return FileLocator.find(getBundle(), path, null);
}
public final ILog getLog() {
return InternalPlatform.getDefault().getLog(getBundle());
}
public final IPath getStateLocation() throws IllegalStateException {
return InternalPlatform.getDefault().getStateLocation(getBundle(), true);
}
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;
}
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());
}
}
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 (DebugOptions) this.debugTracker.getService();
}
public String toString() {
Bundle myBundle = getBundle();
if (myBundle == null)
return ""; //$NON-NLS-1$
String name = myBundle.getSymbolicName();
return name == null ? new Long(myBundle.getBundleId()).toString() : name;
}
public void start(BundleContext context) throws Exception {
bundle = context.getBundle();
initializeDescriptor(bundle.getSymbolicName());
}
private IPluginDescriptor initializeDescriptor(String symbolicName) {
if (CompatibilityHelper.initializeCompatibility() == null)
return null; //This associate a descriptor to any real bundle that uses this to start
if (symbolicName == null)
return null; IPluginDescriptor tmp = CompatibilityHelper.getPluginDescriptor(symbolicName); //Runtime descriptor is never set to support dynamic re-installation of compatibility
if (!symbolicName.equals(Platform.PI_RUNTIME))
descriptor = tmp; CompatibilityHelper.setPlugin(tmp, this);
CompatibilityHelper.setActive(tmp);
return tmp;
}
public void stop(BundleContext context) throws Exception { if (this.debugTracker != null) {
this.debugTracker.close();
this.debugTracker = null;
}
// sub-classes to override
}
public final Bundle getBundle() {
if (bundle != null)
return bundle;
ClassLoader cl = getClass().getClassLoader();
if (cl instanceof BundleReference)
return ((BundleReference) cl).getBundle();
return null;
}
}
plugin
public void start(BundleContext context) throws Exception {
bundle = context.getBundle();
initializeDescriptor(bundle.getSymbolicName());
}
private IPluginDescriptor initializeDescriptor(String symbolicName) {
if (CompatibilityHelper.initializeCompatibility() == null)
return null;
//This associate a descriptor to any real bundle that uses this to start
if (symbolicName == null)
return null;
IPluginDescriptor tmp = CompatibilityHelper.getPluginDescriptor(symbolicName);
//Runtime descriptor is never set to support dynamic re-installation of compatibility
if (!symbolicName.equals(Platform.PI_RUNTIME))
descriptor = tmp;
CompatibilityHelper.setPlugin(tmp, this);
CompatibilityHelper.setActive(tmp);
return tmp;
}public final Bundle getBundle() {
if (bundle != null)
return bundle;
ClassLoader cl = getClass().getClassLoader();
if (cl instanceof BundleReference)
return ((BundleReference) cl).getBundle();
return null;
}public Plugin(IPluginDescriptor descriptor) {
Assert.isNotNull(descriptor);
Assert.isTrue(!CompatibilityHelper.hasPluginObject(descriptor), NLS.bind(Messages.plugin_deactivatedLoad, this.getClass().getName(), descriptor.getUniqueIdentifier() + " is not activated")); //$NON-NLS-1$
this.descriptor = descriptor;
// on plugin start, find and start the corresponding bundle.
bundle = InternalPlatform.getDefault().getBundle(descriptor.getUniqueIdentifier());
try {
InternalPlatform.start(bundle);
} catch (BundleException e) {
String message = NLS.bind(Messages.plugin_startupProblems, descriptor.getUniqueIdentifier());
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, message, e);
InternalPlatform.getDefault().log(status);
}
}- AbstractUIPlugin
package org.eclipse.ui.plugin;
public abstract class AbstractUIPlugin extends Plugin {
private static final String FN_DIALOG_SETTINGS = "dialog_settings.xml"; //$NON-NLS-1$
private IDialogSettings dialogSettings = null;
private ScopedPreferenceStore preferenceStore;
private ImageRegistry imageRegistry = null;
private BundleListener bundleListener;
public AbstractUIPlugin() {
super();
}
protected ImageRegistry createImageRegistry() {
//If we are in the UI Thread use that
if(Display.getCurrent() != null) {
return new ImageRegistry(Display.getCurrent());
}
if(PlatformUI.isWorkbenchRunning()) {
return new ImageRegistry(PlatformUI.getWorkbench().getDisplay());
}
//Invalid thread access if it is not the UI Thread
//and the workbench is not created.
throw new SWTError(SWT.ERROR_THREAD_INVALID_ACCESS);
}
public IDialogSettings getDialogSettings() {
if (dialogSettings == null) {
loadDialogSettings();
}
return dialogSettings;
}
public ImageRegistry getImageRegistry() {
if (imageRegistry == null) {
imageRegistry = createImageRegistry();
initializeImageRegistry(imageRegistry);
}
return imageRegistry;
}
public IPreferenceStore getPreferenceStore() {
// Create the preference store lazily.
if (preferenceStore == null) {
preferenceStore = new ScopedPreferenceStore(new InstanceScope(),getBundle().getSymbolicName()); }
return preferenceStore;
}
public IWorkbench getWorkbench() {
return PlatformUI.getWorkbench();
}
protected void initializeDefaultPreferences(IPreferenceStore store) {
// spec'ed to do nothing
}
protected void initializeDefaultPluginPreferences() {
initializeDefaultPreferences(getPreferenceStore());
}
protected void initializeImageRegistry(ImageRegistry reg) {
// spec'ed to do nothing
}
protected void loadDialogSettings() {
dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
IPath dataLocation = getStateLocationOrNull();
if (dataLocation != null) {
String readWritePath = dataLocation.append(FN_DIALOG_SETTINGS)
.toOSString();
File settingsFile = new File(readWritePath);
if (settingsFile.exists()) {
try {
dialogSettings.load(readWritePath);
} catch (IOException e) {
// load failed so ensure we have an empty settings
dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
}
return;
}
}
// otherwise look for bundle specific dialog settings
URL dsURL = BundleUtility.find(getBundle(), FN_DIALOG_SETTINGS);
if (dsURL == null) {
return;
}
InputStream is = null;
try {
is = dsURL.openStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "utf-8")); //$NON-NLS-1$
dialogSettings.load(reader);
} catch (IOException e) {
// load failed so ensure we have an empty settings
dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
// do nothing
}
}
}
protected void loadPreferenceStore() {
// do nothing by default
}
protected void refreshPluginActions() {
// If the workbench is not started yet, or is no longer running, do nothing.
if (!PlatformUI.isWorkbenchRunning()) {
return;
}
Display.getDefault().asyncExec(new Runnable() {
public void run() {
WWinPluginAction.refreshActionList();
}
});
}
protected void saveDialogSettings() {
if (dialogSettings == null) {
return;
}
try {
IPath path = getStateLocationOrNull();
if(path == null) {
return;
}
String readWritePath = path
.append(FN_DIALOG_SETTINGS).toOSString();
dialogSettings.save(readWritePath);
} catch (IOException e) {
// spec'ed to ignore problems
} catch (IllegalStateException e) {
// spec'ed to ignore problems
}
}
public void startup() throws CoreException {
// this method no longer does anything
// the code that used to be here in 2.1 has moved to start(BundleContext)
super.startup();
}
public void shutdown() throws CoreException {
// this method no longer does anything interesting
// the code that used to be here in 2.1 has moved to stop(BundleContext),
// which is called regardless of whether the plug-in being instantiated
// requires org.eclipse.core.runtime.compatibility
super.shutdown();
}
public void start(BundleContext context) throws Exception {
super.start(context);
final BundleContext fc = context;
// Should only attempt refreshPluginActions() once the bundle
// has been fully started. Otherwise, action delegates
// can be created while in the process of creating
// a triggering action delegate (if UI events are processed during startup).
// Also, if the start throws an exception, the bundle will be shut down.
// We don't want to have created any delegates if this happens.
// See bug 63324 for more details.
bundleListener = new BundleListener() {
public void bundleChanged(BundleEvent event) {
if (event.getBundle() == getBundle()) {
if (event.getType() == BundleEvent.STARTED) {
// We're getting notified that the bundle has been started.
// Make sure it's still active. It may have been shut down between
// the time this event was queued and now.
if (getBundle().getState() == Bundle.ACTIVE) {
refreshPluginActions();
}
fc.removeBundleListener(this);
}
}
}
};
context.addBundleListener(bundleListener);
// bundleListener is removed in stop(BundleContext)
}
public void stop(BundleContext context) throws Exception {
try {
if (bundleListener != null) {
context.removeBundleListener(bundleListener);
}
saveDialogSettings();
savePreferenceStore();
preferenceStore = null;
if (imageRegistry != null)
imageRegistry.dispose();
imageRegistry = null;
} finally {
super.stop(context);
}
}
public static ImageDescriptor imageDescriptorFromPlugin(String pluginId,
String imageFilePath) {
if (pluginId == null || imageFilePath == null) {
throw new IllegalArgumentException();
} IWorkbench workbench = PlatformUI.isWorkbenchRunning() ? PlatformUI.getWorkbench() : null;
ImageDescriptor imageDescriptor = workbench == null ? null : workbench
.getSharedImages().getImageDescriptor(imageFilePath);
if (imageDescriptor != null)
return imageDescriptor; // found in the shared images // if the bundle is not ready then there is no image
Bundle bundle = Platform.getBundle(pluginId);
if (!BundleUtility.isReady(bundle)) {
return null;
} // look for the image (this will check both the plugin and fragment folders
URL fullPathString = BundleUtility.find(bundle, imageFilePath);
if (fullPathString == null) {
try {
fullPathString = new URL(imageFilePath);
} catch (MalformedURLException e) {
return null;
}
}
return ImageDescriptor.createFromURL(fullPathString);
}
private IPath getStateLocationOrNull() {
try {
return getStateLocation();
} catch (IllegalStateException e) {
// This occurs if -data=@none is explicitly specified, so ignore this silently.
// Is this OK? See bug 85071.
return null;
}
}
}AbstractUIPlugin
Here are the class we used in AbstractUIPlugin
The Workbench
When the Workbench is launched, the first thing you see is a dialog that allows you to select where the workspace should be located. The workspace is the directory where your work will be stored. For now, just click OK to pick the default location.After the workspace location is chosen, a single Workbench window is displayed. A Workbench window offers one or more perspectives. A perspective contains editors and views, such as the Project Explorer. Multiple Workbench windows can be opened simultaneously. Initially, in the first Workbench window that is opened, the Java perspective is displayed, with only the Welcome view visible. Click the arrow labeled Workbench in the Welcome view to cause the other views in the perspective to become visible. Note you can get the Welcome view back at any time by selecting Help > Welcome.A shortcut bar appears in the top right corner of the window. This allows you to open new perspectives and switch between ones already open. The name of the active perspective is shown in the title of the window and its item in the shortcut bar is highlighted.
/*******************************************************************************
* Copyright (c) 2000, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Francis Upton - <francisu@ieee.org> -
* Fix for Bug 217777 [Workbench] Workbench event loop does not terminate if Display is closed
*******************************************************************************/ package org.eclipse.ui.internal; import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.ULocale.Category;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.CommandManager;
import org.eclipse.core.commands.CommandManagerEvent;
import org.eclipse.core.commands.ICommandManagerListener;
import org.eclipse.core.commands.common.EventManager;
import org.eclipse.core.commands.contexts.ContextManager;
import org.eclipse.core.commands.contexts.ContextManagerEvent;
import org.eclipse.core.commands.contexts.IContextManagerListener;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionDelta;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IPlatformRunnable;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.InjectionException;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.internal.workbench.E4Workbench;
import org.eclipse.e4.ui.internal.workbench.renderers.swt.IUpdateService;
import org.eclipse.e4.ui.internal.workbench.swt.E4Application;
import org.eclipse.e4.ui.internal.workbench.swt.IEventLoopAdvisor;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MBindingContext;
import org.eclipse.e4.ui.model.application.commands.MBindingTable;
import org.eclipse.e4.ui.model.application.commands.MCategory;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.commands.MCommandsFactory;
import org.eclipse.e4.ui.model.application.commands.impl.CommandsFactoryImpl;
import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicFactoryImpl;
import org.eclipse.e4.ui.services.EContextService;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.ExternalActionManager;
import org.eclipse.jface.action.ExternalActionManager.CommandCallback;
import org.eclipse.jface.action.ExternalActionManager.IActiveChecker;
import org.eclipse.jface.action.ExternalActionManager.IExecuteApplicable;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.bindings.BindingManager;
import org.eclipse.jface.bindings.BindingManagerEvent;
import org.eclipse.jface.bindings.IBindingManagerListener;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.service.runnable.StartupMonitor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.DeviceData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IDecoratorManager;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.ILocalWorkingSetManager;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.ISaveableFilter;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.ISourceProvider;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.activities.IWorkbenchActivitySupport;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.commands.ICommandImageService;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.commands.IWorkbenchCommandSupport;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.contexts.IWorkbenchContextSupport;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
import org.eclipse.ui.internal.actions.CommandAction;
import org.eclipse.ui.internal.activities.ws.WorkbenchActivitySupport;
import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
import org.eclipse.ui.internal.commands.CommandImageManager;
import org.eclipse.ui.internal.commands.CommandImageService;
import org.eclipse.ui.internal.commands.CommandService;
import org.eclipse.ui.internal.commands.WorkbenchCommandSupport;
import org.eclipse.ui.internal.contexts.ActiveContextSourceProvider;
import org.eclipse.ui.internal.contexts.ContextService;
import org.eclipse.ui.internal.contexts.WorkbenchContextSupport;
import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityPart;
import org.eclipse.ui.internal.e4.compatibility.E4Util;
import org.eclipse.ui.internal.handlers.LegacyHandlerService;
import org.eclipse.ui.internal.help.WorkbenchHelpSystem;
import org.eclipse.ui.internal.intro.IIntroRegistry;
import org.eclipse.ui.internal.intro.IntroDescriptor;
import org.eclipse.ui.internal.keys.BindingService;
import org.eclipse.ui.internal.menus.FocusControlSourceProvider;
import org.eclipse.ui.internal.menus.WorkbenchMenuService;
import org.eclipse.ui.internal.misc.Policy;
import org.eclipse.ui.internal.misc.StatusUtil;
import org.eclipse.ui.internal.misc.UIStats;
import org.eclipse.ui.internal.model.ContributionService;
import org.eclipse.ui.internal.progress.ProgressManager;
import org.eclipse.ui.internal.progress.ProgressManagerUtil;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.registry.UIExtensionTracker;
import org.eclipse.ui.internal.registry.ViewDescriptor;
import org.eclipse.ui.internal.services.EvaluationService;
import org.eclipse.ui.internal.services.IServiceLocatorCreator;
import org.eclipse.ui.internal.services.IWorkbenchLocationService;
import org.eclipse.ui.internal.services.MenuSourceProvider;
import org.eclipse.ui.internal.services.ServiceLocator;
import org.eclipse.ui.internal.services.ServiceLocatorCreator;
import org.eclipse.ui.internal.services.SourceProviderService;
import org.eclipse.ui.internal.services.WorkbenchLocationService;
import org.eclipse.ui.internal.splash.EclipseSplashHandler;
import org.eclipse.ui.internal.splash.SplashHandlerFactory;
import org.eclipse.ui.internal.testing.WorkbenchTestable;
import org.eclipse.ui.internal.themes.ColorDefinition;
import org.eclipse.ui.internal.themes.FontDefinition;
import org.eclipse.ui.internal.themes.ThemeElementHelper;
import org.eclipse.ui.internal.themes.WorkbenchThemeManager;
import org.eclipse.ui.internal.tweaklets.GrabFocus;
import org.eclipse.ui.internal.tweaklets.Tweaklets;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.intro.IIntroManager;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.menus.IMenuService;
import org.eclipse.ui.model.IContributionService;
import org.eclipse.ui.operations.IWorkbenchOperationSupport;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.services.IDisposable;
import org.eclipse.ui.services.IEvaluationService;
import org.eclipse.ui.services.IServiceScopes;
import org.eclipse.ui.services.ISourceProviderService;
import org.eclipse.ui.splash.AbstractSplashHandler;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.swt.IFocusService;
import org.eclipse.ui.themes.IThemeManager;
import org.eclipse.ui.views.IViewDescriptor;
import org.eclipse.ui.views.IViewRegistry;
import org.eclipse.ui.wizards.IWizardRegistry;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.SynchronousBundleListener;
import org.osgi.service.event.EventHandler;
import org.osgi.util.tracker.ServiceTracker; /**
* The workbench class represents the top of the Eclipse user interface. Its
* primary responsability is the management of workbench windows, dialogs,
* wizards, and other workbench-related windows.
* <p>
* Note that any code that is run during the creation of a workbench instance
* should not required access to the display.
* </p>
* <p>
* Note that this internal class changed significantly between 2.1 and 3.0.
* Applications that used to define subclasses of this internal class need to be
* rewritten to use the new workbench advisor API.
* </p>
*/
public final class Workbench extends EventManager implements IWorkbench { private final class StartupProgressBundleListener implements SynchronousBundleListener { private final IProgressMonitor progressMonitor; private final int maximumProgressCount; // stack of names of bundles currently starting
private final List starting; StartupProgressBundleListener(IProgressMonitor progressMonitor, int maximumProgressCount) {
super();
this.progressMonitor = progressMonitor;
this.maximumProgressCount = maximumProgressCount;
this.starting = new ArrayList();
} public void bundleChanged(BundleEvent event) {
int eventType = event.getType();
String bundleName; synchronized (this) {
if (eventType == BundleEvent.STARTING) {
starting.add(bundleName = event.getBundle().getSymbolicName());
} else if (eventType == BundleEvent.STARTED) {
progressCount++;
if (progressCount <= maximumProgressCount) {
progressMonitor.worked(1);
}
int index = starting.lastIndexOf(event.getBundle().getSymbolicName());
if (index >= 0) {
starting.remove(index);
}
if (index != starting.size()) {
return; // not currently displayed
}
bundleName = index == 0 ? null : (String) starting.get(index - 1);
} else {
return; // uninteresting event
}
} String taskName; if (bundleName == null) {
taskName = WorkbenchMessages.Startup_Loading_Workbench;
} else {
taskName = NLS.bind(WorkbenchMessages.Startup_Loading, bundleName);
} progressMonitor.subTask(taskName);
}
} /**
* Family for the early startup job.
*/
public static final String EARLY_STARTUP_FAMILY = "earlyStartup"; //$NON-NLS-1$ static final String VERSION_STRING[] = { "0.046", "2.0" }; //$NON-NLS-1$ //$NON-NLS-2$ static final String DEFAULT_WORKBENCH_STATE_FILENAME = "workbench.xml"; //$NON-NLS-1$ /**
* Holds onto the only instance of Workbench.
*/
private static Workbench instance; /**
* The testable object facade.
*
* @since 3.0
*/
private static WorkbenchTestable testableObject; /**
* Signals that the workbench should create a splash implementation when
* instantiated. Intial value is <code>true</code>.
*
* @since 3.3
*/
private static boolean createSplash = true; /**
* The splash handler.
*/
private static AbstractSplashHandler splash; /**
* The display used for all UI interactions with this workbench.
*
* @since 3.0
*/
private Display display; private EditorHistory editorHistory; private boolean runEventLoop = true; private boolean isStarting = true; private boolean isClosing = false; /**
* A boolean field to indicate whether all the workbench windows have been
* closed or not.
*/
private boolean windowsClosed = false; /**
* PlatformUI return code (as opposed to IPlatformRunnable return code).
*/
private int returnCode = PlatformUI.RETURN_UNSTARTABLE; /**
* Advisor providing application-specific configuration and customization of
* the workbench.
*
* @since 3.0
*/
private WorkbenchAdvisor advisor; /**
* Object for configuring the workbench. Lazily initialized to an instance
* unique to the workbench instance.
*
* @since 3.0
*/
private WorkbenchConfigurer workbenchConfigurer; // for dynamic UI
/**
* ExtensionEventHandler handles extension life-cycle events.
*/
private ExtensionEventHandler extensionEventHandler; /**
* A count of how many large updates are going on. This tracks nesting of
* requests to disable services during a large update -- similar to the
* <code>setRedraw</code> functionality on <code>Control</code>. When this
* value becomes greater than zero, services are disabled. When this value
* becomes zero, services are enabled. Please see
* <code>largeUpdateStart()</code> and <code>largeUpdateEnd()</code>.
*/
private int largeUpdates = 0; /**
* The service locator maintained by the workbench. These services are
* initialized during workbench during the <code>init</code> method.
*/
private final ServiceLocator serviceLocator; /**
* A count of how many plug-ins were loaded while restoring the workbench
* state. Initially -1 for unknown number.
*/
private int progressCount = -1; /**
* Listener list for registered IWorkbenchListeners .
*/
private ListenerList workbenchListeners = new ListenerList(ListenerList.IDENTITY); private ServiceRegistration workbenchService; private MApplication application; private IEclipseContext e4Context; private IEventBroker eventBroker; boolean initializationDone = false; private WorkbenchWindow windowBeingCreated = null; /**
* Creates a new workbench.
*
* @param display
* the display to be used for all UI interactions with the
* workbench
* @param advisor
* the application-specific advisor that configures and
* specializes this workbench instance
* @since 3.0
*/
private Workbench(Display display, final WorkbenchAdvisor advisor, MApplication app,
IEclipseContext appContext) {
super();
StartupThreading.setWorkbench(this);
if (instance != null && instance.isRunning()) {
throw new IllegalStateException(WorkbenchMessages.Workbench_CreatingWorkbenchTwice);
}
Assert.isNotNull(display);
Assert.isNotNull(advisor);
this.advisor = advisor;
this.display = display;
application = app;
e4Context = appContext;
Workbench.instance = this;
eventBroker = (IEventBroker) e4Context.get(IEventBroker.class.getName()); appContext.set(getClass().getName(), this);
appContext.set(IWorkbench.class.getName(), this);
appContext.set(IEventLoopAdvisor.class, new IEventLoopAdvisor() {
public void eventLoopIdle(Display display) {
advisor.eventLoopIdle(display);
} public void eventLoopException(Throwable exception) {
advisor.eventLoopException(exception);
}
}); // for dynamic UI [This seems to be for everything that isn't handled by
// some
// subclass of RegistryManager. I think that when an extension is moved
// to the
// RegistryManager implementation, then it should be removed from the
// list in
// ExtensionEventHandler#appear.
// I've found that the new wizard extension in particular is a poor
// choice to
// use as an example, since the result of reading the registry is not
// cached
// -- so it is re-read each time. The only real contribution of this
// dialog is
// to show the user a nice dialog describing the addition.]
extensionEventHandler = new ExtensionEventHandler(this);
Platform.getExtensionRegistry().addRegistryChangeListener(extensionEventHandler);
IServiceLocatorCreator slc = new ServiceLocatorCreator();
serviceLocator = (ServiceLocator) slc.createServiceLocator(null, null, new IDisposable() {
public void dispose() {
final Display display = getDisplay();
if (display != null && !display.isDisposed()) {
MessageDialog.openInformation(null,
WorkbenchMessages.Workbench_NeedsClose_Title,
WorkbenchMessages.Workbench_NeedsClose_Message);
close(PlatformUI.RETURN_RESTART, true);
}
}
});
serviceLocator.setContext(appContext);
serviceLocator.registerService(IServiceLocatorCreator.class, slc);
serviceLocator.registerService(IWorkbenchLocationService.class,
new WorkbenchLocationService(IServiceScopes.WORKBENCH_SCOPE, this, null, null,
null, null, 0)); } /**
* Returns the one and only instance of the workbench, if there is one.
*
* @return the workbench, or <code>null</code> if the workbench has not been
* created, or has been created and already completed
*/
public static final Workbench getInstance() {
return instance;
} /**
* Creates the workbench and associates it with the the given display and
* workbench advisor, and runs the workbench UI. This entails processing and
* dispatching events until the workbench is closed or restarted.
* <p>
* This method is intended to be called by <code>PlatformUI</code>. Fails if
* the workbench UI has already been created.
* </p>
* <p>
* The display passed in must be the default display.
* </p>
*
* @param display
* the display to be used for all UI interactions with the
* workbench
* @param advisor
* the application-specific advisor that configures and
* specializes the workbench
* @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
* exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
* workbench was terminated with a call to
* {@link IWorkbench#restart IWorkbench.restart}; other values
* reserved for future use
*/
public static final int createAndRunWorkbench(final Display display,
final WorkbenchAdvisor advisor) {
final int[] returnCode = new int[1];
Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
public void run() {
final String nlExtensions = Platform.getNLExtensions();
if (nlExtensions.length() > 0) {
ULocale.setDefault(Category.FORMAT,
new ULocale(ULocale.getDefault(Category.FORMAT).getBaseName()
+ nlExtensions));
} System.setProperty(E4Workbench.XMI_URI_ARG,
"org.eclipse.ui.workbench/LegacyIDE.e4xmi"); //$NON-NLS-1$
Object obj = getApplication(Platform.getCommandLineArgs());
if (obj instanceof E4Application) {
E4Application e4app = (E4Application) obj;
E4Workbench e4Workbench = e4app.createE4Workbench(getApplicationContext(),
display);
IEclipseContext workbenchContext = e4Workbench.getContext();
workbenchContext.set(Display.class, display); // create the workbench instance
Workbench workbench = new Workbench(display, advisor, e4Workbench
.getApplication(), e4Workbench.getContext()); // prime the splash nice and early
if (createSplash)
workbench.createSplashWrapper(); AbstractSplashHandler handler = getSplash(); IProgressMonitor progressMonitor = null;
if (handler != null) {
progressMonitor = handler.getBundleProgressMonitor();
if (progressMonitor != null) {
double cutoff = 0.95;
int expectedProgressCount = Math.max(1, WorkbenchPlugin.getDefault()
.getBundleCount() / 10);
progressMonitor.beginTask("", expectedProgressCount); //$NON-NLS-1$
SynchronousBundleListener bundleListener = workbench.new StartupProgressBundleListener(
progressMonitor, (int) (expectedProgressCount * cutoff));
WorkbenchPlugin.getDefault().addBundleListener(bundleListener);
}
}
// run the legacy workbench once
returnCode[0] = workbench.runUI();
// run the e4 event loop and instantiate ... well, stuff
e4Workbench.createAndRunUI(e4Workbench.getApplication());
WorkbenchMenuService wms = (WorkbenchMenuService) e4Workbench.getContext().get(
IMenuService.class);
wms.dispose();
e4app.saveModel();
e4Workbench.close();
returnCode[0] = workbench.returnCode;
}
}
});
return returnCode[0];
} private static ServiceTracker instanceAppContext; static IApplicationContext getApplicationContext() {
if (instanceAppContext == null) {
instanceAppContext = new ServiceTracker(
WorkbenchPlugin.getDefault().getBundleContext(), IApplicationContext.class
.getName(), null);
instanceAppContext.open();
}
return (IApplicationContext) instanceAppContext.getService();
} static Object getApplication(String[] args) {
// Find the name of the application as specified by the PDE JUnit
// launcher.
// If no application is specified, the 3.0 default workbench application
// is returned.
IExtension extension = Platform.getExtensionRegistry().getExtension(Platform.PI_RUNTIME,
Platform.PT_APPLICATIONS, "org.eclipse.e4.ui.workbench.swt.E4Application"); //$NON-NLS-1$ Assert.isNotNull(extension); // If the extension does not have the correct grammar, return null.
// Otherwise, return the application object.
try {
IConfigurationElement[] elements = extension.getConfigurationElements();
if (elements.length > 0) {
IConfigurationElement[] runs = elements[0].getChildren("run"); //$NON-NLS-1$
if (runs.length > 0) {
Object runnable;
runnable = runs[0].createExecutableExtension("class");//$NON-NLS-1$
if (runnable instanceof IPlatformRunnable || runnable instanceof IApplication)
return runnable;
}
}
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} /**
* Creates the <code>Display</code> to be used by the workbench.
*
* @return the display
*/
public static Display createDisplay() {
// setup the application name used by SWT to lookup resources on some
// platforms
String applicationName = WorkbenchPlugin.getDefault().getAppName();
if (applicationName != null) {
Display.setAppName(applicationName);
} // create the display
Display newDisplay = Display.getCurrent();
if (newDisplay == null) {
if (Policy.DEBUG_SWT_GRAPHICS || Policy.DEBUG_SWT_DEBUG) {
DeviceData data = new DeviceData();
if (Policy.DEBUG_SWT_GRAPHICS) {
data.tracking = true;
}
if (Policy.DEBUG_SWT_DEBUG) {
data.debug = true;
}
newDisplay = new Display(data);
} else {
newDisplay = new Display();
}
} // workaround for 1GEZ9UR and 1GF07HN
newDisplay.setWarnings(false); // Set the priority higher than normal so as to be higher
// than the JobManager.
Thread.currentThread().setPriority(Math.min(Thread.MAX_PRIORITY, Thread.NORM_PRIORITY + 1)); initializeImages(); return newDisplay;
} /**
* Create the splash wrapper and set it to work.
*
* @since 3.3
*/
private void createSplashWrapper() {
final Display display = getDisplay();
String splashLoc = System.getProperty("org.eclipse.equinox.launcher.splash.location"); //$NON-NLS-1$
final Image background = loadImage(splashLoc); SafeRunnable run = new SafeRunnable() { public void run() throws Exception {
if (!WorkbenchPlugin.isSplashHandleSpecified()) {
createSplash = false;
return;
} // create the splash
getSplash();
if (splash == null) {
createSplash = false;
return;
} Shell splashShell = splash.getSplash();
if (splashShell == null) {
splashShell = WorkbenchPlugin.getSplashShell(display); if (splashShell == null)
return;
if (background != null)
splashShell.setBackgroundImage(background);
} Dictionary properties = new Hashtable();
properties.put(Constants.SERVICE_RANKING, new Integer(Integer.MAX_VALUE));
BundleContext context = WorkbenchPlugin.getDefault().getBundleContext();
final ServiceRegistration registration[] = new ServiceRegistration[1];
StartupMonitor startupMonitor = new StartupMonitor() { public void applicationRunning() {
// splash.dispose();
if (background != null)
background.dispose();
registration[0].unregister(); // unregister ourself
WorkbenchPlugin.unsetSplashShell(display); // fire part visibility events now that we're up
for (IWorkbenchWindow window : getWorkbenchWindows()) {
IWorkbenchPage page = window.getActivePage();
if (page != null) {
((WorkbenchPage) page).fireInitialPartVisibilityEvents();
}
}
} public void update() {
// do nothing - we come into the picture far too late
// for this to be relevant
}
};
registration[0] = context.registerService(StartupMonitor.class.getName(),
startupMonitor, properties); splash.init(splashShell);
} /*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.util.SafeRunnable#handleException(java.lang
* .Throwable)
*/
public void handleException(Throwable e) {
StatusManager.getManager().handle(
StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
"Could not instantiate splash", e)); //$NON-NLS-1$
createSplash = false;
splash = null;
if (background != null)
background.dispose(); }
};
SafeRunner.run(run);
} /**
* Load an image from a filesystem path.
*
* @param splashLoc
* the location to load from
* @return the image or <code>null</code>
* @since 3.3
*/
private Image loadImage(String splashLoc) {
Image background = null;
if (splashLoc != null) {
InputStream input = null;
try {
input = new BufferedInputStream(new FileInputStream(splashLoc));
background = new Image(display, input);
} catch (SWTException e) {
StatusManager.getManager().handle(
StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
} catch (IOException e) {
StatusManager.getManager().handle(
StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
// he's done for
}
}
}
}
return background;
} /**
* Return the splash handler for this application. If none is specifically
* provided the default Eclipse implementation is returned.
*
* @return the splash handler for this application or <code>null</code>
* @since 3.3
*/
private static AbstractSplashHandler getSplash() {
if (!createSplash)
return null; if (splash == null) { IProduct product = Platform.getProduct();
if (product != null)
splash = SplashHandlerFactory.findSplashHandlerFor(product); if (splash == null)
splash = new EclipseSplashHandler();
}
return splash;
} /**
* Returns the testable object facade, for use by the test harness.
*
* @return the testable object facade
* @since 3.0
*/
public static WorkbenchTestable getWorkbenchTestable() {
if (testableObject == null) {
testableObject = new WorkbenchTestable();
}
return testableObject;
} /*
* (non-Javadoc) Method declared on IWorkbench.
*
* @since 3.2
*/
public void addWorkbenchListener(IWorkbenchListener listener) {
workbenchListeners.add(listener);
} /*
* (non-Javadoc) Method declared on IWorkbench.
*
* @since 3.2
*/
public void removeWorkbenchListener(IWorkbenchListener listener) {
workbenchListeners.remove(listener);
} /**
* Fire workbench preShutdown event, stopping at the first one to veto
*
* @param forced
* flag indicating whether the shutdown is being forced
* @return <code>true</code> to allow the workbench to proceed with
* shutdown, <code>false</code> to veto a non-forced shutdown
* @since 3.2
*/
boolean firePreShutdown(final boolean forced) {
Object list[] = workbenchListeners.getListeners();
for (int i = 0; i < list.length; i++) {
final IWorkbenchListener l = (IWorkbenchListener) list[i];
final boolean[] result = new boolean[] { false };
SafeRunnable.run(new SafeRunnable() {
public void run() {
result[0] = l.preShutdown(Workbench.this, forced);
}
});
if (!result[0]) {
return false;
}
}
return true;
} /**
* Fire workbench postShutdown event.
*
* @since 3.2
*/
void firePostShutdown() {
Object list[] = workbenchListeners.getListeners();
for (int i = 0; i < list.length; i++) {
final IWorkbenchListener l = (IWorkbenchListener) list[i];
SafeRunnable.run(new SafeRunnable() {
public void run() {
l.postShutdown(Workbench.this);
}
});
}
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public void addWindowListener(IWindowListener l) {
addListenerObject(l);
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public void removeWindowListener(IWindowListener l) {
removeListenerObject(l);
} /**
* Fire window opened event.
*
* @param window
* The window which just opened; should not be <code>null</code>.
*/
protected void fireWindowOpened(final IWorkbenchWindow window) {
Object list[] = getListeners();
for (int i = 0; i < list.length; i++) {
final IWindowListener l = (IWindowListener) list[i];
SafeRunner.run(new SafeRunnable() {
public void run() {
l.windowOpened(window);
}
});
}
} /**
* Fire window closed event.
*
* @param window
* The window which just closed; should not be <code>null</code>.
*/
protected void fireWindowClosed(final IWorkbenchWindow window) {
Object list[] = getListeners();
for (int i = 0; i < list.length; i++) {
final IWindowListener l = (IWindowListener) list[i];
SafeRunner.run(new SafeRunnable() {
public void run() {
l.windowClosed(window);
}
});
}
} /**
* Fire window activated event.
*
* @param window
* The window which was just activated; should not be
* <code>null</code>.
*/
protected void fireWindowActivated(final IWorkbenchWindow window) {
Object list[] = getListeners();
for (int i = 0; i < list.length; i++) {
final IWindowListener l = (IWindowListener) list[i];
SafeRunner.run(new SafeRunnable() {
public void run() {
l.windowActivated(window);
}
});
}
} /**
* Fire window deactivated event.
*
* @param window
* The window which was just deactivated; should not be
* <code>null</code>.
*/
protected void fireWindowDeactivated(final IWorkbenchWindow window) {
Object list[] = getListeners();
for (int i = 0; i < list.length; i++) {
final IWindowListener l = (IWindowListener) list[i];
SafeRunner.run(new SafeRunnable() {
public void run() {
l.windowDeactivated(window);
}
});
}
} /**
* Closes the workbench. Assumes that the busy cursor is active.
*
* @param force
* true if the close is mandatory, and false if the close is
* allowed to fail
* @return true if the close succeeded, and false otherwise
*/
private boolean busyClose(final boolean force) { // notify the advisor of preShutdown and allow it to veto if not forced
isClosing = advisor.preShutdown();
if (!force && !isClosing) {
return false;
} // notify regular workbench clients of preShutdown and allow them to
// veto if not forced
isClosing = firePreShutdown(force);
if (!force && !isClosing) {
return false;
} // save any open editors if they are dirty
isClosing = saveAllEditors(!force, true);
if (!force && !isClosing) {
return false;
} boolean closeEditors = !force
&& PrefUtil.getAPIPreferenceStore().getBoolean(
IWorkbenchPreferenceConstants.CLOSE_EDITORS_ON_EXIT);
if (closeEditors) {
SafeRunner.run(new SafeRunnable() {
public void run() {
IWorkbenchWindow windows[] = getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
IWorkbenchPage pages[] = windows[i].getPages();
for (int j = 0; j < pages.length; j++) {
isClosing = isClosing && pages[j].closeAllEditors(false);
}
}
}
});
if (!force && !isClosing) {
return false;
}
} // discard editors that with non-ppersistable inputs
SafeRunner.run(new SafeRunnable() {
public void run() {
IWorkbenchWindow windows[] = getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
IWorkbenchPage pages[] = windows[i].getPages();
for (int j = 0; j < pages.length; j++) {
List<EditorReference> editorReferences = ((WorkbenchPage) pages[j])
.getInternalEditorReferences();
List<EditorReference> referencesToClose = new ArrayList<EditorReference>();
for (EditorReference reference : editorReferences) {
IEditorPart editor = reference.getEditor(false);
if (editor != null && !reference.persist()) {
referencesToClose.add(reference);
}
} for (EditorReference reference : referencesToClose) {
((WorkbenchPage) pages[j]).closeEditor(reference);
}
}
}
}
}); // persist view states
SafeRunner.run(new SafeRunnable() {
public void run() {
IWorkbenchWindow windows[] = getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
IWorkbenchPage pages[] = windows[i].getPages();
for (int j = 0; j < pages.length; j++) {
IViewReference[] references = pages[j].getViewReferences();
for (int k = 0; k < references.length; k++) {
if (references[k].getView(false) != null) {
((ViewReference) references[k]).persist();
}
}
}
}
}
}); if (!force && !isClosing) {
return false;
} SafeRunner.run(new SafeRunnable(WorkbenchMessages.ErrorClosing) {
public void run() {
if (isClosing || force) {
// isClosing = windowManager.close();
E4Util.unsupported("Need to close since no windowManager"); //$NON-NLS-1$
MWindow selectedWindow = application.getSelectedElement();
WorkbenchWindow selected = null;
for (IWorkbenchWindow window : getWorkbenchWindows()) {
WorkbenchWindow ww = (WorkbenchWindow) window;
if (ww.getModel() == selectedWindow) {
selected = ww;
} else {
((WorkbenchWindow) window).close(false);
}
} if (selected != null) {
selected.close(false);
} windowsClosed = true;
}
}
}); if (!force && !isClosing) {
return false;
} shutdown(); IPresentationEngine engine = application.getContext().get(IPresentationEngine.class);
engine.stop();
//System.err.println("stop()"); //$NON-NLS-1$ runEventLoop = false;
return true;
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#saveAllEditors(boolean)
*/
public boolean saveAllEditors(boolean confirm) {
return saveAllEditors(confirm, false);
} private boolean saveAllEditors(boolean confirm, boolean closing) {
for (IWorkbenchWindow window : getWorkbenchWindows()) {
IWorkbenchPage page = window.getActivePage();
if (page != null) {
if (!((WorkbenchPage) page).saveAllEditors(confirm, closing)) {
return false;
}
}
}
return true;
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public boolean close() {
return close(PlatformUI.RETURN_OK, false);
} /**
* Closes the workbench, returning the given return code from the run
* method. If forced, the workbench is closed no matter what.
*
* @param returnCode
* {@link PlatformUI#RETURN_OK RETURN_OK}for normal exit;
* {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
* workbench was terminated with a call to
* {@link IWorkbench#restart IWorkbench.restart};
* {@link PlatformUI#RETURN_EMERGENCY_CLOSE} for an emergency
* shutdown {@link PlatformUI#RETURN_UNSTARTABLE
* RETURN_UNSTARTABLE}if the workbench could not be started;
* other values reserved for future use
*
* @param force
* true to force the workbench close, and false for a "soft"
* close that can be canceled
* @return true if the close was successful, and false if the close was
* canceled
*/
/* package */
boolean close(int returnCode, final boolean force) {
this.returnCode = returnCode;
final boolean[] ret = new boolean[1];
BusyIndicator.showWhile(null, new Runnable() {
public void run() {
ret[0] = busyClose(force);
}
});
return ret[0];
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchWindow getActiveWorkbenchWindow() {
// Return null if called from a non-UI thread.
// This is not spec'ed behaviour and is misleading, however this is how
// it
// worked in 2.1 and we cannot change it now.
// For more details, see [Bug 57384] [RCP] Main window not active on
// startup
if (Display.getCurrent() == null || !initializationDone) {
return null;
} // the source providers try to update again during shutdown
if (windowsClosed) {
return null;
} // rendering engine not available, can't make workbench windows, see bug
//
if (e4Context.get(IPresentationEngine.class) == null) {
return null;
} MWindow activeWindow = application.getSelectedElement();
if (activeWindow == null && !application.getChildren().isEmpty()) {
activeWindow = application.getChildren().get(0);
} // We can't return a window with no widget...it's in the process
// of closing...see Bug 379717
if (activeWindow != null && activeWindow.getWidget() == null) {
return null;
} return createWorkbenchWindow(getDefaultPageInput(), getPerspectiveRegistry()
.findPerspectiveWithId(getPerspectiveRegistry().getDefaultPerspective()),
activeWindow, false);
} IWorkbenchWindow createWorkbenchWindow(IAdaptable input, IPerspectiveDescriptor descriptor,
MWindow window, boolean newWindow) {
IEclipseContext windowContext = window.getContext();
if (windowContext == null) {
windowContext = E4Workbench.initializeContext(
e4Context, window);
E4Workbench.processHierarchy(window);
}
WorkbenchWindow result = (WorkbenchWindow) windowContext.get(IWorkbenchWindow.class
.getName());
if (result == null) {
if (windowBeingCreated != null)
return windowBeingCreated;
result = new WorkbenchWindow(input, descriptor);
windowBeingCreated = result;
try {
if (newWindow) {
Point size = result.getWindowConfigurer().getInitialSize();
window.setWidth(size.x);
window.setHeight(size.y);
application.getChildren().add(window);
application.setSelectedElement(window);
}
ContextInjectionFactory.inject(result, windowContext);
windowContext.set(IWorkbenchWindow.class.getName(), result);
} finally {
windowBeingCreated = null;
} if (application.getSelectedElement() == window) {
application.getContext().set(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, result);
application.getContext().set(ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME, result.getShell());
} fireWindowOpened(result);
result.fireWindowOpened();
}
return result;
} /*
* Returns the editor history.
*/
public EditorHistory getEditorHistory() {
if (editorHistory == null) {
editorHistory = new EditorHistory();
}
return editorHistory;
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IEditorRegistry getEditorRegistry() {
return WorkbenchPlugin.getDefault().getEditorRegistry();
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchOperationSupport getOperationSupport() {
return WorkbenchPlugin.getDefault().getOperationSupport();
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IPerspectiveRegistry getPerspectiveRegistry() {
return WorkbenchPlugin.getDefault().getPerspectiveRegistry();
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public PreferenceManager getPreferenceManager() {
return WorkbenchPlugin.getDefault().getPreferenceManager();
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IPreferenceStore getPreferenceStore() {
return WorkbenchPlugin.getDefault().getPreferenceStore();
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public ISharedImages getSharedImages() {
return WorkbenchPlugin.getDefault().getSharedImages();
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public int getWorkbenchWindowCount() {
return getWorkbenchWindows().length;
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchWindow[] getWorkbenchWindows() {
List<IWorkbenchWindow> windows = new ArrayList<IWorkbenchWindow>();
for (MWindow window : application.getChildren()) {
IEclipseContext context = window.getContext();
if (context != null) {
IWorkbenchWindow wwindow = (IWorkbenchWindow) context.get(IWorkbenchWindow.class
.getName());
if (wwindow != null) {
windows.add(wwindow);
}
}
}
return windows.toArray(new IWorkbenchWindow[windows.size()]);
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkingSetManager getWorkingSetManager() {
return WorkbenchPlugin.getDefault().getWorkingSetManager();
} /**
* {@inheritDoc}
*/
public ILocalWorkingSetManager createLocalWorkingSetManager() {
return new LocalWorkingSetManager(WorkbenchPlugin.getDefault().getBundleContext());
} /**
* Initializes the workbench now that the display is created.
*
* @return true if init succeeded.
*/
private boolean init() {
// setup debug mode if required.
if (WorkbenchPlugin.getDefault().isDebugging()) {
WorkbenchPlugin.DEBUG = true;
ModalContext.setDebugMode(true);
} // Set up the JFace preference store
JFaceUtil.initializeJFacePreferences(); // create workbench window manager
// windowManager = new WindowManager();
// TODO compat: I've removed the window manager, now what // TODO Correctly order service initialization
// there needs to be some serious consideration given to
// the services, and hooking them up in the correct order
e4Context.set("org.eclipse.core.runtime.Platform", Platform.class); //$NON-NLS-1$
final EvaluationService evaluationService = new EvaluationService(e4Context); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
serviceLocator.registerService(IEvaluationService.class, evaluationService);
}
}); initializeLazyServices(); // Initialize the activity support. activityHelper = ActivityPersistanceHelper.getInstance();
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
WorkbenchImages.getImageRegistry();
}
});
initializeE4Services();
initializeDefaultServices();
initializeFonts();
initializeColors();
initializeApplicationColors(); IIntroRegistry introRegistry = WorkbenchPlugin.getDefault().getIntroRegistry();
if (introRegistry.getIntroCount() > 0) {
IProduct product = Platform.getProduct();
if (product != null) {
introDescriptor = (IntroDescriptor) introRegistry.getIntroForProduct(product
.getId());
}
} // now that the workbench is sufficiently initialized, let the advisor
// have a turn.
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
advisor.internalBasicInitialize(getWorkbenchConfigurer());
}
}); // configure use of color icons in toolbars
boolean useColorIcons = PrefUtil.getInternalPreferenceStore().getBoolean(
IPreferenceConstants.COLOR_ICONS);
ActionContributionItem.setUseColorIconsInToolbars(useColorIcons); // initialize workbench single-click vs double-click behavior
initializeSingleClickOption(); initializeWorkbenchImages(); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
((GrabFocus) Tweaklets.get(GrabFocus.KEY)).init(getDisplay());
}
}); // attempt to restore a previous workbench state
try {
UIStats.start(UIStats.RESTORE_WORKBENCH, "Workbench"); //$NON-NLS-1$ final boolean bail[] = new boolean[1];
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable {
advisor.preStartup();
// TODO compat: open the windows here/instantiate the model
// TODO compat: instantiate the WW around the model
initializationDone = true;
// if (isClosing() || !advisor.openWindows()) {
if (isClosing()) {
bail[0] = true;
}
}
}); if (bail[0])
return false; } finally {
UIStats.end(UIStats.RESTORE_WORKBENCH, this, "Workbench"); //$NON-NLS-1$
} // forceOpenPerspective(); return true;
} /**
*
*/
private void initializeWorkbenchImages() {
StartupThreading.runWithoutExceptions(new StartupRunnable() {
public void runWithException() {
WorkbenchImages.getDescriptors();
}
});
} /**
* Establishes the relationship between JFace actions and the command
* manager.
*/
private void initializeCommandResolver() {
ExternalActionManager.getInstance().setCallback(
new CommandCallback(bindingManager, commandManager, new IActiveChecker() {
public final boolean isActive(final String commandId) {
return workbenchActivitySupport.getActivityManager().getIdentifier(
commandId).isEnabled();
}
}, new IExecuteApplicable() {
public boolean isApplicable(IAction action) {
return !(action instanceof CommandAction);
}
}));
} /**
* Initialize colors defined by the new colorDefinitions extension point.
* Note this will be rolled into initializeColors() at some point.
*
* @since 3.0
*/
private void initializeApplicationColors() {
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
ColorDefinition[] colorDefinitions = WorkbenchPlugin.getDefault()
.getThemeRegistry().getColors();
ThemeElementHelper.populateRegistry(getThemeManager().getTheme(
IThemeManager.DEFAULT_THEME), colorDefinitions, PrefUtil
.getInternalPreferenceStore());
}
});
} private void initializeSingleClickOption() {
IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
boolean openOnSingleClick = store.getBoolean(IPreferenceConstants.OPEN_ON_SINGLE_CLICK);
boolean selectOnHover = store.getBoolean(IPreferenceConstants.SELECT_ON_HOVER);
boolean openAfterDelay = store.getBoolean(IPreferenceConstants.OPEN_AFTER_DELAY);
int singleClickMethod = openOnSingleClick ? OpenStrategy.SINGLE_CLICK
: OpenStrategy.DOUBLE_CLICK;
if (openOnSingleClick) {
if (selectOnHover) {
singleClickMethod |= OpenStrategy.SELECT_ON_HOVER;
}
if (openAfterDelay) {
singleClickMethod |= OpenStrategy.ARROW_KEYS_OPEN;
}
}
OpenStrategy.setOpenMethod(singleClickMethod);
} /*
* Initializes the workbench fonts with the stored values.
*/
private void initializeFonts() {
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
FontDefinition[] fontDefinitions = WorkbenchPlugin.getDefault().getThemeRegistry()
.getFonts(); ThemeElementHelper.populateRegistry(getThemeManager().getCurrentTheme(),
fontDefinitions, PrefUtil.getInternalPreferenceStore());
}
});
} /*
* Initialize the workbench images.
*
* @param windowImages An array of the descriptors of the images to be used
* in the corner of each window, or <code>null</code> if none. It is
* expected that the array will contain the same icon, rendered at different
* sizes.
*
* @since 3.0
*/
private static void initializeImages() {
ImageDescriptor[] windowImages = WorkbenchPlugin.getDefault().getWindowImages();
if (windowImages == null) {
return;
} Image[] images = new Image[windowImages.length];
for (int i = 0; i < windowImages.length; ++i) {
images[i] = windowImages[i].createImage();
}
Window.setDefaultImages(images);
} /*
* Take the workbenches' images out of the shared registry.
*
* @since 3.0
*/
private void uninitializeImages() {
WorkbenchImages.dispose();
Image[] images = Window.getDefaultImages();
Window.setDefaultImage(null);
for (int i = 0; i < images.length; i++) {
images[i].dispose();
}
} /*
* Initialize the workbench colors.
*
* @since 3.0
*/
private void initializeColors() {
StartupThreading.runWithoutExceptions(new StartupRunnable() {
public void runWithException() {
WorkbenchColors.startup();
}
});
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public boolean isClosing() {
return isClosing;
} private final void initializeE4Services() {
// track the workbench preference and update the eclipse context with
// the new value
IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
preferenceStore.addPropertyChangeListener(new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS.equals(event.getProperty())) {
e4Context.set(IPresentationEngine.ANIMATIONS_ENABLED, event.getNewValue());
}
}
}); eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_CHILDREN, new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
if (application == event.getProperty(UIEvents.EventTags.ELEMENT)) {
if (UIEvents.EventTypes.REMOVE.equals(event
.getProperty(UIEvents.EventTags.TYPE))) {
MWindow window = (MWindow) event.getProperty(UIEvents.EventTags.OLD_VALUE);
IEclipseContext windowContext = window.getContext();
if (windowContext != null) {
IWorkbenchWindow wwindow = (IWorkbenchWindow) windowContext
.get(IWorkbenchWindow.class.getName());
if (wwindow != null) {
fireWindowClosed(wwindow);
}
}
}
}
}
});
eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT, new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
if (application == event.getProperty(UIEvents.EventTags.ELEMENT)) {
if (UIEvents.EventTypes.SET.equals(event
.getProperty(UIEvents.EventTags.TYPE))) {
MWindow window = (MWindow) event.getProperty(UIEvents.EventTags.NEW_VALUE);
if (window != null) {
IWorkbenchWindow wwindow = (IWorkbenchWindow) window.getContext().get(
IWorkbenchWindow.class.getName());
if (wwindow != null) {
e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, wwindow);
e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
wwindow.getShell());
}
}
}
}
}
}); // watch for parts' "toBeRendered" attribute being flipped to true, if
// they need to be rendered, then they need a corresponding 3.x
// reference
eventBroker.subscribe(
UIEvents.UIElement.TOPIC_TOBERENDERED, new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
if (Boolean.TRUE.equals(event.getProperty(UIEvents.EventTags.NEW_VALUE))) {
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (element instanceof MPart) {
MPart part = (MPart) element;
createReference(part);
}
}
}
}); // watch for parts' contexts being set, once they've been set, we need
// to inject the ViewReference/EditorReference into the context
eventBroker.subscribe(
UIEvents.Context.TOPIC_CONTEXT,
new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (element instanceof MPart) {
MPart part = (MPart) element;
IEclipseContext context = part.getContext();
if (context != null) {
setReference(part, context);
}
}
}
}); boolean found = false;
List<MPartDescriptor> currentDescriptors = application.getDescriptors();
for (MPartDescriptor desc : currentDescriptors) {
// do we have a matching descriptor?
if (desc.getElementId().equals(CompatibilityEditor.MODEL_ELEMENT_ID)) {
found = true;
break;
}
}
if (!found) {
MPartDescriptor descriptor = org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicFactoryImpl.eINSTANCE
.createPartDescriptor();
descriptor.getTags().add("Editor"); //$NON-NLS-1$
descriptor.setCloseable(true);
descriptor.setAllowMultiple(true);
descriptor.setElementId(CompatibilityEditor.MODEL_ELEMENT_ID);
descriptor.setContributionURI(CompatibilityPart.COMPATIBILITY_EDITOR_URI);
descriptor.setCategory("org.eclipse.e4.primaryDataStack"); //$NON-NLS-1$
application.getDescriptors().add(descriptor);
} WorkbenchPlugin.getDefault().getViewRegistry();
} /**
* Returns a workbench page that will contain the specified part. If no page
* can be located, one will be instantiated.
*
* @param part
* the model part to query a parent workbench page for
* @return the workbench page that contains the specified part
*/
private WorkbenchPage getWorkbenchPage(MPart part) {
IEclipseContext context = getWindowContext(part);
WorkbenchPage page = (WorkbenchPage) context.get(IWorkbenchPage.class.getName());
if (page == null) {
MWindow window = (MWindow) context.get(MWindow.class.getName());
Workbench workbench = (Workbench) PlatformUI.getWorkbench();
workbench.openWorkbenchWindow(getDefaultPageInput(), getPerspectiveRegistry()
.findPerspectiveWithId(getDefaultPerspectiveId()),
window, false);
page = (WorkbenchPage) context.get(IWorkbenchPage.class.getName());
}
return page;
} /**
* Sets the 3.x reference of the specified part into its context.
*
* @param part
* the model part that requires a 3.x part reference
* @param context
* the part's context
*/
private void setReference(MPart part, IEclipseContext context) {
String uri = part.getContributionURI();
if (CompatibilityPart.COMPATIBILITY_VIEW_URI.equals(uri)) {
WorkbenchPage page = getWorkbenchPage(part);
ViewReference ref = page.getViewReference(part);
if (ref == null) {
ref = createViewReference(part, page);
}
context.set(ViewReference.class.getName(), ref);
} else if (CompatibilityPart.COMPATIBILITY_EDITOR_URI.equals(uri)) {
WorkbenchPage page = getWorkbenchPage(part);
EditorReference ref = page.getEditorReference(part);
if (ref == null) {
ref = createEditorReference(part, page);
}
context.set(EditorReference.class.getName(), ref);
}
} private ViewReference createViewReference(MPart part, WorkbenchPage page) {
WorkbenchWindow window = (WorkbenchWindow) page.getWorkbenchWindow();
IViewDescriptor desc = window.getWorkbench().getViewRegistry().find(part.getElementId());
ViewReference ref = new ViewReference(window.getModel().getContext(), page, part,
(ViewDescriptor) desc);
page.addViewReference(ref);
return ref;
} private EditorReference createEditorReference(MPart part, WorkbenchPage page) {
WorkbenchWindow window = (WorkbenchWindow) page.getWorkbenchWindow();
EditorReference ref = new EditorReference(window.getModel().getContext(), page, part, null,
null, null);
page.addEditorReference(ref);
return ref;
} /**
* Creates a workbench part reference for the specified part if one does not
* already exist.
*
* @param part
* the model part to create a 3.x part reference for
*/
private void createReference(MPart part) {
String uri = part.getContributionURI();
if (CompatibilityPart.COMPATIBILITY_VIEW_URI.equals(uri)) {
WorkbenchPage page = getWorkbenchPage(part);
ViewReference ref = page.getViewReference(part);
if (ref == null) {
createViewReference(part, page);
}
} else if (CompatibilityPart.COMPATIBILITY_EDITOR_URI.equals(uri)) {
WorkbenchPage page = getWorkbenchPage(part);
EditorReference ref = page.getEditorReference(part);
if (ref == null) {
createEditorReference(part, page);
}
}
} private IEclipseContext getWindowContext(MPart part) {
MElementContainer<?> parent = (MElementContainer<?>) ((EObject) part).eContainer();
while (!(parent instanceof MWindow)) {
parent = (MElementContainer<?>) ((EObject) parent).eContainer(); // parent.getParent();
} return ((MWindow) parent).getContext();
} private final void initializeLazyServices() {
e4Context.set(IExtensionTracker.class.getName(), new ContextFunction() { public Object compute(IEclipseContext context) {
if (tracker == null) {
tracker = new UIExtensionTracker(getDisplay());
}
return tracker;
}
});
e4Context.set(IWorkbenchActivitySupport.class.getName(), new ContextFunction() { public Object compute(IEclipseContext context) {
if (workbenchActivitySupport == null) {
workbenchActivitySupport = new WorkbenchActivitySupport();
}
return workbenchActivitySupport;
}
});
e4Context.set(IProgressService.class.getName(), new ContextFunction() {
@Override
public Object compute(IEclipseContext context) {
return ProgressManager.getInstance();
}
});
WorkbenchPlugin.getDefault().initializeContext(e4Context);
} private ArrayList<MCommand> commandsToRemove = new ArrayList<MCommand>();
private ArrayList<MCategory> categoriesToRemove = new ArrayList<MCategory>(); private CommandService initializeCommandService(IEclipseContext appContext) {
CommandService service = new CommandService(commandManager, appContext);
appContext.set(ICommandService.class.getName(), service);
appContext.set(IUpdateService.class, service);
service.readRegistry(); Command[] cmds = commandManager.getAllCommands();
for (int i = 0; i < cmds.length; i++) {
Command cmd = cmds[i];
cmd.setHandler(new MakeHandlersGo(this, cmd.getId()));
} commandManager.addCommandManagerListener(new ICommandManagerListener() {
public void commandManagerChanged(CommandManagerEvent commandManagerEvent) {
if (commandManagerEvent.isCommandDefined()) {
Command cmd = commandManagerEvent.getCommandManager().getCommand(
commandManagerEvent.getCommandId());
cmd.setHandler(new MakeHandlersGo(Workbench.this, cmd.getId()));
}
}
});
return service;
} private Map<String, MBindingContext> bindingContexts = new HashMap<String, MBindingContext>(); public MBindingContext getBindingContext(String id) {
// cache
MBindingContext result = bindingContexts.get(id);
if (result == null) {
// search
result = searchContexts(id, application.getRootContext());
if (result == null) {
// create
result = MCommandsFactory.INSTANCE.createBindingContext();
result.setElementId(id);
result.setName("Auto::" + id); //$NON-NLS-1$
application.getRootContext().add(result);
}
if (result != null) {
bindingContexts.put(id, result);
}
}
return result;
} /**
* @param id
* @param rootContext
* @return
*/
private MBindingContext searchContexts(String id, List<MBindingContext> rootContext) {
for (MBindingContext context : rootContext) {
if (context.getElementId().equals(id)) {
return context;
}
MBindingContext result = searchContexts(id, context.getChildren());
if (result != null) {
return result;
}
}
return null;
}
private void defineBindingTable(String id) {
List<MBindingTable> bindingTables = application.getBindingTables();
if (contains(bindingTables, id)) {
return;
}
if (WorkbenchPlugin.getDefault().isDebugging()) {
WorkbenchPlugin.log("Defining a binding table: " + id); //$NON-NLS-1$
}
MBindingTable bt = CommandsFactoryImpl.eINSTANCE.createBindingTable();
bt.setBindingContext(getBindingContext(id));
bindingTables.add(bt);
} /**
* @param bindingTables
* @param id
* @return true if this BT already exists
*/
private boolean contains(List<MBindingTable> bindingTables, String id) {
for (MBindingTable bt : bindingTables) {
if (id.equals(bt.getBindingContext().getElementId())) {
return true;
}
}
return false;
} /**
* Initializes all of the default services for the workbench. For
* initializing the command-based services, this also parses the registry
* and hooks up all the required listeners.
*/
private final void initializeDefaultServices() { final IContributionService contributionService = new ContributionService(getAdvisor());
serviceLocator.registerService(IContributionService.class, contributionService); // TODO Correctly order service initialization
// there needs to be some serious consideration given to
// the services, and hooking them up in the correct order
final IEvaluationService evaluationService = (IEvaluationService) serviceLocator
.getService(IEvaluationService.class); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
serviceLocator.registerService(ISaveablesLifecycleListener.class,
new SaveablesList());
}
}); /*
* Phase 1 of the initialization of commands. When this phase completes,
* all the services and managers will exist, and be accessible via the
* getService(Object) method.
*/
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
Command.DEBUG_COMMAND_EXECUTION = Policy.DEBUG_COMMANDS;
commandManager = e4Context.get(CommandManager.class);
}
}); final CommandService[] commandService = new CommandService[1];
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
commandService[0] = initializeCommandService(e4Context); }
}); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
ContextManager.DEBUG = Policy.DEBUG_CONTEXTS;
contextManager = e4Context.get(ContextManager.class);
}
}); IContextService cxs = (IContextService) ContextInjectionFactory.make(ContextService.class,
e4Context); final IContextService contextService = cxs; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
contextManager.addContextManagerListener(new IContextManagerListener() {
public void contextManagerChanged(ContextManagerEvent contextManagerEvent) {
if (contextManagerEvent.isContextChanged()) {
String id = contextManagerEvent.getContextId();
if (id != null) {
defineBindingTable(id);
}
}
}
});
EContextService ecs = e4Context.get(EContextService.class);
ecs.activateContext(IContextService.CONTEXT_ID_DIALOG_AND_WINDOW);
}
}); serviceLocator.registerService(IContextService.class, contextService); final IBindingService[] bindingService = new BindingService[1]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
BindingManager.DEBUG = Policy.DEBUG_KEY_BINDINGS;
bindingManager = e4Context.get(BindingManager.class);
bindingService[0] = ContextInjectionFactory.make(
BindingService.class, e4Context);
}
}); // bindingService[0].readRegistryAndPreferences(commandService[0]);
serviceLocator.registerService(IBindingService.class, bindingService[0]); final CommandImageManager commandImageManager = new CommandImageManager();
final CommandImageService commandImageService = new CommandImageService(
commandImageManager, commandService[0]);
commandImageService.readRegistry();
serviceLocator.registerService(ICommandImageService.class, commandImageService); final WorkbenchMenuService menuService = new WorkbenchMenuService(serviceLocator, e4Context); serviceLocator.registerService(IMenuService.class, menuService);
// the service must be registered before it is initialized - its
// initialization uses the service locator to address a dependency on
// the menu service
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
menuService.readRegistry();
}
}); /*
* Phase 2 of the initialization of commands. The source providers that
* the workbench provides are creating and registered with the above
* services. These source providers notify the services when particular
* pieces of workbench state change.
*/
final SourceProviderService sourceProviderService = new SourceProviderService(
serviceLocator);
serviceLocator.registerService(ISourceProviderService.class, sourceProviderService);
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
// this currently instantiates all players ... sigh
sourceProviderService.readRegistry();
ISourceProvider[] sp = sourceProviderService.getSourceProviders();
for (int i = 0; i < sp.length; i++) {
evaluationService.addSourceProvider(sp[i]);
if (!(sp[i] instanceof ActiveContextSourceProvider)) {
contextService.addSourceProvider(sp[i]);
}
}
}
}); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
// these guys are need to provide the variables they say
// they source FocusControlSourceProvider focusControl = (FocusControlSourceProvider) sourceProviderService
.getSourceProvider(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME);
serviceLocator.registerService(IFocusService.class, focusControl); menuSourceProvider = (MenuSourceProvider) sourceProviderService
.getSourceProvider(ISources.ACTIVE_MENU_NAME);
}
}); /*
* Phase 3 of the initialization of commands. This handles the creation
* of wrappers for legacy APIs. By the time this phase completes, any
* code trying to access commands through legacy APIs should work.
*/
final IHandlerService[] handlerService = new IHandlerService[1];
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() {
handlerService[0] = new LegacyHandlerService(e4Context);
((LegacyHandlerService) handlerService[0]).initPreExecuteHook();
e4Context.set(IHandlerService.class.getName(), handlerService[0]);
handlerService[0].readRegistry();
}
});
workbenchContextSupport = new WorkbenchContextSupport(this, contextManager);
workbenchCommandSupport = new WorkbenchCommandSupport(bindingManager, commandManager,
contextManager, handlerService[0]);
initializeCommandResolver(); // addWindowListener(windowListener);
bindingManager.addBindingManagerListener(bindingManagerListener); serviceLocator.registerService(ISelectionConversionService.class,
new SelectionConversionService());
} /**
* Returns true if the Workbench is in the process of starting.
*
* @return <code>true</code> if the Workbench is starting, but not yet
* running the event loop.
*/
public boolean isStarting() {
return isStarting && isRunning();
} /*
* If a perspective was specified on the command line (-perspective) then
* force that perspective to open in the active window.
*/
void forceOpenPerspective() {
if (getWorkbenchWindowCount() == 0) {
// there should be an open window by now, bail out.
return;
} String perspId = null;
String[] commandLineArgs = Platform.getCommandLineArgs();
for (int i = 0; i < commandLineArgs.length - 1; i++) {
if (commandLineArgs[i].equalsIgnoreCase("-perspective")) { //$NON-NLS-1$
perspId = commandLineArgs[i + 1];
break;
}
}
if (perspId == null) {
return;
}
IPerspectiveDescriptor desc = getPerspectiveRegistry().findPerspectiveWithId(perspId);
if (desc == null) {
return;
} IWorkbenchWindow win = getActiveWorkbenchWindow();
if (win == null) {
win = getWorkbenchWindows()[0];
} final String threadPerspId = perspId;
final IWorkbenchWindow threadWin = win;
StartupThreading.runWithoutExceptions(new StartupRunnable() {
public void runWithException() throws Throwable {
try {
showPerspective(threadPerspId, threadWin);
} catch (WorkbenchException e) {
String msg = "Workbench exception showing specified command line perspective on startup."; //$NON-NLS-1$
WorkbenchPlugin.log(msg, new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
msg, e));
}
}
});
} /**
* Opens the initial workbench window.
*/
/* package */void openFirstTimeWindow() {
final boolean showProgress = PrefUtil.getAPIPreferenceStore().getBoolean(
IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP); if (!showProgress) {
doOpenFirstTimeWindow();
} else {
// We don't know how many plug-ins will be loaded,
// assume we are loading a tenth of the installed plug-ins.
// (The Eclipse SDK loads 7 of 86 plug-ins at startup as of
// 2005-5-20)
final int expectedProgressCount = Math.max(1, WorkbenchPlugin.getDefault()
.getBundleCount() / 10); runStartupWithProgress(expectedProgressCount, new Runnable() {
public void run() {
doOpenFirstTimeWindow();
}
});
}
} private void doOpenFirstTimeWindow() {
try {
final IAdaptable input[] = new IAdaptable[1];
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable {
input[0] = getDefaultPageInput();
}
}); openWorkbenchWindow(getDefaultPerspectiveId(), input[0]);
} catch (final WorkbenchException e) {
// Don't use the window's shell as the dialog parent,
// as the window is not open yet (bug 76724).
StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable {
ErrorDialog.openError(null, WorkbenchMessages.Problems_Opening_Page, e
.getMessage(), e.getStatus());
}
});
}
} private void runStartupWithProgress(final int expectedProgressCount, final Runnable runnable) {
progressCount = 0;
final double cutoff = 0.95; AbstractSplashHandler handler = getSplash();
IProgressMonitor progressMonitor = null;
if (handler != null)
progressMonitor = handler.getBundleProgressMonitor(); if (progressMonitor == null) {
// cannot report progress (e.g. if the splash screen is not showing)
// fall back to starting without showing progress.
runnable.run();
} else {
progressMonitor.beginTask("", expectedProgressCount); //$NON-NLS-1$
SynchronousBundleListener bundleListener = new StartupProgressBundleListener(
progressMonitor, (int) (expectedProgressCount * cutoff));
WorkbenchPlugin.getDefault().addBundleListener(bundleListener);
try {
runnable.run();
progressMonitor.subTask(WorkbenchMessages.Startup_Done);
int remainingWork = expectedProgressCount
- Math.min(progressCount, (int) (expectedProgressCount * cutoff));
progressMonitor.worked(remainingWork);
progressMonitor.done();
} finally {
WorkbenchPlugin.getDefault().removeBundleListener(bundleListener);
}
}
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchWindow openWorkbenchWindow(IAdaptable input) throws WorkbenchException {
return openWorkbenchWindow(getDefaultPerspectiveId(), input);
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchWindow openWorkbenchWindow(String perspectiveId, IAdaptable input)
throws WorkbenchException {
IPerspectiveDescriptor descriptor = getPerspectiveRegistry().findPerspectiveWithId(
perspectiveId);
try {
MWindow window = BasicFactoryImpl.eINSTANCE.createTrimmedWindow();
return openWorkbenchWindow(input, descriptor, window, true);
} catch (InjectionException e) {
throw new WorkbenchException(e.getMessage(), e);
}
} public WorkbenchWindow openWorkbenchWindow(IAdaptable input, IPerspectiveDescriptor descriptor,
MWindow window, boolean newWindow) {
return (WorkbenchWindow) createWorkbenchWindow(input, descriptor, window, newWindow);
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public boolean restart() {
return close(PlatformUI.RETURN_RESTART, false);
} /**
* Returns the ids of all plug-ins that extend the
* <code>org.eclipse.ui.startup</code> extension point.
*
* @return the ids of all plug-ins containing 1 or more startup extensions
*/
public String[] getEarlyActivatedPlugins() {
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(
PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_STARTUP);
IExtension[] extensions = point.getExtensions();
ArrayList pluginIds = new ArrayList(extensions.length);
for (int i = 0; i < extensions.length; i++) {
String id = extensions[i].getNamespace();
if (!pluginIds.contains(id)) {
pluginIds.add(id);
}
}
return (String[]) pluginIds.toArray(new String[pluginIds.size()]);
} /**
* Returns the ids of the early activated plug-ins that have been disabled
* by the user.
*
* @return the ids of the early activated plug-ins that have been disabled
* by the user
*/
public String[] getDisabledEarlyActivatedPlugins() {
String pref = PrefUtil.getInternalPreferenceStore().getString(
IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
return Util.getArrayFromList(pref, ";"); //$NON-NLS-1$
} /*
* Starts all plugins that extend the <code> org.eclipse.ui.startup </code>
* extension point, and that the user has not disabled via the preference
* page.
*/
private void startPlugins() {
IExtensionRegistry registry = Platform.getExtensionRegistry(); // bug 55901: don't use getConfigElements directly, for pre-3.0
// compat, make sure to allow both missing class
// attribute and a missing startup element
IExtensionPoint point = registry.getExtensionPoint(PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_STARTUP); final IExtension[] extensions = point.getExtensions();
if (extensions.length == 0) {
return;
}
Job job = new Job("Workbench early startup") { //$NON-NLS-1$
protected IStatus run(IProgressMonitor monitor) {
HashSet disabledPlugins = new HashSet(Arrays
.asList(getDisabledEarlyActivatedPlugins()));
monitor.beginTask(WorkbenchMessages.Workbench_startingPlugins, extensions.length);
for (int i = 0; i < extensions.length; ++i) {
if (monitor.isCanceled() || !isRunning()) {
return Status.CANCEL_STATUS;
}
IExtension extension = extensions[i]; // if the plugin is not in the set of disabled plugins, then
// execute the code to start it
if (!disabledPlugins.contains(extension.getNamespace())) {
monitor.subTask(extension.getNamespace());
SafeRunner.run(new EarlyStartupRunnable(extension));
}
monitor.worked(1);
}
monitor.done();
return Status.OK_STATUS;
} public boolean belongsTo(Object family) {
return EARLY_STARTUP_FAMILY.equals(family);
}
};
job.setSystem(true);
job.schedule();
} /**
* Internal method for running the workbench UI. This entails processing and
* dispatching events until the workbench is closed or restarted.
*
* @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
* exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
* workbench was terminated with a call to
* {@link IWorkbench#restart IWorkbench.restart};
* {@link PlatformUI#RETURN_UNSTARTABLE RETURN_UNSTARTABLE}if the
* workbench could not be started; other values reserved for future
* use
* @since 3.0
*/
private int runUI() {
UIStats.start(UIStats.START_WORKBENCH, "Workbench"); //$NON-NLS-1$ // deadlock code
boolean avoidDeadlock = true; String[] commandLineArgs = Platform.getCommandLineArgs();
for (int i = 0; i < commandLineArgs.length; i++) {
if (commandLineArgs[i].equalsIgnoreCase("-allowDeadlock")) { //$NON-NLS-1$
avoidDeadlock = false;
}
} final UISynchronizer synchronizer; if (avoidDeadlock) {
UILockListener uiLockListener = new UILockListener(display);
Job.getJobManager().setLockListener(uiLockListener);
synchronizer = new UISynchronizer(display, uiLockListener);
display.setSynchronizer(synchronizer);
// declare the main thread to be a startup thread.
UISynchronizer.startupThread.set(Boolean.TRUE);
} else
synchronizer = null; // // prime the splash nice and early
// if (createSplash)
// createSplashWrapper(); // ModalContext should not spin the event loop (there is no UI yet to
// block)
ModalContext.setAllowReadAndDispatch(false); // if the -debug command line argument is used and the event loop is
// being
// run while starting the Workbench, log a warning.
if (WorkbenchPlugin.getDefault().isDebugging()) {
display.asyncExec(new Runnable() {
public void run() {
if (isStarting()) {
WorkbenchPlugin.log(StatusUtil.newStatus(IStatus.WARNING,
"Event loop should not be run while the Workbench is starting.", //$NON-NLS-1$
new RuntimeException()));
}
}
});
} Listener closeListener = new Listener() {
public void handleEvent(Event event) {
event.doit = close();
}
}; // Initialize an exception handler.
Window.IExceptionHandler handler = ExceptionHandler.getInstance(); try {
// react to display close event by closing workbench nicely
display.addListener(SWT.Close, closeListener); // install backstop to catch exceptions thrown out of event loop
Window.setExceptionHandler(handler); final boolean[] initOK = new boolean[1]; if (getSplash() != null) { final boolean[] initDone = new boolean[] { false };
final Throwable[] error = new Throwable[1];
Thread initThread = new Thread() {
/*
* (non-Javadoc)
*
* @see java.lang.Thread#run()
*/
public void run() {
try {
// declare us to be a startup thread so that our
// syncs will be executed
UISynchronizer.startupThread.set(Boolean.TRUE);
initOK[0] = Workbench.this.init();
} catch (Throwable e) {
error[0] = e;
} finally {
initDone[0] = true;
display.wake();
}
}
};
initThread.start();
while (true) {
if (!display.readAndDispatch()) {
if (initDone[0])
break;
display.sleep();
}
}
Throwable throwable = error[0];
if (throwable != null) {
if (throwable instanceof Error)
throw (Error) throwable;
if (throwable instanceof Exception)
throw (Exception) throwable; // how very exotic - something that isn't playing by the
// rules. Wrap it in an error and bail
throw new Error(throwable);
}
} else {
// initialize workbench and restore or open one window
initOK[0] = init(); } // let the advisor run its start up code
if (initOK[0]) {
advisor.postStartup(); // may trigger a close/restart
} if (initOK[0] && runEventLoop) {
workbenchService = WorkbenchPlugin.getDefault().getBundleContext().registerService(
IWorkbench.class.getName(), this, null);
// start eager plug-ins
startPlugins();
addStartupRegistryListener(); // WWinPluginAction.refreshActionList(); display.asyncExec(new Runnable() {
public void run() {
UIStats.end(UIStats.START_WORKBENCH, this, "Workbench"); //$NON-NLS-1$
UIStats.startupComplete();
}
}); getWorkbenchTestable().init(display, this); // allow ModalContext to spin the event loop
ModalContext.setAllowReadAndDispatch(true);
isStarting = false; if (synchronizer != null)
synchronizer.started();
// the event loop
// runEventLoop(handler, display);
}
returnCode = PlatformUI.RETURN_OK;
} catch (final Exception e) {
if (!display.isDisposed()) {
handler.handleException(e);
} else {
String msg = "Exception in Workbench.runUI after display was disposed"; //$NON-NLS-1$
WorkbenchPlugin.log(msg, new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, 1,
msg, e));
}
} // restart or exit based on returnCode
return returnCode;
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchPage showPerspective(String perspectiveId, IWorkbenchWindow window)
throws WorkbenchException {
return showPerspective(perspectiveId, window, null);
} private boolean activate(String perspectiveId, IWorkbenchPage page, IAdaptable input,
boolean checkPerspective) {
if (page != null) {
for (IPerspectiveDescriptor openedPerspective : page.getOpenPerspectives()) {
if (!checkPerspective || openedPerspective.getId().equals(perspectiveId)) {
if (page.getInput() == input) {
WorkbenchWindow wwindow = (WorkbenchWindow) page.getWorkbenchWindow();
MWindow model = wwindow.getModel();
application.setSelectedElement(model);
return true;
}
}
}
}
return false;
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchPage showPerspective(String perspectiveId, IWorkbenchWindow targetWindow,
IAdaptable input) throws WorkbenchException {
Assert.isNotNull(perspectiveId);
IPerspectiveDescriptor targetPerspective = getPerspectiveRegistry().findPerspectiveWithId(
perspectiveId);
if (targetPerspective == null) {
throw new WorkbenchException(NLS.bind(
WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective, perspectiveId));
} if (targetWindow != null) {
IWorkbenchPage page = targetWindow.getActivePage();
if (activate(perspectiveId, page, input, true)) {
return page;
}
} for (IWorkbenchWindow window : getWorkbenchWindows()) {
IWorkbenchPage page = window.getActivePage();
if (activate(perspectiveId, page, input, true)) {
return page;
}
} if (targetWindow != null) {
IWorkbenchPage page = targetWindow.getActivePage();
if (activate(perspectiveId, page, input, false)) {
return page;
}
IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
int mode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE); if (IPreferenceConstants.OPM_NEW_WINDOW != mode) {
targetWindow.getShell().open();
if (page == null) {
page = targetWindow.openPage(perspectiveId, input);
} else {
page.setPerspective(targetPerspective);
}
return page;
}
} return openWorkbenchWindow(perspectiveId, input).getActivePage();
} /*
* Shuts down the application.
*/
private void shutdown() {
// shutdown application-specific portions first
try {
advisor.postShutdown();
} catch (Exception ex) {
StatusManager.getManager().handle(
StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
"Exceptions during shutdown", ex)); //$NON-NLS-1$
} // notify regular workbench clients of shutdown, and clear the list when
// done
firePostShutdown();
workbenchListeners.clear(); cancelEarlyStartup();
if (workbenchService != null)
workbenchService.unregister(); // for dynamic UI
Platform.getExtensionRegistry().removeRegistryChangeListener(extensionEventHandler);
Platform.getExtensionRegistry().removeRegistryChangeListener(startupRegistryListener); ((GrabFocus) Tweaklets.get(GrabFocus.KEY)).dispose(); // Bring down all of the services.
serviceLocator.dispose();
application.getCommands().removeAll(commandsToRemove);
application.getCategories().removeAll(categoriesToRemove); workbenchActivitySupport.dispose();
WorkbenchHelpSystem.disposeIfNecessary(); // shutdown the rest of the workbench
WorkbenchColors.shutdown();
activityHelper.shutdown();
uninitializeImages();
if (WorkbenchPlugin.getDefault() != null) {
WorkbenchPlugin.getDefault().reset();
}
WorkbenchThemeManager.getInstance().dispose();
PropertyPageContributorManager.getManager().dispose();
ObjectActionContributorManager.getManager().dispose();
if (tracker != null) {
tracker.close();
}
} /**
* Cancels the early startup job, if it's still running.
*/
private void cancelEarlyStartup() {
Job.getJobManager().cancel(EARLY_STARTUP_FAMILY);
// We do not currently wait for any plug-in currently being started to
// complete
// (e.g. by doing a join on EARLY_STARTUP_FAMILY), since they may do a
// syncExec,
// which would hang. See bug 94537 for rationale.
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IDecoratorManager getDecoratorManager() {
return WorkbenchPlugin.getDefault().getDecoratorManager();
} /**
* Returns the unique object that applications use to configure the
* workbench.
* <p>
* IMPORTANT This method is declared package-private to prevent regular
* plug-ins from downcasting IWorkbench to Workbench and getting hold of the
* workbench configurer that would allow them to tamper with the workbench.
* The workbench configurer is available only to the application.
* </p>
*/
/* package */
WorkbenchConfigurer getWorkbenchConfigurer() {
if (workbenchConfigurer == null) {
workbenchConfigurer = new WorkbenchConfigurer();
}
return workbenchConfigurer;
} /**
* Returns the workbench advisor that created this workbench.
* <p>
* IMPORTANT This method is declared package-private to prevent regular
* plug-ins from downcasting IWorkbench to Workbench and getting hold of the
* workbench advisor that would allow them to tamper with the workbench. The
* workbench advisor is internal to the application.
* </p>
*/
/* package */
WorkbenchAdvisor getAdvisor() {
return advisor;
} /*
* (non-Javadoc) Method declared on IWorkbench.
*/
public Display getDisplay() {
return display;
} /**
* Returns the default perspective id, which may be <code>null</code>.
*
* @return the default perspective id, or <code>null</code>
*/
public String getDefaultPerspectiveId() {
return getAdvisor().getInitialWindowPerspectiveId();
} /**
* Returns the default workbench window page input.
*
* @return the default window page input or <code>null</code> if none
*/
public IAdaptable getDefaultPageInput() {
return getAdvisor().getDefaultPageInput();
} /**
* Returns the id of the preference page that should be presented most
* prominently.
*
* @return the id of the preference page, or <code>null</code> if none
*/
public String getMainPreferencePageId() {
String id = getAdvisor().getMainPreferencePageId();
return id;
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench
*
* @since 3.0
*/
public IElementFactory getElementFactory(String factoryId) {
Assert.isNotNull(factoryId);
return WorkbenchPlugin.getDefault().getElementFactory(factoryId);
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getProgressService()
*/
public IProgressService getProgressService() {
return (IProgressService) e4Context.get(IProgressService.class.getName());
} private WorkbenchActivitySupport workbenchActivitySupport; private WorkbenchCommandSupport workbenchCommandSupport; private WorkbenchContextSupport workbenchContextSupport; /**
* The single instance of the binding manager used by the workbench. This is
* initialized in <code>Workbench.init(Display)</code> and then never
* changed. This value will only be <code>null</code> if the initialization
* call has not yet completed.
*
* @since 3.1
*/
private BindingManager bindingManager; /**
* The single instance of the command manager used by the workbench. This is
* initialized in <code>Workbench.init(Display)</code> and then never
* changed. This value will only be <code>null</code> if the initialization
* call has not yet completed.
*
* @since 3.1
*/
private CommandManager commandManager; /**
* The single instance of the context manager used by the workbench. This is
* initialized in <code>Workbench.init(Display)</code> and then never
* changed. This value will only be <code>null</code> if the initialization
* call has not yet completed.
*
* @since 3.1
*/
private ContextManager contextManager; public IWorkbenchActivitySupport getActivitySupport() {
return (IWorkbenchActivitySupport) e4Context.get(IWorkbenchActivitySupport.class.getName());
} public IWorkbenchCommandSupport getCommandSupport() {
return workbenchCommandSupport;
} public IWorkbenchContextSupport getContextSupport() {
return workbenchContextSupport;
} /**
* This method should not be called outside the framework.
*
* @return The context manager.
*/
public ContextManager getContextManager() {
return contextManager;
} private final IBindingManagerListener bindingManagerListener = new IBindingManagerListener() { public void bindingManagerChanged(BindingManagerEvent bindingManagerEvent) {
if (bindingManagerEvent.isActiveBindingsChanged()) {
updateActiveWorkbenchWindowMenuManager(true);
}
}
}; private void updateActiveWorkbenchWindowMenuManager(boolean textOnly) { final IWorkbenchWindow workbenchWindow = getActiveWorkbenchWindow(); if (workbenchWindow instanceof WorkbenchWindow) {
WorkbenchWindow activeWorkbenchWindow = (WorkbenchWindow) workbenchWindow;
if (activeWorkbenchWindow.isClosing()) {
return;
} // Update the action sets.
final MenuManager menuManager = activeWorkbenchWindow.getMenuManager(); if (textOnly) {
menuManager.update(IAction.TEXT);
} else {
menuManager.update(true);
}
}
} private ActivityPersistanceHelper activityHelper; /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getIntroManager()
*/
public IIntroManager getIntroManager() {
return getWorkbenchIntroManager();
} /**
* @return the workbench intro manager
* @since 3.0
*/
/* package */WorkbenchIntroManager getWorkbenchIntroManager() {
if (introManager == null) {
introManager = new WorkbenchIntroManager(this);
}
return introManager;
} private WorkbenchIntroManager introManager; /**
* @return the intro extension for this workbench.
*
* @since 3.0
*/
public IntroDescriptor getIntroDescriptor() {
return introDescriptor;
} /**
* This method exists as a test hook. This method should
* <strong>NEVER</strong> be called by clients.
*
* @param descriptor
* The intro descriptor to use.
* @since 3.0
*/
public void setIntroDescriptor(IntroDescriptor descriptor) {
if (getIntroManager().getIntro() != null) {
getIntroManager().closeIntro(getIntroManager().getIntro());
}
introDescriptor = descriptor;
} /**
* The descriptor for the intro extension that is valid for this workspace,
* <code>null</code> if none.
*/
private IntroDescriptor introDescriptor; private IExtensionTracker tracker; private IRegistryChangeListener startupRegistryListener = new IRegistryChangeListener() { /*
* (non-Javadoc)
*
* @see
* org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(
* org.eclipse.core.runtime.IRegistryChangeEvent)
*/
public void registryChanged(IRegistryChangeEvent event) {
final IExtensionDelta[] deltas = event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_STARTUP);
if (deltas.length == 0) {
return;
}
final String disabledPlugins = PrefUtil.getInternalPreferenceStore().getString(
IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP); for (int i = 0; i < deltas.length; i++) {
IExtension extension = deltas[i].getExtension();
if (deltas[i].getKind() == IExtensionDelta.REMOVED) {
continue;
} // if the plugin is not in the set of disabled plugins,
// then
// execute the code to start it
if (disabledPlugins.indexOf(extension.getNamespace()) == -1) {
SafeRunner.run(new EarlyStartupRunnable(extension));
}
} }
}; private String factoryID; /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getThemeManager()
*/
public IThemeManager getThemeManager() {
return WorkbenchThemeManager.getInstance();
} /**
* Returns <code>true</code> if the workbench is running, <code>false</code>
* if it has been terminated.
*
* @return <code>true</code> if the workbench is running, <code>false</code>
* if it has been terminated.
*/
public boolean isRunning() {
return runEventLoop;
} /**
* Return the presentation ID specified by the preference or the default ID
* if undefined.
*
* @return the presentation ID
* @see IWorkbenchPreferenceConstants#PRESENTATION_FACTORY_ID
*/
public String getPresentationId() {
if (factoryID != null) {
return factoryID;
} factoryID = PrefUtil.getAPIPreferenceStore().getString(
IWorkbenchPreferenceConstants.PRESENTATION_FACTORY_ID); // Workaround for bug 58975 - New preference mechanism does not properly
// initialize defaults
// Ensure that the UI plugin has started too.
if (factoryID == null || factoryID.equals("")) { //$NON-NLS-1$
factoryID = IWorkbenchConstants.DEFAULT_PRESENTATION_ID;
}
return factoryID;
} /**
* <p>
* Indicates the start of a large update within the workbench. This is used
* to disable CPU-intensive, change-sensitive services that were temporarily
* disabled in the midst of large changes. This method should always be
* called in tandem with <code>largeUpdateEnd</code>, and the event loop
* should not be allowed to spin before that method is called.
* </p>
* <p>
* Important: always use with <code>largeUpdateEnd</code>!
* </p>
*/
public final void largeUpdateStart() {
if (largeUpdates++ == 0) {
// TODO Consider whether these lines still need to be here.
// workbenchCommandSupport.setProcessing(false);
// workbenchContextSupport.setProcessing(false); final IWorkbenchWindow[] windows = getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
IWorkbenchWindow window = windows[i];
if (window instanceof WorkbenchWindow) {
((WorkbenchWindow) window).largeUpdateStart();
}
}
}
} /**
* <p>
* Indicates the end of a large update within the workbench. This is used to
* re-enable services that were temporarily disabled in the midst of large
* changes. This method should always be called in tandem with
* <code>largeUpdateStart</code>, and the event loop should not be allowed
* to spin before this method is called.
* </p>
* <p>
* Important: always protect this call by using <code>finally</code>!
* </p>
*/
public final void largeUpdateEnd() {
if (--largeUpdates == 0) {
// TODO Consider whether these lines still need to be here.
// workbenchCommandSupport.setProcessing(true);
// workbenchContextSupport.setProcessing(true); // Perform window-specific blocking.
final IWorkbenchWindow[] windows = getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
IWorkbenchWindow window = windows[i];
if (window instanceof WorkbenchWindow) {
((WorkbenchWindow) window).largeUpdateEnd();
}
}
}
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getExtensionTracker()
*/
public IExtensionTracker getExtensionTracker() {
return (IExtensionTracker) e4Context.get(IExtensionTracker.class.getName());
} /**
* Adds the listener that handles startup plugins
*
* @since 3.1
*/
private void addStartupRegistryListener() {
IExtensionRegistry registry = Platform.getExtensionRegistry();
registry.addRegistryChangeListener(startupRegistryListener);
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getHelpSystem()
*/
public IWorkbenchHelpSystem getHelpSystem() {
return WorkbenchHelpSystem.getInstance();
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getHelpSystem()
*/
public IWorkbenchBrowserSupport getBrowserSupport() {
return WorkbenchBrowserSupport.getInstance();
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getViewRegistry()
*/
public IViewRegistry getViewRegistry() {
return WorkbenchPlugin.getDefault().getViewRegistry();
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getNewWizardRegistry()
*/
public IWizardRegistry getNewWizardRegistry() {
return WorkbenchPlugin.getDefault().getNewWizardRegistry();
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getImportWizardRegistry()
*/
public IWizardRegistry getImportWizardRegistry() {
return WorkbenchPlugin.getDefault().getImportWizardRegistry();
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getExportWizardRegistry()
*/
public IWizardRegistry getExportWizardRegistry() {
return WorkbenchPlugin.getDefault().getExportWizardRegistry();
} public final Object getAdapter(final Class key) {
return serviceLocator.getService(key);
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.services.IServiceLocator#getService(java.lang.Object)
*/
public final Object getService(final Class key) {
return serviceLocator.getService(key);
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.services.IServiceLocator#hasService(java.lang.Object)
*/
public final boolean hasService(final Class key) {
return serviceLocator.hasService(key);
} /**
* Registers a service with this locator. If there is an existing service
* matching the same <code>api</code> and it implements {@link IDisposable},
* it will be disposed.
*
* @param api
* This is the interface that the service implements. Must not be
* <code>null</code>.
* @param service
* The service to register. This must be some implementation of
* <code>api</code>. This value must not be <code>null</code>.
*/
public final void registerService(final Class api, final Object service) {
serviceLocator.registerService(api, service);
} /**
* The source provider that tracks which context menus (i.e., menus with
* target identifiers) are now showing. This value is <code>null</code>
* until {@link #initializeDefaultServices()} is called.
*/
private MenuSourceProvider menuSourceProvider; /**
* Adds the ids of a menu that is now showing to the menu source provider.
* This is used for legacy action-based handlers which need to become active
* only for the duration of a menu being visible.
*
* @param menuIds
* The identifiers of the menu that is now showing; must not be
* <code>null</code>.
* @param localSelection
* @param localEditorInput
*/
public final void addShowingMenus(final Set menuIds, final ISelection localSelection,
final ISelection localEditorInput) {
menuSourceProvider.addShowingMenus(menuIds, localSelection, localEditorInput);
Map currentState = menuSourceProvider.getCurrentState();
for (String key : menuSourceProvider.getProvidedSourceNames()) {
e4Context.set(key, currentState.get(key));
}
} /**
* Removes the ids of a menu that is now hidden from the menu source
* provider. This is used for legacy action-based handlers which need to
* become active only for the duration of a menu being visible.
*
* @param menuIds
* The identifiers of the menu that is now hidden; must not be
* <code>null</code>.
* @param localSelection
* @param localEditorInput
*/
public final void removeShowingMenus(final Set menuIds, final ISelection localSelection,
final ISelection localEditorInput) {
menuSourceProvider.removeShowingMenus(menuIds, localSelection, localEditorInput);
for (String key : menuSourceProvider.getProvidedSourceNames()) {
e4Context.remove(key);
}
} /*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.IWorkbench#saveAll(org.eclipse.jface.window.IShellProvider
* , org.eclipse.jface.operation.IRunnableContext,
* org.eclipse.ui.ISaveableFilter, boolean)
*/
public boolean saveAll(final IShellProvider shellProvider,
final IRunnableContext runnableContext, final ISaveableFilter filter, boolean confirm) {
Map<Saveable, Set<IWorkbenchPart>> map = new HashMap<Saveable, Set<IWorkbenchPart>>(); for (IWorkbenchWindow window : getWorkbenchWindows()) {
IWorkbenchPage page = window.getActivePage(); IViewReference[] viewReferences = page.getViewReferences();
for (IWorkbenchPartReference reference : viewReferences) {
IWorkbenchPart part = reference.getPart(false);
if (part instanceof ISaveablesSource) {
Saveable[] saveables = ((ISaveablesSource) part).getSaveables();
for (Saveable saveable : saveables) {
if (saveable.isDirty()) {
Set<IWorkbenchPart> parts = map.get(saveable);
if (parts == null) {
parts = new HashSet<IWorkbenchPart>();
map.put(saveable, parts);
}
parts.add(part);
}
}
}
} IEditorReference[] editorReferences = page.getEditorReferences();
for (IWorkbenchPartReference reference : editorReferences) {
IWorkbenchPart part = reference.getPart(false);
if (part instanceof ISaveablesSource) {
Saveable[] saveables = ((ISaveablesSource) part).getSaveables();
for (Saveable saveable : saveables) {
if (saveable.isDirty()) {
Set<IWorkbenchPart> parts = map.get(saveable);
if (parts == null) {
parts = new HashSet<IWorkbenchPart>();
map.put(saveable, parts);
}
parts.add(part);
}
}
}
}
} final List<Saveable> toSave = new ArrayList<Saveable>(); for (Entry<Saveable, Set<IWorkbenchPart>> entrySet : map.entrySet()) {
Saveable saveable = entrySet.getKey();
Set<IWorkbenchPart> parts = entrySet.getValue();
if (filter.select(saveable, parts.toArray(new IWorkbenchPart[parts.size()]))) {
toSave.add(saveable);
}
} if (toSave.isEmpty()) {
return true;
} SaveablesList saveablesList = (SaveablesList) getService(ISaveablesLifecycleListener.class); if (!confirm) {
return !saveablesList.saveModels(toSave, shellProvider, runnableContext);
} // We must negate the result since false is cancel saveAll
return !saveablesList.promptForSaving(toSave, shellProvider, runnableContext, true, false);
} public ServiceLocator getServiceLocator() {
return serviceLocator;
} /*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbench#getModalDialogShellProvider()
*/
public IShellProvider getModalDialogShellProvider() {
return new IShellProvider() {
public Shell getShell() {
return ProgressManagerUtil.getDefaultParent();
}
};
} public IEclipseContext getContext() {
return e4Context;
} public MApplication getApplication() {
return application;
}
}Workbench
- PlatformUI
The PlatformUI class provides access to a single workbench. A workbench is the root object for the UI and has one or more workbench windows. Each workbench window has a collection of workbench pages, only one of which is active and visible to the end user. Each workbench page has a collection of workbench parts. A page's parts are arranged (tiled or stacked) for presentation on the screen. Within a page and its parts the user can interact with and modify a model (typically resources in a workspace). There are two kinds of workbench parts: views and editors. An editor is typically used to edit or browse a document or input object. A view is typically used to navigate a hierarchy of information (like the workspace), open an editor, or display properties for the active editor. The platform creates a workbench when the workbench plug-in is activated. Since this happens at most once during the life of the running platform, there is only one workbench instance. Due to its singular nature, it is commonly referred to as the workbench. Within a workbench the user will interact with many different resource types. Because different tools are required for each, the workbench defines a number of extension points which allow for the integration of new tools. There are extension points for views, editors, action sets, import wizards, export wizards, etc.
- PlatformUI
Activator in our plug-in, subclasses from AbstractUIPlugin: This Activator must has a default constructor without any parameters, so the framework can create a instance of Activator when starting this bundle by using RTTI method Class.newInstance(). Somehow, Activator of boundle just is like a main function of every program.
package com.dragon.contribution.junit;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.dragon.contribution.junit"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
public Activator() {
}
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
public static Activator getDefault() {
return plugin;
}
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}- Framework activate a bundle
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:734)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:390)
at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1177)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Elipse plugin or Bundle & OSGI的更多相关文章
- 解决:“Workbench has not been created yet” error in eclipse plugin programming”,OSGI启动控制台报错问题
项目中使用了OSGI的框架,最近被问到OSGI框架是什么,自己表示几乎没什么认识,于是想自己手动搭建一个OSGI小例子试一试 于是在搭建过程中遇到了下面的问题:项目启动很慢而且控制台也报了很多异常出来 ...
- OSGi Bundle之Hello World
开发一个简单的Hello World的OSGi Bundle(OSGi绑定包) 在OSGi中,软件是以Bundle的形式发布的.一个Bundle由Java类和其它资源构成,它可为其它的Bundle提供 ...
- osgi实战学习之路:4.Bundle
</pre></h1><h1 style="margin:0 0 0 40px; border:none; padding:0px"><p ...
- [转]Eclipse插件开发之基础篇(5) 制作OSGi Bundle
原文地址:http://www.cnblogs.com/liuzhuo/archive/2010/08/18/eclipse_plugin_1_2_2.html 1. 生成OSGi工程 首先打开新工程 ...
- osgi 1
Helloworld入门 准备: eclipse 3.4 需要jar,—— eclipse 自带的,plugin下面有很多,抛开里面的jar,很多都是当前项目不需要的,如果不适用eclipse而是直接 ...
- osgi 2
基础的API BundleActivator BundleContext ServiceReference HelloServiceFactory ServiceTracker osgi 疑惑: I ...
- OSGi 的核心配置、动态化及问题
一.OSGi的核心组件Bundle,与java中jar包的差别就是元数据配置: 常用的Bundle元数据定义: a) Bundle-Activator:定义Activator的实现全 ...
- Bundle使用&NSBundle
之 前在初始化一个类的时候:TestViewController *viewcontroller=[[TestViewController alloc]initWithNibName:@"T ...
- iOS 封装SDK以及封装时bundle文件的处理
这篇教程的主要目的是解释怎么样在你的iOS工程中创建并使用一个SDK,俗称.a文件. 环境:xcode 9.0 创建一个静态库工程 打开Xcode,点击File\New\Project, 选择iOS\ ...
随机推荐
- flex弹性布局,好用
一直不太喜欢自己布局前端页面,都是扒别人的页面 ,最近在练习小程序,页面无处可扒,只有自己布局 发现flex弹性布局真好用,布局起来很简单,实现的效果也很好,赞 以后可以自己写一点前端了,哈哈
- 16. js 判断变量类型,包括ES6 新类型Symbol
相信大家在开发中遇到需要判断变量类型的问题,js变量按存储类型可分为值类型和引用类型,值类型包括Undefined.String.Number.Boolean,引用类型包括object.Array.F ...
- 洛谷P2146 [NOI2015]软件包管理器
https://www.luogu.org/problemnew/show/P2146 传送门 简单的树链剖分......维护下当前安装了多少个包......修改后查询下就行了......附上极其丑陋 ...
- 基于 bootstrap html 响应式 布局
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- POJ - 1948 二维01背包
T了两发,DP方程很简单粗暴 dp[i][j][k]:用前i物品使得容量分别为j和k的背包恰好装满 背包的调用只需一次即可,第一次T就是每次check都丧心病狂地背包一次 对于sum的枚举,其实i j ...
- 划分型博弈型dp
划分型动态规划: 513. Perfect Squares https://www.lintcode.com/problem/perfect-squares/description?_from=lad ...
- Python编程:基础学习常见错误整理
# Python学习之错误整理: # 错误一:# TypeError: cannot concatenate 'str' and 'int' objects# 不能连接str和int对象age = 2 ...
- RabbitMQ基础知识篇
1.Linux安装RabbitMQ. 参考网址:RPM安装RabbitMQ 仔细阅读. 先安装erlang: su -c 'rpm -Uvh http://mirrors.neusoft.edu. ...
- vue嵌套路由 && 404重定向
第一部分: vue嵌套路由 嵌套路由是什么? 嵌套路由就是在一个被路由过来的页面下可以继续使用路由,嵌套也就是路由中的路由的意思. 比如在vue中,我们如果不使用嵌套路由,那么只有一个<rou ...
- DBNull.Value.ToString() == string.Empty
Console.WriteLine(DBNull.Value.ToString() == string.Empty); //True