Mercurial > hg4j
diff src/org/tmatesoft/hg/core/HgManifestCommand.java @ 427:31a89587eb04
FIXMEs: consistent names, throws for commands and their handlers. Use of checked exceptions in hi-level api
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 29 Mar 2012 17:14:35 +0200 |
parents | 6437d261048a |
children | 12f668401613 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgManifestCommand.java Wed Mar 28 19:34:37 2012 +0200 +++ b/src/org/tmatesoft/hg/core/HgManifestCommand.java Thu Mar 29 17:14:35 2012 +0200 @@ -25,10 +25,12 @@ import java.util.LinkedList; import java.util.List; -import org.tmatesoft.hg.internal.Callback; import org.tmatesoft.hg.repo.HgManifest; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgManifest.Flags; +import org.tmatesoft.hg.repo.HgRuntimeException; +import org.tmatesoft.hg.util.CancelSupport; +import org.tmatesoft.hg.util.CancelledException; import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.PathPool; import org.tmatesoft.hg.util.PathRewrite; @@ -45,7 +47,7 @@ private final HgRepository repo; private Path.Matcher matcher; private int startRev = 0, endRev = TIP; - private Handler visitor; + private HgManifestHandler visitor; private boolean needDirs = false; private final Mediator mediator = new Mediator(); @@ -97,12 +99,16 @@ } /** - * Runs the command. + * With all parameters set, execute the command. + * * @param handler - callback to get the outcome + * @throws HgCallbackTargetException propagated exception from the handler + * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state + * @throws CancelledException if execution of the command was cancelled * @throws IllegalArgumentException if handler is <code>null</code> * @throws ConcurrentModificationException if this command is already in use (running) */ - public void execute(Handler handler) throws HgException { + public void execute(HgManifestHandler handler) throws HgCallbackTargetException, HgException, CancelledException { if (handler == null) { throw new IllegalArgumentException(); } @@ -111,25 +117,17 @@ } try { visitor = handler; - mediator.start(); + mediator.start(getCancelSupport(handler, true)); repo.getManifest().walk(startRev, endRev, mediator); + mediator.checkFailure(); + } catch (HgRuntimeException ex) { + throw new HgLibraryFailureException(ex); } finally { mediator.done(); visitor = null; } } - /** - * Callback to walk file/directory tree of a revision - */ - @Callback - public interface Handler { // FIXME TLC - void begin(Nodeid manifestRevision); - void dir(Path p); // optionally invoked (if walker was configured to spit out directories) prior to any files from this dir and subdirs - void file(HgFileRevision fileRevision); // XXX allow to check p is invalid (df.exists()) - void end(Nodeid manifestRevision); - } - // I'd rather let HgManifestCommand implement HgManifest.Inspector directly, but this pollutes API alot private class Mediator implements HgManifest.Inspector { // file names are likely to repeat in each revision, hence caching of Paths. @@ -138,61 +136,111 @@ private PathPool pathPool; private List<HgFileRevision> manifestContent; private Nodeid manifestNodeid; + private Exception failure; + private CancelSupport cancelHelper; - public void start() { + public void start(CancelSupport cs) { + assert cs != null; // Manifest keeps normalized paths pathPool = new PathPool(new PathRewrite.Empty()); + cancelHelper = cs; } public void done() { manifestContent = null; pathPool = null; } + + private void recordFailure(HgCallbackTargetException ex) { + failure = ex; + } + private void recordCancel(CancelledException ex) { + failure = ex; + } + + public void checkFailure() throws HgCallbackTargetException, CancelledException { + // TODO post-1.0 perhaps, can combine this code (record/checkFailure) for reuse in more classes (e.g. in Revlog) + if (failure instanceof HgCallbackTargetException) { + HgCallbackTargetException ex = (HgCallbackTargetException) failure; + failure = null; + throw ex; + } + if (failure instanceof CancelledException) { + CancelledException ex = (CancelledException) failure; + failure = null; + throw ex; + } + } public boolean begin(int manifestRevision, Nodeid nid, int changelogRevision) { if (needDirs && manifestContent == null) { manifestContent = new LinkedList<HgFileRevision>(); } - visitor.begin(manifestNodeid = nid); - return true; + try { + visitor.begin(manifestNodeid = nid); + cancelHelper.checkCancelled(); + return true; + } catch (HgCallbackTargetException ex) { + recordFailure(ex); + return false; + } catch (CancelledException ex) { + recordCancel(ex); + return false; + } } public boolean end(int revision) { - if (needDirs) { - LinkedHashMap<Path, LinkedList<HgFileRevision>> breakDown = new LinkedHashMap<Path, LinkedList<HgFileRevision>>(); - for (HgFileRevision fr : manifestContent) { - Path filePath = fr.getPath(); - Path dirPath = pathPool.parent(filePath); - LinkedList<HgFileRevision> revs = breakDown.get(dirPath); - if (revs == null) { - revs = new LinkedList<HgFileRevision>(); - breakDown.put(dirPath, revs); + try { + if (needDirs) { + LinkedHashMap<Path, LinkedList<HgFileRevision>> breakDown = new LinkedHashMap<Path, LinkedList<HgFileRevision>>(); + for (HgFileRevision fr : manifestContent) { + Path filePath = fr.getPath(); + Path dirPath = pathPool.parent(filePath); + LinkedList<HgFileRevision> revs = breakDown.get(dirPath); + if (revs == null) { + revs = new LinkedList<HgFileRevision>(); + breakDown.put(dirPath, revs); + } + revs.addLast(fr); } - revs.addLast(fr); + for (Path dir : breakDown.keySet()) { + visitor.dir(dir); + cancelHelper.checkCancelled(); + for (HgFileRevision fr : breakDown.get(dir)) { + visitor.file(fr); + } + } + manifestContent.clear(); } - for (Path dir : breakDown.keySet()) { - visitor.dir(dir); - for (HgFileRevision fr : breakDown.get(dir)) { - visitor.file(fr); - } - } - manifestContent.clear(); + visitor.end(manifestNodeid); + cancelHelper.checkCancelled(); + return true; + } catch (HgCallbackTargetException ex) { + recordFailure(ex); + return false; + } catch (CancelledException ex) { + recordCancel(ex); + return false; + } finally { + manifestNodeid = null; } - visitor.end(manifestNodeid); - manifestNodeid = null; - return true; } public boolean next(Nodeid nid, Path fname, Flags flags) { if (matcher != null && !matcher.accept(fname)) { return true; } - HgFileRevision fr = new HgFileRevision(repo, nid, flags, fname); - if (needDirs) { - manifestContent.add(fr); - } else { - visitor.file(fr); + try { + HgFileRevision fr = new HgFileRevision(repo, nid, flags, fname); + if (needDirs) { + manifestContent.add(fr); + } else { + visitor.file(fr); + } + return true; + } catch (HgCallbackTargetException ex) { + recordFailure(ex); + return false; } - return true; } } }