001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  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,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package org.apache.geronimo.gshell.whisper.stream;
021    
022    import java.io.InputStream;
023    import java.io.OutputStream;
024    import java.util.concurrent.atomic.AtomicInteger;
025    
026    import org.slf4j.Logger;
027    import org.slf4j.LoggerFactory;
028    
029    /**
030     * Feeds data from an input stream to an output stream.
031     *
032     * @version $Rev: 578566 $ $Date: 2007-09-23 05:02:46 -0700 (Sun, 23 Sep 2007) $
033     */
034    public class StreamFeeder
035        implements Runnable
036    {
037        private final Logger log = LoggerFactory.getLogger(getClass());
038    
039        private final InputStream input;
040    
041        private final OutputStream output;
042    
043        private volatile boolean running;
044    
045        public StreamFeeder(final InputStream input, final OutputStream output) {
046            assert input != null;
047            assert output != null;
048            
049            this.input = input;
050            this.output = output;
051        }
052    
053        public void run() {
054            running = true;
055    
056            log.debug("Running");
057    
058            //
059            // TODO: Look into using a byte[] buffer here to read larger chunks at the same time?
060            //
061            
062            try {
063                int b;
064    
065                while (running && ((b = input.read()) != -1)) {
066                    output.write(b);
067                }
068            }
069            catch (Throwable e) {
070                log.error("Feed failure: " + e, e);
071            }
072            finally {
073                close();
074            }
075    
076            log.debug("Stopped");
077        }
078    
079        public boolean isRunning() {
080            return running;
081        }
082        
083        public void close() {
084            running = false;
085            
086            log.debug("Closed");
087        }
088    
089        private static final AtomicInteger THREAD_COUNTER = new AtomicInteger(0);
090    
091        public Thread createThread() {
092            Thread t = new Thread(this, getClass().getSimpleName() + "-" + THREAD_COUNTER.getAndIncrement());
093    
094            t.setDaemon(true);
095            
096            return t;
097        }
098    }