com.aptana.ide.editors.unified.actions.ToolBarContributionRegistryImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.ide.editors.unified.actions.ToolBarContributionRegistryImpl.java

Source

/**
 * This file Copyright (c) 2005-2008 Aptana, Inc. This program is
 * dual-licensed under both the Aptana Public License and the GNU General
 * Public license. You may elect to use one or the other of these licenses.
 * 
 * This program is distributed in the hope that it will be useful, but
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 * NONINFRINGEMENT. Redistribution, except as permitted by whichever of
 * the GPL or APL you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or modify this
 * program under the terms of the GNU General Public License,
 * Version 3, as published by the Free Software Foundation.  You should
 * have received a copy of the GNU General Public License, Version 3 along
 * with this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Aptana provides a special exception to allow redistribution of this file
 * with certain other free and open source software ("FOSS") code and certain additional terms
 * pursuant to Section 7 of the GPL. You may view the exception and these
 * terms on the web at http://www.aptana.com/legal/gpl/.
 * 
 * 2. For the Aptana Public License (APL), this program and the
 * accompanying materials are made available under the terms of the APL
 * v1.0 which accompanies this distribution, and is available at
 * http://www.aptana.com/legal/apl/.
 * 
 * You may view the GPL, Aptana's exception and additional terms, and the
 * APL in the file titled license.html at the root of the corresponding
 * plugin containing this source file.
 * 
 * Any modifications to this file must keep this entire header intact.
 */
package com.aptana.ide.editors.unified.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchWindow;

import com.aptana.ide.core.IdeLog;
import com.aptana.ide.editors.UnifiedEditorsPlugin;
import com.aptana.ide.editors.toolbar.IToolBarMember;
import com.aptana.ide.editors.toolbar.IToolbarContributionRegistry;
import com.aptana.ide.editors.toolbar.IToolbarRegistryContributor;
import com.aptana.ide.editors.toolbar.ToolBarContribution;
import com.aptana.ide.editors.unified.IUnifiedEditor;
import com.aptana.ide.editors.unified.InstanceCreator;
import com.aptana.ide.editors.unified.UnifiedConfiguration;

/**
 * real implementation of {@link IToolBarContributionRegistry} lays here
 * @author Pavel Petrochenko
 */
public final class ToolBarContributionRegistryImpl {

    private static final String TOOLBAR_ID = "com.aptana.ide.editors.toolbarContribution"; //$NON-NLS-1$
    private static final Object TAG_ELEMENT = "element"; //$NON-NLS-1$
    private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
    private static final String ATTR_LANGUAGE = "language"; //$NON-NLS-1$
    private static final Object TAG_CONTRIBUTOR = "contributor"; //$NON-NLS-1$

    private static Map toolBarContributions = new HashMap();
    private static Map toolBarContributionNames = new HashMap();
    static WeakHashMap map = new WeakHashMap();
    static WeakHashMap mapListener = new WeakHashMap();

    private static IToolbarContributionRegistry toolbarContributionRegistry = new IToolbarContributionRegistry() {

        public void addContribution(String language, ToolBarContribution tc) {
            ToolBarContributionRegistryImpl.addContribution(language, tc);
        }

        public void removeContribution(String language, ToolBarContribution cont) {
            ToolBarContributionRegistryImpl.removeContribution(language, cont);
        }

        public List getContributions(String language) {
            return ToolBarContributionRegistryImpl.getContributions(language);
        }

    };

    /**
     * @return singleton instance of {@link IToolbarContributionRegistry}
     */
    public static IToolbarContributionRegistry getInstance() {
        return toolbarContributionRegistry;
    }

    private static List getContributions(String language) {
        List list = (List) toolBarContributions.get(language);
        if (list == null) {
            list = new ArrayList();
        }
        return list;
    }

    static {
        loadToolBarContributions();
    }

    /**
     * @author Pavel Petrochenko
     */
    private static final class ContextListener implements ISelectionChangedListener {
        private final IToolBarManager toolBarManager;
        private final TextViewer tv;
        private final IUnifiedEditor activeEditor;

        private ContextListener(IToolBarManager toolBarManager, TextViewer tv, IUnifiedEditor activeEditor) {
            this.toolBarManager = toolBarManager;
            this.tv = tv;
            this.activeEditor = activeEditor;
        }

        /**
         * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
         */
        public void selectionChanged(SelectionChangedEvent event) {
            ITextSelection ts = (ITextSelection) event.getSelection();
            int offset = ts.getOffset();

            try {
                String type = TextUtilities.getContentType(tv.getDocument(),
                        UnifiedConfiguration.UNIFIED_PARTITIONING, offset, true);
                doUpdate(type);
            } catch (BadLocationException e) {
                return;
            }
        }

        /**
         * updates toolbar it it is needed
         * @param chType
         */
        public void updateIfNeeded(String chType) {
            if (tv.getTextWidget().isDisposed()) {
                return;
            }
            ITextSelection ts = (ITextSelection) tv.getSelection();
            int offset = ts.getOffset();
            try {
                String type = TextUtilities.getContentType(tv.getDocument(),
                        UnifiedConfiguration.UNIFIED_PARTITIONING, offset, true);
                if (chType.equals(type)) {
                    updateToolbar(toolBarManager, type, activeEditor);
                    toolBarManager.update(false);
                }
            } catch (BadLocationException e) {
                return;
            }
        }

        //real update
        private void doUpdate(String type) {
            if (type != null && !type.equals(map.get(activeEditor))) {
                map.put(activeEditor, type);
                updateToolbar(toolBarManager, type, activeEditor);
                toolBarManager.update(false);
                WorkbenchWindow activeWorkbenchWindow = (WorkbenchWindow) PlatformUI.getWorkbench()
                        .getActiveWorkbenchWindow();
                // workarounding eclipse strange behavior
                activeWorkbenchWindow.getCoolBarManager2().update(true);
            }
        }
    }

    private ToolBarContributionRegistryImpl() {

    }

    /**
     * @param activeEditor
     * @param toolBarManager
     */
    static void initToolBar(final IUnifiedEditor activeEditor, final IToolBarManager toolBarManager) {
        String defaultLanguage = activeEditor.getFileContext().getDefaultLanguage();
        ISourceViewer viewer = activeEditor.getViewer();
        String cLang = (String) map.get(activeEditor);
        if (viewer instanceof TextViewer && cLang == null) {
            final TextViewer tv = (TextViewer) viewer;
            map.put(activeEditor, defaultLanguage);
            final ContextListener selectionChangedListener = new ContextListener(toolBarManager, tv, activeEditor);
            tv.addPostSelectionChangedListener(selectionChangedListener);
            mapListener.put(activeEditor, selectionChangedListener);
            tv.getTextWidget().addDisposeListener(new DisposeListener() {

                public void widgetDisposed(DisposeEvent e) {
                    tv.removePostSelectionChangedListener(selectionChangedListener);
                    mapListener.remove(activeEditor);
                }
            });
            tv.getTextWidget().addFocusListener(new FocusListener() {

                public void focusGained(FocusEvent e) {
                    map.remove(activeEditor);
                    selectionChangedListener.selectionChanged(new SelectionChangedEvent(tv, tv.getSelection()));
                }

                public void focusLost(FocusEvent e) {

                }

            });
        }
        if (cLang != null) {
            defaultLanguage = cLang;
        }
        // activeEditor.getViewer().getTextWidget().getCaret().addListener(eventType, listener)
        updateToolbar(toolBarManager, defaultLanguage, activeEditor);
    }

    private static void updateToolbar(final IToolBarManager toolBarManager, String defaultLanguage,
            final IUnifiedEditor editor) {
        toolBarManager.removeAll();

        ArrayList contributions = (ArrayList) toolBarContributions.get(defaultLanguage);
        if (contributions != null) {
            for (Iterator iterator = contributions.iterator(); iterator.hasNext();) {
                final ToolBarContribution name = (ToolBarContribution) iterator.next();
                Action action = new Action(name.getText(), Action.AS_PUSH_BUTTON) {
                    public void run() {

                        IToolBarMember member = (IToolBarMember) name.getInstance();
                        member.execute(editor, name.getText());

                    }
                };
                action.setImageDescriptor(name.getIcon());
                action.setToolTipText(name.getTooltipText());
                toolBarManager.add(action);
            }
        }
    }

    private static void loadToolBarContributions() {
        IExtensionRegistry registry = Platform.getExtensionRegistry();
        IExtensionPoint ep = registry.getExtensionPoint(TOOLBAR_ID);

        if (ep != null) {
            IExtension[] extensions = ep.getExtensions();

            for (int i = 0; i < extensions.length; i++) {
                IExtension extension = extensions[i];
                IConfigurationElement[] elements = extension.getConfigurationElements();
                // initialize contributors first
                for (int j = 0; j < elements.length; j++) {
                    try {
                        IConfigurationElement element = elements[j];
                        String elementName = element.getName();
                        if (elementName.equals(TAG_CONTRIBUTOR)) {
                            IToolbarRegistryContributor contributor = (IToolbarRegistryContributor) element
                                    .createExecutableExtension(ATTR_CLASS);
                            contributor.contributeToToolbarRegistry(toolbarContributionRegistry);
                        }
                    } catch (Exception e) {
                        IdeLog.log(UnifiedEditorsPlugin.getDefault(), IStatus.ERROR,
                                "Exception while initializing toolbar contribution registry", e); //$NON-NLS-1$
                    }
                }
                for (int j = 0; j < elements.length; j++) {
                    IConfigurationElement element = elements[j];
                    String elementName = element.getName();
                    try {
                        if (elementName.equals(TAG_ELEMENT)) {
                            String parserClass = element.getAttribute(ATTR_CLASS);
                            String language = element.getAttribute(ATTR_LANGUAGE);
                            String icon = element.getAttribute("icon"); //$NON-NLS-1$
                            String text = element.getAttribute("name"); //$NON-NLS-1$
                            String tooltip = element.getAttribute("tooltip"); //$NON-NLS-1$
                            InstanceCreator creator = null;
                            if (parserClass != null && language != null && language.length() > 0) {
                                creator = new InstanceCreator(element, ATTR_CLASS);
                            }
                            String namespaceIdentifier = extension.getNamespaceIdentifier();
                            ImageDescriptor desc = null;
                            if (icon != null && icon.length() > 0) {
                                desc = ImageDescriptor
                                        .createFromURL(Platform.getBundle(namespaceIdentifier).getEntry(icon));
                            }
                            ToolBarContribution tc = new ToolBarContribution(text, tooltip, desc, creator);
                            addContribution(language, tc);
                        }

                    } catch (Exception e) {
                        IdeLog.log(UnifiedEditorsPlugin.getDefault(), IStatus.ERROR,
                                "Exception while initializing toolbar contribution registry", e); //$NON-NLS-1$
                    }
                }
            }
        }
    }

    private static void addContribution(String language, ToolBarContribution tc) {
        HashSet set = (HashSet) toolBarContributionNames.get(language);
        if (set == null) {
            set = new HashSet();
            toolBarContributionNames.put(language, set);
        }
        if (set.contains(tc.getText())) {
            return;
        }
        set.add(tc.getText());
        ArrayList list = (ArrayList) toolBarContributions.get(language);
        if (list == null) {
            list = new ArrayList();
            toolBarContributions.put(language, list);
        }

        list.add(tc);
        update(language);
    }

    /**
     * @param language
     * @param cont
     */
    private static void removeContribution(String language, ToolBarContribution cont) {
        ArrayList list = (ArrayList) toolBarContributions.get(language);
        HashSet set = (HashSet) toolBarContributionNames.get(language);
        if (list == null) {
            return;
        }
        boolean remove = list.remove(cont);
        if (remove) {
            set.remove(cont.getText());
            update(language);
        }
    }

    private static void update(String language) {
        for (Iterator iterator = mapListener.values().iterator(); iterator.hasNext();) {
            ContextListener name = (ContextListener) iterator.next();
            name.updateIfNeeded(language);
        }
    }

}