org.eclipse.ui.texteditor.MarkerAnnotationPreferences.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ui.texteditor.MarkerAnnotationPreferences.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2011 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.ui.texteditor;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.osgi.framework.Bundle;

import org.eclipse.swt.graphics.RGB;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;

import org.eclipse.core.resources.IMarker;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.StringConverter;

import org.eclipse.ui.internal.editors.text.EditorsPlugin;

import org.eclipse.ui.editors.text.EditorsUI;

/**
 * Objects of this class provide access to all extensions declared for the <code>markerAnnotationSpecification</code> extension point.
 * The extensions are represented as instances of {@link org.eclipse.ui.texteditor.AnnotationPreference}.
 *
 * @since 2.1
 */
public class MarkerAnnotationPreferences {

    /**
     * Initializes the given preference store with the default marker annotation values.
     *
     * @param store the preference store to be initialized
     * @since 3.0
     */
    public static void initializeDefaultValues(IPreferenceStore store) {

        boolean ignoreAnnotationsPrefPage = store
                .getBoolean(AbstractDecoratedTextEditorPreferenceConstants.USE_ANNOTATIONS_PREFERENCE_PAGE);
        boolean ignoreQuickDiffPrefPage = store
                .getBoolean(AbstractDecoratedTextEditorPreferenceConstants.USE_QUICK_DIFF_PREFERENCE_PAGE);

        MarkerAnnotationPreferences preferences = EditorsPlugin.getDefault().getMarkerAnnotationPreferences();
        Iterator e = preferences.getAnnotationPreferences().iterator();
        while (e.hasNext()) {
            AnnotationPreference info = (AnnotationPreference) e.next();

            if (ignoreAnnotationsPrefPage && info.isIncludeOnPreferencePage() && isComplete(info))
                continue;

            if (ignoreQuickDiffPrefPage && (info.getAnnotationType()
                    .equals("org.eclipse.ui.workbench.texteditor.quickdiffChange") //$NON-NLS-1$
                    || (info.getAnnotationType().equals("org.eclipse.ui.workbench.texteditor.quickdiffAddition")) //$NON-NLS-1$
                    || (info.getAnnotationType().equals("org.eclipse.ui.workbench.texteditor.quickdiffDeletion")) //$NON-NLS-1$
            ))
                continue;

            store.setDefault(info.getTextPreferenceKey(), info.getTextPreferenceValue());
            store.setDefault(info.getOverviewRulerPreferenceKey(), info.getOverviewRulerPreferenceValue());
            if (info.getVerticalRulerPreferenceKey() != null)
                store.setDefault(info.getVerticalRulerPreferenceKey(), info.getVerticalRulerPreferenceValue());
            PreferenceConverter.setDefault(store, info.getColorPreferenceKey(), info.getColorPreferenceValue());
            if (info.getShowInNextPrevDropdownToolbarActionKey() != null)
                store.setDefault(info.getShowInNextPrevDropdownToolbarActionKey(),
                        info.isShowInNextPrevDropdownToolbarAction());
            if (info.getIsGoToNextNavigationTargetKey() != null)
                store.setDefault(info.getIsGoToNextNavigationTargetKey(), info.isGoToNextNavigationTarget());
            if (info.getIsGoToPreviousNavigationTargetKey() != null)
                store.setDefault(info.getIsGoToPreviousNavigationTargetKey(),
                        info.isGoToPreviousNavigationTarget());
            if (info.getHighlightPreferenceKey() != null)
                store.setDefault(info.getHighlightPreferenceKey(), info.getHighlightPreferenceValue());
            if (info.getTextStylePreferenceKey() != null)
                store.setDefault(info.getTextStylePreferenceKey(), info.getTextStyleValue());
        }
    }

    /**
     * Removes the marker annotation values which are shown on the
     * general Annotations page  from the given store and prevents
     * setting the default values in the future.
     * <p>
     * Note: In order to work this method must be called before any
     *       call to {@link #initializeDefaultValues(IPreferenceStore)}
     * </p>
     * <p>
     * This method is not part of the API and must only be called
     * by {@link org.eclipse.ui.editors.text.EditorsUI}
     * </p>
     *
     * @param store the preference store to be initialized
     * @throws IllegalStateException if not called by {@link org.eclipse.ui.editors.text.EditorsUI}
     * @since 3.0
     */
    public static void useAnnotationsPreferencePage(IPreferenceStore store) throws IllegalStateException {
        checkAccess();

        store.putValue(AbstractDecoratedTextEditorPreferenceConstants.USE_ANNOTATIONS_PREFERENCE_PAGE,
                Boolean.toString(true));

        MarkerAnnotationPreferences preferences = EditorsPlugin.getDefault().getMarkerAnnotationPreferences();
        Iterator e = preferences.getAnnotationPreferences().iterator();
        while (e.hasNext()) {
            AnnotationPreference info = (AnnotationPreference) e.next();

            // Only reset annotations shown on Annotations preference page
            if (!info.isIncludeOnPreferencePage() || !isComplete(info))
                continue;

            store.setToDefault(info.getTextPreferenceKey());
            store.setToDefault(info.getOverviewRulerPreferenceKey());
            if (info.getVerticalRulerPreferenceKey() != null)
                store.setToDefault(info.getVerticalRulerPreferenceKey());
            store.setToDefault(info.getColorPreferenceKey());
            if (info.getShowInNextPrevDropdownToolbarActionKey() != null)
                store.setToDefault(info.getShowInNextPrevDropdownToolbarActionKey());
            if (info.getIsGoToNextNavigationTargetKey() != null)
                store.setToDefault(info.getIsGoToNextNavigationTargetKey());
            if (info.getIsGoToPreviousNavigationTargetKey() != null)
                store.setToDefault(info.getIsGoToPreviousNavigationTargetKey());
            if (info.getHighlightPreferenceKey() != null)
                store.setToDefault(info.getHighlightPreferenceKey());
            if (info.getTextStylePreferenceKey() != null)
                store.setToDefault(info.getTextStylePreferenceKey());
        }
    }

    /**
     * Removes the Quick Diff marker annotation values which are shown on the
     * general Quick Diff page from the given store and prevents
     * setting the default values in the future.
     * <p>
     * Note: In order to work this method must be called before any
     *       call to {@link #initializeDefaultValues(IPreferenceStore)}
     * </p>
     * <p>
     * This method is not part of the API and must only be called
     * by {@link EditorsUI}
     * </p>
     *
     * @param store the preference store to be initialized
     * @throws IllegalStateException if not called by {@link EditorsUI}
     * @since 3.0
     */
    public static void useQuickDiffPreferencePage(IPreferenceStore store) throws IllegalStateException {
        checkAccess();

        store.putValue(AbstractDecoratedTextEditorPreferenceConstants.USE_QUICK_DIFF_PREFERENCE_PAGE,
                Boolean.toString(true));

        MarkerAnnotationPreferences preferences = EditorsPlugin.getDefault().getMarkerAnnotationPreferences();
        Iterator e = preferences.getAnnotationPreferences().iterator();
        while (e.hasNext()) {
            AnnotationPreference info = (AnnotationPreference) e.next();

            // Only reset annotations shown on Quick Diff preference page

            if (!(info.getAnnotationType().equals("org.eclipse.ui.workbench.texteditor.quickdiffChange") //$NON-NLS-1$
                    || (info.getAnnotationType().equals("org.eclipse.ui.workbench.texteditor.quickdiffAddition")) //$NON-NLS-1$
                    || (info.getAnnotationType().equals("org.eclipse.ui.workbench.texteditor.quickdiffDeletion")) //$NON-NLS-1$
            ))
                continue;

            store.setToDefault(info.getTextPreferenceKey());
            store.setToDefault(info.getOverviewRulerPreferenceKey());
            if (info.getVerticalRulerPreferenceKey() != null)
                store.setToDefault(info.getVerticalRulerPreferenceKey());
            store.setToDefault(info.getColorPreferenceKey());
            if (info.getShowInNextPrevDropdownToolbarActionKey() != null)
                store.setToDefault(info.getShowInNextPrevDropdownToolbarActionKey());
            if (info.getIsGoToNextNavigationTargetKey() != null)
                store.setToDefault(info.getIsGoToNextNavigationTargetKey());
            if (info.getIsGoToPreviousNavigationTargetKey() != null)
                store.setToDefault(info.getIsGoToPreviousNavigationTargetKey());
            if (info.getHighlightPreferenceKey() != null)
                store.setToDefault(info.getHighlightPreferenceKey());
            if (info.getTextStylePreferenceKey() != null)
                store.setToDefault(info.getTextStylePreferenceKey());
        }
    }

    private static final class AccessChecker extends SecurityManager {
        public Class[] getClassContext() {
            return super.getClassContext();
        }
    }

    /**
     * Checks correct access.
     *
     * @throws IllegalStateException if not called by {@link EditorsUI}
     * @since 3.0
     */
    private static void checkAccess() throws IllegalStateException {
        Class[] elements = new AccessChecker().getClassContext();
        if (!(elements[3].equals(EditorsUI.class) || elements[4].equals(EditorsUI.class)))
            throw new IllegalStateException();
    }

    /** The list of extension fragments. */
    private List/*<AnnotationPreference>*/ fFragments;
    /** The list of extensions. */
    private List/*<AnnotationPreference>*/ fPreferences;

    /**
     * Creates a new marker annotation preferences to access
     * marker annotation preferences.
     */
    public MarkerAnnotationPreferences() {
        this(false);
    }

    /**
     * Creates a new marker annotation preferences to access
     * marker annotation preferences.
     * @param initFromPreferences tells this instance to initialize itself from the preferences
     *
     * @since 3.2
     */
    private MarkerAnnotationPreferences(boolean initFromPreferences) {
        if (initFromPreferences)
            initializeSharedMakerAnnotationPreferences();
    }

    /**
     * Returns all extensions provided for the <code>markerAnnotationSpecification</code> extension point.
     *
     * @return all extensions provided for the <code>markerAnnotationSpecification</code> extension point
     *         (element type: {@link AnnotationPreference})
     */
    public List getAnnotationPreferences() {
        if (fPreferences == null)
            initialize();
        return fPreferences;
    }

    /**
     * Returns all extensions provided for the <code>markerAnnotationSpecification</code>
     * extension point including fragments. Fragments share the preference part
     * with a marker annotation specifications provided for a super type but do
     * change the presentation part.
     *
     * @return all extensions provided for the <code>markerAnnotationSpecification</code>
     *         extension point including fragments (element type: {@link AnnotationPreference})
     */
    public List getAnnotationPreferenceFragments() {
        if (fFragments == null)
            initialize();
        return fFragments;
    }

    private void initialize() {
        synchronized (EditorsPlugin.getDefault()) {
            if (!EditorsPlugin.getDefault().isMarkerAnnotationPreferencesInitialized())
                EditorsPlugin.getDefault().setMarkerAnnotationPreferences(new MarkerAnnotationPreferences(true));
        }

        MarkerAnnotationPreferences sharedPrefs = EditorsPlugin.getDefault().getMarkerAnnotationPreferences();

        fFragments = cloneAnnotationPreferences(sharedPrefs.fFragments);
        fPreferences = cloneAnnotationPreferences(sharedPrefs.fPreferences);
    }

    /**
     * Reads all extensions provided for the <code>markerAnnotationSpecification</code> extension point and
     * translates them into <code>AnnotationPreference</code> objects.
     */
    private void initializeSharedMakerAnnotationPreferences() {

        // initialize lists - indicates that the initialization happened
        fFragments = new ArrayList(2);
        fPreferences = new ArrayList(2);

        // populate list
        IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(EditorsUI.PLUGIN_ID,
                "markerAnnotationSpecification"); //$NON-NLS-1$
        if (extensionPoint != null) {
            IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
            for (int i = 0; i < elements.length; i++) {
                AnnotationPreference spec = createSpec(elements[i]);
                if (spec != null)
                    fFragments.add(spec);
                if (isComplete(spec))
                    fPreferences.add(spec);
            }
        }
    }

    /**
     * Deeply clones the given list of <code>AnnotationPreference</code>.
     *
     * @param annotationPreferences a list of <code>AnnotationPreference</code>
     * @return the cloned list of cloned annotation preferences
     * @since 3.1
     */
    private List cloneAnnotationPreferences(List annotationPreferences) {
        if (annotationPreferences == null)
            return null;
        List clone = new ArrayList(annotationPreferences.size());
        Iterator iter = annotationPreferences.iterator();
        while (iter.hasNext())
            clone.add(clone(((AnnotationPreference) iter.next())));
        return clone;
    }

    /**
     * Clones the given annotation preference.
     *
     * @param annotationPreference the annotation preference to clone
     * @return the cloned annotation preference
     * @since 3.1
     */
    private AnnotationPreference clone(AnnotationPreference annotationPreference) {
        if (annotationPreference == null)
            return null;

        AnnotationPreference clone = new AnnotationPreference();
        if (annotationPreference.getAnnotationType() != null) {
            clone.setAnnotationType(annotationPreference.getAnnotationType());
            clone.merge(annotationPreference);
        }

        return clone;
    }

    /**
     * Checks if <code>spec</code> has all the attributes previously required
     * by the marker annotation preference extension point. These are: color, text
     * and overview ruler preference keys.
     *
     * @param spec the <code>AnnotationPreference</code> to check
     * @return <code>true</code> if <code>spec</code> is complete, <code>false</code> otherwise
     * @since 3.0
     */
    private static boolean isComplete(AnnotationPreference spec) {
        return spec.getColorPreferenceKey() != null && spec.getColorPreferenceValue() != null
                && spec.getTextPreferenceKey() != null && spec.getOverviewRulerPreferenceKey() != null;
    }

    /**
     * Creates a <code>AnnotationPreference</code> the given configuration element.
     *
     * @param element the configuration element
     * @return the created annotation preference
     */
    private AnnotationPreference createSpec(IConfigurationElement element) {

        String s;
        int i;
        boolean b;

        ReadOnlyAnnotationPreference info = new ReadOnlyAnnotationPreference();

        s = element.getAttribute("annotationType"); //$NON-NLS-1$
        if (s == null || s.trim().length() == 0)
            return null;
        info.setAnnotationType(s);

        s = element.getAttribute("label"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setPreferenceLabel(s);

        s = element.getAttribute("markerType"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setMarkerType(s);

        s = element.getAttribute("markerSeverity"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            i = StringConverter.asInt(s, IMarker.SEVERITY_INFO);
            info.setSeverity(i);
        }

        s = element.getAttribute("textPreferenceKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setTextPreferenceKey(s);

        s = element.getAttribute("textPreferenceValue"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, false);
            info.setTextPreferenceValue(b);
        }

        s = element.getAttribute("highlightPreferenceKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setHighlightPreferenceKey(s);

        s = element.getAttribute("highlightPreferenceValue"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, false);
            info.setHighlightPreferenceValue(b);
        }

        s = element.getAttribute("overviewRulerPreferenceKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setOverviewRulerPreferenceKey(s);

        s = element.getAttribute("overviewRulerPreferenceValue"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, false);
            info.setOverviewRulerPreferenceValue(b);
        }

        s = element.getAttribute("verticalRulerPreferenceKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setVerticalRulerPreferenceKey(s);

        s = element.getAttribute("verticalRulerPreferenceValue"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, true);
            info.setVerticalRulerPreferenceValue(b);
        }

        s = element.getAttribute("colorPreferenceKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setColorPreferenceKey(s);

        s = element.getAttribute("colorPreferenceValue"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            RGB rgb = StringConverter.asRGB(s);
            info.setColorPreferenceValue(rgb == null ? new RGB(0, 0, 0) : rgb);
        }

        s = element.getAttribute("presentationLayer"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            i = StringConverter.asInt(s, 0);
            info.setPresentationLayer(i);
        }

        s = element.getAttribute("contributesToHeader"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, false);
            info.setContributesToHeader(b);
        }

        s = element.getAttribute("showInNextPrevDropdownToolbarActionKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setShowInNextPrevDropdownToolbarActionKey(s);

        s = element.getAttribute("showInNextPrevDropdownToolbarAction"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, false);
            info.setShowInNextPrevDropdownToolbarAction(b);
        }

        s = element.getAttribute("isGoToNextNavigationTargetKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setIsGoToNextNavigationTargetKey(s);

        s = element.getAttribute("isGoToNextNavigationTarget"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, false);
            info.setIsGoToNextNavigationTarget(b);
        }

        s = element.getAttribute("isGoToPreviousNavigationTargetKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setIsGoToPreviousNavigationTargetKey(s);

        s = element.getAttribute("isGoToPreviousNavigationTarget"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {
            b = StringConverter.asBoolean(s, false);
            info.setIsGoToPreviousNavigationTarget(b);
        }

        s = element.getAttribute("symbolicIcon"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setSymbolicImageName(s);

        s = element.getAttribute("icon"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setImageDescriptor(getImageDescriptor(s, element));

        s = element.getAttribute("quickFixIcon"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setQuickFixImageDescriptor(getImageDescriptor(s, element));

        s = element.getAttribute("annotationImageProvider"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setAnnotationImageProviderData(element, "annotationImageProvider"); //$NON-NLS-1$

        s = element.getAttribute("textStylePreferenceKey"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0)
            info.setTextStylePreferenceKey(s);

        s = element.getAttribute("textStylePreferenceValue"); //$NON-NLS-1$
        if (s != null && s.trim().length() > 0) {

            if (AnnotationPreference.STYLE_BOX.equals(s) || AnnotationPreference.STYLE_DASHED_BOX.equals(s)
                    || AnnotationPreference.STYLE_IBEAM.equals(s) || AnnotationPreference.STYLE_SQUIGGLES.equals(s)
                    || AnnotationPreference.STYLE_PROBLEM_UNDERLINE.equals(s)
                    || AnnotationPreference.STYLE_UNDERLINE.equals(s))
                info.setTextStyleValue(s);
            else
                info.setTextStyleValue(AnnotationPreference.STYLE_NONE);

        }

        s = element.getAttribute("includeOnPreferencePage"); //$NON-NLS-1$
        info.setIncludeOnPreferencePage(s == null || StringConverter.asBoolean(s, true));

        info.markReadOnly();

        return info;
    }

    /**
     * Returns the image descriptor for the icon path specified by the given configuration
     * element.
     *
     * @param iconPath the icon path
     * @param element the configuration element
     * @return the image descriptor
     * @since 3.0
     */
    private ImageDescriptor getImageDescriptor(String iconPath, IConfigurationElement element) {
        String pluginId = element.getContributor().getName();
        Bundle bundle = Platform.getBundle(pluginId);
        if (bundle == null)
            return null;

        URL url = FileLocator.find(bundle, new Path(iconPath), null);
        if (url != null)
            return ImageDescriptor.createFromURL(url);

        return ImageDescriptor.getMissingImageDescriptor();
    }
}