Mercurial > jhg
comparison 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 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 410:df5009d67be2 | 411:464b4404e75d | 
|---|---|
| 19 import static org.tmatesoft.hg.internal.RequiresFile.*; | 19 import static org.tmatesoft.hg.internal.RequiresFile.*; | 
| 20 | 20 | 
| 21 import java.io.File; | 21 import java.io.File; | 
| 22 import java.io.FileOutputStream; | 22 import java.io.FileOutputStream; | 
| 23 import java.io.IOException; | 23 import java.io.IOException; | 
| 24 import java.nio.charset.Charset; | |
| 24 import java.util.ArrayList; | 25 import java.util.ArrayList; | 
| 25 import java.util.Arrays; | 26 import java.util.Arrays; | 
| 26 import java.util.Collections; | 27 import java.util.Collections; | 
| 27 import java.util.Iterator; | 28 import java.util.Iterator; | 
| 28 import java.util.LinkedHashSet; | 29 import java.util.LinkedHashSet; | 
| 54 * XXX perhaps, need to respect this property not only for data files, but for manifest and changelog as well? | 55 * XXX perhaps, need to respect this property not only for data files, but for manifest and changelog as well? | 
| 55 * (@see HgRepository#getChangelog and #getManifest()) | 56 * (@see HgRepository#getChangelog and #getManifest()) | 
| 56 */ | 57 */ | 
| 57 public static final String CFG_PROPERTY_REVLOG_STREAM_CACHE = "hg4j.repo.disable_revlog_cache"; | 58 public static final String CFG_PROPERTY_REVLOG_STREAM_CACHE = "hg4j.repo.disable_revlog_cache"; | 
| 58 | 59 | 
| 60 /** | |
| 61 * Name of charset to use when translating Unicode filenames to Mercurial storage paths, string, | |
| 62 * to resolve with {@link Charset#forName(String)}. | |
| 63 * E.g. <code>"cp1251"</code> or <code>"Latin-1"</code>. | |
| 64 * | |
| 65 * <p>Mercurial uses system encoding when mangling storage paths. Default value | |
| 66 * based on 'file.encoding' Java system property is usually fine here, however | |
| 67 * in certain scenarios it may be desirable to force a different one, and this | |
| 68 * property is exactly for this purpose. | |
| 69 * | |
| 70 * <p>E.g. Eclipse defaults to project encoding (Launch config, Common page) when launching an application, | |
| 71 * and if your project happen to use anything but filesystem default (say, UTF8 on cp1251 system), | |
| 72 * native storage paths won't match | |
| 73 */ | |
| 74 public static final String CFG_PROPERT_FS_FILENAME_ENCODING = "hg.fs.filename.encoding"; | |
| 75 | |
| 59 private int requiresFlags = 0; | 76 private int requiresFlags = 0; | 
| 60 private List<Filter.Factory> filterFactories; | 77 private List<Filter.Factory> filterFactories; | 
| 78 private final SessionContext sessionContext; | |
| 61 private final boolean isCaseSensitiveFileSystem; | 79 private final boolean isCaseSensitiveFileSystem; | 
| 62 private final boolean shallCacheRevlogsInRepo; | 80 private final boolean shallCacheRevlogsInRepo; | 
| 63 | |
| 64 | 81 | 
| 65 public Internals(SessionContext ctx) { | 82 public Internals(SessionContext ctx) { | 
| 83 this.sessionContext = ctx; | |
| 66 isCaseSensitiveFileSystem = !runningOnWindows(); | 84 isCaseSensitiveFileSystem = !runningOnWindows(); | 
| 67 Object p = ctx.getProperty(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); | 85 Object p = ctx.getProperty(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); | 
| 68 shallCacheRevlogsInRepo = p instanceof Boolean ? ((Boolean) p).booleanValue() : Boolean.parseBoolean(String.valueOf(p)); | 86 shallCacheRevlogsInRepo = p instanceof Boolean ? ((Boolean) p).booleanValue() : Boolean.parseBoolean(String.valueOf(p)); | 
| 69 } | 87 } | 
| 70 | 88 | 
| 89 } | 107 } | 
| 90 } | 108 } | 
| 91 | 109 | 
| 92 // XXX perhaps, should keep both fields right here, not in the HgRepository | 110 // XXX perhaps, should keep both fields right here, not in the HgRepository | 
| 93 public PathRewrite buildDataFilesHelper() { | 111 public PathRewrite buildDataFilesHelper() { | 
| 94 return new StoragePathHelper((requiresFlags & STORE) != 0, (requiresFlags & FNCACHE) != 0, (requiresFlags & DOTENCODE) != 0); | 112 Object altEncoding = sessionContext.getProperty(CFG_PROPERT_FS_FILENAME_ENCODING, null); | 
| 113 Charset cs; | |
| 114 if (altEncoding == null) { | |
| 115 cs = Charset.defaultCharset(); | |
| 116 } else { | |
| 117 try { | |
| 118 cs = Charset.forName(altEncoding.toString()); | |
| 119 } catch (IllegalArgumentException ex) { | |
| 120 // both IllegalCharsetNameException and UnsupportedCharsetException are subclasses of IAE, too | |
| 121 // not severe enough to throw an exception, imo. Just record the fact it's bad ad we ignore it | |
| 122 sessionContext.getLog().error(getClass(), ex, String.format("Bad configuration value for filename encoding %s", altEncoding)); | |
| 123 cs = Charset.defaultCharset(); | |
| 124 } | |
| 125 } | |
| 126 return new StoragePathHelper((requiresFlags & STORE) != 0, (requiresFlags & FNCACHE) != 0, (requiresFlags & DOTENCODE) != 0, cs); | |
| 95 } | 127 } | 
| 96 | 128 | 
| 97 public PathRewrite buildRepositoryFilesHelper() { | 129 public PathRewrite buildRepositoryFilesHelper() { | 
| 98 if ((requiresFlags & STORE) != 0) { | 130 if ((requiresFlags & STORE) != 0) { | 
| 99 return new PathRewrite() { | 131 return new PathRewrite() { | 
