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() {