diff src/org/tmatesoft/hg/core/HgCatCommand.java @ 148:1a7a9a20e1f9

Exceptions, javadoc. Initial cancel and progress support
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 23 Feb 2011 22:36:28 +0100
parents 4a948ec83980
children d5268ca7715b
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCatCommand.java	Tue Feb 22 15:49:26 2011 +0100
+++ b/src/org/tmatesoft/hg/core/HgCatCommand.java	Wed Feb 23 22:36:28 2011 +0100
@@ -16,14 +16,17 @@
  */
 package org.tmatesoft.hg.core;
 
+import static org.tmatesoft.hg.repo.HgInternals.wrongLocalRevision;
 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION;
 import static org.tmatesoft.hg.repo.HgRepository.TIP;
 
 import java.io.FileNotFoundException;
+import java.io.IOException;
 
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.util.ByteChannel;
+import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.Path;
 
 /**
@@ -43,25 +46,59 @@
 		repo = hgRepo;
 	}
 
+	/**
+	 * File to read, required parameter 
+	 * @param fname path to a repository file, can't be <code>null</code>
+	 * @return <code>this</code> for convenience
+	 * @throws IllegalArgumentException if supplied fname is null or points to directory
+	 */
 	public HgCatCommand file(Path fname) {
+		if (fname == null || fname.isDirectory()) {
+			throw new IllegalArgumentException(String.valueOf(fname));
+		}
 		file = fname;
 		return this;
 	}
 
-	// rev can't be WORKING_COPY (if allowed, need to implement in #execute())
+	/**
+	 * Invocation of this method clears revision set with {@link #revision(Nodeid)} or {@link #revision(int)} earlier.
+	 * XXX rev can't be WORKING_COPY (if allowed, need to implement in #execute())
+	 * @param rev local revision number, non-negative, or one of predefined constants. Note, use of {@link HgRepository#BAD_REVISION}, 
+	 * although possible, makes little sense (command would fail if executed).  
+ 	 * @return <code>this</code> for convenience
+	 */
 	public HgCatCommand revision(int rev) {
+		if (wrongLocalRevision(rev)) {
+			throw new IllegalArgumentException(String.valueOf(rev));
+		}
 		localRevision = rev;
 		revision = null;
 		return this;
 	}
 	
+	/**
+	 * Select revision to read. Invocation of this method clears revision set with {@link #revision(int)} or {@link #revision(Nodeid)} earlier.
+	 * 
+	 * @param nodeid - unique revision identifier, Note, use of <code>null</code> or {@link Nodeid#NULL} is senseless
+	 * @return <code>this</code> for convenience
+	 */
 	public HgCatCommand revision(Nodeid nodeid) {
+		if (nodeid != null && nodeid.isNull()) {
+			nodeid = null;
+		}
 		revision = nodeid;
 		localRevision = BAD_REVISION;
 		return this;
 	}
 
-	public void execute(ByteChannel sink) throws Exception /*TODO own exception type*/ {
+	/**
+	 * Runs the command with current set of parameters and pipes data to provided sink.
+	 * 
+	 * @param sink output channel to write data to.
+	 * @throws HgDataStreamException 
+	 * @throws IllegalArgumentException when command arguments are incomplete or wrong
+	 */
+	public void execute(ByteChannel sink) throws HgDataStreamException, IOException, CancelledException {
 		if (localRevision == BAD_REVISION && revision == null) {
 			throw new IllegalArgumentException("Either local file revision number or nodeid shall be specified");
 		}
@@ -69,11 +106,11 @@
 			throw new IllegalArgumentException("Name of the file is missing");
 		}
 		if (sink == null) {
-			throw new IllegalArgumentException();
+			throw new IllegalArgumentException("Need an output channel");
 		}
 		HgDataFile dataFile = repo.getFileNode(file);
 		if (!dataFile.exists()) {
-			throw new FileNotFoundException();
+			throw new HgDataStreamException(file.toString(), new FileNotFoundException(file.toString()));
 		}
 		int revToExtract;
 		if (revision != null) {