All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.git.GitModuleConfig Maven / Gradle / Ivy

There is a newer version: RELEASE240
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.git;

import java.awt.Color;
import java.awt.EventQueue;
import java.io.File;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.prefs.Preferences;
import org.netbeans.libs.git.GitURI;
import org.netbeans.modules.git.FileInformation.Mode;
import org.netbeans.modules.git.ui.repository.RepositoryInfo;
import org.netbeans.modules.git.ui.repository.remote.ConnectionSettings;
import org.netbeans.modules.versioning.util.KeyringSupport;
import org.netbeans.modules.versioning.util.Utils;
import org.openide.util.NbPreferences;

/**
 *
 * @author ondra
 */
public final class GitModuleConfig {
    
    private static GitModuleConfig instance;
    private static final String AUTO_OPEN_OUTPUT_WINDOW = "autoOpenOutput";     // NOI18N
    private static final String AUTO_REPLACE_INVALID_BRANCH_NAME_CHARACTERS = "autoReplaceInvalidBranchNameCharacters";
    public static final String PROP_COMMIT_EXCLUSIONS          = "commitExclusions";   // NOI18N
    private static final String PROP_LAST_USED_MODE     = "lastUsedMode";       // NOI18N
    private static final String EXCLUDE_NEW_FILES       = "excludeNewFiles";    // NOI18N
    private static final String RECENT_COMMIT_AUTHORS   = "recentCommitAuhtors";// NOI18N
    private static final String RECENT_COMMITERS        = "recentCommiters";    // NOI18N
    private static final String RECENT_GURI             = "recent_guri";    
    private static final String SIGN_OFF                = "signOff";            // NOI18N
    private static final String REVERT_ALL              = "revertAll";          // NOI18N
    private static final String REMOVE_ALL_NEW          = "removeAllNew";       // NOI18N
    private static final String REVERT_INDEX            = "revertIndex";        // NOI18N
    private static final String REVERT_WT               = "revertWT";           // NOI18N
    private static final String REMOVE_WT_NEW           = "removeWTNew";        // NOI18N
    private static final String PROP_LAST_USED_COMMIT_VIEW_MODE = "lastUsedCommitViewMode"; //NOI18N
    private static final String AUTO_IGNORE_FILES       = "autoIgnoreFiles"; //NOI18N
    private static final String SHOW_CLONE_COMPLETED    = "cloneCompleted.showCloneCompleted";        // NOI18N  
    private static final String GURI_PASSWORD           = "guri_password";
    private static final String GURI_PASSPHRASE           = "guri_passphrase";
    private static final String PROP_STATUS_VIEW_MODE = "statusViewMode"; //NOI18N
    private static final String PROP_DIFF_VIEW_MODE = "diffViewMode"; //NOI18N
    private static final String DELIMITER               = "<=~=>";              // NOI18N
    private static final String KEY_SHOW_HISTORY_MERGES = "showHistoryMerges"; //NOI18N
    private static final String KEY_SHOW_FILE_INFO = "showFileInfo"; //NOI18N
    private static final String KEY_SEARCH_ON_BRANCH = "searchOnBranch.enabled"; //NOI18N
    private static final String PROP_ANNOTATIONFORMAT_PROJECT = "annotationFormat.project"; //NOI18N
    private static final String KEY_ANNOTATION_DISPLAYED_FIELDS = "annotate.displayedFields"; //NOI18N
    
    private String lastCanceledCommitMessage;
    private static final String DEFAULT_ANNOTATION_PROJECT = Annotator.DEFAULT_ANNOTATION_PROJECT;
    
    public static GitModuleConfig getDefault () {
        if (instance == null) {
            instance = new GitModuleConfig();
        }
        return instance;
    }
    private Set exclusions;
    
    private GitModuleConfig() { }

    public boolean isExcludedFromCommit(String path) {
        Set commitExclusions = getCommitExclusions();        
        return commitExclusions.contains(path);
    }

    public Color getColor(String colorName, Color defaultColor) {
         int colorRGB = getPreferences().getInt(colorName, defaultColor.getRGB());
         return new Color(colorRGB);
    }

    public void setColor(String colorName, Color value) {
         getPreferences().putInt(colorName, value.getRGB());
    }

    public Preferences getPreferences() {
        return NbPreferences.forModule(GitModuleConfig.class);
    }

    public boolean getExludeNewFiles() {
        return getPreferences().getBoolean(EXCLUDE_NEW_FILES, false);
    }

    public void setExcludeNewFiles(boolean value) {
        getPreferences().putBoolean(EXCLUDE_NEW_FILES, value);
    }
    
    public String getLastCanceledCommitMessage() {
        return lastCanceledCommitMessage == null ? "" : lastCanceledCommitMessage; //NOI18N
    }

    public void setLastCanceledCommitMessage(String message) {
        lastCanceledCommitMessage = message;
    }

    /**
     * @param paths collection of paths, of File.getAbsolutePath()
     */
    public void addExclusionPaths(Collection paths) {
        Set commitExclusions = getCommitExclusions();
        if (commitExclusions.addAll(paths)) {
            Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS, new ArrayList(commitExclusions));
        }
    }

    /**
     * @param paths collection of paths, File.getAbsolutePath()
     */
    public void removeExclusionPaths(Collection paths) {
        Set commitExclusions = getCommitExclusions();
        if (commitExclusions.removeAll(paths)) {
            Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS, new ArrayList(commitExclusions));
        }
    }   

    public String getProjectAnnotationFormat () {
        return getPreferences().get(PROP_ANNOTATIONFORMAT_PROJECT, DEFAULT_ANNOTATION_PROJECT);
    }

    public void setProjectAnnotationFormat (String text) {
        getPreferences().put(PROP_ANNOTATIONFORMAT_PROJECT, text);
    }

    public boolean getAutoSyncBranch (File repository, String branch) {
        RepositoryInfo.NBGitConfig cfg = RepositoryInfo.getInstance(repository).getNetbeansConfig();
        return cfg.getAutoSyncBranch(branch);
    }

    public void setAutoSyncBranch (File repository, String branch, boolean autoSync) {
        RepositoryInfo.NBGitConfig cfg = RepositoryInfo.getInstance(repository).getNetbeansConfig();
        cfg.setAutoSyncBranch(branch, autoSync);
    }
    
    synchronized Set getCommitExclusions() {
        if (exclusions == null) {
            exclusions = new HashSet(Utils.getStringList(getPreferences(), PROP_COMMIT_EXCLUSIONS));
        }
        return exclusions;
    }  
    
    public Mode getLastUsedModificationContext () {
        Mode mode;
        try {
            mode = Mode.valueOf(getPreferences().get(PROP_LAST_USED_MODE, Mode.HEAD_VS_WORKING_TREE.name()));
        } catch (IllegalArgumentException ex) {
            mode = null;
        }
        return mode == null ? Mode.HEAD_VS_WORKING_TREE : mode;
    }

    public void setLastUsedModificationContext (Mode mode) {
        getPreferences().put(PROP_LAST_USED_MODE, mode.name());
    }    

    public Mode getLastUsedCommitViewMode () {
        Mode mode;
        try {
            mode = Mode.valueOf(getPreferences().get(PROP_LAST_USED_COMMIT_VIEW_MODE, Mode.HEAD_VS_WORKING_TREE.name()));
        } catch (IllegalArgumentException ex) {
            mode = null;
        }
        return mode == null ? Mode.HEAD_VS_WORKING_TREE : mode;
    }

    public void setLastUsedCommitViewMode (Mode mode) {
        getPreferences().put(PROP_LAST_USED_COMMIT_VIEW_MODE, mode.name());
    }
    
    public boolean getAutoOpenOutput() {
        return getPreferences().getBoolean(AUTO_OPEN_OUTPUT_WINDOW, true);
    }

    public void setAutoOpenOutput(boolean value) {
        getPreferences().putBoolean(AUTO_OPEN_OUTPUT_WINDOW, value);
    }

    public boolean getAutoReplaceInvalidBranchNameCharacters() {
        return getPreferences().getBoolean(AUTO_REPLACE_INVALID_BRANCH_NAME_CHARACTERS, true);
    }

    public void setAutoReplaceInvalidBranchNameCharacters(boolean value) {
        getPreferences().putBoolean(AUTO_REPLACE_INVALID_BRANCH_NAME_CHARACTERS, value);
    }    
    
    public void putRecentCommitAuthors(String author) {
        if(author == null) return;
        author = author.trim();
        if(author.isEmpty()) return;
        Utils.insert(getPreferences(), RECENT_COMMIT_AUTHORS, author, 10);
    }
    
    public void putRecentCommiter(String commiter) {
        if(commiter == null) return;
        commiter = commiter.trim();
        if(commiter.isEmpty()) return;
        Utils.insert(getPreferences(), RECENT_COMMITERS, commiter, 10);
    }
    
    public List getRecentCommitAuthors() {
        return Utils.getStringList(getPreferences(), RECENT_COMMIT_AUTHORS);
    }
    
    public List getRecentCommiters() {
        return Utils.getStringList(getPreferences(), RECENT_COMMITERS);
    }

    public void setSignOff(boolean value) {
        getPreferences().putBoolean(SIGN_OFF, value);
    }
    
    public boolean getSignOff() {
        return getPreferences().getBoolean(SIGN_OFF, false);
    }
    
    public void putRevertAll(boolean value) {
        getPreferences().putBoolean(REVERT_ALL, value);        
    }
    
    public void putRevertIndex(boolean value) {
        getPreferences().putBoolean(REVERT_INDEX, value);        
    }
    
    public void putRevertWT(boolean value) {
        getPreferences().putBoolean(REVERT_WT, value);        
    }
    
    public void putRemoveAllNew(boolean value) {
        getPreferences().putBoolean(REMOVE_ALL_NEW, value);        
    }
    
    public void putRemoveWTNew(boolean value) {
        getPreferences().putBoolean(REMOVE_WT_NEW, value);        
    }
    
    public boolean getRevertAll() {
        return getPreferences().getBoolean(REVERT_ALL, true);        
    }
    
    public boolean getRevertIndex() {
        return getPreferences().getBoolean(REVERT_INDEX, false);        
    }
    
    public boolean getRevertWT() {
        return getPreferences().getBoolean(REVERT_WT, true);        
    }
        
    public boolean getRemoveWTNew() {
        return getPreferences().getBoolean(REMOVE_WT_NEW, false);                
    }
    
    public boolean getRemoveAllNew() {
        return getPreferences().getBoolean(REMOVE_ALL_NEW, false);                
    }

    public boolean getAutoIgnoreFiles () {
        return getPreferences().getBoolean(AUTO_IGNORE_FILES, true);
    }

    public void setAutoIgnoreFiles (boolean flag) {
        getPreferences().putBoolean(AUTO_IGNORE_FILES, flag);
    }

    public boolean getShowCloneCompleted() {
        return getPreferences().getBoolean(SHOW_CLONE_COMPLETED, true);
    }
    
    public void setShowCloneCompleted(boolean bl) {
        getPreferences().putBoolean(SHOW_CLONE_COMPLETED, bl);
    }

    public boolean getShowHistoryMerges() {
        return getPreferences().getBoolean(KEY_SHOW_HISTORY_MERGES, true);
    }

    public void setShowHistoryMerges(boolean bShowMerges) {
        getPreferences().putBoolean(KEY_SHOW_HISTORY_MERGES, bShowMerges);
    }
    public boolean getShowFileInfo() {
        return getPreferences().getBoolean(KEY_SHOW_FILE_INFO, false);
    }
    public void setShowFileInfo(boolean info) {
        getPreferences().putBoolean(KEY_SHOW_FILE_INFO, info);
    }
    
    private final HashMap cachedConnectionSettings = new HashMap(5);
    public void insertRecentConnectionSettings (ConnectionSettings toStore) {
        assert !EventQueue.isDispatchThread();
        String guriString = getUriStringWithoutCredentials(toStore.getUri());
        if (guriString == null) {
            return;
        }        
        Preferences prefs = getPreferences();
        removeStaleEntries(prefs, guriString);
        
        if (toStore.isSaveCredentials() && (toStore.getPassphrase() != null || toStore.getPassword() != null)) {
            // keep permanently and remove from cache
            storeCredentials(toStore);
            cachedConnectionSettings.remove(guriString);
        } else {
            // remove from perm storage, we should not keep it forever
            deleteCredentials(toStore.getUri());
            // but keep until end of session
            cachedConnectionSettings.put(guriString, toStore);
        }
        
        if (!guriString.isEmpty()) {
            Utils.insert(prefs, RECENT_GURI, new GitConnectionSettingsEntry(guriString, toStore).toString(), -1);
        }
    }

    public void removeConnectionSettings (GitURI toRemove) {
        assert !EventQueue.isDispatchThread();
        String guriString = getUriStringWithoutCredentials(toRemove);
        if (guriString == null) {
            return;
        }        
        Preferences prefs = getPreferences();
        removeStaleEntries(prefs, guriString);
        
        cachedConnectionSettings.remove(guriString);
        deleteCredentials(toRemove);
    }

    private void removeStaleEntries (Preferences prefs, String guriString) {
        List urlValues = Utils.getStringList(prefs, RECENT_GURI);
        for (Iterator it = urlValues.iterator(); it.hasNext();) {
            String rcOldString = it.next();
            GitURI guriOld = null;
            try {
                GitConnectionSettingsEntry entry = GitConnectionSettingsEntry.create(rcOldString);
                if(entry != null) {
                    guriOld = new GitURI(entry.guriString);
                }
            } catch (URISyntaxException ex) {
                Git.LOG.log(Level.WARNING, rcOldString, ex);
            }
            if(guriString.equals(guriOld.toString())) {
                Utils.removeFromArray(prefs, RECENT_GURI, rcOldString);
            }
        }
    }    
    
    public List getRecentConnectionSettings () {
        assert !EventQueue.isDispatchThread();
        
        Preferences prefs = getPreferences();
        List urls = Utils.getStringList(prefs, RECENT_GURI);
        List ret = new ArrayList(urls.size());
        for (String guriString : urls) {
            GitConnectionSettingsEntry entry = GitConnectionSettingsEntry.create(guriString);
            if (entry == null) {
                continue;
            }
            // before we contact keyring, check the cache:
            ConnectionSettings connSettings = cachedConnectionSettings.get(entry.guriString);
            if (connSettings == null) {
                connSettings = entry.toConnectionSettings();
                if (connSettings.isPrivateKeyAuth()) {
                    char[] passphrase = KeyringSupport.read(GURI_PASSPHRASE, connSettings.getUri().toString());
                    connSettings.setPassphrase(passphrase == null ? new char[0] : passphrase);
                } else {
                    char[] password = KeyringSupport.read(GURI_PASSWORD, connSettings.getUri().toString());
                    connSettings.setPassword(password == null ? new char[0] : password);
                }
            }
            ret.add(connSettings);
        }
        return ret;
    }
    
    public ConnectionSettings getConnectionSettings (String uriString) {
        assert !EventQueue.isDispatchThread();
        ConnectionSettings retval = null;
        String username = null;
        try {
            GitURI uri = new GitURI(uriString);
            username = uri.getUser();
            uriString = getUriStringWithoutCredentials(uri);
        } catch (URISyntaxException ex) {
            //
        }
        
        // before we contact keyring, check the cache:
        ConnectionSettings cachedSetting = cachedConnectionSettings.get(uriString);
        if (cachedSetting != null && (username == null || cachedSetting.getUser() == null || username.equals(cachedSetting.getUser()))) {
            return cachedSetting.copy();
        }
        
        Preferences prefs = getPreferences();
        List urls = Utils.getStringList(prefs, RECENT_GURI);
        for (String guriString : urls) {
            GitConnectionSettingsEntry entry = GitConnectionSettingsEntry.create(guriString);
            if (entry == null) {
                continue;
            }
            ConnectionSettings storedSettings = entry.toConnectionSettings();
            if (uriString.equals(entry.guriString) && (username == null || storedSettings.getUser() == null || username.equals(storedSettings.getUser()))) {
                if (storedSettings.isPrivateKeyAuth()) {
                    char[] passphrase = KeyringSupport.read(GURI_PASSPHRASE, storedSettings.getUri().toString());
                    storedSettings.setPassphrase(passphrase == null ? new char[0] : passphrase);
                } else {
                    char[] password = KeyringSupport.read(GURI_PASSWORD, storedSettings.getUri().toString());
                    storedSettings.setPassword(password == null ? new char[0] : password);
                }
                retval = storedSettings;
                break;
            }
        }
        return retval;
    }

    private void storeCredentials (ConnectionSettings settings) {
        assert !EventQueue.isDispatchThread();
        GitURI uri = settings.getUri().setUser(settings.getUser());
        KeyringSupport.save(GURI_PASSWORD, uri.toString(), settings.getPassword(), null);
        KeyringSupport.save(GURI_PASSPHRASE, uri.toString(), settings.getPassphrase(), null);
    }
    
    private void deleteCredentials (GitURI guri) {
        assert !EventQueue.isDispatchThread();
        KeyringSupport.save(GURI_PASSWORD, guri.toString(), null, null);
        KeyringSupport.save(GURI_PASSPHRASE, guri.toString(), null, null);
    }

    private String getUriStringWithoutCredentials (GitURI guri) {
        String guriString = null;
        if (guri != null) {
            guriString = guri.setUser(null).setPass(null).toString();
        }
        return guriString;
    }

    public int getDiffViewMode (int def) {
        return getPreferences().getInt(PROP_DIFF_VIEW_MODE, def);
    }

    public void setDiffViewMode (int value) {
        getPreferences().putInt(PROP_DIFF_VIEW_MODE, value);
    }

    public int getStatusViewMode (int def) {
        return getPreferences().getInt(PROP_STATUS_VIEW_MODE, def);
    }

    public void setStatusViewMode (int value) {
        getPreferences().putInt(PROP_STATUS_VIEW_MODE, value);
    }
    
    public boolean isSearchOnlyCurrentBranchEnabled () {
        return getPreferences().getBoolean(KEY_SEARCH_ON_BRANCH, true);
    }

    public void setSearchOnlyCurrentBranchEnabled (boolean enabled) {
        getPreferences().putBoolean(KEY_SEARCH_ON_BRANCH, enabled);
    }
    
    public void setAnnotationDisplayedFields (int value) {
        getPreferences().putInt(KEY_ANNOTATION_DISPLAYED_FIELDS, value);
    }
    
    public int getAnnotationDisplayedFields (int defaultValue) {
        return getPreferences().getInt(KEY_ANNOTATION_DISPLAYED_FIELDS, defaultValue);
    }
    
    private static class GitConnectionSettingsEntry {
        final String guriString;
        private String stringValue;
        private final ConnectionSettings settings;
        static GitConnectionSettingsEntry create (String entryString) {
            String[] s = entryString.split(DELIMITER);
            assert s.length > 0;
            try {
                return new GitConnectionSettingsEntry(s[0], parse(s));
            } catch (URISyntaxException ex) {
                Git.LOG.log(Level.WARNING, "Cannot parse stored connection settings: {0}, {1}", new Object[] { s, ex.getMessage() });
                return null;
            }
        }
        GitConnectionSettingsEntry (String guriString, ConnectionSettings setts) {
            this.guriString = guriString;
            this.settings = setts;
        }
        @Override
        public String toString() {
            if(stringValue == null) {
                StringBuilder sb = new StringBuilder();
                sb.append(guriString);
                sb.append(DELIMITER);
                sb.append(settings.getUser() == null ? "" : settings.getUser());
                sb.append(DELIMITER);
                sb.append(settings.isSaveCredentials() ? "1" : "0"); //NOI18N
                sb.append(DELIMITER);
                sb.append(settings.isPrivateKeyAuth() ? "1" : "0"); //NOI18N
                sb.append(DELIMITER);
                sb.append(settings.getIdentityFile());
                stringValue = sb.toString();
            }
            return stringValue;
        }

        private static ConnectionSettings parse (String[] s) throws URISyntaxException {
            String uri = s[0].trim();
            ConnectionSettings setts = new ConnectionSettings(new GitURI(uri));
            if (s.length > 1) {
                setts.setUser(s[1].isEmpty() ? null : s[1]);
            }
            if (s.length > 2) {
                setts.setSaveCredentials("1".equals(s[2]));
            }
            if (s.length > 3) {
                setts.setPrivateKeyAuth("1".equals(s[3]));
            }
            if (s.length > 4) {
                setts.setIdentityFile(s[4]);
            }
            return setts;
        }

        private ConnectionSettings toConnectionSettings () {
            return settings;
        }
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy