1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.dbunit.dataset.datatype;
23
24 import java.io.BufferedInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.net.MalformedURLException;
32 import java.net.URL;
33 import java.sql.Blob;
34 import java.sql.PreparedStatement;
35 import java.sql.ResultSet;
36 import java.sql.SQLException;
37
38 import org.dbunit.dataset.ITable;
39 import org.dbunit.util.Base64;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43
44
45
46
47
48
49 public class BytesDataType extends AbstractDataType
50 {
51
52
53
54
55 private static final Logger logger = LoggerFactory.getLogger(BytesDataType.class);
56
57 private static final int MAX_URI_LENGTH = 256;
58
59 BytesDataType(String name, int sqlType)
60 {
61 super(name, sqlType, byte[].class, false);
62 }
63
64 private byte[] toByteArray(InputStream in, int length) throws IOException
65 {
66 if (logger.isDebugEnabled())
67 {
68 logger.debug("toByteArray(in={}, length={}) - start", in, Integer.toString(length));
69 }
70
71 ByteArrayOutputStream out = new ByteArrayOutputStream(length);
72 in = new BufferedInputStream(in);
73 int i = in.read();
74 while (i != -1)
75 {
76 out.write(i);
77 i = in.read();
78 }
79 return out.toByteArray();
80 }
81
82
83
84
85
86
87
88
89
90
91
92 public Object typeCast(Object value) throws TypeCastException
93 {
94 logger.debug("typeCast(value={}) - start", value);
95
96 if (value == null || value == ITable.NO_VALUE)
97 {
98 return null;
99 }
100
101 if (value instanceof byte[])
102 {
103 return value;
104 }
105
106 if (value instanceof String)
107 {
108 String stringValue = (String)value;
109
110
111 if (stringValue.length() == 0 || stringValue.length() > MAX_URI_LENGTH)
112 {
113 logger.debug("Assuming given string to be Base64 and not a URI");
114 return Base64.decode((String)value);
115 }
116
117 try
118 {
119 logger.debug("Assuming given string to be a URI");
120 try
121 {
122
123 URL url = new URL(stringValue);
124 return toByteArray(url.openStream(), 0);
125 }
126 catch (MalformedURLException e1)
127 {
128 logger.debug("Given string is not a valid URI - trying to resolve it as file...");
129 try
130 {
131
132 File file = new File(stringValue);
133 return toByteArray(new FileInputStream(file), (int)file.length());
134 }
135 catch (FileNotFoundException e2)
136 {
137 logger.debug("Assuming given string to be Base64 and not a URI or File");
138
139 return Base64.decode(stringValue);
140 }
141 }
142 }
143 catch (IOException e)
144 {
145 throw new TypeCastException(value, this, e);
146 }
147 }
148
149 if (value instanceof Blob)
150 {
151 try
152 {
153 Blob blobValue = (Blob)value;
154 if (blobValue.length() == 0) {
155 return null;
156 }
157 return blobValue.getBytes(1, (int)blobValue.length());
158 }
159 catch (SQLException e)
160 {
161 throw new TypeCastException(value, this, e);
162 }
163 }
164
165 if (value instanceof URL)
166 {
167 try
168 {
169 return toByteArray(((URL)value).openStream(), 0);
170 }
171 catch (IOException e)
172 {
173 throw new TypeCastException(value, this, e);
174 }
175 }
176
177 if (value instanceof File)
178 {
179 try
180 {
181 File file = (File)value;
182 return toByteArray(new FileInputStream(file), (int)file.length());
183 }
184 catch (IOException e)
185 {
186 throw new TypeCastException(value, this, e);
187 }
188 }
189
190 throw new TypeCastException(value, this);
191 }
192
193
194 protected int compareNonNulls(Object value1, Object value2) throws TypeCastException
195 {
196 logger.debug("compareNonNulls(value1={}, value2={}) - start", value1, value2);
197
198 try
199 {
200 byte[] value1cast = (byte[])typeCast(value1);
201 byte[] value2cast = (byte[])typeCast(value2);
202
203 return compare(value1cast, value2cast);
204 }
205 catch (ClassCastException e)
206 {
207 throw new TypeCastException(e);
208 }
209 }
210
211 public int compare(byte[] v1, byte[] v2) throws TypeCastException
212 {
213 if (logger.isDebugEnabled())
214 {
215 logger.debug("compare(v1={}, v2={}) - start", v1, v2);
216 }
217
218 int len1 = v1.length;
219 int len2 = v2.length;
220 int n = Math.min(len1, len2);
221 int i = 0;
222 int j = 0;
223
224 if (i == j)
225 {
226 int k = i;
227 int lim = n + i;
228 while (k < lim)
229 {
230 byte c1 = v1[k];
231 byte c2 = v2[k];
232 if (c1 != c2)
233 {
234 return c1 - c2;
235 }
236 k++;
237 }
238 }
239 else
240 {
241 while (n-- != 0)
242 {
243 byte c1 = v1[i++];
244 byte c2 = v2[j++];
245 if (c1 != c2)
246 {
247 return c1 - c2;
248 }
249 }
250 }
251 return len1 - len2;
252 }
253
254 public Object getSqlValue(int column, ResultSet resultSet)
255 throws SQLException, TypeCastException
256 {
257 if(logger.isDebugEnabled())
258 logger.debug("getSqlValue(column={}, resultSet={}) - start", new Integer(column), resultSet);
259
260 byte[] value = resultSet.getBytes(column);
261 if (value == null || resultSet.wasNull())
262 {
263 return null;
264 }
265 return value;
266 }
267
268 public void setSqlValue(Object value, int column, PreparedStatement statement)
269 throws SQLException, TypeCastException
270 {
271 if (logger.isDebugEnabled())
272 {
273 logger.debug("setSqlValue(value={}, column={}, statement={}) - start",
274 new Object[]{value, new Integer(column), statement} );
275 }
276
277 super.setSqlValue(value, column, statement);
278 }
279
280 }