Mercurial > hg4j
diff src/org/tmatesoft/hg/core/HgLogCommand.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/HgLogCommand.java Wed Mar 28 19:34:37 2012 +0200 +++ b/src/org/tmatesoft/hg/core/HgLogCommand.java Thu Mar 29 17:14:35 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 TMate Software Ltd +s * Copyright (c) 2011-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,7 +36,6 @@ import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgInternals; import org.tmatesoft.hg.repo.HgInvalidControlFileException; -import org.tmatesoft.hg.repo.HgInvalidRevisionException; import org.tmatesoft.hg.repo.HgInvalidStateException; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgRuntimeException; @@ -136,8 +135,9 @@ /** * Limit to specified subset of Changelog, [min(rev1,rev2), max(rev1,rev2)], inclusive. * Revision may be specified with {@link HgRepository#TIP} - * @param rev1 - revision local index - * @param rev2 - revision local index + * + * @param rev1 - local index of start changeset revision + * @param rev2 - index of end changeset revision * @return <code>this</code> instance for convenience */ public HgLogCommand range(int rev1, int rev2) { @@ -159,13 +159,16 @@ * * @param nid changeset revision * @return <code>this</code> for convenience - * @throws HgInvalidRevisionException if supplied nodeid doesn't identify any revision from this revlog - * @throws HgInvalidControlFileException if access to revlog index/data entry failed + * @throws HgBadArgumentException if failed to find supplied changeset revision */ - public HgLogCommand changeset(Nodeid nid) throws HgInvalidControlFileException, HgInvalidRevisionException { + public HgLogCommand changeset(Nodeid nid) throws HgBadArgumentException { // XXX perhaps, shall support multiple (...) arguments and extend #execute to handle not only range, but also set of revisions. - final int csetRevIndex = repo.getChangelog().getRevisionIndex(nid); - return range(csetRevIndex, csetRevIndex); + try { + final int csetRevIndex = repo.getChangelog().getRevisionIndex(nid); + return range(csetRevIndex, csetRevIndex); + } catch (HgRuntimeException ex) { + throw new HgBadArgumentException("Can't find revision", ex).setRevision(nid); + } } /** @@ -189,7 +192,9 @@ /** * Similar to {@link #execute(HgChangesetHandler)}, collects and return result as a list. - * @throws HgException FIXME EXCEPTIONS + * + * @see #execute(HgChangesetHandler) + * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state */ public List<HgChangeset> execute() throws HgException { CollectHandler collector = new CollectHandler(); @@ -213,9 +218,8 @@ * Iterate over range of changesets configured in the command. * * @param handler callback to process changesets. - * @throws HgCallbackTargetException wrapper for any exception user callback code may produce - * @throws HgInvalidControlFileException if access to revlog index/data entry failed - * @throws HgException in case of some other library issue + * @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 when inspector argument is null * @throws ConcurrentModificationException if this log command instance is already running @@ -241,15 +245,18 @@ } else { progressHelper.start(-1/*XXX enum const, or a dedicated method startUnspecified(). How about startAtLeast(int)?*/); HgDataFile fileNode = repo.getFileNode(file); + if (!fileNode.exists()) { + throw new HgPathNotFoundException(String.format("File %s not found in the repository", file), file); + } fileNode.history(startRev, endRev, this); csetTransform.checkFailure(); if (fileNode.isCopy()) { // even if we do not follow history, report file rename do { - if (handler instanceof FileHistoryHandler) { + if (handler instanceof HgChangesetHandler.WithCopyHistory) { HgFileRevision src = new HgFileRevision(repo, fileNode.getCopySourceRevision(), null, fileNode.getCopySourceName()); HgFileRevision dst = new HgFileRevision(repo, fileNode.getRevision(0), null, fileNode.getPath(), src.getPath()); - ((FileHistoryHandler) handler).copy(src, dst); + ((HgChangesetHandler.WithCopyHistory) handler).copy(src, dst); } if (limit > 0 && count >= limit) { // if limit reach, follow is useless. @@ -263,8 +270,8 @@ } while (followHistory && fileNode.isCopy()); } } -// } catch (HgRuntimeException ex) { -// FIXME wrap with checked HgRuntime subclass + } catch (HgRuntimeException ex) { + throw new HgLibraryFailureException(ex); } finally { csetTransform = null; progressHelper.done(); @@ -275,9 +282,8 @@ * Tree-wise iteration of a file history, with handy access to parent-child relations between changesets. * * @param handler callback to process changesets. - * @throws HgCallbackTargetException to re-throw exception from the handler - * @throws HgInvalidControlFileException if access to revlog index/data entry failed - * @throws HgException in case of some other library issue + * @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 command is not satisfied with its arguments * @throws ConcurrentModificationException if this log command instance is already running @@ -345,7 +351,7 @@ // 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)); + handler.treeElement(ei.init(n)); ph2.worked(1); cancelHelper.checkCancelled(); } @@ -390,26 +396,6 @@ } - /** - * When {@link HgLogCommand} is executed against file, handler passed to {@link HgLogCommand#execute(HgChangesetHandler)} may optionally - * implement this interface to get information about file renames. Method {@link #copy(HgFileRevision, HgFileRevision)} would - * get invoked prior any changeset of the original file (if file history being followed) is reported via {@link #next(HgChangeset)}. - * - * For {@link HgLogCommand#file(Path, boolean)} with renamed file path and follow argument set to false, - * {@link #copy(HgFileRevision, HgFileRevision)} would be invoked for the first copy/rename in the history of the file, but not - * followed by any changesets. - * - * @author Artem Tikhomirov - * @author TMate Software Ltd. - */ - 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? - /** - * @throws HgCallbackTargetException wrapper object for any exception user code may produce - */ - void copy(HgFileRevision from, HgFileRevision to) throws HgCallbackTargetException; - } - public static class CollectHandler implements HgChangesetHandler { private final List<HgChangeset> result = new LinkedList<HgChangeset>(); @@ -417,7 +403,7 @@ return Collections.unmodifiableList(result); } - public void next(HgChangeset changeset) { + public void cset(HgChangeset changeset) { result.add(changeset.clone()); } }