Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/HgRepository.java @ 591:e447384f3771
CommitFacility as internal class; refactored infrastructure around internals (access to RevlogStream)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 30 Apr 2013 18:55:42 +0200 |
parents | 36e36b926747 |
children | 5c68567b3645 |
comparison
equal
deleted
inserted
replaced
590:8cbc2a883d95 | 591:e447384f3771 |
---|---|
21 | 21 |
22 import java.io.File; | 22 import java.io.File; |
23 import java.io.FileReader; | 23 import java.io.FileReader; |
24 import java.io.IOException; | 24 import java.io.IOException; |
25 import java.io.StringReader; | 25 import java.io.StringReader; |
26 import java.lang.ref.SoftReference; | |
27 import java.nio.CharBuffer; | 26 import java.nio.CharBuffer; |
28 import java.util.ArrayList; | 27 import java.util.ArrayList; |
29 import java.util.Collections; | 28 import java.util.Collections; |
30 import java.util.HashMap; | |
31 import java.util.List; | 29 import java.util.List; |
32 | 30 |
33 import org.tmatesoft.hg.core.Nodeid; | 31 import org.tmatesoft.hg.core.Nodeid; |
34 import org.tmatesoft.hg.core.SessionContext; | 32 import org.tmatesoft.hg.core.SessionContext; |
35 import org.tmatesoft.hg.internal.ByteArrayChannel; | 33 import org.tmatesoft.hg.internal.ByteArrayChannel; |
92 /** | 90 /** |
93 * Name of the primary branch, "default". | 91 * Name of the primary branch, "default". |
94 */ | 92 */ |
95 public static final String DEFAULT_BRANCH_NAME = "default"; | 93 public static final String DEFAULT_BRANCH_NAME = "default"; |
96 | 94 |
97 private final File repoDir; // .hg folder | |
98 private final File workingDir; // .hg/../ | 95 private final File workingDir; // .hg/../ |
99 private final String repoLocation; | 96 private final String repoLocation; |
100 /* | 97 /* |
101 * normalized slashes but otherwise regular file names | 98 * normalized slashes but otherwise regular file names |
102 * the only front-end path rewrite, kept here as rest of the library shall | 99 * the only front-end path rewrite, kept here as rest of the library shall |
112 private HgMergeState mergeState; | 109 private HgMergeState mergeState; |
113 private SubrepoManager subRepos; | 110 private SubrepoManager subRepos; |
114 private HgBookmarks bookmarks; | 111 private HgBookmarks bookmarks; |
115 private HgExtensionsManager extManager; | 112 private HgExtensionsManager extManager; |
116 | 113 |
117 // XXX perhaps, shall enable caching explicitly | |
118 private final HashMap<Path, SoftReference<RevlogStream>> streamsCache = new HashMap<Path, SoftReference<RevlogStream>>(); | |
119 | |
120 private final org.tmatesoft.hg.internal.Internals impl; | 114 private final org.tmatesoft.hg.internal.Internals impl; |
121 private HgIgnore ignore; | 115 private HgIgnore ignore; |
122 private HgRepoConfig repoConfig; | 116 private HgRepoConfig repoConfig; |
123 | 117 |
124 /* | 118 /* |
128 */ | 122 */ |
129 private String wcBranch; | 123 private String wcBranch; |
130 | 124 |
131 | 125 |
132 HgRepository(String repositoryPath) { | 126 HgRepository(String repositoryPath) { |
133 repoDir = null; | |
134 workingDir = null; | 127 workingDir = null; |
135 repoLocation = repositoryPath; | 128 repoLocation = repositoryPath; |
136 normalizePath = null; | 129 normalizePath = null; |
137 sessionContext = null; | 130 sessionContext = null; |
138 impl = null; | 131 impl = null; |
144 HgRepository(SessionContext ctx, String repositoryPath, File repositoryRoot) throws HgRuntimeException { | 137 HgRepository(SessionContext ctx, String repositoryPath, File repositoryRoot) throws HgRuntimeException { |
145 assert ".hg".equals(repositoryRoot.getName()) && repositoryRoot.isDirectory(); | 138 assert ".hg".equals(repositoryRoot.getName()) && repositoryRoot.isDirectory(); |
146 assert repositoryPath != null; | 139 assert repositoryPath != null; |
147 assert repositoryRoot != null; | 140 assert repositoryRoot != null; |
148 assert ctx != null; | 141 assert ctx != null; |
149 repoDir = repositoryRoot; | 142 workingDir = repositoryRoot.getParentFile(); |
150 workingDir = repoDir.getParentFile(); | |
151 if (workingDir == null) { | 143 if (workingDir == null) { |
152 throw new IllegalArgumentException(repoDir.toString()); | 144 throw new IllegalArgumentException(repositoryRoot.toString()); |
153 } | 145 } |
154 repoLocation = repositoryPath; | 146 repoLocation = repositoryPath; |
155 sessionContext = ctx; | 147 sessionContext = ctx; |
156 impl = new org.tmatesoft.hg.internal.Internals(this, repositoryRoot); | 148 impl = new Internals(this, repositoryRoot, new Internals.ImplAccess() { |
149 | |
150 public RevlogStream getStream(HgDataFile df) { | |
151 return df.content; | |
152 } | |
153 public RevlogStream getManifestStream() { | |
154 return HgRepository.this.getManifest().content; | |
155 } | |
156 public RevlogStream getChangelogStream() { | |
157 return HgRepository.this.getChangelog().content; | |
158 } | |
159 }); | |
157 normalizePath = impl.buildNormalizePathRewrite(); | 160 normalizePath = impl.buildNormalizePathRewrite(); |
158 } | 161 } |
159 | 162 |
160 @Override | 163 @Override |
161 public String toString() { | 164 public String toString() { |
172 * provide {@link File}, e.g. {@link #getWorkingDir()} | 175 * provide {@link File}, e.g. {@link #getWorkingDir()} |
173 * | 176 * |
174 * @return repository location information, never <code>null</code> | 177 * @return repository location information, never <code>null</code> |
175 */ | 178 */ |
176 public String getLocation() { | 179 public String getLocation() { |
177 return repoLocation; | 180 return repoLocation; // XXX field to keep this is bit too much |
178 } | 181 } |
179 | 182 |
180 public boolean isInvalid() { | 183 public boolean isInvalid() { |
181 return impl == null || impl.isInvalid(); | 184 return impl == null || impl.isInvalid(); |
182 } | 185 } |
183 | 186 |
184 public HgChangelog getChangelog() { | 187 public HgChangelog getChangelog() { |
185 if (changelog == null) { | 188 if (changelog == null) { |
186 File chlogFile = impl.getFileFromStoreDir("00changelog.i"); | 189 RevlogStream content = impl.createChangelogStream(); |
187 RevlogStream content = new RevlogStream(impl.getDataAccess(), chlogFile); | |
188 changelog = new HgChangelog(this, content); | 190 changelog = new HgChangelog(this, content); |
189 } | 191 } |
190 return changelog; | 192 return changelog; |
191 } | 193 } |
192 | 194 |
193 public HgManifest getManifest() { | 195 public HgManifest getManifest() { |
194 if (manifest == null) { | 196 if (manifest == null) { |
195 File manifestFile = impl.getFileFromStoreDir("00manifest.i"); | 197 RevlogStream content = impl.createManifestStream(); |
196 RevlogStream content = new RevlogStream(impl.getDataAccess(), manifestFile); | |
197 manifest = new HgManifest(this, content, impl.buildFileNameEncodingHelper()); | 198 manifest = new HgManifest(this, content, impl.buildFileNameEncodingHelper()); |
198 } | 199 } |
199 return manifest; | 200 return manifest; |
200 } | 201 } |
201 | 202 |
269 Path p = sessionContext.getPathFactory().path(nPath); | 270 Path p = sessionContext.getPathFactory().path(nPath); |
270 return getFileNode(p); | 271 return getFileNode(p); |
271 } | 272 } |
272 | 273 |
273 public HgDataFile getFileNode(Path path) { | 274 public HgDataFile getFileNode(Path path) { |
274 RevlogStream content = resolveStoreFile(path); | 275 RevlogStream content = impl.resolveStoreFile(path); |
275 if (content == null) { | 276 if (content == null) { |
276 return new HgDataFile(this, path); | 277 return new HgDataFile(this, path); |
277 } | 278 } |
278 return new HgDataFile(this, path, content); | 279 return new HgDataFile(this, path, content); |
279 } | 280 } |
484 * @return session environment of the repository | 485 * @return session environment of the repository |
485 */ | 486 */ |
486 public SessionContext getSessionContext() { | 487 public SessionContext getSessionContext() { |
487 return sessionContext; | 488 return sessionContext; |
488 } | 489 } |
489 | |
490 /** | |
491 * Perhaps, should be separate interface, like ContentLookup | |
492 * @param path - normalized file name | |
493 * @return <code>null</code> if path doesn't resolve to a existing file | |
494 */ | |
495 /*package-local*/ RevlogStream resolveStoreFile(Path path) { | |
496 final SoftReference<RevlogStream> ref = streamsCache.get(path); | |
497 RevlogStream cached = ref == null ? null : ref.get(); | |
498 if (cached != null) { | |
499 return cached; | |
500 } | |
501 File f = impl.getFileFromDataDir(path); | |
502 if (f.exists()) { | |
503 RevlogStream s = new RevlogStream(impl.getDataAccess(), f); | |
504 if (impl.shallCacheRevlogs()) { | |
505 streamsCache.put(path, new SoftReference<RevlogStream>(s)); | |
506 } | |
507 return s; | |
508 } | |
509 return null; | |
510 } | |
511 | |
512 /*package-local*/ RevlogStream createStoreFile(Path path) throws HgInvalidControlFileException { | |
513 File f = impl.getFileFromDataDir(path); | |
514 try { | |
515 if (!f.exists()) { | |
516 f.getParentFile().mkdirs(); | |
517 f.createNewFile(); | |
518 } | |
519 RevlogStream s = new RevlogStream(impl.getDataAccess(), f); | |
520 if (impl.shallCacheRevlogs()) { | |
521 streamsCache.put(path, new SoftReference<RevlogStream>(s)); | |
522 } | |
523 return s; | |
524 } catch (IOException ex) { | |
525 throw new HgInvalidControlFileException("Can't create a file in the storage", ex, f); | |
526 } | |
527 } | |
528 | 490 |
529 /*package-local*/ List<Filter> getFiltersFromRepoToWorkingDir(Path p) { | 491 /*package-local*/ List<Filter> getFiltersFromRepoToWorkingDir(Path p) { |
530 return instantiateFilters(p, new Filter.Options(Filter.Direction.FromRepo)); | 492 return instantiateFilters(p, new Filter.Options(Filter.Direction.FromRepo)); |
531 } | 493 } |
532 | 494 |