001    /*
002     * Copyright (C) 2012 eXo Platform SAS.
003     *
004     * This is free software; you can redistribute it and/or modify it
005     * under the terms of the GNU Lesser General Public License as
006     * published by the Free Software Foundation; either version 2.1 of
007     * the License, or (at your option) any later version.
008     *
009     * This software is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with this software; if not, write to the Free
016     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018     */
019    
020    package org.crsh.util;
021    
022    import java.io.IOException;
023    import java.io.InterruptedIOException;
024    import java.util.LinkedList;
025    
026    public class PipedChannel {
027    
028      /** . */
029      private final LinkedList<Integer> queue;
030    
031      /** . */
032      private final Object lock;
033    
034      /** . */
035      private boolean closed;
036    
037      /** . */
038      private InputStream in;
039    
040      /** . */
041      private OutputStream out;
042    
043      public PipedChannel() {
044        this.queue = new LinkedList<Integer>();
045        this.lock = new Object();
046        this.closed = false;
047        in = new InputStream();
048        out = new OutputStream();
049      }
050    
051      public InputStream getIn() {
052        return in;
053      }
054    
055      public OutputStream getOut() {
056        return out;
057      }
058    
059      class InputStream extends java.io.InputStream {
060        @Override
061        public int read() throws IOException {
062          synchronized (lock) {
063            while (true) {
064              if (queue.size() > 0) {
065                return queue.removeFirst();
066              } else {
067                if (closed) {
068                  throw new IOException("closed");
069                } else {
070                  try {
071                    lock.wait();
072                  }
073                  catch (InterruptedException e) {
074                    InterruptedIOException iioe = new InterruptedIOException();
075                    iioe.initCause(e);
076                    throw iioe;
077                  }
078                }
079              }
080            }
081          }
082        }
083    
084        @Override
085        public void close() throws IOException {
086          synchronized (lock) {
087            if (!closed) {
088              closed = true;
089              lock.notifyAll();
090            }
091          }
092        }
093      }
094    
095      class OutputStream extends java.io.OutputStream {
096        @Override
097        public void write(int b) throws IOException {
098          synchronized (lock) {
099            if (closed) {
100              throw new IOException("closed");
101            }
102            queue.add(b);
103          }
104        }
105    
106        @Override
107        public void flush() throws IOException {
108          synchronized (lock) {
109            if (closed) {
110              throw new IOException("closed");
111            }
112            lock.notifyAll();
113          }
114        }
115    
116        @Override
117        public void close() throws IOException {
118          synchronized (lock) {
119            if (!closed) {
120              closed = true;
121              lock.notifyAll();
122            }
123          }
124        }
125      }
126    }