com.aptana.ide.ui.io.IOUIPlugin.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.ide.ui.io.IOUIPlugin.java

Source

/**
 * Aptana Studio
 * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
 * Please see the license.html included with this distribution for details.
 * Any modifications to this file must keep this entire header intact.
 */
// $codepro.audit.disable declaredExceptions
// $codepro.audit.disable staticFieldNamingConvention
// $codepro.audit.disable unnecessaryExceptions
// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.enforceTheSingletonPropertyWithAPrivateConstructor

package com.aptana.ide.ui.io;

import java.io.File;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.OpenResourceAction;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.navigator.CommonViewer;
import org.eclipse.ui.navigator.resources.ProjectExplorer;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

import com.aptana.core.io.efs.SyncUtils;
import com.aptana.core.logging.IdeLog;
import com.aptana.core.util.EclipseUtil;
import com.aptana.ide.core.io.ConnectionPointType;
import com.aptana.ide.core.io.CoreIOPlugin;
import com.aptana.ide.core.io.IConnectionPoint;
import com.aptana.ide.core.io.IConnectionPointCategory;
import com.aptana.ide.core.io.IConnectionPointManager;
import com.aptana.ide.core.io.events.ConnectionPointEvent;
import com.aptana.ide.core.io.events.IConnectionPointListener;
import com.aptana.ide.ui.io.internal.UniformFileStoreEditorInput;
import com.aptana.ide.ui.io.navigator.FileSystemElementComparer;
import com.aptana.ide.ui.io.navigator.RemoteNavigatorView;
import com.aptana.ide.ui.io.navigator.actions.Messages;
import com.aptana.theme.IThemeManager;
import com.aptana.theme.ThemePlugin;
import com.aptana.ui.util.UIUtils;

/**
 * The activator class controls the plug-in life cycle
 */
public class IOUIPlugin extends AbstractUIPlugin {

    // The plug-in ID
    public static final String PLUGIN_ID = "com.aptana.ui.io"; //$NON-NLS-1$

    // The shared instance
    private static IOUIPlugin plugin;

    private Map<IEditorInput, Job> saveRemoteJobs;

    private IConnectionPointListener connectionListener;

    private IPreferenceChangeListener themeChangeListener;

    private final IPartListener fPartListener = new IPartListener() {

        public void partActivated(IWorkbenchPart part) {
        }

        public void partBroughtToTop(IWorkbenchPart part) {
        }

        public void partClosed(IWorkbenchPart part) {
        }

        public void partDeactivated(IWorkbenchPart part) {
        }

        public void partOpened(IWorkbenchPart part) {
            if (part instanceof ProjectExplorer) {
                handleProjectExplorerListeners(part);
            } else if (part instanceof IEditorPart) {
                attachSaveListener((IEditorPart) part);
            }
        }
    };

    private void handleProjectExplorerListeners(final IWorkbenchPart part) {
        CommonViewer viewer = ((ProjectExplorer) part).getCommonViewer();
        viewer.setComparer(new FileSystemElementComparer());
        final Tree tree = viewer.getTree();
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                Object element = selection.getFirstElement();

                if (selection.size() == 1 && (element instanceof IResource)
                        && ((IResource) element).getType() == IResource.PROJECT) {
                    OpenResourceAction openResourceAction = new OpenResourceAction(
                            PlatformUI.getWorkbench().getActiveWorkbenchWindow());
                    openResourceAction.selectionChanged((IStructuredSelection) event.getViewer().getSelection());
                    if (openResourceAction.isEnabled()) {
                        openResourceAction.run();
                    }
                }

            }
        });
        tree.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseDown(MouseEvent e) {
                if (tree.getItem(new Point(e.x, e.y)) == null) {
                    tree.deselectAll();
                    tree.notifyListeners(SWT.Selection, new Event());
                }
            }
        });
    }

    private final IWindowListener fWindowListener = new IWindowListener() {

        public void windowActivated(IWorkbenchWindow window) {
        }

        public void windowClosed(IWorkbenchWindow window) {
            IPartService partService = window.getPartService();
            if (partService != null) {
                partService.removePartListener(fPartListener);
            }
        }

        public void windowDeactivated(IWorkbenchWindow window) {
        }

        public void windowOpened(IWorkbenchWindow window) {
            IPartService partService = window.getPartService();
            if (partService != null) {
                partService.addPartListener(fPartListener);
            }
        }
    };

    /**
     * The constructor
     */
    public IOUIPlugin() {
    }

    /**
     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
     */
    public void start(BundleContext context) throws Exception {
        super.start(context);
        plugin = this;
        Job job = new Job("Initializing IOUI Plugion") //$NON-NLS-1$
        {

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                connectionListener = new IConnectionPointListener() {

                    public void connectionPointChanged(ConnectionPointEvent event) {
                        IConnectionPoint connection = event.getConnectionPoint();
                        IConnectionPointManager manager = CoreIOPlugin.getConnectionPointManager();
                        ConnectionPointType type = manager.getType(connection);
                        if (type == null) {
                            return;
                        }

                        switch (event.getKind()) {
                        case ConnectionPointEvent.POST_ADD:
                            refreshNavigatorViewAndSelect(
                                    manager.getConnectionPointCategory(type.getCategory().getId()), connection);
                            break;
                        case ConnectionPointEvent.POST_DELETE:
                            refreshNavigatorView(manager.getConnectionPointCategory(type.getCategory().getId()));
                            break;
                        case ConnectionPointEvent.POST_CHANGE:
                            refreshNavigatorView(connection);
                        }
                    }

                };
                CoreIOPlugin.getConnectionPointManager().addConnectionPointListener(connectionListener);

                themeChangeListener = new IPreferenceChangeListener() {
                    public void preferenceChange(PreferenceChangeEvent event) {
                        if (event.getKey().equals(IThemeManager.THEME_CHANGED)) {
                            ImageUtils.themeChanged();
                        }
                    }
                };
                EclipseUtil.instanceScope().getNode(ThemePlugin.PLUGIN_ID)
                        .addPreferenceChangeListener(themeChangeListener);

                saveRemoteJobs = new HashMap<IEditorInput, Job>();
                addPartListener();

                return Status.OK_STATUS;
            }

        };
        EclipseUtil.setSystemForJob(job);
        job.schedule();
    }

    /**
     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
     */
    public void stop(BundleContext context) throws Exception {
        if (connectionListener != null) {
            CoreIOPlugin.getConnectionPointManager().removeConnectionPointListener(connectionListener);
            connectionListener = null;
        }
        if (themeChangeListener != null) {
            EclipseUtil.instanceScope().getNode(ThemePlugin.PLUGIN_ID)
                    .removePreferenceChangeListener(themeChangeListener);
            themeChangeListener = null;
        }
        removePartListener();
        if (saveRemoteJobs != null) {
            Collection<Job> jobs = saveRemoteJobs.values();
            for (Job job : jobs) {
                job.cancel();
            }
            saveRemoteJobs.clear();
            saveRemoteJobs = null;
        }
        plugin = null;
        super.stop(context);
    }

    /**
     * Returns the shared instance
     * 
     * @return the shared instance
     */
    public static IOUIPlugin getDefault() {
        return plugin;
    }

    /**
     * Returns an image descriptor for the image file at the given plug-in relative path.
     * 
     * @param path
     *            the path
     * @return the image descriptor
     */
    public static ImageDescriptor getImageDescriptor(String path) {
        return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
    }

    /**
     * Returns an image for the image file at the given plug-in relative path.
     * 
     * @param path
     *            the path
     * @return the image object
     */
    public static Image getImage(String path) {
        ImageRegistry registry = plugin.getImageRegistry();
        Image image = registry.get(path);
        if (image == null) {
            ImageDescriptor id = getImageDescriptor(path);
            if (id == null) {
                return null;
            }
            registry.put(path, id);
            image = registry.get(path);
        }
        return image;
    }

    public static void refreshNavigatorView(Object element) {
        refreshNavigatorViewAndSelect(element, null);
    }

    public static void refreshNavigatorViewAndSelect(final Object element, final Object selection) {
        UIUtils.getDisplay().asyncExec(new Runnable() {

            public void run() {
                try {
                    IViewPart view = findView(IPageLayout.ID_PROJECT_EXPLORER);
                    refreshNavigatorInternal(view, element, selection);

                    view = findView(RemoteNavigatorView.ID);
                    if (view != null) {
                        // if the content of the remote category changed, refresh the root of Remote view
                        if (element instanceof IConnectionPointCategory
                                && ((IConnectionPointCategory) element).isRemote()) {
                            Object input = ((CommonNavigator) view).getCommonViewer().getInput();
                            refreshNavigatorInternal(view, input, selection);
                        } else {
                            refreshNavigatorInternal(view, element, selection);
                        }
                    }
                } catch (PartInitException e) {
                }
            }
        });
    }

    private static void refreshNavigatorInternal(IViewPart viewPart, Object element, Object selection) {
        if (viewPart == null) {
            return;
        }
        if (viewPart instanceof CommonNavigator) {
            CommonViewer viewer = ((CommonNavigator) viewPart).getCommonViewer();
            if (element == null) {
                // full refresh
                System.err.println("FIXME: full refresh for " + viewer.getClass().getSimpleName()); //$NON-NLS-1$ // $codepro.audit.disable debuggingCode
                viewer.refresh();
            } else {
                Widget widget = viewer.testFindItem(element);
                if (widget != null) {
                    Object data = widget.getData();
                    if (data != null) {
                        viewer.refresh(data);
                    }
                }
            }
        }

        if (selection != null && viewPart instanceof CommonNavigator) {
            // ensures the category's new content are loaded
            CommonViewer viewer = ((CommonNavigator) viewPart).getCommonViewer();
            viewer.expandToLevel(element, 1);
            viewer.setSelection(new StructuredSelection(selection));
        }
    }

    private static IViewPart findView(String viewID) throws PartInitException {
        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window != null) {
            IWorkbenchPage page = window.getActivePage();
            if (page != null) {
                return page.findView(viewID);
            }
        }
        return null;
    }

    private void addPartListener() {
        IWorkbench workbench = null;
        try {
            workbench = PlatformUI.getWorkbench();
        } catch (Exception e) {
            // ignore, may be running headless, like in tests
        }
        if (workbench != null) {
            IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
            IPartService partService;
            for (IWorkbenchWindow window : windows) {
                final IWorkbenchWindow workbenchWindow = window;
                UIUtils.getDisplay().syncExec(new Runnable() {
                    public void run() {
                        IViewPart projectExplorer = null;
                        if ((projectExplorer = workbenchWindow.getActivePage()
                                .findView(IPageLayout.ID_PROJECT_EXPLORER)) != null) {
                            // If the project explorer view is already opened at this time, then
                            // we need to explicitly add the listener to it.
                            handleProjectExplorerListeners(projectExplorer);
                        }
                    }
                });
                partService = window.getPartService();
                if (partService != null) {
                    partService.addPartListener(fPartListener);
                }
            }

            // Listen on any future windows
            PlatformUI.getWorkbench().addWindowListener(fWindowListener);
        }
    }

    private void removePartListener() {
        IWorkbench workbench = null;
        try {
            workbench = PlatformUI.getWorkbench();
        } catch (Exception e) {
            // ignore, may be running headless, like in tests
        }
        if (workbench != null) {
            IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
            IPartService partService;
            for (IWorkbenchWindow window : windows) {
                partService = window.getPartService();
                if (partService != null) {
                    partService.removePartListener(fPartListener);
                }
            }
            PlatformUI.getWorkbench().removeWindowListener(fWindowListener);
        }
    }

    /**
     * Watches the local file for changes and saves it back to the original remote file when the editor is saved.
     * 
     * @param editorPart
     *            the editor part the file is opened on
     */
    private void attachSaveListener(final IEditorPart editorPart) {
        final IEditorInput editorInput = editorPart.getEditorInput();
        if (!(editorInput instanceof UniformFileStoreEditorInput)
                || !((UniformFileStoreEditorInput) editorInput).isRemote()) {
            // the original is a local file; no need to re-save it
            return;
        }

        editorPart.addPropertyListener(new IPropertyListener() {

            public void propertyChanged(Object source, int propId) {
                if (propId == EditorPart.PROP_DIRTY && source instanceof EditorPart) {
                    EditorPart ed = (EditorPart) source;
                    if (ed.isDirty()) {
                        return;
                    }

                    Job job = saveRemoteJobs.get(editorInput);
                    if (job != null) {
                        // a job saving the remote file is already running
                        return;
                    }
                    job = new Job(Messages.EditorUtils_MSG_RemotelySaving + ed.getPartName()) {

                        protected IStatus run(final IProgressMonitor monitor) {
                            UniformFileStoreEditorInput input = (UniformFileStoreEditorInput) editorInput;
                            final IFileStore localCacheFile = input.getLocalFileStore();
                            IFileStore originalFile = input.getFileStore();
                            IFileInfo originalFileInfo = input.getFileInfo();
                            try {
                                IFileInfo currentFileInfo = originalFile.fetchInfo(EFS.NONE, monitor);
                                if (currentFileInfo.exists()
                                        && (currentFileInfo.getLastModified() != originalFileInfo.getLastModified()
                                                || currentFileInfo.getLength() != originalFileInfo.getLength())) {
                                    if (!UIUtils.showPromptDialog(Messages.EditorUtils_OverwritePrompt_Title,
                                            MessageFormat.format(Messages.EditorUtils_OverwritePrompt_Message,
                                                    originalFile.getName()))) {
                                        return Status.CANCEL_STATUS;
                                    }
                                }
                                SyncUtils.copy(localCacheFile, null, originalFile, EFS.NONE, monitor);
                            } catch (final CoreException e) {
                                // save failed; offers user to save the file locally instead
                                final String filename = originalFile.getName();
                                UIUtils.getDisplay().asyncExec(new Runnable() {

                                    public void run() {
                                        if (MessageDialog.openConfirm(UIUtils.getActiveShell(),
                                                MessageFormat.format(
                                                        Messages.IOUIPlugin_ErrorSavingRemoteFile_Title, filename),
                                                MessageFormat.format(
                                                        Messages.IOUIPlugin_ErrorSavingRemoteFile_Message,
                                                        e.getLocalizedMessage()))) {
                                            FileDialog dialog = new FileDialog(UIUtils.getActiveShell(), SWT.SAVE);
                                            dialog.setFileName(filename);
                                            String filepath = dialog.open();
                                            if (filepath != null) {
                                                IFileStore localFileStore = EFS.getLocalFileSystem()
                                                        .fromLocalFile(new File(filepath));
                                                try {
                                                    SyncUtils.copy(localCacheFile, null, localFileStore, EFS.NONE,
                                                            monitor);
                                                } catch (CoreException e1) {
                                                    UIUtils.showErrorMessage(MessageFormat.format(
                                                            Messages.IOUIPlugin_ErrorSavingRemoteFile_Title,
                                                            filename), e);
                                                }
                                            }
                                        }
                                    }
                                });
                            } finally {
                                // update cached remote file info
                                try {
                                    input.setFileInfo(originalFile.fetchInfo(EFS.NONE, monitor));
                                } catch (CoreException e) {
                                    IdeLog.logWarning(IOUIPlugin.getDefault(), e);
                                }
                            }
                            return Status.OK_STATUS;
                        }
                    };
                    saveRemoteJobs.put(editorInput, job);
                    job.addJobChangeListener(new JobChangeAdapter() {

                        public void done(IJobChangeEvent event) {
                            saveRemoteJobs.remove(editorInput);
                        };
                    });
                    job.schedule();
                }
            }
        });
    }
}