KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > remoting > ProxyWriter


1 package hudson.remoting;
2
3 import java.io.CharArrayWriter JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.io.OutputStream JavaDoc;
6 import java.io.Writer JavaDoc;
7
8 /**
9  * {@link Writer} that sends bits to an exported
10  * {@link Writer} on a remote machine.
11  */

12 final class ProxyWriter extends Writer JavaDoc {
13     private Channel channel;
14     private int oid;
15
16     /**
17      * If bytes are written to this stream before it's connected
18      * to a remote object, bytes will be stored in this buffer.
19      */

20     private CharArrayWriter JavaDoc tmp;
21
22     /**
23      * Set to true if the stream is closed.
24      */

25     private boolean closed;
26
27     /**
28      * Creates unconnected {@link ProxyWriter}.
29      * The returned stream accepts data right away, and
30      * when it's {@link #connect(Channel,int) connected} later,
31      * the data will be sent at once to the remote stream.
32      */

33     public ProxyWriter() {
34     }
35
36     /**
37      * Creates an already connected {@link ProxyWriter}.
38      *
39      * @param oid
40      * The object id of the exported {@link OutputStream}.
41      */

42     public ProxyWriter(Channel channel, int oid) throws IOException JavaDoc {
43         connect(channel,oid);
44     }
45
46     /**
47      * Connects this stream to the specified remote object.
48      */

49     synchronized void connect(Channel channel, int oid) throws IOException JavaDoc {
50         if(this.channel!=null)
51             throw new IllegalStateException JavaDoc("Cannot connect twice");
52         this.channel = channel;
53         this.oid = oid;
54
55         // if we already have bytes to write, do so now.
56
if(tmp!=null) {
57             write(tmp.toCharArray());
58             tmp = null;
59         }
60         if(closed) // already marked closed?
61
close();
62     }
63
64     public void write(int c) throws IOException JavaDoc {
65         write(new char[]{(char)c},0,1);
66     }
67
68     public void write(char[] cbuf, int off, int len) throws IOException JavaDoc {
69         if(closed)
70             throw new IOException JavaDoc("stream is already closed");
71         if(off==0 && len==cbuf.length)
72             write(cbuf);
73         else {
74             char[] buf = new char[len];
75             System.arraycopy(cbuf,off,buf,0,len);
76             write(buf);
77         }
78     }
79
80
81
82     public synchronized void write(char[] cbuf) throws IOException JavaDoc {
83         if(closed)
84             throw new IOException JavaDoc("stream is already closed");
85         if(channel==null) {
86             if(tmp==null)
87                 tmp = new CharArrayWriter JavaDoc();
88             tmp.write(cbuf);
89         } else {
90             channel.send(new Chunk(oid,cbuf));
91         }
92     }
93
94     public void flush() throws IOException JavaDoc {
95         // noop
96
}
97
98     public synchronized void close() throws IOException JavaDoc {
99         closed = true;
100         if(channel!=null) {
101             channel.send(new EOF(oid));
102             channel = null;
103             oid = -1;
104         }
105     }
106
107     protected void finalize() throws Throwable JavaDoc {
108         super.finalize();
109         close();
110     }
111
112     /**
113      * {@link Command} for sending bytes.
114      */

115     private static final class Chunk extends Command {
116         private final int oid;
117         private final char[] buf;
118
119         public Chunk(int oid, char[] buf) {
120             this.oid = oid;
121             this.buf = buf;
122         }
123
124         protected void execute(Channel channel) {
125             Writer JavaDoc os = (Writer JavaDoc) channel.getExportedObject(oid);
126             try {
127                 os.write(buf);
128             } catch (IOException JavaDoc e) {
129                 // ignore errors
130
}
131         }
132
133         public String JavaDoc toString() {
134             return "Pipe.Chunk("+oid+","+buf.length+")";
135         }
136
137         private static final long serialVersionUID = 1L;
138     }
139
140     /**
141      * {@link Command} for sending EOF.
142      */

143     private static final class EOF extends Command {
144         private final int oid;
145
146         public EOF(int oid) {
147             this.oid = oid;
148         }
149
150         protected void execute(Channel channel) {
151             OutputStream JavaDoc os = (OutputStream JavaDoc) channel.getExportedObject(oid);
152             channel.unexport(oid);
153             try {
154                 os.close();
155             } catch (IOException JavaDoc e) {
156                 // ignore errors
157
}
158         }
159
160         public String JavaDoc toString() {
161             return "Pipe.EOF("+oid+")";
162         }
163
164         private static final long serialVersionUID = 1L;
165     }
166 }
167
Popular Tags