/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.internal.wc;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.io.svn.ISVNConnector;
import org.tmatesoft.svn.core.internal.io.svn.SVNTunnelConnector;
import org.tmatesoft.svn.core.internal.util.SVNHashMap;
import org.tmatesoft.svn.core.wc.ISVNConflictHandler;
import org.tmatesoft.svn.core.wc.ISVNMerger;
import org.tmatesoft.svn.core.wc.ISVNMergerFactory;
import org.tmatesoft.svn.core.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
/**
* @version 1.3
* @author TMate Software Ltd.
*/
public class DefaultSVNOptions implements ISVNOptions, ISVNMergerFactory {
private static final String MISCELLANY_GROUP = "miscellany";
private static final String AUTH_GROUP = "auth";
private static final String AUTOPROPS_GROUP = "auto-props";
private static final String SVNKIT_GROUP = "svnkit";
private static final String OLD_SVNKIT_GROUP = "javasvn";
private static final String HELPERS_GROUP = "helpers";
private static final String HTTP_SPOOL_DIRECTORY = "http-spool-directory";
private static final String USE_COMMIT_TIMES = "use-commit-times";
private static final String GLOBAL_IGNORES = "global-ignores";
private static final String ENABLE_AUTO_PROPS = "enable-auto-props";
private static final String STORE_AUTH_CREDS = "store-auth-creds";
private static final String KEYWORD_TIMEZONE = "keyword_timezone";
private static final String KEYWORD_LOCALE = "keyword_locale";
private static final String EDITOR_CMD = "editor-cmd";
private static final String DIFF_CMD = "diff-cmd";
private static final String MERGE_TOOL_CMD = "merge-tool-cmd";
private static final String NO_UNLOCK = "no-unlock";
private static final String LOG_ENCODING = "log-encoding";
private static final String PRESERVED_CONFLICT_FILE_EXTENSIONS = "preserved-conflict-file-exts";
private static final String INTERACTIVE_COFLICTS = "interactive-conflicts";
private static final String MIME_TYPES_FILE = "mime-types-file";
private static final String GLOBAL_CHARSET = "global-charset";
private static final String PASSWORD_STORES = "password-stores";
private static final String DEFAULT_IGNORES = "*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store";
private static final String YES = "yes";
private static final String NO = "no";
private static final String DEFAULT_LOCALE = Locale.getDefault().toString();
private static final String DEFAULT_TIMEZONE = TimeZone.getDefault().getID();
private static final String[] DEFAULT_PASSWORD_STORE_TYPES = new String[]{
DefaultSVNPersistentAuthenticationProvider.WINDOWS_CRYPTO_API_PASSWORD_STORAGE,
DefaultSVNPersistentAuthenticationProvider.MAC_OS_KEYCHAIN_PASSWORD_STORAGE,
DefaultSVNPersistentAuthenticationProvider.GNOME_KEYRING_PASSWORD_STORAGE
};
private boolean myIsReadonly;
private File myConfigDirectory;
private SVNCompositeConfigFile myConfigFile;
private ISVNMergerFactory myMergerFactory;
private ISVNConflictHandler myConflictResolver;
private String myKeywordLocale = DEFAULT_LOCALE;
private String myKeywordTimezone = DEFAULT_TIMEZONE;
private SimpleDateFormat myKeywordDateFormat = new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss' 'ZZZZ' ('E', 'dd' 'MMM' 'yyyy')'");
private Map myConfigOptions;
public DefaultSVNOptions() {
this(null, true);
}
public DefaultSVNOptions(File directory, boolean readOnly) {
myConfigDirectory = directory == null ? getDefaultConfigDir() : directory;
myIsReadonly = readOnly;
}
public boolean isUseCommitTimes() {
String value = getConfigFile().getPropertyValue(MISCELLANY_GROUP, USE_COMMIT_TIMES);
return getBooleanValue(value, false);
}
public void setInMemoryConfigOptions(Map configOptions) {
myConfigOptions = configOptions;
if (myConfigFile != null) {
myConfigFile.setGroupsToOptions(myConfigOptions);
}
}
/**
* Enables or disables the commit-times option.
*
* <p>
* The commit-times option makes checkout/update/switch/revert operations put
* last-committed timestamps on every file they touch.
*
* <p>
* This option corresponds to
* the <i>'use-commit-times'</i> option that can be found in the
* SVN's <i>config</i> file under the <i>[miscellany]</i> section.
*
* @param useCommitTimes <span class="javakeyword">true</span> to
* enable commit-times, <span class="javakeyword">false</span>
* to disable
* @see #isUseCommitTimes()
*/
public void setUseCommitTimes(boolean useCommitTimes) {
getConfigFile().setPropertyValue(MISCELLANY_GROUP, USE_COMMIT_TIMES, useCommitTimes ? YES : NO, !myIsReadonly);
}
/**
* Determines if the autoproperties option is enabled.
*
* <p>
* Autoproperties are the properties that are automatically set
* on files when they are added or imported.
*
* <p>
* This option corresponds to the <i>'enable-auto-props'</i> option
* that can be found in the SVN's <i>config</i> file under the
* <i>[miscellany]</i> section.
*
* @return <span class="javakeyword">true</span> if autoproperties
* are enabled, otherwise <span class="javakeyword">false</span>
*/
public boolean isUseAutoProperties() {
String value = getConfigFile().getPropertyValue(MISCELLANY_GROUP, ENABLE_AUTO_PROPS);
return getBooleanValue(value, false);
}
/**
* Enables or disables the autoproperties option.
*
* <p>
* Autoproperties are the properties that are automatically set
* on files when they are added or imported.
*
* <p>
* This option corresponds to the <i>'enable-auto-props'</i> option
* that can be found in the SVN's <i>config</i> file under the
* <i>[miscellany]</i> section.
*
* @param useAutoProperties <span class="javakeyword">true</span> to
* enable autoproperties, <span class="javakeyword">false</span>
* to disable
* @see #isUseAutoProperties()
*/
public void setUseAutoProperties(boolean useAutoProperties) {
getConfigFile().setPropertyValue(MISCELLANY_GROUP, ENABLE_AUTO_PROPS, useAutoProperties ? YES : NO, !myIsReadonly);
}
/**
* Determines if the authentication storage is enabled.
*
* <p>
* The auth storage is used for disk-caching of all
* authentication information: usernames, passwords, server certificates,
* and any other types of cacheable credentials.
*
* <p>
* This option corresponds to the
* <i>'store-auth-creds'</i> option that can be found
* in the SVN's <i>config</i> file under the <i>[auth]</i> section.
*
* @return <span class="javakeyword">true</span> if auth storage
* is enabled, otherwise <span class="javakeyword">false</span>
*/
public boolean isAuthStorageEnabled() {
String value = getConfigFile().getPropertyValue(AUTH_GROUP, STORE_AUTH_CREDS);
return getBooleanValue(value, true);
}
public boolean isKeepLocks() {
String value = getConfigFile().getPropertyValue(MISCELLANY_GROUP, NO_UNLOCK);
return getBooleanValue(value, false);
}
/**
* Enables or disables the authentication storage.
*
* <p>
* The auth storage is used for disk-caching of all
* authentication information: usernames, passwords, server certificates,
* and any other types of cacheable credentials.
*
* <p>
* This option corresponds to the
* <i>'store-auth-creds'</i> option that can be found
* in the SVN's <i>config</i> file under the <i>[auth]</i> section.
*
* @param storeAuth <span class="javakeyword">true</span> to
* enable the auth storage, <span class="javakeyword">false</span>
* to disable
* @see #isAuthStorageEnabled()
*/
public void setAuthStorageEnabled(boolean storeAuth) {
getConfigFile().setPropertyValue(AUTH_GROUP, STORE_AUTH_CREDS, storeAuth ? YES : NO, !myIsReadonly);
}
public void setKeepLocks(boolean keep) {
getConfigFile().setPropertyValue(MISCELLANY_GROUP, NO_UNLOCK, keep ? YES : NO, !myIsReadonly);
}
public static boolean isIgnored(ISVNOptions options, String name) {
String[] patterns = options.getIgnorePatterns();
for (int i = 0; patterns != null && i < patterns.length; i++) {
String pattern = patterns[i];
if (matches(pattern, name)) {
return true;
}
}
return false;
}
public String[] getIgnorePatterns() {
String value = getConfigFile().getPropertyValue(MISCELLANY_GROUP, GLOBAL_IGNORES);
if (value == null) {
value = DEFAULT_IGNORES;
}
Collection tokensList = new ArrayList();
for (StringTokenizer tokens = new StringTokenizer(value, " \t"); tokens.hasMoreTokens();) {
String token = tokens.nextToken();
if ("".equals(token)) {
continue;
}
tokensList.add(token);
}
return (String[]) tokensList.toArray(new String[tokensList.size()]);
}
/**
* Sets global ignore patterns.
*
* <p>
* The global ignore patterns describe the names of
* files and directories that SVNKit should ignore during status, add and
* import operations. Similar to the
* <i>'global-ignores'</i> option that can be found in the SVN's <i>config</i>
* file under the <i>[miscellany]</i> section.
*
* <p>
* For example, to set all <code>.exe</code> files to be ignored include
* <code>"*.exe"</code> pattern into <code>patterns</code>.
*
* <p>
* If <code>patterns</code> is <span class="javakeyword">null</span> or
* empty then all the patterns will be removed.
*
* @param patterns an array of patterns (that usually contain wildcards)
* that specify file and directory names to be ignored until
* they are versioned
* @see #getIgnorePatterns()
*/
public void setIgnorePatterns(String[] patterns) {
if (patterns == null || patterns.length == 0) {
getConfigFile().setPropertyValue(MISCELLANY_GROUP, GLOBAL_IGNORES, null, !myIsReadonly);
return;
}
StringBuffer value = new StringBuffer();
for (int i = 0; i < patterns.length; i++) {
String pattern = patterns[i];
if (pattern != null && !"".equals(pattern.trim())) {
value.append(pattern);
value.append(" ");
}
}
String valueStr = value.toString().trim();
if ("".equals(valueStr)) {
valueStr = null;
}
getConfigFile().setPropertyValue(MISCELLANY_GROUP, GLOBAL_IGNORES, valueStr, !myIsReadonly);
}
/**
* Removes a particular global ignore pattern.
*
* @param pattern a patterna to be removed
* @see #addIgnorePattern(String)
*/
public void deleteIgnorePattern(String pattern) {
if (pattern == null) {
return;
}
String[] patterns = getIgnorePatterns();
Collection newPatterns = new ArrayList();
for (int i = 0; i < patterns.length; i++) {
String s = patterns[i];
if (!s.equals(pattern)) {
newPatterns.add(s);
}
}
patterns = (String[]) newPatterns.toArray(new String[newPatterns.size()]);
setIgnorePatterns(patterns);
}
/**
* Adds a new particular ignore pattern to global
* ignore patterns.
*
* @param pattern an ignore pattern to be added
* @see #deleteIgnorePattern(String)
*/
public void addIgnorePattern(String pattern) {
if (pattern == null) {
return;
}
String[] patterns = getIgnorePatterns();
Collection oldPatterns = new ArrayList(Arrays.asList(patterns));
if (!oldPatterns.contains(pattern)) {
oldPatterns.add(pattern);
patterns = (String[]) oldPatterns.toArray(new String[oldPatterns.size()]);
setIgnorePatterns(patterns);
}
}
/**
* Returns autoproperties as a {@link java.util.Map}
* where each key is a file name pattern and the corresponding
* value is a string in the form of <code>"propName=propValue"</code>.
*
* @return a {@link java.util.Map} containing autoproperties
*/
public Map getAutoProperties() {
return getConfigFile().getProperties(AUTOPROPS_GROUP);
}
/**
* Sets autoproperties that will be automatically put on all files
* that will be added or imported.
*
* <p>
* There can be several properties specified for one file pattern -
* they should be delimited by ";".
*
* @param autoProperties a {@link java.util.Map} which keys are file
* name patterns and their values are strings
* in the form of <code>"propName=propValue"</code>
* @see #getAutoProperties()
*/
public void setAutoProperties(Map autoProperties) {
autoProperties = autoProperties == null ? Collections.EMPTY_MAP : autoProperties;
Map existingProperties = getAutoProperties();
for (Iterator names = existingProperties.keySet().iterator(); names.hasNext();) {
String pattern = (String) names.next();
String value = (String) existingProperties.get(pattern);
if (value.equals(autoProperties.get(pattern))) {
continue;
}
getConfigFile().setPropertyValue(AUTOPROPS_GROUP, pattern, null, false);
names.remove();
}
// add all new
for (Iterator names = autoProperties.keySet().iterator(); names.hasNext();) {
String pattern = (String) names.next();
String value = (String) autoProperties.get(pattern);
if (value.equals(existingProperties.get(pattern))) {
continue;
}
getConfigFile().setPropertyValue(AUTOPROPS_GROUP, pattern, value, false);
}
if (!myIsReadonly) {
getConfigFile().save();
}
}
public String getEditor() {
return getConfigFile().getPropertyValue(HELPERS_GROUP, EDITOR_CMD);
}
public String getMergeTool() {
return getConfigFile().getPropertyValue(HELPERS_GROUP, MERGE_TOOL_CMD);
}
/**
* Removes a particular autoproperty by specifying a file name
* pattern.
*
* @param pattern a file name pattern
* @see #setAutoProperty(String, String)
*
*/
public void deleteAutoProperty(String pattern) {
getConfigFile().setPropertyValue(AUTOPROPS_GROUP, pattern, null, !myIsReadonly);
}
/**
* Sets an autoproperty - binds a file name pattern with a
* string in the form of <code>"propName=propValue"</code>.
*
* @param pattern a file name pattern (usually containing
* wildcards)
* @param properties a property for <code>pattern</code>
*/
public void setAutoProperty(String pattern, String properties) {
getConfigFile().setPropertyValue(AUTOPROPS_GROUP, pattern, properties, !myIsReadonly);
}
public boolean isInteractiveConflictResolution() {
String value = getConfigFile().getPropertyValue(MISCELLANY_GROUP, INTERACTIVE_COFLICTS);
return getBooleanValue(value, true);
}
public void setInteractiveConflictResolution(boolean interactive) {
getConfigFile().setPropertyValue(MISCELLANY_GROUP, INTERACTIVE_COFLICTS, interactive ? YES : NO, !myIsReadonly);
}
public Map applyAutoProperties(File file, Map target) {
String fileName = file.getName();
target = target == null ? new SVNHashMap() : target;
if (!isUseAutoProperties()) {
return target;
}
Map autoProperties = getAutoProperties();
for (Iterator names = autoProperties.keySet().iterator(); names.hasNext();) {
String pattern = (String) names.next();
String value = (String) autoProperties.get(pattern);
if (value != null && !"".equals(value) && matches(pattern, fileName)) {
StringBuffer token = new StringBuffer();
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
if (ch == ';' || i == value.length() - 1) {
if (i + 1 < value.length() && value.charAt(i + 1) == ';') {
// escaped ;
token.append(';');
i++;
if (i < value.length() - 1) {
continue;
}
// escaped at the end of the line.
}
if (ch != ';') {
// just last character.
token.append(ch);
}
// another token.
String t = token.toString().trim();
int index = t.indexOf('=');
if (index < 0) {
target.put(t, "");
} else {
String name = t.substring(0, index).trim();
String pValue = index == t.length() - 1 ? "" : t.substring(index + 1).trim();
if (!"".equals(name.trim())) {
if (pValue.startsWith("\"") && pValue.endsWith("\"") && pValue.length() > 1) {
pValue = pValue.substring(1, pValue.length() - 1);
} else if (pValue.startsWith("\'") && pValue.endsWith("\'") && pValue.length() > 1) {
pValue = pValue.substring(1, pValue.length() - 1);
}
target.put(name, pValue);
}
}
token = token.delete(0, token.length());
} else {
token.append(ch);
}
}
}
}
return target;
}
public ISVNMergerFactory getMergerFactory() {
if (myMergerFactory == null) {
return this;
}
return myMergerFactory;
}
/**
* Sets a factory object which is responsible for creating
* merger drivers.
*
* @param mergerFactory a factory that produces merger drivers
* for merge operations
* @see #getMergerFactory()
*/
public void setMergerFactory(ISVNMergerFactory mergerFactory) {
myMergerFactory = mergerFactory;
}
/**
* Returns the value of a property from the <i>[svnkit]</i> section
* of the <i>config</i> file.
*
* @param propertyName a SVNKit specific config property name
* @return the value of the property
*/
public String getPropertyValue(String propertyName) {
if (propertyName == null) {
return null;
}
String value = getConfigFile().getPropertyValue(SVNKIT_GROUP, propertyName);
if (value == null) {
value = getConfigFile().getPropertyValue(OLD_SVNKIT_GROUP, propertyName);
}
return value;
}
public File getHttpSpoolDirectory() {
final String spoolDirectory = getPropertyValue(HTTP_SPOOL_DIRECTORY);
if (spoolDirectory != null) {
return new File(spoolDirectory);
}
return null;
}
/**
* Sets the value of a property from the <i>[svnkit]</i> section
* of the <i>config</i> file.
*
* @param propertyName a SVNKit specific config property name
* @param propertyValue a new value for the property; if
* <span class="javakeyword">null</span> the
* property is removed
*/
public void setPropertyValue(String propertyName, String propertyValue) {
if (propertyName == null || "".equals(propertyName.trim())) {
return;
}
getConfigFile().setPropertyValue(SVNKIT_GROUP, propertyName, propertyValue, !myIsReadonly);
}
public void setConflictHandler(ISVNConflictHandler resolver) {
myConflictResolver = resolver;
}
public ISVNConflictHandler getConflictResolver() {
return myConflictResolver;
}
public static boolean matches(String pattern, String fileName) {
if (pattern == null || fileName == null) {
return false;
}
Pattern compiled = compileNamePatter(pattern);
if (compiled != null) {
return compiled.matcher(fileName).matches();
}
return false;
}
public ISVNMerger createMerger(byte[] conflictStart, byte[] conflictSeparator, byte[] conflictEnd) {
return new DefaultSVNMerger(conflictStart, conflictSeparator, conflictEnd, myConflictResolver, SVNDiffConflictChoiceStyle.CHOOSE_MODIFIED_LATEST);
}
public ISVNConnector createTunnelConnector(SVNURL url) {
String subProtocolName = url.getProtocol().substring("svn+".length());
if (subProtocolName == null) {
return null;
}
Map tunnels = getConfigFile().getProperties("tunnels");
final String tunnel = (String)tunnels.get(subProtocolName);
if (tunnel == null) {
return null;
}
return new SVNTunnelConnector(subProtocolName, tunnel);
}
public DateFormat getKeywordDateFormat() {
String localeID = getConfigFile().getPropertyValue(SVNKIT_GROUP, KEYWORD_LOCALE);
if (localeID == null) {
localeID = DEFAULT_LOCALE;
}
String tzID = getConfigFile().getPropertyValue(SVNKIT_GROUP, KEYWORD_TIMEZONE);
if (tzID == null) {
tzID = DEFAULT_TIMEZONE;
}
if (!myKeywordTimezone.equals(tzID)) {
TimeZone tz = TimeZone.getTimeZone(tzID);
myKeywordTimezone = tzID;
synchronized (myKeywordDateFormat) {
myKeywordDateFormat.setTimeZone(tz);
}
}
if (!myKeywordLocale.equals(localeID)) {
Locale newLocale = toLocale(localeID);
if (newLocale == null) {
newLocale = Locale.getDefault();
}
myKeywordLocale = localeID;
synchronized (myKeywordDateFormat) {
myKeywordDateFormat.setCalendar(Calendar.getInstance(myKeywordDateFormat.getTimeZone(), newLocale));
myKeywordDateFormat.setDateFormatSymbols(new DateFormatSymbols(newLocale));
}
}
return myKeywordDateFormat;
}
public String[] getPreservedConflictFileExtensions() {
String value = getConfigFile().getPropertyValue(MISCELLANY_GROUP, PRESERVED_CONFLICT_FILE_EXTENSIONS);
if (value == null) {
value = "";
}
Collection tokensList = new ArrayList();
for (StringTokenizer tokens = new StringTokenizer(value, " \n\r\t"); tokens.hasMoreTokens();) {
String token = tokens.nextToken();
if ("".equals(token)) {
continue;
}
tokensList.add(token);
}
return (String[]) tokensList.toArray(new String[tokensList.size()]);
}
public boolean isAllowAllForwardMergesFromSelf() {
return false;
}
public String getLogEncoding() {
return getConfigFile().getPropertyValue(MISCELLANY_GROUP, LOG_ENCODING);
}
public String getGlobalCharset() {
return getPropertyValue(GLOBAL_CHARSET);
}
public void setGlobalCharset(String charset) {
setPropertyValue(GLOBAL_CHARSET, charset);
}
public String getNativeCharset() {
return System.getProperty("file.encoding");
}
public byte[] getNativeEOL() {
return System.getProperty("line.separator").getBytes();
}
public Map getFileExtensionsToMimeTypes() {
String mimeTypesFile = getConfigFile().getPropertyValue(MISCELLANY_GROUP, MIME_TYPES_FILE);
if (mimeTypesFile == null) {
return null;
}
BufferedReader reader = null;
Map extensionsToMimeTypes = new SVNHashMap();
try {
reader = new BufferedReader(new FileReader(mimeTypesFile));
LinkedList tokensList = new LinkedList();
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) {
continue;
}
tokensList.clear();
for (StringTokenizer tokens = new StringTokenizer(line, " \t"); tokens.hasMoreTokens();) {
String token = tokens.nextToken();
if ("".equals(token)) {
continue;
}
tokensList.add(token);
}
if (tokensList.size() < 2) {
continue;
}
String mimeType = (String) tokensList.get(0);
for (int i = 1; i < tokensList.size(); i++) {
String extension = (String) tokensList.get(i);
extensionsToMimeTypes.put(extension, mimeType);
}
}
} catch (IOException e) {
return null;
} finally {
SVNFileUtil.closeFile(reader);
}
return extensionsToMimeTypes;
}
public String getDiffCommand() {
return getConfigFile().getPropertyValue(HELPERS_GROUP, DIFF_CMD);
}
public void setDiffCommand(String diffCmd) {
getConfigFile().setPropertyValue(HELPERS_GROUP, DIFF_CMD, diffCmd, !myIsReadonly);
}
public String[] getPasswordStorageTypes() {
String storeTypesOption = getConfigFile().getPropertyValue(AUTH_GROUP, PASSWORD_STORES);
if (storeTypesOption == null) {
return DEFAULT_PASSWORD_STORE_TYPES;
}
List storeTypes = new ArrayList();
for (StringTokenizer types = new StringTokenizer(storeTypesOption, " ,"); types.hasMoreTokens();) {
String type = types.nextToken();
type = type == null ? null : type.trim();
if (type != null && !"".equals(type)) {
storeTypes.add(type);
}
}
return (String[]) storeTypes.toArray(new String[storeTypes.size()]);
}
private String getDefaultSSHCommandLine() {
Map tunnels = getConfigFile().getProperties("tunnels");
if (tunnels == null || !tunnels.containsKey("ssh")) {
return null;
}
return (String) tunnels.get("ssh");
}
private String getDefaultSSHOptionValue(String optionName, String systemProperty, String fallbackSystemProperty) {
if (optionName != null) {
String sshCommandLine = getDefaultSSHCommandLine();
if (sshCommandLine != null) {
String value = getOptionValue(sshCommandLine, optionName);
if (value != null) {
return value;
}
}
}
return System.getProperty(systemProperty, System.getProperty(fallbackSystemProperty));
}
public int getDefaultSSHPortNumber() {
String sshCommandLine = getDefaultSSHCommandLine();
if (sshCommandLine == null) {
return -1;
}
final String portOption = sshCommandLine.toLowerCase().trim().startsWith("plink") ? "-p" : "-P";
String port = getDefaultSSHOptionValue(portOption, "svnkit.ssh2.port", "javasvn.ssh2.port");
if (port != null) {
try {
return Integer.parseInt(port);
} catch (NumberFormatException e) {
//
}
}
return -1;
}
public String getDefaultSSHUserName() {
String userName = getDefaultSSHOptionValue("-l", "svnkit.ssh2.username", "javasvn.ssh2.username");
if (userName == null) {
userName = System.getProperty("user.name");
}
return userName;
}
public String getDefaultSSHPassword() {
return getDefaultSSHOptionValue("-pw", "svnkit.ssh2.password", "javasvn.ssh2.password");
}
public String getDefaultSSHKeyFile() {
return getDefaultSSHOptionValue("-i", "svnkit.ssh2.key", "javasvn.ssh2.key");
}
public String getDefaultSSHPassphrase() {
return getDefaultSSHOptionValue(null, "svnkit.ssh2.passphrase", "javasvn.ssh2.passphrase");
}
private SVNCompositeConfigFile getConfigFile() {
if (myConfigFile == null) {
SVNConfigFile.createDefaultConfiguration(myConfigDirectory);
SVNConfigFile userConfig = new SVNConfigFile(new File(myConfigDirectory, "config"));
SVNConfigFile systemConfig = new SVNConfigFile(new File(SVNFileUtil.getSystemConfigurationDirectory(), "config"));
myConfigFile = new SVNCompositeConfigFile(systemConfig, userConfig);
myConfigFile.setGroupsToOptions(myConfigOptions);
}
return myConfigFile;
}
private static String getOptionValue(String commandLine, String optionName) {
if (commandLine == null || optionName == null) {
return null;
}
for (StringTokenizer options = new StringTokenizer(commandLine, " \r\n\t"); options.hasMoreTokens();) {
String option = options.nextToken().trim();
if (optionName.equals(option) && options.hasMoreTokens()) {
return options.nextToken();
} else if (option.startsWith(optionName)) {
return option.substring(optionName.length());
}
}
return null;
}
private static Pattern compileNamePatter(String wildcard) {
if (wildcard == null) {
return null;
}
StringBuffer result = new StringBuffer();
for (int i = 0; i < wildcard.length(); i++) {
char ch = wildcard.charAt(i);
switch (ch) {
case '?':
result.append(".");
break;
case '*':
result.append(".*");
break;
case '\\':
if (i + 1 < wildcard.length()) {
ch = wildcard.charAt(i + 1);
if (ch == '\\') {
i++;
} else {
break;
}
}
case '.':
case '!':
case '$':
case '(':
case ')':
case '+':
case '<':
case '>':
case '|':
case '^':
case '{':
case '}':
result.append("\\");
default:
result.append(ch);
}
}
try {
return Pattern.compile(result.toString());
} catch (PatternSyntaxException e) {
return null;
}
}
private static Locale toLocale(String str) {
if (str == null) {
return null;
}
int len = str.length();
if (len != 2 && len != 5 && len < 7) {
return null;
}
char ch0 = str.charAt(0);
char ch1 = str.charAt(1);
if (ch0 < 'a' || ch0 > 'z' || ch1 < 'a' || ch1 > 'z') {
return null;
}
if (len == 2) {
return new Locale(str, "");
}
if (str.charAt(2) != '_') {
return null;
}
char ch3 = str.charAt(3);
char ch4 = str.charAt(4);
if (ch3 < 'A' || ch3 > 'Z' || ch4 < 'A' || ch4 > 'Z') {
return null;
}
if (len == 5) {
return new Locale(str.substring(0, 2), str.substring(3, 5));
}
if (str.charAt(5) != '_') {
return null;
}
return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
}
private static File getDefaultConfigDir() {
return SVNWCUtil.getDefaultConfigurationDirectory();
}
public static boolean getBooleanValue(String value, boolean defaultValue) {
if (value == null) {
return defaultValue;
}
value = value.trim();
return YES.equalsIgnoreCase(value) || "true".equalsIgnoreCase(value)
|| "on".equalsIgnoreCase(value);
}
}