001/*
002 * $Id: OutputStreamDemux.java,v 1.10 2011/03/24 16:06:33 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2011
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
031package edu.wisc.ssec.mcidasv.jython;
032
033import static edu.wisc.ssec.mcidasv.util.Contract.notNull;
034
035import java.io.ByteArrayOutputStream;
036import java.io.IOException;
037import java.io.OutputStream;
038import java.io.UnsupportedEncodingException;
039import java.util.Map;
040import java.util.concurrent.ConcurrentHashMap;
041
042public 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}