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