[JGIT PATCH 7/7] Refactor bundle transport to permit streaming from application

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The new TransportBundleStream is public and can be created by an
application directly from any InputStream.  This permits the app
to obtain the bundle data on its own via any means and feed it
into the bundle transport.

Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx>
---
 .../src/org/spearce/jgit/transport/Transport.java  |    4 +-
 .../spearce/jgit/transport/TransportBundle.java    |   36 +-------
 .../jgit/transport/TransportBundleFile.java        |   82 +++++++++++++++
 .../jgit/transport/TransportBundleStream.java      |  105 ++++++++++++++++++++
 4 files changed, 191 insertions(+), 36 deletions(-)
 create mode 100644 org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleFile.java
 create mode 100644 org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleStream.java

diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java b/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java
index 65f2c6b..7284b28 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java
@@ -204,8 +204,8 @@ else if (TransportGitAnon.canHandle(remote))
 		else if (TransportAmazonS3.canHandle(remote))
 			return new TransportAmazonS3(local, remote);
 
-		else if (TransportBundle.canHandle(remote))
-			return new TransportBundle(local, remote);
+		else if (TransportBundleFile.canHandle(remote))
+			return new TransportBundleFile(local, remote);
 
 		else if (TransportLocal.canHandle(remote))
 			return new TransportLocal(local, remote);
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java
index 765fc0f..fed34e8 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java
@@ -40,9 +40,6 @@
 package org.spearce.jgit.transport;
 
 import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -52,8 +49,8 @@
 import java.util.List;
 import java.util.Set;
 
-import org.spearce.jgit.errors.MissingObjectException;
 import org.spearce.jgit.errors.MissingBundlePrerequisiteException;
+import org.spearce.jgit.errors.MissingObjectException;
 import org.spearce.jgit.errors.NotSupportedException;
 import org.spearce.jgit.errors.PackProtocolException;
 import org.spearce.jgit.errors.TransportException;
@@ -66,7 +63,6 @@
 import org.spearce.jgit.revwalk.RevFlag;
 import org.spearce.jgit.revwalk.RevObject;
 import org.spearce.jgit.revwalk.RevWalk;
-import org.spearce.jgit.util.FS;
 import org.spearce.jgit.util.RawParseUtils;
 
 /**
@@ -76,39 +72,11 @@
  * communicate with to decide what the peer already knows. So push is not
  * supported by the bundle transport.
  */
-class TransportBundle extends PackTransport {
+abstract class TransportBundle extends PackTransport {
 	static final String V2_BUNDLE_SIGNATURE = "# v2 git bundle";
 
-	static boolean canHandle(final URIish uri) {
-		if (uri.getHost() != null || uri.getPort() > 0 || uri.getUser() != null
-				|| uri.getPass() != null || uri.getPath() == null)
-			return false;
-
-		if ("file".equals(uri.getScheme()) || uri.getScheme() == null) {
-			final File f = FS.resolve(new File("."), uri.getPath());
-			return f.isFile() || f.getName().endsWith(".bundle");
-		}
-
-		return false;
-	}
-
-	private final File bundle;
-
 	TransportBundle(final Repository local, final URIish uri) {
 		super(local, uri);
-		bundle = FS.resolve(new File("."), uri.getPath()).getAbsoluteFile();
-	}
-
-	@Override
-	public FetchConnection openFetch() throws NotSupportedException,
-			TransportException {
-		final InputStream src;
-		try {
-			src = new FileInputStream(bundle);
-		} catch (FileNotFoundException err) {
-			throw new TransportException(uri, "not found");
-		}
-		return new BundleFetchConnection(src);
 	}
 
 	@Override
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleFile.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleFile.java
new file mode 100644
index 0000000..c9ff1b2
--- /dev/null
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleFile.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@xxxxxxxxxxx>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.transport;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.spearce.jgit.errors.NotSupportedException;
+import org.spearce.jgit.errors.TransportException;
+import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.util.FS;
+
+class TransportBundleFile extends TransportBundle {
+	static boolean canHandle(final URIish uri) {
+		if (uri.getHost() != null || uri.getPort() > 0 || uri.getUser() != null
+				|| uri.getPass() != null || uri.getPath() == null)
+			return false;
+
+		if ("file".equals(uri.getScheme()) || uri.getScheme() == null) {
+			final File f = FS.resolve(new File("."), uri.getPath());
+			return f.isFile() || f.getName().endsWith(".bundle");
+		}
+
+		return false;
+	}
+
+	private final File bundle;
+
+	TransportBundleFile(final Repository local, final URIish uri) {
+		super(local, uri);
+		bundle = FS.resolve(new File("."), uri.getPath()).getAbsoluteFile();
+	}
+
+	@Override
+	public FetchConnection openFetch() throws NotSupportedException,
+			TransportException {
+		final InputStream src;
+		try {
+			src = new FileInputStream(bundle);
+		} catch (FileNotFoundException err) {
+			throw new TransportException(uri, "not found");
+		}
+		return new BundleFetchConnection(src);
+	}
+}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleStream.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleStream.java
new file mode 100644
index 0000000..0272261
--- /dev/null
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundleStream.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.transport;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spearce.jgit.errors.TransportException;
+import org.spearce.jgit.lib.Repository;
+
+/**
+ * Single shot fetch from a streamed Git bundle.
+ * <p>
+ * The bundle is read from an unbuffered input stream, which limits the
+ * transport to opening at most one FetchConnection before needing to recreate
+ * the transport instance.
+ */
+public class TransportBundleStream extends TransportBundle {
+	private InputStream src;
+
+	/**
+	 * Create a new transport to fetch objects from a streamed bundle.
+	 * <p>
+	 * The stream can be unbuffered (buffering is automatically provided
+	 * internally to smooth out short reads) and unpositionable (the stream is
+	 * read from only once, sequentially).
+	 * <p>
+	 * When the FetchConnection or the this instance is closed the supplied
+	 * input stream is also automatically closed. This frees callers from
+	 * needing to keep track of the supplied stream.
+	 * 
+	 * @param db
+	 *            repository the fetched objects will be loaded into.
+	 * @param uri
+	 *            symbolic name of the source of the stream. The URI can
+	 *            reference a non-existent resource. It is used only for
+	 *            exception reporting.
+	 * @param in
+	 *            the stream to read the bundle from.
+	 */
+	public TransportBundleStream(final Repository db, final URIish uri,
+			final InputStream in) {
+		super(db, uri);
+		src = in;
+	}
+
+	@Override
+	public FetchConnection openFetch() throws TransportException {
+		if (src == null)
+			throw new TransportException(uri, "Only one fetch supported");
+		try {
+			return new BundleFetchConnection(src);
+		} finally {
+			src = null;
+		}
+	}
+
+	@Override
+	public void close() {
+		if (src != null) {
+			try {
+				src.close();
+			} catch (IOException err) {
+				// Ignore a close error.
+			} finally {
+				src = null;
+			}
+		}
+	}
+}
-- 
1.6.0.1.319.g9f32b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux