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");