001    /*
002     * $Id: OutputStreamDemux.java,v 1.11 2012/02/19 17:35:47 davep Exp $
003     *
004     * This file is part of McIDAS-V
005     *
006     * Copyright 2007-2012
007     * Space Science and Engineering Center (SSEC)
008     * University of Wisconsin - Madison
009     * 1225 W. Dayton Street, Madison, WI 53706, USA
010     * https://www.ssec.wisc.edu/mcidas
011     * 
012     * All Rights Reserved
013     * 
014     * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015     * some McIDAS-V source code is based on IDV and VisAD source code.  
016     * 
017     * McIDAS-V is free software; you can redistribute it and/or modify
018     * it under the terms of the GNU Lesser Public License as published by
019     * the Free Software Foundation; either version 3 of the License, or
020     * (at your option) any later version.
021     * 
022     * McIDAS-V is distributed in the hope that it will be useful,
023     * but WITHOUT ANY WARRANTY; without even the implied warranty of
024     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025     * GNU Lesser Public License for more details.
026     * 
027     * You should have received a copy of the GNU Lesser Public License
028     * along with this program.  If not, see http://www.gnu.org/licenses.
029     */
030    
031    package edu.wisc.ssec.mcidasv.jython;
032    
033    import static edu.wisc.ssec.mcidasv.util.Contract.notNull;
034    
035    import java.io.ByteArrayOutputStream;
036    import java.io.IOException;
037    import java.io.OutputStream;
038    import java.io.UnsupportedEncodingException;
039    import java.util.Map;
040    import java.util.concurrent.ConcurrentHashMap;
041    
042    public class OutputStreamDemux extends ByteArrayOutputStream {
043    
044        protected enum OutputType { NORMAL, ERROR };
045    
046        private OutputType type;
047    
048        private final Map<String, ByteArrayOutputStream> streamMap = new ConcurrentHashMap<String, ByteArrayOutputStream>();
049        private final Map<String, Interpreter> interpreterMap = new ConcurrentHashMap<String, Interpreter>();
050        private final Map<String, Console> consoleMap = new ConcurrentHashMap<String, Console>();
051    
052        private static String id() {
053            return Thread.currentThread().getName();
054        }
055    
056        public synchronized void addStream(final Console console, final Interpreter interpreter, final OutputType type) {
057            notNull(console, "Cannot provide a null Jython console");
058            notNull(interpreter, "Cannot provide a null Jython interpreter");
059            this.type = notNull(type, "Cannot provide a null output type");
060            String threadId = id();
061            streamMap.put(threadId, new ByteArrayOutputStream());
062            interpreterMap.put(threadId, interpreter);
063            consoleMap.put(threadId, console);
064        }
065    
066        @Override public void close() throws IOException {
067            streamMap.get(id()).close();
068        }
069    
070        @Override public synchronized void flush() throws IOException {
071            streamMap.get(id()).flush();
072            Console console = consoleMap.get(id());
073            Interpreter interpreter = interpreterMap.get(id());
074            interpreter.handleStreams(console, null);
075        }
076    
077        @Override public void write(byte[] b) throws IOException {
078            streamMap.get(id()).write(b);
079        }
080    
081        @Override public void write(byte[] b, int off, int len) {
082            streamMap.get(id()).write(b, off, len);
083        }
084    
085        @Override public void write(int b) {
086            streamMap.get(id()).write(b);
087        }
088    
089        @Override public void reset() {
090            streamMap.get(id()).reset();
091        }
092    
093        @Override public int size() {
094            return streamMap.get(id()).size();
095        }
096    
097        @Override public byte[] toByteArray() {
098            return streamMap.get(id()).toByteArray();
099        }
100    
101        @Deprecated @Override public String toString(int hibyte) {
102            return streamMap.get(id()).toString();
103        }
104    
105        @Override public String toString(String charsetName) throws UnsupportedEncodingException {
106            return streamMap.get(id()).toString(charsetName);
107        }
108    
109        @Override public void writeTo(OutputStream out) throws IOException {
110            streamMap.get(id()).writeTo(out);
111        }
112    
113        @Override public String toString() {
114            ByteArrayOutputStream stream = streamMap.get(id());
115            if (stream == null) {
116                return "null";
117            } else {
118                return stream.toString();
119            }
120        }
121    }