Mercurial > hg4j
diff src/org/tmatesoft/hg/internal/Internals.java @ 411:464b4404e75d smartgit3
Issue 29: Bad storage path translation - translate Unicode chars to filesystem encoding
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 20 Mar 2012 17:56:50 +0100 |
parents | 0f5696623512 |
children | 63c5a9d7ca3f |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/Internals.java Fri Mar 16 20:19:51 2012 +0100 +++ b/src/org/tmatesoft/hg/internal/Internals.java Tue Mar 20 17:56:50 2012 +0100 @@ -21,6 +21,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -56,13 +57,30 @@ */ public static final String CFG_PROPERTY_REVLOG_STREAM_CACHE = "hg4j.repo.disable_revlog_cache"; + /** + * Name of charset to use when translating Unicode filenames to Mercurial storage paths, string, + * to resolve with {@link Charset#forName(String)}. + * E.g. <code>"cp1251"</code> or <code>"Latin-1"</code>. + * + * <p>Mercurial uses system encoding when mangling storage paths. Default value + * based on 'file.encoding' Java system property is usually fine here, however + * in certain scenarios it may be desirable to force a different one, and this + * property is exactly for this purpose. + * + * <p>E.g. Eclipse defaults to project encoding (Launch config, Common page) when launching an application, + * and if your project happen to use anything but filesystem default (say, UTF8 on cp1251 system), + * native storage paths won't match + */ + public static final String CFG_PROPERT_FS_FILENAME_ENCODING = "hg.fs.filename.encoding"; + private int requiresFlags = 0; private List<Filter.Factory> filterFactories; + private final SessionContext sessionContext; private final boolean isCaseSensitiveFileSystem; private final boolean shallCacheRevlogsInRepo; - public Internals(SessionContext ctx) { + this.sessionContext = ctx; isCaseSensitiveFileSystem = !runningOnWindows(); Object p = ctx.getProperty(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); shallCacheRevlogsInRepo = p instanceof Boolean ? ((Boolean) p).booleanValue() : Boolean.parseBoolean(String.valueOf(p)); @@ -91,7 +109,21 @@ // XXX perhaps, should keep both fields right here, not in the HgRepository public PathRewrite buildDataFilesHelper() { - return new StoragePathHelper((requiresFlags & STORE) != 0, (requiresFlags & FNCACHE) != 0, (requiresFlags & DOTENCODE) != 0); + Object altEncoding = sessionContext.getProperty(CFG_PROPERT_FS_FILENAME_ENCODING, null); + Charset cs; + if (altEncoding == null) { + cs = Charset.defaultCharset(); + } else { + try { + cs = Charset.forName(altEncoding.toString()); + } catch (IllegalArgumentException ex) { + // both IllegalCharsetNameException and UnsupportedCharsetException are subclasses of IAE, too + // not severe enough to throw an exception, imo. Just record the fact it's bad ad we ignore it + sessionContext.getLog().error(getClass(), ex, String.format("Bad configuration value for filename encoding %s", altEncoding)); + cs = Charset.defaultCharset(); + } + } + return new StoragePathHelper((requiresFlags & STORE) != 0, (requiresFlags & FNCACHE) != 0, (requiresFlags & DOTENCODE) != 0, cs); } public PathRewrite buildRepositoryFilesHelper() {