Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/Internals.java @ 414:bb278ccf9866
Pull changes from smartgit3 branch
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 21 Mar 2012 20:51:12 +0100 |
parents | 7f27122011c3 63c5a9d7ca3f |
children | ee8264d80747 |
comparison
equal
deleted
inserted
replaced
413:7f27122011c3 | 414:bb278ccf9866 |
---|---|
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; |
28 import java.util.Iterator; | |
27 import java.util.LinkedHashSet; | 29 import java.util.LinkedHashSet; |
28 import java.util.List; | 30 import java.util.List; |
29 import java.util.StringTokenizer; | 31 import java.util.StringTokenizer; |
30 | 32 |
31 import org.tmatesoft.hg.core.SessionContext; | 33 import org.tmatesoft.hg.core.SessionContext; |
53 * 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? |
54 * (@see HgRepository#getChangelog and #getManifest()) | 56 * (@see HgRepository#getChangelog and #getManifest()) |
55 */ | 57 */ |
56 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"; |
57 | 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_PROPERTY_FS_FILENAME_ENCODING = "hg.fs.filename.encoding"; | |
75 | |
58 private int requiresFlags = 0; | 76 private int requiresFlags = 0; |
59 private List<Filter.Factory> filterFactories; | 77 private List<Filter.Factory> filterFactories; |
78 private final SessionContext sessionContext; | |
60 private final boolean isCaseSensitiveFileSystem; | 79 private final boolean isCaseSensitiveFileSystem; |
61 private final boolean shallCacheRevlogsInRepo; | 80 private final boolean shallCacheRevlogsInRepo; |
62 | |
63 | 81 |
64 public Internals(SessionContext ctx) { | 82 public Internals(SessionContext ctx) { |
83 this.sessionContext = ctx; | |
65 isCaseSensitiveFileSystem = !runningOnWindows(); | 84 isCaseSensitiveFileSystem = !runningOnWindows(); |
66 Object p = ctx.getProperty(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); | 85 Object p = ctx.getProperty(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); |
67 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)); |
68 } | 87 } |
69 | 88 |
80 requiresFlags = flags; | 99 requiresFlags = flags; |
81 } | 100 } |
82 | 101 |
83 public PathRewrite buildNormalizePathRewrite() { | 102 public PathRewrite buildNormalizePathRewrite() { |
84 if (runningOnWindows()) { | 103 if (runningOnWindows()) { |
85 return new PathRewrite() { | 104 return new WinToNixPathRewrite(); |
86 | |
87 public CharSequence rewrite(CharSequence p) { | |
88 // TODO handle . and .. (although unlikely to face them from GUI client) | |
89 String path = p.toString(); | |
90 path = path.replace('\\', '/').replace("//", "/"); | |
91 if (path.startsWith("/")) { | |
92 path = path.substring(1); | |
93 } | |
94 return path; | |
95 } | |
96 }; | |
97 } else { | 105 } else { |
98 return new PathRewrite.Empty(); // or strip leading slash, perhaps? | 106 return new PathRewrite.Empty(); // or strip leading slash, perhaps? |
99 } | 107 } |
100 } | 108 } |
101 | 109 |
102 // 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 |
103 public PathRewrite buildDataFilesHelper() { | 111 public PathRewrite buildDataFilesHelper() { |
104 return new StoragePathHelper((requiresFlags & STORE) != 0, (requiresFlags & FNCACHE) != 0, (requiresFlags & DOTENCODE) != 0); | 112 // Note, tests in TestStorePath depend on the encoding not being cached |
113 Charset cs = getFileEncoding(); | |
114 // StoragePathHelper needs fine-grained control over char encoding, hence doesn't use EncodingHelper | |
115 return new StoragePathHelper((requiresFlags & STORE) != 0, (requiresFlags & FNCACHE) != 0, (requiresFlags & DOTENCODE) != 0, cs); | |
105 } | 116 } |
106 | 117 |
107 public PathRewrite buildRepositoryFilesHelper() { | 118 public PathRewrite buildRepositoryFilesHelper() { |
108 if ((requiresFlags & STORE) != 0) { | 119 if ((requiresFlags & STORE) != 0) { |
109 return new PathRewrite() { | 120 return new PathRewrite() { |
153 new File(hgDir, "store").mkdir(); // with that, hg verify says ok. | 164 new File(hgDir, "store").mkdir(); // with that, hg verify says ok. |
154 } | 165 } |
155 | 166 |
156 public boolean isCaseSensitiveFileSystem() { | 167 public boolean isCaseSensitiveFileSystem() { |
157 return isCaseSensitiveFileSystem; | 168 return isCaseSensitiveFileSystem; |
169 } | |
170 | |
171 public EncodingHelper buildFileNameEncodingHelper() { | |
172 return new EncodingHelper(getFileEncoding()); | |
173 } | |
174 | |
175 private Charset getFileEncoding() { | |
176 Object altEncoding = sessionContext.getProperty(CFG_PROPERTY_FS_FILENAME_ENCODING, null); | |
177 Charset cs; | |
178 if (altEncoding == null) { | |
179 cs = Charset.defaultCharset(); | |
180 } else { | |
181 try { | |
182 cs = Charset.forName(altEncoding.toString()); | |
183 } catch (IllegalArgumentException ex) { | |
184 // both IllegalCharsetNameException and UnsupportedCharsetException are subclasses of IAE, too | |
185 // not severe enough to throw an exception, imo. Just record the fact it's bad ad we ignore it | |
186 sessionContext.getLog().error(Internals.class, ex, String.format("Bad configuration value for filename encoding %s", altEncoding)); | |
187 cs = Charset.defaultCharset(); | |
188 } | |
189 } | |
190 return cs; | |
158 } | 191 } |
159 | 192 |
160 public static boolean runningOnWindows() { | 193 public static boolean runningOnWindows() { |
161 return System.getProperty("os.name").indexOf("Windows") != -1; | 194 return System.getProperty("os.name").indexOf("Windows") != -1; |
162 } | 195 } |
341 } | 374 } |
342 | 375 |
343 public boolean shallCacheRevlogs() { | 376 public boolean shallCacheRevlogs() { |
344 return shallCacheRevlogsInRepo; | 377 return shallCacheRevlogsInRepo; |
345 } | 378 } |
379 | |
380 public static <T> CharSequence join(Iterable<T> col, CharSequence separator) { | |
381 if (col == null) { | |
382 return String.valueOf(col); | |
383 } | |
384 Iterator<T> it = col.iterator(); | |
385 if (!it.hasNext()) { | |
386 return "[]"; | |
387 } | |
388 String v = String.valueOf(it.next()); | |
389 StringBuilder sb = new StringBuilder(v); | |
390 while (it.hasNext()) { | |
391 sb.append(separator); | |
392 v = String.valueOf(it.next()); | |
393 sb.append(v); | |
394 } | |
395 return sb; | |
396 } | |
346 } | 397 } |