001    package org.codehaus.plexus.util.cli;
002    
003    /*
004     * Copyright The Codehaus Foundation.
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.io.OutputStream;
022    
023    import org.apache.commons.io.IOUtils;
024    
025    /**
026     * Read from an InputStream and write the output to an OutputStream.
027     * 
028     * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
029     * @version $Id$
030     */
031    public class StreamFeeder extends AbstractStreamHandler {
032    
033            private InputStream input;
034            private OutputStream output;
035    
036            /**
037             * Create a new StreamFeeder
038             * 
039             * @param input
040             *            Stream to read from
041             * @param output
042             *            Stream to write to
043             */
044            public StreamFeeder(InputStream input, OutputStream output) {
045                    this.input = input;
046                    this.output = output;
047            }
048    
049            // ----------------------------------------------------------------------
050            // Runnable implementation
051            // ----------------------------------------------------------------------
052    
053            @Override
054            public void run() {
055                    try {
056                            feed();
057                    } catch (Throwable ex) {
058                            // Catch everything so the streams will be closed and flagged as done.
059                    } finally {
060                            close();
061                            synchronized (this) {
062                                    setDone();
063                                    this.notifyAll();
064                            }
065                    }
066            }
067    
068            // ----------------------------------------------------------------------
069            //
070            // ----------------------------------------------------------------------
071    
072            public void close() {
073                    if (input != null) {
074                            synchronized (input) {
075                                    IOUtils.closeQuietly(input);
076                                    input = null;
077                            }
078                    }
079    
080                    if (output != null) {
081                            synchronized (output) {
082                                    IOUtils.closeQuietly(output);
083                                    output = null;
084                            }
085                    }
086            }
087    
088            // ----------------------------------------------------------------------
089            //
090            // ----------------------------------------------------------------------
091    
092            private void feed() throws IOException {
093                    int data = input.read();
094    
095                    while (!isDone() && data != -1) {
096                            synchronized (output) {
097                                    if (!isDisabled()) {
098                                            output.write(data);
099                                    }
100    
101                                    data = input.read();
102                            }
103                    }
104            }
105    
106    }