Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/Internals.java @ 490:b3c16d1aede0
Refactoring: move HgRepository's implementation aspects to Internals (which is now its imlementation counterpart and primary repository class to be used by other parts of the library)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 16 Aug 2012 17:08:34 +0200 |
parents | e31e85cf4d4c |
children | ba36f66c32b4 |
comparison
equal
deleted
inserted
replaced
489:9c0138cda59a | 490:b3c16d1aede0 |
---|---|
18 | 18 |
19 import static org.tmatesoft.hg.internal.RequiresFile.*; | 19 import static org.tmatesoft.hg.internal.RequiresFile.*; |
20 import static org.tmatesoft.hg.util.LogFacility.Severity.Error; | 20 import static org.tmatesoft.hg.util.LogFacility.Severity.Error; |
21 | 21 |
22 import java.io.File; | 22 import java.io.File; |
23 import java.io.FileOutputStream; | |
24 import java.io.IOException; | 23 import java.io.IOException; |
25 import java.nio.charset.Charset; | 24 import java.nio.charset.Charset; |
26 import java.util.ArrayList; | 25 import java.util.ArrayList; |
27 import java.util.Arrays; | 26 import java.util.Arrays; |
28 import java.util.Collections; | 27 import java.util.Collections; |
30 import java.util.LinkedHashSet; | 29 import java.util.LinkedHashSet; |
31 import java.util.List; | 30 import java.util.List; |
32 import java.util.StringTokenizer; | 31 import java.util.StringTokenizer; |
33 | 32 |
34 import org.tmatesoft.hg.core.SessionContext; | 33 import org.tmatesoft.hg.core.SessionContext; |
35 import org.tmatesoft.hg.repo.HgInternals; | |
36 import org.tmatesoft.hg.repo.HgInvalidControlFileException; | 34 import org.tmatesoft.hg.repo.HgInvalidControlFileException; |
37 import org.tmatesoft.hg.repo.HgRepoConfig.ExtensionsSection; | 35 import org.tmatesoft.hg.repo.HgRepoConfig.ExtensionsSection; |
38 import org.tmatesoft.hg.repo.HgRepository; | 36 import org.tmatesoft.hg.repo.HgRepository; |
39 import org.tmatesoft.hg.util.PathRewrite; | 37 import org.tmatesoft.hg.util.PathRewrite; |
40 | 38 |
75 */ | 73 */ |
76 public static final String CFG_PROPERTY_FS_FILENAME_ENCODING = "hg.fs.filename.encoding"; | 74 public static final String CFG_PROPERTY_FS_FILENAME_ENCODING = "hg.fs.filename.encoding"; |
77 | 75 |
78 private int requiresFlags = 0; | 76 private int requiresFlags = 0; |
79 private List<Filter.Factory> filterFactories; | 77 private List<Filter.Factory> filterFactories; |
80 private final SessionContext sessionContext; | 78 private final HgRepository repo; |
79 private final File repoDir; | |
81 private final boolean isCaseSensitiveFileSystem; | 80 private final boolean isCaseSensitiveFileSystem; |
82 private final boolean shallCacheRevlogsInRepo; | 81 private final boolean shallCacheRevlogsInRepo; |
83 | 82 private final DataAccessProvider dataAccess; |
84 public Internals(SessionContext ctx) { | 83 |
85 sessionContext = ctx; | 84 public Internals(HgRepository hgRepo, File hgDir) { |
85 repo = hgRepo; | |
86 repoDir = hgDir; | |
86 isCaseSensitiveFileSystem = !runningOnWindows(); | 87 isCaseSensitiveFileSystem = !runningOnWindows(); |
88 SessionContext ctx = repo.getSessionContext(); | |
87 shallCacheRevlogsInRepo = new PropertyMarshal(ctx).getBoolean(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); | 89 shallCacheRevlogsInRepo = new PropertyMarshal(ctx).getBoolean(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); |
88 } | 90 dataAccess = new DataAccessProvider(ctx); |
89 | 91 } |
90 public void parseRequires(HgRepository hgRepo, File requiresFile) throws HgInvalidControlFileException { | 92 |
93 public boolean isInvalid() { | |
94 return !repoDir.exists() || !repoDir.isDirectory(); | |
95 } | |
96 | |
97 public File getFileFromRepoDir(String name) { | |
98 return new File(repoDir, name); | |
99 } | |
100 | |
101 public SessionContext getContext() { | |
102 return repo.getSessionContext(); | |
103 } | |
104 | |
105 public HgRepository getRepo() { | |
106 return repo; | |
107 } | |
108 | |
109 public DataAccessProvider getDataAccess() { | |
110 return dataAccess; | |
111 } | |
112 | |
113 public void parseRequires() throws HgInvalidControlFileException { | |
114 File requiresFile =getFileFromRepoDir("requires"); | |
91 try { | 115 try { |
92 new RequiresFile().parse(this, requiresFile); | 116 new RequiresFile().parse(this, requiresFile); |
93 } catch (IOException ex) { | 117 } catch (IOException ex) { |
94 throw new HgInvalidControlFileException("Parse failed", ex, requiresFile); | 118 throw new HgInvalidControlFileException("Parse failed", ex, requiresFile); |
95 } | 119 } |
107 } | 131 } |
108 } | 132 } |
109 | 133 |
110 // XXX perhaps, should keep both fields right here, not in the HgRepository | 134 // XXX perhaps, should keep both fields right here, not in the HgRepository |
111 public PathRewrite buildDataFilesHelper() { | 135 public PathRewrite buildDataFilesHelper() { |
112 // Note, tests in TestStorePath depend on the encoding not being cached | 136 return new RepoInitializer().setRequires(requiresFlags).buildDataFilesHelper(getContext()); |
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); | |
116 } | 137 } |
117 | 138 |
118 public PathRewrite buildRepositoryFilesHelper() { | 139 public PathRewrite buildRepositoryFilesHelper() { |
119 if ((requiresFlags & STORE) != 0) { | 140 if ((requiresFlags & STORE) != 0) { |
120 return new PathRewrite() { | 141 return new PathRewrite() { |
125 } else { | 146 } else { |
126 return new PathRewrite.Empty(); | 147 return new PathRewrite.Empty(); |
127 } | 148 } |
128 } | 149 } |
129 | 150 |
130 public List<Filter.Factory> getFilters(HgRepository hgRepo) { | 151 public List<Filter.Factory> getFilters() { |
131 if (filterFactories == null) { | 152 if (filterFactories == null) { |
132 filterFactories = new ArrayList<Filter.Factory>(); | 153 filterFactories = new ArrayList<Filter.Factory>(); |
133 ExtensionsSection cfg = hgRepo.getConfiguration().getExtensions(); | 154 ExtensionsSection cfg = repo.getConfiguration().getExtensions(); |
134 if (cfg.isEnabled("eol")) { | 155 if (cfg.isEnabled("eol")) { |
135 NewlineFilter.Factory ff = new NewlineFilter.Factory(); | 156 NewlineFilter.Factory ff = new NewlineFilter.Factory(); |
136 ff.initialize(hgRepo); | 157 ff.initialize(repo); |
137 filterFactories.add(ff); | 158 filterFactories.add(ff); |
138 } | 159 } |
139 if (cfg.isEnabled("keyword")) { | 160 if (cfg.isEnabled("keyword")) { |
140 KeywordFilter.Factory ff = new KeywordFilter.Factory(); | 161 KeywordFilter.Factory ff = new KeywordFilter.Factory(); |
141 ff.initialize(hgRepo); | 162 ff.initialize(repo); |
142 filterFactories.add(ff); | 163 filterFactories.add(ff); |
143 } | 164 } |
144 } | 165 } |
145 return filterFactories; | 166 return filterFactories; |
146 } | |
147 | |
148 public void initEmptyRepository(File hgDir) throws IOException { | |
149 hgDir.mkdir(); | |
150 FileOutputStream requiresFile = new FileOutputStream(new File(hgDir, "requires")); | |
151 StringBuilder sb = new StringBuilder(40); | |
152 sb.append("revlogv1\n"); | |
153 if ((requiresFlags & STORE) != 0) { | |
154 sb.append("store\n"); | |
155 } | |
156 if ((requiresFlags & FNCACHE) != 0) { | |
157 sb.append("fncache\n"); | |
158 } | |
159 if ((requiresFlags & DOTENCODE) != 0) { | |
160 sb.append("dotencode\n"); | |
161 } | |
162 requiresFile.write(sb.toString().getBytes()); | |
163 requiresFile.close(); | |
164 new File(hgDir, "store").mkdir(); // with that, hg verify says ok. | |
165 } | 167 } |
166 | 168 |
167 public boolean isCaseSensitiveFileSystem() { | 169 public boolean isCaseSensitiveFileSystem() { |
168 return isCaseSensitiveFileSystem; | 170 return isCaseSensitiveFileSystem; |
169 } | 171 } |
170 | 172 |
171 public EncodingHelper buildFileNameEncodingHelper() { | 173 public EncodingHelper buildFileNameEncodingHelper() { |
172 return new EncodingHelper(getFileEncoding(), sessionContext); | 174 SessionContext ctx = repo.getSessionContext(); |
173 } | 175 return new EncodingHelper(getFileEncoding(ctx), ctx); |
174 | 176 } |
175 private Charset getFileEncoding() { | 177 |
176 Object altEncoding = sessionContext.getConfigurationProperty(CFG_PROPERTY_FS_FILENAME_ENCODING, null); | 178 /*package-local*/ static Charset getFileEncoding(SessionContext ctx) { |
179 Object altEncoding = ctx.getConfigurationProperty(CFG_PROPERTY_FS_FILENAME_ENCODING, null); | |
177 Charset cs; | 180 Charset cs; |
178 if (altEncoding == null) { | 181 if (altEncoding == null) { |
179 cs = Charset.defaultCharset(); | 182 cs = Charset.defaultCharset(); |
180 } else { | 183 } else { |
181 try { | 184 try { |
182 cs = Charset.forName(altEncoding.toString()); | 185 cs = Charset.forName(altEncoding.toString()); |
183 } catch (IllegalArgumentException ex) { | 186 } catch (IllegalArgumentException ex) { |
184 // both IllegalCharsetNameException and UnsupportedCharsetException are subclasses of IAE, too | 187 // 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 | 188 // not severe enough to throw an exception, imo. Just record the fact it's bad ad we ignore it |
186 sessionContext.getLog().dump(Internals.class, Error, ex, String.format("Bad configuration value for filename encoding %s", altEncoding)); | 189 ctx.getLog().dump(Internals.class, Error, ex, String.format("Bad configuration value for filename encoding %s", altEncoding)); |
187 cs = Charset.defaultCharset(); | 190 cs = Charset.defaultCharset(); |
188 } | 191 } |
189 } | 192 } |
190 return cs; | 193 return cs; |
191 } | 194 } |
243 } | 246 } |
244 | 247 |
245 /** | 248 /** |
246 * @see http://www.selenic.com/mercurial/hgrc.5.html | 249 * @see http://www.selenic.com/mercurial/hgrc.5.html |
247 */ | 250 */ |
248 public ConfigFile readConfiguration(HgRepository hgRepo, File repoRoot) throws IOException { | 251 public ConfigFile readConfiguration() throws IOException { |
249 // XXX Internals now have sessionContext field, is there real need to extract one from the repo? | 252 SessionContext sessionCtx = repo.getSessionContext(); |
250 SessionContext sessionCtx = HgInternals.getContext(hgRepo); | |
251 ConfigFile configFile = new ConfigFile(sessionCtx); | 253 ConfigFile configFile = new ConfigFile(sessionCtx); |
252 File hgInstallRoot = findHgInstallRoot(sessionCtx); // may be null | 254 File hgInstallRoot = findHgInstallRoot(sessionCtx); // may be null |
253 // | 255 // |
254 if (runningOnWindows()) { | 256 if (runningOnWindows()) { |
255 if (hgInstallRoot != null) { | 257 if (hgInstallRoot != null) { |
286 configFile.addLocation(new File("/etc/mercurial/hgrc")); | 288 configFile.addLocation(new File("/etc/mercurial/hgrc")); |
287 configFile.addLocation(new File(System.getenv("HOME"), ".hgrc")); | 289 configFile.addLocation(new File(System.getenv("HOME"), ".hgrc")); |
288 } | 290 } |
289 // last one, overrides anything else | 291 // last one, overrides anything else |
290 // <repo>/.hg/hgrc | 292 // <repo>/.hg/hgrc |
291 configFile.addLocation(new File(repoRoot, "hgrc")); | 293 configFile.addLocation(getFileFromRepoDir("hgrc")); |
292 return configFile; | 294 return configFile; |
293 } | 295 } |
294 | 296 |
295 private static List<File> getWindowsConfigFilesPerInstall(File hgInstallDir) { | 297 private static List<File> getWindowsConfigFilesPerInstall(File hgInstallDir) { |
296 File f = new File(hgInstallDir, "Mercurial.ini"); | 298 File f = new File(hgInstallDir, "Mercurial.ini"); |