diff src/org/tmatesoft/hg/core/ChangesetTransformer.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 528b6780a8bd
children 31a89587eb04
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/ChangesetTransformer.java	Fri Mar 23 21:26:01 2012 +0100
+++ b/src/org/tmatesoft/hg/core/ChangesetTransformer.java	Fri Mar 23 22:51:18 2012 +0100
@@ -22,6 +22,7 @@
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.repo.HgStatusCollector;
+import org.tmatesoft.hg.util.Adaptable;
 import org.tmatesoft.hg.util.CancelSupport;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.PathPool;
@@ -35,7 +36,7 @@
  * @author Artem Tikhomirov
  * @author TMate Software Ltd.
  */
-/*package-local*/ class ChangesetTransformer implements HgChangelog.Inspector {
+/*package-local*/ class ChangesetTransformer implements HgChangelog.Inspector, Adaptable, CancelSupport {
 	private final HgChangesetHandler handler;
 	private final ProgressSupport progressHelper;
 	private final CancelSupport cancelHelper;
@@ -56,14 +57,14 @@
 		HgStatusCollector statusCollector = new HgStatusCollector(hgRepo);
 		t = new Transformation(statusCollector, pw);
 		handler = delegate;
+		// we let HgChangelog#range deal with progress (pipe through getAdapter)
+		// but use own cancellation (which involves CallbackTargetException as well, and preserves original cancellation 
+		// exception in case clients care)
 		cancelHelper = cs;
 		progressHelper = ps;
 	}
 	
 	public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
-		if (failure != null || cancellation != null) {
-			return; // FIXME need a better way to stop iterating revlog 
-		}
 		if (branches != null && !branches.contains(cset.branch())) {
 			return;
 		}
@@ -71,10 +72,9 @@
 		HgChangeset changeset = t.handle(revisionNumber, nodeid, cset);
 		try {
 			handler.next(changeset);
-			progressHelper.worked(1);
 			cancelHelper.checkCancelled();
-		} catch (RuntimeException ex) {
-			failure = new HgCallbackTargetException(ex).setRevision(nodeid).setRevisionIndex(revisionNumber);
+		} catch (HgCallbackTargetException ex) {
+			failure = ex.setRevision(nodeid).setRevisionIndex(revisionNumber);
 		} catch (CancelledException ex) {
 			cancellation = ex;
 		}
@@ -118,4 +118,19 @@
 			return changeset;
 		}
 	}
+
+	public void checkCancelled() throws CancelledException {
+		if (failure != null || cancellation != null) {
+			// stop HgChangelog.Iterator. Our exception is for the purposes of cancellation only,
+			// the one we have stored (this.cancellation) is for user
+			throw new CancelledException(); 
+		}
+	}
+
+	public <T> T getAdapter(Class<T> adapterClass) {
+		if (adapterClass == ProgressSupport.class) {
+			return adapterClass.cast(progressHelper);
+		}
+		return null;
+	}
 }
\ No newline at end of file