Mercurial > jhg
diff src/org/tmatesoft/hg/repo/HgManifest.java @ 423:9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 23 Mar 2012 22:51:18 +0100 |
parents | fdd7d756dea0 |
children | 6437d261048a |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgManifest.java Fri Mar 23 21:26:01 2012 +0100 +++ b/src/org/tmatesoft/hg/repo/HgManifest.java Fri Mar 23 22:51:18 2012 +0100 @@ -17,8 +17,7 @@ package org.tmatesoft.hg.repo; import static org.tmatesoft.hg.core.Nodeid.NULL; -import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; -import static org.tmatesoft.hg.repo.HgRepository.TIP; +import static org.tmatesoft.hg.repo.HgRepository.*; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -27,12 +26,9 @@ import java.util.HashMap; import java.util.Map; -import org.tmatesoft.hg.core.HgBadStateException; import org.tmatesoft.hg.core.HgChangesetFileSneaker; -import org.tmatesoft.hg.core.HgException; -import org.tmatesoft.hg.core.HgInvalidControlFileException; -import org.tmatesoft.hg.core.HgInvalidRevisionException; import org.tmatesoft.hg.core.Nodeid; +import org.tmatesoft.hg.internal.Callback; import org.tmatesoft.hg.internal.DataAccess; import org.tmatesoft.hg.internal.DigestHelper; import org.tmatesoft.hg.internal.EncodingHelper; @@ -137,8 +133,10 @@ * incrementally, nor it mandates presence of manifest version for a changeset. Thus, there might be changesets that record {@link Nodeid#NULL} * as corresponding manifest revision. This situation is deemed exceptional now and what would <code>inspector</code> get depends on whether * <code>start</code> or <code>end</code> arguments point to such changeset, or such changeset happen to be somewhere inside the range - * <code>[start..end]</code>. Implementation does it best to report empty manifests (<code>Inspector.begin(BAD_REVISION, NULL, csetRevIndex);</code> - * followed immediately by <code>Inspector.end(BAD_REVISION)</code> when <code>start</code> and/or <code>end</code> point to changeset with no associated + * <code>[start..end]</code>. Implementation does it best to report empty manifests + * (<code>Inspector.begin(HgRepository.NO_REVISION, NULL, csetRevIndex);</code> + * followed immediately by <code>Inspector.end(HgRepository.NO_REVISION)</code> + * when <code>start</code> and/or <code>end</code> point to changeset with no associated * manifest revision. However, if changeset-manifest revision pairs look like: * <pre> * 3 8 @@ -148,14 +146,14 @@ * call <code>walk(3,5, insp)</code> would yield only (3,8) and (5,9) to the inspector, without additional empty * <code>Inspector.begin(); Inspector.end()</code> call pair. * + * @see HgRepository#NO_REVISION * @param start changelog (not manifest!) revision to begin with * @param end changelog (not manifest!) revision to stop, inclusive. * @param inspector manifest revision visitor, can't be <code>null</code> - * @throws HgInvalidRevisionException if start or end specify non-existent revision index - * @throws IllegalArgumentException if start or end is not a revision index - * @throws HgInvalidControlFileException if access to revlog index/data entry failed + * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> + * @throws IllegalArgumentException if inspector callback is <code>null</code> */ - public void walk(int start, int end, final Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException { + public void walk(int start, int end, final Inspector inspector) throws HgRuntimeException, IllegalArgumentException { if (inspector == null) { throw new IllegalArgumentException(); } @@ -164,8 +162,8 @@ do { manifestFirst = fromChangelog(csetFirst+i); if (manifestFirst == BAD_REVISION) { - inspector.begin(BAD_REVISION, NULL, csetFirst+i); - inspector.end(BAD_REVISION); + inspector.begin(NO_REVISION, NULL, csetFirst+i); + inspector.end(NO_REVISION); } i++; } while (manifestFirst == BAD_REVISION && csetFirst+i <= csetLast); @@ -179,15 +177,15 @@ do { manifestLast = fromChangelog(csetLast-i); if (manifestLast == BAD_REVISION) { - inspector.begin(BAD_REVISION, NULL, csetLast-i); - inspector.end(BAD_REVISION); + inspector.begin(NO_REVISION, NULL, csetLast-i); + inspector.end(NO_REVISION); } i++; } while (manifestLast == BAD_REVISION && csetLast-i >= csetFirst); if (manifestLast == BAD_REVISION) { - // hmm, manifestFirst != -1 here, hence there's i from [csetFirst..csetLast] for which manifest entry exists, - // and thus it's impossible to run into manifestLast == -1. Nevertheless, never hurts to check. - throw new HgBadStateException(String.format("Manifest %d-%d(!) for cset range [%d..%d] ", manifestFirst, manifestLast, csetFirst, csetLast)); + // hmm, manifestFirst != BAD_REVISION here, hence there's i from [csetFirst..csetLast] for which manifest entry exists, + // and thus it's impossible to run into manifestLast == BAD_REVISION. Nevertheless, never hurts to check. + throw new HgInvalidStateException(String.format("Manifest %d-%d(!) for cset range [%d..%d] ", manifestFirst, manifestLast, csetFirst, csetLast)); } if (manifestLast < manifestFirst) { // there are tool-constructed repositories that got order of changeset revisions completely different from that of manifest @@ -207,10 +205,10 @@ * * @param inspector manifest revision visitor, can't be <code>null</code> * @param revisionIndexes local indexes of changesets to visit, non-<code>null</code> - * @throws HgInvalidRevisionException if argument specifies non-existent revision index - * @throws HgInvalidControlFileException if access to revlog index/data entry failed + * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> + * @throws InvalidArgumentException if supplied arguments are <code>null</code>s */ - public void walk(final Inspector inspector, int... revisionIndexes) throws HgInvalidRevisionException, HgInvalidControlFileException { + public void walk(final Inspector inspector, int... revisionIndexes) throws HgRuntimeException, IllegalArgumentException { if (inspector == null || revisionIndexes == null) { throw new IllegalArgumentException(); } @@ -310,8 +308,8 @@ final int manifestRevisionIndex = fromChangelog(changelogRevisionIndexes[i]); if (manifestRevisionIndex == BAD_REVISION) { if (inspector != null) { - inspector.begin(BAD_REVISION, NULL, changelogRevisionIndexes[i]); - inspector.end(BAD_REVISION); + inspector.begin(NO_REVISION, NULL, changelogRevisionIndexes[i]); + inspector.end(NO_REVISION); } // othrwise, ignore changeset without manifest } else { @@ -335,6 +333,7 @@ } } + @Callback public interface Inspector { boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision); /** @@ -346,6 +345,7 @@ } @Experimental(reason="Explore Path alternative for filenames and enum for flags") + @Callback public interface Inspector2 extends Inspector { /** * @param nid file revision @@ -448,7 +448,7 @@ progressHelper = ProgressSupport.Factory.get(delegate); } - public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) throws HgException { + public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) { try { if (!inspector.begin(revisionNumber, new Nodeid(nodeid, true), linkRevision)) { iterateControl.stop(); @@ -525,7 +525,7 @@ iterateControl.checkCancelled(); progressHelper.worked(1); } catch (IOException ex) { - throw new HgException(ex); + throw new HgInvalidControlFileException("Failed reading manifest", ex, null).setRevisionIndex(revisionNumber); } } @@ -613,19 +613,14 @@ } } for (int u : undefinedChangelogRevision) { - try { - Nodeid manifest = repo.getChangelog().range(u, u).get(0).manifest(); - // TODO calculate those missing effectively (e.g. cache and sort nodeids to speed lookup - // right away in the #next (may refactor ParentWalker's sequential and sorted into dedicated helper and reuse here) - if (manifest.isNull()) { - repo.getContext().getLog().warn(getClass(), "Changeset %d has no associated manifest entry", u); - // keep -1 in the changelog2manifest map. - } else { - changelog2manifest[u] = repo.getManifest().getRevisionIndex(manifest); - } - } catch (HgInvalidControlFileException ex) { - // FIXME EXCEPTIONS need to propagate the error up to client - repo.getContext().getLog().error(getClass(), ex, null); + Nodeid manifest = repo.getChangelog().range(u, u).get(0).manifest(); + // TODO calculate those missing effectively (e.g. cache and sort nodeids to speed lookup + // right away in the #next (may refactor ParentWalker's sequential and sorted into dedicated helper and reuse here) + if (manifest.isNull()) { + repo.getContext().getLog().warn(getClass(), "Changeset %d has no associated manifest entry", u); + // keep -1 in the changelog2manifest map. + } else { + changelog2manifest[u] = repo.getManifest().getRevisionIndex(manifest); } } } @@ -649,7 +644,7 @@ filenameAsBytes = eh.toManifest(fileToLookUp.toString()); } - public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgException { + public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { byte b; @@ -689,7 +684,7 @@ } } } catch (IOException ex) { - throw new HgException(ex); // FIXME EXCEPTIONS + throw new HgInvalidControlFileException("Failed reading manifest", ex, null); } } }