WorkTreeUpdater: use DirCacheCheckout#StreamSupplier

This avoids having to introduce the StreamLoader bridging class.

Change-Id: I98de155c458745236df24d6323eabed5061e7f8c
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index c955d79..e7f40d8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -58,7 +58,6 @@
 import org.eclipse.jgit.util.FileUtils;
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.RawParseUtils;
-import org.eclipse.jgit.util.WorkTreeUpdater;
 import org.eclipse.jgit.util.StringUtils;
 import org.eclipse.jgit.util.TemporaryBuffer;
 import org.eclipse.jgit.util.TemporaryBuffer.LocalFile;
@@ -461,8 +460,7 @@ private void applyBinary(Repository repository, String path, File f,
 							SHA1InputStream hashed = new SHA1InputStream(hash,
 									input)) {
 						DirCacheCheckout.getContent(repository, path, checkOut,
-								WorkTreeUpdater.createStreamLoader(() -> hashed, finalSize),
-								null, out);
+								() -> hashed, null, out);
 						if (!fh.getNewId().toObjectId()
 								.equals(hash.toObjectId())) {
 							throw new PatchApplyException(MessageFormat.format(
@@ -630,9 +628,7 @@ && canApplyAt(hunkLines, newLines, 0)) {
 			}
 			try (OutputStream output = new FileOutputStream(f)) {
 				DirCacheCheckout.getContent(repository, path, checkOut,
-						WorkTreeUpdater.createStreamLoader(buffer::openInputStream,
-								buffer.length()),
-						null, output);
+						buffer::openInputStream, null, output);
 			}
 		} finally {
 			buffer.destroy();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index f4d19cb..b134cdc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -61,7 +61,6 @@
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.LfsFactory;
 import org.eclipse.jgit.util.WorkTreeUpdater;
-import org.eclipse.jgit.util.WorkTreeUpdater.StreamLoader;
 import org.eclipse.jgit.util.TemporaryBuffer;
 
 /**
@@ -912,9 +911,7 @@ private File writeMergedFile(TemporaryBuffer rawMerged,
 		if (!fs.exists(parentFolder)) {
 			parentFolder.mkdirs();
 		}
-		StreamLoader contentLoader = WorkTreeUpdater.createStreamLoader(rawMerged::openInputStream,
-				rawMerged.length());
-		workTreeUpdater.updateFileWithContent(contentLoader,
+		workTreeUpdater.updateFileWithContent(rawMerged::openInputStream,
 				eol, tw.getSmudgeCommand(attributes), of.getPath(), of);
 		return of;
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/WorkTreeUpdater.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/WorkTreeUpdater.java
index d35efe3..16cd7f8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/WorkTreeUpdater.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/WorkTreeUpdater.java
@@ -11,7 +11,6 @@
 
 import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
 
-import java.io.BufferedInputStream;
 import java.io.Closeable;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -34,22 +33,19 @@
 import org.eclipse.jgit.dircache.DirCacheBuildIterator;
 import org.eclipse.jgit.dircache.DirCacheBuilder;
 import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.dircache.DirCacheCheckout.StreamSupplier;
 import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
 import org.eclipse.jgit.dircache.DirCacheEntry;
 import org.eclipse.jgit.errors.IndexWriteException;
-import org.eclipse.jgit.errors.LargeObjectException;
 import org.eclipse.jgit.errors.NoWorkTreeException;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ObjectReader;
-import org.eclipse.jgit.lib.ObjectStream;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
 import org.eclipse.jgit.treewalk.WorkingTreeOptions;
@@ -245,77 +241,6 @@ public static WorkTreeUpdater createInCoreWorkTreeUpdater(Repository repo,
 		return new WorkTreeUpdater(repo, dirCache, oi);
 	}
 
-	/**
-	 * Something that can supply an {@link InputStream}.
-	 */
-	public interface StreamSupplier {
-
-		/**
-		 * Loads the input stream.
-		 *
-		 * @return the loaded stream
-		 * @throws IOException
-		 *             if any reading error occurs
-		 */
-		InputStream load() throws IOException;
-	}
-
-	/**
-	 * We want to use DirCacheCheckout for its CR-LF and smudge filters, but DirCacheCheckout needs an
-	 * ObjectLoader rather than InputStream. This class provides a bridge between the two.
-	 */
-	public static class StreamLoader extends ObjectLoader {
-
-		private final StreamSupplier data;
-
-		private final long size;
-
-		private StreamLoader(StreamSupplier data, long length) {
-			this.data = data;
-			this.size = length;
-		}
-
-		@Override
-		public int getType() {
-			return Constants.OBJ_BLOB;
-		}
-
-		@Override
-		public long getSize() {
-			return size;
-		}
-
-		@Override
-		public boolean isLarge() {
-			return true;
-		}
-
-		@Override
-		public byte[] getCachedBytes() throws LargeObjectException {
-			throw new LargeObjectException();
-		}
-
-		@Override
-		public ObjectStream openStream() throws IOException {
-			return new ObjectStream.Filter(getType(), getSize(),
-					new BufferedInputStream(data.load()));
-		}
-	}
-
-	/**
-	 * Creates stream loader for the given supplier.
-	 *
-	 * @param supplier
-	 *            to wrap
-	 * @param length
-	 *            of the supplied content
-	 * @return the result stream loader
-	 */
-	public static StreamLoader createStreamLoader(StreamSupplier supplier,
-			long length) {
-		return new StreamLoader(supplier, length);
-	}
-
 	private static int getInCoreFileSizeLimit(Config config) {
 		return config.getInt(ConfigConstants.CONFIG_MERGE_SECTION,
 				ConfigConstants.CONFIG_KEY_IN_CORE_LIMIT, 10 << 20);
@@ -599,8 +524,8 @@ public void close() throws IOException {
 	/**
 	 * Updates the file in the checkout with the given content.
 	 *
-	 * @param resultStreamLoader
-	 *            with the content to be updated
+	 * @param inputStream
+	 *            the content to be updated
 	 * @param streamType
 	 *            for parsing the content
 	 * @param smudgeCommand
@@ -612,7 +537,7 @@ public void close() throws IOException {
 	 * @throws IOException
 	 *             if the file cannot be updated
 	 */
-	public void updateFileWithContent(StreamLoader resultStreamLoader,
+	public void updateFileWithContent(StreamSupplier inputStream,
 			EolStreamType streamType, String smudgeCommand, String path,
 			File file) throws IOException {
 		if (inCore) {
@@ -623,7 +548,7 @@ public void updateFileWithContent(StreamLoader resultStreamLoader,
 
 		try (OutputStream outputStream = new FileOutputStream(file)) {
 			DirCacheCheckout.getContent(repo, path, metadata,
-					resultStreamLoader, workingTreeOptions, outputStream);
+					inputStream, workingTreeOptions, outputStream);
 		}
 	}
 
@@ -631,8 +556,8 @@ public void updateFileWithContent(StreamLoader resultStreamLoader,
 	 * Creates a path with the given content, and adds it to the specified stage
 	 * to the index builder.
 	 *
-	 * @param inputStream
-	 *            with the content to be updated
+	 * @param input
+	 *            the content to be updated
 	 * @param path
 	 *            of the file to be updated
 	 * @param fileMode
@@ -649,43 +574,12 @@ public void updateFileWithContent(StreamLoader resultStreamLoader,
 	 * @throws IOException
 	 *             if inserting the content fails
 	 */
-	public DirCacheEntry insertToIndex(InputStream inputStream, byte[] path,
-			FileMode fileMode, int entryStage, Instant lastModified, int len,
-			Attribute lfsAttribute) throws IOException {
-		StreamLoader contentLoader = createStreamLoader(() -> inputStream, len);
-		return insertToIndex(contentLoader, path, fileMode, entryStage,
-				lastModified, len, lfsAttribute);
-	}
-
-	/**
-	 * Creates a path with the given content, and adds it to the specified stage
-	 * to the index builder.
-	 *
-	 * @param resultStreamLoader
-	 *            with the content to be updated
-	 * @param path
-	 *            of the file to be updated
-	 * @param fileMode
-	 *            of the modified file
-	 * @param entryStage
-	 *            of the new entry
-	 * @param lastModified
-	 *            instant of the modified file
-	 * @param len
-	 *            of the content
-	 * @param lfsAttribute
-	 *            for checking for LFS enablement
-	 * @return the entry which was added to the index
-	 * @throws IOException
-	 *             if inserting the content fails
-	 */
-	public DirCacheEntry insertToIndex(StreamLoader resultStreamLoader,
+	public DirCacheEntry insertToIndex(InputStream input,
 			byte[] path, FileMode fileMode, int entryStage,
 			Instant lastModified, int len, Attribute lfsAttribute)
 			throws IOException {
-		return addExistingToIndex(
-				insertResult(resultStreamLoader, lfsAttribute), path, fileMode,
-				entryStage, lastModified, len);
+		return addExistingToIndex(insertResult(input, lfsAttribute, len), path,
+				fileMode, entryStage, lastModified, len);
 	}
 
 	/**
@@ -713,16 +607,15 @@ public DirCacheEntry addExistingToIndex(ObjectId objectId, byte[] path,
 			dce.setLastModified(lastModified);
 		}
 		dce.setLength(inCore ? 0 : len);
-
 		dce.setObjectId(objectId);
 		builder.add(dce);
 		return dce;
 	}
 
-	private ObjectId insertResult(StreamLoader resultStreamLoader,
-			Attribute lfsAttribute) throws IOException {
+	private ObjectId insertResult(InputStream input,
+			Attribute lfsAttribute, long length) throws IOException {
 		try (LfsInputStream is = LfsFactory.getInstance().applyCleanFilter(repo,
-				resultStreamLoader.data.load(), resultStreamLoader.size,
+				input, length,
 				lfsAttribute)) {
 			return inserter.insert(OBJ_BLOB, is.getLength(), is);
 		}