blob: bbe0604aef140a6d2c47201d2ce9d1f7cd032635 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.io.OutputStream;
import java.util.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
import org.eclipse.ui.internal.decorators.DecoratorManager;
import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceManager;
import org.eclipse.ui.internal.intro.IIntroRegistry;
import org.eclipse.ui.internal.intro.IntroRegistry;
import org.eclipse.ui.internal.misc.StatusUtil;
import org.eclipse.ui.internal.operations.WorkbenchOperationSupport;
import org.eclipse.ui.internal.progress.ProgressManager;
import org.eclipse.ui.internal.registry.ActionSetRegistry;
import org.eclipse.ui.internal.registry.EditorRegistry;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.registry.PerspectiveRegistry;
import org.eclipse.ui.internal.registry.PreferencePageRegistryReader;
import org.eclipse.ui.internal.registry.ViewRegistry;
import org.eclipse.ui.internal.registry.WorkingSetRegistry;
import org.eclipse.ui.internal.themes.IThemeRegistry;
import org.eclipse.ui.internal.themes.ThemeRegistry;
import org.eclipse.ui.internal.themes.ThemeRegistryReader;
import org.eclipse.ui.internal.util.BundleUtility;
import org.eclipse.ui.internal.util.SWTResourceUtil;
import org.eclipse.ui.internal.wizards.ExportWizardRegistry;
import org.eclipse.ui.internal.wizards.ImportWizardRegistry;
import org.eclipse.ui.internal.wizards.NewWizardRegistry;
import org.eclipse.ui.operations.IWorkbenchOperationSupport;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.presentations.AbstractPresentationFactory;
import org.eclipse.ui.views.IViewRegistry;
import org.eclipse.ui.wizards.IWizardRegistry;
import org.osgi.framework.*;
import com.ibm.icu.text.MessageFormat;
/**
* This class represents the TOP of the workbench UI world
* A plugin class is effectively an application wrapper
* for a plugin & its classes. This class should be thought
* of as the workbench UI's application class.
*
* This class is responsible for tracking various registries
* font, preference, graphics, dialog store.
*
* This class is explicitly referenced by the
* workbench plugin's "plugin.xml" and places it
* into the UI start extension point of the main
* overall application harness
*
* When is this class started?
* When the Application
* calls createExecutableExtension to create an executable
* instance of our workbench class.
*/
public class WorkbenchPlugin extends AbstractUIPlugin {
private static final String LEFT_TO_RIGHT = "ltr"; //$NON-NLS-1$
private static final String RIGHT_TO_LEFT = "rtl";//$NON-NLS-1$
private static final String ORIENTATION_COMMAND_LINE = "-dir";//$NON-NLS-1$
private static final String ORIENTATION_PROPERTY = "eclipse.orientation";//$NON-NLS-1$
private static final String NL_USER_PROPERTY = "osgi.nl.user"; //$NON-NLS-1$
private static final String UI_BUNDLE_ACTIVATOR = "org.eclipse.ui.internal.UIPlugin"; //$NON-NLS-1$
// Default instance of the receiver
private static WorkbenchPlugin inst;
// Manager that maps resources to descriptors of editors to use
private EditorRegistry editorRegistry;
// Manager for the DecoratorManager
private DecoratorManager decoratorManager;
// Theme registry
private ThemeRegistry themeRegistry;
// Manager for working sets (IWorkingSet)
private WorkingSetManager workingSetManager;
// Working set registry, stores working set dialogs
private WorkingSetRegistry workingSetRegistry;
// The context within which this plugin was started.
private BundleContext bundleContext;
// The set of currently starting bundles
private Collection startingBundles = new HashSet();
/**
* Global workbench ui plugin flag. Only workbench implementation is allowed to use this flag
* All other plugins, examples, or test cases must *not* use this flag.
*/
public static boolean DEBUG = false;
/**
* The workbench plugin ID.
*
* @issue we should just drop this constant and use PlatformUI.PLUGIN_ID instead
*/
public static String PI_WORKBENCH = PlatformUI.PLUGIN_ID;
/**
* The character used to separate preference page category ids
*/
public static char PREFERENCE_PAGE_CATEGORY_SEPARATOR = '/';
// Other data.
private WorkbenchPreferenceManager preferenceManager;
private ViewRegistry viewRegistry;
private PerspectiveRegistry perspRegistry;
private ActionSetRegistry actionSetRegistry;
private SharedImages sharedImages;
/**
* Information describing the product (formerly called "primary plugin"); lazily
* initialized.
* @since 3.0
*/
private ProductInfo productInfo = null;
private IntroRegistry introRegistry;
private WorkbenchOperationSupport operationSupport;
private BundleListener bundleListener;
/**
* Create an instance of the WorkbenchPlugin. The workbench plugin is
* effectively the "application" for the workbench UI. The entire UI
* operates as a good plugin citizen.
*/
public WorkbenchPlugin() {
super();
inst = this;
}
/**
* Unload all members. This can be used to run a second instance of a workbench.
* @since 3.0
*/
void reset() {
editorRegistry = null;
if (decoratorManager != null) {
decoratorManager.dispose();
decoratorManager = null;
}
ProgressManager.shutdownProgressManager();
themeRegistry = null;
if (workingSetManager != null) {
workingSetManager.dispose();
workingSetManager = null;
}
workingSetRegistry = null;
preferenceManager = null;
if (viewRegistry != null) {
viewRegistry.dispose();
viewRegistry = null;
}
if (perspRegistry != null) {
perspRegistry.dispose();
perspRegistry = null;
}
actionSetRegistry = null;
sharedImages = null;
productInfo = null;
introRegistry = null;
if (operationSupport != null) {
operationSupport.dispose();
operationSupport = null;
}
DEBUG = false;
}
/**
* Creates an extension. If the extension plugin has not
* been loaded a busy cursor will be activated during the duration of
* the load.
*
* @param element the config element defining the extension
* @param classAttribute the name of the attribute carrying the class
* @return the extension object
* @throws CoreException if the extension cannot be created
*/
public static Object createExtension(final IConfigurationElement element,
final String classAttribute) throws CoreException {
try {
// If plugin has been loaded create extension.
// Otherwise, show busy cursor then create extension.
if (BundleUtility.isActivated(element.getDeclaringExtension()
.getNamespace())) {
return element.createExecutableExtension(classAttribute);
}
final Object[] ret = new Object[1];
final CoreException[] exc = new CoreException[1];
BusyIndicator.showWhile(null, new Runnable() {
public void run() {
try {
ret[0] = element
.createExecutableExtension(classAttribute);
} catch (CoreException e) {
exc[0] = e;
}
}
});
if (exc[0] != null) {
throw exc[0];
}
return ret[0];
} catch (CoreException core) {
throw core;
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, PI_WORKBENCH,
IStatus.ERROR, WorkbenchMessages.WorkbenchPlugin_extension,e));
}
}
/**
* Answers whether the provided element either has an attribute with the
* given name or a child element with the given name with an attribute
* called class.
*
* @param element
* the element to test
* @param extensionName
* the name of the extension to test for
* @return whether or not the extension is declared
* @since 3.3
*/
public static boolean hasExecutableExtension(IConfigurationElement element,
String extensionName) {
if (element.getAttribute(extensionName) != null)
return true;
String elementText = element.getValue();
if (elementText != null && !elementText.equals("")) //$NON-NLS-1$
return true;
IConfigurationElement [] children = element.getChildren(extensionName);
if (children.length == 1) {
if (children[0].getAttribute(IWorkbenchRegistryConstants.ATT_CLASS) != null)
return true;
}
return false;
}
/**
* Checks to see if the provided element has the syntax for an executable
* extension with a given name that resides in a bundle that is already
* active. Determining the bundle happens in one of two ways:<br/>
* <ul>
* <li>The element has an attribute with the specified name or element text
* in the form <code>bundle.id/class.name[:optional attributes]</code></li>
* <li>The element has a child element with the specified name that has a
* <code>plugin</code> attribute</li>
* </ul>
*
* @param element
* the element to test
* @param extensionName
* the name of the extension to test for
* @return whether or not the bundle expressed by the above criteria is
* active. If the bundle cannot be determined then the state of the
* bundle that declared the element is returned.
* @since 3.3
*/
public static boolean isBundleLoadedForExecutableExtension(
IConfigurationElement element, String extensionName) {
Bundle bundle = getBundleForExecutableExtension(element, extensionName);
if (bundle == null)
return true;
return bundle.getState() == Bundle.ACTIVE;
}
/**
* Returns the bundle that contains the class referenced by an executable
* extension. Determining the bundle happens in one of two ways:<br/>
* <ul>
* <li>The element has an attribute with the specified name or element text
* in the form <code>bundle.id/class.name[:optional attributes]</code></li>
* <li>The element has a child element with the specified name that has a
* <code>plugin</code> attribute</li>
* </ul>
*
* @param element
* the element to test
* @param extensionName
* the name of the extension to test for
* @return the bundle referenced by the extension. If that bundle cannot be
* determined the bundle that declared the element is returned. Note
* that this may be <code>null</code>.
* @since 3.3
*/
public static Bundle getBundleForExecutableExtension(IConfigurationElement element, String extensionName) {
// this code is derived heavily from
// ConfigurationElement.createExecutableExtension.
String prop = null;
String executable;
String contributorName = null;
int i;
if (extensionName != null)
prop = element.getAttribute(extensionName);
else {
// property not specified, try as element value
prop = element.getValue();
if (prop != null) {
prop = prop.trim();
if (prop.equals("")) //$NON-NLS-1$
prop = null;
}
}
if (prop == null) {
// property not defined, try as a child element
IConfigurationElement[] exec = element.getChildren(extensionName);
if (exec.length != 0)
contributorName = exec[0].getAttribute("plugin"); //$NON-NLS-1$
} else {
// simple property or element value, parse it into its components
i = prop.indexOf(':');
if (i != -1)
executable = prop.substring(0, i).trim();
else
executable = prop;
i = executable.indexOf('/');
if (i != -1)
contributorName = executable.substring(0, i).trim();
}
if (contributorName == null)
contributorName = element.getContributor().getName();
return Platform.getBundle(contributorName);
}
/**
* Returns the image registry for this plugin.
*
* Where are the images? The images (typically gifs) are found in the same
* plugins directory.
*
* @see ImageRegistry
*
* Note: The workbench uses the standard JFace ImageRegistry to track its
* images. In addition the class WorkbenchGraphicResources provides
* convenience access to the graphics resources and fast field access for
* some of the commonly used graphical images.
*/
protected ImageRegistry createImageRegistry() {
return WorkbenchImages.getImageRegistry();
}
/**
* Returns the action set registry for the workbench.
*
* @return the workbench action set registry
*/
public ActionSetRegistry getActionSetRegistry() {
if (actionSetRegistry == null) {
actionSetRegistry = new ActionSetRegistry();
}
return actionSetRegistry;
}
/**
* Return the default instance of the receiver. This represents the runtime plugin.
* @return WorkbenchPlugin
* @see AbstractUIPlugin for the typical implementation pattern for plugin classes.
*/
public static WorkbenchPlugin getDefault() {
return inst;
}
/**
* Answer the manager that maps resource types to a the
* description of the editor to use
* @return IEditorRegistry the editor registry used
* by this plug-in.
*/
public IEditorRegistry getEditorRegistry() {
if (editorRegistry == null) {
editorRegistry = new EditorRegistry();
}
return editorRegistry;
}
/**
* Answer the element factory for an id, or <code>null</code. if not found.
* @param targetID
* @return IElementFactory
*/
public IElementFactory getElementFactory(String targetID) {
// Get the extension point registry.
IExtensionPoint extensionPoint;
extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(
PI_WORKBENCH, IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY);
if (extensionPoint == null) {
WorkbenchPlugin
.log("Unable to find element factory. Extension point: " + IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY + " not found"); //$NON-NLS-2$ //$NON-NLS-1$
return null;
}
// Loop through the config elements.
IConfigurationElement targetElement = null;
IConfigurationElement[] configElements = extensionPoint
.getConfigurationElements();
for (int j = 0; j < configElements.length; j++) {
String strID = configElements[j].getAttribute("id"); //$NON-NLS-1$
if (targetID.equals(strID)) {
targetElement = configElements[j];
break;
}
}
if (targetElement == null) {
// log it since we cannot safely display a dialog.
WorkbenchPlugin.log("Unable to find element factory: " + targetID); //$NON-NLS-1$
return null;
}
// Create the extension.
IElementFactory factory = null;
try {
factory = (IElementFactory) createExtension(targetElement, "class"); //$NON-NLS-1$
} catch (CoreException e) {
// log it since we cannot safely display a dialog.
WorkbenchPlugin.log(
"Unable to create element factory.", e.getStatus()); //$NON-NLS-1$
factory = null;
}
return factory;
}
/**
* Returns the presentation factory with the given id, or <code>null</code> if not found.
* @param targetID The id of the presentation factory to use.
* @return AbstractPresentationFactory or <code>null</code>
* if not factory matches that id.
*/
public AbstractPresentationFactory getPresentationFactory(String targetID) {
Object o = createExtension(
IWorkbenchRegistryConstants.PL_PRESENTATION_FACTORIES,
"factory", targetID); //$NON-NLS-1$
if (o instanceof AbstractPresentationFactory) {
return (AbstractPresentationFactory) o;
}
WorkbenchPlugin
.log("Error creating presentation factory: " + targetID + " -- class is not an AbstractPresentationFactory"); //$NON-NLS-1$ //$NON-NLS-2$
return null;
}
/**
* Looks up the configuration element with the given id on the given extension point
* and instantiates the class specified by the class attributes.
*
* @param extensionPointId the extension point id (simple id)
* @param elementName the name of the configuration element, or <code>null</code>
* to match any element
* @param targetID the target id
* @return the instantiated extension object, or <code>null</code> if not found
*/
private Object createExtension(String extensionPointId, String elementName,
String targetID) {
IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
.getExtensionPoint(PI_WORKBENCH, extensionPointId);
if (extensionPoint == null) {
WorkbenchPlugin
.log("Unable to find extension. Extension point: " + extensionPointId + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
return null;
}
// Loop through the config elements.
IConfigurationElement targetElement = null;
IConfigurationElement[] elements = extensionPoint
.getConfigurationElements();
for (int j = 0; j < elements.length; j++) {
IConfigurationElement element = elements[j];
if (elementName == null || elementName.equals(element.getName())) {
String strID = element.getAttribute("id"); //$NON-NLS-1$
if (targetID.equals(strID)) {
targetElement = element;
break;
}
}
}
if (targetElement == null) {
// log it since we cannot safely display a dialog.
WorkbenchPlugin.log("Unable to find extension: " + targetID //$NON-NLS-1$
+ " in extension point: " + extensionPointId); //$NON-NLS-1$
return null;
}
// Create the extension.
try {
return createExtension(targetElement, "class"); //$NON-NLS-1$
} catch (CoreException e) {
// log it since we cannot safely display a dialog.
WorkbenchPlugin.log("Unable to create extension: " + targetID //$NON-NLS-1$
+ " in extension point: " + extensionPointId //$NON-NLS-1$
+ ", status: ", e.getStatus()); //$NON-NLS-1$
}
return null;
}
/**
* Return the perspective registry.
* @return IPerspectiveRegistry. The registry for the receiver.
*/
public IPerspectiveRegistry getPerspectiveRegistry() {
if (perspRegistry == null) {
perspRegistry = new PerspectiveRegistry();
// the load methods can touch on WorkbenchImages if an image is
// missing so we need to wrap the call in
// a startup block for the case where a custom descriptor exists on
// startup that does not have an image
// associated with it. See bug 196352.
StartupThreading.runWithoutExceptions(new StartupRunnable() {
public void runWithException() throws Throwable {
perspRegistry.load();
}
});
}
return perspRegistry;
}
/**
* Returns the working set manager
*
* @return the working set manager
* @since 2.0
*/
public IWorkingSetManager getWorkingSetManager() {
if (workingSetManager == null) {
workingSetManager = new WorkingSetManager(bundleContext);
workingSetManager.restoreState();
}
return workingSetManager;
}
/**
* Returns the working set registry
*
* @return the working set registry
* @since 2.0
*/
public WorkingSetRegistry getWorkingSetRegistry() {
if (workingSetRegistry == null) {
workingSetRegistry = new WorkingSetRegistry();
workingSetRegistry.load();
}
return workingSetRegistry;
}
/**
* Returns the introduction registry.
*
* @return the introduction registry.
* @since 3.0
*/
public IIntroRegistry getIntroRegistry() {
if (introRegistry == null) {
introRegistry = new IntroRegistry();
}
return introRegistry;
}
/**
* Returns the operation support.
*
* @return the workbench operation support.
* @since 3.1
*/
public IWorkbenchOperationSupport getOperationSupport() {
if (operationSupport == null) {
operationSupport = new WorkbenchOperationSupport();
}
return operationSupport;
}
/**
* Get the preference manager.
* @return PreferenceManager the preference manager for
* the receiver.
*/
public PreferenceManager getPreferenceManager() {
if (preferenceManager == null) {
preferenceManager = new WorkbenchPreferenceManager(
PREFERENCE_PAGE_CATEGORY_SEPARATOR);
//Get the pages from the registry
PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader(
getWorkbench());
registryReader
.loadFromRegistry(Platform.getExtensionRegistry());
preferenceManager.addPages(registryReader.getTopLevelNodes());
}
return preferenceManager;
}
/**
* Returns the shared images for the workbench.
*
* @return the shared image manager
*/
public ISharedImages getSharedImages() {
if (sharedImages == null) {
sharedImages = new SharedImages();
}
return sharedImages;
}
/**
* Returns the theme registry for the workbench.
*
* @return the theme registry
*/
public IThemeRegistry getThemeRegistry() {
if (themeRegistry == null) {
themeRegistry = new ThemeRegistry();
ThemeRegistryReader reader = new ThemeRegistryReader();
reader.readThemes(Platform.getExtensionRegistry(),
themeRegistry);
}
return themeRegistry;
}
/**
* Answer the view registry.
* @return IViewRegistry the view registry for the
* receiver.
*/
public IViewRegistry getViewRegistry() {
if (viewRegistry == null) {
viewRegistry = new ViewRegistry();
}
return viewRegistry;
}
/**
* Answer the workbench.
* @deprecated Use <code>PlatformUI.getWorkbench()</code> instead.
*/
public IWorkbench getWorkbench() {
return PlatformUI.getWorkbench();
}
/**
* Set default preference values.
* This method must be called whenever the preference store is initially loaded
* because the default values are not stored in the preference store.
*/
protected void initializeDefaultPreferences(IPreferenceStore store) {
// Do nothing. This should not be called.
// Prefs are initialized in WorkbenchPreferenceInitializer.
}
/**
* Logs the given message to the platform log.
*
* If you have an exception in hand, call log(String, Throwable) instead.
*
* If you have a status object in hand call log(String, IStatus) instead.
*
* This convenience method is for internal use by the Workbench only and
* must not be called outside the Workbench.
*
* @param message
* A high level UI message describing when the problem happened.
*/
public static void log(String message) {
getDefault().getLog().log(
StatusUtil.newStatus(IStatus.ERROR, message, null));
}
/**
* Log the throwable.
* @param t
*/
public static void log(Throwable t) {
getDefault().getLog().log(getStatus(t));
}
/**
* Return the status from throwable
* @param t throwable
* @return IStatus
*/
public static IStatus getStatus(Throwable t) {
String message = StatusUtil.getLocalizedMessage(t);
return newError(message, t);
}
/**
* Create a new error from the message and the
* throwable.
* @param message
* @param t
* @return IStatus
*/
public static IStatus newError(String message, Throwable t) {
String pluginId = "org.eclipse.ui.workbench"; //$NON-NLS-1$
int errorCode = IStatus.OK;
// If this was a CoreException, keep the original plugin ID and error
// code
if (t instanceof CoreException) {
CoreException ce = (CoreException) t;
pluginId = ce.getStatus().getPlugin();
errorCode = ce.getStatus().getCode();
}
return new Status(IStatus.ERROR, pluginId, errorCode, message,
StatusUtil.getCause(t));
}
/**
* Logs the given message and throwable to the platform log.
*
* If you have a status object in hand call log(String, IStatus) instead.
*
* This convenience method is for internal use by the Workbench only and
* must not be called outside the Workbench.
*
* @param message
* A high level UI message describing when the problem happened.
* @param t
* The throwable from where the problem actually occurred.
*/
public static void log(String message, Throwable t) {
IStatus status = StatusUtil.newStatus(IStatus.ERROR, message, t);
log(message, status);
}
/**
* Logs the given throwable to the platform log, indicating the class and
* method from where it is being logged (this is not necessarily where it
* occurred).
*
* This convenience method is for internal use by the Workbench only and
* must not be called outside the Workbench.
*
* @param clazz
* The calling class.
* @param methodName
* The calling method name.
* @param t
* The throwable from where the problem actually occurred.
*/
public static void log(Class clazz, String methodName, Throwable t) {
String msg = MessageFormat.format("Exception in {0}.{1}: {2}", //$NON-NLS-1$
new Object[] { clazz.getName(), methodName, t });
log(msg, t);
}
/**
* Logs the given message and status to the platform log.
*
* This convenience method is for internal use by the Workbench only and
* must not be called outside the Workbench.
*
* @param message
* A high level UI message describing when the problem happened.
* May be <code>null</code>.
* @param status
* The status describing the problem. Must not be null.
*/
public static void log(String message, IStatus status) {
//1FTUHE0: ITPCORE:ALL - API - Status & logging - loss of semantic info
if (message != null) {
getDefault().getLog().log(
StatusUtil.newStatus(IStatus.ERROR, message, null));
}
getDefault().getLog().log(status);
}
/**
* Log the status to the default log.
* @param status
*/
public static void log(IStatus status) {
getDefault().getLog().log(status);
}
/**
* Get the decorator manager for the receiver
* @return DecoratorManager the decorator manager
* for the receiver.
*/
public DecoratorManager getDecoratorManager() {
if (this.decoratorManager == null) {
this.decoratorManager = new DecoratorManager();
}
return decoratorManager;
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
context.addBundleListener(getBundleListener());
super.start(context);
bundleContext = context;
JFaceUtil.initializeJFace();
Window.setDefaultOrientation(getDefaultOrientation());
// The UI plugin needs to be initialized so that it can install the callback in PrefUtil,
// which needs to be done as early as possible, before the workbench
// accesses any API preferences.
Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
try {
// Attempt to load the activator of the ui bundle. This will force lazy start
// of the ui bundle. Using the bundle activator class here because it is a
// class that needs to be loaded anyway so it should not cause extra classes
// to be loaded.
if(uiBundle != null)
uiBundle.loadClass(UI_BUNDLE_ACTIVATOR);
} catch (ClassNotFoundException e) {
WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$
}
/*
* DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are
* likely to cause a deadlock in class loader code. Please see Bug 86450
* for more information.
*/
}
/**
* Get the default orientation from the command line
* arguments. If there are no arguments imply the
* orientation.
* @return int
* @see SWT#NONE
* @see SWT#RIGHT_TO_LEFT
* @see SWT#LEFT_TO_RIGHT
*/
private int getDefaultOrientation() {
String[] commandLineArgs = Platform.getCommandLineArgs();
int orientation = getCommandLineOrientation(commandLineArgs);
if(orientation != SWT.NONE) {
return orientation;
}
orientation = getSystemPropertyOrientation();
if(orientation != SWT.NONE) {
return orientation;
}
return checkCommandLineLocale(); //Use the default value if there is nothing specified
}
/**
* Check to see if the command line parameter for -nl
* has been set. If so imply the orientation from this
* specified Locale. If it is a bidirectional Locale
* return SWT#RIGHT_TO_LEFT.
* If it has not been set or has been set to
* a unidirectional Locale then return SWT#NONE.
*
* Locale is determined differently by different JDKs
* and may not be consistent with the users expectations.
*
* @return int
* @see SWT#NONE
* @see SWT#RIGHT_TO_LEFT
*/
private int checkCommandLineLocale() {
//Check if the user property is set. If not do not
//rely on the vm.
if(System.getProperty(NL_USER_PROPERTY) == null) {
return SWT.NONE;
}
Locale locale = Locale.getDefault();
String lang = locale.getLanguage();
if ("iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
"fa".equals(lang) || "ur".equals(lang)) { //$NON-NLS-1$ //$NON-NLS-2$
return SWT.RIGHT_TO_LEFT;
}
return SWT.NONE;
}
/**
* Check to see if the orientation was set in the
* system properties. If there is no orientation
* specified return SWT#NONE.
* @return int
* @see SWT#NONE
* @see SWT#RIGHT_TO_LEFT
* @see SWT#LEFT_TO_RIGHT
*/
private int getSystemPropertyOrientation() {
String orientation = System.getProperty(ORIENTATION_PROPERTY);
if(RIGHT_TO_LEFT.equals(orientation)) {
return SWT.RIGHT_TO_LEFT;
}
if(LEFT_TO_RIGHT.equals(orientation)) {
return SWT.LEFT_TO_RIGHT;
}
return SWT.NONE;
}
/**
* Find the orientation in the commandLineArgs. If there
* is no orientation specified return SWT#NONE.
* @param commandLineArgs
* @return int
* @see SWT#NONE
* @see SWT#RIGHT_TO_LEFT
* @see SWT#LEFT_TO_RIGHT
*/
private int getCommandLineOrientation(String[] commandLineArgs) {
//Do not process the last one as it will never have a parameter
for (int i = 0; i < commandLineArgs.length - 1; i++) {
if(commandLineArgs[i].equalsIgnoreCase(ORIENTATION_COMMAND_LINE)){
String orientation = commandLineArgs[i+1];
if(orientation.equals(RIGHT_TO_LEFT)){
System.setProperty(ORIENTATION_PROPERTY,RIGHT_TO_LEFT);
return SWT.RIGHT_TO_LEFT;
}
if(orientation.equals(LEFT_TO_RIGHT)){
System.setProperty(ORIENTATION_PROPERTY,LEFT_TO_RIGHT);
return SWT.LEFT_TO_RIGHT;
}
}
}
return SWT.NONE;
}
/**
* Return an array of all bundles contained in this workbench.
*
* @return an array of bundles in the workbench or an empty array if none
* @since 3.0
*/
public Bundle[] getBundles() {
return bundleContext == null ? new Bundle[0] : bundleContext
.getBundles();
}
/**
* Returns the bundle context associated with the workbench plug-in.
*
* @return the bundle context
* @since 3.1
*/
public BundleContext getBundleContext() {
return bundleContext;
}
/**
* Returns the application name.
* <p>
* Note this is never shown to the user.
* It is used to initialize the SWT Display.
* On Motif, for example, this can be used
* to set the name used for resource lookup.
* </p>
*
* @return the application name, or <code>null</code>
* @see org.eclipse.swt.widgets.Display#setAppName
* @since 3.0
*/
public String getAppName() {
return getProductInfo().getAppName();
}
/**
* Returns the name of the product.
*
* @return the product name, or <code>null</code> if none
* @since 3.0
*/
public String getProductName() {
return getProductInfo().getProductName();
}
/**
* Returns the image descriptors for the window image to use for this product.
*
* @return an array of the image descriptors for the window image, or
* <code>null</code> if none
* @since 3.0
*/
public ImageDescriptor[] getWindowImages() {
return getProductInfo().getWindowImages();
}
/**
* Returns an instance that describes this plugin's product (formerly "primary
* plugin").
* @return ProductInfo the product info for the receiver
*/
private ProductInfo getProductInfo() {
if (productInfo == null) {
productInfo = new ProductInfo(Platform.getProduct());
}
return productInfo;
}
/* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
if (bundleListener!=null) {
context.removeBundleListener(bundleListener);
bundleListener = null;
}
// TODO normally super.stop(*) would be the last statement in this
// method
super.stop(context);
if (workingSetManager != null) {
workingSetManager.dispose();
workingSetManager= null;
}
SWTResourceUtil.shutdown();
}
/**
* Return the new wizard registry.
*
* @return the new wizard registry
* @since 3.1
*/
public IWizardRegistry getNewWizardRegistry() {
return NewWizardRegistry.getInstance();
}
/**
* Return the import wizard registry.
*
* @return the import wizard registry
* @since 3.1
*/
public IWizardRegistry getImportWizardRegistry() {
return ImportWizardRegistry.getInstance();
}
/**
* Return the export wizard registry.
*
* @return the export wizard registry
* @since 3.1
*/
public IWizardRegistry getExportWizardRegistry() {
return ExportWizardRegistry.getInstance();
}
/**
* FOR INTERNAL WORKBENCH USE ONLY.
*
* Returns the path to a location in the file system that can be used
* to persist/restore state between workbench invocations.
* If the location did not exist prior to this call it will be created.
* Returns <code>null</code> if no such location is available.
*
* @return path to a location in the file system where this plug-in can
* persist data between sessions, or <code>null</code> if no such
* location is available.
* @since 3.1
*/
public IPath getDataLocation() {
try {
return getStateLocation();
} catch (IllegalStateException e) {
// This occurs if -data=@none is explicitly specified, so ignore this silently.
// Is this OK? See bug 85071.
return null;
}
}
/* package */ void addBundleListener(BundleListener bundleListener) {
bundleContext.addBundleListener(bundleListener);
}
/* package */ void removeBundleListener(BundleListener bundleListener) {
bundleContext.removeBundleListener(bundleListener);
}
/* package */ int getBundleCount() {
return bundleContext.getBundles().length;
}
/* package */ OutputStream getSplashStream() {
// assumes the output stream is available as a service
// see EclipseStarter.publishSplashScreen
ServiceReference[] ref;
try {
ref = bundleContext.getServiceReferences(OutputStream.class.getName(), null);
} catch (InvalidSyntaxException e) {
return null;
}
if(ref==null) {
return null;
}
for (int i = 0; i < ref.length; i++) {
String name = (String) ref[i].getProperty("name"); //$NON-NLS-1$
if (name != null && name.equals("splashstream")) { //$NON-NLS-1$
Object result = bundleContext.getService(ref[i]);
bundleContext.ungetService(ref[i]);
return (OutputStream) result;
}
}
return null;
}
/**
* @return
*/
private BundleListener getBundleListener() {
if (bundleListener == null) {
bundleListener = new SynchronousBundleListener() {
public void bundleChanged(BundleEvent event) {
WorkbenchPlugin.this.bundleChanged(event);
}
};
}
return bundleListener;
}
private void bundleChanged(BundleEvent event) {
// a bundle in the STARTING state generates 2 events, LAZY_ACTIVATION
// when it enters STARTING and STARTING when it exists STARTING :-)
synchronized (startingBundles) {
switch (event.getType()) {
case BundleEvent.STARTING :
startingBundles.add(event.getBundle());
break;
case BundleEvent.STARTED :
case BundleEvent.STOPPED :
startingBundles.remove(event.getBundle());
break;
default :
break;
}
}
}
public boolean isStarting(Bundle bundle) {
synchronized (startingBundles) {
return startingBundles.contains(bundle);
}
}
}