1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.tcp.protocols;
12
13 import org.mule.ResponseOutputStream;
14 import org.mule.api.MuleMessage;
15 import org.mule.transport.tcp.TcpProtocol;
16 import org.mule.util.ClassUtils;
17 import org.mule.util.IOUtils;
18 import org.mule.util.SerializationUtils;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.io.Serializable;
24 import java.net.Socket;
25 import java.net.SocketException;
26 import java.net.SocketTimeoutException;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public abstract class AbstractByteProtocol implements TcpProtocol
44 {
45 private static final Log logger = LogFactory.getLog(DirectProtocol.class);
46 private static final long PAUSE_PERIOD = 100;
47 public static final int EOF = -1;
48
49
50 public static final boolean STREAM_OK = true;
51 public static final boolean NO_STREAM = false;
52 private boolean streamOk;
53 private boolean rethrowExceptionOnRead = false;
54
55 public AbstractByteProtocol(boolean streamOk)
56 {
57 this.streamOk = streamOk;
58 }
59
60 public void write(OutputStream os, Object data) throws IOException
61 {
62 if (data instanceof InputStream)
63 {
64 if (streamOk)
65 {
66 InputStream is = (InputStream) data;
67 IOUtils.copyLarge(is, os);
68 os.flush();
69 os.close();
70 is.close();
71 }
72 else
73 {
74 throw new IOException("TCP protocol " + ClassUtils.getSimpleName(getClass())
75 + " cannot handle streaming");
76 }
77 }
78 else if (data instanceof MuleMessage)
79 {
80 write(os, ((MuleMessage) data).getPayload());
81 }
82 else if (data instanceof byte[])
83 {
84 writeByteArray(os, (byte[]) data);
85 }
86 else if (data instanceof String)
87 {
88
89
90 writeByteArray(os, ((String) data).getBytes());
91 }
92 else if (data instanceof Serializable)
93 {
94 writeByteArray(os, SerializationUtils.serialize((Serializable) data));
95 }
96 else
97 {
98 throw new IllegalArgumentException("Cannot serialize data: " + data);
99 }
100 }
101
102 protected void writeByteArray(OutputStream os, byte[] data) throws IOException
103 {
104 os.write(data);
105 }
106
107
108
109
110
111
112
113
114
115 protected int safeRead(InputStream is, byte[] buffer) throws IOException
116 {
117 return safeRead(is, buffer, buffer.length);
118 }
119
120
121
122
123
124
125
126
127
128
129 protected int safeRead(InputStream is, byte[] buffer, int size) throws IOException
130 {
131 int len;
132 try
133 {
134 do
135 {
136 len = is.read(buffer, 0, size);
137 if (0 == len)
138 {
139
140
141 try
142 {
143 Thread.sleep(PAUSE_PERIOD);
144 }
145 catch (InterruptedException e)
146 {
147
148 }
149 }
150 }
151 while (0 == len);
152 return len;
153 }
154 catch (SocketException e)
155 {
156
157 logger.info("Socket exception occured: " + e.getMessage());
158 if (this.rethrowExceptionOnRead)
159 {
160 throw e;
161 }
162 else
163 {
164 return EOF;
165 }
166 }
167 catch (SocketTimeoutException e)
168 {
169 logger.debug("Socket timeout.");
170 if (this.rethrowExceptionOnRead)
171 {
172 throw e;
173 }
174 else
175 {
176 return EOF;
177 }
178 }
179 }
180
181
182
183
184
185
186
187
188
189
190 protected int copy(InputStream source, byte[] buffer, OutputStream dest) throws IOException
191 {
192 return copy(source, buffer, dest, buffer.length);
193 }
194
195
196
197
198
199
200
201
202
203
204
205 protected int copy(InputStream source, byte[] buffer, OutputStream dest, int size) throws IOException
206 {
207 int len = safeRead(source, buffer, size);
208 if (len > 0)
209 {
210 dest.write(buffer, 0, len);
211 }
212 return len;
213 }
214
215 protected byte[] nullEmptyArray(byte[] data)
216 {
217 if (0 == data.length)
218 {
219 return null;
220 }
221 else
222 {
223 return data;
224 }
225 }
226
227 public ResponseOutputStream createResponse(Socket socket) throws IOException
228 {
229 return new ResponseOutputStream(socket, new ProtocolStream(this, streamOk, socket.getOutputStream()));
230 }
231
232 public boolean isRethrowExceptionOnRead()
233 {
234 return rethrowExceptionOnRead;
235 }
236
237 public void setRethrowExceptionOnRead(boolean rethrowExceptionOnRead)
238 {
239 this.rethrowExceptionOnRead = rethrowExceptionOnRead;
240 }
241
242 }