Mercurial > hg4j
changeset 370:a2341e761609
Let callback implementations deliver errors (e,g. own exceptions) to client code
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 22 Dec 2011 02:37:10 +0300 |
parents | 091666b87f62 |
children | aa2e589d4e84 |
files | src/org/tmatesoft/hg/core/HgCallbackTargetException.java src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java src/org/tmatesoft/hg/core/HgLogCommand.java |
diffstat | 3 files changed, 41 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCallbackTargetException.java Thu Dec 22 01:46:40 2011 +0300 +++ b/src/org/tmatesoft/hg/core/HgCallbackTargetException.java Thu Dec 22 02:37:10 2011 +0300 @@ -21,7 +21,14 @@ /** - * Checked exception that indicates errors in client code and tries to supply extra information about the context it occured in. + * Checked exception that indicates errors in client code and tries to supply extra information about the context it occurred in. + * + * Generally, client need to pass own error information/exceptions from within implementations of the callback methods they supply. + * However, there's no straightforward way to alter throws clause for these methods, and alternatives like generic {@link Exception} or + * library's own {@link HgException} are rather obscure. Suggested approach is to wrap whatever exception user code produces with + * {@link RuntimeException} subclass, {@link Wrap}. Then, unwrap and re-throw with checked {@link HgCallbackTargetException}. + * + * FIXME REVISIT perhaps, shall just throw HgCallbackTargetException from any handler, and do not catch anything in commands at all? * * @author Artem Tikhomirov * @author TMate Software Ltd.
--- a/src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java Thu Dec 22 01:46:40 2011 +0300 +++ b/src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java Thu Dec 22 02:37:10 2011 +0300 @@ -29,9 +29,11 @@ public interface HgChangesetTreeHandler { /** * @param entry access to various pieces of information about current tree node. Instances might be - * reused across calls and shall not be kept by client's code + * reused across calls and shall not be kept by client's code + * @throws HgCallbackTargetException.Wrap wrapper object for any exception user code may produce. Wrapped exception would get re-thrown with {@link HgCallbackTargetException} + * @throws CancelledException FIXME */ - public void next(HgChangesetTreeHandler.TreeElement entry) throws CancelledException; + public void next(HgChangesetTreeHandler.TreeElement entry) throws HgCallbackTargetException.Wrap, CancelledException; interface TreeElement { /**
--- a/src/org/tmatesoft/hg/core/HgLogCommand.java Thu Dec 22 01:46:40 2011 +0300 +++ b/src/org/tmatesoft/hg/core/HgLogCommand.java Thu Dec 22 02:37:10 2011 +0300 @@ -203,10 +203,13 @@ /** * * @param handler callback to process changesets. + * @throws HgCallbackTargetException FIXME + * @throws HgException FIXME + * @throws CancelledException FIXME * @throws IllegalArgumentException when inspector argument is null * @throws ConcurrentModificationException if this log command instance is already running */ - public void execute(HgChangesetHandler handler) throws HgDataStreamException, HgInvalidControlFileException, HgCallbackTargetException, CancelledException { + public void execute(HgChangesetHandler handler) throws HgCallbackTargetException, HgException, CancelledException { if (handler == null) { throw new IllegalArgumentException(); } @@ -237,7 +240,7 @@ HgFileRevision dst = new HgFileRevision(repo, fileNode.getRevision(0), fileNode.getPath(), src.getPath()); try { ((FileHistoryHandler) handler).copy(src, dst); - } catch (RuntimeException ex) { + } catch (HgCallbackTargetException.Wrap ex) { throw new HgCallbackTargetException(ex).setRevision(fileNode.getCopySourceRevision()).setFileName(fileNode.getCopySourceName()); } } @@ -259,7 +262,14 @@ } } - public void execute(HgChangesetTreeHandler handler) throws CancelledException, HgException { + /** + * + * @param handler + * @throws HgCallbackTargetException + * @throws HgException + * @throws CancelledException + */ + public void execute(HgChangesetTreeHandler handler) throws HgCallbackTargetException, HgException, CancelledException { if (handler == null) { throw new IllegalArgumentException(); } @@ -318,13 +328,17 @@ } else { ph2 = new ProgressSupport.Sub(progressHelper, 3); } - ph2.start(completeHistory.length); - // XXX shall sort completeHistory according to changeset numbers? - for (int i = 0; i < completeHistory.length; i++ ) { - final HistoryNode n = completeHistory[i]; - handler.next(ei.init(n)); - ph2.worked(1); - cancelHelper.checkCancelled(); + try { + ph2.start(completeHistory.length); + // XXX shall sort completeHistory according to changeset numbers? + for (int i = 0; i < completeHistory.length; i++ ) { + final HistoryNode n = completeHistory[i]; + handler.next(ei.init(n)); + ph2.worked(1); + cancelHelper.checkCancelled(); + } + } catch (HgCallbackTargetException.Wrap ex) { + throw new HgCallbackTargetException(ex); } progressHelper.done(); } @@ -379,9 +393,12 @@ * @author Artem Tikhomirov * @author TMate Software Ltd. */ - public interface FileHistoryHandler extends HgChangesetHandler { + public interface FileHistoryHandler extends HgChangesetHandler { // FIXME move to stanalone class file, perhaps? // XXX perhaps, should distinguish copy from rename? And what about merged revisions and following them? - void copy(HgFileRevision from, HgFileRevision to); + /** + * @throws HgCallbackTargetException.Wrap wrapper object for any exception user code may produce. Wrapped exception would get re-thrown with {@link HgCallbackTargetException} + */ + void copy(HgFileRevision from, HgFileRevision to) throws HgCallbackTargetException.Wrap; } public static class CollectHandler implements HgChangesetHandler {