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.OutputStream;
0013: import java.util.*;
0014:
0015: import org.eclipse.core.runtime.CoreException;
0016: import org.eclipse.core.runtime.IConfigurationElement;
0017: import org.eclipse.core.runtime.IExtensionPoint;
0018: import org.eclipse.core.runtime.IPath;
0019: import org.eclipse.core.runtime.IStatus;
0020: import org.eclipse.core.runtime.Platform;
0021: import org.eclipse.core.runtime.Status;
0022: import org.eclipse.jface.preference.IPreferenceStore;
0023: import org.eclipse.jface.preference.PreferenceManager;
0024: import org.eclipse.jface.resource.ImageDescriptor;
0025: import org.eclipse.jface.resource.ImageRegistry;
0026: import org.eclipse.jface.window.Window;
0027: import org.eclipse.swt.SWT;
0028: import org.eclipse.swt.custom.BusyIndicator;
0029: import org.eclipse.ui.IEditorRegistry;
0030: import org.eclipse.ui.IElementFactory;
0031: import org.eclipse.ui.IPerspectiveRegistry;
0032: import org.eclipse.ui.ISharedImages;
0033: import org.eclipse.ui.IWorkbench;
0034: import org.eclipse.ui.IWorkingSetManager;
0035: import org.eclipse.ui.PlatformUI;
0036: import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
0037: import org.eclipse.ui.internal.decorators.DecoratorManager;
0038: import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceManager;
0039: import org.eclipse.ui.internal.intro.IIntroRegistry;
0040: import org.eclipse.ui.internal.intro.IntroRegistry;
0041: import org.eclipse.ui.internal.misc.StatusUtil;
0042: import org.eclipse.ui.internal.operations.WorkbenchOperationSupport;
0043: import org.eclipse.ui.internal.progress.ProgressManager;
0044: import org.eclipse.ui.internal.registry.ActionSetRegistry;
0045: import org.eclipse.ui.internal.registry.EditorRegistry;
0046: import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
0047: import org.eclipse.ui.internal.registry.PerspectiveRegistry;
0048: import org.eclipse.ui.internal.registry.PreferencePageRegistryReader;
0049: import org.eclipse.ui.internal.registry.ViewRegistry;
0050: import org.eclipse.ui.internal.registry.WorkingSetRegistry;
0051: import org.eclipse.ui.internal.themes.IThemeRegistry;
0052: import org.eclipse.ui.internal.themes.ThemeRegistry;
0053: import org.eclipse.ui.internal.themes.ThemeRegistryReader;
0054: import org.eclipse.ui.internal.util.BundleUtility;
0055: import org.eclipse.ui.internal.util.SWTResourceUtil;
0056: import org.eclipse.ui.internal.wizards.ExportWizardRegistry;
0057: import org.eclipse.ui.internal.wizards.ImportWizardRegistry;
0058: import org.eclipse.ui.internal.wizards.NewWizardRegistry;
0059: import org.eclipse.ui.operations.IWorkbenchOperationSupport;
0060: import org.eclipse.ui.plugin.AbstractUIPlugin;
0061: import org.eclipse.ui.presentations.AbstractPresentationFactory;
0062: import org.eclipse.ui.views.IViewRegistry;
0063: import org.eclipse.ui.wizards.IWizardRegistry;
0064: import org.osgi.framework.*;
0065:
0066: import com.ibm.icu.text.MessageFormat;
0067:
0068: /**
0069: * This class represents the TOP of the workbench UI world
0070: * A plugin class is effectively an application wrapper
0071: * for a plugin & its classes. This class should be thought
0072: * of as the workbench UI's application class.
0073: *
0074: * This class is responsible for tracking various registries
0075: * font, preference, graphics, dialog store.
0076: *
0077: * This class is explicitly referenced by the
0078: * workbench plugin's "plugin.xml" and places it
0079: * into the UI start extension point of the main
0080: * overall application harness
0081: *
0082: * When is this class started?
0083: * When the Application
0084: * calls createExecutableExtension to create an executable
0085: * instance of our workbench class.
0086: */
0087: public class WorkbenchPlugin extends AbstractUIPlugin {
0088:
0089: private static final String LEFT_TO_RIGHT = "ltr"; //$NON-NLS-1$
0090: private static final String RIGHT_TO_LEFT = "rtl";//$NON-NLS-1$
0091: private static final String ORIENTATION_COMMAND_LINE = "-dir";//$NON-NLS-1$
0092: private static final String ORIENTATION_PROPERTY = "eclipse.orientation";//$NON-NLS-1$
0093: private static final String NL_USER_PROPERTY = "osgi.nl.user"; //$NON-NLS-1$
0094: private static final String UI_BUNDLE_ACTIVATOR = "org.eclipse.ui.internal.UIPlugin"; //$NON-NLS-1$
0095:
0096: // Default instance of the receiver
0097: private static WorkbenchPlugin inst;
0098:
0099: // Manager that maps resources to descriptors of editors to use
0100: private EditorRegistry editorRegistry;
0101:
0102: // Manager for the DecoratorManager
0103: private DecoratorManager decoratorManager;
0104:
0105: // Theme registry
0106: private ThemeRegistry themeRegistry;
0107:
0108: // Manager for working sets (IWorkingSet)
0109: private WorkingSetManager workingSetManager;
0110:
0111: // Working set registry, stores working set dialogs
0112: private WorkingSetRegistry workingSetRegistry;
0113:
0114: // The context within which this plugin was started.
0115: private BundleContext bundleContext;
0116:
0117: // The set of currently starting bundles
0118: private Collection startingBundles = new HashSet();
0119:
0120: /**
0121: * Global workbench ui plugin flag. Only workbench implementation is allowed to use this flag
0122: * All other plugins, examples, or test cases must *not* use this flag.
0123: */
0124: public static boolean DEBUG = false;
0125:
0126: /**
0127: * The workbench plugin ID.
0128: *
0129: * @issue we should just drop this constant and use PlatformUI.PLUGIN_ID instead
0130: */
0131: public static String PI_WORKBENCH = PlatformUI.PLUGIN_ID;
0132:
0133: /**
0134: * The character used to separate preference page category ids
0135: */
0136: public static char PREFERENCE_PAGE_CATEGORY_SEPARATOR = '/';
0137:
0138: // Other data.
0139: private WorkbenchPreferenceManager preferenceManager;
0140:
0141: private ViewRegistry viewRegistry;
0142:
0143: private PerspectiveRegistry perspRegistry;
0144:
0145: private ActionSetRegistry actionSetRegistry;
0146:
0147: private SharedImages sharedImages;
0148:
0149: /**
0150: * Information describing the product (formerly called "primary plugin"); lazily
0151: * initialized.
0152: * @since 3.0
0153: */
0154: private ProductInfo productInfo = null;
0155:
0156: private IntroRegistry introRegistry;
0157:
0158: private WorkbenchOperationSupport operationSupport;
0159: private BundleListener bundleListener;
0160:
0161: /**
0162: * Create an instance of the WorkbenchPlugin. The workbench plugin is
0163: * effectively the "application" for the workbench UI. The entire UI
0164: * operates as a good plugin citizen.
0165: */
0166: public WorkbenchPlugin() {
0167: super ();
0168: inst = this ;
0169: }
0170:
0171: /**
0172: * Unload all members. This can be used to run a second instance of a workbench.
0173: * @since 3.0
0174: */
0175: void reset() {
0176: editorRegistry = null;
0177:
0178: if (decoratorManager != null) {
0179: decoratorManager.dispose();
0180: decoratorManager = null;
0181: }
0182:
0183: ProgressManager.shutdownProgressManager();
0184:
0185: themeRegistry = null;
0186: if (workingSetManager != null) {
0187: workingSetManager.dispose();
0188: workingSetManager = null;
0189: }
0190: workingSetRegistry = null;
0191:
0192: preferenceManager = null;
0193: if (viewRegistry != null) {
0194: viewRegistry.dispose();
0195: viewRegistry = null;
0196: }
0197: if (perspRegistry != null) {
0198: perspRegistry.dispose();
0199: perspRegistry = null;
0200: }
0201: actionSetRegistry = null;
0202: sharedImages = null;
0203:
0204: productInfo = null;
0205: introRegistry = null;
0206:
0207: if (operationSupport != null) {
0208: operationSupport.dispose();
0209: operationSupport = null;
0210: }
0211:
0212: DEBUG = false;
0213:
0214: }
0215:
0216: /**
0217: * Creates an extension. If the extension plugin has not
0218: * been loaded a busy cursor will be activated during the duration of
0219: * the load.
0220: *
0221: * @param element the config element defining the extension
0222: * @param classAttribute the name of the attribute carrying the class
0223: * @return the extension object
0224: * @throws CoreException if the extension cannot be created
0225: */
0226: public static Object createExtension(
0227: final IConfigurationElement element,
0228: final String classAttribute) throws CoreException {
0229: try {
0230: // If plugin has been loaded create extension.
0231: // Otherwise, show busy cursor then create extension.
0232: if (BundleUtility.isActivated(element
0233: .getDeclaringExtension().getNamespace())) {
0234: return element
0235: .createExecutableExtension(classAttribute);
0236: }
0237: final Object[] ret = new Object[1];
0238: final CoreException[] exc = new CoreException[1];
0239: BusyIndicator.showWhile(null, new Runnable() {
0240: public void run() {
0241: try {
0242: ret[0] = element
0243: .createExecutableExtension(classAttribute);
0244: } catch (CoreException e) {
0245: exc[0] = e;
0246: }
0247: }
0248: });
0249: if (exc[0] != null) {
0250: throw exc[0];
0251: }
0252: return ret[0];
0253:
0254: } catch (CoreException core) {
0255: throw core;
0256: } catch (Exception e) {
0257: throw new CoreException(new Status(IStatus.ERROR,
0258: PI_WORKBENCH, IStatus.ERROR,
0259: WorkbenchMessages.WorkbenchPlugin_extension, e));
0260: }
0261: }
0262:
0263: /**
0264: * Answers whether the provided element either has an attribute with the
0265: * given name or a child element with the given name with an attribute
0266: * called class.
0267: *
0268: * @param element
0269: * the element to test
0270: * @param extensionName
0271: * the name of the extension to test for
0272: * @return whether or not the extension is declared
0273: * @since 3.3
0274: */
0275: public static boolean hasExecutableExtension(
0276: IConfigurationElement element, String extensionName) {
0277:
0278: if (element.getAttribute(extensionName) != null)
0279: return true;
0280: String elementText = element.getValue();
0281: if (elementText != null && !elementText.equals("")) //$NON-NLS-1$
0282: return true;
0283: IConfigurationElement[] children = element
0284: .getChildren(extensionName);
0285: if (children.length == 1) {
0286: if (children[0]
0287: .getAttribute(IWorkbenchRegistryConstants.ATT_CLASS) != null)
0288: return true;
0289: }
0290: return false;
0291: }
0292:
0293: /**
0294: * Checks to see if the provided element has the syntax for an executable
0295: * extension with a given name that resides in a bundle that is already
0296: * active. Determining the bundle happens in one of two ways:<br/>
0297: * <ul>
0298: * <li>The element has an attribute with the specified name or element text
0299: * in the form <code>bundle.id/class.name[:optional attributes]</code></li>
0300: * <li>The element has a child element with the specified name that has a
0301: * <code>plugin</code> attribute</li>
0302: * </ul>
0303: *
0304: * @param element
0305: * the element to test
0306: * @param extensionName
0307: * the name of the extension to test for
0308: * @return whether or not the bundle expressed by the above criteria is
0309: * active. If the bundle cannot be determined then the state of the
0310: * bundle that declared the element is returned.
0311: * @since 3.3
0312: */
0313: public static boolean isBundleLoadedForExecutableExtension(
0314: IConfigurationElement element, String extensionName) {
0315: Bundle bundle = getBundleForExecutableExtension(element,
0316: extensionName);
0317:
0318: if (bundle == null)
0319: return true;
0320: return bundle.getState() == Bundle.ACTIVE;
0321: }
0322:
0323: /**
0324: * Returns the bundle that contains the class referenced by an executable
0325: * extension. Determining the bundle happens in one of two ways:<br/>
0326: * <ul>
0327: * <li>The element has an attribute with the specified name or element text
0328: * in the form <code>bundle.id/class.name[:optional attributes]</code></li>
0329: * <li>The element has a child element with the specified name that has a
0330: * <code>plugin</code> attribute</li>
0331: * </ul>
0332: *
0333: * @param element
0334: * the element to test
0335: * @param extensionName
0336: * the name of the extension to test for
0337: * @return the bundle referenced by the extension. If that bundle cannot be
0338: * determined the bundle that declared the element is returned. Note
0339: * that this may be <code>null</code>.
0340: * @since 3.3
0341: */
0342: public static Bundle getBundleForExecutableExtension(
0343: IConfigurationElement element, String extensionName) {
0344: // this code is derived heavily from
0345: // ConfigurationElement.createExecutableExtension.
0346: String prop = null;
0347: String executable;
0348: String contributorName = null;
0349: int i;
0350:
0351: if (extensionName != null)
0352: prop = element.getAttribute(extensionName);
0353: else {
0354: // property not specified, try as element value
0355: prop = element.getValue();
0356: if (prop != null) {
0357: prop = prop.trim();
0358: if (prop.equals("")) //$NON-NLS-1$
0359: prop = null;
0360: }
0361: }
0362:
0363: if (prop == null) {
0364: // property not defined, try as a child element
0365: IConfigurationElement[] exec = element
0366: .getChildren(extensionName);
0367: if (exec.length != 0)
0368: contributorName = exec[0].getAttribute("plugin"); //$NON-NLS-1$
0369: } else {
0370: // simple property or element value, parse it into its components
0371: i = prop.indexOf(':');
0372: if (i != -1)
0373: executable = prop.substring(0, i).trim();
0374: else
0375: executable = prop;
0376:
0377: i = executable.indexOf('/');
0378: if (i != -1)
0379: contributorName = executable.substring(0, i).trim();
0380:
0381: }
0382:
0383: if (contributorName == null)
0384: contributorName = element.getContributor().getName();
0385:
0386: return Platform.getBundle(contributorName);
0387: }
0388:
0389: /**
0390: * Returns the image registry for this plugin.
0391: *
0392: * Where are the images? The images (typically gifs) are found in the same
0393: * plugins directory.
0394: *
0395: * @see ImageRegistry
0396: *
0397: * Note: The workbench uses the standard JFace ImageRegistry to track its
0398: * images. In addition the class WorkbenchGraphicResources provides
0399: * convenience access to the graphics resources and fast field access for
0400: * some of the commonly used graphical images.
0401: */
0402: protected ImageRegistry createImageRegistry() {
0403: return WorkbenchImages.getImageRegistry();
0404: }
0405:
0406: /**
0407: * Returns the action set registry for the workbench.
0408: *
0409: * @return the workbench action set registry
0410: */
0411: public ActionSetRegistry getActionSetRegistry() {
0412: if (actionSetRegistry == null) {
0413: actionSetRegistry = new ActionSetRegistry();
0414: }
0415: return actionSetRegistry;
0416: }
0417:
0418: /**
0419: * Return the default instance of the receiver. This represents the runtime plugin.
0420: * @return WorkbenchPlugin
0421: * @see AbstractUIPlugin for the typical implementation pattern for plugin classes.
0422: */
0423: public static WorkbenchPlugin getDefault() {
0424: return inst;
0425: }
0426:
0427: /**
0428: * Answer the manager that maps resource types to a the
0429: * description of the editor to use
0430: * @return IEditorRegistry the editor registry used
0431: * by this plug-in.
0432: */
0433:
0434: public IEditorRegistry getEditorRegistry() {
0435: if (editorRegistry == null) {
0436: editorRegistry = new EditorRegistry();
0437: }
0438: return editorRegistry;
0439: }
0440:
0441: /**
0442: * Answer the element factory for an id, or <code>null</code. if not found.
0443: * @param targetID
0444: * @return IElementFactory
0445: */
0446: public IElementFactory getElementFactory(String targetID) {
0447:
0448: // Get the extension point registry.
0449: IExtensionPoint extensionPoint;
0450: extensionPoint = Platform.getExtensionRegistry()
0451: .getExtensionPoint(PI_WORKBENCH,
0452: IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY);
0453:
0454: if (extensionPoint == null) {
0455: WorkbenchPlugin
0456: .log("Unable to find element factory. Extension point: " + IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY + " not found"); //$NON-NLS-2$ //$NON-NLS-1$
0457: return null;
0458: }
0459:
0460: // Loop through the config elements.
0461: IConfigurationElement targetElement = null;
0462: IConfigurationElement[] configElements = extensionPoint
0463: .getConfigurationElements();
0464: for (int j = 0; j < configElements.length; j++) {
0465: String strID = configElements[j].getAttribute("id"); //$NON-NLS-1$
0466: if (targetID.equals(strID)) {
0467: targetElement = configElements[j];
0468: break;
0469: }
0470: }
0471: if (targetElement == null) {
0472: // log it since we cannot safely display a dialog.
0473: WorkbenchPlugin
0474: .log("Unable to find element factory: " + targetID); //$NON-NLS-1$
0475: return null;
0476: }
0477:
0478: // Create the extension.
0479: IElementFactory factory = null;
0480: try {
0481: factory = (IElementFactory) createExtension(targetElement,
0482: "class"); //$NON-NLS-1$
0483: } catch (CoreException e) {
0484: // log it since we cannot safely display a dialog.
0485: WorkbenchPlugin.log(
0486: "Unable to create element factory.", e.getStatus()); //$NON-NLS-1$
0487: factory = null;
0488: }
0489: return factory;
0490: }
0491:
0492: /**
0493: * Returns the presentation factory with the given id, or <code>null</code> if not found.
0494: * @param targetID The id of the presentation factory to use.
0495: * @return AbstractPresentationFactory or <code>null</code>
0496: * if not factory matches that id.
0497: */
0498: public AbstractPresentationFactory getPresentationFactory(
0499: String targetID) {
0500: Object o = createExtension(
0501: IWorkbenchRegistryConstants.PL_PRESENTATION_FACTORIES,
0502: "factory", targetID); //$NON-NLS-1$
0503: if (o instanceof AbstractPresentationFactory) {
0504: return (AbstractPresentationFactory) o;
0505: }
0506: WorkbenchPlugin
0507: .log("Error creating presentation factory: " + targetID + " -- class is not an AbstractPresentationFactory"); //$NON-NLS-1$ //$NON-NLS-2$
0508: return null;
0509: }
0510:
0511: /**
0512: * Looks up the configuration element with the given id on the given extension point
0513: * and instantiates the class specified by the class attributes.
0514: *
0515: * @param extensionPointId the extension point id (simple id)
0516: * @param elementName the name of the configuration element, or <code>null</code>
0517: * to match any element
0518: * @param targetID the target id
0519: * @return the instantiated extension object, or <code>null</code> if not found
0520: */
0521: private Object createExtension(String extensionPointId,
0522: String elementName, String targetID) {
0523: IExtensionPoint extensionPoint = Platform
0524: .getExtensionRegistry().getExtensionPoint(PI_WORKBENCH,
0525: extensionPointId);
0526: if (extensionPoint == null) {
0527: WorkbenchPlugin
0528: .log("Unable to find extension. Extension point: " + extensionPointId + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
0529: return null;
0530: }
0531:
0532: // Loop through the config elements.
0533: IConfigurationElement targetElement = null;
0534: IConfigurationElement[] elements = extensionPoint
0535: .getConfigurationElements();
0536: for (int j = 0; j < elements.length; j++) {
0537: IConfigurationElement element = elements[j];
0538: if (elementName == null
0539: || elementName.equals(element.getName())) {
0540: String strID = element.getAttribute("id"); //$NON-NLS-1$
0541: if (targetID.equals(strID)) {
0542: targetElement = element;
0543: break;
0544: }
0545: }
0546: }
0547: if (targetElement == null) {
0548: // log it since we cannot safely display a dialog.
0549: WorkbenchPlugin.log("Unable to find extension: " + targetID //$NON-NLS-1$
0550: + " in extension point: " + extensionPointId); //$NON-NLS-1$
0551: return null;
0552: }
0553:
0554: // Create the extension.
0555: try {
0556: return createExtension(targetElement, "class"); //$NON-NLS-1$
0557: } catch (CoreException e) {
0558: // log it since we cannot safely display a dialog.
0559: WorkbenchPlugin
0560: .log(
0561: "Unable to create extension: " + targetID //$NON-NLS-1$
0562: + " in extension point: " + extensionPointId //$NON-NLS-1$
0563: + ", status: ", e.getStatus()); //$NON-NLS-1$
0564: }
0565: return null;
0566: }
0567:
0568: /**
0569: * Return the perspective registry.
0570: * @return IPerspectiveRegistry. The registry for the receiver.
0571: */
0572: public IPerspectiveRegistry getPerspectiveRegistry() {
0573: if (perspRegistry == null) {
0574: perspRegistry = new PerspectiveRegistry();
0575: // the load methods can touch on WorkbenchImages if an image is
0576: // missing so we need to wrap the call in
0577: // a startup block for the case where a custom descriptor exists on
0578: // startup that does not have an image
0579: // associated with it. See bug 196352.
0580: StartupThreading
0581: .runWithoutExceptions(new StartupRunnable() {
0582: public void runWithException() throws Throwable {
0583: perspRegistry.load();
0584: }
0585: });
0586:
0587: }
0588: return perspRegistry;
0589: }
0590:
0591: /**
0592: * Returns the working set manager
0593: *
0594: * @return the working set manager
0595: * @since 2.0
0596: */
0597: public IWorkingSetManager getWorkingSetManager() {
0598: if (workingSetManager == null) {
0599: workingSetManager = new WorkingSetManager(bundleContext);
0600: workingSetManager.restoreState();
0601: }
0602: return workingSetManager;
0603: }
0604:
0605: /**
0606: * Returns the working set registry
0607: *
0608: * @return the working set registry
0609: * @since 2.0
0610: */
0611: public WorkingSetRegistry getWorkingSetRegistry() {
0612: if (workingSetRegistry == null) {
0613: workingSetRegistry = new WorkingSetRegistry();
0614: workingSetRegistry.load();
0615: }
0616: return workingSetRegistry;
0617: }
0618:
0619: /**
0620: * Returns the introduction registry.
0621: *
0622: * @return the introduction registry.
0623: * @since 3.0
0624: */
0625: public IIntroRegistry getIntroRegistry() {
0626: if (introRegistry == null) {
0627: introRegistry = new IntroRegistry();
0628: }
0629: return introRegistry;
0630: }
0631:
0632: /**
0633: * Returns the operation support.
0634: *
0635: * @return the workbench operation support.
0636: * @since 3.1
0637: */
0638: public IWorkbenchOperationSupport getOperationSupport() {
0639: if (operationSupport == null) {
0640: operationSupport = new WorkbenchOperationSupport();
0641: }
0642: return operationSupport;
0643: }
0644:
0645: /**
0646: * Get the preference manager.
0647: * @return PreferenceManager the preference manager for
0648: * the receiver.
0649: */
0650: public PreferenceManager getPreferenceManager() {
0651: if (preferenceManager == null) {
0652: preferenceManager = new WorkbenchPreferenceManager(
0653: PREFERENCE_PAGE_CATEGORY_SEPARATOR);
0654:
0655: //Get the pages from the registry
0656: PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader(
0657: getWorkbench());
0658: registryReader.loadFromRegistry(Platform
0659: .getExtensionRegistry());
0660: preferenceManager.addPages(registryReader
0661: .getTopLevelNodes());
0662:
0663: }
0664: return preferenceManager;
0665: }
0666:
0667: /**
0668: * Returns the shared images for the workbench.
0669: *
0670: * @return the shared image manager
0671: */
0672: public ISharedImages getSharedImages() {
0673: if (sharedImages == null) {
0674: sharedImages = new SharedImages();
0675: }
0676: return sharedImages;
0677: }
0678:
0679: /**
0680: * Returns the theme registry for the workbench.
0681: *
0682: * @return the theme registry
0683: */
0684: public IThemeRegistry getThemeRegistry() {
0685: if (themeRegistry == null) {
0686: themeRegistry = new ThemeRegistry();
0687: ThemeRegistryReader reader = new ThemeRegistryReader();
0688: reader.readThemes(Platform.getExtensionRegistry(),
0689: themeRegistry);
0690: }
0691: return themeRegistry;
0692: }
0693:
0694: /**
0695: * Answer the view registry.
0696: * @return IViewRegistry the view registry for the
0697: * receiver.
0698: */
0699: public IViewRegistry getViewRegistry() {
0700: if (viewRegistry == null) {
0701: viewRegistry = new ViewRegistry();
0702: }
0703: return viewRegistry;
0704: }
0705:
0706: /**
0707: * Answer the workbench.
0708: * @deprecated Use <code>PlatformUI.getWorkbench()</code> instead.
0709: */
0710: public IWorkbench getWorkbench() {
0711: return PlatformUI.getWorkbench();
0712: }
0713:
0714: /**
0715: * Set default preference values.
0716: * This method must be called whenever the preference store is initially loaded
0717: * because the default values are not stored in the preference store.
0718: */
0719: protected void initializeDefaultPreferences(IPreferenceStore store) {
0720: // Do nothing. This should not be called.
0721: // Prefs are initialized in WorkbenchPreferenceInitializer.
0722: }
0723:
0724: /**
0725: * Logs the given message to the platform log.
0726: *
0727: * If you have an exception in hand, call log(String, Throwable) instead.
0728: *
0729: * If you have a status object in hand call log(String, IStatus) instead.
0730: *
0731: * This convenience method is for internal use by the Workbench only and
0732: * must not be called outside the Workbench.
0733: *
0734: * @param message
0735: * A high level UI message describing when the problem happened.
0736: */
0737: public static void log(String message) {
0738: getDefault().getLog().log(
0739: StatusUtil.newStatus(IStatus.ERROR, message, null));
0740: }
0741:
0742: /**
0743: * Log the throwable.
0744: * @param t
0745: */
0746: public static void log(Throwable t) {
0747: getDefault().getLog().log(getStatus(t));
0748: }
0749:
0750: /**
0751: * Return the status from throwable
0752: * @param t throwable
0753: * @return IStatus
0754: */
0755: public static IStatus getStatus(Throwable t) {
0756: String message = StatusUtil.getLocalizedMessage(t);
0757:
0758: return newError(message, t);
0759: }
0760:
0761: /**
0762: * Create a new error from the message and the
0763: * throwable.
0764: * @param message
0765: * @param t
0766: * @return IStatus
0767: */
0768: public static IStatus newError(String message, Throwable t) {
0769: String pluginId = "org.eclipse.ui.workbench"; //$NON-NLS-1$
0770: int errorCode = IStatus.OK;
0771:
0772: // If this was a CoreException, keep the original plugin ID and error
0773: // code
0774: if (t instanceof CoreException) {
0775: CoreException ce = (CoreException) t;
0776: pluginId = ce.getStatus().getPlugin();
0777: errorCode = ce.getStatus().getCode();
0778: }
0779:
0780: return new Status(IStatus.ERROR, pluginId, errorCode, message,
0781: StatusUtil.getCause(t));
0782: }
0783:
0784: /**
0785: * Logs the given message and throwable to the platform log.
0786: *
0787: * If you have a status object in hand call log(String, IStatus) instead.
0788: *
0789: * This convenience method is for internal use by the Workbench only and
0790: * must not be called outside the Workbench.
0791: *
0792: * @param message
0793: * A high level UI message describing when the problem happened.
0794: * @param t
0795: * The throwable from where the problem actually occurred.
0796: */
0797: public static void log(String message, Throwable t) {
0798: IStatus status = StatusUtil
0799: .newStatus(IStatus.ERROR, message, t);
0800: log(message, status);
0801: }
0802:
0803: /**
0804: * Logs the given throwable to the platform log, indicating the class and
0805: * method from where it is being logged (this is not necessarily where it
0806: * occurred).
0807: *
0808: * This convenience method is for internal use by the Workbench only and
0809: * must not be called outside the Workbench.
0810: *
0811: * @param clazz
0812: * The calling class.
0813: * @param methodName
0814: * The calling method name.
0815: * @param t
0816: * The throwable from where the problem actually occurred.
0817: */
0818: public static void log(Class clazz, String methodName, Throwable t) {
0819: String msg = MessageFormat.format("Exception in {0}.{1}: {2}", //$NON-NLS-1$
0820: new Object[] { clazz.getName(), methodName, t });
0821: log(msg, t);
0822: }
0823:
0824: /**
0825: * Logs the given message and status to the platform log.
0826: *
0827: * This convenience method is for internal use by the Workbench only and
0828: * must not be called outside the Workbench.
0829: *
0830: * @param message
0831: * A high level UI message describing when the problem happened.
0832: * May be <code>null</code>.
0833: * @param status
0834: * The status describing the problem. Must not be null.
0835: */
0836: public static void log(String message, IStatus status) {
0837:
0838: //1FTUHE0: ITPCORE:ALL - API - Status & logging - loss of semantic info
0839:
0840: if (message != null) {
0841: getDefault().getLog().log(
0842: StatusUtil.newStatus(IStatus.ERROR, message, null));
0843: }
0844:
0845: getDefault().getLog().log(status);
0846: }
0847:
0848: /**
0849: * Log the status to the default log.
0850: * @param status
0851: */
0852: public static void log(IStatus status) {
0853: getDefault().getLog().log(status);
0854: }
0855:
0856: /**
0857: * Get the decorator manager for the receiver
0858: * @return DecoratorManager the decorator manager
0859: * for the receiver.
0860: */
0861: public DecoratorManager getDecoratorManager() {
0862: if (this .decoratorManager == null) {
0863: this .decoratorManager = new DecoratorManager();
0864: }
0865: return decoratorManager;
0866: }
0867:
0868: /*
0869: * (non-Javadoc)
0870: * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
0871: */
0872: public void start(BundleContext context) throws Exception {
0873: context.addBundleListener(getBundleListener());
0874: super .start(context);
0875: bundleContext = context;
0876:
0877: JFaceUtil.initializeJFace();
0878:
0879: Window.setDefaultOrientation(getDefaultOrientation());
0880:
0881: // The UI plugin needs to be initialized so that it can install the callback in PrefUtil,
0882: // which needs to be done as early as possible, before the workbench
0883: // accesses any API preferences.
0884: Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
0885: try {
0886: // Attempt to load the activator of the ui bundle. This will force lazy start
0887: // of the ui bundle. Using the bundle activator class here because it is a
0888: // class that needs to be loaded anyway so it should not cause extra classes
0889: // to be loaded.
0890: if (uiBundle != null)
0891: uiBundle.loadClass(UI_BUNDLE_ACTIVATOR);
0892: } catch (ClassNotFoundException e) {
0893: WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$
0894: }
0895: /*
0896: * DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are
0897: * likely to cause a deadlock in class loader code. Please see Bug 86450
0898: * for more information.
0899: */
0900:
0901: }
0902:
0903: /**
0904: * Get the default orientation from the command line
0905: * arguments. If there are no arguments imply the
0906: * orientation.
0907: * @return int
0908: * @see SWT#NONE
0909: * @see SWT#RIGHT_TO_LEFT
0910: * @see SWT#LEFT_TO_RIGHT
0911: */
0912: private int getDefaultOrientation() {
0913:
0914: String[] commandLineArgs = Platform.getCommandLineArgs();
0915:
0916: int orientation = getCommandLineOrientation(commandLineArgs);
0917:
0918: if (orientation != SWT.NONE) {
0919: return orientation;
0920: }
0921:
0922: orientation = getSystemPropertyOrientation();
0923:
0924: if (orientation != SWT.NONE) {
0925: return orientation;
0926: }
0927:
0928: return checkCommandLineLocale(); //Use the default value if there is nothing specified
0929: }
0930:
0931: /**
0932: * Check to see if the command line parameter for -nl
0933: * has been set. If so imply the orientation from this
0934: * specified Locale. If it is a bidirectional Locale
0935: * return SWT#RIGHT_TO_LEFT.
0936: * If it has not been set or has been set to
0937: * a unidirectional Locale then return SWT#NONE.
0938: *
0939: * Locale is determined differently by different JDKs
0940: * and may not be consistent with the users expectations.
0941: *
0942:
0943: * @return int
0944: * @see SWT#NONE
0945: * @see SWT#RIGHT_TO_LEFT
0946: */
0947: private int checkCommandLineLocale() {
0948:
0949: //Check if the user property is set. If not do not
0950: //rely on the vm.
0951: if (System.getProperty(NL_USER_PROPERTY) == null) {
0952: return SWT.NONE;
0953: }
0954:
0955: Locale locale = Locale.getDefault();
0956: String lang = locale.getLanguage();
0957:
0958: if ("iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
0959: "fa".equals(lang) || "ur".equals(lang)) { //$NON-NLS-1$ //$NON-NLS-2$
0960: return SWT.RIGHT_TO_LEFT;
0961: }
0962:
0963: return SWT.NONE;
0964: }
0965:
0966: /**
0967: * Check to see if the orientation was set in the
0968: * system properties. If there is no orientation
0969: * specified return SWT#NONE.
0970: * @return int
0971: * @see SWT#NONE
0972: * @see SWT#RIGHT_TO_LEFT
0973: * @see SWT#LEFT_TO_RIGHT
0974: */
0975: private int getSystemPropertyOrientation() {
0976: String orientation = System.getProperty(ORIENTATION_PROPERTY);
0977: if (RIGHT_TO_LEFT.equals(orientation)) {
0978: return SWT.RIGHT_TO_LEFT;
0979: }
0980: if (LEFT_TO_RIGHT.equals(orientation)) {
0981: return SWT.LEFT_TO_RIGHT;
0982: }
0983: return SWT.NONE;
0984: }
0985:
0986: /**
0987: * Find the orientation in the commandLineArgs. If there
0988: * is no orientation specified return SWT#NONE.
0989: * @param commandLineArgs
0990: * @return int
0991: * @see SWT#NONE
0992: * @see SWT#RIGHT_TO_LEFT
0993: * @see SWT#LEFT_TO_RIGHT
0994: */
0995: private int getCommandLineOrientation(String[] commandLineArgs) {
0996: //Do not process the last one as it will never have a parameter
0997: for (int i = 0; i < commandLineArgs.length - 1; i++) {
0998: if (commandLineArgs[i]
0999: .equalsIgnoreCase(ORIENTATION_COMMAND_LINE)) {
1000: String orientation = commandLineArgs[i + 1];
1001: if (orientation.equals(RIGHT_TO_LEFT)) {
1002: System.setProperty(ORIENTATION_PROPERTY,
1003: RIGHT_TO_LEFT);
1004: return SWT.RIGHT_TO_LEFT;
1005: }
1006: if (orientation.equals(LEFT_TO_RIGHT)) {
1007: System.setProperty(ORIENTATION_PROPERTY,
1008: LEFT_TO_RIGHT);
1009: return SWT.LEFT_TO_RIGHT;
1010: }
1011: }
1012: }
1013:
1014: return SWT.NONE;
1015: }
1016:
1017: /**
1018: * Return an array of all bundles contained in this workbench.
1019: *
1020: * @return an array of bundles in the workbench or an empty array if none
1021: * @since 3.0
1022: */
1023: public Bundle[] getBundles() {
1024: return bundleContext == null ? new Bundle[0] : bundleContext
1025: .getBundles();
1026: }
1027:
1028: /**
1029: * Returns the bundle context associated with the workbench plug-in.
1030: *
1031: * @return the bundle context
1032: * @since 3.1
1033: */
1034: public BundleContext getBundleContext() {
1035: return bundleContext;
1036: }
1037:
1038: /**
1039: * Returns the application name.
1040: * <p>
1041: * Note this is never shown to the user.
1042: * It is used to initialize the SWT Display.
1043: * On Motif, for example, this can be used
1044: * to set the name used for resource lookup.
1045: * </p>
1046: *
1047: * @return the application name, or <code>null</code>
1048: * @see org.eclipse.swt.widgets.Display#setAppName
1049: * @since 3.0
1050: */
1051: public String getAppName() {
1052: return getProductInfo().getAppName();
1053: }
1054:
1055: /**
1056: * Returns the name of the product.
1057: *
1058: * @return the product name, or <code>null</code> if none
1059: * @since 3.0
1060: */
1061: public String getProductName() {
1062: return getProductInfo().getProductName();
1063: }
1064:
1065: /**
1066: * Returns the image descriptors for the window image to use for this product.
1067: *
1068: * @return an array of the image descriptors for the window image, or
1069: * <code>null</code> if none
1070: * @since 3.0
1071: */
1072: public ImageDescriptor[] getWindowImages() {
1073: return getProductInfo().getWindowImages();
1074: }
1075:
1076: /**
1077: * Returns an instance that describes this plugin's product (formerly "primary
1078: * plugin").
1079: * @return ProductInfo the product info for the receiver
1080: */
1081: private ProductInfo getProductInfo() {
1082: if (productInfo == null) {
1083: productInfo = new ProductInfo(Platform.getProduct());
1084: }
1085: return productInfo;
1086: }
1087:
1088: /* (non-Javadoc)
1089: * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
1090: */
1091: public void stop(BundleContext context) throws Exception {
1092: if (bundleListener != null) {
1093: context.removeBundleListener(bundleListener);
1094: bundleListener = null;
1095: }
1096: // TODO normally super.stop(*) would be the last statement in this
1097: // method
1098: super .stop(context);
1099: if (workingSetManager != null) {
1100: workingSetManager.dispose();
1101: workingSetManager = null;
1102: }
1103: SWTResourceUtil.shutdown();
1104: }
1105:
1106: /**
1107: * Return the new wizard registry.
1108: *
1109: * @return the new wizard registry
1110: * @since 3.1
1111: */
1112: public IWizardRegistry getNewWizardRegistry() {
1113: return NewWizardRegistry.getInstance();
1114: }
1115:
1116: /**
1117: * Return the import wizard registry.
1118: *
1119: * @return the import wizard registry
1120: * @since 3.1
1121: */
1122: public IWizardRegistry getImportWizardRegistry() {
1123: return ImportWizardRegistry.getInstance();
1124: }
1125:
1126: /**
1127: * Return the export wizard registry.
1128: *
1129: * @return the export wizard registry
1130: * @since 3.1
1131: */
1132: public IWizardRegistry getExportWizardRegistry() {
1133: return ExportWizardRegistry.getInstance();
1134: }
1135:
1136: /**
1137: * FOR INTERNAL WORKBENCH USE ONLY.
1138: *
1139: * Returns the path to a location in the file system that can be used
1140: * to persist/restore state between workbench invocations.
1141: * If the location did not exist prior to this call it will be created.
1142: * Returns <code>null</code> if no such location is available.
1143: *
1144: * @return path to a location in the file system where this plug-in can
1145: * persist data between sessions, or <code>null</code> if no such
1146: * location is available.
1147: * @since 3.1
1148: */
1149: public IPath getDataLocation() {
1150: try {
1151: return getStateLocation();
1152: } catch (IllegalStateException e) {
1153: // This occurs if -data=@none is explicitly specified, so ignore this silently.
1154: // Is this OK? See bug 85071.
1155: return null;
1156: }
1157: }
1158:
1159: /* package */void addBundleListener(BundleListener bundleListener) {
1160: bundleContext.addBundleListener(bundleListener);
1161: }
1162:
1163: /* package */void removeBundleListener(
1164: BundleListener bundleListener) {
1165: bundleContext.removeBundleListener(bundleListener);
1166: }
1167:
1168: /* package */int getBundleCount() {
1169: return bundleContext.getBundles().length;
1170: }
1171:
1172: /* package */OutputStream getSplashStream() {
1173: // assumes the output stream is available as a service
1174: // see EclipseStarter.publishSplashScreen
1175: ServiceReference[] ref;
1176: try {
1177: ref = bundleContext.getServiceReferences(OutputStream.class
1178: .getName(), null);
1179: } catch (InvalidSyntaxException e) {
1180: return null;
1181: }
1182: if (ref == null) {
1183: return null;
1184: }
1185: for (int i = 0; i < ref.length; i++) {
1186: String name = (String) ref[i].getProperty("name"); //$NON-NLS-1$
1187: if (name != null && name.equals("splashstream")) { //$NON-NLS-1$
1188: Object result = bundleContext.getService(ref[i]);
1189: bundleContext.ungetService(ref[i]);
1190: return (OutputStream) result;
1191: }
1192: }
1193: return null;
1194: }
1195:
1196: /**
1197: * @return
1198: */
1199: private BundleListener getBundleListener() {
1200: if (bundleListener == null) {
1201: bundleListener = new SynchronousBundleListener() {
1202: public void bundleChanged(BundleEvent event) {
1203: WorkbenchPlugin.this .bundleChanged(event);
1204: }
1205: };
1206: }
1207: return bundleListener;
1208: }
1209:
1210: private void bundleChanged(BundleEvent event) {
1211: // a bundle in the STARTING state generates 2 events, LAZY_ACTIVATION
1212: // when it enters STARTING and STARTING when it exists STARTING :-)
1213: synchronized (startingBundles) {
1214: switch (event.getType()) {
1215: case BundleEvent.STARTING:
1216: startingBundles.add(event.getBundle());
1217: break;
1218: case BundleEvent.STARTED:
1219: case BundleEvent.STOPPED:
1220: startingBundles.remove(event.getBundle());
1221: break;
1222: default:
1223: break;
1224: }
1225: }
1226: }
1227:
1228: public boolean isStarting(Bundle bundle) {
1229: synchronized (startingBundles) {
1230: return startingBundles.contains(bundle);
1231: }
1232: }
1233:
1234: }
|