001package org.kuali.common.util.stream;
002
003import java.io.BufferedReader;
004import java.io.IOException;
005import java.io.InputStream;
006import java.io.InputStreamReader;
007import java.io.PrintWriter;
008
009import org.codehaus.plexus.util.IOUtil;
010import org.codehaus.plexus.util.cli.AbstractStreamHandler;
011import org.codehaus.plexus.util.cli.StreamConsumer;
012
013/**
014 * Copied from Plexus in order to add constructors that allow you to provide a BufferedReader directly, or to provide an explicit character encoding.
015 * 
016 * This class would be entirely unnecessary if the Plexus version had a constructor that allowed you to provide a BufferedReader
017 */
018public class StreamPumper extends AbstractStreamHandler {
019
020        private final BufferedReader in;
021        private final StreamConsumer consumer;
022        private final PrintWriter out;
023        private volatile Exception exception = null;
024        private static final int SIZE = 1024;
025
026        public StreamPumper(InputStream in) {
027                this(in, (StreamConsumer) null);
028        }
029
030        public StreamPumper(InputStream in, StreamConsumer consumer) {
031                this(in, (PrintWriter) null, consumer);
032        }
033
034        public StreamPumper(InputStream in, PrintWriter writer) {
035                this(in, writer, null);
036        }
037
038        public StreamPumper(InputStream in, PrintWriter writer, StreamConsumer consumer) {
039                this(new BufferedReader(new InputStreamReader(in), SIZE), writer, consumer);
040        }
041
042        public StreamPumper(InputStream in, String encoding, StreamConsumer consumer) throws IOException {
043                this(new BufferedReader(new InputStreamReader(in, encoding), SIZE), null, consumer);
044        }
045
046        public StreamPumper(BufferedReader in, PrintWriter writer, StreamConsumer consumer) {
047                this.in = in;
048                this.out = writer;
049                this.consumer = consumer;
050        }
051
052        @Override
053        public void run() {
054                try {
055                        for (String line = in.readLine(); line != null; line = in.readLine()) {
056                                try {
057                                        if (exception == null) {
058                                                consumeLine(line);
059                                        }
060                                } catch (Exception t) {
061                                        exception = t;
062                                }
063
064                                if (out != null) {
065                                        out.println(line);
066                                        out.flush();
067                                }
068                        }
069                } catch (IOException e) {
070                        exception = e;
071                } finally {
072                        IOUtil.close(in);
073                        synchronized (this) {
074                                setDone();
075                                this.notifyAll();
076                        }
077                }
078        }
079
080        public void flush() {
081                if (out != null) {
082                        out.flush();
083                }
084        }
085
086        public void close() {
087                IOUtil.close(out);
088        }
089
090        public Exception getException() {
091                return exception;
092        }
093
094        private void consumeLine(String line) {
095                if (consumer != null && !isDisabled()) {
096                        consumer.consumeLine(line);
097                }
098        }
099}