Subclass java.io.InputStream via gen-class. Does not print progress yet, but does correctly download all search indices
This commit is contained in:
parent
09d0bfa4b6
commit
f2a14bae38
4 changed files with 38 additions and 93 deletions
|
@ -34,7 +34,7 @@
|
|||
:offline (comp (partial not-any? identity)
|
||||
(juxt :online :disabled))}
|
||||
:source-paths ["leiningen-core/src" "src"]
|
||||
:java-source-paths ["src/java"]
|
||||
:aot [leiningen.extstream]
|
||||
;; work around Clojure bug http://dev.clojure.org/jira/browse/CLJ-1034
|
||||
:uberjar-exclusions [#"^data_readers.clj$"]
|
||||
:eval-in :leiningen)
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
package leiningen;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Extends java.io.InputStream by reporting to console output
|
||||
* the percentage of the stream that has been consumed after each
|
||||
* read. Employs a Decorator pattern so that the capabilities of
|
||||
* the original InputStream subclass are preserved.
|
||||
*/
|
||||
|
||||
public class ConsoleReportingInputStream extends InputStream
|
||||
{
|
||||
|
||||
private final long contentLength;
|
||||
private final InputStream stream;
|
||||
private long totalBytesRead=0;
|
||||
|
||||
/**
|
||||
* @param stream - the InputStream to be wrapped by this object
|
||||
* @param contentLength - the size, in bytes, of the content
|
||||
* referred to by the stream parameter
|
||||
*/
|
||||
public ConsoleReportingInputStream(InputStream stream, long contentLength)
|
||||
throws IOException
|
||||
{
|
||||
if(stream == null) {
|
||||
throw new IOException("InputStream cannot be null");
|
||||
}
|
||||
|
||||
if(contentLength <= 0) {
|
||||
throw new IOException("InputStream content-length must be greater than zero");
|
||||
}
|
||||
|
||||
this.stream = stream;
|
||||
this.contentLength = contentLength;
|
||||
}
|
||||
|
||||
|
||||
private void updateAndReportProgress(int bytesRead) {
|
||||
|
||||
totalBytesRead += bytesRead;
|
||||
double progress = (totalBytesRead * 100.0)/contentLength;
|
||||
// if progress < 100.0, then end output with carriage return
|
||||
// otherwise, end output with newline. This ensures that
|
||||
// progress will update on the same line until 100% reached
|
||||
char lineTerm = '\r';
|
||||
if(progress == 100.0) { lineTerm = '\n'; }
|
||||
|
||||
// Show one digit to the right of the decimal
|
||||
System.out.printf("%.1f", progress);
|
||||
System.out.print("% complete" + lineTerm);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
byte[] buf = new byte[1];
|
||||
int cnt = stream.read(buf);
|
||||
|
||||
if(cnt == -1) { return cnt; }
|
||||
else {
|
||||
updateAndReportProgress(cnt);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException
|
||||
{
|
||||
int cnt = stream.read(b);
|
||||
if(cnt >= 0) {
|
||||
updateAndReportProgress(cnt);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
int cnt = stream.read(b, off, len);
|
||||
if(cnt >= 0) {
|
||||
updateAndReportProgress(cnt);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
}
|
35
src/leiningen/extstream.clj
Normal file
35
src/leiningen/extstream.clj
Normal file
|
@ -0,0 +1,35 @@
|
|||
(ns leiningen.extstream
|
||||
(:gen-class
|
||||
:extends java.io.InputStream
|
||||
:state state
|
||||
:init init
|
||||
:constructors {[java.io.InputStream Long] []}
|
||||
:main false))
|
||||
|
||||
(defn -init [stream content-length]
|
||||
[ [] (ref (into {} {:stream stream
|
||||
:content-length content-length
|
||||
:total-bytes 0})) ])
|
||||
|
||||
(defn print-progress [count length]
|
||||
(let [progress (/ (* count 100.0) length)]
|
||||
(printf "%.1f%%\r" progress)))
|
||||
|
||||
(defn -read-void [this]
|
||||
(let [b []
|
||||
count (.read (:stream @(.state this)) b)]
|
||||
(if (= -1 count) count (first b))))
|
||||
|
||||
(defn -read-byte<> [this bytebuf]
|
||||
(let [state-map (.state this)
|
||||
stream (:stream @state-map)
|
||||
content-length (:content-length @state-map)
|
||||
count (.read stream bytebuf)]
|
||||
count))
|
||||
|
||||
(defn -read-byte<>-int-int [this bytebuf off len]
|
||||
(let [state-map (.state this)
|
||||
stream (:stream @state-map)
|
||||
content-length (:content-length @state-map)
|
||||
count (.read stream bytebuf off len)]
|
||||
count))
|
|
@ -15,7 +15,7 @@
|
|||
(org.apache.maven.index.updater IndexUpdater IndexUpdateRequest
|
||||
ResourceFetcher)
|
||||
(org.codehaus.plexus DefaultPlexusContainer PlexusContainer)
|
||||
(leiningen ConsoleReportingInputStream)))
|
||||
(leiningen extstream)))
|
||||
|
||||
(defonce container (DefaultPlexusContainer.))
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
|||
(println "Downloading" (str @base-url "/" name))
|
||||
(let [r (http/get (str @base-url "/" name)
|
||||
{:throw-exceptions false :as :stream})
|
||||
s (ConsoleReportingInputStream.
|
||||
s (extstream.
|
||||
(:body r)
|
||||
(Long/parseLong (get (:headers r) "content-length")))]
|
||||
(deliver stream s)
|
||||
|
|
Loading…
Reference in a new issue