1 package hudson.remoting; 2 3 import java.io.ByteArrayOutputStream ; 4 import java.io.IOException ; 5 import java.io.OutputStream ; 6 7 11 final class ProxyOutputStream extends OutputStream { 12 private Channel channel; 13 private int oid; 14 15 19 private ByteArrayOutputStream tmp; 20 21 24 private boolean closed; 25 26 32 public ProxyOutputStream() { 33 } 34 35 41 public ProxyOutputStream(Channel channel, int oid) throws IOException { 42 connect(channel,oid); 43 } 44 45 48 synchronized void connect(Channel channel, int oid) throws IOException { 49 if(this.channel!=null) 50 throw new IllegalStateException ("Cannot connect twice"); 51 this.channel = channel; 52 this.oid = oid; 53 54 if(tmp!=null) { 56 channel.send(new Chunk(oid,tmp.toByteArray())); 57 tmp = null; 58 } 59 if(closed) close(); 61 } 62 63 public void write(int b) throws IOException { 64 write(new byte[]{(byte)b},0,1); 65 } 66 67 public void write(byte b[], int off, int len) throws IOException { 68 if(closed) 69 throw new IOException ("stream is already closed"); 70 if(off==0 && len==b.length) 71 write(b); 72 else { 73 byte[] buf = new byte[len]; 74 System.arraycopy(b,off,buf,0,len); 75 write(buf); 76 } 77 } 78 79 public synchronized void write(byte b[]) throws IOException { 80 if(closed) 81 throw new IOException ("stream is already closed"); 82 if(channel==null) { 83 if(tmp==null) 84 tmp = new ByteArrayOutputStream (); 85 tmp.write(b); 86 } else { 87 channel.send(new Chunk(oid,b)); 88 } 89 } 90 91 92 public void flush() throws IOException { 93 if(channel!=null) 94 channel.send(new Flush(oid)); 95 } 96 97 public synchronized void close() throws IOException { 98 closed = true; 99 if(channel!=null) { 100 channel.send(new EOF(oid)); 101 channel = null; 102 oid = -1; 103 } 104 } 105 106 protected void finalize() throws Throwable { 107 super.finalize(); 108 close(); 109 } 110 111 114 private static final class Chunk extends Command { 115 private final int oid; 116 private final byte[] buf; 117 118 public Chunk(int oid, byte[] buf) { 119 this.oid = oid; 120 this.buf = buf; 121 } 122 123 protected void execute(Channel channel) { 124 OutputStream os = (OutputStream ) channel.getExportedObject(oid); 125 try { 126 os.write(buf); 127 } catch (IOException e) { 128 } 130 } 131 132 public String toString() { 133 return "Pipe.Chunk("+oid+","+buf.length+")"; 134 } 135 136 private static final long serialVersionUID = 1L; 137 } 138 139 142 private static final class Flush extends Command { 143 private final int oid; 144 145 public Flush(int oid) { 146 this.oid = oid; 147 } 148 149 protected void execute(Channel channel) { 150 OutputStream os = (OutputStream ) channel.getExportedObject(oid); 151 try { 152 os.flush(); 153 } catch (IOException e) { 154 } 156 } 157 158 public String toString() { 159 return "Pipe.Flush("+oid+")"; 160 } 161 162 private static final long serialVersionUID = 1L; 163 } 164 165 168 private static final class EOF extends Command { 169 private final int oid; 170 171 public EOF(int oid) { 172 this.oid = oid; 173 } 174 175 176 protected void execute(Channel channel) { 177 OutputStream os = (OutputStream ) channel.getExportedObject(oid); 178 channel.unexport(oid); 179 try { 180 os.close(); 181 } catch (IOException e) { 182 } 184 } 185 186 public String toString() { 187 return "Pipe.EOF("+oid+")"; 188 } 189 190 private static final long serialVersionUID = 1L; 191 } 192 } 193 | Popular Tags |