/******************************************************************************* * Copyright (c) 2000, 2016 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 * Patrik Suzzi <psuzzi@gmail.com> - Bug 489250 *******************************************************************************/ package org.eclipse.ui.internal.ide; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IBundleGroup; import org.eclipse.core.runtime.IBundleGroupProvider; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.ide.registry.MarkerImageProviderRegistry; import org.eclipse.ui.internal.ide.registry.ProjectImageRegistry; import org.eclipse.ui.internal.ide.registry.UnassociatedEditorStrategyRegistry; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import com.ibm.icu.text.MessageFormat; /** * This internal class represents the top of the IDE workbench. * * This class is responsible for tracking various registries * font, preference, graphics, dialog store. * * This class is explicitly referenced by the * IDE workbench plug-in's "plugin.xml" * * @since 3.0 */ public class IDEWorkbenchPlugin extends AbstractUIPlugin { // Default instance of the receiver private static IDEWorkbenchPlugin inst; /** * The IDE workbench plugin ID. */ public static final String IDE_WORKBENCH = "org.eclipse.ui.ide"; //$NON-NLS-1$ /** * The ID of the default text editor. * This must correspond to EditorsUI.DEFAULT_TEXT_EDITOR_ID. */ public static final String DEFAULT_TEXT_EDITOR_ID = "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$ // IDE workbench extension point names public static final String PL_MARKER_IMAGE_PROVIDER = "markerImageProviders"; //$NON-NLS-1$ public static final String PL_MARKER_HELP = "markerHelp"; //$NON-NLS-1$ public static final String PL_MARKER_RESOLUTION = "markerResolution"; //$NON-NLS-1$ public static final String PL_PROJECT_NATURE_IMAGES = "projectNatureImages"; //$NON-NLS-1$ private final static String ICONS_PATH = "$nl$/icons/full/";//$NON-NLS-1$ private static final int PROBLEMS_VIEW_CREATION_DELAY= 6000; /** * Project image registry; lazily initialized. */ private ProjectImageRegistry projectImageRegistry = null; /** * Marker image registry; lazily initialized. */ private MarkerImageProviderRegistry markerImageProviderRegistry = null; /** * Unassociated file/editor strategy registry; lazily initialized */ private UnassociatedEditorStrategyRegistry unassociatedEditorStrategyRegistry = null; private ResourceManager resourceManager; /** * Create an instance of the receiver. */ public IDEWorkbenchPlugin() { super(); inst = this; } /** * 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 Object the extension object * @throws CoreException */ public static Object createExtension(final IConfigurationElement element, final String classAttribute) throws CoreException { // If plugin has been loaded create extension. // Otherwise, show busy cursor then create extension. Bundle plugin = Platform.getBundle(element.getNamespace()); if (plugin.getState() == Bundle.ACTIVE) { return element.createExecutableExtension(classAttribute); } final Object[] ret = new Object[1]; final CoreException[] exc = new CoreException[1]; BusyIndicator.showWhile(null, () -> { try { ret[0] = element.createExecutableExtension(classAttribute); } catch (CoreException e) { exc[0] = e; } }); if (exc[0] != null) { throw exc[0]; } return ret[0]; } /* Return the default instance of the receiver. This represents the runtime plugin. * * @see AbstractPlugin for the typical implementation pattern for plugin classes. */ public static IDEWorkbenchPlugin getDefault() { return inst; } /** * Return the workspace used by the workbench * * This method is internal to the workbench and must not be called * by any plugins. */ public static IWorkspace getPluginWorkspace() { return ResourcesPlugin.getWorkspace(); } /** * 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 IDE Workbench only and * must not be called outside the IDE 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)); } /** * 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 IDE Workbench only and * must not be called outside the IDE 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 IDE Workbench only and * must not be called outside the IDE 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$ 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 IDE Workbench only and * must not be called outside the IDE 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); } @Override protected void refreshPluginActions() { // do nothing } /** * Return the manager that maps project nature ids to images. */ public ProjectImageRegistry getProjectImageRegistry() { if (projectImageRegistry == null) { projectImageRegistry = new ProjectImageRegistry(); projectImageRegistry.load(); } return projectImageRegistry; } /** * Returns the marker image provider registry for the workbench. * * @return the marker image provider registry */ public MarkerImageProviderRegistry getMarkerImageProviderRegistry() { if (markerImageProviderRegistry == null) { markerImageProviderRegistry = new MarkerImageProviderRegistry(); } return markerImageProviderRegistry; } /** * Returns the unassociated file/editor strategy registry for the workbench. * * @return the unassociated file/editor strategy registry */ public synchronized UnassociatedEditorStrategyRegistry getUnassociatedEditorStrategyRegistry() { if (unassociatedEditorStrategyRegistry == null) { unassociatedEditorStrategyRegistry = new UnassociatedEditorStrategyRegistry(); } return unassociatedEditorStrategyRegistry; } /** * Returns the about information of all known features, * omitting any features which are missing this information. * * @return a possibly empty list of about infos */ public AboutInfo[] getFeatureInfos() { // cannot be cached since bundle groups come and go List infos = new ArrayList(); // add an entry for each bundle group IBundleGroupProvider[] providers = Platform.getBundleGroupProviders(); if (providers != null) { for (IBundleGroupProvider provider : providers) { for (IBundleGroup bundleGroup : provider.getBundleGroups()) { infos.add(new AboutInfo(bundleGroup)); } } } return (AboutInfo[]) infos.toArray(new AboutInfo[infos.size()]); } /** * Get the workbench image with the given path relative to * ICON_PATH. * @param relativePath * @return ImageDescriptor */ public static ImageDescriptor getIDEImageDescriptor(String relativePath){ return imageDescriptorFromPlugin(IDE_WORKBENCH, ICONS_PATH + relativePath); } /** * Return the resourceManager used by this plug-in. * @return */ public ResourceManager getResourceManager() { if(resourceManager == null){ resourceManager = new LocalResourceManager(JFaceResources.getResources()); } return resourceManager; } @Override public void stop(BundleContext context) throws Exception { super.stop(context); if (resourceManager != null) resourceManager.dispose(); } @Override public void start(BundleContext context) throws Exception { super.start(context); createProblemsViews(); } /** * Create (but don't activate) the Problems views so that the view's tooltip and icon are * up-to-date. */ private void createProblemsViews() { final Runnable r= new Runnable() { @Override public void run() { IWorkbench workbench = PlatformUI.isWorkbenchRunning() ? PlatformUI.getWorkbench() : null; if (workbench != null && (workbench.getDisplay().isDisposed() || workbench.isClosing())) return; if (workbench == null || workbench.isStarting()) { Display.getCurrent().timerExec(PROBLEMS_VIEW_CREATION_DELAY, this); return; } // We can't access preferences store before scheduling the job // because this would cause instance area to be initialized // before user selected the workspace location. // See bug 514297 and // org.eclipse.core.internal.runtime.DataArea.assertLocationInitialized() if (!getDefault().getPreferenceStore() .getBoolean(IDEInternalPreferences.SHOW_PROBLEMS_VIEW_DECORATIONS_ON_STARTUP)) { return; } for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) { IWorkbenchPage activePage= window.getActivePage(); if (activePage == null) continue; for (IViewReference viewReference : activePage.getViewReferences()) { if (IPageLayout.ID_PROBLEM_VIEW.equals(viewReference.getId())) try { activePage.showView(viewReference.getId(), viewReference.getSecondaryId(), IWorkbenchPage.VIEW_CREATE); } catch (PartInitException e) { log("Could not create Problems view", e.getStatus()); //$NON-NLS-1$ } } } } }; Display display = Display.getCurrent(); if (display != null) { display.timerExec(PROBLEMS_VIEW_CREATION_DELAY, r); } else { Job job = new Job("Initializing Problems view") { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench == null) { // Workbench not created yet, so avoid using display to // avoid crash like in bug 513901 schedule(PROBLEMS_VIEW_CREATION_DELAY); return Status.OK_STATUS; } if (workbench != null && workbench.isClosing()) { return Status.CANCEL_STATUS; } PlatformUI.getWorkbench().getDisplay().asyncExec(r); return Status.OK_STATUS; } }; job.setSystem(true); job.setUser(false); job.schedule(PROBLEMS_VIEW_CREATION_DELAY); } } }