Source Code Cross Referenced for Workbench.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » internal » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui workbench » org.eclipse.ui.internal 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.ui.internal;
0011:
0012:        import java.io.BufferedInputStream;
0013:        import java.io.BufferedReader;
0014:        import java.io.File;
0015:        import java.io.FileInputStream;
0016:        import java.io.FileOutputStream;
0017:        import java.io.IOException;
0018:        import java.io.InputStream;
0019:        import java.io.InputStreamReader;
0020:        import java.io.OutputStreamWriter;
0021:        import java.lang.reflect.Method;
0022:        import java.util.ArrayList;
0023:        import java.util.Arrays;
0024:        import java.util.Dictionary;
0025:        import java.util.HashSet;
0026:        import java.util.Hashtable;
0027:        import java.util.List;
0028:        import java.util.Set;
0029:
0030:        import org.eclipse.core.commands.Command;
0031:        import org.eclipse.core.commands.CommandManager;
0032:        import org.eclipse.core.commands.common.EventManager;
0033:        import org.eclipse.core.commands.contexts.ContextManager;
0034:        import org.eclipse.core.databinding.observable.Realm;
0035:        import org.eclipse.core.runtime.Assert;
0036:        import org.eclipse.core.runtime.IAdaptable;
0037:        import org.eclipse.core.runtime.IExtension;
0038:        import org.eclipse.core.runtime.IExtensionDelta;
0039:        import org.eclipse.core.runtime.IExtensionPoint;
0040:        import org.eclipse.core.runtime.IExtensionRegistry;
0041:        import org.eclipse.core.runtime.IPath;
0042:        import org.eclipse.core.runtime.IProduct;
0043:        import org.eclipse.core.runtime.IProgressMonitor;
0044:        import org.eclipse.core.runtime.IRegistryChangeEvent;
0045:        import org.eclipse.core.runtime.IRegistryChangeListener;
0046:        import org.eclipse.core.runtime.IStatus;
0047:        import org.eclipse.core.runtime.ListenerList;
0048:        import org.eclipse.core.runtime.MultiStatus;
0049:        import org.eclipse.core.runtime.Platform;
0050:        import org.eclipse.core.runtime.SafeRunner;
0051:        import org.eclipse.core.runtime.Status;
0052:        import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
0053:        import org.eclipse.core.runtime.jobs.Job;
0054:        import org.eclipse.jface.action.ActionContributionItem;
0055:        import org.eclipse.jface.action.ExternalActionManager;
0056:        import org.eclipse.jface.action.IAction;
0057:        import org.eclipse.jface.action.MenuManager;
0058:        import org.eclipse.jface.action.ExternalActionManager.CommandCallback;
0059:        import org.eclipse.jface.action.ExternalActionManager.IActiveChecker;
0060:        import org.eclipse.jface.bindings.BindingManager;
0061:        import org.eclipse.jface.bindings.BindingManagerEvent;
0062:        import org.eclipse.jface.bindings.IBindingManagerListener;
0063:        import org.eclipse.jface.databinding.swt.SWTObservables;
0064:        import org.eclipse.jface.dialogs.ErrorDialog;
0065:        import org.eclipse.jface.dialogs.IDialogConstants;
0066:        import org.eclipse.jface.dialogs.MessageDialog;
0067:        import org.eclipse.jface.dialogs.ProgressMonitorDialog;
0068:        import org.eclipse.jface.operation.IRunnableContext;
0069:        import org.eclipse.jface.operation.ModalContext;
0070:        import org.eclipse.jface.preference.IPreferenceStore;
0071:        import org.eclipse.jface.preference.PreferenceManager;
0072:        import org.eclipse.jface.resource.ImageDescriptor;
0073:        import org.eclipse.jface.util.OpenStrategy;
0074:        import org.eclipse.jface.util.SafeRunnable;
0075:        import org.eclipse.jface.viewers.ISelection;
0076:        import org.eclipse.jface.window.IShellProvider;
0077:        import org.eclipse.jface.window.Window;
0078:        import org.eclipse.jface.window.WindowManager;
0079:        import org.eclipse.osgi.service.runnable.StartupMonitor;
0080:        import org.eclipse.osgi.util.NLS;
0081:        import org.eclipse.swt.SWT;
0082:        import org.eclipse.swt.custom.BusyIndicator;
0083:        import org.eclipse.swt.graphics.DeviceData;
0084:        import org.eclipse.swt.graphics.Image;
0085:        import org.eclipse.swt.widgets.Control;
0086:        import org.eclipse.swt.widgets.Display;
0087:        import org.eclipse.swt.widgets.Event;
0088:        import org.eclipse.swt.widgets.Listener;
0089:        import org.eclipse.swt.widgets.Shell;
0090:        import org.eclipse.ui.IDecoratorManager;
0091:        import org.eclipse.ui.IEditorPart;
0092:        import org.eclipse.ui.IEditorRegistry;
0093:        import org.eclipse.ui.IElementFactory;
0094:        import org.eclipse.ui.ILocalWorkingSetManager;
0095:        import org.eclipse.ui.IMemento;
0096:        import org.eclipse.ui.IPerspectiveDescriptor;
0097:        import org.eclipse.ui.IPerspectiveRegistry;
0098:        import org.eclipse.ui.ISaveableFilter;
0099:        import org.eclipse.ui.ISaveablePart;
0100:        import org.eclipse.ui.ISaveablesLifecycleListener;
0101:        import org.eclipse.ui.ISharedImages;
0102:        import org.eclipse.ui.IWindowListener;
0103:        import org.eclipse.ui.IWorkbench;
0104:        import org.eclipse.ui.IWorkbenchListener;
0105:        import org.eclipse.ui.IWorkbenchPage;
0106:        import org.eclipse.ui.IWorkbenchPart;
0107:        import org.eclipse.ui.IWorkbenchPreferenceConstants;
0108:        import org.eclipse.ui.IWorkbenchWindow;
0109:        import org.eclipse.ui.IWorkingSetManager;
0110:        import org.eclipse.ui.PlatformUI;
0111:        import org.eclipse.ui.Saveable;
0112:        import org.eclipse.ui.WorkbenchException;
0113:        import org.eclipse.ui.XMLMemento;
0114:        import org.eclipse.ui.activities.IWorkbenchActivitySupport;
0115:        import org.eclipse.ui.application.IWorkbenchConfigurer;
0116:        import org.eclipse.ui.application.WorkbenchAdvisor;
0117:        import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
0118:        import org.eclipse.ui.commands.ICommandService;
0119:        import org.eclipse.ui.commands.IWorkbenchCommandSupport;
0120:        import org.eclipse.ui.contexts.IContextService;
0121:        import org.eclipse.ui.contexts.IWorkbenchContextSupport;
0122:        import org.eclipse.ui.handlers.IHandlerService;
0123:        import org.eclipse.ui.help.IWorkbenchHelpSystem;
0124:        import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
0125:        import org.eclipse.ui.internal.activities.ws.WorkbenchActivitySupport;
0126:        import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
0127:        import org.eclipse.ui.internal.commands.CommandImageManager;
0128:        import org.eclipse.ui.internal.commands.CommandImageService;
0129:        import org.eclipse.ui.internal.commands.CommandService;
0130:        import org.eclipse.ui.internal.commands.ICommandImageService;
0131:        import org.eclipse.ui.internal.commands.WorkbenchCommandSupport;
0132:        import org.eclipse.ui.internal.contexts.ActiveContextSourceProvider;
0133:        import org.eclipse.ui.internal.contexts.ContextService;
0134:        import org.eclipse.ui.internal.contexts.WorkbenchContextSupport;
0135:        import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager;
0136:        import org.eclipse.ui.internal.handlers.HandlerService;
0137:        import org.eclipse.ui.internal.help.WorkbenchHelpSystem;
0138:        import org.eclipse.ui.internal.intro.IIntroRegistry;
0139:        import org.eclipse.ui.internal.intro.IntroDescriptor;
0140:        import org.eclipse.ui.internal.keys.BindingService;
0141:        import org.eclipse.ui.internal.menus.FocusControlSourceProvider;
0142:        import org.eclipse.ui.internal.menus.WorkbenchMenuService;
0143:        import org.eclipse.ui.internal.misc.Policy;
0144:        import org.eclipse.ui.internal.misc.StatusUtil;
0145:        import org.eclipse.ui.internal.misc.UIStats;
0146:        import org.eclipse.ui.internal.progress.ProgressManager;
0147:        import org.eclipse.ui.internal.registry.IActionSetDescriptor;
0148:        import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
0149:        import org.eclipse.ui.internal.registry.UIExtensionTracker;
0150:        import org.eclipse.ui.internal.services.ActionSetSourceProvider;
0151:        import org.eclipse.ui.internal.services.ActivePartSourceProvider;
0152:        import org.eclipse.ui.internal.services.ActiveShellSourceProvider;
0153:        import org.eclipse.ui.internal.services.CurrentSelectionSourceProvider;
0154:        import org.eclipse.ui.internal.services.EvaluationService;
0155:        import org.eclipse.ui.internal.services.IEvaluationService;
0156:        import org.eclipse.ui.internal.services.ISourceProviderService;
0157:        import org.eclipse.ui.internal.services.MenuSourceProvider;
0158:        import org.eclipse.ui.internal.services.ServiceLocator;
0159:        import org.eclipse.ui.internal.services.SourceProviderService;
0160:        import org.eclipse.ui.internal.splash.EclipseSplashHandler;
0161:        import org.eclipse.ui.internal.splash.SplashHandlerFactory;
0162:        import org.eclipse.ui.internal.testing.WorkbenchTestable;
0163:        import org.eclipse.ui.internal.themes.ColorDefinition;
0164:        import org.eclipse.ui.internal.themes.FontDefinition;
0165:        import org.eclipse.ui.internal.themes.ThemeElementHelper;
0166:        import org.eclipse.ui.internal.themes.WorkbenchThemeManager;
0167:        import org.eclipse.ui.internal.tweaklets.GrabFocus;
0168:        import org.eclipse.ui.internal.tweaklets.Tweaklets;
0169:        import org.eclipse.ui.internal.util.PrefUtil;
0170:        import org.eclipse.ui.internal.util.Util;
0171:        import org.eclipse.ui.intro.IIntroManager;
0172:        import org.eclipse.ui.keys.IBindingService;
0173:        import org.eclipse.ui.menus.IMenuService;
0174:        import org.eclipse.ui.operations.IWorkbenchOperationSupport;
0175:        import org.eclipse.ui.progress.IProgressService;
0176:        import org.eclipse.ui.services.IDisposable;
0177:        import org.eclipse.ui.splash.AbstractSplashHandler;
0178:        import org.eclipse.ui.statushandlers.StatusManager;
0179:        import org.eclipse.ui.swt.IFocusService;
0180:        import org.eclipse.ui.themes.IThemeManager;
0181:        import org.eclipse.ui.views.IViewRegistry;
0182:        import org.eclipse.ui.wizards.IWizardRegistry;
0183:        import org.osgi.framework.BundleContext;
0184:        import org.osgi.framework.BundleEvent;
0185:        import org.osgi.framework.Constants;
0186:        import org.osgi.framework.ServiceRegistration;
0187:        import org.osgi.framework.SynchronousBundleListener;
0188:
0189:        /**
0190:         * The workbench class represents the top of the Eclipse user interface. Its
0191:         * primary responsability is the management of workbench windows, dialogs,
0192:         * wizards, and other workbench-related windows.
0193:         * <p>
0194:         * Note that any code that is run during the creation of a workbench instance
0195:         * should not required access to the display.
0196:         * </p>
0197:         * <p>
0198:         * Note that this internal class changed significantly between 2.1 and 3.0.
0199:         * Applications that used to define subclasses of this internal class need to be
0200:         * rewritten to use the new workbench advisor API.
0201:         * </p>
0202:         */
0203:        public final class Workbench extends EventManager implements  IWorkbench {
0204:
0205:            private final class StartupProgressBundleListener implements 
0206:                    SynchronousBundleListener {
0207:
0208:                private final IProgressMonitor progressMonitor;
0209:
0210:                private final int maximumProgressCount;
0211:
0212:                // stack of names of bundles currently starting
0213:                private final List starting;
0214:
0215:                StartupProgressBundleListener(IProgressMonitor progressMonitor,
0216:                        int maximumProgressCount) {
0217:                    super ();
0218:                    this .progressMonitor = progressMonitor;
0219:                    this .maximumProgressCount = maximumProgressCount;
0220:                    this .starting = new ArrayList();
0221:                }
0222:
0223:                public void bundleChanged(BundleEvent event) {
0224:                    int eventType = event.getType();
0225:                    String bundleName;
0226:
0227:                    synchronized (this ) {
0228:                        if (eventType == BundleEvent.STARTING) {
0229:                            starting.add(bundleName = event.getBundle()
0230:                                    .getSymbolicName());
0231:                        } else if (eventType == BundleEvent.STARTED) {
0232:                            progressCount++;
0233:                            if (progressCount <= maximumProgressCount) {
0234:                                progressMonitor.worked(1);
0235:                            }
0236:                            int index = starting.lastIndexOf(event.getBundle()
0237:                                    .getSymbolicName());
0238:                            if (index >= 0) {
0239:                                starting.remove(index);
0240:                            }
0241:                            if (index != starting.size()) {
0242:                                return; // not currently displayed
0243:                            }
0244:                            bundleName = index == 0 ? null : (String) starting
0245:                                    .get(index - 1);
0246:                        } else {
0247:                            return; // uninteresting event
0248:                        }
0249:                    }
0250:
0251:                    String taskName;
0252:
0253:                    if (bundleName == null) {
0254:                        taskName = WorkbenchMessages.Startup_Loading_Workbench;
0255:                    } else {
0256:                        taskName = NLS.bind(WorkbenchMessages.Startup_Loading,
0257:                                bundleName);
0258:                    }
0259:
0260:                    progressMonitor.subTask(taskName);
0261:                }
0262:            }
0263:
0264:            /**
0265:             * Family for the early startup job.
0266:             */
0267:            public static final String EARLY_STARTUP_FAMILY = "earlyStartup"; //$NON-NLS-1$
0268:
0269:            static final String VERSION_STRING[] = { "0.046", "2.0" }; //$NON-NLS-1$ //$NON-NLS-2$
0270:
0271:            static final String DEFAULT_WORKBENCH_STATE_FILENAME = "workbench.xml"; //$NON-NLS-1$
0272:
0273:            /**
0274:             * Holds onto the only instance of Workbench.
0275:             */
0276:            private static Workbench instance;
0277:
0278:            /**
0279:             * The testable object facade.
0280:             * 
0281:             * @since 3.0
0282:             */
0283:            private static WorkbenchTestable testableObject;
0284:
0285:            /**
0286:             * Signals that the workbench should create a splash implementation when
0287:             * instantiated. Intial value is <code>true</code>.
0288:             * 
0289:             * @since 3.3
0290:             */
0291:            private static boolean createSplash = true;
0292:
0293:            /**
0294:             * The splash handler.
0295:             */
0296:            private static AbstractSplashHandler splash;
0297:
0298:            /**
0299:             * The display used for all UI interactions with this workbench.
0300:             * 
0301:             * @since 3.0
0302:             */
0303:            private Display display;
0304:
0305:            private WindowManager windowManager;
0306:
0307:            private WorkbenchWindow activatedWindow;
0308:
0309:            private EditorHistory editorHistory;
0310:
0311:            private boolean runEventLoop = true;
0312:
0313:            private boolean isStarting = true;
0314:
0315:            private boolean isClosing = false;
0316:
0317:            /**
0318:             * PlatformUI return code (as opposed to IPlatformRunnable return code).
0319:             */
0320:            private int returnCode = PlatformUI.RETURN_UNSTARTABLE;
0321:
0322:            /**
0323:             * Advisor providing application-specific configuration and customization of
0324:             * the workbench.
0325:             * 
0326:             * @since 3.0
0327:             */
0328:            private WorkbenchAdvisor advisor;
0329:
0330:            /**
0331:             * Object for configuring the workbench. Lazily initialized to an instance
0332:             * unique to the workbench instance.
0333:             * 
0334:             * @since 3.0
0335:             */
0336:            private WorkbenchConfigurer workbenchConfigurer;
0337:
0338:            // for dynamic UI
0339:            /**
0340:             * ExtensionEventHandler handles extension life-cycle events.
0341:             */
0342:            private ExtensionEventHandler extensionEventHandler;
0343:
0344:            /**
0345:             * A count of how many large updates are going on. This tracks nesting of
0346:             * requests to disable services during a large update -- similar to the
0347:             * <code>setRedraw</code> functionality on <code>Control</code>. When
0348:             * this value becomes greater than zero, services are disabled. When this
0349:             * value becomes zero, services are enabled. Please see
0350:             * <code>largeUpdateStart()</code> and <code>largeUpdateEnd()</code>.
0351:             */
0352:            private int largeUpdates = 0;
0353:
0354:            /**
0355:             * The service locator maintained by the workbench. These services are
0356:             * initialized during workbench during the <code>init</code> method.
0357:             */
0358:            private final ServiceLocator serviceLocator = new ServiceLocator();
0359:
0360:            /**
0361:             * A count of how many plug-ins were loaded while restoring the workbench
0362:             * state. Initially -1 for unknown number.
0363:             */
0364:            private int progressCount = -1;
0365:
0366:            /**
0367:             * A field to hold the workbench windows that have been restored. In the
0368:             * event that not all windows have been restored, this field allows the
0369:             * openWindowsAfterRestore method to open some windows.
0370:             */
0371:            private WorkbenchWindow[] createdWindows;
0372:
0373:            /**
0374:             * Listener list for registered IWorkbenchListeners .
0375:             */
0376:            private ListenerList workbenchListeners = new ListenerList(
0377:                    ListenerList.IDENTITY);
0378:
0379:            /**
0380:             * Creates a new workbench.
0381:             * 
0382:             * @param display
0383:             *            the display to be used for all UI interactions with the
0384:             *            workbench
0385:             * @param advisor
0386:             *            the application-specific advisor that configures and
0387:             *            specializes this workbench instance
0388:             * @since 3.0
0389:             */
0390:            private Workbench(Display display, WorkbenchAdvisor advisor) {
0391:                super ();
0392:                StartupThreading.setWorkbench(this );
0393:                if (instance != null && instance.isRunning()) {
0394:                    throw new IllegalStateException(
0395:                            WorkbenchMessages.Workbench_CreatingWorkbenchTwice);
0396:                }
0397:                Assert.isNotNull(display);
0398:                Assert.isNotNull(advisor);
0399:                this .advisor = advisor;
0400:                this .display = display;
0401:                Workbench.instance = this ;
0402:
0403:                // for dynamic UI [This seems to be for everything that isn't handled by
0404:                // some
0405:                // subclass of RegistryManager. I think that when an extension is moved
0406:                // to the
0407:                // RegistryManager implementation, then it should be removed from the
0408:                // list in
0409:                // ExtensionEventHandler#appear.
0410:                // I've found that the new wizard extension in particular is a poor
0411:                // choice to
0412:                // use as an example, since the result of reading the registry is not
0413:                // cached
0414:                // -- so it is re-read each time. The only real contribution of this
0415:                // dialog is
0416:                // to show the user a nice dialog describing the addition.]
0417:                extensionEventHandler = new ExtensionEventHandler(this );
0418:                Platform.getExtensionRegistry().addRegistryChangeListener(
0419:                        extensionEventHandler);
0420:            }
0421:
0422:            /**
0423:             * Returns the one and only instance of the workbench, if there is one.
0424:             * 
0425:             * @return the workbench, or <code>null</code> if the workbench has not
0426:             *         been created, or has been created and already completed
0427:             */
0428:            public static final Workbench getInstance() {
0429:                return instance;
0430:            }
0431:
0432:            /**
0433:             * Creates the workbench and associates it with the the given display and
0434:             * workbench advisor, and runs the workbench UI. This entails processing and
0435:             * dispatching events until the workbench is closed or restarted.
0436:             * <p>
0437:             * This method is intended to be called by <code>PlatformUI</code>. Fails
0438:             * if the workbench UI has already been created.
0439:             * </p>
0440:             * <p>
0441:             * The display passed in must be the default display.
0442:             * </p>
0443:             * 
0444:             * @param display
0445:             *            the display to be used for all UI interactions with the
0446:             *            workbench
0447:             * @param advisor
0448:             *            the application-specific advisor that configures and
0449:             *            specializes the workbench
0450:             * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
0451:             *         exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
0452:             *         workbench was terminated with a call to
0453:             *         {@link IWorkbench#restart IWorkbench.restart}; other values
0454:             *         reserved for future use
0455:             */
0456:            public static final int createAndRunWorkbench(
0457:                    final Display display, final WorkbenchAdvisor advisor) {
0458:                final int[] returnCode = new int[1];
0459:                Realm.runWithDefault(SWTObservables.getRealm(display),
0460:                        new Runnable() {
0461:                            public void run() {
0462:                                // create the workbench instance
0463:                                Workbench workbench = new Workbench(display,
0464:                                        advisor);
0465:                                // run the workbench event loop
0466:                                returnCode[0] = workbench.runUI();
0467:                            }
0468:                        });
0469:                return returnCode[0];
0470:            }
0471:
0472:            /**
0473:             * Creates the <code>Display</code> to be used by the workbench.
0474:             * 
0475:             * @return the display
0476:             */
0477:            public static Display createDisplay() {
0478:                // setup the application name used by SWT to lookup resources on some
0479:                // platforms
0480:                String applicationName = WorkbenchPlugin.getDefault()
0481:                        .getAppName();
0482:                if (applicationName != null) {
0483:                    Display.setAppName(applicationName);
0484:                }
0485:
0486:                // create the display
0487:                Display newDisplay = Display.getCurrent();
0488:                if (newDisplay == null) {
0489:                    if (Policy.DEBUG_SWT_GRAPHICS || Policy.DEBUG_SWT_DEBUG) {
0490:                        DeviceData data = new DeviceData();
0491:                        if (Policy.DEBUG_SWT_GRAPHICS) {
0492:                            data.tracking = true;
0493:                        }
0494:                        if (Policy.DEBUG_SWT_DEBUG) {
0495:                            data.debug = true;
0496:                        }
0497:                        newDisplay = new Display(data);
0498:                    } else {
0499:                        newDisplay = new Display();
0500:                    }
0501:                }
0502:
0503:                // workaround for 1GEZ9UR and 1GF07HN
0504:                newDisplay.setWarnings(false);
0505:
0506:                // Set the priority higher than normal so as to be higher
0507:                // than the JobManager.
0508:                Thread.currentThread()
0509:                        .setPriority(
0510:                                Math.min(Thread.MAX_PRIORITY,
0511:                                        Thread.NORM_PRIORITY + 1));
0512:
0513:                initializeImages();
0514:
0515:                return newDisplay;
0516:            }
0517:
0518:            /**
0519:             * Create the splash wrapper and set it to work.
0520:             * 
0521:             * @since 3.3
0522:             */
0523:            private void createSplashWrapper() {
0524:                final Display display = getDisplay();
0525:                String splashLoc = System
0526:                        .getProperty("org.eclipse.equinox.launcher.splash.location"); //$NON-NLS-1$
0527:                final Image background = loadImage(splashLoc);
0528:
0529:                SafeRunnable run = new SafeRunnable() {
0530:
0531:                    public void run() throws Exception {
0532:                        String splashHandle = System
0533:                                .getProperty("org.eclipse.equinox.launcher.splash.handle"); //$NON-NLS-1$
0534:                        if (splashHandle == null) {
0535:                            createSplash = false;
0536:                            return;
0537:                        }
0538:
0539:                        // create the splash
0540:                        getSplash();
0541:                        if (splash == null) {
0542:                            createSplash = false;
0543:                            return;
0544:                        }
0545:
0546:                        Shell splashShell = splash.getSplash();
0547:                        if (splashShell == null) {
0548:                            // look for the 32 bit internal_new shell method
0549:                            try {
0550:                                Method method = Shell.class
0551:                                        .getMethod(
0552:                                                "internal_new", new Class[] { Display.class, int.class }); //$NON-NLS-1$
0553:                                // we're on a 32 bit platform so invoke it with splash
0554:                                // handle as an int
0555:                                splashShell = (Shell) method.invoke(null,
0556:                                        new Object[] { display,
0557:                                                new Integer(splashHandle) });
0558:                            } catch (NoSuchMethodException e) {
0559:                                // look for the 64 bit internal_new shell method
0560:                                try {
0561:                                    Method method = Shell.class
0562:                                            .getMethod(
0563:                                                    "internal_new", new Class[] { Display.class, long.class }); //$NON-NLS-1$
0564:
0565:                                    // we're on a 64 bit platform so invoke it with a long
0566:                                    splashShell = (Shell) method.invoke(null,
0567:                                            new Object[] { display,
0568:                                                    new Long(splashHandle) });
0569:                                } catch (NoSuchMethodException e2) {
0570:                                    // cant find either method - don't do anything.
0571:                                }
0572:                            }
0573:
0574:                            if (splashShell == null)
0575:                                return;
0576:                            if (background != null)
0577:                                splashShell.setBackgroundImage(background);
0578:                        }
0579:
0580:                        Dictionary properties = new Hashtable();
0581:                        properties.put(Constants.SERVICE_RANKING, new Integer(
0582:                                Integer.MAX_VALUE));
0583:                        BundleContext context = WorkbenchPlugin.getDefault()
0584:                                .getBundleContext();
0585:                        final ServiceRegistration registration[] = new ServiceRegistration[1];
0586:                        StartupMonitor startupMonitor = new StartupMonitor() {
0587:
0588:                            public void applicationRunning() {
0589:                                splash.dispose();
0590:                                if (background != null)
0591:                                    background.dispose();
0592:                                registration[0].unregister(); // unregister ourself
0593:                            }
0594:
0595:                            public void update() {
0596:                                // do nothing - we come into the picture far too late
0597:                                // for this to be relevant
0598:                            }
0599:                        };
0600:                        registration[0] = context.registerService(
0601:                                StartupMonitor.class.getName(), startupMonitor,
0602:                                properties);
0603:
0604:                        splash.init(splashShell);
0605:                    }
0606:
0607:                    /* (non-Javadoc)
0608:                     * @see org.eclipse.jface.util.SafeRunnable#handleException(java.lang.Throwable)
0609:                     */
0610:                    public void handleException(Throwable e) {
0611:                        StatusManager.getManager().handle(
0612:                                StatusUtil.newStatus(
0613:                                        WorkbenchPlugin.PI_WORKBENCH,
0614:                                        "Could not instantiate splash", e)); //$NON-NLS-1$
0615:                        createSplash = false;
0616:                        splash = null;
0617:                        if (background != null)
0618:                            background.dispose();
0619:
0620:                    }
0621:                };
0622:                SafeRunner.run(run);
0623:            }
0624:
0625:            /**
0626:             * Load an image from a filesystem path.
0627:             * 
0628:             * @param splashLoc the location to load from
0629:             * @return the image or <code>null</code>
0630:             * @since 3.3
0631:             */
0632:            private Image loadImage(String splashLoc) {
0633:                Image background = null;
0634:                if (splashLoc != null) {
0635:                    try {
0636:                        InputStream input = new BufferedInputStream(
0637:                                new FileInputStream(splashLoc));
0638:                        background = new Image(display, input);
0639:                    } catch (IOException e) {
0640:                        StatusManager.getManager().handle(
0641:                                StatusUtil.newStatus(
0642:                                        WorkbenchPlugin.PI_WORKBENCH, e));
0643:                    }
0644:                }
0645:                return background;
0646:            }
0647:
0648:            /**
0649:             * Return the splash handler for this application. If none is specifically
0650:             * provided the default Eclipse implementation is returned.
0651:             * 
0652:             * @return the splash handler for this application or <code>null</code>
0653:             * @since 3.3
0654:             */
0655:            private static AbstractSplashHandler getSplash() {
0656:                if (!createSplash)
0657:                    return null;
0658:
0659:                if (splash == null) {
0660:
0661:                    IProduct product = Platform.getProduct();
0662:                    if (product != null)
0663:                        splash = SplashHandlerFactory
0664:                                .findSplashHandlerFor(product);
0665:
0666:                    if (splash == null)
0667:                        splash = new EclipseSplashHandler();
0668:                }
0669:                return splash;
0670:            }
0671:
0672:            /**
0673:             * Returns the testable object facade, for use by the test harness.
0674:             * 
0675:             * @return the testable object facade
0676:             * @since 3.0
0677:             */
0678:            public static WorkbenchTestable getWorkbenchTestable() {
0679:                if (testableObject == null) {
0680:                    testableObject = new WorkbenchTestable();
0681:                }
0682:                return testableObject;
0683:            }
0684:
0685:            /*
0686:             * (non-Javadoc) Method declared on IWorkbench.
0687:             * 
0688:             * @since 3.2
0689:             */
0690:            public void addWorkbenchListener(IWorkbenchListener listener) {
0691:                workbenchListeners.add(listener);
0692:            }
0693:
0694:            /*
0695:             * (non-Javadoc) Method declared on IWorkbench.
0696:             * 
0697:             * @since 3.2
0698:             */
0699:            public void removeWorkbenchListener(IWorkbenchListener listener) {
0700:                workbenchListeners.remove(listener);
0701:            }
0702:
0703:            /**
0704:             * Fire workbench preShutdown event, stopping at the first one to veto
0705:             * 
0706:             * @param forced
0707:             *            flag indicating whether the shutdown is being forced
0708:             * @return <code>true</code> to allow the workbench to proceed with
0709:             *         shutdown, <code>false</code> to veto a non-forced shutdown
0710:             * @since 3.2
0711:             */
0712:            boolean firePreShutdown(final boolean forced) {
0713:                Object list[] = workbenchListeners.getListeners();
0714:                for (int i = 0; i < list.length; i++) {
0715:                    final IWorkbenchListener l = (IWorkbenchListener) list[i];
0716:                    final boolean[] result = new boolean[] { false };
0717:                    SafeRunnable.run(new SafeRunnable() {
0718:                        public void run() {
0719:                            result[0] = l.preShutdown(Workbench.this , forced);
0720:                        }
0721:                    });
0722:                    if (!result[0]) {
0723:                        return false;
0724:                    }
0725:                }
0726:                return true;
0727:            }
0728:
0729:            /**
0730:             * Fire workbench postShutdown event.
0731:             * 
0732:             * @since 3.2
0733:             */
0734:            void firePostShutdown() {
0735:                Object list[] = workbenchListeners.getListeners();
0736:                for (int i = 0; i < list.length; i++) {
0737:                    final IWorkbenchListener l = (IWorkbenchListener) list[i];
0738:                    SafeRunnable.run(new SafeRunnable() {
0739:                        public void run() {
0740:                            l.postShutdown(Workbench.this );
0741:                        }
0742:                    });
0743:                }
0744:            }
0745:
0746:            /*
0747:             * (non-Javadoc) Method declared on IWorkbench.
0748:             */
0749:            public void addWindowListener(IWindowListener l) {
0750:                addListenerObject(l);
0751:            }
0752:
0753:            /*
0754:             * (non-Javadoc) Method declared on IWorkbench.
0755:             */
0756:            public void removeWindowListener(IWindowListener l) {
0757:                removeListenerObject(l);
0758:            }
0759:
0760:            /**
0761:             * Fire window opened event.
0762:             * 
0763:             * @param window
0764:             *            The window which just opened; should not be <code>null</code>.
0765:             */
0766:            protected void fireWindowOpened(final IWorkbenchWindow window) {
0767:                Object list[] = getListeners();
0768:                for (int i = 0; i < list.length; i++) {
0769:                    final IWindowListener l = (IWindowListener) list[i];
0770:                    SafeRunner.run(new SafeRunnable() {
0771:                        public void run() {
0772:                            l.windowOpened(window);
0773:                        }
0774:                    });
0775:                }
0776:            }
0777:
0778:            /**
0779:             * Fire window closed event.
0780:             * 
0781:             * @param window
0782:             *            The window which just closed; should not be <code>null</code>.
0783:             */
0784:            protected void fireWindowClosed(final IWorkbenchWindow window) {
0785:                if (activatedWindow == window) {
0786:                    // Do not hang onto it so it can be GC'ed
0787:                    activatedWindow = null;
0788:                }
0789:
0790:                Object list[] = getListeners();
0791:                for (int i = 0; i < list.length; i++) {
0792:                    final IWindowListener l = (IWindowListener) list[i];
0793:                    SafeRunner.run(new SafeRunnable() {
0794:                        public void run() {
0795:                            l.windowClosed(window);
0796:                        }
0797:                    });
0798:                }
0799:            }
0800:
0801:            /**
0802:             * Fire window activated event.
0803:             * 
0804:             * @param window
0805:             *            The window which was just activated; should not be
0806:             *            <code>null</code>.
0807:             */
0808:            protected void fireWindowActivated(final IWorkbenchWindow window) {
0809:                Object list[] = getListeners();
0810:                for (int i = 0; i < list.length; i++) {
0811:                    final IWindowListener l = (IWindowListener) list[i];
0812:                    SafeRunner.run(new SafeRunnable() {
0813:                        public void run() {
0814:                            l.windowActivated(window);
0815:                        }
0816:                    });
0817:                }
0818:            }
0819:
0820:            /**
0821:             * Fire window deactivated event.
0822:             * 
0823:             * @param window
0824:             *            The window which was just deactivated; should not be
0825:             *            <code>null</code>.
0826:             */
0827:            protected void fireWindowDeactivated(final IWorkbenchWindow window) {
0828:                Object list[] = getListeners();
0829:                for (int i = 0; i < list.length; i++) {
0830:                    final IWindowListener l = (IWindowListener) list[i];
0831:                    SafeRunner.run(new SafeRunnable() {
0832:                        public void run() {
0833:                            l.windowDeactivated(window);
0834:                        }
0835:                    });
0836:                }
0837:            }
0838:
0839:            /**
0840:             * Closes the workbench. Assumes that the busy cursor is active.
0841:             * 
0842:             * @param force
0843:             *            true if the close is mandatory, and false if the close is
0844:             *            allowed to fail
0845:             * @return true if the close succeeded, and false otherwise
0846:             */
0847:            private boolean busyClose(final boolean force) {
0848:
0849:                // notify the advisor of preShutdown and allow it to veto if not forced
0850:                isClosing = advisor.preShutdown();
0851:                if (!force && !isClosing) {
0852:                    return false;
0853:                }
0854:
0855:                // notify regular workbench clients of preShutdown and allow them to
0856:                // veto if not forced
0857:                isClosing = firePreShutdown(force);
0858:                if (!force && !isClosing) {
0859:                    return false;
0860:                }
0861:
0862:                // save any open editors if they are dirty
0863:                isClosing = saveAllEditors(!force);
0864:                if (!force && !isClosing) {
0865:                    return false;
0866:                }
0867:
0868:                boolean closeEditors = !force
0869:                        && PrefUtil
0870:                                .getAPIPreferenceStore()
0871:                                .getBoolean(
0872:                                        IWorkbenchPreferenceConstants.CLOSE_EDITORS_ON_EXIT);
0873:                if (closeEditors) {
0874:                    SafeRunner.run(new SafeRunnable() {
0875:                        public void run() {
0876:                            IWorkbenchWindow windows[] = getWorkbenchWindows();
0877:                            for (int i = 0; i < windows.length; i++) {
0878:                                IWorkbenchPage pages[] = windows[i].getPages();
0879:                                for (int j = 0; j < pages.length; j++) {
0880:                                    isClosing = isClosing
0881:                                            && pages[j].closeAllEditors(false);
0882:                                }
0883:                            }
0884:                        }
0885:                    });
0886:                    if (!force && !isClosing) {
0887:                        return false;
0888:                    }
0889:                }
0890:
0891:                if (getWorkbenchConfigurer().getSaveAndRestore()) {
0892:                    SafeRunner.run(new SafeRunnable() {
0893:                        public void run() {
0894:                            XMLMemento mem = recordWorkbenchState();
0895:                            // Save the IMemento to a file.
0896:                            saveMementoToFile(mem);
0897:                        }
0898:
0899:                        public void handleException(Throwable e) {
0900:                            String message;
0901:                            if (e.getMessage() == null) {
0902:                                message = WorkbenchMessages.ErrorClosingNoArg;
0903:                            } else {
0904:                                message = NLS.bind(
0905:                                        WorkbenchMessages.ErrorClosingOneArg, e
0906:                                                .getMessage());
0907:                            }
0908:
0909:                            if (!MessageDialog.openQuestion(null,
0910:                                    WorkbenchMessages.Error, message)) {
0911:                                isClosing = false;
0912:                            }
0913:                        }
0914:                    });
0915:                }
0916:                if (!force && !isClosing) {
0917:                    return false;
0918:                }
0919:
0920:                SafeRunner
0921:                        .run(new SafeRunnable(WorkbenchMessages.ErrorClosing) {
0922:                            public void run() {
0923:                                if (isClosing || force) {
0924:                                    isClosing = windowManager.close();
0925:                                }
0926:                            }
0927:                        });
0928:
0929:                if (!force && !isClosing) {
0930:                    return false;
0931:                }
0932:
0933:                shutdown();
0934:
0935:                runEventLoop = false;
0936:                return true;
0937:            }
0938:
0939:            /* (non-Javadoc)
0940:             * @see org.eclipse.ui.IWorkbench#saveAllEditors(boolean)
0941:             */
0942:            public boolean saveAllEditors(boolean confirm) {
0943:                final boolean finalConfirm = confirm;
0944:                final boolean[] result = new boolean[1];
0945:                result[0] = true;
0946:
0947:                SafeRunner
0948:                        .run(new SafeRunnable(WorkbenchMessages.ErrorClosing) {
0949:                            public void run() {
0950:                                // Collect dirtyParts
0951:                                ArrayList dirtyParts = new ArrayList();
0952:                                ArrayList dirtyEditorsInput = new ArrayList();
0953:                                IWorkbenchWindow windows[] = getWorkbenchWindows();
0954:                                for (int i = 0; i < windows.length; i++) {
0955:                                    IWorkbenchPage pages[] = windows[i]
0956:                                            .getPages();
0957:                                    for (int j = 0; j < pages.length; j++) {
0958:                                        WorkbenchPage page = (WorkbenchPage) pages[j];
0959:
0960:                                        ISaveablePart[] parts = page
0961:                                                .getDirtyParts();
0962:
0963:                                        for (int k = 0; k < parts.length; k++) {
0964:                                            ISaveablePart part = parts[k];
0965:
0966:                                            if (part.isSaveOnCloseNeeded()) {
0967:                                                if (part instanceof  IEditorPart) {
0968:                                                    IEditorPart editor = (IEditorPart) part;
0969:                                                    if (!dirtyEditorsInput
0970:                                                            .contains(editor
0971:                                                                    .getEditorInput())) {
0972:                                                        dirtyParts.add(editor);
0973:                                                        dirtyEditorsInput
0974:                                                                .add(editor
0975:                                                                        .getEditorInput());
0976:                                                    }
0977:                                                } else {
0978:                                                    dirtyParts.add(part);
0979:                                                }
0980:                                            }
0981:                                        }
0982:                                    }
0983:                                }
0984:                                IShellProvider shellProvider;
0985:                                IRunnableContext runnableContext;
0986:                                IWorkbenchWindow w = getActiveWorkbenchWindow();
0987:                                if (w == null && windows.length > 0) {
0988:                                    w = windows[0];
0989:                                }
0990:                                if (w != null) {
0991:                                    shellProvider = (WorkbenchWindow) w;
0992:                                    runnableContext = w;
0993:                                } else {
0994:                                    shellProvider = new IShellProvider() {
0995:                                        public Shell getShell() {
0996:                                            return null;
0997:                                        }
0998:                                    };
0999:                                    runnableContext = new ProgressMonitorDialog(
1000:                                            null);
1001:                                }
1002:                                // The fourth parameter is true to also save saveables from
1003:                                // non-part sources, see bug 139004.
1004:                                result[0] = EditorManager.saveAll(dirtyParts,
1005:                                        finalConfirm, false, true,
1006:                                        runnableContext, shellProvider);
1007:                            }
1008:                        });
1009:                return result[0];
1010:            }
1011:
1012:            /**
1013:             * Opens a new workbench window and page with a specific perspective.
1014:             * 
1015:             * Assumes that busy cursor is active.
1016:             */
1017:            private IWorkbenchWindow busyOpenWorkbenchWindow(
1018:                    final String perspID, final IAdaptable input)
1019:                    throws WorkbenchException {
1020:                // Create a workbench window (becomes active window)
1021:                final WorkbenchWindow newWindowArray[] = new WorkbenchWindow[1];
1022:                StartupThreading
1023:                        .runWithWorkbenchExceptions(new StartupRunnable() {
1024:                            public void runWithException() {
1025:                                newWindowArray[0] = newWorkbenchWindow();
1026:                            }
1027:                        });
1028:
1029:                final WorkbenchWindow newWindow = newWindowArray[0];
1030:
1031:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1032:
1033:                    public void runWithException() {
1034:                        newWindow.create(); // must be created before adding to window
1035:                        // manager
1036:                    }
1037:                });
1038:                windowManager.add(newWindow);
1039:
1040:                final WorkbenchException[] exceptions = new WorkbenchException[1];
1041:                // Create the initial page.
1042:                if (perspID != null) {
1043:                    StartupThreading
1044:                            .runWithWorkbenchExceptions(new StartupRunnable() {
1045:
1046:                                public void runWithException()
1047:                                        throws WorkbenchException {
1048:                                    try {
1049:                                        newWindow.busyOpenPage(perspID, input);
1050:                                    } catch (WorkbenchException e) {
1051:                                        windowManager.remove(newWindow);
1052:                                        exceptions[0] = e;
1053:                                    }
1054:                                }
1055:                            });
1056:                }
1057:                if (exceptions[0] != null)
1058:                    throw exceptions[0];
1059:
1060:                // Open window after opening page, to avoid flicker.
1061:                StartupThreading
1062:                        .runWithWorkbenchExceptions(new StartupRunnable() {
1063:
1064:                            public void runWithException() {
1065:                                newWindow.open();
1066:                            }
1067:                        });
1068:
1069:                return newWindow;
1070:            }
1071:
1072:            /*
1073:             * (non-Javadoc) Method declared on IWorkbench.
1074:             */
1075:            public boolean close() {
1076:                return close(PlatformUI.RETURN_OK, false);
1077:            }
1078:
1079:            /**
1080:             * Closes the workbench, returning the given return code from the run
1081:             * method. If forced, the workbench is closed no matter what.
1082:             * 
1083:             * @param returnCode
1084:             *            {@link PlatformUI#RETURN_OK RETURN_OK}for normal exit;
1085:             *            {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
1086:             *            workbench was terminated with a call to
1087:             *            {@link IWorkbench#restart IWorkbench.restart};
1088:             *            {@link PlatformUI#RETURN_EMERGENCY_CLOSE} for an emergency
1089:             *            shutdown
1090:             *            {@link PlatformUI#RETURN_UNSTARTABLE RETURN_UNSTARTABLE}if
1091:             *            the workbench could not be started; other values reserved for
1092:             *            future use
1093:             * 
1094:             * @param force
1095:             *            true to force the workbench close, and false for a "soft"
1096:             *            close that can be canceled
1097:             * @return true if the close was successful, and false if the close was
1098:             *         canceled
1099:             */
1100:            /* package */
1101:            boolean close(int returnCode, final boolean force) {
1102:                this .returnCode = returnCode;
1103:                final boolean[] ret = new boolean[1];
1104:                BusyIndicator.showWhile(null, new Runnable() {
1105:                    public void run() {
1106:                        ret[0] = busyClose(force);
1107:                    }
1108:                });
1109:                return ret[0];
1110:            }
1111:
1112:            /*
1113:             * (non-Javadoc) Method declared on IWorkbench.
1114:             */
1115:            public IWorkbenchWindow getActiveWorkbenchWindow() {
1116:                // Return null if called from a non-UI thread.
1117:                // This is not spec'ed behaviour and is misleading, however this is how
1118:                // it
1119:                // worked in 2.1 and we cannot change it now.
1120:                // For more details, see [Bug 57384] [RCP] Main window not active on
1121:                // startup
1122:                if (Display.getCurrent() == null) {
1123:                    return null;
1124:                }
1125:
1126:                // Look at the current shell and up its parent
1127:                // hierarchy for a workbench window.
1128:                Control shell = display.getActiveShell();
1129:                while (shell != null) {
1130:                    Object data = shell.getData();
1131:                    if (data instanceof  IWorkbenchWindow) {
1132:                        return (IWorkbenchWindow) data;
1133:                    }
1134:                    shell = shell.getParent();
1135:                }
1136:
1137:                // Look for the window that was last known being
1138:                // the active one
1139:                WorkbenchWindow win = getActivatedWindow();
1140:                if (win != null) {
1141:                    return win;
1142:                }
1143:
1144:                // Look at all the shells and pick the first one
1145:                // that is a workbench window.
1146:                Shell shells[] = display.getShells();
1147:                for (int i = 0; i < shells.length; i++) {
1148:                    Object data = shells[i].getData();
1149:                    if (data instanceof  IWorkbenchWindow) {
1150:                        return (IWorkbenchWindow) data;
1151:                    }
1152:                }
1153:
1154:                // Can't find anything!
1155:                return null;
1156:            }
1157:
1158:            /*
1159:             * Returns the editor history.
1160:             */
1161:            public EditorHistory getEditorHistory() {
1162:                if (editorHistory == null) {
1163:                    editorHistory = new EditorHistory();
1164:                }
1165:                return editorHistory;
1166:            }
1167:
1168:            /*
1169:             * (non-Javadoc) Method declared on IWorkbench.
1170:             */
1171:            public IEditorRegistry getEditorRegistry() {
1172:                return WorkbenchPlugin.getDefault().getEditorRegistry();
1173:            }
1174:
1175:            /*
1176:             * Returns the number for a new window. This will be the first number > 0
1177:             * which is not used to identify another window in the workbench.
1178:             */
1179:            private int getNewWindowNumber() {
1180:                // Get window list.
1181:                Window[] windows = windowManager.getWindows();
1182:                int count = windows.length;
1183:
1184:                // Create an array of booleans (size = window count).
1185:                // Cross off every number found in the window list.
1186:                boolean checkArray[] = new boolean[count];
1187:                for (int nX = 0; nX < count; nX++) {
1188:                    if (windows[nX] instanceof  WorkbenchWindow) {
1189:                        WorkbenchWindow ww = (WorkbenchWindow) windows[nX];
1190:                        int index = ww.getNumber() - 1;
1191:                        if (index >= 0 && index < count) {
1192:                            checkArray[index] = true;
1193:                        }
1194:                    }
1195:                }
1196:
1197:                // Return first index which is not used.
1198:                // If no empty index was found then every slot is full.
1199:                // Return next index.
1200:                for (int index = 0; index < count; index++) {
1201:                    if (!checkArray[index]) {
1202:                        return index + 1;
1203:                    }
1204:                }
1205:                return count + 1;
1206:            }
1207:
1208:            /*
1209:             * (non-Javadoc) Method declared on IWorkbench.
1210:             */
1211:            public IWorkbenchOperationSupport getOperationSupport() {
1212:                return WorkbenchPlugin.getDefault().getOperationSupport();
1213:            }
1214:
1215:            /*
1216:             * (non-Javadoc) Method declared on IWorkbench.
1217:             */
1218:            public IPerspectiveRegistry getPerspectiveRegistry() {
1219:                return WorkbenchPlugin.getDefault().getPerspectiveRegistry();
1220:            }
1221:
1222:            /*
1223:             * (non-Javadoc) Method declared on IWorkbench.
1224:             */
1225:            public PreferenceManager getPreferenceManager() {
1226:                return WorkbenchPlugin.getDefault().getPreferenceManager();
1227:            }
1228:
1229:            /*
1230:             * (non-Javadoc) Method declared on IWorkbench.
1231:             */
1232:            public IPreferenceStore getPreferenceStore() {
1233:                return WorkbenchPlugin.getDefault().getPreferenceStore();
1234:            }
1235:
1236:            /*
1237:             * (non-Javadoc) Method declared on IWorkbench.
1238:             */
1239:            public ISharedImages getSharedImages() {
1240:                return WorkbenchPlugin.getDefault().getSharedImages();
1241:            }
1242:
1243:            /**
1244:             * Returns the window manager for this workbench.
1245:             * 
1246:             * @return the window manager
1247:             */
1248:            /* package */
1249:            WindowManager getWindowManager() {
1250:                return windowManager;
1251:            }
1252:
1253:            /*
1254:             * Answer the workbench state file.
1255:             */
1256:            private File getWorkbenchStateFile() {
1257:                IPath path = WorkbenchPlugin.getDefault().getDataLocation();
1258:                if (path == null) {
1259:                    return null;
1260:                }
1261:                path = path.append(DEFAULT_WORKBENCH_STATE_FILENAME);
1262:                return path.toFile();
1263:            }
1264:
1265:            /*
1266:             * (non-Javadoc) Method declared on IWorkbench.
1267:             */
1268:            public int getWorkbenchWindowCount() {
1269:                return windowManager.getWindowCount();
1270:            }
1271:
1272:            /*
1273:             * (non-Javadoc) Method declared on IWorkbench.
1274:             */
1275:            public IWorkbenchWindow[] getWorkbenchWindows() {
1276:                Window[] windows = windowManager.getWindows();
1277:                IWorkbenchWindow[] dwindows = new IWorkbenchWindow[windows.length];
1278:                System.arraycopy(windows, 0, dwindows, 0, windows.length);
1279:                return dwindows;
1280:            }
1281:
1282:            /*
1283:             * (non-Javadoc) Method declared on IWorkbench.
1284:             */
1285:            public IWorkingSetManager getWorkingSetManager() {
1286:                return WorkbenchPlugin.getDefault().getWorkingSetManager();
1287:            }
1288:
1289:            /**
1290:             * {@inheritDoc}
1291:             */
1292:            public ILocalWorkingSetManager createLocalWorkingSetManager() {
1293:                return new LocalWorkingSetManager(WorkbenchPlugin.getDefault()
1294:                        .getBundleContext());
1295:            }
1296:
1297:            /**
1298:             * Initializes the workbench now that the display is created.
1299:             * 
1300:             * @return true if init succeeded.
1301:             */
1302:            private boolean init() {
1303:                // setup debug mode if required.
1304:                if (WorkbenchPlugin.getDefault().isDebugging()) {
1305:                    WorkbenchPlugin.DEBUG = true;
1306:                    ModalContext.setDebugMode(true);
1307:                }
1308:
1309:                // Set up the JFace preference store
1310:                JFaceUtil.initializeJFacePreferences();
1311:
1312:                // create workbench window manager
1313:                windowManager = new WindowManager();
1314:
1315:                IIntroRegistry introRegistry = WorkbenchPlugin.getDefault()
1316:                        .getIntroRegistry();
1317:                if (introRegistry.getIntroCount() > 0) {
1318:                    IProduct product = Platform.getProduct();
1319:                    if (product != null) {
1320:                        introDescriptor = (IntroDescriptor) introRegistry
1321:                                .getIntroForProduct(product.getId());
1322:                    }
1323:                }
1324:
1325:                // Initialize the activity support.
1326:                workbenchActivitySupport = new WorkbenchActivitySupport();
1327:                activityHelper = ActivityPersistanceHelper.getInstance();
1328:
1329:                initializeDefaultServices();
1330:                initializeFonts();
1331:                initializeColors();
1332:                initializeApplicationColors();
1333:
1334:                // now that the workbench is sufficiently initialized, let the advisor
1335:                // have a turn.
1336:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1337:
1338:                    public void runWithException() {
1339:                        advisor
1340:                                .internalBasicInitialize(getWorkbenchConfigurer());
1341:                    }
1342:                });
1343:
1344:                // configure use of color icons in toolbars
1345:                boolean useColorIcons = PrefUtil.getInternalPreferenceStore()
1346:                        .getBoolean(IPreferenceConstants.COLOR_ICONS);
1347:                ActionContributionItem
1348:                        .setUseColorIconsInToolbars(useColorIcons);
1349:
1350:                // initialize workbench single-click vs double-click behavior
1351:                initializeSingleClickOption();
1352:
1353:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1354:
1355:                    public void runWithException() {
1356:                        ((GrabFocus) Tweaklets.get(GrabFocus.KEY))
1357:                                .init(getDisplay());
1358:                    }
1359:                });
1360:
1361:                // attempt to restore a previous workbench state
1362:                try {
1363:                    UIStats.start(UIStats.RESTORE_WORKBENCH, "Workbench"); //$NON-NLS-1$
1364:
1365:                    final boolean bail[] = new boolean[1];
1366:                    StartupThreading
1367:                            .runWithoutExceptions(new StartupRunnable() {
1368:
1369:                                public void runWithException() throws Throwable {
1370:                                    advisor.preStartup();
1371:
1372:                                    if (!advisor.openWindows()) {
1373:                                        bail[0] = true;
1374:                                    }
1375:                                }
1376:                            });
1377:
1378:                    if (bail[0])
1379:                        return false;
1380:
1381:                } finally {
1382:                    UIStats.end(UIStats.RESTORE_WORKBENCH, this , "Workbench"); //$NON-NLS-1$
1383:                }
1384:
1385:                forceOpenPerspective();
1386:
1387:                return true;
1388:            }
1389:
1390:            /**
1391:             * Establishes the relationship between JFace actions and the command
1392:             * manager.
1393:             */
1394:            private void initializeCommandResolver() {
1395:                ExternalActionManager.getInstance().setCallback(
1396:                        new CommandCallback(bindingManager, commandManager,
1397:                                new IActiveChecker() {
1398:                                    public final boolean isActive(
1399:                                            final String commandId) {
1400:                                        return workbenchActivitySupport
1401:                                                .getActivityManager()
1402:                                                .getIdentifier(commandId)
1403:                                                .isEnabled();
1404:                                    }
1405:                                }));
1406:            }
1407:
1408:            /**
1409:             * Initialize colors defined by the new colorDefinitions extension point.
1410:             * Note this will be rolled into initializeColors() at some point.
1411:             * 
1412:             * @since 3.0
1413:             */
1414:            private void initializeApplicationColors() {
1415:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1416:
1417:                    public void runWithException() {
1418:                        ColorDefinition[] colorDefinitions = WorkbenchPlugin
1419:                                .getDefault().getThemeRegistry().getColors();
1420:                        ThemeElementHelper.populateRegistry(getThemeManager()
1421:                                .getTheme(IThemeManager.DEFAULT_THEME),
1422:                                colorDefinitions, PrefUtil
1423:                                        .getInternalPreferenceStore());
1424:                    }
1425:                });
1426:            }
1427:
1428:            private void initializeSingleClickOption() {
1429:                IPreferenceStore store = WorkbenchPlugin.getDefault()
1430:                        .getPreferenceStore();
1431:                boolean openOnSingleClick = store
1432:                        .getBoolean(IPreferenceConstants.OPEN_ON_SINGLE_CLICK);
1433:                boolean selectOnHover = store
1434:                        .getBoolean(IPreferenceConstants.SELECT_ON_HOVER);
1435:                boolean openAfterDelay = store
1436:                        .getBoolean(IPreferenceConstants.OPEN_AFTER_DELAY);
1437:                int singleClickMethod = openOnSingleClick ? OpenStrategy.SINGLE_CLICK
1438:                        : OpenStrategy.DOUBLE_CLICK;
1439:                if (openOnSingleClick) {
1440:                    if (selectOnHover) {
1441:                        singleClickMethod |= OpenStrategy.SELECT_ON_HOVER;
1442:                    }
1443:                    if (openAfterDelay) {
1444:                        singleClickMethod |= OpenStrategy.ARROW_KEYS_OPEN;
1445:                    }
1446:                }
1447:                OpenStrategy.setOpenMethod(singleClickMethod);
1448:            }
1449:
1450:            /*
1451:             * Initializes the workbench fonts with the stored values.
1452:             */
1453:            private void initializeFonts() {
1454:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1455:
1456:                    public void runWithException() {
1457:                        FontDefinition[] fontDefinitions = WorkbenchPlugin
1458:                                .getDefault().getThemeRegistry().getFonts();
1459:
1460:                        ThemeElementHelper.populateRegistry(getThemeManager()
1461:                                .getCurrentTheme(), fontDefinitions, PrefUtil
1462:                                .getInternalPreferenceStore());
1463:                    }
1464:                });
1465:            }
1466:
1467:            /*
1468:             * Initialize the workbench images.
1469:             * 
1470:             * @param windowImages An array of the descriptors of the images to be used
1471:             * in the corner of each window, or <code>null</code> if none. It is
1472:             * expected that the array will contain the same icon, rendered at different
1473:             * sizes.
1474:             * 
1475:             * @since 3.0
1476:             */
1477:            private static void initializeImages() {
1478:                ImageDescriptor[] windowImages = WorkbenchPlugin.getDefault()
1479:                        .getWindowImages();
1480:                if (windowImages == null) {
1481:                    return;
1482:                }
1483:
1484:                Image[] images = new Image[windowImages.length];
1485:                for (int i = 0; i < windowImages.length; ++i) {
1486:                    images[i] = windowImages[i].createImage();
1487:                }
1488:                Window.setDefaultImages(images);
1489:            }
1490:
1491:            /*
1492:             * Take the workbenches' images out of the shared registry.
1493:             * 
1494:             * @since 3.0
1495:             */
1496:            private void uninitializeImages() {
1497:                WorkbenchImages.dispose();
1498:                Image[] images = Window.getDefaultImages();
1499:                Window.setDefaultImage(null);
1500:                for (int i = 0; i < images.length; i++) {
1501:                    images[i].dispose();
1502:                }
1503:            }
1504:
1505:            /*
1506:             * Initialize the workbench colors.
1507:             * 
1508:             * @since 3.0
1509:             */
1510:            private void initializeColors() {
1511:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1512:                    public void runWithException() {
1513:                        WorkbenchColors.startup();
1514:                    }
1515:                });
1516:            }
1517:
1518:            /*
1519:             * (non-Javadoc) Method declared on IWorkbench.
1520:             */
1521:            public boolean isClosing() {
1522:                return isClosing;
1523:            }
1524:
1525:            /**
1526:             * Initializes all of the default services for the workbench. For
1527:             * initializing the command-based services, this also parses the registry
1528:             * and hooks up all the required listeners.
1529:             */
1530:            private final void initializeDefaultServices() {
1531:
1532:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1533:
1534:                    public void runWithException() {
1535:                        serviceLocator.registerService(IWorkbench.class,
1536:                                Workbench.this );
1537:                    }
1538:                });
1539:
1540:                // TODO Correctly order service initialization
1541:                // there needs to be some serious consideration given to
1542:                // the services, and hooking them up in the correct order
1543:                final EvaluationService evaluationService = new EvaluationService();
1544:
1545:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1546:
1547:                    public void runWithException() {
1548:                        serviceLocator.registerService(
1549:                                IEvaluationService.class, evaluationService);
1550:                    }
1551:                });
1552:
1553:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1554:
1555:                    public void runWithException() {
1556:                        serviceLocator.registerService(
1557:                                ISaveablesLifecycleListener.class,
1558:                                new SaveablesList());
1559:                    }
1560:                });
1561:
1562:                /*
1563:                 * Phase 1 of the initialization of commands. When this phase completes,
1564:                 * all the services and managers will exist, and be accessible via the
1565:                 * getService(Object) method.
1566:                 */
1567:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1568:
1569:                    public void runWithException() {
1570:                        Command.DEBUG_COMMAND_EXECUTION = Policy.DEBUG_COMMANDS;
1571:                        commandManager = new CommandManager();
1572:                    }
1573:                });
1574:
1575:                final CommandService[] commandService = new CommandService[1];
1576:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1577:
1578:                    public void runWithException() {
1579:                        commandService[0] = new CommandService(commandManager);
1580:                        commandService[0].readRegistry();
1581:                        serviceLocator.registerService(ICommandService.class,
1582:                                commandService[0]);
1583:
1584:                    }
1585:                });
1586:
1587:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1588:
1589:                    public void runWithException() {
1590:                        ContextManager.DEBUG = Policy.DEBUG_CONTEXTS;
1591:                        contextManager = new ContextManager();
1592:                    }
1593:                });
1594:
1595:                final IContextService contextService = new ContextService(
1596:                        contextManager);
1597:
1598:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1599:
1600:                    public void runWithException() {
1601:                        contextService.readRegistry();
1602:                    }
1603:                });
1604:
1605:                serviceLocator.registerService(IContextService.class,
1606:                        contextService);
1607:
1608:                final IHandlerService[] handlerService = new IHandlerService[1];
1609:
1610:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1611:
1612:                    public void runWithException() {
1613:                        handlerService[0] = new HandlerService(
1614:                                commandService[0], evaluationService);
1615:                        handlerService[0].readRegistry();
1616:                    }
1617:                });
1618:
1619:                serviceLocator.registerService(IHandlerService.class,
1620:                        handlerService[0]);
1621:
1622:                final IBindingService[] bindingService = new BindingService[1];
1623:
1624:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1625:
1626:                    public void runWithException() {
1627:                        BindingManager.DEBUG = Policy.DEBUG_KEY_BINDINGS;
1628:                        bindingManager = new BindingManager(contextManager,
1629:                                commandManager);
1630:                        bindingService[0] = new BindingService(bindingManager,
1631:                                commandService[0], Workbench.this );
1632:
1633:                    }
1634:                });
1635:
1636:                bindingService[0].readRegistryAndPreferences(commandService[0]);
1637:                serviceLocator.registerService(IBindingService.class,
1638:                        bindingService[0]);
1639:
1640:                final CommandImageManager commandImageManager = new CommandImageManager();
1641:                final CommandImageService commandImageService = new CommandImageService(
1642:                        commandImageManager, commandService[0]);
1643:                commandImageService.readRegistry();
1644:                serviceLocator.registerService(ICommandImageService.class,
1645:                        commandImageService);
1646:
1647:                final WorkbenchMenuService menuService = new WorkbenchMenuService(
1648:                        serviceLocator);
1649:
1650:                serviceLocator.registerService(IMenuService.class, menuService);
1651:                // the service must be registered before it is initialized - its
1652:                // initialization uses the service locator to address a dependency on
1653:                // the menu service
1654:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1655:
1656:                    public void runWithException() {
1657:                        menuService.readRegistry();
1658:                    }
1659:                });
1660:
1661:                /*
1662:                 * Phase 2 of the initialization of commands. The source providers that
1663:                 * the workbench provides are creating and registered with the above
1664:                 * services. These source providers notify the services when particular
1665:                 * pieces of workbench state change.
1666:                 */
1667:                final ISourceProviderService sourceProviderService = new SourceProviderService();
1668:                serviceLocator.registerService(ISourceProviderService.class,
1669:                        sourceProviderService);
1670:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1671:
1672:                    public void runWithException() {
1673:                        final ActiveShellSourceProvider activeShellSourceProvider = new ActiveShellSourceProvider(
1674:                                Workbench.this );
1675:                        evaluationService
1676:                                .addSourceProvider(activeShellSourceProvider);
1677:                        handlerService[0]
1678:                                .addSourceProvider(activeShellSourceProvider);
1679:                        contextService
1680:                                .addSourceProvider(activeShellSourceProvider);
1681:                        menuService
1682:                                .addSourceProvider(activeShellSourceProvider);
1683:                        sourceProviderService
1684:                                .registerProvider(activeShellSourceProvider);
1685:                    }
1686:                });
1687:
1688:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1689:
1690:                    public void runWithException() {
1691:                        final ActivePartSourceProvider activePartSourceProvider = new ActivePartSourceProvider(
1692:                                Workbench.this );
1693:                        evaluationService
1694:                                .addSourceProvider(activePartSourceProvider);
1695:                        handlerService[0]
1696:                                .addSourceProvider(activePartSourceProvider);
1697:                        contextService
1698:                                .addSourceProvider(activePartSourceProvider);
1699:                        menuService.addSourceProvider(activePartSourceProvider);
1700:                        sourceProviderService
1701:                                .registerProvider(activePartSourceProvider);
1702:                    }
1703:                });
1704:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1705:
1706:                    public void runWithException() {
1707:                        final ActiveContextSourceProvider activeContextSourceProvider = new ActiveContextSourceProvider(
1708:                                contextService);
1709:                        evaluationService
1710:                                .addSourceProvider(activeContextSourceProvider);
1711:                        handlerService[0]
1712:                                .addSourceProvider(activeContextSourceProvider);
1713:                        menuService
1714:                                .addSourceProvider(activeContextSourceProvider);
1715:                        sourceProviderService
1716:                                .registerProvider(activeContextSourceProvider);
1717:                    }
1718:                });
1719:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1720:
1721:                    public void runWithException() {
1722:                        final CurrentSelectionSourceProvider currentSelectionSourceProvider = new CurrentSelectionSourceProvider(
1723:                                Workbench.this );
1724:                        evaluationService
1725:                                .addSourceProvider(currentSelectionSourceProvider);
1726:                        handlerService[0]
1727:                                .addSourceProvider(currentSelectionSourceProvider);
1728:                        contextService
1729:                                .addSourceProvider(currentSelectionSourceProvider);
1730:                        menuService
1731:                                .addSourceProvider(currentSelectionSourceProvider);
1732:                        sourceProviderService
1733:                                .registerProvider(currentSelectionSourceProvider);
1734:
1735:                        actionSetSourceProvider = new ActionSetSourceProvider();
1736:                        evaluationService
1737:                                .addSourceProvider(actionSetSourceProvider);
1738:                        handlerService[0]
1739:                                .addSourceProvider(actionSetSourceProvider);
1740:                        contextService
1741:                                .addSourceProvider(actionSetSourceProvider);
1742:                        menuService.addSourceProvider(actionSetSourceProvider);
1743:                        sourceProviderService
1744:                                .registerProvider(actionSetSourceProvider);
1745:
1746:                        FocusControlSourceProvider focusControl = new FocusControlSourceProvider();
1747:                        serviceLocator.registerService(IFocusService.class,
1748:                                focusControl);
1749:                        evaluationService.addSourceProvider(focusControl);
1750:                        handlerService[0].addSourceProvider(focusControl);
1751:                        contextService.addSourceProvider(focusControl);
1752:                        menuService.addSourceProvider(focusControl);
1753:                        sourceProviderService.registerProvider(focusControl);
1754:
1755:                        menuSourceProvider = new MenuSourceProvider();
1756:                        evaluationService.addSourceProvider(menuSourceProvider);
1757:                        handlerService[0].addSourceProvider(menuSourceProvider);
1758:                        contextService.addSourceProvider(menuSourceProvider);
1759:                        menuService.addSourceProvider(menuSourceProvider);
1760:                        sourceProviderService
1761:                                .registerProvider(menuSourceProvider);
1762:                    }
1763:                });
1764:
1765:                /*
1766:                 * Phase 3 of the initialization of commands. This handles the creation
1767:                 * of wrappers for legacy APIs. By the time this phase completes, any
1768:                 * code trying to access commands through legacy APIs should work.
1769:                 */
1770:                workbenchContextSupport = new WorkbenchContextSupport(this ,
1771:                        contextManager);
1772:                workbenchCommandSupport = new WorkbenchCommandSupport(
1773:                        bindingManager, commandManager, contextManager,
1774:                        handlerService[0]);
1775:                initializeCommandResolver();
1776:
1777:                addWindowListener(windowListener);
1778:                bindingManager
1779:                        .addBindingManagerListener(bindingManagerListener);
1780:
1781:                serviceLocator.registerService(
1782:                        ISelectionConversionService.class,
1783:                        new SelectionConversionService());
1784:            }
1785:
1786:            /**
1787:             * Returns true if the Workbench is in the process of starting.
1788:             * 
1789:             * @return <code>true</code> if the Workbench is starting, but not yet
1790:             *         running the event loop.
1791:             */
1792:            public boolean isStarting() {
1793:                return isStarting;
1794:            }
1795:
1796:            /*
1797:             * Creates a new workbench window.
1798:             * 
1799:             * @return the new workbench window
1800:             */
1801:            private WorkbenchWindow newWorkbenchWindow() {
1802:                return new WorkbenchWindow(getNewWindowNumber());
1803:            }
1804:
1805:            /*
1806:             * If a perspective was specified on the command line (-perspective) then
1807:             * force that perspective to open in the active window.
1808:             */
1809:            private void forceOpenPerspective() {
1810:                if (getWorkbenchWindowCount() == 0) {
1811:                    // there should be an open window by now, bail out.
1812:                    return;
1813:                }
1814:
1815:                String perspId = null;
1816:                String[] commandLineArgs = Platform.getCommandLineArgs();
1817:                for (int i = 0; i < commandLineArgs.length - 1; i++) {
1818:                    if (commandLineArgs[i].equalsIgnoreCase("-perspective")) { //$NON-NLS-1$
1819:                        perspId = commandLineArgs[i + 1];
1820:                        break;
1821:                    }
1822:                }
1823:                if (perspId == null) {
1824:                    return;
1825:                }
1826:                IPerspectiveDescriptor desc = getPerspectiveRegistry()
1827:                        .findPerspectiveWithId(perspId);
1828:                if (desc == null) {
1829:                    return;
1830:                }
1831:
1832:                IWorkbenchWindow win = getActiveWorkbenchWindow();
1833:                if (win == null) {
1834:                    win = getWorkbenchWindows()[0];
1835:                }
1836:
1837:                final String threadPerspId = perspId;
1838:                final IWorkbenchWindow threadWin = win;
1839:                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1840:                    public void runWithException() throws Throwable {
1841:                        try {
1842:                            showPerspective(threadPerspId, threadWin);
1843:                        } catch (WorkbenchException e) {
1844:                            String msg = "Workbench exception showing specified command line perspective on startup."; //$NON-NLS-1$
1845:                            WorkbenchPlugin.log(msg, new Status(IStatus.ERROR,
1846:                                    PlatformUI.PLUGIN_ID, 0, msg, e));
1847:                        }
1848:                    }
1849:                });
1850:            }
1851:
1852:            /**
1853:             * Opens the initial workbench window.
1854:             */
1855:            /* package */void openFirstTimeWindow() {
1856:                final boolean showProgress = PrefUtil
1857:                        .getAPIPreferenceStore()
1858:                        .getBoolean(
1859:                                IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP);
1860:
1861:                if (!showProgress) {
1862:                    doOpenFirstTimeWindow();
1863:                } else {
1864:                    // We don't know how many plug-ins will be loaded,
1865:                    // assume we are loading a tenth of the installed plug-ins.
1866:                    // (The Eclipse SDK loads 7 of 86 plug-ins at startup as of
1867:                    // 2005-5-20)
1868:                    final int expectedProgressCount = Math.max(1,
1869:                            WorkbenchPlugin.getDefault().getBundleCount() / 10);
1870:
1871:                    runStartupWithProgress(expectedProgressCount,
1872:                            new Runnable() {
1873:                                public void run() {
1874:                                    doOpenFirstTimeWindow();
1875:                                }
1876:                            });
1877:                }
1878:            }
1879:
1880:            private void runStartupWithProgress(
1881:                    final int expectedProgressCount, final Runnable runnable) {
1882:                progressCount = 0;
1883:                final double cutoff = 0.95;
1884:
1885:                AbstractSplashHandler handler = getSplash();
1886:                IProgressMonitor progressMonitor = null;
1887:                if (handler != null)
1888:                    progressMonitor = handler.getBundleProgressMonitor();
1889:
1890:                if (progressMonitor == null) {
1891:                    // cannot report progress (e.g. if the splash screen is not showing)
1892:                    // fall back to starting without showing progress.
1893:                    runnable.run();
1894:                } else {
1895:                    progressMonitor.beginTask("", expectedProgressCount); //$NON-NLS-1$
1896:                    SynchronousBundleListener bundleListener = new StartupProgressBundleListener(
1897:                            progressMonitor,
1898:                            (int) (expectedProgressCount * cutoff));
1899:                    WorkbenchPlugin.getDefault().addBundleListener(
1900:                            bundleListener);
1901:                    try {
1902:                        runnable.run();
1903:                        progressMonitor.subTask(WorkbenchMessages.Startup_Done);
1904:                        int remainingWork = expectedProgressCount
1905:                                - Math.min(progressCount,
1906:                                        (int) (expectedProgressCount * cutoff));
1907:                        progressMonitor.worked(remainingWork);
1908:                        progressMonitor.done();
1909:                    } finally {
1910:                        WorkbenchPlugin.getDefault().removeBundleListener(
1911:                                bundleListener);
1912:                    }
1913:                }
1914:            }
1915:
1916:            private void doOpenFirstTimeWindow() {
1917:                try {
1918:                    final IAdaptable input[] = new IAdaptable[1];
1919:                    StartupThreading
1920:                            .runWithoutExceptions(new StartupRunnable() {
1921:
1922:                                public void runWithException() throws Throwable {
1923:                                    input[0] = getDefaultPageInput();
1924:                                }
1925:                            });
1926:
1927:                    busyOpenWorkbenchWindow(getPerspectiveRegistry()
1928:                            .getDefaultPerspective(), input[0]);
1929:                } catch (final WorkbenchException e) {
1930:                    // Don't use the window's shell as the dialog parent,
1931:                    // as the window is not open yet (bug 76724).
1932:                    StartupThreading
1933:                            .runWithoutExceptions(new StartupRunnable() {
1934:
1935:                                public void runWithException() throws Throwable {
1936:                                    ErrorDialog
1937:                                            .openError(
1938:                                                    null,
1939:                                                    WorkbenchMessages.Problems_Opening_Page,
1940:                                                    e.getMessage(), e
1941:                                                            .getStatus());
1942:                                }
1943:                            });
1944:                }
1945:            }
1946:
1947:            /*
1948:             * Restores the workbench UI from the workbench state file (workbench.xml).
1949:             * 
1950:             * @return a status object indicating OK if a window was opened,
1951:             * RESTORE_CODE_RESET if no window was opened but one should be, and
1952:             * RESTORE_CODE_EXIT if the workbench should close immediately
1953:             */
1954:            /* package */IStatus restoreState() {
1955:
1956:                if (!getWorkbenchConfigurer().getSaveAndRestore()) {
1957:                    String msg = WorkbenchMessages.Workbench_restoreDisabled;
1958:                    return new Status(IStatus.WARNING,
1959:                            WorkbenchPlugin.PI_WORKBENCH,
1960:                            IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null);
1961:                }
1962:                // Read the workbench state file.
1963:                final File stateFile = getWorkbenchStateFile();
1964:                // If there is no state file cause one to open.
1965:                if (stateFile == null || !stateFile.exists()) {
1966:                    String msg = WorkbenchMessages.Workbench_noStateToRestore;
1967:                    return new Status(IStatus.WARNING,
1968:                            WorkbenchPlugin.PI_WORKBENCH,
1969:                            IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null);
1970:                }
1971:
1972:                final IStatus result[] = { new Status(IStatus.OK,
1973:                        WorkbenchPlugin.PI_WORKBENCH, IStatus.OK, "", null) }; //$NON-NLS-1$
1974:                SafeRunner.run(new SafeRunnable(
1975:                        WorkbenchMessages.ErrorReadingState) {
1976:                    public void run() throws Exception {
1977:                        FileInputStream input = new FileInputStream(stateFile);
1978:                        BufferedReader reader = new BufferedReader(
1979:                                new InputStreamReader(input, "utf-8")); //$NON-NLS-1$
1980:                        IMemento memento = XMLMemento.createReadRoot(reader);
1981:
1982:                        // Validate known version format
1983:                        String version = memento
1984:                                .getString(IWorkbenchConstants.TAG_VERSION);
1985:                        boolean valid = false;
1986:                        for (int i = 0; i < VERSION_STRING.length; i++) {
1987:                            if (VERSION_STRING[i].equals(version)) {
1988:                                valid = true;
1989:                                break;
1990:                            }
1991:                        }
1992:                        if (!valid) {
1993:                            reader.close();
1994:                            String msg = WorkbenchMessages.Invalid_workbench_state_ve;
1995:                            MessageDialog.openError((Shell) null,
1996:                                    WorkbenchMessages.Restoring_Problems, msg);
1997:                            stateFile.delete();
1998:                            result[0] = new Status(IStatus.ERROR,
1999:                                    WorkbenchPlugin.PI_WORKBENCH,
2000:                                    IWorkbenchConfigurer.RESTORE_CODE_RESET,
2001:                                    msg, null);
2002:                            return;
2003:                        }
2004:
2005:                        // Validate compatible version format
2006:                        // We no longer support the release 1.0 format
2007:                        if (VERSION_STRING[0].equals(version)) {
2008:                            reader.close();
2009:                            String msg = WorkbenchMessages.Workbench_incompatibleSavedStateVersion;
2010:                            boolean ignoreSavedState = new MessageDialog(
2011:                                    null,
2012:                                    WorkbenchMessages.Workbench_incompatibleUIState,
2013:                                    null, msg, MessageDialog.WARNING,
2014:                                    new String[] { IDialogConstants.OK_LABEL,
2015:                                            IDialogConstants.CANCEL_LABEL }, 0)
2016:                                    .open() == 0;
2017:                            // OK is the default
2018:                            if (ignoreSavedState) {
2019:                                stateFile.delete();
2020:                                result[0] = new Status(
2021:                                        IStatus.WARNING,
2022:                                        WorkbenchPlugin.PI_WORKBENCH,
2023:                                        IWorkbenchConfigurer.RESTORE_CODE_RESET,
2024:                                        msg, null);
2025:                            } else {
2026:                                result[0] = new Status(IStatus.WARNING,
2027:                                        WorkbenchPlugin.PI_WORKBENCH,
2028:                                        IWorkbenchConfigurer.RESTORE_CODE_EXIT,
2029:                                        msg, null);
2030:                            }
2031:                            return;
2032:                        }
2033:
2034:                        // Restore the saved state
2035:                        final IStatus restoreResult = restoreState(memento);
2036:                        reader.close();
2037:                        if (restoreResult.getSeverity() == IStatus.ERROR) {
2038:                            StartupThreading
2039:                                    .runWithoutExceptions(new StartupRunnable() {
2040:
2041:                                        public void runWithException()
2042:                                                throws Throwable {
2043:                                            ErrorDialog
2044:                                                    .openError(
2045:                                                            null,
2046:                                                            WorkbenchMessages.Workspace_problemsTitle,
2047:                                                            WorkbenchMessages.Workbench_problemsRestoringMsg,
2048:                                                            restoreResult);
2049:                                        }
2050:                                    });
2051:
2052:                        }
2053:                    }
2054:
2055:                    public void handleException(final Throwable e) {
2056:                        StartupThreading
2057:                                .runWithoutExceptions(new StartupRunnable() {
2058:
2059:                                    public void runWithException() {
2060:                                        handle(e);
2061:                                        String msg = e.getMessage() == null ? "" : e.getMessage(); //$NON-NLS-1$
2062:                                        result[0] = new Status(
2063:                                                IStatus.ERROR,
2064:                                                WorkbenchPlugin.PI_WORKBENCH,
2065:                                                IWorkbenchConfigurer.RESTORE_CODE_RESET,
2066:                                                msg, e);
2067:                                        stateFile.delete();
2068:                                    }
2069:                                });
2070:                    }
2071:
2072:                    private void handle(final Throwable e) {
2073:                        super .handleException(e);
2074:                    }
2075:                });
2076:                // ensure at least one window was opened
2077:                if (result[0].isOK() && windowManager.getWindows().length == 0) {
2078:                    String msg = WorkbenchMessages.Workbench_noWindowsRestored;
2079:                    result[0] = new Status(IStatus.ERROR,
2080:                            WorkbenchPlugin.PI_WORKBENCH,
2081:                            IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null);
2082:                }
2083:                return result[0];
2084:            }
2085:
2086:            /*
2087:             * (non-Javadoc) Method declared on IWorkbench.
2088:             */
2089:            public IWorkbenchWindow openWorkbenchWindow(IAdaptable input)
2090:                    throws WorkbenchException {
2091:                return openWorkbenchWindow(getPerspectiveRegistry()
2092:                        .getDefaultPerspective(), input);
2093:            }
2094:
2095:            /*
2096:             * (non-Javadoc) Method declared on IWorkbench.
2097:             */
2098:            public IWorkbenchWindow openWorkbenchWindow(final String perspID,
2099:                    final IAdaptable input) throws WorkbenchException {
2100:                // Run op in busy cursor.
2101:                final Object[] result = new Object[1];
2102:                BusyIndicator.showWhile(null, new Runnable() {
2103:                    public void run() {
2104:                        try {
2105:                            result[0] = busyOpenWorkbenchWindow(perspID, input);
2106:                        } catch (WorkbenchException e) {
2107:                            result[0] = e;
2108:                        }
2109:                    }
2110:                });
2111:                if (result[0] instanceof  IWorkbenchWindow) {
2112:                    return (IWorkbenchWindow) result[0];
2113:                } else if (result[0] instanceof  WorkbenchException) {
2114:                    throw (WorkbenchException) result[0];
2115:                } else {
2116:                    throw new WorkbenchException(
2117:                            WorkbenchMessages.Abnormal_Workbench_Conditi);
2118:                }
2119:            }
2120:
2121:            /*
2122:             * (non-Javadoc)
2123:             * 
2124:             * @see org.eclipse.ui.IWorkbench#restoreWorkbenchWindow(org.eclipse.ui.IMemento)
2125:             */
2126:            IWorkbenchWindow restoreWorkbenchWindow(IMemento memento)
2127:                    throws WorkbenchException {
2128:                WorkbenchWindow newWindow = newWorkbenchWindow();
2129:                newWindow.create();
2130:
2131:                windowManager.add(newWindow);
2132:
2133:                // whether the window was opened
2134:                boolean opened = false;
2135:
2136:                try {
2137:                    newWindow.restoreState(memento, null);
2138:                    newWindow.fireWindowRestored();
2139:                    newWindow.open();
2140:                    opened = true;
2141:                } finally {
2142:                    if (!opened) {
2143:                        newWindow.close();
2144:                    }
2145:                }
2146:
2147:                return newWindow;
2148:            }
2149:
2150:            /*
2151:             * Record the workbench UI in a document
2152:             */
2153:            private XMLMemento recordWorkbenchState() {
2154:                XMLMemento memento = XMLMemento
2155:                        .createWriteRoot(IWorkbenchConstants.TAG_WORKBENCH);
2156:                final IStatus status = saveState(memento);
2157:                if (status.getSeverity() != IStatus.OK) {
2158:                    // don't use newWindow as parent because it has not yet been opened
2159:                    // (bug 76724)
2160:                    StartupThreading
2161:                            .runWithoutExceptions(new StartupRunnable() {
2162:
2163:                                public void runWithException() throws Throwable {
2164:                                    ErrorDialog
2165:                                            .openError(
2166:                                                    null,
2167:                                                    WorkbenchMessages.Workbench_problemsSaving,
2168:                                                    WorkbenchMessages.Workbench_problemsSavingMsg,
2169:                                                    status);
2170:                                }
2171:                            });
2172:
2173:                }
2174:                return memento;
2175:            }
2176:
2177:            /*
2178:             * (non-Javadoc) Method declared on IWorkbench.
2179:             */
2180:            public boolean restart() {
2181:                // this is the return code from run() to trigger a restart
2182:                return close(PlatformUI.RETURN_RESTART, false);
2183:            }
2184:
2185:            /*
2186:             * Restores the state of the previously saved workbench
2187:             */
2188:            private IStatus restoreState(final IMemento memento) {
2189:
2190:                final MultiStatus result = new MultiStatus(
2191:                        PlatformUI.PLUGIN_ID, IStatus.OK,
2192:                        WorkbenchMessages.Workbench_problemsRestoring, null);
2193:
2194:                final boolean showProgress = PrefUtil
2195:                        .getAPIPreferenceStore()
2196:                        .getBoolean(
2197:                                IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP);
2198:
2199:                try {
2200:                    /*
2201:                     * Restored windows will be set in the createdWindows field to be
2202:                     * used by the openWindowsAfterRestore() method
2203:                     */
2204:                    if (!showProgress) {
2205:                        doRestoreState(memento, result);
2206:                    } else {
2207:                        // Retrieve how many plug-ins were loaded while restoring the
2208:                        // workbench
2209:                        Integer lastProgressCount = memento
2210:                                .getInteger(IWorkbenchConstants.TAG_PROGRESS_COUNT);
2211:
2212:                        // If we don't know how many plug-ins were loaded last time,
2213:                        // assume we are loading half of the installed plug-ins.
2214:                        final int expectedProgressCount = Math.max(1,
2215:                                lastProgressCount == null ? WorkbenchPlugin
2216:                                        .getDefault().getBundleCount() / 2
2217:                                        : lastProgressCount.intValue());
2218:
2219:                        runStartupWithProgress(expectedProgressCount,
2220:                                new Runnable() {
2221:                                    public void run() {
2222:                                        doRestoreState(memento, result);
2223:                                    }
2224:                                });
2225:                    }
2226:                } finally {
2227:                    openWindowsAfterRestore();
2228:                }
2229:                return result;
2230:            }
2231:
2232:            /**
2233:             * Returns the ids of all plug-ins that extend the
2234:             * <code>org.eclipse.ui.startup</code> extension point.
2235:             * 
2236:             * @return the ids of all plug-ins containing 1 or more startup extensions
2237:             */
2238:            public String[] getEarlyActivatedPlugins() {
2239:                IExtensionPoint point = Platform.getExtensionRegistry()
2240:                        .getExtensionPoint(PlatformUI.PLUGIN_ID,
2241:                                IWorkbenchRegistryConstants.PL_STARTUP);
2242:                IExtension[] extensions = point.getExtensions();
2243:                ArrayList pluginIds = new ArrayList(extensions.length);
2244:                for (int i = 0; i < extensions.length; i++) {
2245:                    String id = extensions[i].getNamespace();
2246:                    if (!pluginIds.contains(id)) {
2247:                        pluginIds.add(id);
2248:                    }
2249:                }
2250:                return (String[]) pluginIds
2251:                        .toArray(new String[pluginIds.size()]);
2252:            }
2253:
2254:            /**
2255:             * Returns the ids of the early activated plug-ins that have been disabled
2256:             * by the user.
2257:             * 
2258:             * @return the ids of the early activated plug-ins that have been disabled
2259:             *         by the user
2260:             */
2261:            public String[] getDisabledEarlyActivatedPlugins() {
2262:                String pref = PrefUtil.getInternalPreferenceStore().getString(
2263:                        IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
2264:                return Util.getArrayFromList(pref, ";"); //$NON-NLS-1$
2265:            }
2266:
2267:            /*
2268:             * Starts all plugins that extend the <code> org.eclipse.ui.startup </code>
2269:             * extension point, and that the user has not disabled via the preference
2270:             * page.
2271:             */
2272:            private void startPlugins() {
2273:                IExtensionRegistry registry = Platform.getExtensionRegistry();
2274:
2275:                // bug 55901: don't use getConfigElements directly, for pre-3.0
2276:                // compat, make sure to allow both missing class
2277:                // attribute and a missing startup element
2278:                IExtensionPoint point = registry.getExtensionPoint(
2279:                        PlatformUI.PLUGIN_ID,
2280:                        IWorkbenchRegistryConstants.PL_STARTUP);
2281:
2282:                final IExtension[] extensions = point.getExtensions();
2283:                if (extensions.length == 0) {
2284:                    return;
2285:                }
2286:                Job job = new Job("Workbench early startup") { //$NON-NLS-1$
2287:                    protected IStatus run(IProgressMonitor monitor) {
2288:                        HashSet disabledPlugins = new HashSet(Arrays
2289:                                .asList(getDisabledEarlyActivatedPlugins()));
2290:                        monitor.beginTask(
2291:                                WorkbenchMessages.Workbench_startingPlugins,
2292:                                extensions.length);
2293:                        for (int i = 0; i < extensions.length; ++i) {
2294:                            if (monitor.isCanceled() || !isRunning()) {
2295:                                return Status.CANCEL_STATUS;
2296:                            }
2297:                            IExtension extension = extensions[i];
2298:
2299:                            // if the plugin is not in the set of disabled plugins, then
2300:                            // execute the code to start it
2301:                            if (!disabledPlugins.contains(extension
2302:                                    .getNamespace())) {
2303:                                monitor.subTask(extension.getNamespace());
2304:                                SafeRunner.run(new EarlyStartupRunnable(
2305:                                        extension));
2306:                            }
2307:                            monitor.worked(1);
2308:                        }
2309:                        monitor.done();
2310:                        return Status.OK_STATUS;
2311:                    }
2312:
2313:                    public boolean belongsTo(Object family) {
2314:                        return EARLY_STARTUP_FAMILY.equals(family);
2315:                    }
2316:                };
2317:                job.setSystem(true);
2318:                job.schedule();
2319:            }
2320:
2321:            /**
2322:             * Internal method for running the workbench UI. This entails processing and
2323:             * dispatching events until the workbench is closed or restarted.
2324:             * 
2325:             * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
2326:             *         exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
2327:             *         workbench was terminated with a call to
2328:             *         {@link IWorkbench#restart IWorkbench.restart};
2329:             *         {@link PlatformUI#RETURN_UNSTARTABLE RETURN_UNSTARTABLE}if the
2330:             *         workbench could not be started; other values reserved for future
2331:             *         use
2332:             * @since 3.0
2333:             */
2334:            private int runUI() {
2335:                UIStats.start(UIStats.START_WORKBENCH, "Workbench"); //$NON-NLS-1$
2336:
2337:                // deadlock code
2338:                boolean avoidDeadlock = true;
2339:
2340:                String[] commandLineArgs = Platform.getCommandLineArgs();
2341:                for (int i = 0; i < commandLineArgs.length; i++) {
2342:                    if (commandLineArgs[i].equalsIgnoreCase("-allowDeadlock")) { //$NON-NLS-1$
2343:                        avoidDeadlock = false;
2344:                    }
2345:                }
2346:
2347:                final UISynchronizer synchronizer;
2348:
2349:                if (avoidDeadlock) {
2350:                    UILockListener uiLockListener = new UILockListener(display);
2351:                    Platform.getJobManager().setLockListener(uiLockListener);
2352:                    synchronizer = new UISynchronizer(display, uiLockListener);
2353:                    display.setSynchronizer(synchronizer);
2354:                    // declare the main thread to be a startup thread.
2355:                    UISynchronizer.startupThread.set(Boolean.TRUE);
2356:                } else
2357:                    synchronizer = null;
2358:
2359:                // prime the splash nice and early
2360:                if (createSplash)
2361:                    createSplashWrapper();
2362:
2363:                // ModalContext should not spin the event loop (there is no UI yet to
2364:                // block)
2365:                ModalContext.setAllowReadAndDispatch(false);
2366:
2367:                // if the -debug command line argument is used and the event loop is
2368:                // being
2369:                // run while starting the Workbench, log a warning.
2370:                if (WorkbenchPlugin.getDefault().isDebugging()) {
2371:                    display.asyncExec(new Runnable() {
2372:                        public void run() {
2373:                            if (isStarting()) {
2374:                                WorkbenchPlugin
2375:                                        .log(StatusUtil
2376:                                                .newStatus(
2377:                                                        IStatus.WARNING,
2378:                                                        "Event loop should not be run while the Workbench is starting.", //$NON-NLS-1$
2379:                                                        new RuntimeException()));
2380:                            }
2381:                        }
2382:                    });
2383:                }
2384:
2385:                Listener closeListener = new Listener() {
2386:                    public void handleEvent(Event event) {
2387:                        event.doit = close();
2388:                    }
2389:                };
2390:
2391:                // Initialize an exception handler.
2392:                Window.IExceptionHandler handler = ExceptionHandler
2393:                        .getInstance();
2394:
2395:                try {
2396:                    // react to display close event by closing workbench nicely
2397:                    display.addListener(SWT.Close, closeListener);
2398:
2399:                    // install backstop to catch exceptions thrown out of event loop
2400:                    Window.setExceptionHandler(handler);
2401:
2402:                    final boolean[] initOK = new boolean[1];
2403:
2404:                    if (getSplash() != null) {
2405:
2406:                        final boolean[] initDone = new boolean[] { false };
2407:                        Thread initThread = new Thread() {
2408:                            /* (non-Javadoc)
2409:                             * @see java.lang.Thread#run()
2410:                             */
2411:                            public void run() {
2412:                                try {
2413:                                    //declare us to be a startup thread so that our syncs will be executed 
2414:                                    UISynchronizer.startupThread
2415:                                            .set(Boolean.TRUE);
2416:                                    initOK[0] = Workbench.this .init();
2417:                                } finally {
2418:                                    initDone[0] = true;
2419:                                    display.wake();
2420:                                }
2421:                            }
2422:                        };
2423:                        initThread.start();
2424:                        while (true) {
2425:                            if (!display.readAndDispatch()) {
2426:                                if (initDone[0])
2427:                                    break;
2428:                                display.sleep();
2429:                            }
2430:
2431:                        }
2432:                    } else {
2433:                        // initialize workbench and restore or open one window
2434:                        initOK[0] = init();
2435:
2436:                    }
2437:                    // drop the splash screen now that a workbench window is up
2438:                    Platform.endSplash();
2439:
2440:                    // let the advisor run its start up code
2441:                    if (initOK[0]) {
2442:                        advisor.postStartup(); // may trigger a close/restart
2443:                    }
2444:
2445:                    if (initOK[0] && runEventLoop) {
2446:                        // start eager plug-ins
2447:                        startPlugins();
2448:                        addStartupRegistryListener();
2449:
2450:                        // WWinPluginAction.refreshActionList();
2451:
2452:                        display.asyncExec(new Runnable() {
2453:                            public void run() {
2454:                                UIStats.end(UIStats.START_WORKBENCH, this ,
2455:                                        "Workbench"); //$NON-NLS-1$
2456:                                UIStats.startupComplete();
2457:                            }
2458:                        });
2459:
2460:                        getWorkbenchTestable().init(display, this );
2461:
2462:                        // allow ModalContext to spin the event loop
2463:                        ModalContext.setAllowReadAndDispatch(true);
2464:                        isStarting = false;
2465:
2466:                        if (synchronizer != null)
2467:                            synchronizer.started();
2468:                        // the event loop
2469:                        runEventLoop(handler, display);
2470:                    }
2471:
2472:                } catch (final Exception e) {
2473:                    if (!display.isDisposed()) {
2474:                        handler.handleException(e);
2475:                    } else {
2476:                        String msg = "Exception in Workbench.runUI after display was disposed"; //$NON-NLS-1$
2477:                        WorkbenchPlugin.log(msg, new Status(IStatus.ERROR,
2478:                                WorkbenchPlugin.PI_WORKBENCH, 1, msg, e));
2479:                    }
2480:                } finally {
2481:                    // mandatory clean up
2482:
2483:                    // The runEventLoop flag may not have been cleared if an exception
2484:                    // occurred
2485:                    // Needs to be false to ensure PlatformUI.isWorkbenchRunning()
2486:                    // returns false.
2487:                    runEventLoop = false;
2488:
2489:                    if (!display.isDisposed()) {
2490:                        display.removeListener(SWT.Close, closeListener);
2491:                    }
2492:                }
2493:
2494:                // restart or exit based on returnCode
2495:                return returnCode;
2496:            }
2497:
2498:            /*
2499:             * Runs an event loop for the workbench.
2500:             */
2501:            private void runEventLoop(Window.IExceptionHandler handler,
2502:                    Display display) {
2503:                runEventLoop = true;
2504:                while (runEventLoop) {
2505:                    try {
2506:                        if (!display.readAndDispatch()) {
2507:                            getAdvisor().eventLoopIdle(display);
2508:                        }
2509:                    } catch (Throwable t) {
2510:                        handler.handleException(t);
2511:                    }
2512:                }
2513:            }
2514:
2515:            /*
2516:             * Saves the current state of the workbench so it can be restored later on
2517:             */
2518:            private IStatus saveState(IMemento memento) {
2519:                MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID,
2520:                        IStatus.OK, WorkbenchMessages.Workbench_problemsSaving,
2521:                        null);
2522:
2523:                // Save the version number.
2524:                memento.putString(IWorkbenchConstants.TAG_VERSION,
2525:                        VERSION_STRING[1]);
2526:
2527:                // Save how many plug-ins were loaded while restoring the workbench
2528:                if (progressCount != -1) {
2529:                    memento.putInteger(IWorkbenchConstants.TAG_PROGRESS_COUNT,
2530:                            progressCount);
2531:                }
2532:
2533:                // Save the advisor state.
2534:                IMemento advisorState = memento
2535:                        .createChild(IWorkbenchConstants.TAG_WORKBENCH_ADVISOR);
2536:                result.add(getAdvisor().saveState(advisorState));
2537:
2538:                // Save the workbench windows.
2539:                IWorkbenchWindow[] windows = getWorkbenchWindows();
2540:                for (int nX = 0; nX < windows.length; nX++) {
2541:                    WorkbenchWindow window = (WorkbenchWindow) windows[nX];
2542:                    IMemento childMem = memento
2543:                            .createChild(IWorkbenchConstants.TAG_WINDOW);
2544:                    result.merge(window.saveState(childMem));
2545:                }
2546:                result.add(getEditorHistory().saveState(
2547:                        memento.createChild(IWorkbenchConstants.TAG_MRU_LIST)));
2548:                return result;
2549:            }
2550:
2551:            /*
2552:             * Save the workbench UI in a persistence file.
2553:             */
2554:            private boolean saveMementoToFile(XMLMemento memento) {
2555:                // Save it to a file.
2556:                // XXX: nobody currently checks the return value of this method.
2557:                File stateFile = getWorkbenchStateFile();
2558:                if (stateFile == null) {
2559:                    return false;
2560:                }
2561:                try {
2562:                    FileOutputStream stream = new FileOutputStream(stateFile);
2563:                    OutputStreamWriter writer = new OutputStreamWriter(stream,
2564:                            "utf-8"); //$NON-NLS-1$
2565:                    memento.save(writer);
2566:                    writer.close();
2567:                } catch (IOException e) {
2568:                    stateFile.delete();
2569:                    MessageDialog.openError((Shell) null,
2570:                            WorkbenchMessages.SavingProblem,
2571:                            WorkbenchMessages.ProblemSavingState);
2572:                    return false;
2573:                }
2574:
2575:                // Success !
2576:                return true;
2577:            }
2578:
2579:            /*
2580:             * (non-Javadoc) Method declared on IWorkbench.
2581:             */
2582:            public IWorkbenchPage showPerspective(String perspectiveId,
2583:                    IWorkbenchWindow window) throws WorkbenchException {
2584:                Assert.isNotNull(perspectiveId);
2585:
2586:                // If the specified window has the requested perspective open, then the
2587:                // window
2588:                // is given focus and the perspective is shown. The page's input is
2589:                // ignored.
2590:                WorkbenchWindow win = (WorkbenchWindow) window;
2591:                if (win != null) {
2592:                    WorkbenchPage page = win.getActiveWorkbenchPage();
2593:                    if (page != null) {
2594:                        IPerspectiveDescriptor perspectives[] = page
2595:                                .getOpenPerspectives();
2596:                        for (int i = 0; i < perspectives.length; i++) {
2597:                            IPerspectiveDescriptor persp = perspectives[i];
2598:                            if (perspectiveId.equals(persp.getId())) {
2599:                                win.makeVisible();
2600:                                page.setPerspective(persp);
2601:                                return page;
2602:                            }
2603:                        }
2604:                    }
2605:                }
2606:
2607:                // If another window that has the workspace root as input and the
2608:                // requested
2609:                // perpective open and active, then the window is given focus.
2610:                IAdaptable input = getDefaultPageInput();
2611:                IWorkbenchWindow[] windows = getWorkbenchWindows();
2612:                for (int i = 0; i < windows.length; i++) {
2613:                    win = (WorkbenchWindow) windows[i];
2614:                    if (window != win) {
2615:                        WorkbenchPage page = win.getActiveWorkbenchPage();
2616:                        if (page != null) {
2617:                            boolean inputSame = false;
2618:                            if (input == null) {
2619:                                inputSame = (page.getInput() == null);
2620:                            } else {
2621:                                inputSame = input.equals(page.getInput());
2622:                            }
2623:                            if (inputSame) {
2624:                                Perspective persp = page.getActivePerspective();
2625:                                if (persp != null) {
2626:                                    IPerspectiveDescriptor desc = persp
2627:                                            .getDesc();
2628:                                    if (desc != null) {
2629:                                        if (perspectiveId.equals(desc.getId())) {
2630:                                            Shell shell = win.getShell();
2631:                                            shell.open();
2632:                                            if (shell.getMinimized()) {
2633:                                                shell.setMinimized(false);
2634:                                            }
2635:                                            return page;
2636:                                        }
2637:                                    }
2638:                                }
2639:                            }
2640:                        }
2641:                    }
2642:                }
2643:
2644:                // Otherwise the requested perspective is opened and shown in the
2645:                // specified
2646:                // window or in a new window depending on the current user preference
2647:                // for opening
2648:                // perspectives, and that window is given focus.
2649:                win = (WorkbenchWindow) window;
2650:                if (win != null) {
2651:                    IPreferenceStore store = WorkbenchPlugin.getDefault()
2652:                            .getPreferenceStore();
2653:                    int mode = store
2654:                            .getInt(IPreferenceConstants.OPEN_PERSP_MODE);
2655:                    IWorkbenchPage page = win.getActiveWorkbenchPage();
2656:                    IPerspectiveDescriptor persp = null;
2657:                    if (page != null) {
2658:                        persp = page.getPerspective();
2659:                    }
2660:
2661:                    // Only open a new window if user preference is set and the window
2662:                    // has an active perspective.
2663:                    if (IPreferenceConstants.OPM_NEW_WINDOW == mode
2664:                            && persp != null) {
2665:                        IWorkbenchWindow newWindow = openWorkbenchWindow(
2666:                                perspectiveId, input);
2667:                        return newWindow.getActivePage();
2668:                    }
2669:
2670:                    IPerspectiveDescriptor desc = getPerspectiveRegistry()
2671:                            .findPerspectiveWithId(perspectiveId);
2672:                    if (desc == null) {
2673:                        throw new WorkbenchException(
2674:                                NLS
2675:                                        .bind(
2676:                                                WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
2677:                                                perspectiveId));
2678:                    }
2679:                    win.getShell().open();
2680:                    if (page == null) {
2681:                        page = win.openPage(perspectiveId, input);
2682:                    } else {
2683:                        page.setPerspective(desc);
2684:                    }
2685:                    return page;
2686:                }
2687:
2688:                // Just throw an exception....
2689:                throw new WorkbenchException(NLS.bind(
2690:                        WorkbenchMessages.Workbench_showPerspectiveError,
2691:                        perspectiveId));
2692:            }
2693:
2694:            /*
2695:             * (non-Javadoc) Method declared on IWorkbench.
2696:             */
2697:            public IWorkbenchPage showPerspective(String perspectiveId,
2698:                    IWorkbenchWindow window, IAdaptable input)
2699:                    throws WorkbenchException {
2700:                Assert.isNotNull(perspectiveId);
2701:
2702:                // If the specified window has the requested perspective open and the
2703:                // same requested
2704:                // input, then the window is given focus and the perspective is shown.
2705:                boolean inputSameAsWindow = false;
2706:                WorkbenchWindow win = (WorkbenchWindow) window;
2707:                if (win != null) {
2708:                    WorkbenchPage page = win.getActiveWorkbenchPage();
2709:                    if (page != null) {
2710:                        boolean inputSame = false;
2711:                        if (input == null) {
2712:                            inputSame = (page.getInput() == null);
2713:                        } else {
2714:                            inputSame = input.equals(page.getInput());
2715:                        }
2716:                        if (inputSame) {
2717:                            inputSameAsWindow = true;
2718:                            IPerspectiveDescriptor perspectives[] = page
2719:                                    .getOpenPerspectives();
2720:                            for (int i = 0; i < perspectives.length; i++) {
2721:                                IPerspectiveDescriptor persp = perspectives[i];
2722:                                if (perspectiveId.equals(persp.getId())) {
2723:                                    win.makeVisible();
2724:                                    page.setPerspective(persp);
2725:                                    return page;
2726:                                }
2727:                            }
2728:                        }
2729:                    }
2730:                }
2731:
2732:                // If another window has the requested input and the requested
2733:                // perpective open and active, then that window is given focus.
2734:                IWorkbenchWindow[] windows = getWorkbenchWindows();
2735:                for (int i = 0; i < windows.length; i++) {
2736:                    win = (WorkbenchWindow) windows[i];
2737:                    if (window != win) {
2738:                        WorkbenchPage page = win.getActiveWorkbenchPage();
2739:                        if (page != null) {
2740:                            boolean inputSame = false;
2741:                            if (input == null) {
2742:                                inputSame = (page.getInput() == null);
2743:                            } else {
2744:                                inputSame = input.equals(page.getInput());
2745:                            }
2746:                            if (inputSame) {
2747:                                Perspective persp = page.getActivePerspective();
2748:                                if (persp != null) {
2749:                                    IPerspectiveDescriptor desc = persp
2750:                                            .getDesc();
2751:                                    if (desc != null) {
2752:                                        if (perspectiveId.equals(desc.getId())) {
2753:                                            win.getShell().open();
2754:                                            return page;
2755:                                        }
2756:                                    }
2757:                                }
2758:                            }
2759:                        }
2760:                    }
2761:                }
2762:
2763:                // If the specified window has the same requested input but not the
2764:                // requested
2765:                // perspective, then the window is given focus and the perspective is
2766:                // opened and shown
2767:                // on condition that the user preference is not to open perspectives in
2768:                // a new window.
2769:                win = (WorkbenchWindow) window;
2770:                if (inputSameAsWindow && win != null) {
2771:                    IPreferenceStore store = WorkbenchPlugin.getDefault()
2772:                            .getPreferenceStore();
2773:                    int mode = store
2774:                            .getInt(IPreferenceConstants.OPEN_PERSP_MODE);
2775:
2776:                    if (IPreferenceConstants.OPM_NEW_WINDOW != mode) {
2777:                        IWorkbenchPage page = win.getActiveWorkbenchPage();
2778:                        IPerspectiveDescriptor desc = getPerspectiveRegistry()
2779:                                .findPerspectiveWithId(perspectiveId);
2780:                        if (desc == null) {
2781:                            throw new WorkbenchException(
2782:                                    NLS
2783:                                            .bind(
2784:                                                    WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
2785:                                                    perspectiveId));
2786:                        }
2787:                        win.getShell().open();
2788:                        if (page == null) {
2789:                            page = win.openPage(perspectiveId, input);
2790:                        } else {
2791:                            page.setPerspective(desc);
2792:                        }
2793:                        return page;
2794:                    }
2795:                }
2796:
2797:                // If the specified window has no active perspective, then open the
2798:                // requested perspective and show the specified window.
2799:                if (win != null) {
2800:                    IWorkbenchPage page = win.getActiveWorkbenchPage();
2801:                    IPerspectiveDescriptor persp = null;
2802:                    if (page != null) {
2803:                        persp = page.getPerspective();
2804:                    }
2805:                    if (persp == null) {
2806:                        IPerspectiveDescriptor desc = getPerspectiveRegistry()
2807:                                .findPerspectiveWithId(perspectiveId);
2808:                        if (desc == null) {
2809:                            throw new WorkbenchException(
2810:                                    NLS
2811:                                            .bind(
2812:                                                    WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
2813:                                                    perspectiveId));
2814:                        }
2815:                        win.getShell().open();
2816:                        if (page == null) {
2817:                            page = win.openPage(perspectiveId, input);
2818:                        } else {
2819:                            page.setPerspective(desc);
2820:                        }
2821:                        return page;
2822:                    }
2823:                }
2824:
2825:                // Otherwise the requested perspective is opened and shown in a new
2826:                // window, and the
2827:                // window is given focus.
2828:                IWorkbenchWindow newWindow = openWorkbenchWindow(perspectiveId,
2829:                        input);
2830:                return newWindow.getActivePage();
2831:            }
2832:
2833:            /*
2834:             * Shuts down the application.
2835:             */
2836:            private void shutdown() {
2837:                // shutdown application-specific portions first
2838:                advisor.postShutdown();
2839:
2840:                // notify regular workbench clients of shutdown, and clear the list when
2841:                // done
2842:                firePostShutdown();
2843:                workbenchListeners.clear();
2844:
2845:                cancelEarlyStartup();
2846:
2847:                // for dynamic UI
2848:                Platform.getExtensionRegistry().removeRegistryChangeListener(
2849:                        extensionEventHandler);
2850:                Platform.getExtensionRegistry().removeRegistryChangeListener(
2851:                        startupRegistryListener);
2852:
2853:                ((GrabFocus) Tweaklets.get(GrabFocus.KEY)).dispose();
2854:
2855:                // Bring down all of the services.
2856:                serviceLocator.dispose();
2857:
2858:                workbenchActivitySupport.dispose();
2859:                WorkbenchHelpSystem.disposeIfNecessary();
2860:
2861:                // shutdown the rest of the workbench
2862:                WorkbenchColors.shutdown();
2863:                activityHelper.shutdown();
2864:                uninitializeImages();
2865:                if (WorkbenchPlugin.getDefault() != null) {
2866:                    WorkbenchPlugin.getDefault().reset();
2867:                }
2868:                WorkbenchThemeManager.getInstance().dispose();
2869:                PropertyPageContributorManager.getManager().dispose();
2870:                ObjectActionContributorManager.getManager().dispose();
2871:                if (tracker != null) {
2872:                    tracker.close();
2873:                }
2874:            }
2875:
2876:            /**
2877:             * Cancels the early startup job, if it's still running.
2878:             */
2879:            private void cancelEarlyStartup() {
2880:                Platform.getJobManager().cancel(EARLY_STARTUP_FAMILY);
2881:                // We do not currently wait for any plug-in currently being started to
2882:                // complete
2883:                // (e.g. by doing a join on EARLY_STARTUP_FAMILY), since they may do a
2884:                // syncExec,
2885:                // which would hang. See bug 94537 for rationale.
2886:            }
2887:
2888:            /*
2889:             * (non-Javadoc) Method declared on IWorkbench.
2890:             */
2891:            public IDecoratorManager getDecoratorManager() {
2892:                return WorkbenchPlugin.getDefault().getDecoratorManager();
2893:            }
2894:
2895:            /*
2896:             * Returns the workbench window which was last known being the active one,
2897:             * or <code> null </code> .
2898:             */
2899:            private WorkbenchWindow getActivatedWindow() {
2900:                if (activatedWindow != null) {
2901:                    Shell shell = activatedWindow.getShell();
2902:                    if (shell != null && !shell.isDisposed()) {
2903:                        return activatedWindow;
2904:                    }
2905:                }
2906:
2907:                return null;
2908:            }
2909:
2910:            /*
2911:             * Sets the workbench window which was last known being the active one, or
2912:             * <code> null </code> .
2913:             */
2914:            /* package */
2915:            void setActivatedWindow(WorkbenchWindow window) {
2916:                activatedWindow = window;
2917:            }
2918:
2919:            /**
2920:             * Returns the unique object that applications use to configure the
2921:             * workbench.
2922:             * <p>
2923:             * IMPORTANT This method is declared package-private to prevent regular
2924:             * plug-ins from downcasting IWorkbench to Workbench and getting hold of the
2925:             * workbench configurer that would allow them to tamper with the workbench.
2926:             * The workbench configurer is available only to the application.
2927:             * </p>
2928:             */
2929:            /* package */
2930:            WorkbenchConfigurer getWorkbenchConfigurer() {
2931:                if (workbenchConfigurer == null) {
2932:                    workbenchConfigurer = new WorkbenchConfigurer();
2933:                }
2934:                return workbenchConfigurer;
2935:            }
2936:
2937:            /**
2938:             * Returns the workbench advisor that created this workbench.
2939:             * <p>
2940:             * IMPORTANT This method is declared package-private to prevent regular
2941:             * plug-ins from downcasting IWorkbench to Workbench and getting hold of the
2942:             * workbench advisor that would allow them to tamper with the workbench. The
2943:             * workbench advisor is internal to the application.
2944:             * </p>
2945:             */
2946:            /* package */
2947:            WorkbenchAdvisor getAdvisor() {
2948:                return advisor;
2949:            }
2950:
2951:            /*
2952:             * (non-Javadoc) Method declared on IWorkbench.
2953:             */
2954:            public Display getDisplay() {
2955:                return display;
2956:            }
2957:
2958:            /**
2959:             * Returns the default perspective id, which may be <code>null</code>.
2960:             * 
2961:             * @return the default perspective id, or <code>null</code>
2962:             */
2963:            public String getDefaultPerspectiveId() {
2964:                return getAdvisor().getInitialWindowPerspectiveId();
2965:            }
2966:
2967:            /**
2968:             * Returns the default workbench window page input.
2969:             * 
2970:             * @return the default window page input or <code>null</code> if none
2971:             */
2972:            public IAdaptable getDefaultPageInput() {
2973:                return getAdvisor().getDefaultPageInput();
2974:            }
2975:
2976:            /**
2977:             * Returns the id of the preference page that should be presented most
2978:             * prominently.
2979:             * 
2980:             * @return the id of the preference page, or <code>null</code> if none
2981:             */
2982:            public String getMainPreferencePageId() {
2983:                String id = getAdvisor().getMainPreferencePageId();
2984:                return id;
2985:            }
2986:
2987:            /*
2988:             * (non-Javadoc)
2989:             * 
2990:             * @see org.eclipse.ui.IWorkbench
2991:             * @since 3.0
2992:             */
2993:            public IElementFactory getElementFactory(String factoryId) {
2994:                Assert.isNotNull(factoryId);
2995:                return WorkbenchPlugin.getDefault()
2996:                        .getElementFactory(factoryId);
2997:            }
2998:
2999:            /*
3000:             * (non-Javadoc)
3001:             * 
3002:             * @see org.eclipse.ui.IWorkbench#getProgressService()
3003:             */
3004:            public IProgressService getProgressService() {
3005:                return ProgressManager.getInstance();
3006:            }
3007:
3008:            private WorkbenchActivitySupport workbenchActivitySupport;
3009:
3010:            private WorkbenchCommandSupport workbenchCommandSupport;
3011:
3012:            private WorkbenchContextSupport workbenchContextSupport;
3013:
3014:            /**
3015:             * The single instance of the binding manager used by the workbench. This is
3016:             * initialized in <code>Workbench.init(Display)</code> and then never
3017:             * changed. This value will only be <code>null</code> if the
3018:             * initialization call has not yet completed.
3019:             * 
3020:             * @since 3.1
3021:             */
3022:            private BindingManager bindingManager;
3023:
3024:            /**
3025:             * The single instance of the command manager used by the workbench. This is
3026:             * initialized in <code>Workbench.init(Display)</code> and then never
3027:             * changed. This value will only be <code>null</code> if the
3028:             * initialization call has not yet completed.
3029:             * 
3030:             * @since 3.1
3031:             */
3032:            private CommandManager commandManager;
3033:
3034:            /**
3035:             * The single instance of the context manager used by the workbench. This is
3036:             * initialized in <code>Workbench.init(Display)</code> and then never
3037:             * changed. This value will only be <code>null</code> if the
3038:             * initialization call has not yet completed.
3039:             * 
3040:             * @since 3.1
3041:             */
3042:            private ContextManager contextManager;
3043:
3044:            public IWorkbenchActivitySupport getActivitySupport() {
3045:                return workbenchActivitySupport;
3046:            }
3047:
3048:            public IWorkbenchCommandSupport getCommandSupport() {
3049:                return workbenchCommandSupport;
3050:            }
3051:
3052:            public IWorkbenchContextSupport getContextSupport() {
3053:                return workbenchContextSupport;
3054:            }
3055:
3056:            private final IWindowListener windowListener = new IWindowListener() {
3057:
3058:                public void windowActivated(IWorkbenchWindow window) {
3059:                    updateActiveWorkbenchWindowMenuManager(true);
3060:                }
3061:
3062:                public void windowClosed(IWorkbenchWindow window) {
3063:                    updateActiveWorkbenchWindowMenuManager(true);
3064:                }
3065:
3066:                public void windowDeactivated(IWorkbenchWindow window) {
3067:                    updateActiveWorkbenchWindowMenuManager(true);
3068:                }
3069:
3070:                public void windowOpened(IWorkbenchWindow window) {
3071:                    updateActiveWorkbenchWindowMenuManager(true);
3072:                }
3073:            };
3074:
3075:            private final IBindingManagerListener bindingManagerListener = new IBindingManagerListener() {
3076:
3077:                public void bindingManagerChanged(
3078:                        BindingManagerEvent bindingManagerEvent) {
3079:                    if (bindingManagerEvent.isActiveBindingsChanged()) {
3080:                        updateActiveWorkbenchWindowMenuManager(true);
3081:                    }
3082:                }
3083:            };
3084:
3085:            /**
3086:             * The source provider that tracks the activation of action sets within the
3087:             * workbench. This source provider is <code>null</code> until
3088:             * {@link #initializeDefaultServices()} is called.
3089:             */
3090:            private ActionSetSourceProvider actionSetSourceProvider;
3091:
3092:            private WorkbenchWindow activeWorkbenchWindow = null;
3093:
3094:            private void updateActiveWorkbenchWindowMenuManager(boolean textOnly) {
3095:                if (activeWorkbenchWindow != null) {
3096:                    activeWorkbenchWindow
3097:                            .removeActionSetsListener(actionSetSourceProvider);
3098:                    activeWorkbenchWindow = null;
3099:                }
3100:                boolean actionSetsUpdated = false;
3101:
3102:                final IWorkbenchWindow workbenchWindow = getActiveWorkbenchWindow();
3103:
3104:                if (workbenchWindow instanceof  WorkbenchWindow) {
3105:                    activeWorkbenchWindow = (WorkbenchWindow) workbenchWindow;
3106:                    if (activeWorkbenchWindow.isClosing()) {
3107:                        return;
3108:                    }
3109:
3110:                    // Update the action sets.
3111:                    final Shell windowShell = activeWorkbenchWindow.getShell();
3112:                    final Shell activeShell = getDisplay().getActiveShell();
3113:                    final IContextService service = (IContextService) getService(IContextService.class);
3114:                    if (Util.equals(windowShell, activeShell)
3115:                            || service.getShellType(activeShell) == IContextService.TYPE_WINDOW) {
3116:                        activeWorkbenchWindow
3117:                                .addActionSetsListener(actionSetSourceProvider);
3118:                        final WorkbenchPage page = activeWorkbenchWindow
3119:                                .getActiveWorkbenchPage();
3120:                        final IActionSetDescriptor[] newActionSets;
3121:                        if (page != null) {
3122:                            newActionSets = page.getActionSets();
3123:                            final ActionSetsEvent event = new ActionSetsEvent(
3124:                                    newActionSets);
3125:                            actionSetSourceProvider.actionSetsChanged(event);
3126:                            actionSetsUpdated = true;
3127:                        }
3128:                    }
3129:
3130:                    final MenuManager menuManager = activeWorkbenchWindow
3131:                            .getMenuManager();
3132:
3133:                    if (textOnly) {
3134:                        menuManager.update(IAction.TEXT);
3135:                    } else {
3136:                        menuManager.update(true);
3137:                    }
3138:                }
3139:
3140:                if (!actionSetsUpdated) {
3141:                    final ActionSetsEvent event = new ActionSetsEvent(null);
3142:                    actionSetSourceProvider.actionSetsChanged(event);
3143:                }
3144:            }
3145:
3146:            private ActivityPersistanceHelper activityHelper;
3147:
3148:            /*
3149:             * (non-Javadoc)
3150:             * 
3151:             * @see org.eclipse.ui.IWorkbench#getIntroManager()
3152:             */
3153:            public IIntroManager getIntroManager() {
3154:                return getWorkbenchIntroManager();
3155:            }
3156:
3157:            /**
3158:             * @return the workbench intro manager
3159:             * @since 3.0
3160:             */
3161:            /* package */WorkbenchIntroManager getWorkbenchIntroManager() {
3162:                if (introManager == null) {
3163:                    introManager = new WorkbenchIntroManager(this );
3164:                }
3165:                return introManager;
3166:            }
3167:
3168:            private WorkbenchIntroManager introManager;
3169:
3170:            /**
3171:             * @return the intro extension for this workbench.
3172:             * 
3173:             * @since 3.0
3174:             */
3175:            public IntroDescriptor getIntroDescriptor() {
3176:                return introDescriptor;
3177:            }
3178:
3179:            /**
3180:             * This method exists as a test hook. This method should <strong>NEVER</strong>
3181:             * be called by clients.
3182:             * 
3183:             * @param descriptor
3184:             *            The intro descriptor to use.
3185:             * @since 3.0
3186:             */
3187:            public void setIntroDescriptor(IntroDescriptor descriptor) {
3188:                if (getIntroManager().getIntro() != null) {
3189:                    getIntroManager().closeIntro(getIntroManager().getIntro());
3190:                }
3191:                introDescriptor = descriptor;
3192:            }
3193:
3194:            /**
3195:             * The descriptor for the intro extension that is valid for this workspace,
3196:             * <code>null</code> if none.
3197:             */
3198:            private IntroDescriptor introDescriptor;
3199:
3200:            private IExtensionTracker tracker;
3201:
3202:            private IRegistryChangeListener startupRegistryListener = new IRegistryChangeListener() {
3203:
3204:                /*
3205:                 * (non-Javadoc)
3206:                 * 
3207:                 * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent)
3208:                 */
3209:                public void registryChanged(IRegistryChangeEvent event) {
3210:                    final IExtensionDelta[] deltas = event.getExtensionDeltas(
3211:                            PlatformUI.PLUGIN_ID,
3212:                            IWorkbenchRegistryConstants.PL_STARTUP);
3213:                    if (deltas.length == 0) {
3214:                        return;
3215:                    }
3216:                    final String disabledPlugins = PrefUtil
3217:                            .getInternalPreferenceStore()
3218:                            .getString(
3219:                                    IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
3220:
3221:                    for (int i = 0; i < deltas.length; i++) {
3222:                        IExtension extension = deltas[i].getExtension();
3223:                        if (deltas[i].getKind() == IExtensionDelta.REMOVED) {
3224:                            continue;
3225:                        }
3226:
3227:                        // if the plugin is not in the set of disabled plugins,
3228:                        // then
3229:                        // execute the code to start it
3230:                        if (disabledPlugins.indexOf(extension.getNamespace()) == -1) {
3231:                            SafeRunner.run(new EarlyStartupRunnable(extension));
3232:                        }
3233:                    }
3234:
3235:                }
3236:            };
3237:
3238:            private String factoryID;
3239:
3240:            /*
3241:             * (non-Javadoc)
3242:             * 
3243:             * @see org.eclipse.ui.IWorkbench#getThemeManager()
3244:             */
3245:            public IThemeManager getThemeManager() {
3246:                return WorkbenchThemeManager.getInstance();
3247:            }
3248:
3249:            /**
3250:             * Returns <code>true</code> if the workbench is running,
3251:             * <code>false</code> if it has been terminated.
3252:             * 
3253:             * @return <code>true</code> if the workbench is running,
3254:             *         <code>false</code> if it has been terminated.
3255:             */
3256:            public boolean isRunning() {
3257:                return runEventLoop;
3258:            }
3259:
3260:            /**
3261:             * Return the presentation ID specified by the preference or the default ID
3262:             * if undefined.
3263:             * 
3264:             * @return the presentation ID
3265:             * @see IWorkbenchPreferenceConstants#PRESENTATION_FACTORY_ID
3266:             */
3267:            public String getPresentationId() {
3268:                if (factoryID != null) {
3269:                    return factoryID;
3270:                }
3271:
3272:                factoryID = PrefUtil.getAPIPreferenceStore().getString(
3273:                        IWorkbenchPreferenceConstants.PRESENTATION_FACTORY_ID);
3274:
3275:                // Workaround for bug 58975 - New preference mechanism does not properly
3276:                // initialize defaults
3277:                // Ensure that the UI plugin has started too.
3278:                if (factoryID == null || factoryID.equals("")) { //$NON-NLS-1$
3279:                    factoryID = IWorkbenchConstants.DEFAULT_PRESENTATION_ID;
3280:                }
3281:                return factoryID;
3282:            }
3283:
3284:            /**
3285:             * <p>
3286:             * Indicates the start of a large update within the workbench. This is used
3287:             * to disable CPU-intensive, change-sensitive services that were temporarily
3288:             * disabled in the midst of large changes. This method should always be
3289:             * called in tandem with <code>largeUpdateEnd</code>, and the event loop
3290:             * should not be allowed to spin before that method is called.
3291:             * </p>
3292:             * <p>
3293:             * Important: always use with <code>largeUpdateEnd</code>!
3294:             * </p>
3295:             */
3296:            public final void largeUpdateStart() {
3297:                if (largeUpdates++ == 0) {
3298:                    // TODO Consider whether these lines still need to be here.
3299:                    // workbenchCommandSupport.setProcessing(false);
3300:                    // workbenchContextSupport.setProcessing(false);
3301:
3302:                    final IWorkbenchWindow[] windows = getWorkbenchWindows();
3303:                    for (int i = 0; i < windows.length; i++) {
3304:                        IWorkbenchWindow window = windows[i];
3305:                        if (window instanceof  WorkbenchWindow) {
3306:                            ((WorkbenchWindow) window).largeUpdateStart();
3307:                        }
3308:                    }
3309:                }
3310:            }
3311:
3312:            /**
3313:             * <p>
3314:             * Indicates the end of a large update within the workbench. This is used to
3315:             * re-enable services that were temporarily disabled in the midst of large
3316:             * changes. This method should always be called in tandem with
3317:             * <code>largeUpdateStart</code>, and the event loop should not be
3318:             * allowed to spin before this method is called.
3319:             * </p>
3320:             * <p>
3321:             * Important: always protect this call by using <code>finally</code>!
3322:             * </p>
3323:             */
3324:            public final void largeUpdateEnd() {
3325:                if (--largeUpdates == 0) {
3326:                    // TODO Consider whether these lines still need to be here.
3327:                    // workbenchCommandSupport.setProcessing(true);
3328:                    // workbenchContextSupport.setProcessing(true);
3329:
3330:                    // Perform window-specific blocking.
3331:                    final IWorkbenchWindow[] windows = getWorkbenchWindows();
3332:                    for (int i = 0; i < windows.length; i++) {
3333:                        IWorkbenchWindow window = windows[i];
3334:                        if (window instanceof  WorkbenchWindow) {
3335:                            ((WorkbenchWindow) window).largeUpdateEnd();
3336:                        }
3337:                    }
3338:                }
3339:            }
3340:
3341:            /*
3342:             * (non-Javadoc)
3343:             * 
3344:             * @see org.eclipse.ui.IWorkbench#getExtensionTracker()
3345:             */
3346:            public IExtensionTracker getExtensionTracker() {
3347:                if (tracker == null) {
3348:                    tracker = new UIExtensionTracker(getDisplay());
3349:                }
3350:                return tracker;
3351:            }
3352:
3353:            /**
3354:             * Adds the listener that handles startup plugins
3355:             * 
3356:             * @since 3.1
3357:             */
3358:            private void addStartupRegistryListener() {
3359:                IExtensionRegistry registry = Platform.getExtensionRegistry();
3360:                registry.addRegistryChangeListener(startupRegistryListener);
3361:            }
3362:
3363:            /*
3364:             * (non-Javadoc)
3365:             * 
3366:             * @see org.eclipse.ui.IWorkbench#getHelpSystem()
3367:             */
3368:            public IWorkbenchHelpSystem getHelpSystem() {
3369:                return WorkbenchHelpSystem.getInstance();
3370:            }
3371:
3372:            /*
3373:             * (non-Javadoc)
3374:             * 
3375:             * @see org.eclipse.ui.IWorkbench#getHelpSystem()
3376:             */
3377:            public IWorkbenchBrowserSupport getBrowserSupport() {
3378:                return WorkbenchBrowserSupport.getInstance();
3379:            }
3380:
3381:            /*
3382:             * (non-Javadoc)
3383:             * 
3384:             * @see org.eclipse.ui.IWorkbench#getViewRegistry()
3385:             */
3386:            public IViewRegistry getViewRegistry() {
3387:                return WorkbenchPlugin.getDefault().getViewRegistry();
3388:            }
3389:
3390:            /*
3391:             * (non-Javadoc)
3392:             * 
3393:             * @see org.eclipse.ui.IWorkbench#getNewWizardRegistry()
3394:             */
3395:            public IWizardRegistry getNewWizardRegistry() {
3396:                return WorkbenchPlugin.getDefault().getNewWizardRegistry();
3397:            }
3398:
3399:            /*
3400:             * (non-Javadoc)
3401:             * 
3402:             * @see org.eclipse.ui.IWorkbench#getImportWizardRegistry()
3403:             */
3404:            public IWizardRegistry getImportWizardRegistry() {
3405:                return WorkbenchPlugin.getDefault().getImportWizardRegistry();
3406:            }
3407:
3408:            /*
3409:             * (non-Javadoc)
3410:             * 
3411:             * @see org.eclipse.ui.IWorkbench#getExportWizardRegistry()
3412:             */
3413:            public IWizardRegistry getExportWizardRegistry() {
3414:                return WorkbenchPlugin.getDefault().getExportWizardRegistry();
3415:            }
3416:
3417:            public final Object getAdapter(final Class key) {
3418:                return serviceLocator.getService(key);
3419:            }
3420:
3421:            private void doRestoreState(final IMemento memento,
3422:                    final MultiStatus status) {
3423:                IMemento childMem;
3424:                try {
3425:                    UIStats.start(UIStats.RESTORE_WORKBENCH, "MRUList"); //$NON-NLS-1$
3426:                    IMemento mruMemento = memento
3427:                            .getChild(IWorkbenchConstants.TAG_MRU_LIST);
3428:                    if (mruMemento != null) {
3429:                        status.add(getEditorHistory().restoreState(mruMemento));
3430:                    }
3431:                } finally {
3432:                    UIStats.end(UIStats.RESTORE_WORKBENCH, this , "MRUList"); //$NON-NLS-1$
3433:                }
3434:
3435:                // Restore advisor state.
3436:                IMemento advisorState = memento
3437:                        .getChild(IWorkbenchConstants.TAG_WORKBENCH_ADVISOR);
3438:                if (advisorState != null) {
3439:                    status.add(getAdvisor().restoreState(advisorState));
3440:                }
3441:
3442:                // Get the child windows.
3443:                IMemento[] children = memento
3444:                        .getChildren(IWorkbenchConstants.TAG_WINDOW);
3445:
3446:                createdWindows = new WorkbenchWindow[children.length];
3447:
3448:                // Read the workbench windows.
3449:                for (int i = 0; i < children.length; i++) {
3450:                    childMem = children[i];
3451:                    final WorkbenchWindow[] newWindow = new WorkbenchWindow[1];
3452:
3453:                    StartupThreading
3454:                            .runWithoutExceptions(new StartupRunnable() {
3455:
3456:                                public void runWithException() {
3457:                                    newWindow[0] = newWorkbenchWindow();
3458:                                    newWindow[0].create();
3459:                                }
3460:                            });
3461:                    createdWindows[i] = newWindow[0];
3462:
3463:                    // allow the application to specify an initial perspective to open
3464:                    // @issue temporary workaround for ignoring initial perspective
3465:                    // String initialPerspectiveId =
3466:                    // getAdvisor().getInitialWindowPerspectiveId();
3467:                    // if (initialPerspectiveId != null) {
3468:                    // IPerspectiveDescriptor desc =
3469:                    // getPerspectiveRegistry().findPerspectiveWithId(initialPerspectiveId);
3470:                    // result.merge(newWindow.restoreState(childMem, desc));
3471:                    // }
3472:                    // add the window so that any work done in newWindow.restoreState
3473:                    // that relies on Workbench methods has windows to work with
3474:                    windowManager.add(newWindow[0]);
3475:
3476:                    // now that we've added it to the window manager we need to listen
3477:                    // for any exception that might hose us before we get a chance to
3478:                    // open it. If one occurs, remove the new window from the manager.
3479:                    // Assume that the new window is a phantom for now
3480:                    boolean restored = false;
3481:                    try {
3482:                        status.merge(newWindow[0].restoreState(childMem, null));
3483:                        try {
3484:                            newWindow[0].fireWindowRestored();
3485:                        } catch (WorkbenchException e) {
3486:                            status.add(e.getStatus());
3487:                        }
3488:                        // everything worked so far, don't close now
3489:                        restored = true;
3490:                    } finally {
3491:                        if (!restored) {
3492:                            // null the window in newWindowHolder so that it won't be
3493:                            // opened later on
3494:                            createdWindows[i] = null;
3495:                            StartupThreading
3496:                                    .runWithoutExceptions(new StartupRunnable() {
3497:
3498:                                        public void runWithException()
3499:                                                throws Throwable {
3500:                                            newWindow[0].close();
3501:                                        }
3502:                                    });
3503:                        }
3504:                    }
3505:                }
3506:            }
3507:
3508:            private void openWindowsAfterRestore() {
3509:                if (createdWindows == null) {
3510:                    return;
3511:                }
3512:                // now open the windows (except the ones that were nulled because we
3513:                // closed them above)
3514:                for (int i = 0; i < createdWindows.length; i++) {
3515:                    if (createdWindows[i] != null) {
3516:                        final WorkbenchWindow myWindow = createdWindows[i];
3517:                        StartupThreading
3518:                                .runWithoutExceptions(new StartupRunnable() {
3519:
3520:                                    public void runWithException()
3521:                                            throws Throwable {
3522:                                        boolean opened = false;
3523:                                        try {
3524:                                            myWindow.open();
3525:                                            opened = true;
3526:                                        } finally {
3527:                                            if (!opened) {
3528:                                                myWindow.close();
3529:                                            }
3530:                                        }
3531:                                    }
3532:                                });
3533:                    }
3534:                }
3535:                createdWindows = null;
3536:            }
3537:
3538:            /*
3539:             * (non-Javadoc)
3540:             * 
3541:             * @see org.eclipse.ui.services.IServiceLocator#getService(java.lang.Object)
3542:             */
3543:            public final Object getService(final Class key) {
3544:                return serviceLocator.getService(key);
3545:            }
3546:
3547:            /*
3548:             * (non-Javadoc)
3549:             * 
3550:             * @see org.eclipse.ui.services.IServiceLocator#hasService(java.lang.Object)
3551:             */
3552:            public final boolean hasService(final Class key) {
3553:                return serviceLocator.hasService(key);
3554:            }
3555:
3556:            /**
3557:             * Registers a service with this locator. If there is an existing service
3558:             * matching the same <code>api</code> and it implements
3559:             * {@link IDisposable}, it will be disposed.
3560:             * 
3561:             * @param api
3562:             *            This is the interface that the service implements. Must not be
3563:             *            <code>null</code>.
3564:             * @param service
3565:             *            The service to register. This must be some implementation of
3566:             *            <code>api</code>. This value must not be <code>null</code>.
3567:             */
3568:            public final void registerService(final Class api,
3569:                    final Object service) {
3570:                serviceLocator.registerService(api, service);
3571:            }
3572:
3573:            /**
3574:             * The source provider that tracks which context menus (i.e., menus with
3575:             * target identifiers) are now showing. This value is <code>null</code>
3576:             * until {@link #initializeDefaultServices()} is called.
3577:             */
3578:            private MenuSourceProvider menuSourceProvider;
3579:
3580:            /**
3581:             * Adds the ids of a menu that is now showing to the menu source provider.
3582:             * This is used for legacy action-based handlers which need to become active
3583:             * only for the duration of a menu being visible.
3584:             * 
3585:             * @param menuIds
3586:             *            The identifiers of the menu that is now showing; must not be
3587:             *            <code>null</code>.
3588:             */
3589:            public final void addShowingMenus(final Set menuIds,
3590:                    final ISelection localSelection,
3591:                    final ISelection localEditorInput) {
3592:                menuSourceProvider.addShowingMenus(menuIds, localSelection,
3593:                        localEditorInput);
3594:            }
3595:
3596:            /**
3597:             * Removes the ids of a menu that is now hidden from the menu source
3598:             * provider. This is used for legacy action-based handlers which need to
3599:             * become active only for the duration of a menu being visible.
3600:             * 
3601:             * @param menuIds
3602:             *            The identifiers of the menu that is now hidden; must not be
3603:             *            <code>null</code>.
3604:             */
3605:            public final void removeShowingMenus(final Set menuIds,
3606:                    final ISelection localSelection,
3607:                    final ISelection localEditorInput) {
3608:                menuSourceProvider.removeShowingMenus(menuIds, localSelection,
3609:                        localEditorInput);
3610:            }
3611:
3612:            /* (non-Javadoc)
3613:             * @see org.eclipse.ui.IWorkbench#saveAll(org.eclipse.jface.window.IShellProvider, org.eclipse.jface.operation.IRunnableContext, org.eclipse.ui.ISaveableFilter, boolean)
3614:             */
3615:            public boolean saveAll(IShellProvider shellProvider,
3616:                    IRunnableContext runnableContext, ISaveableFilter filter,
3617:                    boolean confirm) {
3618:                SaveablesList saveablesList = (SaveablesList) PlatformUI
3619:                        .getWorkbench().getService(
3620:                                ISaveablesLifecycleListener.class);
3621:                Saveable[] saveables = saveablesList.getOpenModels();
3622:                List toSave = getFilteredSaveables(filter, saveables);
3623:                if (toSave.isEmpty())
3624:                    return true;
3625:
3626:                if (!confirm) {
3627:                    return !saveablesList.saveModels(toSave, shellProvider,
3628:                            runnableContext);
3629:                }
3630:
3631:                // We must negate the result since false is cancel saveAll
3632:                return !saveablesList.promptForSaving(toSave, shellProvider,
3633:                        runnableContext, true, false);
3634:            }
3635:
3636:            /*
3637:             * Apply the given filter to the list of saveables
3638:             */
3639:            private List getFilteredSaveables(ISaveableFilter filter,
3640:                    Saveable[] saveables) {
3641:                List toSave = new ArrayList();
3642:                if (filter == null) {
3643:                    for (int i = 0; i < saveables.length; i++) {
3644:                        Saveable saveable = saveables[i];
3645:                        if (saveable.isDirty())
3646:                            toSave.add(saveable);
3647:                    }
3648:                } else {
3649:                    SaveablesList saveablesList = (SaveablesList) getService(ISaveablesLifecycleListener.class);
3650:                    for (int i = 0; i < saveables.length; i++) {
3651:                        Saveable saveable = saveables[i];
3652:                        if (saveable.isDirty()) {
3653:                            IWorkbenchPart[] parts = saveablesList
3654:                                    .getPartsForSaveable(saveable);
3655:                            if (matchesFilter(filter, saveable, parts))
3656:                                toSave.add(saveable);
3657:                        }
3658:                    }
3659:                }
3660:                return toSave;
3661:            }
3662:
3663:            /*
3664:             * Test whether the given filter matches the saveable
3665:             */
3666:            private boolean matchesFilter(ISaveableFilter filter,
3667:                    Saveable saveable, IWorkbenchPart[] parts) {
3668:                return filter == null || filter.select(saveable, parts);
3669:            }
3670:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.