Develop and register service,html
lookup and use service!java
Android Design on service's publish-find-bind model.react
One simple example:shell
Service: windows
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:api
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
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.app
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.less
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.dom
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.eclipse
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.
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.
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 }
1 public interface BundleActivator { 2 public void start(BundleContext context) throws Exception; 3 public void stop(BundleContext context) throws Exception; 4 }
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 }
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 }
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 }
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 }
Here are the class we used in AbstractUIPlugin
When the Workbench is launched, the first thing you see is a dialog that allows you to select where the workspace should be located. The workspace is the directory where your work will be stored. For now, just click OK to pick the default location.After the workspace location is chosen, a single Workbench window is displayed. A Workbench window offers one or more perspectives. A perspective contains editors and views, such as the Project Explorer. Multiple Workbench windows can be opened simultaneously. Initially, in the first Workbench window that is opened, the Java perspective is displayed, with only the Welcome view visible. Click the arrow labeled Workbench in the Welcome view to cause the other views in the perspective to become visible. Note you can get the Welcome view back at any time by selecting Help > Welcome.A shortcut bar appears in the top right corner of the window. This allows you to open new perspectives and switch between ones already open. The name of the active perspective is shown in the title of the window and its item in the shortcut bar is highlighted.
/******************************************************************************* * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Francis Upton - <francisu@ieee.org> - * Fix for Bug 217777 [Workbench] Workbench event loop does not terminate if Display is closed *******************************************************************************/ package org.eclipse.ui.internal; import com.ibm.icu.util.ULocale; import com.ibm.icu.util.ULocale.Category; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.CommandManager; import org.eclipse.core.commands.CommandManagerEvent; import org.eclipse.core.commands.ICommandManagerListener; import org.eclipse.core.commands.common.EventManager; import org.eclipse.core.commands.contexts.ContextManager; import org.eclipse.core.commands.contexts.ContextManagerEvent; import org.eclipse.core.commands.contexts.IContextManagerListener; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionDelta; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IPlatformRunnable; import org.eclipse.core.runtime.IProduct; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IRegistryChangeEvent; import org.eclipse.core.runtime.IRegistryChangeListener; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.e4.core.contexts.ContextFunction; import org.eclipse.e4.core.contexts.ContextInjectionFactory; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.InjectionException; import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.e4.ui.internal.workbench.E4Workbench; import org.eclipse.e4.ui.internal.workbench.renderers.swt.IUpdateService; import org.eclipse.e4.ui.internal.workbench.swt.E4Application; import org.eclipse.e4.ui.internal.workbench.swt.IEventLoopAdvisor; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.commands.MBindingContext; import org.eclipse.e4.ui.model.application.commands.MBindingTable; import org.eclipse.e4.ui.model.application.commands.MCategory; import org.eclipse.e4.ui.model.application.commands.MCommand; import org.eclipse.e4.ui.model.application.commands.MCommandsFactory; import org.eclipse.e4.ui.model.application.commands.impl.CommandsFactoryImpl; import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; import org.eclipse.e4.ui.model.application.ui.MElementContainer; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.model.application.ui.basic.MWindow; import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicFactoryImpl; import org.eclipse.e4.ui.services.EContextService; import org.eclipse.e4.ui.workbench.IPresentationEngine; import org.eclipse.e4.ui.workbench.UIEvents; import org.eclipse.emf.ecore.EObject; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.ExternalActionManager; import org.eclipse.jface.action.ExternalActionManager.CommandCallback; import org.eclipse.jface.action.ExternalActionManager.IActiveChecker; import org.eclipse.jface.action.ExternalActionManager.IExecuteApplicable; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.bindings.BindingManager; import org.eclipse.jface.bindings.BindingManagerEvent; import org.eclipse.jface.bindings.IBindingManagerListener; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.ModalContext; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.OpenStrategy; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.window.IShellProvider; import org.eclipse.jface.window.Window; import org.eclipse.osgi.service.runnable.StartupMonitor; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.DeviceData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IDecoratorManager; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IEditorRegistry; import org.eclipse.ui.IElementFactory; import org.eclipse.ui.ILocalWorkingSetManager; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveRegistry; import org.eclipse.ui.ISaveableFilter; import org.eclipse.ui.ISaveablesLifecycleListener; import org.eclipse.ui.ISaveablesSource; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.ISourceProvider; import org.eclipse.ui.ISources; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.Saveable; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.activities.IWorkbenchActivitySupport; import org.eclipse.ui.application.WorkbenchAdvisor; import org.eclipse.ui.browser.IWorkbenchBrowserSupport; import org.eclipse.ui.commands.ICommandImageService; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.commands.IWorkbenchCommandSupport; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.contexts.IWorkbenchContextSupport; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.help.IWorkbenchHelpSystem; import org.eclipse.ui.internal.StartupThreading.StartupRunnable; import org.eclipse.ui.internal.actions.CommandAction; import org.eclipse.ui.internal.activities.ws.WorkbenchActivitySupport; import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport; import org.eclipse.ui.internal.commands.CommandImageManager; import org.eclipse.ui.internal.commands.CommandImageService; import org.eclipse.ui.internal.commands.CommandService; import org.eclipse.ui.internal.commands.WorkbenchCommandSupport; import org.eclipse.ui.internal.contexts.ActiveContextSourceProvider; import org.eclipse.ui.internal.contexts.ContextService; import org.eclipse.ui.internal.contexts.WorkbenchContextSupport; import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager; import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor; import org.eclipse.ui.internal.e4.compatibility.CompatibilityPart; import org.eclipse.ui.internal.e4.compatibility.E4Util; import org.eclipse.ui.internal.handlers.LegacyHandlerService; import org.eclipse.ui.internal.help.WorkbenchHelpSystem; import org.eclipse.ui.internal.intro.IIntroRegistry; import org.eclipse.ui.internal.intro.IntroDescriptor; import org.eclipse.ui.internal.keys.BindingService; import org.eclipse.ui.internal.menus.FocusControlSourceProvider; import org.eclipse.ui.internal.menus.WorkbenchMenuService; import org.eclipse.ui.internal.misc.Policy; import org.eclipse.ui.internal.misc.StatusUtil; import org.eclipse.ui.internal.misc.UIStats; import org.eclipse.ui.internal.model.ContributionService; import org.eclipse.ui.internal.progress.ProgressManager; import org.eclipse.ui.internal.progress.ProgressManagerUtil; import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; import org.eclipse.ui.internal.registry.UIExtensionTracker; import org.eclipse.ui.internal.registry.ViewDescriptor; import org.eclipse.ui.internal.services.EvaluationService; import org.eclipse.ui.internal.services.IServiceLocatorCreator; import org.eclipse.ui.internal.services.IWorkbenchLocationService; import org.eclipse.ui.internal.services.MenuSourceProvider; import org.eclipse.ui.internal.services.ServiceLocator; import org.eclipse.ui.internal.services.ServiceLocatorCreator; import org.eclipse.ui.internal.services.SourceProviderService; import org.eclipse.ui.internal.services.WorkbenchLocationService; import org.eclipse.ui.internal.splash.EclipseSplashHandler; import org.eclipse.ui.internal.splash.SplashHandlerFactory; import org.eclipse.ui.internal.testing.WorkbenchTestable; import org.eclipse.ui.internal.themes.ColorDefinition; import org.eclipse.ui.internal.themes.FontDefinition; import org.eclipse.ui.internal.themes.ThemeElementHelper; import org.eclipse.ui.internal.themes.WorkbenchThemeManager; import org.eclipse.ui.internal.tweaklets.GrabFocus; import org.eclipse.ui.internal.tweaklets.Tweaklets; import org.eclipse.ui.internal.util.PrefUtil; import org.eclipse.ui.internal.util.Util; import org.eclipse.ui.intro.IIntroManager; import org.eclipse.ui.keys.IBindingService; import org.eclipse.ui.menus.IMenuService; import org.eclipse.ui.model.IContributionService; import org.eclipse.ui.operations.IWorkbenchOperationSupport; import org.eclipse.ui.progress.IProgressService; import org.eclipse.ui.services.IDisposable; import org.eclipse.ui.services.IEvaluationService; import org.eclipse.ui.services.IServiceScopes; import org.eclipse.ui.services.ISourceProviderService; import org.eclipse.ui.splash.AbstractSplashHandler; import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.ui.swt.IFocusService; import org.eclipse.ui.themes.IThemeManager; import org.eclipse.ui.views.IViewDescriptor; import org.eclipse.ui.views.IViewRegistry; import org.eclipse.ui.wizards.IWizardRegistry; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.framework.SynchronousBundleListener; import org.osgi.service.event.EventHandler; import org.osgi.util.tracker.ServiceTracker; /** * The workbench class represents the top of the Eclipse user interface. Its * primary responsability is the management of workbench windows, dialogs, * wizards, and other workbench-related windows. * <p> * Note that any code that is run during the creation of a workbench instance * should not required access to the display. * </p> * <p> * Note that this internal class changed significantly between 2.1 and 3.0. * Applications that used to define subclasses of this internal class need to be * rewritten to use the new workbench advisor API. * </p> */ public final class Workbench extends EventManager implements IWorkbench { private final class StartupProgressBundleListener implements SynchronousBundleListener { private final IProgressMonitor progressMonitor; private final int maximumProgressCount; // stack of names of bundles currently starting private final List starting; StartupProgressBundleListener(IProgressMonitor progressMonitor, int maximumProgressCount) { super(); this.progressMonitor = progressMonitor; this.maximumProgressCount = maximumProgressCount; this.starting = new ArrayList(); } public void bundleChanged(BundleEvent event) { int eventType = event.getType(); String bundleName; synchronized (this) { if (eventType == BundleEvent.STARTING) { starting.add(bundleName = event.getBundle().getSymbolicName()); } else if (eventType == BundleEvent.STARTED) { progressCount++; if (progressCount <= maximumProgressCount) { progressMonitor.worked(1); } int index = starting.lastIndexOf(event.getBundle().getSymbolicName()); if (index >= 0) { starting.remove(index); } if (index != starting.size()) { return; // not currently displayed } bundleName = index == 0 ? null : (String) starting.get(index - 1); } else { return; // uninteresting event } } String taskName; if (bundleName == null) { taskName = WorkbenchMessages.Startup_Loading_Workbench; } else { taskName = NLS.bind(WorkbenchMessages.Startup_Loading, bundleName); } progressMonitor.subTask(taskName); } } /** * Family for the early startup job. */ public static final String EARLY_STARTUP_FAMILY = "earlyStartup"; //$NON-NLS-1$ static final String VERSION_STRING[] = { "0.046", "2.0" }; //$NON-NLS-1$ //$NON-NLS-2$ static final String DEFAULT_WORKBENCH_STATE_FILENAME = "workbench.xml"; //$NON-NLS-1$ /** * Holds onto the only instance of Workbench. */ private static Workbench instance; /** * The testable object facade. * * @since 3.0 */ private static WorkbenchTestable testableObject; /** * Signals that the workbench should create a splash implementation when * instantiated. Intial value is <code>true</code>. * * @since 3.3 */ private static boolean createSplash = true; /** * The splash handler. */ private static AbstractSplashHandler splash; /** * The display used for all UI interactions with this workbench. * * @since 3.0 */ private Display display; private EditorHistory editorHistory; private boolean runEventLoop = true; private boolean isStarting = true; private boolean isClosing = false; /** * A boolean field to indicate whether all the workbench windows have been * closed or not. */ private boolean windowsClosed = false; /** * PlatformUI return code (as opposed to IPlatformRunnable return code). */ private int returnCode = PlatformUI.RETURN_UNSTARTABLE; /** * Advisor providing application-specific configuration and customization of * the workbench. * * @since 3.0 */ private WorkbenchAdvisor advisor; /** * Object for configuring the workbench. Lazily initialized to an instance * unique to the workbench instance. * * @since 3.0 */ private WorkbenchConfigurer workbenchConfigurer; // for dynamic UI /** * ExtensionEventHandler handles extension life-cycle events. */ private ExtensionEventHandler extensionEventHandler; /** * A count of how many large updates are going on. This tracks nesting of * requests to disable services during a large update -- similar to the * <code>setRedraw</code> functionality on <code>Control</code>. When this * value becomes greater than zero, services are disabled. When this value * becomes zero, services are enabled. Please see * <code>largeUpdateStart()</code> and <code>largeUpdateEnd()</code>. */ private int largeUpdates = 0; /** * The service locator maintained by the workbench. These services are * initialized during workbench during the <code>init</code> method. */ private final ServiceLocator serviceLocator; /** * A count of how many plug-ins were loaded while restoring the workbench * state. Initially -1 for unknown number. */ private int progressCount = -1; /** * Listener list for registered IWorkbenchListeners . */ private ListenerList workbenchListeners = new ListenerList(ListenerList.IDENTITY); private ServiceRegistration workbenchService; private MApplication application; private IEclipseContext e4Context; private IEventBroker eventBroker; boolean initializationDone = false; private WorkbenchWindow windowBeingCreated = null; /** * Creates a new workbench. * * @param display * the display to be used for all UI interactions with the * workbench * @param advisor * the application-specific advisor that configures and * specializes this workbench instance * @since 3.0 */ private Workbench(Display display, final WorkbenchAdvisor advisor, MApplication app, IEclipseContext appContext) { super(); StartupThreading.setWorkbench(this); if (instance != null && instance.isRunning()) { throw new IllegalStateException(WorkbenchMessages.Workbench_CreatingWorkbenchTwice); } Assert.isNotNull(display); Assert.isNotNull(advisor); this.advisor = advisor; this.display = display; application = app; e4Context = appContext; Workbench.instance = this; eventBroker = (IEventBroker) e4Context.get(IEventBroker.class.getName()); appContext.set(getClass().getName(), this); appContext.set(IWorkbench.class.getName(), this); appContext.set(IEventLoopAdvisor.class, new IEventLoopAdvisor() { public void eventLoopIdle(Display display) { advisor.eventLoopIdle(display); } public void eventLoopException(Throwable exception) { advisor.eventLoopException(exception); } }); // for dynamic UI [This seems to be for everything that isn't handled by // some // subclass of RegistryManager. I think that when an extension is moved // to the // RegistryManager implementation, then it should be removed from the // list in // ExtensionEventHandler#appear. // I've found that the new wizard extension in particular is a poor // choice to // use as an example, since the result of reading the registry is not // cached // -- so it is re-read each time. The only real contribution of this // dialog is // to show the user a nice dialog describing the addition.] extensionEventHandler = new ExtensionEventHandler(this); Platform.getExtensionRegistry().addRegistryChangeListener(extensionEventHandler); IServiceLocatorCreator slc = new ServiceLocatorCreator(); serviceLocator = (ServiceLocator) slc.createServiceLocator(null, null, new IDisposable() { public void dispose() { final Display display = getDisplay(); if (display != null && !display.isDisposed()) { MessageDialog.openInformation(null, WorkbenchMessages.Workbench_NeedsClose_Title, WorkbenchMessages.Workbench_NeedsClose_Message); close(PlatformUI.RETURN_RESTART, true); } } }); serviceLocator.setContext(appContext); serviceLocator.registerService(IServiceLocatorCreator.class, slc); serviceLocator.registerService(IWorkbenchLocationService.class, new WorkbenchLocationService(IServiceScopes.WORKBENCH_SCOPE, this, null, null, null, null, 0)); } /** * Returns the one and only instance of the workbench, if there is one. * * @return the workbench, or <code>null</code> if the workbench has not been * created, or has been created and already completed */ public static final Workbench getInstance() { return instance; } /** * Creates the workbench and associates it with the the given display and * workbench advisor, and runs the workbench UI. This entails processing and * dispatching events until the workbench is closed or restarted. * <p> * This method is intended to be called by <code>PlatformUI</code>. Fails if * the workbench UI has already been created. * </p> * <p> * The display passed in must be the default display. * </p> * * @param display * the display to be used for all UI interactions with the * workbench * @param advisor * the application-specific advisor that configures and * specializes the workbench * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal * exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the * workbench was terminated with a call to * {@link IWorkbench#restart IWorkbench.restart}; other values * reserved for future use */ public static final int createAndRunWorkbench(final Display display, final WorkbenchAdvisor advisor) { final int[] returnCode = new int[1]; Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { public void run() { final String nlExtensions = Platform.getNLExtensions(); if (nlExtensions.length() > 0) { ULocale.setDefault(Category.FORMAT, new ULocale(ULocale.getDefault(Category.FORMAT).getBaseName() + nlExtensions)); } System.setProperty(E4Workbench.XMI_URI_ARG, "org.eclipse.ui.workbench/LegacyIDE.e4xmi"); //$NON-NLS-1$ Object obj = getApplication(Platform.getCommandLineArgs()); if (obj instanceof E4Application) { E4Application e4app = (E4Application) obj; E4Workbench e4Workbench = e4app.createE4Workbench(getApplicationContext(), display); IEclipseContext workbenchContext = e4Workbench.getContext(); workbenchContext.set(Display.class, display); // create the workbench instance Workbench workbench = new Workbench(display, advisor, e4Workbench .getApplication(), e4Workbench.getContext()); // prime the splash nice and early if (createSplash) workbench.createSplashWrapper(); AbstractSplashHandler handler = getSplash(); IProgressMonitor progressMonitor = null; if (handler != null) { progressMonitor = handler.getBundleProgressMonitor(); if (progressMonitor != null) { double cutoff = 0.95; int expectedProgressCount = Math.max(1, WorkbenchPlugin.getDefault() .getBundleCount() / 10); progressMonitor.beginTask("", expectedProgressCount); //$NON-NLS-1$ SynchronousBundleListener bundleListener = workbench.new StartupProgressBundleListener( progressMonitor, (int) (expectedProgressCount * cutoff)); WorkbenchPlugin.getDefault().addBundleListener(bundleListener); } } // run the legacy workbench once returnCode[0] = workbench.runUI(); // run the e4 event loop and instantiate ... well, stuff e4Workbench.createAndRunUI(e4Workbench.getApplication()); WorkbenchMenuService wms = (WorkbenchMenuService) e4Workbench.getContext().get( IMenuService.class); wms.dispose(); e4app.saveModel(); e4Workbench.close(); returnCode[0] = workbench.returnCode; } } }); return returnCode[0]; } private static ServiceTracker instanceAppContext; static IApplicationContext getApplicationContext() { if (instanceAppContext == null) { instanceAppContext = new ServiceTracker( WorkbenchPlugin.getDefault().getBundleContext(), IApplicationContext.class .getName(), null); instanceAppContext.open(); } return (IApplicationContext) instanceAppContext.getService(); } static Object getApplication(String[] args) { // Find the name of the application as specified by the PDE JUnit // launcher. // If no application is specified, the 3.0 default workbench application // is returned. IExtension extension = Platform.getExtensionRegistry().getExtension(Platform.PI_RUNTIME, Platform.PT_APPLICATIONS, "org.eclipse.e4.ui.workbench.swt.E4Application"); //$NON-NLS-1$ Assert.isNotNull(extension); // If the extension does not have the correct grammar, return null. // Otherwise, return the application object. try { IConfigurationElement[] elements = extension.getConfigurationElements(); if (elements.length > 0) { IConfigurationElement[] runs = elements[0].getChildren("run"); //$NON-NLS-1$ if (runs.length > 0) { Object runnable; runnable = runs[0].createExecutableExtension("class");//$NON-NLS-1$ if (runnable instanceof IPlatformRunnable || runnable instanceof IApplication) return runnable; } } } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * Creates the <code>Display</code> to be used by the workbench. * * @return the display */ public static Display createDisplay() { // setup the application name used by SWT to lookup resources on some // platforms String applicationName = WorkbenchPlugin.getDefault().getAppName(); if (applicationName != null) { Display.setAppName(applicationName); } // create the display Display newDisplay = Display.getCurrent(); if (newDisplay == null) { if (Policy.DEBUG_SWT_GRAPHICS || Policy.DEBUG_SWT_DEBUG) { DeviceData data = new DeviceData(); if (Policy.DEBUG_SWT_GRAPHICS) { data.tracking = true; } if (Policy.DEBUG_SWT_DEBUG) { data.debug = true; } newDisplay = new Display(data); } else { newDisplay = new Display(); } } // workaround for 1GEZ9UR and 1GF07HN newDisplay.setWarnings(false); // Set the priority higher than normal so as to be higher // than the JobManager. Thread.currentThread().setPriority(Math.min(Thread.MAX_PRIORITY, Thread.NORM_PRIORITY + 1)); initializeImages(); return newDisplay; } /** * Create the splash wrapper and set it to work. * * @since 3.3 */ private void createSplashWrapper() { final Display display = getDisplay(); String splashLoc = System.getProperty("org.eclipse.equinox.launcher.splash.location"); //$NON-NLS-1$ final Image background = loadImage(splashLoc); SafeRunnable run = new SafeRunnable() { public void run() throws Exception { if (!WorkbenchPlugin.isSplashHandleSpecified()) { createSplash = false; return; } // create the splash getSplash(); if (splash == null) { createSplash = false; return; } Shell splashShell = splash.getSplash(); if (splashShell == null) { splashShell = WorkbenchPlugin.getSplashShell(display); if (splashShell == null) return; if (background != null) splashShell.setBackgroundImage(background); } Dictionary properties = new Hashtable(); properties.put(Constants.SERVICE_RANKING, new Integer(Integer.MAX_VALUE)); BundleContext context = WorkbenchPlugin.getDefault().getBundleContext(); final ServiceRegistration registration[] = new ServiceRegistration[1]; StartupMonitor startupMonitor = new StartupMonitor() { public void applicationRunning() { // splash.dispose(); if (background != null) background.dispose(); registration[0].unregister(); // unregister ourself WorkbenchPlugin.unsetSplashShell(display); // fire part visibility events now that we're up for (IWorkbenchWindow window : getWorkbenchWindows()) { IWorkbenchPage page = window.getActivePage(); if (page != null) { ((WorkbenchPage) page).fireInitialPartVisibilityEvents(); } } } public void update() { // do nothing - we come into the picture far too late // for this to be relevant } }; registration[0] = context.registerService(StartupMonitor.class.getName(), startupMonitor, properties); splash.init(splashShell); } /* * (non-Javadoc) * * @see * org.eclipse.jface.util.SafeRunnable#handleException(java.lang * .Throwable) */ public void handleException(Throwable e) { StatusManager.getManager().handle( StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, "Could not instantiate splash", e)); //$NON-NLS-1$ createSplash = false; splash = null; if (background != null) background.dispose(); } }; SafeRunner.run(run); } /** * Load an image from a filesystem path. * * @param splashLoc * the location to load from * @return the image or <code>null</code> * @since 3.3 */ private Image loadImage(String splashLoc) { Image background = null; if (splashLoc != null) { InputStream input = null; try { input = new BufferedInputStream(new FileInputStream(splashLoc)); background = new Image(display, input); } catch (SWTException e) { StatusManager.getManager().handle( StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e)); } catch (IOException e) { StatusManager.getManager().handle( StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e)); } finally { if (input != null) { try { input.close(); } catch (IOException e) { // he's done for } } } } return background; } /** * Return the splash handler for this application. If none is specifically * provided the default Eclipse implementation is returned. * * @return the splash handler for this application or <code>null</code> * @since 3.3 */ private static AbstractSplashHandler getSplash() { if (!createSplash) return null; if (splash == null) { IProduct product = Platform.getProduct(); if (product != null) splash = SplashHandlerFactory.findSplashHandlerFor(product); if (splash == null) splash = new EclipseSplashHandler(); } return splash; } /** * Returns the testable object facade, for use by the test harness. * * @return the testable object facade * @since 3.0 */ public static WorkbenchTestable getWorkbenchTestable() { if (testableObject == null) { testableObject = new WorkbenchTestable(); } return testableObject; } /* * (non-Javadoc) Method declared on IWorkbench. * * @since 3.2 */ public void addWorkbenchListener(IWorkbenchListener listener) { workbenchListeners.add(listener); } /* * (non-Javadoc) Method declared on IWorkbench. * * @since 3.2 */ public void removeWorkbenchListener(IWorkbenchListener listener) { workbenchListeners.remove(listener); } /** * Fire workbench preShutdown event, stopping at the first one to veto * * @param forced * flag indicating whether the shutdown is being forced * @return <code>true</code> to allow the workbench to proceed with * shutdown, <code>false</code> to veto a non-forced shutdown * @since 3.2 */ boolean firePreShutdown(final boolean forced) { Object list[] = workbenchListeners.getListeners(); for (int i = 0; i < list.length; i++) { final IWorkbenchListener l = (IWorkbenchListener) list[i]; final boolean[] result = new boolean[] { false }; SafeRunnable.run(new SafeRunnable() { public void run() { result[0] = l.preShutdown(Workbench.this, forced); } }); if (!result[0]) { return false; } } return true; } /** * Fire workbench postShutdown event. * * @since 3.2 */ void firePostShutdown() { Object list[] = workbenchListeners.getListeners(); for (int i = 0; i < list.length; i++) { final IWorkbenchListener l = (IWorkbenchListener) list[i]; SafeRunnable.run(new SafeRunnable() { public void run() { l.postShutdown(Workbench.this); } }); } } /* * (non-Javadoc) Method declared on IWorkbench. */ public void addWindowListener(IWindowListener l) { addListenerObject(l); } /* * (non-Javadoc) Method declared on IWorkbench. */ public void removeWindowListener(IWindowListener l) { removeListenerObject(l); } /** * Fire window opened event. * * @param window * The window which just opened; should not be <code>null</code>. */ protected void fireWindowOpened(final IWorkbenchWindow window) { Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowOpened(window); } }); } } /** * Fire window closed event. * * @param window * The window which just closed; should not be <code>null</code>. */ protected void fireWindowClosed(final IWorkbenchWindow window) { Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowClosed(window); } }); } } /** * Fire window activated event. * * @param window * The window which was just activated; should not be * <code>null</code>. */ protected void fireWindowActivated(final IWorkbenchWindow window) { Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowActivated(window); } }); } } /** * Fire window deactivated event. * * @param window * The window which was just deactivated; should not be * <code>null</code>. */ protected void fireWindowDeactivated(final IWorkbenchWindow window) { Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowDeactivated(window); } }); } } /** * Closes the workbench. Assumes that the busy cursor is active. * * @param force * true if the close is mandatory, and false if the close is * allowed to fail * @return true if the close succeeded, and false otherwise */ private boolean busyClose(final boolean force) { // notify the advisor of preShutdown and allow it to veto if not forced isClosing = advisor.preShutdown(); if (!force && !isClosing) { return false; } // notify regular workbench clients of preShutdown and allow them to // veto if not forced isClosing = firePreShutdown(force); if (!force && !isClosing) { return false; } // save any open editors if they are dirty isClosing = saveAllEditors(!force, true); if (!force && !isClosing) { return false; } boolean closeEditors = !force && PrefUtil.getAPIPreferenceStore().getBoolean( IWorkbenchPreferenceConstants.CLOSE_EDITORS_ON_EXIT); if (closeEditors) { SafeRunner.run(new SafeRunnable() { public void run() { IWorkbenchWindow windows[] = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { IWorkbenchPage pages[] = windows[i].getPages(); for (int j = 0; j < pages.length; j++) { isClosing = isClosing && pages[j].closeAllEditors(false); } } } }); if (!force && !isClosing) { return false; } } // discard editors that with non-ppersistable inputs SafeRunner.run(new SafeRunnable() { public void run() { IWorkbenchWindow windows[] = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { IWorkbenchPage pages[] = windows[i].getPages(); for (int j = 0; j < pages.length; j++) { List<EditorReference> editorReferences = ((WorkbenchPage) pages[j]) .getInternalEditorReferences(); List<EditorReference> referencesToClose = new ArrayList<EditorReference>(); for (EditorReference reference : editorReferences) { IEditorPart editor = reference.getEditor(false); if (editor != null && !reference.persist()) { referencesToClose.add(reference); } } for (EditorReference reference : referencesToClose) { ((WorkbenchPage) pages[j]).closeEditor(reference); } } } } }); // persist view states SafeRunner.run(new SafeRunnable() { public void run() { IWorkbenchWindow windows[] = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { IWorkbenchPage pages[] = windows[i].getPages(); for (int j = 0; j < pages.length; j++) { IViewReference[] references = pages[j].getViewReferences(); for (int k = 0; k < references.length; k++) { if (references[k].getView(false) != null) { ((ViewReference) references[k]).persist(); } } } } } }); if (!force && !isClosing) { return false; } SafeRunner.run(new SafeRunnable(WorkbenchMessages.ErrorClosing) { public void run() { if (isClosing || force) { // isClosing = windowManager.close(); E4Util.unsupported("Need to close since no windowManager"); //$NON-NLS-1$ MWindow selectedWindow = application.getSelectedElement(); WorkbenchWindow selected = null; for (IWorkbenchWindow window : getWorkbenchWindows()) { WorkbenchWindow ww = (WorkbenchWindow) window; if (ww.getModel() == selectedWindow) { selected = ww; } else { ((WorkbenchWindow) window).close(false); } } if (selected != null) { selected.close(false); } windowsClosed = true; } } }); if (!force && !isClosing) { return false; } shutdown(); IPresentationEngine engine = application.getContext().get(IPresentationEngine.class); engine.stop(); //System.err.println("stop()"); //$NON-NLS-1$ runEventLoop = false; return true; } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#saveAllEditors(boolean) */ public boolean saveAllEditors(boolean confirm) { return saveAllEditors(confirm, false); } private boolean saveAllEditors(boolean confirm, boolean closing) { for (IWorkbenchWindow window : getWorkbenchWindows()) { IWorkbenchPage page = window.getActivePage(); if (page != null) { if (!((WorkbenchPage) page).saveAllEditors(confirm, closing)) { return false; } } } return true; } /* * (non-Javadoc) Method declared on IWorkbench. */ public boolean close() { return close(PlatformUI.RETURN_OK, false); } /** * Closes the workbench, returning the given return code from the run * method. If forced, the workbench is closed no matter what. * * @param returnCode * {@link PlatformUI#RETURN_OK RETURN_OK}for normal exit; * {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the * workbench was terminated with a call to * {@link IWorkbench#restart IWorkbench.restart}; * {@link PlatformUI#RETURN_EMERGENCY_CLOSE} for an emergency * shutdown {@link PlatformUI#RETURN_UNSTARTABLE * RETURN_UNSTARTABLE}if the workbench could not be started; * other values reserved for future use * * @param force * true to force the workbench close, and false for a "soft" * close that can be canceled * @return true if the close was successful, and false if the close was * canceled */ /* package */ boolean close(int returnCode, final boolean force) { this.returnCode = returnCode; final boolean[] ret = new boolean[1]; BusyIndicator.showWhile(null, new Runnable() { public void run() { ret[0] = busyClose(force); } }); return ret[0]; } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchWindow getActiveWorkbenchWindow() { // Return null if called from a non-UI thread. // This is not spec'ed behaviour and is misleading, however this is how // it // worked in 2.1 and we cannot change it now. // For more details, see [Bug 57384] [RCP] Main window not active on // startup if (Display.getCurrent() == null || !initializationDone) { return null; } // the source providers try to update again during shutdown if (windowsClosed) { return null; } // rendering engine not available, can't make workbench windows, see bug // 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; } }
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.
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 }
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)