org.eclipse.team.internal.ui.TeamUIPlugin.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.team.internal.ui.TeamUIPlugin.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2014 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.team.internal.ui;

import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.RepositoryProviderType;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.internal.ui.mapping.StreamMergerDelegate;
import org.eclipse.team.internal.ui.mapping.WorkspaceTeamStateProvider;
import org.eclipse.team.internal.ui.synchronize.SynchronizeManager;
import org.eclipse.team.internal.ui.synchronize.TeamSynchronizingPerspective;
import org.eclipse.team.internal.ui.synchronize.actions.GlobalRefreshAction;
import org.eclipse.team.ui.ISharedImages;
import org.eclipse.team.ui.mapping.ITeamStateProvider;
import org.eclipse.team.ui.synchronize.*;
import org.eclipse.ui.*;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.*;

/**
 * TeamUIPlugin is the plugin for generic, non-provider specific,
 * team UI functionality in the workbench.
 */
public class TeamUIPlugin extends AbstractUIPlugin {

    private static TeamUIPlugin instance;

    // image paths
    public static final String ICON_PATH = "$nl$/icons/full/"; //$NON-NLS-1$

    public static final String ID = "org.eclipse.team.ui"; //$NON-NLS-1$

    // plugin id
    public static final String PLUGIN_ID = "org.eclipse.team.ui"; //$NON-NLS-1$

    public static final String TRIGGER_POINT_ID = "org.eclipse.team.ui.activityTriggerPoint"; //$NON-NLS-1$

    private static List propertyChangeListeners = new ArrayList(5);

    private Hashtable imageDescriptors = new Hashtable(20);

    private WorkspaceTeamStateProvider provider;

    private Map decoratedStateProviders = new HashMap();

    // manages synchronize participants
    private SynchronizeManager synchronizeManager;

    private ServiceRegistration debugRegistration;

    /**
     * ID of the 'Remove from View' action.
     * Value: <code>"org.eclipse.team.internal.ui.RemoveFromView"</code>
     */
    public static final String REMOVE_FROM_VIEW_ACTION_ID = "org.eclipse.team.internal.ui.RemoveFromView"; //$NON-NLS-1$

    /**
     * Creates a new TeamUIPlugin.
     */
    public TeamUIPlugin() {
        super();
        instance = 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 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 bundle = Platform.getBundle(element.getNamespaceIdentifier());
        if (bundle.getState() == org.osgi.framework.Bundle.ACTIVE) {
            return element.createExecutableExtension(classAttribute);
        } else {
            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];
            else
                return ret[0];
        }
    }

    /**
     * Convenience method to get the currently active workbench page. Note that
     * the active page may not be the one that the usr perceives as active in
     * some situations so this method of obtaining the activae page should only
     * be used if no other method is available.
     * 
     * @return the active workbench page
     */
    public static IWorkbenchPage getActivePage() {
        IWorkbenchWindow window = getPlugin().getWorkbench().getActiveWorkbenchWindow();
        if (window == null)
            return null;
        return window.getActivePage();
    }

    /**
     * Return the default instance of the receiver. This represents the runtime plugin.
     * 
     * @return the singleton plugin instance
     */
    public static TeamUIPlugin getPlugin() {
        return instance;
    }

    /**
     * Initializes the preferences for this plugin if necessary.
     */
    protected void initializeDefaultPluginPreferences() {
        IPreferenceStore store = getPreferenceStore();
        store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL, false);
        store.setDefault(IPreferenceIds.SHOW_AUTHOR_IN_COMPARE_EDITOR, false);
        store.setDefault(IPreferenceIds.MAKE_FILE_WRITTABLE_IF_CONTEXT_MISSING, false);
        store.setDefault(IPreferenceIds.REUSE_OPEN_COMPARE_EDITOR, true);
        store.setDefault(IPreferenceIds.RUN_IMPORT_IN_BACKGROUND, false);
        store.setDefault(IPreferenceIds.APPLY_PATCH_IN_SYNCHRONIZE_VIEW, false);
        store.setDefault(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS, true);
        store.setDefault(IPreferenceIds.SYNCVIEW_DEFAULT_LAYOUT, IPreferenceIds.COMPRESSED_LAYOUT);
        store.setDefault(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE, TeamSynchronizingPerspective.ID);
        store.setDefault(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT,
                GlobalRefreshAction.NO_DEFAULT_PARTICPANT);
        store.setDefault(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT_SEC_ID,
                GlobalRefreshAction.NO_DEFAULT_PARTICPANT);
        store.setDefault(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE, MessageDialogWithToggle.PROMPT);
        store.setDefault(IPreferenceIds.SYNCVIEW_REMOVE_FROM_VIEW_NO_PROMPT, false);
        store.setDefault(IPreferenceIds.PREF_WORKSPACE_FIRST_TIME, true);

        // Convert the old compressed folder preference to the new layout preference
        if (!store.isDefault(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS)
                && !store.getBoolean(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS)) {
            // Set the compress folder preference to the default true) \
            // so will will ignore it in the future
            store.setToDefault(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS);
            // Set the layout to tree (which was used when compress folder was false)
            store.setDefault(IPreferenceIds.SYNCVIEW_DEFAULT_LAYOUT, IPreferenceIds.TREE_LAYOUT);
        }
    }

    /**
     * Convenience method for logging statuses to the plugin log
     * 
     * @param status  the status to log
     */
    public static void log(IStatus status) {
        getPlugin().getLog().log(status);
    }

    /**
     * Convenience method for logging a TeamException in such a way that the
     * stacktrace is logged as well.
     * @param e
     */
    public static void log(CoreException e) {
        IStatus status = e.getStatus();
        log(status.getSeverity(), status.getMessage(), e);
    }

    /**
     * Log the given exception along with the provided message and severity
     * indicator
     * 
     * @param severity
     *            the severity
     * @param message
     *            a human-readable message, localized to the current locale
     * @param e
     *            a low-level exception, or <code>null</code> if not applicable
     */
    public static void log(int severity, String message, Throwable e) {
        log(new Status(severity, ID, 0, message, e));
    }

    /**
     * @see Plugin#start(BundleContext)
     */
    public void start(BundleContext context) throws Exception {
        super.start(context);

        // register debug options listener
        Hashtable properties = new Hashtable(2);
        properties.put(DebugOptions.LISTENER_SYMBOLICNAME, ID);
        debugRegistration = context.registerService(DebugOptionsListener.class, Policy.DEBUG_OPTIONS_LISTENER,
                properties);

        initializeImages(this);

        // This is a backwards compatibility check to ensure that repository
        // provider capability are enabled automatically if an old workspace is
        // opened for the first time and contains projects shared with a disabled
        // capability. We defer the actual processing of the projects to another
        // job since it is not critical to the startup of the team ui plugin.
        IPreferenceStore store = getPreferenceStore();
        if (store.getBoolean(IPreferenceIds.PREF_WORKSPACE_FIRST_TIME)) {
            Job capabilityInitializer = new Job("") { //$NON-NLS-1$
                protected IStatus run(IProgressMonitor monitor) {
                    TeamCapabilityHelper.getInstance();
                    getPreferenceStore().setValue(IPreferenceIds.PREF_WORKSPACE_FIRST_TIME, false);
                    return Status.OK_STATUS;
                }

                public boolean shouldRun() {
                    // Only initialize the capability helper if the UI is running (bug 76348)
                    return PlatformUI.isWorkbenchRunning();
                }
            };
            capabilityInitializer.setSystem(true);
            capabilityInitializer.setPriority(Job.DECORATE);
            capabilityInitializer.schedule(1000);
        }

        StreamMergerDelegate.start();
    }

    /* (non-Javadoc)
     * @see Plugin#stop(BundleContext)
     */
    public void stop(BundleContext context) throws Exception {
        try {
            // unregister debug options listener
            debugRegistration.unregister();
            debugRegistration = null;

            if (synchronizeManager != null)
                synchronizeManager.dispose();
        } finally {
            super.stop(context);
        }
        if (provider != null) {
            provider.dispose();
        }
        for (Iterator iter = decoratedStateProviders.values().iterator(); iter.hasNext();) {
            SubscriberTeamStateProvider sdsp = (SubscriberTeamStateProvider) iter.next();
            sdsp.dispose();
        }
    }

    /**
     * Register for changes made to Team properties.
     * @param listener the listener to register
     */
    public static void addPropertyChangeListener(IPropertyChangeListener listener) {
        propertyChangeListeners.add(listener);
    }

    /**
     * Deregister as a Team property changes.
     * @param listener the listener to remove
     */
    public static void removePropertyChangeListener(IPropertyChangeListener listener) {
        propertyChangeListeners.remove(listener);
    }

    /**
     * Broadcast a Team property change.
     * @param event the property change event object
     */
    public static void broadcastPropertyChange(PropertyChangeEvent event) {
        for (Iterator it = propertyChangeListeners.iterator(); it.hasNext();) {
            IPropertyChangeListener listener = (IPropertyChangeListener) it.next();
            listener.propertyChange(event);
        }
    }

    /**
     * Creates an image and places it in the image registry.
     * 
     * @param id  the identifier for the image
     * @param baseURL  the base URL for the image
     */
    private static void createImageDescriptor(TeamUIPlugin plugin, String id) {
        // Delegate to the plugin instance to avoid concurrent class loading problems
        plugin.privateCreateImageDescriptor(id);
    }

    private void privateCreateImageDescriptor(String id) {
        ImageDescriptor desc = ImageDescriptor.createFromURL(getImageUrl(id));
        imageDescriptors.put(id, desc);
    }

    /**
     * Returns the image descriptor for the given image ID.
     * Returns null if there is no such image.
     * 
     * @param id  the identifier for the image to retrieve
     * @return the image associated with the given ID
     */
    public static ImageDescriptor getImageDescriptor(String id) {
        // Delegate to the plugin instance to avoid concurrent class loading problems
        return getPlugin().privateGetImageDescriptor(id);
    }

    private ImageDescriptor privateGetImageDescriptor(String id) {
        if (!imageDescriptors.containsKey(id)) {
            createImageDescriptor(getPlugin(), id);
        }
        return (ImageDescriptor) imageDescriptors.get(id);
    }

    /**
     * Convenience method to get an image descriptor for an extension
     * 
     * @param extension  the extension declaring the image
     * @param subdirectoryAndFilename  the path to the image
     * @return the image
     */
    public static ImageDescriptor getImageDescriptorFromExtension(IExtension extension,
            String subdirectoryAndFilename) {
        URL fullPathString = FileLocator.find(Platform.getBundle(extension.getNamespaceIdentifier()),
                new Path(subdirectoryAndFilename), null);
        return ImageDescriptor.createFromURL(fullPathString);
    }

    /*
     * Initializes the table of images used in this plugin. The plugin is
     * provided because this method is called before the plugin staic
     * variable has been set. See the comment on the getPlugin() method
     * for a description of why this is required. 
     */
    private void initializeImages(TeamUIPlugin plugin) {
        // Overlays
        createImageDescriptor(plugin, ISharedImages.IMG_DIRTY_OVR);
        createImageDescriptor(plugin, ISharedImages.IMG_CONFLICT_OVR);
        createImageDescriptor(plugin, ISharedImages.IMG_CHECKEDIN_OVR);
        createImageDescriptor(plugin, ISharedImages.IMG_CHECKEDOUT_OVR);
        createImageDescriptor(plugin, ISharedImages.IMG_ERROR_OVR);
        createImageDescriptor(plugin, ISharedImages.IMG_WARNING_OVR);
        createImageDescriptor(plugin, ISharedImages.IMG_HOURGLASS_OVR);

        // Target Management Icons
        createImageDescriptor(plugin, ITeamUIImages.IMG_SITE_ELEMENT);

        // Sync View Icons
        createImageDescriptor(plugin, ITeamUIImages.IMG_DLG_SYNC_INCOMING);
        createImageDescriptor(plugin, ITeamUIImages.IMG_DLG_SYNC_OUTGOING);
        createImageDescriptor(plugin, ITeamUIImages.IMG_DLG_SYNC_CONFLICTING);
        createImageDescriptor(plugin, ITeamUIImages.IMG_REFRESH);
        createImageDescriptor(plugin, ITeamUIImages.IMG_CHANGE_FILTER);
        createImageDescriptor(plugin, ITeamUIImages.IMG_IGNORE_WHITESPACE);
        createImageDescriptor(plugin, ITeamUIImages.IMG_COLLAPSE_ALL);
        createImageDescriptor(plugin, ITeamUIImages.IMG_COLLAPSE_ALL_ENABLED);

        createImageDescriptor(plugin, ITeamUIImages.IMG_DLG_SYNC_INCOMING_DISABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_DLG_SYNC_OUTGOING_DISABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_DLG_SYNC_CONFLICTING_DISABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_REFRESH_DISABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_IGNORE_WHITESPACE_DISABLED);

        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_CATCHUP);
        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_RELEASE);
        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_FREE);

        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_CATCHUP_DISABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_RELEASE_DISABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_FREE_DISABLED);

        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_CATCHUP_ENABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_RELEASE_ENABLED);
        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_MODE_FREE_ENABLED);

        // Wizard banners
        createImageDescriptor(plugin, ITeamUIImages.IMG_PROJECTSET_IMPORT_BANNER);
        createImageDescriptor(plugin, ITeamUIImages.IMG_PROJECTSET_EXPORT_BANNER);
        createImageDescriptor(plugin, ITeamUIImages.IMG_WIZBAN_SHARE);

        // Live Sync View icons
        createImageDescriptor(plugin, ITeamUIImages.IMG_COMPRESSED_FOLDER);
        createImageDescriptor(plugin, ITeamUIImages.IMG_SYNC_VIEW);
        createImageDescriptor(plugin, ITeamUIImages.IMG_HIERARCHICAL);

        // Local History Page
        createImageDescriptor(plugin, ITeamUIImages.IMG_DATES_CATEGORY);
        createImageDescriptor(plugin, ITeamUIImages.IMG_COMPARE_VIEW);
        createImageDescriptor(plugin, ITeamUIImages.IMG_LOCALREVISION_TABLE);
    }

    private URL getImageUrl(String relative) {
        return FileLocator.find(Platform.getBundle(PLUGIN_ID), new Path(ICON_PATH + relative), null);
    }

    /**
     * Returns the standard display to be used. The method first checks, if the
     * thread calling this method has an associated display. If so, this display
     * is returned. Otherwise the method returns the display for this workbench.
     * 
     * @return the standard display to be used
     */
    public static Display getStandardDisplay() {
        Display display = Display.getCurrent();
        if (display == null) {
            display = PlatformUI.getWorkbench().getDisplay();
        }
        return display;
    }

    public Image getImage(String key) {
        Image image = getImageRegistry().get(key);
        if (image == null) {
            ImageDescriptor d = getImageDescriptor(key);
            image = d.createImage();
            getImageRegistry().put(key, image);
        }
        return image;
    }

    public static void run(IRunnableWithProgress runnable) {
        try {
            PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(true, true, runnable);
        } catch (InvocationTargetException e) {
            Utils.handleError(getStandardDisplay().getActiveShell(), e, null, null);
        } catch (InterruptedException e2) {
            // Nothing to be done
        }
    }

    public org.osgi.service.prefs.Preferences getInstancePreferences() {
        return InstanceScope.INSTANCE.getNode(getBundle().getSymbolicName());
    }

    public synchronized TeamStateProvider getDecoratedStateProvider(RepositoryProviderType rpt) {
        TeamStateProvider provider = (TeamStateProvider) decoratedStateProviders.get(rpt.getID());
        if (provider != null)
            return provider;
        Subscriber subscriber = rpt.getSubscriber();
        if (subscriber != null) {
            provider = new SubscriberTeamStateProvider(subscriber);
            decoratedStateProviders.put(rpt.getID(), provider);
            return provider;
        }
        return null;
    }

    /**
     * Return a decorated state provider that delegates to the appropriate team 
     * provider.
     * @return a decorated state provider that delegates to the appropriate team 
     * provider
     */
    public synchronized ITeamStateProvider getDecoratedStateProvider() {
        if (provider == null)
            provider = new WorkspaceTeamStateProvider();
        return provider;
    }

    public ISynchronizeManager getSynchronizeManager() {
        if (synchronizeManager == null) {
            synchronizeManager = new SynchronizeManager();
        }
        return synchronizeManager;
    }
}