Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/Internals.java @ 493:ba36f66c32b4
Refactor to keep knowledge about repository control files and their location in respect to .hg/ in a single place (facilitate future adoption of shared repositories)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 18 Oct 2012 18:36:13 +0200 |
parents | b3c16d1aede0 |
children | d2f6ab541330 |
comparison
equal
deleted
inserted
replaced
492:e4eaa23e3442 | 493:ba36f66c32b4 |
---|---|
14 * the terms of a license other than GNU General Public License | 14 * the terms of a license other than GNU General Public License |
15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
16 */ | 16 */ |
17 package org.tmatesoft.hg.internal; | 17 package org.tmatesoft.hg.internal; |
18 | 18 |
19 import static org.tmatesoft.hg.internal.RequiresFile.*; | |
20 import static org.tmatesoft.hg.util.LogFacility.Severity.Error; | 19 import static org.tmatesoft.hg.util.LogFacility.Severity.Error; |
21 | 20 |
22 import java.io.File; | 21 import java.io.File; |
23 import java.io.IOException; | 22 import java.io.IOException; |
24 import java.nio.charset.Charset; | 23 import java.nio.charset.Charset; |
29 import java.util.LinkedHashSet; | 28 import java.util.LinkedHashSet; |
30 import java.util.List; | 29 import java.util.List; |
31 import java.util.StringTokenizer; | 30 import java.util.StringTokenizer; |
32 | 31 |
33 import org.tmatesoft.hg.core.SessionContext; | 32 import org.tmatesoft.hg.core.SessionContext; |
34 import org.tmatesoft.hg.repo.HgInvalidControlFileException; | 33 import org.tmatesoft.hg.repo.HgDataFile; |
34 import org.tmatesoft.hg.repo.HgRuntimeException; | |
35 import org.tmatesoft.hg.repo.HgRepoConfig.ExtensionsSection; | 35 import org.tmatesoft.hg.repo.HgRepoConfig.ExtensionsSection; |
36 import org.tmatesoft.hg.repo.HgRepository; | 36 import org.tmatesoft.hg.repo.HgRepository; |
37 import org.tmatesoft.hg.util.PathRewrite; | 37 import org.tmatesoft.hg.util.PathRewrite; |
38 | 38 |
39 /** | 39 /** |
71 * and if your project happen to use anything but filesystem default (say, UTF8 on cp1251 system), | 71 * and if your project happen to use anything but filesystem default (say, UTF8 on cp1251 system), |
72 * native storage paths won't match | 72 * native storage paths won't match |
73 */ | 73 */ |
74 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"; |
75 | 75 |
76 private int requiresFlags = 0; | |
77 private List<Filter.Factory> filterFactories; | 76 private List<Filter.Factory> filterFactories; |
78 private final HgRepository repo; | 77 private final HgRepository repo; |
79 private final File repoDir; | 78 private final File repoDir; |
80 private final boolean isCaseSensitiveFileSystem; | 79 private final boolean isCaseSensitiveFileSystem; |
81 private final boolean shallCacheRevlogsInRepo; | 80 private final boolean shallCacheRevlogsInRepo; |
82 private final DataAccessProvider dataAccess; | 81 private final DataAccessProvider dataAccess; |
83 | 82 |
84 public Internals(HgRepository hgRepo, File hgDir) { | 83 @SuppressWarnings("unused") |
84 private final int requiresFlags; | |
85 | |
86 private final PathRewrite dataPathHelper; // access to file storage area (usually under .hg/store/data/), with filenames mangled | |
87 private final PathRewrite repoPathHelper; // access to system files (under .hg/store if requires has 'store' flag) | |
88 | |
89 public Internals(HgRepository hgRepo, File hgDir) throws HgRuntimeException { | |
85 repo = hgRepo; | 90 repo = hgRepo; |
86 repoDir = hgDir; | 91 repoDir = hgDir; |
87 isCaseSensitiveFileSystem = !runningOnWindows(); | 92 isCaseSensitiveFileSystem = !runningOnWindows(); |
88 SessionContext ctx = repo.getSessionContext(); | 93 SessionContext ctx = repo.getSessionContext(); |
89 shallCacheRevlogsInRepo = new PropertyMarshal(ctx).getBoolean(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); | 94 shallCacheRevlogsInRepo = new PropertyMarshal(ctx).getBoolean(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); |
90 dataAccess = new DataAccessProvider(ctx); | 95 dataAccess = new DataAccessProvider(ctx); |
96 RepoInitializer repoInit = new RepoInitializer().initRequiresFromFile(repoDir); | |
97 requiresFlags = repoInit.getRequires(); | |
98 dataPathHelper = repoInit.buildDataFilesHelper(getContext()); | |
99 repoPathHelper = repoInit.buildStoreFilesHelper(); | |
91 } | 100 } |
92 | 101 |
93 public boolean isInvalid() { | 102 public boolean isInvalid() { |
94 return !repoDir.exists() || !repoDir.isDirectory(); | 103 return !repoDir.exists() || !repoDir.isDirectory(); |
95 } | 104 } |
96 | 105 |
106 /** | |
107 * Access files under ".hg/". | |
108 * File not necessarily exists, this method is merely a factory for Files at specific, configuration-dependent location. | |
109 * | |
110 * @param name shall be normalized path | |
111 */ | |
97 public File getFileFromRepoDir(String name) { | 112 public File getFileFromRepoDir(String name) { |
98 return new File(repoDir, name); | 113 return new File(repoDir, name); |
99 } | 114 } |
115 | |
116 /** | |
117 * Access files under ".hg/store/" or ".hg/" depending on use of 'store' in requires. | |
118 * File not necessarily exists, this method is merely a factory for Files at specific, configuration-dependent location. | |
119 * | |
120 * @param name shall be normalized path | |
121 */ | |
122 public File getFileFromStoreDir(String name) { | |
123 CharSequence location = repoPathHelper.rewrite(name); | |
124 return new File(repoDir, location.toString()); | |
125 } | |
126 | |
127 /** | |
128 * Access files under ".hg/store/data", ".hg/store/dh/" or ".hg/data" according to settings in requires file. | |
129 * File not necessarily exists, this method is merely a factory for Files at specific, configuration-dependent location. | |
130 * | |
131 * @param name shall be normalized path, without .i or .d suffixes | |
132 */ | |
133 public File getFileFromDataDir(CharSequence path) { | |
134 CharSequence storagePath = dataPathHelper.rewrite(path); | |
135 return new File(repoDir, storagePath.toString()); | |
136 } | |
100 | 137 |
101 public SessionContext getContext() { | 138 public SessionContext getContext() { |
102 return repo.getSessionContext(); | 139 return repo.getSessionContext(); |
103 } | 140 } |
104 | 141 |
108 | 145 |
109 public DataAccessProvider getDataAccess() { | 146 public DataAccessProvider getDataAccess() { |
110 return dataAccess; | 147 return dataAccess; |
111 } | 148 } |
112 | 149 |
113 public void parseRequires() throws HgInvalidControlFileException { | |
114 File requiresFile =getFileFromRepoDir("requires"); | |
115 try { | |
116 new RequiresFile().parse(this, requiresFile); | |
117 } catch (IOException ex) { | |
118 throw new HgInvalidControlFileException("Parse failed", ex, requiresFile); | |
119 } | |
120 } | |
121 | |
122 public/*for tests, otherwise pkg*/ void setStorageConfig(int version, int flags) { | |
123 requiresFlags = flags; | |
124 } | |
125 | |
126 public PathRewrite buildNormalizePathRewrite() { | 150 public PathRewrite buildNormalizePathRewrite() { |
127 if (runningOnWindows()) { | 151 if (runningOnWindows()) { |
128 return new WinToNixPathRewrite(); | 152 return new WinToNixPathRewrite(); |
129 } else { | 153 } else { |
130 return new PathRewrite.Empty(); // or strip leading slash, perhaps? | 154 return new PathRewrite.Empty(); // or strip leading slash, perhaps? |
131 } | |
132 } | |
133 | |
134 // XXX perhaps, should keep both fields right here, not in the HgRepository | |
135 public PathRewrite buildDataFilesHelper() { | |
136 return new RepoInitializer().setRequires(requiresFlags).buildDataFilesHelper(getContext()); | |
137 } | |
138 | |
139 public PathRewrite buildRepositoryFilesHelper() { | |
140 if ((requiresFlags & STORE) != 0) { | |
141 return new PathRewrite() { | |
142 public CharSequence rewrite(CharSequence path) { | |
143 return "store/" + path; | |
144 } | |
145 }; | |
146 } else { | |
147 return new PathRewrite.Empty(); | |
148 } | 155 } |
149 } | 156 } |
150 | 157 |
151 public List<Filter.Factory> getFilters() { | 158 public List<Filter.Factory> getFilters() { |
152 if (filterFactories == null) { | 159 if (filterFactories == null) { |
190 cs = Charset.defaultCharset(); | 197 cs = Charset.defaultCharset(); |
191 } | 198 } |
192 } | 199 } |
193 return cs; | 200 return cs; |
194 } | 201 } |
202 | |
203 /** | |
204 * Access to mangled name of a file in repository storage, may come handy for debug. | |
205 * @return mangled path of the repository file | |
206 */ | |
207 public CharSequence getStoragePath(HgDataFile df) { | |
208 return dataPathHelper.rewrite(df.getPath().toString()); | |
209 } | |
210 | |
195 | 211 |
196 public static boolean runningOnWindows() { | 212 public static boolean runningOnWindows() { |
197 return System.getProperty("os.name").indexOf("Windows") != -1; | 213 return System.getProperty("os.name").indexOf("Windows") != -1; |
198 } | 214 } |
199 | 215 |