com.vectrace.MercurialEclipse.preferences.PreferenceInitializer.java Source code

Java tutorial

Introduction

Here is the source code for com.vectrace.MercurialEclipse.preferences.PreferenceInitializer.java

Source

/*******************************************************************************
 * Copyright (c) 2005-2010 VecTrace (Zingo Andersen) 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:
 *     VecTrace (Zingo Andersen) - implementation
 *     Jrme Ngre              - adding label decorator section
 *     Stefan C                  - Code cleanup
 *     Andrei Loskutov           - bug fixes
 *     Zsolt Koppany (intland)   - bug fixes
 *     Philip Graf               - use default timeout from preferences
 *     Amenel VOGLOZIN           - Update Quick Diff, Changeset context menu options, and others
 *******************************************************************************/

package com.vectrace.MercurialEclipse.preferences;

import static com.vectrace.MercurialEclipse.preferences.MercurialPreferenceConstants.*;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;

import com.vectrace.MercurialEclipse.MercurialEclipsePlugin;
import com.vectrace.MercurialEclipse.synchronize.PresentationMode;
import com.vectrace.MercurialEclipse.team.MercurialUtilities;

/**
 * Class used to initialize default preference values.
 */
public class PreferenceInitializer extends AbstractPreferenceInitializer {
    private static final boolean IS_WINDOWS = MercurialUtilities.isWindows();

    @Override
    public void initializeDefaultPreferences() {
        final IPreferenceStore store = MercurialEclipsePlugin.getDefault().getPreferenceStore();

        store.setDefault(PREF_COMMIT_UPDATE_QUICKDIFF, true);

        // per default, we use exact the executable we have (if any) on board
        store.setDefault(USE_BUILT_IN_HG_EXECUTABLE, true);

        // try to find out, IF we have the built-in hg executable
        detectAndSetHgExecutable(store);

        store.setDefault(PREF_AUTO_SHARE_PROJECTS, true);

        // This preference is currently not compatible with sym-linked projects
        store.setDefault(PREF_SYNC_ALL_PROJECTS_IN_REPO, false);

        store.setDefault(PREF_SYNC_ONLY_CURRENT_BRANCH, false);
        store.setDefault(PREF_SYNC_SHOW_EMPTY_GROUPS, true);
        store.setDefault(PREF_SYNC_PRESENTATION_MODE, PresentationMode.COMPRESSED_TREE.name());
        store.setDefault(PREF_SYNC_ENABLE_LOCAL_CHANGESETS, false);
        store.setDefault(PREF_SYNC_ENABLE_LOCAL_CHANGESETS_CONTEXT_MENU, true);

        // currently this reduces performance 2x => so disable per default
        store.setDefault(PREF_ENABLE_SUBREPO_SUPPORT, false);

        store.setDefault(HISTORY_LOG_USE_REMOVED, false);

        // "Highest" importance should be default, like "merge conflict"
        // when having 2 different statuses in a folder it should have the more important one
        store.setDefault(LABELDECORATOR_LOGIC, LABELDECORATOR_LOGIC_HB);

        store.setDefault(RESOURCE_DECORATOR_SHOW_CHANGESET_IN_PROJECT_LABEL, false);
        store.setDefault(RESOURCE_DECORATOR_SHOW_CHANGESET, false);
        store.setDefault(RESOURCE_DECORATOR_SHOW_INCOMING_CHANGESET, false);
        store.setDefault(RESOURCE_DECORATOR_SHOW_SUMMARY, true);
        store.setDefault(PREF_DECORATE_PROJECT_LABEL_SYNTAX, HgDecoratorConstants.DEFAULT_PROJECT_SYNTAX);

        store.setDefault(SYNC_COMPUTE_FULL_REMOTE_FILE_STATUS, true);

        store.setDefault(LOG_BATCH_SIZE, 500);
        store.setDefault(COMMIT_MESSAGE_BATCH_SIZE, 10);

        // blue
        store.setDefault(PREF_CONSOLE_COMMAND_COLOR, "0,0,255");
        // black
        store.setDefault(PREF_CONSOLE_MESSAGE_COLOR, "0,0,0");
        // red
        store.setDefault(PREF_CONSOLE_ERROR_COLOR, "255,0,0");

        store.setDefault(PREF_CONSOLE_SHOW_ON_STARTUP, false);
        store.setDefault(PREF_CONSOLE_LIMIT_OUTPUT, true);
        store.setDefault(PREF_CONSOLE_HIGH_WATER_MARK, 100000);

        store.setDefault(PREF_DECORATE_WITH_COLORS, true);
        store.setDefault(PREF_SHOW_COMMENTS, true);
        store.setDefault(PREF_SHOW_PATHS, true);
        // See issue #13662: do not show diffs per default: they may cause OOM on huge changesets
        store.setDefault(PREF_SHOW_DIFFS, false);
        store.setDefault(PREF_SHOW_ALL_TAGS, false);
        store.setDefault(PREF_SHOW_GRAPH, true);
        store.setDefault(PREF_SHOW_GOTO_TEXT, false);
        store.setDefault(PREF_AFFECTED_PATHS_LAYOUT, LAYOUT_HORIZONTAL);
        store.setDefault(PREF_SIGCHECK_IN_HISTORY, false);

        store.setDefault(PREF_HISTORY_MERGE_CHANGESET_BACKGROUND, "255,210,210");
        store.setDefault(PREF_HISTORY_MERGE_CHANGESET_FOREGROUND, "0,0,0");

        int defaultTimeout = TimeoutPreferencePage.DEFAULT_TIMEOUT;
        store.setDefault(DEFAULT_TIMEOUT, defaultTimeout);

        // remote operations are always longer than local
        store.setDefault(CLONE_TIMEOUT, defaultTimeout * 10);
        store.setDefault(PUSH_TIMEOUT, defaultTimeout * 10);
        store.setDefault(PULL_TIMEOUT, defaultTimeout * 10);

        store.setDefault(UPDATE_TIMEOUT, defaultTimeout);
        store.setDefault(COMMIT_TIMEOUT, defaultTimeout);
        store.setDefault(IMERGE_TIMEOUT, defaultTimeout);
        store.setDefault(LOG_TIMEOUT, defaultTimeout);
        store.setDefault(STATUS_TIMEOUT, defaultTimeout);
        store.setDefault(ADD_TIMEOUT, defaultTimeout);
        store.setDefault(REMOVE_TIMEOUT, defaultTimeout);

        String defaultUsername = store.getDefaultString(MERCURIAL_USERNAME);
        if (defaultUsername == null || defaultUsername.length() == 0) {
            // the task below may block UI thread and cause entire system to wait forever
            // therefore start job execution.
            // The preference key is only used as a cache by MercurialUtilities.getDefaultUserName() and
            // it is useful to show on the preference page.
            // Possibly relevant: http://www.javaforge.com/issue/20425
            Job job = new Job("Detecting hg user name") {
                @Override
                protected IStatus run(IProgressMonitor monitor) {
                    store.setDefault(MERCURIAL_USERNAME, MercurialUtilities.getDefaultUserName());
                    return Status.OK_STATUS;
                }
            };
            job.setPriority(Job.LONG);
            job.setSystem(true);
            job.schedule(200);
        }
        store.setDefault(PREF_USE_MERCURIAL_USERNAME, false);
        store.setDefault(PREF_DEFAULT_REBASE_KEEP_BRANCHES, false);
        store.setDefault(PREF_USE_EXTERNAL_MERGE, false);
        store.setDefault(PREF_DEFAULT_TRANSPLANT_FROM_LOCAL_BRANCHES, true);
        store.setDefault(PREF_CLONE_UNCOMPRESSED, false);

        store.setDefault(PREF_PRESELECT_UNTRACKED_IN_COMMIT_DIALOG, false);
        store.setDefault(PREF_VERIFY_SERVER_CERTIFICATE, true);
        store.setDefault(PREF_SHOW_LOGICAL_NAME_OF_REPOSITORIES, true);
        store.setDefault(PREF_RESOLVE_SHOW_RECAP_DIALOG, true);

        store.setDefault(PREF_SHOW_PULL_WARNING_DIALOG, MessageDialogWithToggle.PROMPT);
        store.setDefault(PREF_SHOW_MULTIPLE_PROJECTS_DIALOG, MessageDialogWithToggle.PROMPT);
        store.setDefault(PREF_SHOW_MERGE_CONFICT_NOTIFICATION_DIALOG, MessageDialogWithToggle.PROMPT);
        store.setDefault(PREF_SHOW_REBASE_CONFICT_NOTIFICATION_DIALOG, MessageDialogWithToggle.PROMPT);
        store.setDefault(PREF_SHOW_QFINISH_WARNING_DIALOG, MessageDialogWithToggle.PROMPT);
        store.setDefault(PREF_SHOW_PUSH_FORCE_GUIDANCE_DIALOG, MessageDialogWithToggle.PROMPT);

        // Shelve extension
        store.setDefault(PREF_SHELVE_USE_INTERACTION, false);

        // Persistence of the column layout in the History view - no UI associated with these
        // settings.
        store.setDefault(PREF_HISTORY_COLUMN_PERSISTENCE, true);
        store.setDefault(PREF_HISTORY_COLUMN_WIDTHS, "");

    }

    private static File checkForPossibleHgExecutables() {
        File hgExecutable = null;

        String envPath = System.getenv("PATH");

        if (envPath != null) {
            String pathSeparator = String.valueOf(File.pathSeparatorChar);
            String execSuffix = IS_WINDOWS ? ".exe" : "";
            for (StringTokenizer st = new StringTokenizer(envPath, pathSeparator, false); st.hasMoreElements();) {
                String execPath = st.nextToken() + "/hg" + execSuffix;
                File file = new File(execPath);
                if (file.isFile()) {
                    hgExecutable = file;
                    break;
                }
            }
        }

        if (hgExecutable == null && !IS_WINDOWS) {
            String extraPath[] = { "/usr/bin/hg", "/usr/local/bin/hg", // default on MacOS
                    "/opt/local/bin/hg", // if installed via MacPorts
            };

            for (String fileName : extraPath) {
                File file = new File(fileName);
                if (file.isFile()) {
                    hgExecutable = file;
                    break;
                }
            }
        }
        return hgExecutable;
    }

    private static void detectAndSetHgExecutable(IPreferenceStore store) {
        // Currently only tested on Windows. The binary is expected to be found
        // at "os\win32\x86\hg.exe" (relative to the plugin/fragment directory)
        File hgExecutable = getIntegratedHgExecutable();
        String defaultExecPath;
        String existingValue = store.getString(MERCURIAL_EXECUTABLE);

        // Use built in if possible
        if (store.getBoolean(USE_BUILT_IN_HG_EXECUTABLE) && hgExecutable != null) {
            defaultExecPath = hgExecutable.getPath();
            store.setValue(MERCURIAL_EXECUTABLE, defaultExecPath);
            store.setDefault(MERCURIAL_EXECUTABLE, defaultExecPath);
            return;
        }

        // Future: Should we ignore the integrated executable if the pref is disabled?
        if (hgExecutable == null) {
            hgExecutable = checkForPossibleHgExecutables();
        }
        if (hgExecutable == null) {
            defaultExecPath = "hg";
        } else {
            defaultExecPath = hgExecutable.getPath();
        }

        if (existingValue != null && !new File(existingValue).isFile()) {
            // If already set override if it's invalid
            store.setValue(MERCURIAL_EXECUTABLE, defaultExecPath);
        }
        store.setDefault(MERCURIAL_EXECUTABLE, defaultExecPath);
    }

    /**
     * @return an full absolute path to the embedded hg executable from the (fragment)
     * plugin. This path is guaranteed to point to an <b>existing</b> file. Returns null
     * if the file cannot be found, does not exists or is not a file at all.
     */
    public static File getIntegratedHgExecutable() {
        IPath path = IS_WINDOWS ? new Path("$os$/hg.exe") : new Path("$os$/hg");
        URL url = FileLocator.find(MercurialEclipsePlugin.getDefault().getBundle(), path, null);
        if (url == null) {
            return null;
        }
        try {
            url = FileLocator.toFileURL(url);
            File execFile = new File(url.getPath());
            if (execFile.isFile()) {
                return execFile.getAbsoluteFile();
            }
        } catch (IOException e) {
            MercurialEclipsePlugin.logError(e);
        }
        return null;
    }
}