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 |
