Subclass java.io.InputStream via gen-class. Does not print progress yet, but does correctly download all search indices

This commit is contained in:
Matthew Blair 2014-03-11 20:33:46 -04:00
parent 09d0bfa4b6
commit f2a14bae38
4 changed files with 38 additions and 93 deletions

View file

@ -34,7 +34,7 @@
:offline (comp (partial not-any? identity) :offline (comp (partial not-any? identity)
(juxt :online :disabled))} (juxt :online :disabled))}
:source-paths ["leiningen-core/src" "src"] :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 ;; work around Clojure bug http://dev.clojure.org/jira/browse/CLJ-1034
:uberjar-exclusions [#"^data_readers.clj$"] :uberjar-exclusions [#"^data_readers.clj$"]
:eval-in :leiningen) :eval-in :leiningen)

View file

@ -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;
}
}

View 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))

View file

@ -15,7 +15,7 @@
(org.apache.maven.index.updater IndexUpdater IndexUpdateRequest (org.apache.maven.index.updater IndexUpdater IndexUpdateRequest
ResourceFetcher) ResourceFetcher)
(org.codehaus.plexus DefaultPlexusContainer PlexusContainer) (org.codehaus.plexus DefaultPlexusContainer PlexusContainer)
(leiningen ConsoleReportingInputStream))) (leiningen extstream)))
(defonce container (DefaultPlexusContainer.)) (defonce container (DefaultPlexusContainer.))
@ -49,7 +49,7 @@
(println "Downloading" (str @base-url "/" name)) (println "Downloading" (str @base-url "/" name))
(let [r (http/get (str @base-url "/" name) (let [r (http/get (str @base-url "/" name)
{:throw-exceptions false :as :stream}) {:throw-exceptions false :as :stream})
s (ConsoleReportingInputStream. s (extstream.
(:body r) (:body r)
(Long/parseLong (get (:headers r) "content-length")))] (Long/parseLong (get (:headers r) "content-length")))]
(deliver stream s) (deliver stream s)