Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/HgManifest.java @ 628:6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 22 May 2013 15:52:31 +0200 |
parents | e1b29756f901 |
children | 8a5cdcb27b8f |
comparison
equal
deleted
inserted
replaced
627:5153eb73b18d | 628:6526d8adbc0f |
---|---|
235 * gets invoked doesn't resemble order of changeset revisions supplied, manifest revisions are reported in the order they appear | 235 * gets invoked doesn't resemble order of changeset revisions supplied, manifest revisions are reported in the order they appear |
236 * in manifest revlog (with exception of changesets with missing manifest that may be reported in any order). | 236 * in manifest revlog (with exception of changesets with missing manifest that may be reported in any order). |
237 * | 237 * |
238 * @param inspector manifest revision visitor, can't be <code>null</code> | 238 * @param inspector manifest revision visitor, can't be <code>null</code> |
239 * @param revisionIndexes local indexes of changesets to visit, non-<code>null</code> | 239 * @param revisionIndexes local indexes of changesets to visit, non-<code>null</code> |
240 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 240 * @throws HgInvalidRevisionException if method argument specifies non-existent revision index. <em>Runtime exception</em> |
241 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em> | |
242 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em> | |
241 * @throws InvalidArgumentException if supplied arguments are <code>null</code>s | 243 * @throws InvalidArgumentException if supplied arguments are <code>null</code>s |
242 */ | 244 */ |
243 public void walk(final Inspector inspector, int... revisionIndexes) throws HgRuntimeException, IllegalArgumentException { | 245 public void walk(final Inspector inspector, int... revisionIndexes) throws HgRuntimeException, IllegalArgumentException { |
244 if (inspector == null || revisionIndexes == null) { | 246 if (inspector == null || revisionIndexes == null) { |
245 throw new IllegalArgumentException(); | 247 throw new IllegalArgumentException(); |
251 // | 253 // |
252 /** | 254 /** |
253 * Tells manifest revision number that corresponds to the given changeset. May return {@link HgRepository#BAD_REVISION} | 255 * Tells manifest revision number that corresponds to the given changeset. May return {@link HgRepository#BAD_REVISION} |
254 * if changeset has no associated manifest (cset records NULL nodeid for manifest). | 256 * if changeset has no associated manifest (cset records NULL nodeid for manifest). |
255 * @return manifest revision index, non-negative, or {@link HgRepository#BAD_REVISION}. | 257 * @return manifest revision index, non-negative, or {@link HgRepository#BAD_REVISION}. |
256 * @throws HgInvalidRevisionException if method argument specifies non-existent revision index | 258 * @throws HgInvalidRevisionException if method argument specifies non-existent revision index. <em>Runtime exception</em> |
257 * @throws HgInvalidControlFileException if access to revlog index/data entry failed | 259 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em> |
258 */ | 260 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em> |
259 /*package-local*/ int fromChangelog(int changesetRevisionIndex) throws HgInvalidRevisionException, HgInvalidControlFileException { | 261 */ |
262 /*package-local*/ int fromChangelog(int changesetRevisionIndex) throws HgRuntimeException { | |
260 if (HgInternals.wrongRevisionIndex(changesetRevisionIndex)) { | 263 if (HgInternals.wrongRevisionIndex(changesetRevisionIndex)) { |
261 throw new HgInvalidRevisionException(changesetRevisionIndex); | 264 throw new HgInvalidRevisionException(changesetRevisionIndex); |
262 } | 265 } |
263 if (changesetRevisionIndex == HgRepository.WORKING_COPY || changesetRevisionIndex == HgRepository.BAD_REVISION) { | 266 if (changesetRevisionIndex == HgRepository.WORKING_COPY || changesetRevisionIndex == HgRepository.BAD_REVISION) { |
264 throw new HgInvalidRevisionException("Can't use constants like WORKING_COPY or BAD_REVISION", null, changesetRevisionIndex); | 267 throw new HgInvalidRevisionException("Can't use constants like WORKING_COPY or BAD_REVISION", null, changesetRevisionIndex); |
294 * @see #walkFileRevisions(Path, Inspector, int...) | 297 * @see #walkFileRevisions(Path, Inspector, int...) |
295 * @see HgChangesetFileSneaker | 298 * @see HgChangesetFileSneaker |
296 * @param changelogRevisionIndex local changeset index | 299 * @param changelogRevisionIndex local changeset index |
297 * @param file path to file in question | 300 * @param file path to file in question |
298 * @return file revision or <code>null</code> if manifest at specified revision doesn't list such file | 301 * @return file revision or <code>null</code> if manifest at specified revision doesn't list such file |
299 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 302 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em> |
300 */ | 303 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em> |
301 public Nodeid getFileRevision(int changelogRevisionIndex, final Path file) throws HgInvalidRevisionException, HgInvalidControlFileException { | 304 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em> |
305 */ | |
306 public Nodeid getFileRevision(int changelogRevisionIndex, final Path file) throws HgRuntimeException { | |
302 // there's no need for HgDataFile to own this method, or get a delegate | 307 // there's no need for HgDataFile to own this method, or get a delegate |
303 // as most of HgDataFile API is using file revision indexes, and there's easy step from file revision index to | 308 // as most of HgDataFile API is using file revision indexes, and there's easy step from file revision index to |
304 // both file revision and changeset revision index. But there's no easy way to go from changesetRevisionIndex to | 309 // both file revision and changeset revision index. But there's no easy way to go from changesetRevisionIndex to |
305 // file revision (the task this method solves), except for HgFileInformer | 310 // file revision (the task this method solves), except for HgFileInformer |
306 // I feel methods dealing with changeset indexes shall be more exposed in HgChangelog and HgManifest API. | 311 // I feel methods dealing with changeset indexes shall be more exposed in HgChangelog and HgManifest API. |
328 * | 333 * |
329 * @see #getFileRevision(int, Path) | 334 * @see #getFileRevision(int, Path) |
330 * @param file path of interest | 335 * @param file path of interest |
331 * @param inspector callback to receive details about selected file | 336 * @param inspector callback to receive details about selected file |
332 * @param changelogRevisionIndexes changeset indexes to visit | 337 * @param changelogRevisionIndexes changeset indexes to visit |
333 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 338 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em> |
339 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em> | |
340 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em> | |
334 */ | 341 */ |
335 public void walkFileRevisions(Path file, Inspector inspector, int... changelogRevisionIndexes) throws HgRuntimeException { | 342 public void walkFileRevisions(Path file, Inspector inspector, int... changelogRevisionIndexes) throws HgRuntimeException { |
336 if (file == null || inspector == null || changelogRevisionIndexes == null) { | 343 if (file == null || inspector == null || changelogRevisionIndexes == null) { |
337 throw new IllegalArgumentException(); | 344 throw new IllegalArgumentException(); |
338 } | 345 } |
347 * | 354 * |
348 * @see HgDataFile#getFlags(int) | 355 * @see HgDataFile#getFlags(int) |
349 * @param changesetRevIndex changeset revision index | 356 * @param changesetRevIndex changeset revision index |
350 * @param file path to look up | 357 * @param file path to look up |
351 * @return one of predefined enum values, or <code>null</code> if file was not known in the specified revision | 358 * @return one of predefined enum values, or <code>null</code> if file was not known in the specified revision |
352 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 359 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em> |
353 */ | 360 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em> |
354 public Flags getFileFlags(int changesetRevIndex, Path file) throws HgInvalidRevisionException, HgInvalidControlFileException { | 361 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em> |
362 */ | |
363 public Flags getFileFlags(int changesetRevIndex, Path file) throws HgRuntimeException { | |
355 int manifestRevIdx = fromChangelog(changesetRevIndex); | 364 int manifestRevIdx = fromChangelog(changesetRevIndex); |
356 IntMap<Flags> resMap = new IntMap<Flags>(2); | 365 IntMap<Flags> resMap = new IntMap<Flags>(2); |
357 FileLookupInspector parser = new FileLookupInspector(encodingHelper, file, null, resMap); | 366 FileLookupInspector parser = new FileLookupInspector(encodingHelper, file, null, resMap); |
358 parser.walk(manifestRevIdx, content); | 367 parser.walk(manifestRevIdx, content); |
359 assert resMap.size() <= 1; // size() == 0 if not found | 368 assert resMap.size() <= 1; // size() == 0 if not found |
372 } | 381 } |
373 | 382 |
374 /** | 383 /** |
375 * @param changelogRevisionIndexes non-null | 384 * @param changelogRevisionIndexes non-null |
376 * @param inspector may be null if reporting of missing manifests is not needed | 385 * @param inspector may be null if reporting of missing manifests is not needed |
377 * @throws HgInvalidRevisionException if arguments specify non-existent revision index | 386 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em> |
378 * @throws IllegalArgumentException if any index argument is not a revision index | 387 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em> |
379 * @throws HgInvalidControlFileException if access to revlog index/data entry failed | 388 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em> |
380 */ | 389 */ |
381 private int[] toManifestRevisionIndexes(int[] changelogRevisionIndexes, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException { | 390 private int[] toManifestRevisionIndexes(int[] changelogRevisionIndexes, Inspector inspector) throws HgRuntimeException { |
382 int[] manifestRevs = new int[changelogRevisionIndexes.length]; | 391 int[] manifestRevs = new int[changelogRevisionIndexes.length]; |
383 boolean needsSort = false; | 392 boolean needsSort = false; |
384 int j = 0; | 393 int j = 0; |
385 for (int i = 0; i < changelogRevisionIndexes.length; i++) { | 394 for (int i = 0; i < changelogRevisionIndexes.length; i++) { |
386 final int manifestRevisionIndex = fromChangelog(changelogRevisionIndexes[i]); | 395 final int manifestRevisionIndex = fromChangelog(changelogRevisionIndexes[i]); |
419 * | 428 * |
420 * @param manifestRevisionIndex local revision index of the inspected revision | 429 * @param manifestRevisionIndex local revision index of the inspected revision |
421 * @param manifestRevision revision of the manifest we're about to iterate through | 430 * @param manifestRevision revision of the manifest we're about to iterate through |
422 * @param changelogRevisionIndex local revision index of changelog this manifest points to | 431 * @param changelogRevisionIndex local revision index of changelog this manifest points to |
423 * @return <code>true</code> to continue iteration, <code>false</code> to stop | 432 * @return <code>true</code> to continue iteration, <code>false</code> to stop |
433 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em> | |
424 */ | 434 */ |
425 boolean begin(int manifestRevisionIndex, Nodeid manifestRevision, int changelogRevisionIndex); | 435 boolean begin(int manifestRevisionIndex, Nodeid manifestRevision, int changelogRevisionIndex) throws HgRuntimeException; |
426 | 436 |
427 | 437 |
428 /** | 438 /** |
429 * Reports each manifest entry | 439 * Reports each manifest entry |
430 * | 440 * |
431 * @param nid file revision | 441 * @param nid file revision |
432 * @param fname file name | 442 * @param fname file name |
433 * @param flags one of {@link HgManifest.Flags} constants, not <code>null</code> | 443 * @param flags one of {@link HgManifest.Flags} constants, not <code>null</code> |
434 * @return <code>true</code> to continue iteration, <code>false</code> to stop | 444 * @return <code>true</code> to continue iteration, <code>false</code> to stop |
445 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em> | |
435 */ | 446 */ |
436 boolean next(Nodeid nid, Path fname, Flags flags); | 447 boolean next(Nodeid nid, Path fname, Flags flags) throws HgRuntimeException; |
437 | 448 |
438 /** | 449 /** |
439 * Denotes leaving specific manifest revision, after all entries were reported using {@link #next(Nodeid, Path, Flags)} | 450 * Denotes leaving specific manifest revision, after all entries were reported using {@link #next(Nodeid, Path, Flags)} |
440 * | 451 * |
441 * @param manifestRevisionIndex indicates manifest revision, corresponds to opening {@link #begin(int, Nodeid, int)} | 452 * @param manifestRevisionIndex indicates manifest revision, corresponds to opening {@link #begin(int, Nodeid, int)} |
442 * @return <code>true</code> to continue iteration, <code>false</code> to stop | 453 * @return <code>true</code> to continue iteration, <code>false</code> to stop |
454 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em> | |
443 */ | 455 */ |
444 boolean end(int manifestRevisionIndex); | 456 boolean end(int manifestRevisionIndex) throws HgRuntimeException; |
445 } | 457 } |
446 | 458 |
447 /** | 459 /** |
448 * When Pool uses Strings directly, | 460 * When Pool uses Strings directly, |
449 * ManifestParser creates new String instance with new char[] value, and does byte->char conversion. | 461 * ManifestParser creates new String instance with new char[] value, and does byte->char conversion. |
529 fnamePool = new IdentityPool<PathProxy>(); | 541 fnamePool = new IdentityPool<PathProxy>(); |
530 thisRevPool = new IdentityPool<Nodeid>(); | 542 thisRevPool = new IdentityPool<Nodeid>(); |
531 progressHelper = ProgressSupport.Factory.get(delegate); | 543 progressHelper = ProgressSupport.Factory.get(delegate); |
532 } | 544 } |
533 | 545 |
534 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) { | 546 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) throws HgRuntimeException { |
535 try { | 547 try { |
536 if (!inspector.begin(revisionNumber, new Nodeid(nodeid, true), linkRevision)) { | 548 if (!inspector.begin(revisionNumber, new Nodeid(nodeid, true), linkRevision)) { |
537 iterateControl.stop(); | 549 iterateControl.stop(); |
538 return; | 550 return; |
539 } | 551 } |
621 | 633 |
622 private final int changelogRevisionCount; | 634 private final int changelogRevisionCount; |
623 private int[] changelog2manifest; | 635 private int[] changelog2manifest; |
624 RevisionLookup manifestNodeids; | 636 RevisionLookup manifestNodeids; |
625 | 637 |
626 private RevisionMapper(boolean useOwnRevisionLookup) { | 638 private RevisionMapper(boolean useOwnRevisionLookup) throws HgRuntimeException { |
627 changelogRevisionCount = HgManifest.this.getRepo().getChangelog().getRevisionCount(); | 639 changelogRevisionCount = HgManifest.this.getRepo().getChangelog().getRevisionCount(); |
628 if (useOwnRevisionLookup) { | 640 if (useOwnRevisionLookup) { |
629 manifestNodeids = new RevisionLookup(HgManifest.this.content); | 641 manifestNodeids = new RevisionLookup(HgManifest.this.content); |
630 } | 642 } |
631 } | 643 } |
689 public void finish(Object token) { | 701 public void finish(Object token) { |
690 // it's not a nice idea to fix changesets that reuse existing manifest entries from inside | 702 // it's not a nice idea to fix changesets that reuse existing manifest entries from inside |
691 // #finish, as the manifest read operation is not complete at the moment. | 703 // #finish, as the manifest read operation is not complete at the moment. |
692 } | 704 } |
693 | 705 |
694 public void fixReusedManifests() { | 706 public void fixReusedManifests() throws HgRuntimeException { |
695 if (changelog2manifest == null) { | 707 if (changelog2manifest == null) { |
696 // direct, 1-1 mapping of changeset indexes to manifest | 708 // direct, 1-1 mapping of changeset indexes to manifest |
697 return; | 709 return; |
698 } | 710 } |
699 // I assume there'd be not too many revisions we don't know manifest of | 711 // I assume there'd be not too many revisions we don't know manifest of |
766 delegate = delegateInspector; | 778 delegate = delegateInspector; |
767 csetIndex2FileRev = null; | 779 csetIndex2FileRev = null; |
768 csetIndex2Flags = null; | 780 csetIndex2Flags = null; |
769 } | 781 } |
770 | 782 |
771 void walk(int manifestRevIndex, RevlogStream content) { | 783 void walk(int manifestRevIndex, RevlogStream content) throws HgRuntimeException { |
772 content.iterate(manifestRevIndex, manifestRevIndex, true, this); | 784 content.iterate(manifestRevIndex, manifestRevIndex, true, this); |
773 } | 785 } |
774 | 786 |
775 void walk(int[] manifestRevIndexes, RevlogStream content) { | 787 void walk(int[] manifestRevIndexes, RevlogStream content) throws HgRuntimeException { |
776 content.iterate(manifestRevIndexes, true, this); | 788 content.iterate(manifestRevIndexes, true, this); |
777 } | 789 } |
778 | 790 |
779 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { | 791 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgRuntimeException { |
780 ByteVector byteVector = new ByteVector(256, 128); // allocate for long paths right away | 792 ByteVector byteVector = new ByteVector(256, 128); // allocate for long paths right away |
781 try { | 793 try { |
782 byte b; | 794 byte b; |
783 while (!data.isEmpty() && (b = data.readByte()) != '\n') { | 795 while (!data.isEmpty() && (b = data.readByte()) != '\n') { |
784 if (b != 0) { | 796 if (b != 0) { |