Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgManifest.java @ 366:189dc6dc1c3e
Use exceptions to expose errors reading mercurial data
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 16 Dec 2011 04:43:18 +0100 |
parents | 5f9073eabf06 |
children | 2fadf8695f8a |
comparison
equal
deleted
inserted
replaced
365:3572fcb06473 | 366:189dc6dc1c3e |
---|---|
23 import java.util.ArrayList; | 23 import java.util.ArrayList; |
24 import java.util.Arrays; | 24 import java.util.Arrays; |
25 import java.util.HashMap; | 25 import java.util.HashMap; |
26 import java.util.Map; | 26 import java.util.Map; |
27 | 27 |
28 import org.tmatesoft.hg.core.HgBadStateException; | 28 import org.tmatesoft.hg.core.HgException; |
29 import org.tmatesoft.hg.core.HgInvalidControlFileException; | 29 import org.tmatesoft.hg.core.HgInvalidControlFileException; |
30 import org.tmatesoft.hg.core.Nodeid; | 30 import org.tmatesoft.hg.core.Nodeid; |
31 import org.tmatesoft.hg.internal.DataAccess; | 31 import org.tmatesoft.hg.internal.DataAccess; |
32 import org.tmatesoft.hg.internal.DigestHelper; | 32 import org.tmatesoft.hg.internal.DigestHelper; |
33 import org.tmatesoft.hg.internal.EncodingHelper; | 33 import org.tmatesoft.hg.internal.EncodingHelper; |
100 * | 100 * |
101 * @param start changelog (not manifest!) revision to begin with | 101 * @param start changelog (not manifest!) revision to begin with |
102 * @param end changelog (not manifest!) revision to stop, inclusive. | 102 * @param end changelog (not manifest!) revision to stop, inclusive. |
103 * @param inspector can't be <code>null</code> | 103 * @param inspector can't be <code>null</code> |
104 */ | 104 */ |
105 public void walk(int start, int end, final Inspector inspector) { | 105 public void walk(int start, int end, final Inspector inspector) throws /*FIXME HgInvalidRevisionException,*/ HgInvalidControlFileException { |
106 if (inspector == null) { | 106 if (inspector == null) { |
107 throw new IllegalArgumentException(); | 107 throw new IllegalArgumentException(); |
108 } | 108 } |
109 int start0 = fromChangelog(start); | 109 int start0 = fromChangelog(start); |
110 int end0 = fromChangelog(end); | 110 int end0 = fromChangelog(end); |
121 * "Sparse" iteration of the manifest | 121 * "Sparse" iteration of the manifest |
122 * | 122 * |
123 * @param inspector | 123 * @param inspector |
124 * @param localRevisions local changeset revisions to visit | 124 * @param localRevisions local changeset revisions to visit |
125 */ | 125 */ |
126 public void walk(final Inspector inspector, int... localRevisions) { | 126 public void walk(final Inspector inspector, int... localRevisions) throws HgInvalidControlFileException{ |
127 if (inspector == null || localRevisions == null) { | 127 if (inspector == null || localRevisions == null) { |
128 throw new IllegalArgumentException(); | 128 throw new IllegalArgumentException(); |
129 } | 129 } |
130 int[] localManifestRevs = toLocalManifestRevisions(localRevisions); | 130 int[] localManifestRevs = toLocalManifestRevisions(localRevisions); |
131 content.iterate(localManifestRevs, true, new ManifestParser(inspector)); | 131 content.iterate(localManifestRevs, true, new ManifestParser(inspector)); |
132 } | 132 } |
133 | 133 |
134 // manifest revision number that corresponds to the given changeset | 134 // manifest revision number that corresponds to the given changeset |
135 /*package-local*/ int fromChangelog(int revisionNumber) { | 135 /*package-local*/ int fromChangelog(int revisionNumber) throws HgInvalidControlFileException { |
136 if (HgInternals.wrongLocalRevision(revisionNumber)) { | 136 if (HgInternals.wrongLocalRevision(revisionNumber)) { |
137 throw new IllegalArgumentException(String.valueOf(revisionNumber)); | 137 throw new IllegalArgumentException(String.valueOf(revisionNumber)); |
138 } | 138 } |
139 if (revisionNumber == HgRepository.WORKING_COPY || revisionNumber == HgRepository.BAD_REVISION) { | 139 if (revisionNumber == HgRepository.WORKING_COPY || revisionNumber == HgRepository.BAD_REVISION) { |
140 throw new IllegalArgumentException("Can't use constants like WORKING_COPY or BAD_REVISION"); | 140 throw new IllegalArgumentException("Can't use constants like WORKING_COPY or BAD_REVISION"); |
153 * @param localChangelogRevision local changeset index | 153 * @param localChangelogRevision local changeset index |
154 * @param file path to file in question | 154 * @param file path to file in question |
155 * @return file revision or <code>null</code> if manifest at specified revision doesn't list such file | 155 * @return file revision or <code>null</code> if manifest at specified revision doesn't list such file |
156 */ | 156 */ |
157 @Experimental(reason="Perhaps, HgDataFile shall own this method, or get a delegate?") | 157 @Experimental(reason="Perhaps, HgDataFile shall own this method, or get a delegate?") |
158 public Nodeid getFileRevision(int localChangelogRevision, final Path file) { | 158 public Nodeid getFileRevision(int localChangelogRevision, final Path file) throws HgInvalidControlFileException{ |
159 return getFileRevisions(file, localChangelogRevision).get(localChangelogRevision); | 159 return getFileRevisions(file, localChangelogRevision).get(localChangelogRevision); |
160 } | 160 } |
161 | 161 |
162 // XXX package-local, IntMap, and HgDataFile getFileRevisionAt(int... localChangelogRevisions) | 162 // XXX package-local, IntMap, and HgDataFile getFileRevisionAt(int... localChangelogRevisions) |
163 @Experimental(reason="@see #getFileRevision") | 163 @Experimental(reason="@see #getFileRevision") |
164 public Map<Integer, Nodeid> getFileRevisions(final Path file, int... localChangelogRevisions) { | 164 public Map<Integer, Nodeid> getFileRevisions(final Path file, int... localChangelogRevisions) throws HgInvalidControlFileException{ |
165 // FIXME need tests | 165 // FIXME need tests |
166 int[] localManifestRevisions = toLocalManifestRevisions(localChangelogRevisions); | 166 int[] localManifestRevisions = toLocalManifestRevisions(localChangelogRevisions); |
167 final HashMap<Integer,Nodeid> rv = new HashMap<Integer, Nodeid>(localChangelogRevisions.length); | 167 final HashMap<Integer,Nodeid> rv = new HashMap<Integer, Nodeid>(localChangelogRevisions.length); |
168 content.iterate(localManifestRevisions, true, new RevlogStream.Inspector() { | 168 content.iterate(localManifestRevisions, true, new RevlogStream.Inspector() { |
169 | 169 |
170 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { | 170 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgException { |
171 ByteArrayOutputStream bos = new ByteArrayOutputStream(); | 171 ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
172 try { | 172 try { |
173 byte b; | 173 byte b; |
174 while (!data.isEmpty() && (b = data.readByte()) != '\n') { | 174 while (!data.isEmpty() && (b = data.readByte()) != '\n') { |
175 if (b != 0) { | 175 if (b != 0) { |
189 while (!data.isEmpty() && (b = data.readByte()) != '\n') | 189 while (!data.isEmpty() && (b = data.readByte()) != '\n') |
190 ; | 190 ; |
191 } | 191 } |
192 } | 192 } |
193 } catch (IOException ex) { | 193 } catch (IOException ex) { |
194 throw new HgBadStateException(ex); | 194 throw new HgException(ex); |
195 } | 195 } |
196 } | 196 } |
197 }); | 197 }); |
198 return rv; | 198 return rv; |
199 } | 199 } |
200 | 200 |
201 | 201 |
202 private int[] toLocalManifestRevisions(int[] localChangelogRevisions) { | 202 private int[] toLocalManifestRevisions(int[] localChangelogRevisions) throws HgInvalidControlFileException { |
203 int[] localManifestRevs = new int[localChangelogRevisions.length]; | 203 int[] localManifestRevs = new int[localChangelogRevisions.length]; |
204 boolean needsSort = false; | 204 boolean needsSort = false; |
205 for (int i = 0; i < localChangelogRevisions.length; i++) { | 205 for (int i = 0; i < localChangelogRevisions.length; i++) { |
206 final int manifestLocalRev = fromChangelog(localChangelogRevisions[i]); | 206 final int manifestLocalRev = fromChangelog(localChangelogRevisions[i]); |
207 localManifestRevs[i] = manifestLocalRev; | 207 localManifestRevs[i] = manifestLocalRev; |
316 fnamePool = new Pool2<PathProxy>(); | 316 fnamePool = new Pool2<PathProxy>(); |
317 thisRevPool = new Pool2<Nodeid>(); | 317 thisRevPool = new Pool2<Nodeid>(); |
318 progressHelper = ProgressSupport.Factory.get(delegate); | 318 progressHelper = ProgressSupport.Factory.get(delegate); |
319 } | 319 } |
320 | 320 |
321 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) { | 321 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) throws HgException { |
322 try { | 322 try { |
323 if (!inspector.begin(revisionNumber, new Nodeid(nodeid, true), linkRevision)) { | 323 if (!inspector.begin(revisionNumber, new Nodeid(nodeid, true), linkRevision)) { |
324 iterateControl.stop(); | 324 iterateControl.stop(); |
325 return; | 325 return; |
326 } | 326 } |
390 nodeidPool = thisRevPool; | 390 nodeidPool = thisRevPool; |
391 thisRevPool = t; | 391 thisRevPool = t; |
392 iterateControl.checkCancelled(); | 392 iterateControl.checkCancelled(); |
393 progressHelper.worked(1); | 393 progressHelper.worked(1); |
394 } catch (IOException ex) { | 394 } catch (IOException ex) { |
395 throw new HgBadStateException(ex); | 395 throw new HgException(ex); |
396 } | 396 } |
397 } | 397 } |
398 | 398 |
399 public void start(int count, Callback callback, Object token) { | 399 public void start(int count, Callback callback, Object token) { |
400 CancelSupport cs = CancelSupport.Factory.get(inspector, null); | 400 CancelSupport cs = CancelSupport.Factory.get(inspector, null); |
470 if (changelog2manifest[i] == -1) { | 470 if (changelog2manifest[i] == -1) { |
471 undefinedChangelogRevision.add(i); | 471 undefinedChangelogRevision.add(i); |
472 } | 472 } |
473 } | 473 } |
474 for (int u : undefinedChangelogRevision) { | 474 for (int u : undefinedChangelogRevision) { |
475 Nodeid manifest = repo.getChangelog().range(u, u).get(0).manifest(); | |
476 // FIXME calculate those missing effectively (e.g. cache and sort nodeids to speed lookup | |
477 // right away in the #next (may refactor ParentWalker's sequential and sorted into dedicated helper and reuse here) | |
478 try { | 475 try { |
476 Nodeid manifest = repo.getChangelog().range(u, u).get(0).manifest(); | |
477 // FIXME calculate those missing effectively (e.g. cache and sort nodeids to speed lookup | |
478 // right away in the #next (may refactor ParentWalker's sequential and sorted into dedicated helper and reuse here) | |
479 changelog2manifest[u] = repo.getManifest().getLocalRevision(manifest); | 479 changelog2manifest[u] = repo.getManifest().getLocalRevision(manifest); |
480 } catch (HgInvalidControlFileException ex) { | 480 } catch (HgInvalidControlFileException ex) { |
481 // FIXME need to propagate the error up to client | 481 // FIXME need to propagate the error up to client |
482 repo.getContext().getLog().error(getClass(), ex, null); | 482 repo.getContext().getLog().error(getClass(), ex, null); |
483 } | 483 } |