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 }