diff src/org/tmatesoft/hg/core/HgFileRevision.java @ 316:ee6b467c1a5f

Supply HGFileRevision with copy information when possible, calculate it otherwise
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 28 Sep 2011 13:09:16 +0200
parents 4c3b9f679412
children 58725dd511b3
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgFileRevision.java	Wed Sep 28 12:18:21 2011 +0200
+++ b/src/org/tmatesoft/hg/core/HgFileRevision.java	Wed Sep 28 13:09:16 2011 +0200
@@ -17,6 +17,7 @@
 package org.tmatesoft.hg.core;
 
 import org.tmatesoft.hg.repo.HgDataFile;
+import org.tmatesoft.hg.repo.HgInternals;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.util.ByteChannel;
 import org.tmatesoft.hg.util.CancelledException;
@@ -32,16 +33,25 @@
 	private final HgRepository repo;
 	private final Nodeid revision;
 	private final Path path;
-	
+	private Path origin;
+	private Boolean isCopy = null; // null means not yet known
+
 	public HgFileRevision(HgRepository hgRepo, Nodeid rev, Path p) {
 		if (hgRepo == null || rev == null || p == null) {
 			// since it's package local, it is our code to blame for non validated arguments
-			throw new HgBadStateException();
+			throw new IllegalArgumentException();
 		}
 		repo = hgRepo;
 		revision = rev;
 		path = p;
 	}
+
+	// this cons shall be used when we know whether p was a copy. Perhaps, shall pass Map<Path,Path> instead to stress orig argument is not optional  
+	HgFileRevision(HgRepository hgRepo, Nodeid rev, Path p, Path orig) {
+		this(hgRepo, rev, p);
+		isCopy = Boolean.valueOf(orig == null);
+		origin = orig; 
+	}
 	
 	public Path getPath() {
 		return path;
@@ -49,10 +59,42 @@
 	public Nodeid getRevision() {
 		return revision;
 	}
+	public boolean wasCopied() {
+		if (isCopy == null) {
+			checkCopy();
+		}
+		return isCopy.booleanValue();
+	}
+	/**
+	 * @return <code>null</code> if {@link #wasCopied()} is <code>false</code>, name of the copy source otherwise.
+	 */
+	public Path getOriginIfCopy() {
+		if (wasCopied()) {
+			return origin;
+		}
+		return null;
+	}
+
 	public void putContentTo(ByteChannel sink) throws HgDataStreamException, CancelledException {
 		HgDataFile fn = repo.getFileNode(path);
 		int localRevision = fn.getLocalRevision(revision);
 		fn.contentWithFilters(localRevision, sink);
 	}
 
+	private void checkCopy() {
+		HgDataFile fn = repo.getFileNode(path);
+		try {
+			if (fn.isCopy()) {
+				if (fn.getRevision(0).equals(revision)) {
+					// this HgFileRevision represents first revision of the copy
+					isCopy = Boolean.TRUE;
+					origin = fn.getCopySourceName();
+					return;
+				}
+			}
+		} catch (HgDataStreamException ex) {
+			HgInternals.getContext(repo).getLog().error(getClass(), ex, null);
+		}
+		isCopy = Boolean.FALSE;
+	}
 }