zoukankan      html  css  js  c++  java
  • 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:     

     1 package org.serc.helloworld;
     2 public interface Hello 
     3 {
     4    void sayHello();
     5 }
     6 
     7 package org.serc.helloworld.impl;
     8 public class HelloImpl implements Hello
     9 {
    10   final String helloString;
    11   public HelloImpl(String helloString){
    12     this.helloString= helloString;
    13   }
    14   public void sayHello(){
    15     System.out.println(this.helloString);
    16   }
    17 }
    18 
    19 package org.serc.helloworld.activator;
    20 public class Activator implements BundleActivator {
    21   private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
    22   public void start(BundleContext ctx) {//only register one service just now
    23     registrations.add(ctx.registerService(Hello.class.getName(),new HelloImpl("Hello, OSGi"), null));
    24   }
    25   public void stop(BundleContext ctx) {
    26     for(ServiceRegistration registration : registrations) {
    27        System.out.println("unregistering:"+ registration);
    28        registration.unregister();
    29     }
    30   }
    31 }
    32 //MANIFEST
    33 Bundle-ManifestVersion:2
    34 Bundle-SymbolicName:org.serc.helloworld
    35 Bundle-Version:1.0
    36 Bundle-Activator:org.serc.helloworld.activator.Activator
    37 Import-Package:org.osgi.framework
    38 Export-Package:org.serc.helloworld;version="1.0" //the package which will be used by other bundle

    Client:

     1 package org.serc.helloworld.client;
     2 public class HelloUser implements BundleActivator {
     3   public void start(BundleContext ctx) { //ctx is created by runtime kernel, framwork entity
     4      ServiceReference ref = ctx.getServiceReference(Hello.class.getName());//now get a service reference which implement Hello 
     5      if(ref != null) {
     6          Hello hello = null;
     7          try{
     8               hello= (Hello) ctx.getService(ref);//get reference
     9               if(hello != null)
    10                   hello.sayHello();
    11               else
    12                   System.out.println("Service:Hello---objectnull");
    13          }
    14          catch (RuntimeException e) {
    15               e.printStackTrace();
    16          }
    17          finally{
    18             ctx.ungetService(ref);
    19             hello= null;
    20           }
    21     }
    22     else {
    23         System.out.println("Service:Hello---notexists");
    24     }
    25   }
    26   public void stop(BundleContext ctx) throws Exception {
    27   }
    28 }
    29 //
    30 Bundle-ManifestVersion:2
    31 Bundle-SymbolicName:org.serc.helloworld.client
    32 Bundle-Version:1.0
    33 Bundle-Activator:org.serc.helloworld.client.HelloUser   //Bundle luncher
    34 Import-Package:org.serc.helloworld;version="[1.0,2.0)",org.osgi.framework //the package which is used by this bundle
    • Bundle
      1. 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
      2. 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.
      3. 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.

      4. 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. 
      5. 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.The BundleContext object is only valid during the execution of its context bundle; that is, during the period from when the context bundle is in the STARTING, STOPPING, and ACTIVE bundle states. If the BundleContext object is used subsequently, an IllegalStateException must be thrown.

      6. The BundleContext object must never be reused after its context bundle is stopped.Two BundleContext objects are equal if they both refer to the same execution context of a bundle.

      7. The Framework is the only entity that can create BundleContext objects and they are only valid within the Framework that created them.

    • 1 public interface Comparable<T> { //generic in Java
      2     public int compareTo(T o);
      3 }
       1 package org.osgi.framework;
       2 public interface Bundle extends Comparable<Bundle> {    
       3     int    UNINSTALLED                = 0x00000001;
       4     int    INSTALLED                = 0x00000002;
       5     int    RESOLVED                = 0x00000004;
       6     int    STARTING                = 0x00000008;
       7     int    STOPPING                = 0x00000010;
       8     int    ACTIVE                    = 0x00000020;
       9     int    START_TRANSIENT            = 0x00000001;
      10     int    START_ACTIVATION_POLICY    = 0x00000002;
      11     int    STOP_TRANSIENT            = 0x00000001;
      12     int    SIGNERS_ALL                = 1;
      13     int    SIGNERS_TRUSTED            = 2;
      14     int getState();
      15     void start(int options) throws BundleException;
      16     void start() throws BundleException;
      17     void stop(int options) throws BundleException;
      18     void stop() throws BundleException;
      19     void update(InputStream input) throws BundleException;
      20     void update() throws BundleException;
      21     void uninstall() throws BundleException;
      22     Dictionary<String, String> getHeaders();
      23     long getBundleId();
      24     String getLocation();
      25     ServiceReference<?>[] getRegisteredServices();
      26     ServiceReference<?>[] getServicesInUse();
      27     boolean hasPermission(Object permission);
      28     URL getResource(String name);
      29     Enumeration<String> getEntryPaths(String path);
      30     URL getEntry(String path);
      31     long getLastModified();
      32     Enumeration<URL> findEntries(String path, String filePattern, boolean recurse);
      33     BundleContext getBundleContext();
      34     Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType);
      35     Version getVersion();
      36     <A> A adapt(Class<A> type);
      37     File getDataFile(String filename);
      38 }
    • 1 public interface BundleReference {
      2     public Bundle getBundle();
      3 }
    •  1 package org.osgi.framework;
       2 public interface BundleContext extends BundleReference {
       3     String getProperty(String key);
       4     Bundle getBundle();
       5     Bundle installBundle(String location, InputStream input) throws BundleException;
       6     Bundle installBundle(String location) throws BundleException;
       7     Bundle getBundle(long id);
       8     Bundle[] getBundles();
       9     void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException;
      10     void addServiceListener(ServiceListener listener);
      11     void removeServiceListener(ServiceListener listener);
      12     void addBundleListener(BundleListener listener);
      13     void removeBundleListener(BundleListener listener);
      14     void addFrameworkListener(FrameworkListener listener);
      15     void removeFrameworkListener(FrameworkListener listener);
      16     ServiceRegistration<?> registerService(String clazz, Object service, Dictionary<String, ?> properties);
      17     <S> ServiceRegistration<S> registerService(Class<S> clazz, S service, Dictionary<String, ?> properties);
      18     ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
      19     ServiceReference<?>[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
      20     ServiceReference<?> getServiceReference(String clazz);
      21     <S> ServiceReference<S> getServiceReference(Class<S> clazz);
      22     <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter) throws InvalidSyntaxException;
      23     <S> S getService(ServiceReference<S> reference);
      24     boolean ungetService(ServiceReference<?> reference);
      25     File getDataFile(String filename);
      26     Filter createFilter(String filter) throws InvalidSyntaxException;
      27     Bundle getBundle(String location);
      28 }
    • BundleActivator
      1. 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. 
    • 1 public interface BundleActivator {
      2     public void start(BundleContext context) throws Exception;
      3     public void stop(BundleContext context) throws Exception;
      4 } 
    • Plugin 
      1 /*******************************************************************************
      2  * Copyright (c) 2000, 2012 IBM Corporation and others.
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  * 
      8  * Contributors:
      9  *     IBM Corporation - initial API and implementation
     10  *     Julian Chen - fix for bug #92572, jclRM
     11  *     Benjamin Cabe <benjamin.cabe@anyware-tech.com> - fix for bug 265532
     12  *******************************************************************************/
     13 package org.eclipse.core.internal.runtime;
     14 
     15 import java.io.*;
     16 import java.net.MalformedURLException;
     17 import java.net.URL;
     18 import java.util.*;
     19 import org.eclipse.core.internal.preferences.exchange.ILegacyPreferences;
     20 import org.eclipse.core.internal.preferences.exchange.IProductPreferencesService;
     21 import org.eclipse.core.internal.preferences.legacy.InitLegacyPreferences;
     22 import org.eclipse.core.internal.preferences.legacy.ProductPreferencesService;
     23 import org.eclipse.core.runtime.*;
     24 import org.eclipse.core.runtime.content.IContentTypeManager;
     25 import org.eclipse.core.runtime.preferences.IPreferencesService;
     26 import org.eclipse.equinox.app.IApplicationContext;
     27 import org.eclipse.equinox.internal.app.*;
     28 import org.eclipse.equinox.internal.app.Activator;
     29 import org.eclipse.equinox.log.*;
     30 import org.eclipse.osgi.framework.log.FrameworkLog;
     31 import org.eclipse.osgi.service.datalocation.Location;
     32 import org.eclipse.osgi.service.debug.DebugOptions;
     33 import org.eclipse.osgi.service.environment.EnvironmentInfo;
     34 import org.eclipse.osgi.service.resolver.PlatformAdmin;
     35 import org.osgi.framework.*;
     36 import org.osgi.service.packageadmin.PackageAdmin;
     37 import org.osgi.util.tracker.ServiceTracker;
     38 
     39 /**
     40  * Bootstrap class for the platform. It is responsible for setting up the
     41  * platform class loader and passing control to the actual application class
     42  */
     43 public final class InternalPlatform {
     44 
     45     private static final String[] ARCH_LIST = {Platform.ARCH_PA_RISC, //
     46             Platform.ARCH_PPC, //
     47             Platform.ARCH_SPARC, //
     48             Platform.ARCH_X86, //
     49             Platform.ARCH_AMD64, // 
     50             Platform.ARCH_IA64, //
     51             Platform.ARCH_IA64_32};
     52 
     53     // debug support:  set in loadOptions()
     54     public static boolean DEBUG = false;
     55     public static boolean DEBUG_PLUGIN_PREFERENCES = false;
     56 
     57     static boolean splashEnded = false;
     58     private static boolean initialized;
     59     private static final String KEYRING = "-keyring"; //$NON-NLS-1$
     60     private static String keyringFile;
     61 
     62     //XXX This is not synchronized
     63     private static Map logs = new HashMap(5);
     64 
     65     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};
     66     private static String password = ""; //$NON-NLS-1$
     67     private static final String PASSWORD = "-password"; //$NON-NLS-1$
     68 
     69     private static final String PLUGIN_PATH = ".plugin-path"; //$NON-NLS-1$
     70 
     71     public static final String PROP_APPLICATION = "eclipse.application"; //$NON-NLS-1$
     72     public static final String PROP_ARCH = "osgi.arch"; //$NON-NLS-1$
     73     public static final String PROP_CONFIG_AREA = "osgi.configuration.area"; //$NON-NLS-1$
     74     public static final String PROP_CONSOLE_LOG = "eclipse.consoleLog"; //$NON-NLS-1$
     75     public static final String PROP_DEBUG = "osgi.debug"; //$NON-NLS-1$
     76     public static final String PROP_DEV = "osgi.dev"; //$NON-NLS-1$
     77 
     78     // OSGI system properties.  Copied from EclipseStarter
     79     public static final String PROP_INSTALL_AREA = "osgi.install.area"; //$NON-NLS-1$
     80     public static final String PROP_NL = "osgi.nl"; //$NON-NLS-1$
     81     public static final String PROP_OS = "osgi.os"; //$NON-NLS-1$
     82 
     83     // Eclipse System Properties
     84     public static final String PROP_PRODUCT = "eclipse.product"; //$NON-NLS-1$
     85     public static final String PROP_WS = "osgi.ws"; //$NON-NLS-1$
     86     public static final String PROP_ACTIVATE_PLUGINS = "eclipse.activateRuntimePlugins"; //$NON-NLS-1$
     87 
     88     private static final InternalPlatform singleton = new InternalPlatform();
     89 
     90     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};
     91     private Path cachedInstanceLocation; // Cache the path of the instance location
     92     private ServiceTracker configurationLocation = null;
     93     private BundleContext context;
     94 
     95     private Map groupProviders = new HashMap(3);
     96     private ServiceTracker installLocation = null;
     97     private ServiceTracker instanceLocation = null;
     98 
     99     private Plugin runtimeInstance; // Keep track of the plugin object for runtime in case the backward compatibility is run.
    100 
    101     private ServiceRegistration legacyPreferencesService = null;
    102     private ServiceRegistration customPreferencesService = null;
    103 
    104     private ServiceTracker environmentTracker = null;
    105     private ServiceTracker logTracker = null;
    106     private ServiceTracker bundleTracker = null;
    107     private ServiceTracker debugTracker = null;
    108     private ServiceTracker contentTracker = null;
    109     private ServiceTracker preferencesTracker = null;
    110     private ServiceTracker userLocation = null;
    111     private ServiceTracker groupProviderTracker = null;
    112     private ServiceTracker logReaderTracker = null;
    113     private ServiceTracker extendedLogTracker = null;
    114 
    115     private IProduct product;
    116 
    117     public static InternalPlatform getDefault() {
    118         return singleton;
    119     }
    120 
    121     /**
    122      * Private constructor to block instance creation.
    123      */
    124     private InternalPlatform() {
    125         super();
    126     }
    127 
    128     /**
    129      * @see Platform#addLogListener(ILogListener)
    130      */
    131     public void addLogListener(ILogListener listener) {
    132         assertInitialized();
    133         RuntimeLog.addLogListener(listener);
    134     }
    135 
    136     private void assertInitialized() {
    137         //avoid the Policy.bind if assertion is true
    138         if (!initialized)
    139             Assert.isTrue(false, Messages.meta_appNotInit);
    140     }
    141 
    142     /**
    143      * @see Platform#endSplash()
    144      */
    145     public void endSplash() {
    146         synchronized (this) {
    147             if (splashEnded)
    148                 return; // do not do this more than once
    149             splashEnded = true;
    150         }
    151         IApplicationContext applicationContext = getApplicationContext();
    152         if (applicationContext != null)
    153             applicationContext.applicationRunning();
    154     }
    155 
    156     /**
    157      * @see Platform#getAdapterManager()
    158      */
    159     public IAdapterManager getAdapterManager() {
    160         assertInitialized();
    161         return AdapterManager.getDefault();
    162     }
    163 
    164     /**
    165      * XXX Use the Environment info service. Need to see how to set the value of the app args.
    166      */
    167     public String[] getApplicationArgs() {
    168         return CommandLineArgs.getApplicationArgs();
    169     }
    170 
    171     public boolean getBooleanOption(String option, boolean defaultValue) {
    172         String value = getOption(option);
    173         if (value == null)
    174             return defaultValue;
    175         return value.equalsIgnoreCase("true"); //$NON-NLS-1$
    176     }
    177 
    178     public Bundle getBundle(String symbolicName) {
    179         PackageAdmin packageAdmin = getBundleAdmin();
    180         if (packageAdmin == null)
    181             return null;
    182         Bundle[] bundles = packageAdmin.getBundles(symbolicName, null);
    183         if (bundles == null)
    184             return null;
    185         //Return the first bundle that is not installed or uninstalled
    186         for (int i = 0; i < bundles.length; i++) {
    187             if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
    188                 return bundles[i];
    189             }
    190         }
    191         return null;
    192     }
    193 
    194     public BundleContext getBundleContext() {
    195         return context;
    196     }
    197 
    198     /**
    199      * Returns the bundle id of the bundle that contains the provided object, or
    200      * <code>null</code> if the bundle could not be determined.
    201      */
    202     public String getBundleId(Object object) {
    203         if (object == null)
    204             return null;
    205         PackageAdmin packageAdmin = getBundleAdmin();
    206         if (packageAdmin == null)
    207             return null;
    208         Bundle source = packageAdmin.getBundle(object.getClass());
    209         if (source != null && source.getSymbolicName() != null)
    210             return source.getSymbolicName();
    211         return null;
    212     }
    213 
    214     public IBundleGroupProvider[] getBundleGroupProviders() {
    215         Object[] objectArray = groupProviderTracker.getServices();
    216         if (objectArray == null) // getServices may return null; but we can not.
    217             return new IBundleGroupProvider[0];
    218         IBundleGroupProvider[] result = new IBundleGroupProvider[objectArray.length];
    219         System.arraycopy(objectArray, 0, result, 0, objectArray.length);
    220         return result;
    221     }
    222 
    223     public void registerBundleGroupProvider(IBundleGroupProvider provider) {
    224         // get the bundle context and register the provider as a service
    225         ServiceRegistration registration = getBundleContext().registerService(IBundleGroupProvider.class.getName(), provider, null);
    226         // store the service registration (map provider -> registration)
    227         synchronized (groupProviders) {
    228             groupProviders.put(provider, registration);
    229         }
    230     }
    231 
    232     public void unregisterBundleGroupProvider(IBundleGroupProvider provider) {
    233         // get the service reference (map provider -> reference)
    234         ServiceRegistration registration;
    235         synchronized (groupProviders) {
    236             registration = (ServiceRegistration) groupProviders.remove(provider);
    237         }
    238         if (registration == null)
    239             return;
    240         // unregister the provider
    241         registration.unregister();
    242     }
    243 
    244     public Bundle[] getBundles(String symbolicName, String version) {
    245         PackageAdmin packageAdmin = getBundleAdmin();
    246         if (packageAdmin == null)
    247             return null;
    248         Bundle[] bundles = packageAdmin.getBundles(symbolicName, version);
    249         if (bundles == null)
    250             return null;
    251         // optimize for common case; length==1
    252         if (bundles.length == 1 && (bundles[0].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0)
    253             return bundles;
    254         //Remove all the bundles that are installed or uninstalled
    255         Bundle[] selectedBundles = new Bundle[bundles.length];
    256         int added = 0;
    257         for (int i = 0; i < bundles.length; i++) {
    258             if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
    259                 selectedBundles[added++] = bundles[i];
    260             }
    261         }
    262         if (added == 0)
    263             return null;
    264 
    265         //return an array of the correct size
    266         Bundle[] results = new Bundle[added];
    267         System.arraycopy(selectedBundles, 0, results, 0, added);
    268         return results;
    269     }
    270 
    271     public String[] getCommandLineArgs() {
    272         return CommandLineArgs.getAllArgs();
    273     }
    274 
    275     public Location getConfigurationLocation() {
    276         assertInitialized();
    277         return (Location) configurationLocation.getService();
    278     }
    279 
    280     /**
    281      * Lazy initialize ContentTypeManager - it can only be used after the registry is up and running
    282      */
    283     public IContentTypeManager getContentTypeManager() {
    284         return contentTracker == null ? null : (IContentTypeManager) contentTracker.getService();
    285     }
    286 
    287     public EnvironmentInfo getEnvironmentInfoService() {
    288         return  environmentTracker == null ? null : (EnvironmentInfo) environmentTracker.getService();
    289     }
    290 
    291     public Bundle[] getFragments(Bundle bundle) {
    292         PackageAdmin packageAdmin = getBundleAdmin();
    293         if (packageAdmin == null)
    294             return null;
    295         return packageAdmin.getFragments(bundle);
    296     }
    297 
    298     public FrameworkLog getFrameworkLog() {
    299         return logTracker == null ? null : (FrameworkLog) logTracker.getService();
    300     }
    301 
    302     public Bundle[] getHosts(Bundle bundle) {
    303         PackageAdmin packageAdmin = getBundleAdmin();
    304         if (packageAdmin == null)
    305             return null;
    306         return packageAdmin.getHosts(bundle);
    307     }
    308 
    309     public Location getInstallLocation() {
    310         assertInitialized();
    311         return (Location) installLocation.getService();
    312     }
    313 
    314     public URL getInstallURL() {
    315         Location location = getInstallLocation();
    316         // it is pretty much impossible for the install location to be null.  If it is, the
    317         // system is in a bad way so throw and exception and get the heck outta here.
    318         if (location == null)
    319             throw new IllegalStateException("The installation location must not be null"); //$NON-NLS-1$
    320         return location.getURL();
    321     }
    322 
    323     public Location getInstanceLocation() {
    324         assertInitialized();
    325         return (Location) instanceLocation.getService();
    326     }
    327 
    328     /**
    329      * @see Platform#getLocation()
    330      */
    331     public IPath getLocation() throws IllegalStateException {
    332         if (cachedInstanceLocation == null) {
    333             Location location = getInstanceLocation();
    334             if (location == null)
    335                 return null;
    336             //    This makes the assumption that the instance location is a file: URL
    337             File file = new File(location.getURL().getFile());
    338             cachedInstanceLocation = new Path(file.toString());
    339         }
    340         return cachedInstanceLocation;
    341     }
    342 
    343     /**
    344      * Returns a log for the given plugin. Creates a new one if needed.
    345      * XXX change this into a LogMgr service that would keep track of the map. See if it can be a service factory.
    346      * It would contain all the logging methods that are here.
    347      * Relate to RuntimeLog if appropriate.
    348      * The system log listener needs to be optional: turned on or off. What about a system property? :-)
    349      */
    350     public ILog getLog(Bundle bundle) {
    351         Log result = (Log) logs.get(bundle);
    352         if (result != null)
    353             return result;
    354         ExtendedLogService logService = (ExtendedLogService) extendedLogTracker.getService();
    355         Logger logger = logService == null ? null : logService.getLogger(bundle, PlatformLogWriter.EQUINOX_LOGGER_NAME);
    356         result = new Log(bundle, logger);
    357         ExtendedLogReaderService logReader = (ExtendedLogReaderService) logReaderTracker.getService();
    358         logReader.addLogListener(result, result);
    359         logs.put(bundle, result);
    360         return result;
    361     }
    362 
    363     /**
    364      * Returns the object which defines the location and organization
    365      * of the platform's meta area.
    366      */
    367     public DataArea getMetaArea() {
    368         // TODO: deprecate?
    369         return MetaDataKeeper.getMetaArea();
    370     }
    371 
    372     public String getNL() {
    373         return getBundleContext().getProperty(PROP_NL);
    374     }
    375 
    376     /**
    377      * Unicode locale extensions are defined using command line parameter -nlExtensions,
    378      * or the system property "osgi.nl.extensions".
    379      */
    380     public String getNLExtensions() {
    381         String nlExtensions = PlatformActivator.getContext().getProperty("osgi.nl.extensions"); //$NON-NLS-1$
    382         if (nlExtensions == null)
    383             return ""; //$NON-NLS-1$
    384         if (!nlExtensions.startsWith("@")) //$NON-NLS-1$
    385             nlExtensions = '@' + nlExtensions;
    386         return nlExtensions;
    387     }
    388 
    389     /**
    390      * @see Platform
    391      */
    392     public String getOption(String option) {
    393         DebugOptions options = getDebugOptions();
    394         if (options != null)
    395             return options.getOption(option);
    396         return null;
    397     }
    398 
    399     public String getOS() {
    400         return getBundleContext().getProperty(PROP_OS);
    401     }
    402 
    403     public String getOSArch() {
    404         return getBundleContext().getProperty(PROP_ARCH);
    405     }
    406 
    407     public PlatformAdmin getPlatformAdmin() {
    408         if (context == null)
    409             return null;
    410         ServiceReference platformAdminReference = context.getServiceReference(PlatformAdmin.class.getName());
    411         if (platformAdminReference == null)
    412             return null;
    413         return (PlatformAdmin) context.getService(platformAdminReference);
    414     }
    415 
    416     //TODO I guess it is now time to get rid of that
    417     /*
    418      * This method is retained for R1.0 compatibility because it is defined as API.
    419      * Its function matches the API description (returns <code>null</code> when
    420      * argument URL is <code>null</code> or cannot be read).
    421      */
    422     public URL[] getPluginPath(URL pluginPathLocation /*R1.0 compatibility*/
    423     ) {
    424         InputStream input = null;
    425         // first try and see if the given plugin path location exists.
    426         if (pluginPathLocation == null)
    427             return null;
    428         try {
    429             input = pluginPathLocation.openStream();
    430         } catch (IOException e) {
    431             //fall through
    432         }
    433 
    434         // if the given path was null or did not exist, look for a plugin path
    435         // definition in the install location.
    436         if (input == null)
    437             try {
    438                 URL url = new URL("platform:/base/" + PLUGIN_PATH); //$NON-NLS-1$
    439                 input = url.openStream();
    440             } catch (MalformedURLException e) {
    441                 //fall through
    442             } catch (IOException e) {
    443                 //fall through
    444             }
    445 
    446         // nothing was found at the supplied location or in the install location
    447         if (input == null)
    448             return null;
    449         // if we found a plugin path definition somewhere so read it and close the location.
    450         URL[] result = null;
    451         try {
    452             try {
    453                 result = readPluginPath(input);
    454             } finally {
    455                 input.close();
    456             }
    457         } catch (IOException e) {
    458             //let it return null on failure to read
    459         }
    460         return result;
    461     }
    462 
    463     /**
    464      * 
    465      */
    466     public IPreferencesService getPreferencesService() {
    467         return preferencesTracker == null ? null : (IPreferencesService) preferencesTracker.getService();
    468     }
    469 
    470     /*
    471      * XXX move this into the app model.
    472      */
    473     public IProduct getProduct() {
    474         if (product != null)
    475             return product;
    476         EclipseAppContainer container = Activator.getContainer();
    477         IBranding branding = container == null ? null : container.getBranding();
    478         if (branding == null)
    479             return null;
    480         Object brandingProduct = branding.getProduct();
    481         if (!(brandingProduct instanceof IProduct))
    482             brandingProduct = new Product(branding);
    483         product = (IProduct) brandingProduct;
    484         return product;
    485     }
    486 
    487     public IExtensionRegistry getRegistry() {
    488         return RegistryFactory.getRegistry();
    489     }
    490 
    491     /**
    492      * XXX deprecate and use NLS or BundleFinder.find()
    493      */
    494     public ResourceBundle getResourceBundle(Bundle bundle) {
    495         return ResourceTranslator.getResourceBundle(bundle);
    496     }
    497 
    498     /**
    499      * XXX deprecate and use NLS or BundleFinder.find()
    500      */
    501     public String getResourceString(Bundle bundle, String value) {
    502         return ResourceTranslator.getResourceString(bundle, value);
    503     }
    504 
    505     /**
    506      * XXX deprecate and use NLS or BundleFinder.find()
    507      */
    508     public String getResourceString(Bundle bundle, String value, ResourceBundle resourceBundle) {
    509         return ResourceTranslator.getResourceString(bundle, value, resourceBundle);
    510     }
    511 
    512     /**
    513      * This method is only used to register runtime once compatibility has been started.
    514      */
    515     public Plugin getRuntimeInstance() {
    516         return runtimeInstance;
    517     }
    518 
    519     private IApplicationContext getApplicationContext() {
    520         ServiceReference[] ref;
    521         try {
    522             ref = context.getServiceReferences(IApplicationContext.class.getName(), "(eclipse.application.type=main.thread)"); //$NON-NLS-1$
    523         } catch (InvalidSyntaxException e) {
    524             return null;
    525         }
    526         if (ref == null || ref.length == 0)
    527             return null;
    528         // assumes the application context is available as a service
    529         IApplicationContext result = (IApplicationContext) context.getService(ref[0]);
    530         if (result != null) {
    531             context.ungetService(ref[0]);
    532             return result;
    533         }
    534         return null;
    535     }
    536 
    537     /**
    538      * XXX Investigate the usage of a service factory
    539      */
    540     public IPath getStateLocation(Bundle bundle) {
    541         return getStateLocation(bundle, true);
    542     }
    543 
    544     public IPath getStateLocation(Bundle bundle, boolean create) throws IllegalStateException {
    545         assertInitialized();
    546         IPath result = getMetaArea().getStateLocation(bundle);
    547         if (create)
    548             result.toFile().mkdirs();
    549         return result;
    550     }
    551 
    552     public long getStateTimeStamp() {
    553         PlatformAdmin admin = getPlatformAdmin();
    554         return admin == null ? -1 : admin.getState(false).getTimeStamp();
    555     }
    556 
    557     public Location getUserLocation() {
    558         assertInitialized();
    559         return (Location) userLocation.getService();
    560     }
    561 
    562     public String getWS() {
    563         return getBundleContext().getProperty(PROP_WS);
    564     }
    565 
    566     private void initializeAuthorizationHandler() {
    567         try {
    568             AuthorizationHandler.setKeyringFile(keyringFile);
    569             AuthorizationHandler.setPassword(password);
    570         } catch (NoClassDefFoundError e) {
    571             // The authorization fragment is not available. If someone tries to use that API, an error will be logged
    572         }
    573     }
    574 
    575     /*
    576      * Finds and loads the options file 
    577      */
    578     void initializeDebugFlags() {
    579         // load runtime options
    580         DEBUG = getBooleanOption(Platform.PI_RUNTIME + "/debug", false); //$NON-NLS-1$
    581         if (DEBUG) {
    582             DEBUG_PLUGIN_PREFERENCES = getBooleanOption(Platform.PI_RUNTIME + "/preferences/plugin", false); //$NON-NLS-1$
    583         }
    584     }
    585 
    586     public boolean isFragment(Bundle bundle) {
    587         PackageAdmin packageAdmin = getBundleAdmin();
    588         if (packageAdmin == null)
    589             return false;
    590         return (packageAdmin.getBundleType(bundle) & PackageAdmin.BUNDLE_TYPE_FRAGMENT) > 0;
    591     }
    592 
    593     /*
    594      *XXX do what you want to do. track osgi, track runtime, or whatever.
    595      */
    596     public boolean isRunning() {
    597         try {
    598             return initialized && context != null && context.getBundle().getState() == Bundle.ACTIVE;
    599         } catch (IllegalStateException e) {
    600             return false;
    601         }
    602     }
    603 
    604     /**
    605      * Returns a list of known system architectures.
    606      * 
    607      * @return the list of system architectures known to the system
    608      * XXX This is useless
    609      */
    610     public String[] knownOSArchValues() {
    611         return ARCH_LIST;
    612     }
    613 
    614     /**
    615      * Returns a list of known operating system names.
    616      * 
    617      * @return the list of operating systems known to the system
    618      * XXX This is useless
    619      */
    620     public String[] knownOSValues() {
    621         return OS_LIST;
    622     }
    623 
    624     /**
    625      * Returns a list of known windowing system names.
    626      * 
    627      * @return the list of window systems known to the system
    628      * XXX This is useless
    629      */
    630     public String[] knownWSValues() {
    631         return WS_LIST;
    632     }
    633 
    634     /**
    635      * Notifies all listeners of the platform log.  This includes the console log, if 
    636      * used, and the platform log file.  All Plugin log messages get funnelled
    637      * through here as well.
    638      */
    639     public void log(final IStatus status) {
    640         // TODO: deprecate?
    641         RuntimeLog.log(status);
    642     }
    643 
    644     private void processCommandLine(String[] args) {
    645         if (args == null || args.length == 0)
    646             return;
    647 
    648         for (int i = 0; i < args.length; i++) {
    649             // check for args with parameters
    650             if (i == args.length - 1 || args[i + 1].startsWith("-")) //$NON-NLS-1$
    651                 continue;
    652             String arg = args[++i];
    653 
    654             // look for the keyring file
    655             if (args[i - 1].equalsIgnoreCase(KEYRING))
    656                 keyringFile = arg;
    657             // look for the user password.  
    658             if (args[i - 1].equalsIgnoreCase(PASSWORD))
    659                 password = arg;
    660         }
    661     }
    662 
    663     private URL[] readPluginPath(InputStream input) {
    664         Properties ini = new Properties();
    665         try {
    666             ini.load(input);
    667         } catch (IOException e) {
    668             return null;
    669         }
    670         Vector result = new Vector(5);
    671         for (Enumeration groups = ini.propertyNames(); groups.hasMoreElements();) {
    672             String group = (String) groups.nextElement();
    673             for (StringTokenizer entries = new StringTokenizer(ini.getProperty(group), ";"); entries.hasMoreElements();) { //$NON-NLS-1$
    674                 String entry = (String) entries.nextElement();
    675                 if (!entry.equals("")) //$NON-NLS-1$
    676                     try {
    677                         result.addElement(new URL(entry));
    678                     } catch (MalformedURLException e) {
    679                         //intentionally ignore bad URLs
    680                         System.err.println("Ignoring plugin: " + entry); //$NON-NLS-1$
    681                     }
    682             }
    683         }
    684         return (URL[]) result.toArray(new URL[result.size()]);
    685     }
    686 
    687     /**
    688      * @see Platform#removeLogListener(ILogListener)
    689      */
    690     public void removeLogListener(ILogListener listener) {
    691         assertInitialized();
    692         RuntimeLog.removeLogListener(listener);
    693     }
    694 
    695     /**
    696      * This method is only used to register runtime once compatibility has been started.
    697      */
    698     public void setRuntimeInstance(Plugin runtime) {
    699         runtimeInstance = runtime;
    700     }
    701 
    702     /**
    703      * Internal method for starting up the platform.  The platform is not started with any location
    704      * and should not try to access the instance data area.
    705      * 
    706      * Note: the content type manager must be initialized only after the registry has been created
    707      */
    708     public void start(BundleContext runtimeContext) {
    709         this.context = runtimeContext;
    710         openOSGiTrackers();
    711         splashEnded = false;
    712         processCommandLine(getEnvironmentInfoService().getNonFrameworkArgs());
    713         initializeDebugFlags();
    714         initialized = true;
    715         getMetaArea();
    716         initializeAuthorizationHandler();
    717         startServices();
    718 
    719         // See if need to activate rest of the runtime plugins. Plugins are "gently" activated by touching 
    720         // a class from the corresponding plugin(s). 
    721         boolean shouldActivate = !"false".equalsIgnoreCase(context.getProperty(PROP_ACTIVATE_PLUGINS)); //$NON-NLS-1$
    722         if (shouldActivate) {
    723             // activate Preferences plugin by creating a class from it:
    724             new org.eclipse.core.runtime.preferences.DefaultScope();
    725             // activate Jobs plugin by creating a class from it:
    726             org.eclipse.core.runtime.jobs.Job.getJobManager();
    727         }
    728     }
    729 
    730     /**
    731      * Shutdown runtime pieces in this order:
    732      * Content[auto shutdown] -> Preferences[auto shutdown] -> Registry -> Jobs
    733      * The "auto" shutdown takes place before this code is executed
    734      */
    735     public void stop(BundleContext bundleContext) {
    736         assertInitialized();
    737         stopServices(); // should be done after preferences shutdown
    738         initialized = false;
    739         closeOSGITrackers();
    740         context = null;
    741     }
    742 
    743     private void openOSGiTrackers() {
    744         Filter filter = null;
    745         try {
    746             filter = context.createFilter(Location.INSTANCE_FILTER);
    747         } catch (InvalidSyntaxException e) {
    748             // ignore this.  It should never happen as we have tested the above format.
    749         }
    750         instanceLocation = new ServiceTracker(context, filter, null);
    751         instanceLocation.open();
    752         
    753         try {
    754             filter = context.createFilter(Location.USER_FILTER);
    755         } catch (InvalidSyntaxException e) {
    756             // ignore this.  It should never happen as we have tested the above format.
    757         }
    758         userLocation = new ServiceTracker(context, filter, null);
    759         userLocation.open();
    760         
    761         try {
    762             filter = context.createFilter(Location.CONFIGURATION_FILTER);
    763         } catch (InvalidSyntaxException e) {
    764             // ignore this.  It should never happen as we have tested the above format.
    765         }
    766         configurationLocation = new ServiceTracker(context, filter, null);
    767         configurationLocation.open();
    768         
    769         try {
    770             filter = context.createFilter(Location.INSTALL_FILTER);
    771         } catch (InvalidSyntaxException e) {
    772             // ignore this.  It should never happen as we have tested the above format.
    773         }
    774         installLocation = new ServiceTracker(context, filter, null);
    775         installLocation.open();
    776         
    777         if (context != null) {
    778             logTracker = new ServiceTracker(context, FrameworkLog.class.getName(), null);
    779             logTracker.open();
    780         }
    781         
    782         if (context != null) {
    783             bundleTracker = new ServiceTracker(context, PackageAdmin.class.getName(), null);
    784             bundleTracker.open();
    785         }
    786         
    787         if (context != null) {
    788             contentTracker = new ServiceTracker(context, IContentTypeManager.class.getName(), null);
    789             contentTracker.open();
    790         }
    791         
    792         if (context != null) {
    793             preferencesTracker = new ServiceTracker(context, IPreferencesService.class.getName(), null);
    794             preferencesTracker.open();
    795         }
    796         
    797         try {
    798             filter = context.createFilter("(objectClass=" + IBundleGroupProvider.class.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
    799         } catch (InvalidSyntaxException e) {
    800             // ignore this, it should never happen
    801         }
    802         groupProviderTracker = new ServiceTracker(context, filter, null);
    803         groupProviderTracker.open();
    804         
    805         logReaderTracker = new ServiceTracker(context, ExtendedLogReaderService.class.getName(), null);
    806         logReaderTracker.open();
    807         
    808         extendedLogTracker = new ServiceTracker(context, ExtendedLogService.class.getName(), null);
    809         extendedLogTracker.open();
    810         
    811         environmentTracker = new ServiceTracker(context, EnvironmentInfo.class.getName(), null);
    812         environmentTracker.open();
    813 
    814         debugTracker = new ServiceTracker(context, DebugOptions.class.getName(), null);
    815         debugTracker.open();
    816     }
    817 
    818     private void startServices() {
    819         // The check for getProduct() is relatively expensive (about 3% of the headless startup),
    820         // so we don't want to enforce it here. 
    821         customPreferencesService = context.registerService(IProductPreferencesService.class.getName(), new ProductPreferencesService(), new Hashtable());
    822 
    823         // Only register this interface if compatibility is installed - the check for a bundle presence
    824         // is a quick test that doesn't consume much.
    825         if (getBundle(CompatibilityHelper.PI_RUNTIME_COMPATIBILITY) != null)
    826             legacyPreferencesService = context.registerService(ILegacyPreferences.class.getName(), new InitLegacyPreferences(), new Hashtable());
    827     }
    828 
    829     private void stopServices() {
    830         if (legacyPreferencesService != null) {
    831             legacyPreferencesService.unregister();
    832             legacyPreferencesService = null;
    833         }
    834         if (customPreferencesService != null) {
    835             customPreferencesService.unregister();
    836             customPreferencesService = null;
    837         }
    838     }
    839 
    840     private PackageAdmin getBundleAdmin() {
    841         return bundleTracker == null ? null : (PackageAdmin) bundleTracker.getService();
    842     }
    843 
    844     private DebugOptions getDebugOptions() {
    845         return debugTracker == null ? null : (DebugOptions) debugTracker.getService();
    846     }
    847 
    848     private void closeOSGITrackers() {
    849         if (preferencesTracker != null) {
    850             preferencesTracker.close();
    851             preferencesTracker = null;
    852         }
    853         if (contentTracker != null) {
    854             contentTracker.close();
    855             contentTracker = null;
    856         }
    857         if (debugTracker != null) {
    858             debugTracker.close();
    859             debugTracker = null;
    860         }
    861         if (bundleTracker != null) {
    862             bundleTracker.close();
    863             bundleTracker = null;
    864         }
    865         if (logTracker != null) {
    866             logTracker.close();
    867             logTracker = null;
    868         }
    869         if (groupProviderTracker != null) {
    870             groupProviderTracker.close();
    871             groupProviderTracker = null;
    872         }
    873         if (environmentTracker != null) {
    874             environmentTracker.close();
    875             environmentTracker = null;
    876         }
    877         if (logReaderTracker != null) {
    878             logReaderTracker.close();
    879             logReaderTracker = null;
    880         }
    881         if (extendedLogTracker != null) {
    882             extendedLogTracker.close();
    883             extendedLogTracker = null;
    884         }
    885         if (installLocation != null) {
    886             installLocation.close();
    887             installLocation = null;
    888         }
    889         if (userLocation != null) {
    890             userLocation.close();
    891             userLocation = null;
    892         }
    893         if (configurationLocation != null) {
    894             configurationLocation.close();
    895             configurationLocation = null;
    896         }
    897         if (instanceLocation != null) {
    898             instanceLocation.close();
    899             instanceLocation = null;
    900         }
    901     }
    902 
    903     /**
    904      * Print a debug message to the console. 
    905      * Pre-pend the message with the current date and the name of the current thread.
    906      */
    907     public static void message(String message) {
    908         StringBuffer buffer = new StringBuffer();
    909         buffer.append(new Date(System.currentTimeMillis()));
    910         buffer.append(" - ["); //$NON-NLS-1$
    911         buffer.append(Thread.currentThread().getName());
    912         buffer.append("] "); //$NON-NLS-1$
    913         buffer.append(message);
    914         System.out.println(buffer.toString());
    915     }
    916 
    917     public static void start(Bundle bundle) throws BundleException {
    918         int originalState = bundle.getState();
    919         if ((originalState & Bundle.ACTIVE) != 0)
    920             return; // bundle is already active
    921         try {
    922             // attempt to activate the bundle
    923             bundle.start(Bundle.START_TRANSIENT);
    924         } catch (BundleException e) {
    925             if ((originalState & Bundle.STARTING) != 0 && (bundle.getState() & Bundle.STARTING) != 0)
    926                 // This can happen if the bundle was in the process of being activated on this thread, just return
    927                 return;
    928             throw e;
    929         }
    930     }
    931 }
    InternalPlatform
      1 package org.eclipse.core.runtime;
      2 public abstract class Plugin implements BundleActivator {
      3     public static final String PLUGIN_PREFERENCE_SCOPE = "instance"; 
      4     private Bundle bundle;
      5     private boolean debug = false;
      6     private ServiceTracker debugTracker = null;
      7     private IPluginDescriptor descriptor;
      8     public static final String PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME = "preferences"; //$NON-NLS-1$
      9     public static final String PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME = PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME + ".ini"; //$NON-NLS-1$
     10     private Preferences preferences = null;
     11     public Plugin() {
     12         super();
     13     }
     14     public Plugin(IPluginDescriptor descriptor) {
     15         Assert.isNotNull(descriptor);
     16         Assert.isTrue(!CompatibilityHelper.hasPluginObject(descriptor), NLS.bind(Messages.plugin_deactivatedLoad, this.getClass().getName(), descriptor.getUniqueIdentifier() + " is not activated")); //$NON-NLS-1$
     17         this.descriptor = descriptor;
     18 
     19         // on plugin start, find and start the corresponding bundle.
     20         bundle = InternalPlatform.getDefault().getBundle(descriptor.getUniqueIdentifier());
     21         try {
     22             InternalPlatform.start(bundle);
     23         } catch (BundleException e) {
     24             String message = NLS.bind(Messages.plugin_startupProblems, descriptor.getUniqueIdentifier());
     25             IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, message, e);
     26             InternalPlatform.getDefault().log(status);
     27         }
     28     }
     29     public final URL find(IPath path) {
     30         return FileLocator.find(getBundle(), path, null);
     31     }
     32     public final ILog getLog() {
     33         return InternalPlatform.getDefault().getLog(getBundle());
     34     }
     35     public final IPath getStateLocation() throws IllegalStateException {
     36         return InternalPlatform.getDefault().getStateLocation(getBundle(), true);
     37     }
     38     public boolean isDebugging() {
     39         Bundle debugBundle = getBundle();
     40         if (debugBundle == null)
     41             return debug;
     42         String key = debugBundle.getSymbolicName() + "/debug"; //$NON-NLS-1$
     43         // first check if platform debugging is enabled
     44         final DebugOptions debugOptions = getDebugOptions();
     45         if (debugOptions == null)
     46             return debug;
     47         // if platform debugging is enabled, check to see if this plugin is enabled for debugging
     48         return debugOptions.isDebugEnabled() ? InternalPlatform.getDefault().getBooleanOption(key, false) : false;
     49     }
     50     public void setDebugging(boolean value) {
     51         Bundle debugBundle = getBundle();
     52         if (debugBundle == null) {
     53             this.debug = value;
     54             return;
     55         }
     56         String key = debugBundle.getSymbolicName() + "/debug"; //$NON-NLS-1$
     57         final DebugOptions options = getDebugOptions();
     58         if (options == null)
     59             this.debug = value;
     60         else {
     61             if (!options.isDebugEnabled())
     62                 options.setDebugEnabled(true);
     63             options.setOption(key, value ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
     64         }
     65     }
     66     private DebugOptions getDebugOptions() {
     67         Bundle debugBundle = getBundle();
     68         if (debugBundle == null)
     69             return null;
     70         if (debugTracker == null) {
     71             BundleContext context = debugBundle.getBundleContext();
     72             if (context == null)
     73                 return null;
     74             debugTracker = new ServiceTracker(context, DebugOptions.class.getName(), null);
     75             debugTracker.open();
     76         }
     77         return (DebugOptions) this.debugTracker.getService();
     78     }
     79     public String toString() {
     80         Bundle myBundle = getBundle();
     81         if (myBundle == null)
     82             return ""; //$NON-NLS-1$
     83         String name = myBundle.getSymbolicName();
     84         return name == null ? new Long(myBundle.getBundleId()).toString() : name;
     85     }
     86     public void start(BundleContext context) throws Exception {
     87         bundle = context.getBundle();
     88         initializeDescriptor(bundle.getSymbolicName());
     89     }
     90     private IPluginDescriptor initializeDescriptor(String symbolicName) {
     91         if (CompatibilityHelper.initializeCompatibility() == null)
     92             return null;
     93 
     94         //This associate a descriptor to any real bundle that uses this to start
     95         if (symbolicName == null)
     96             return null;
     97 
     98         IPluginDescriptor tmp = CompatibilityHelper.getPluginDescriptor(symbolicName);
     99 
    100         //Runtime descriptor is never set to support dynamic re-installation of compatibility 
    101         if (!symbolicName.equals(Platform.PI_RUNTIME))
    102             descriptor = tmp;
    103 
    104         CompatibilityHelper.setPlugin(tmp, this);
    105         CompatibilityHelper.setActive(tmp);
    106         return tmp;
    107     }
    108     public void stop(BundleContext context) throws Exception {
    109 
    110         if (this.debugTracker != null) {
    111             this.debugTracker.close();
    112             this.debugTracker = null;
    113         }
    114         // sub-classes to override
    115     }
    116     public final Bundle getBundle() {
    117         if (bundle != null)
    118             return bundle;
    119         ClassLoader cl = getClass().getClassLoader();
    120         if (cl instanceof BundleReference)
    121             return ((BundleReference) cl).getBundle();
    122         return null;
    123     }
    124 }
    plugin
    •  1 public void start(BundleContext context) throws Exception {
       2         bundle = context.getBundle();
       3         initializeDescriptor(bundle.getSymbolicName());
       4     }
       5     private IPluginDescriptor initializeDescriptor(String symbolicName) {
       6         if (CompatibilityHelper.initializeCompatibility() == null)
       7             return null;
       8         //This associate a descriptor to any real bundle that uses this to start
       9         if (symbolicName == null)
      10             return null;
      11         IPluginDescriptor tmp = CompatibilityHelper.getPluginDescriptor(symbolicName);
      12         //Runtime descriptor is never set to support dynamic re-installation of compatibility 
      13         if (!symbolicName.equals(Platform.PI_RUNTIME))
      14             descriptor = tmp;
      15         CompatibilityHelper.setPlugin(tmp, this);
      16         CompatibilityHelper.setActive(tmp);
      17         return tmp;
      18     }
      1 public final Bundle getBundle() {
      2         if (bundle != null)
      3             return bundle;
      4         ClassLoader cl = getClass().getClassLoader();
      5         if (cl instanceof BundleReference)
      6             return ((BundleReference) cl).getBundle();
      7         return null;
      8 }
       1 public Plugin(IPluginDescriptor descriptor) {
       2         Assert.isNotNull(descriptor);
       3         Assert.isTrue(!CompatibilityHelper.hasPluginObject(descriptor), NLS.bind(Messages.plugin_deactivatedLoad, this.getClass().getName(), descriptor.getUniqueIdentifier() + " is not activated")); //$NON-NLS-1$
       4         this.descriptor = descriptor;
       5         // on plugin start, find and start the corresponding bundle.
       6         bundle = InternalPlatform.getDefault().getBundle(descriptor.getUniqueIdentifier());
       7         try {
       8             InternalPlatform.start(bundle);
       9         } catch (BundleException e) {
      10             String message = NLS.bind(Messages.plugin_startupProblems, descriptor.getUniqueIdentifier());
      11             IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, message, e);
      12             InternalPlatform.getDefault().log(status);
      13         }
      14     } 
    • AbstractUIPlugin
    •   1 package org.eclipse.ui.plugin;
        2 public abstract class AbstractUIPlugin extends Plugin {
        3     private static final String FN_DIALOG_SETTINGS = "dialog_settings.xml"; //$NON-NLS-1$
        4     private IDialogSettings dialogSettings = null;
        5     private ScopedPreferenceStore preferenceStore;
        6     private ImageRegistry imageRegistry = null;
        7     private BundleListener bundleListener;
        8     public AbstractUIPlugin() {
        9         super();
       10     }
       11     protected ImageRegistry createImageRegistry() {        
       12         //If we are in the UI Thread use that
       13         if(Display.getCurrent() != null) {
       14             return new ImageRegistry(Display.getCurrent());
       15         }        
       16         if(PlatformUI.isWorkbenchRunning()) {
       17             return new ImageRegistry(PlatformUI.getWorkbench().getDisplay());
       18         }        
       19         //Invalid thread access if it is not the UI Thread 
       20         //and the workbench is not created.
       21         throw new SWTError(SWT.ERROR_THREAD_INVALID_ACCESS);
       22     }
       23     public IDialogSettings getDialogSettings() {
       24         if (dialogSettings == null) {
       25             loadDialogSettings();
       26         }
       27         return dialogSettings;
       28     }
       29     public ImageRegistry getImageRegistry() {
       30         if (imageRegistry == null) {
       31             imageRegistry = createImageRegistry();
       32             initializeImageRegistry(imageRegistry);
       33         }
       34         return imageRegistry;
       35     }
       36     public IPreferenceStore getPreferenceStore() {
       37         // Create the preference store lazily.
       38         if (preferenceStore == null) {
       39             preferenceStore = new ScopedPreferenceStore(new InstanceScope(),getBundle().getSymbolicName());
       40 
       41         }
       42         return preferenceStore;
       43     }
       44     public IWorkbench getWorkbench() {
       45         return PlatformUI.getWorkbench();
       46     }
       47     protected void initializeDefaultPreferences(IPreferenceStore store) {
       48         // spec'ed to do nothing
       49     }
       50     protected void initializeDefaultPluginPreferences() {
       51         initializeDefaultPreferences(getPreferenceStore());
       52     }
       53     protected void initializeImageRegistry(ImageRegistry reg) {
       54         // spec'ed to do nothing
       55     }
       56     protected void loadDialogSettings() {
       57         dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
       58         IPath dataLocation = getStateLocationOrNull();
       59         if (dataLocation != null) {
       60             String readWritePath = dataLocation.append(FN_DIALOG_SETTINGS)
       61                     .toOSString();
       62             File settingsFile = new File(readWritePath);
       63             if (settingsFile.exists()) {
       64                 try {
       65                     dialogSettings.load(readWritePath);
       66                 } catch (IOException e) {
       67                     // load failed so ensure we have an empty settings
       68                     dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
       69                 }                
       70                 return;
       71             }
       72         }
       73         // otherwise look for bundle specific dialog settings
       74         URL dsURL = BundleUtility.find(getBundle(), FN_DIALOG_SETTINGS);
       75         if (dsURL == null) {
       76             return;
       77         }
       78         InputStream is = null;
       79         try {
       80             is = dsURL.openStream();
       81             BufferedReader reader = new BufferedReader(
       82                     new InputStreamReader(is, "utf-8")); //$NON-NLS-1$
       83             dialogSettings.load(reader);
       84         } catch (IOException e) {
       85             // load failed so ensure we have an empty settings
       86             dialogSettings = new DialogSettings("Workbench"); //$NON-NLS-1$
       87         } finally {
       88             try {
       89                 if (is != null) {
       90                     is.close();
       91                 }
       92             } catch (IOException e) {
       93                 // do nothing
       94             }
       95         }
       96     }
       97     protected void loadPreferenceStore() {
       98         // do nothing by default 
       99     }
      100     protected void refreshPluginActions() {
      101         // If the workbench is not started yet, or is no longer running, do nothing.
      102         if (!PlatformUI.isWorkbenchRunning()) {
      103             return;
      104         }
      105         Display.getDefault().asyncExec(new Runnable() {
      106             public void run() {
      107                 WWinPluginAction.refreshActionList();
      108             }
      109         });
      110     }
      111     protected void saveDialogSettings() {
      112         if (dialogSettings == null) {
      113             return;
      114         }
      115         try {
      116             IPath path = getStateLocationOrNull();
      117             if(path == null) {
      118                 return;
      119             }
      120             String readWritePath = path
      121                     .append(FN_DIALOG_SETTINGS).toOSString();
      122             dialogSettings.save(readWritePath);
      123         } catch (IOException e) {
      124             // spec'ed to ignore problems
      125         } catch (IllegalStateException e) {
      126             // spec'ed to ignore problems
      127         }
      128     }
      129     public void startup() throws CoreException {
      130         // this method no longer does anything
      131         // the code that used to be here in 2.1 has moved to start(BundleContext)
      132         super.startup();
      133     }
      134     public void shutdown() throws CoreException {
      135         // this method no longer does anything interesting
      136         // the code that used to be here in 2.1 has moved to stop(BundleContext),
      137         //   which is called regardless of whether the plug-in being instantiated
      138         //   requires org.eclipse.core.runtime.compatibility
      139         super.shutdown();
      140     }
      141     public void start(BundleContext context) throws Exception {
      142         super.start(context);
      143         final BundleContext fc = context;
      144         // Should only attempt refreshPluginActions() once the bundle
      145         // has been fully started.  Otherwise, action delegates
      146         // can be created while in the process of creating 
      147         // a triggering action delegate (if UI events are processed during startup).  
      148         // Also, if the start throws an exception, the bundle will be shut down.  
      149         // We don't want to have created any delegates if this happens.
      150         // See bug 63324 for more details.
      151         bundleListener = new BundleListener() {
      152             public void bundleChanged(BundleEvent event) {
      153                 if (event.getBundle() == getBundle()) {
      154                     if (event.getType() == BundleEvent.STARTED) {
      155                         // We're getting notified that the bundle has been started.
      156                         // Make sure it's still active.  It may have been shut down between
      157                         // the time this event was queued and now.
      158                         if (getBundle().getState() == Bundle.ACTIVE) {
      159                             refreshPluginActions();
      160                         }
      161                         fc.removeBundleListener(this);
      162                     }
      163                 }
      164             }
      165         };
      166         context.addBundleListener(bundleListener);
      167         // bundleListener is removed in stop(BundleContext)
      168     }
      169     public void stop(BundleContext context) throws Exception {
      170         try {
      171             if (bundleListener != null) {
      172                 context.removeBundleListener(bundleListener);
      173             }
      174             saveDialogSettings();
      175             savePreferenceStore();
      176             preferenceStore = null;
      177             if (imageRegistry != null)
      178                 imageRegistry.dispose();
      179             imageRegistry = null;
      180         } finally {
      181             super.stop(context);
      182         }
      183     }
      184     public static ImageDescriptor imageDescriptorFromPlugin(String pluginId,
      185             String imageFilePath) {
      186         if (pluginId == null || imageFilePath == null) {
      187             throw new IllegalArgumentException();
      188         }
      189 
      190         IWorkbench workbench = PlatformUI.isWorkbenchRunning() ? PlatformUI.getWorkbench() : null;
      191         ImageDescriptor imageDescriptor = workbench == null ? null : workbench
      192                 .getSharedImages().getImageDescriptor(imageFilePath);
      193         if (imageDescriptor != null)
      194             return imageDescriptor; // found in the shared images
      195 
      196         // if the bundle is not ready then there is no image
      197         Bundle bundle = Platform.getBundle(pluginId);
      198         if (!BundleUtility.isReady(bundle)) {
      199             return null;
      200         }
      201 
      202         // look for the image (this will check both the plugin and fragment folders
      203         URL fullPathString = BundleUtility.find(bundle, imageFilePath);
      204         if (fullPathString == null) {
      205             try {
      206                 fullPathString = new URL(imageFilePath);
      207             } catch (MalformedURLException e) {
      208                 return null;
      209             }
      210         }
      211         return ImageDescriptor.createFromURL(fullPathString);
      212     }
      213     private IPath getStateLocationOrNull() {
      214         try {
      215             return getStateLocation();
      216         } catch (IllegalStateException e) {
      217             // This occurs if -data=@none is explicitly specified, so ignore this silently.
      218             // Is this OK? See bug 85071.
      219             return null;
      220         }
      221     }        
      222 }
      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 command link 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
              // 320932
              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.

    •  1 package com.dragon.contribution.junit;
       2 import org.eclipse.jface.resource.ImageDescriptor;
       3 import org.eclipse.ui.plugin.AbstractUIPlugin;
       4 import org.osgi.framework.BundleContext;
       5 /**
       6  * The activator class controls the plug-in life cycle
       7  */
       8 public class Activator extends AbstractUIPlugin {
       9     // The plug-in ID
      10     public static final String PLUGIN_ID = "com.dragon.contribution.junit"; //$NON-NLS-1$
      11     // The shared instance
      12     private static Activator plugin;
      13     public Activator() {
      14     }
      15     public void start(BundleContext context) throws Exception {
      16         super.start(context);
      17         plugin = this;
      18     }
      19     public void stop(BundleContext context) throws Exception {
      20         plugin = null;
      21         super.stop(context);
      22     }
      23     public static Activator getDefault() {
      24         return plugin;
      25     }
      26     public static ImageDescriptor getImageDescriptor(String path) {
      27         return imageDescriptorFromPlugin(PLUGIN_ID, path);
      28     }
      29 } 
    • Framework activate a bundle
    •  1     at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:734)
       2     at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
       3     at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
       4     at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:390)
       5     at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1177)
       6     at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559)
       7     at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544)
       8     at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457)
       9     at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243)
      10     at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438)
      11     at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1)
      12     at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
      13     at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
  • 相关阅读:
    20200311 1. 消息中间件概述
    20200311 0. RabbitMQ 安装
    20210309 java.lang.Integer
    20210304. Redis【归档】
    20210304. 8. Redis 大厂面试汇总
    20210304. 7. Redis 企业实战
    20210304. 6. Redis 高可用方案
    20210304. 5. Redis 扩展功能
    Evolution Strategies as a Scalable Alternative to Reinforcement Learning
    脉冲神经网络研究现状及展望——论文摘抄
  • 原文地址:https://www.cnblogs.com/iiiDragon/p/3300673.html
Copyright © 2011-2022 走看看