1 | /* |
---|
2 | Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. |
---|
3 | |
---|
4 | |
---|
5 | The MySQL Connector/J is licensed under the terms of the GPLv2 |
---|
6 | <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors. |
---|
7 | There are special exceptions to the terms and conditions of the GPLv2 as it is applied to |
---|
8 | this software, see the FLOSS License Exception |
---|
9 | <http://www.mysql.com/about/legal/licensing/foss-exception.html>. |
---|
10 | |
---|
11 | This program is free software; you can redistribute it and/or modify it under the terms |
---|
12 | of the GNU General Public License as published by the Free Software Foundation; version 2 |
---|
13 | of the License. |
---|
14 | |
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
---|
16 | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
---|
17 | See the GNU General Public License for more details. |
---|
18 | |
---|
19 | You should have received a copy of the GNU General Public License along with this |
---|
20 | program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth |
---|
21 | Floor, Boston, MA 02110-1301 USA |
---|
22 | |
---|
23 | |
---|
24 | |
---|
25 | */ |
---|
26 | package com.mysql.jdbc; |
---|
27 | |
---|
28 | import java.io.ObjectInputStream; |
---|
29 | import java.io.PrintWriter; |
---|
30 | import java.io.StringWriter; |
---|
31 | import java.lang.reflect.Constructor; |
---|
32 | import java.lang.reflect.InvocationTargetException; |
---|
33 | import java.lang.reflect.Method; |
---|
34 | import java.math.BigDecimal; |
---|
35 | import java.math.BigInteger; |
---|
36 | import java.sql.SQLException; |
---|
37 | import java.util.HashMap; |
---|
38 | import java.util.Iterator; |
---|
39 | import java.util.LinkedList; |
---|
40 | import java.util.List; |
---|
41 | import java.util.Map; |
---|
42 | import java.util.Properties; |
---|
43 | import java.util.TimeZone; |
---|
44 | |
---|
45 | /** |
---|
46 | * Various utility methods for the driver. |
---|
47 | * |
---|
48 | * @author Mark Matthews |
---|
49 | */ |
---|
50 | public class Util { |
---|
51 | protected final static Method systemNanoTimeMethod; |
---|
52 | |
---|
53 | static { |
---|
54 | Method aMethod; |
---|
55 | |
---|
56 | try { |
---|
57 | aMethod = System.class.getMethod("nanoTime", (Class[])null); |
---|
58 | } catch (SecurityException e) { |
---|
59 | aMethod = null; |
---|
60 | } catch (NoSuchMethodException e) { |
---|
61 | aMethod = null; |
---|
62 | } |
---|
63 | |
---|
64 | systemNanoTimeMethod = aMethod; |
---|
65 | } |
---|
66 | |
---|
67 | public static boolean nanoTimeAvailable() { |
---|
68 | return systemNanoTimeMethod != null; |
---|
69 | } |
---|
70 | |
---|
71 | private static Method CAST_METHOD; |
---|
72 | |
---|
73 | // cache this ourselves, as the method call is statically-synchronized in |
---|
74 | // all but JDK6! |
---|
75 | |
---|
76 | private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault(); |
---|
77 | |
---|
78 | static final TimeZone getDefaultTimeZone() { |
---|
79 | return (TimeZone) DEFAULT_TIMEZONE.clone(); |
---|
80 | } |
---|
81 | |
---|
82 | class RandStructcture { |
---|
83 | long maxValue; |
---|
84 | |
---|
85 | double maxValueDbl; |
---|
86 | |
---|
87 | long seed1; |
---|
88 | |
---|
89 | long seed2; |
---|
90 | } |
---|
91 | |
---|
92 | private static Util enclosingInstance = new Util(); |
---|
93 | |
---|
94 | private static boolean isJdbc4 = false; |
---|
95 | |
---|
96 | private static boolean isColdFusion = false; |
---|
97 | |
---|
98 | static { |
---|
99 | try { |
---|
100 | CAST_METHOD = Class.class.getMethod("cast", |
---|
101 | new Class[] { Object.class }); |
---|
102 | } catch (Throwable t) { |
---|
103 | // ignore - not available in this VM |
---|
104 | } |
---|
105 | |
---|
106 | try { |
---|
107 | Class.forName("java.sql.NClob"); |
---|
108 | isJdbc4 = true; |
---|
109 | } catch (Throwable t) { |
---|
110 | isJdbc4 = false; |
---|
111 | } |
---|
112 | |
---|
113 | // |
---|
114 | // Detect the ColdFusion MX environment |
---|
115 | // |
---|
116 | // Unfortunately, no easy-to-discern classes are available |
---|
117 | // to our classloader to check... |
---|
118 | // |
---|
119 | |
---|
120 | String loadedFrom = stackTraceToString(new Throwable()); |
---|
121 | |
---|
122 | if (loadedFrom != null) { |
---|
123 | isColdFusion = loadedFrom.indexOf("coldfusion") != -1; |
---|
124 | } else { |
---|
125 | isColdFusion = false; |
---|
126 | } |
---|
127 | } |
---|
128 | |
---|
129 | // ~ Methods |
---|
130 | // ---------------------------------------------------------------- |
---|
131 | |
---|
132 | public static boolean isJdbc4() { |
---|
133 | return isJdbc4; |
---|
134 | } |
---|
135 | |
---|
136 | public static boolean isColdFusion() { |
---|
137 | return isColdFusion; |
---|
138 | } |
---|
139 | |
---|
140 | // Right from Monty's code |
---|
141 | public static String newCrypt(String password, String seed) { |
---|
142 | byte b; |
---|
143 | double d; |
---|
144 | |
---|
145 | if ((password == null) || (password.length() == 0)) { |
---|
146 | return password; |
---|
147 | } |
---|
148 | |
---|
149 | long[] pw = newHash(seed); |
---|
150 | long[] msg = newHash(password); |
---|
151 | long max = 0x3fffffffL; |
---|
152 | long seed1 = (pw[0] ^ msg[0]) % max; |
---|
153 | long seed2 = (pw[1] ^ msg[1]) % max; |
---|
154 | char[] chars = new char[seed.length()]; |
---|
155 | |
---|
156 | for (int i = 0; i < seed.length(); i++) { |
---|
157 | seed1 = ((seed1 * 3) + seed2) % max; |
---|
158 | seed2 = (seed1 + seed2 + 33) % max; |
---|
159 | d = (double) seed1 / (double) max; |
---|
160 | b = (byte) java.lang.Math.floor((d * 31) + 64); |
---|
161 | chars[i] = (char) b; |
---|
162 | } |
---|
163 | |
---|
164 | seed1 = ((seed1 * 3) + seed2) % max; |
---|
165 | seed2 = (seed1 + seed2 + 33) % max; |
---|
166 | d = (double) seed1 / (double) max; |
---|
167 | b = (byte) java.lang.Math.floor(d * 31); |
---|
168 | |
---|
169 | for (int i = 0; i < seed.length(); i++) { |
---|
170 | chars[i] ^= (char) b; |
---|
171 | } |
---|
172 | |
---|
173 | return new String(chars); |
---|
174 | } |
---|
175 | |
---|
176 | static long[] newHash(String password) { |
---|
177 | long nr = 1345345333L; |
---|
178 | long add = 7; |
---|
179 | long nr2 = 0x12345671L; |
---|
180 | long tmp; |
---|
181 | |
---|
182 | for (int i = 0; i < password.length(); ++i) { |
---|
183 | if ((password.charAt(i) == ' ') || (password.charAt(i) == '\t')) { |
---|
184 | continue; // skip spaces |
---|
185 | } |
---|
186 | |
---|
187 | tmp = (0xff & password.charAt(i)); |
---|
188 | nr ^= ((((nr & 63) + add) * tmp) + (nr << 8)); |
---|
189 | nr2 += ((nr2 << 8) ^ nr); |
---|
190 | add += tmp; |
---|
191 | } |
---|
192 | |
---|
193 | long[] result = new long[2]; |
---|
194 | result[0] = nr & 0x7fffffffL; |
---|
195 | result[1] = nr2 & 0x7fffffffL; |
---|
196 | |
---|
197 | return result; |
---|
198 | } |
---|
199 | |
---|
200 | public static String oldCrypt(String password, String seed) { |
---|
201 | long hp; |
---|
202 | long hm; |
---|
203 | long s1; |
---|
204 | long s2; |
---|
205 | long max = 0x01FFFFFF; |
---|
206 | double d; |
---|
207 | byte b; |
---|
208 | |
---|
209 | if ((password == null) || (password.length() == 0)) { |
---|
210 | return password; |
---|
211 | } |
---|
212 | |
---|
213 | hp = oldHash(seed); |
---|
214 | hm = oldHash(password); |
---|
215 | |
---|
216 | long nr = hp ^ hm; |
---|
217 | nr %= max; |
---|
218 | s1 = nr; |
---|
219 | s2 = nr / 2; |
---|
220 | |
---|
221 | char[] chars = new char[seed.length()]; |
---|
222 | |
---|
223 | for (int i = 0; i < seed.length(); i++) { |
---|
224 | s1 = ((s1 * 3) + s2) % max; |
---|
225 | s2 = (s1 + s2 + 33) % max; |
---|
226 | d = (double) s1 / max; |
---|
227 | b = (byte) java.lang.Math.floor((d * 31) + 64); |
---|
228 | chars[i] = (char) b; |
---|
229 | } |
---|
230 | |
---|
231 | return new String(chars); |
---|
232 | } |
---|
233 | |
---|
234 | static long oldHash(String password) { |
---|
235 | long nr = 1345345333; |
---|
236 | long nr2 = 7; |
---|
237 | long tmp; |
---|
238 | |
---|
239 | for (int i = 0; i < password.length(); i++) { |
---|
240 | if ((password.charAt(i) == ' ') || (password.charAt(i) == '\t')) { |
---|
241 | continue; |
---|
242 | } |
---|
243 | |
---|
244 | tmp = password.charAt(i); |
---|
245 | nr ^= ((((nr & 63) + nr2) * tmp) + (nr << 8)); |
---|
246 | nr2 += tmp; |
---|
247 | } |
---|
248 | |
---|
249 | return nr & ((1L << 31) - 1L); |
---|
250 | } |
---|
251 | |
---|
252 | private static RandStructcture randomInit(long seed1, long seed2) { |
---|
253 | RandStructcture randStruct = enclosingInstance.new RandStructcture(); |
---|
254 | |
---|
255 | randStruct.maxValue = 0x3FFFFFFFL; |
---|
256 | randStruct.maxValueDbl = randStruct.maxValue; |
---|
257 | randStruct.seed1 = seed1 % randStruct.maxValue; |
---|
258 | randStruct.seed2 = seed2 % randStruct.maxValue; |
---|
259 | |
---|
260 | return randStruct; |
---|
261 | } |
---|
262 | |
---|
263 | /** |
---|
264 | * Given a ResultSet and an index into the columns of that ResultSet, read |
---|
265 | * binary data from the column which represents a serialized object, and |
---|
266 | * re-create the object. |
---|
267 | * |
---|
268 | * @param resultSet |
---|
269 | * the ResultSet to use. |
---|
270 | * @param index |
---|
271 | * an index into the ResultSet. |
---|
272 | * @return the object if it can be de-serialized |
---|
273 | * @throws Exception |
---|
274 | * if an error occurs |
---|
275 | */ |
---|
276 | public static Object readObject(java.sql.ResultSet resultSet, int index) |
---|
277 | throws Exception { |
---|
278 | ObjectInputStream objIn = new ObjectInputStream(resultSet |
---|
279 | .getBinaryStream(index)); |
---|
280 | Object obj = objIn.readObject(); |
---|
281 | objIn.close(); |
---|
282 | |
---|
283 | return obj; |
---|
284 | } |
---|
285 | |
---|
286 | private static double rnd(RandStructcture randStruct) { |
---|
287 | randStruct.seed1 = ((randStruct.seed1 * 3) + randStruct.seed2) |
---|
288 | % randStruct.maxValue; |
---|
289 | randStruct.seed2 = (randStruct.seed1 + randStruct.seed2 + 33) |
---|
290 | % randStruct.maxValue; |
---|
291 | |
---|
292 | return ((randStruct.seed1) / randStruct.maxValueDbl); |
---|
293 | } |
---|
294 | |
---|
295 | /** |
---|
296 | * DOCUMENT ME! |
---|
297 | * |
---|
298 | * @param message |
---|
299 | * DOCUMENT ME! |
---|
300 | * @param password |
---|
301 | * DOCUMENT ME! |
---|
302 | * |
---|
303 | * @return DOCUMENT ME! |
---|
304 | */ |
---|
305 | public static String scramble(String message, String password) { |
---|
306 | long[] hashPass; |
---|
307 | long[] hashMessage; |
---|
308 | byte[] to = new byte[8]; |
---|
309 | String val = ""; //$NON-NLS-1$ |
---|
310 | |
---|
311 | message = message.substring(0, 8); |
---|
312 | |
---|
313 | if ((password != null) && (password.length() > 0)) { |
---|
314 | hashPass = newHash(password); |
---|
315 | hashMessage = newHash(message); |
---|
316 | |
---|
317 | RandStructcture randStruct = randomInit(hashPass[0] |
---|
318 | ^ hashMessage[0], hashPass[1] ^ hashMessage[1]); |
---|
319 | |
---|
320 | int msgPos = 0; |
---|
321 | int msgLength = message.length(); |
---|
322 | int toPos = 0; |
---|
323 | |
---|
324 | while (msgPos++ < msgLength) { |
---|
325 | to[toPos++] = (byte) (Math.floor(rnd(randStruct) * 31) + 64); |
---|
326 | } |
---|
327 | |
---|
328 | /* Make it harder to break */ |
---|
329 | byte extra = (byte) (Math.floor(rnd(randStruct) * 31)); |
---|
330 | |
---|
331 | for (int i = 0; i < to.length; i++) { |
---|
332 | to[i] ^= extra; |
---|
333 | } |
---|
334 | |
---|
335 | val = StringUtils.toString(to); |
---|
336 | } |
---|
337 | |
---|
338 | return val; |
---|
339 | } |
---|
340 | |
---|
341 | // ~ Inner Classes |
---|
342 | // ---------------------------------------------------------- |
---|
343 | |
---|
344 | /** |
---|
345 | * Converts a nested exception into a nicer message |
---|
346 | * |
---|
347 | * @param ex |
---|
348 | * the exception to expand into a message. |
---|
349 | * |
---|
350 | * @return a message containing the exception, the message (if any), and a |
---|
351 | * stacktrace. |
---|
352 | */ |
---|
353 | public static String stackTraceToString(Throwable ex) { |
---|
354 | StringBuffer traceBuf = new StringBuffer(); |
---|
355 | traceBuf.append(Messages.getString("Util.1")); //$NON-NLS-1$ |
---|
356 | |
---|
357 | if (ex != null) { |
---|
358 | traceBuf.append(ex.getClass().getName()); |
---|
359 | |
---|
360 | String message = ex.getMessage(); |
---|
361 | |
---|
362 | if (message != null) { |
---|
363 | traceBuf.append(Messages.getString("Util.2")); //$NON-NLS-1$ |
---|
364 | traceBuf.append(message); |
---|
365 | } |
---|
366 | |
---|
367 | StringWriter out = new StringWriter(); |
---|
368 | |
---|
369 | PrintWriter printOut = new PrintWriter(out); |
---|
370 | |
---|
371 | ex.printStackTrace(printOut); |
---|
372 | |
---|
373 | traceBuf.append(Messages.getString("Util.3")); //$NON-NLS-1$ |
---|
374 | traceBuf.append(out.toString()); |
---|
375 | } |
---|
376 | |
---|
377 | traceBuf.append(Messages.getString("Util.4")); //$NON-NLS-1$ |
---|
378 | |
---|
379 | return traceBuf.toString(); |
---|
380 | } |
---|
381 | |
---|
382 | public static Object getInstance(String className, Class<?>[] argTypes, |
---|
383 | Object[] args, ExceptionInterceptor exceptionInterceptor) throws SQLException { |
---|
384 | |
---|
385 | try { |
---|
386 | return handleNewInstance(Class.forName(className).getConstructor( |
---|
387 | argTypes), args, exceptionInterceptor); |
---|
388 | } catch (SecurityException e) { |
---|
389 | throw SQLError.createSQLException( |
---|
390 | "Can't instantiate required class", |
---|
391 | SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); |
---|
392 | } catch (NoSuchMethodException e) { |
---|
393 | throw SQLError.createSQLException( |
---|
394 | "Can't instantiate required class", |
---|
395 | SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); |
---|
396 | } catch (ClassNotFoundException e) { |
---|
397 | throw SQLError.createSQLException( |
---|
398 | "Can't instantiate required class", |
---|
399 | SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); |
---|
400 | } |
---|
401 | } |
---|
402 | |
---|
403 | /** |
---|
404 | * Handles constructing new instance with the given constructor and wrapping |
---|
405 | * (or not, as required) the exceptions that could possibly be generated |
---|
406 | */ |
---|
407 | public static final Object handleNewInstance(Constructor<?> ctor, Object[] args, ExceptionInterceptor exceptionInterceptor) |
---|
408 | throws SQLException { |
---|
409 | try { |
---|
410 | |
---|
411 | return ctor.newInstance(args); |
---|
412 | } catch (IllegalArgumentException e) { |
---|
413 | throw SQLError.createSQLException( |
---|
414 | "Can't instantiate required class", |
---|
415 | SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); |
---|
416 | } catch (InstantiationException e) { |
---|
417 | throw SQLError.createSQLException( |
---|
418 | "Can't instantiate required class", |
---|
419 | SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); |
---|
420 | } catch (IllegalAccessException e) { |
---|
421 | throw SQLError.createSQLException( |
---|
422 | "Can't instantiate required class", |
---|
423 | SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); |
---|
424 | } catch (InvocationTargetException e) { |
---|
425 | Throwable target = e.getTargetException(); |
---|
426 | |
---|
427 | if (target instanceof SQLException) { |
---|
428 | throw (SQLException) target; |
---|
429 | } |
---|
430 | |
---|
431 | if (target instanceof ExceptionInInitializerError) { |
---|
432 | target = ((ExceptionInInitializerError) target).getException(); |
---|
433 | } |
---|
434 | |
---|
435 | throw SQLError.createSQLException(target.toString(), |
---|
436 | SQLError.SQL_STATE_GENERAL_ERROR, exceptionInterceptor); |
---|
437 | } |
---|
438 | } |
---|
439 | |
---|
440 | /** |
---|
441 | * Does a network interface exist locally with the given hostname? |
---|
442 | * |
---|
443 | * @param hostname |
---|
444 | * the hostname (or IP address in string form) to check |
---|
445 | * @return true if it exists, false if no, or unable to determine due to VM |
---|
446 | * version support of java.net.NetworkInterface |
---|
447 | */ |
---|
448 | public static boolean interfaceExists(String hostname) { |
---|
449 | try { |
---|
450 | Class<?> networkInterfaceClass = Class |
---|
451 | .forName("java.net.NetworkInterface"); |
---|
452 | return networkInterfaceClass.getMethod("getByName", (Class[])null).invoke( |
---|
453 | networkInterfaceClass, new Object[] { hostname }) != null; |
---|
454 | } catch (Throwable t) { |
---|
455 | return false; |
---|
456 | } |
---|
457 | } |
---|
458 | |
---|
459 | /** |
---|
460 | * Reflexive access on JDK-1.5's Class.cast() method so we don't have to |
---|
461 | * move that out into separate classes built for JDBC-4.0. |
---|
462 | * |
---|
463 | * @param invokeOn |
---|
464 | * @param toCast |
---|
465 | * @return |
---|
466 | */ |
---|
467 | public static Object cast(Object invokeOn, Object toCast) { |
---|
468 | if (CAST_METHOD != null) { |
---|
469 | try { |
---|
470 | return CAST_METHOD.invoke(invokeOn, new Object[] { toCast }); |
---|
471 | } catch (Throwable t) { |
---|
472 | return null; |
---|
473 | } |
---|
474 | } |
---|
475 | |
---|
476 | return null; |
---|
477 | } |
---|
478 | |
---|
479 | public static long getCurrentTimeNanosOrMillis() { |
---|
480 | if (systemNanoTimeMethod != null) { |
---|
481 | try { |
---|
482 | return ((Long) systemNanoTimeMethod.invoke(null, (Object[])null)) |
---|
483 | .longValue(); |
---|
484 | } catch (IllegalArgumentException e) { |
---|
485 | // ignore - fall through to currentTimeMillis() |
---|
486 | } catch (IllegalAccessException e) { |
---|
487 | // ignore - fall through to currentTimeMillis() |
---|
488 | } catch (InvocationTargetException e) { |
---|
489 | // ignore - fall through to currentTimeMillis() |
---|
490 | } |
---|
491 | } |
---|
492 | |
---|
493 | return System.currentTimeMillis(); |
---|
494 | } |
---|
495 | |
---|
496 | @SuppressWarnings({ "rawtypes", "unchecked" }) |
---|
497 | public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs) |
---|
498 | throws SQLException { |
---|
499 | while (rs.next()) { |
---|
500 | mappedValues.put(rs.getObject(1), rs.getObject(2)); |
---|
501 | } |
---|
502 | } |
---|
503 | |
---|
504 | @SuppressWarnings({ "rawtypes", "unchecked" }) |
---|
505 | public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs, int key, int value) |
---|
506 | throws SQLException { |
---|
507 | while (rs.next()) { |
---|
508 | mappedValues.put(rs.getObject(key), rs.getObject(value)); |
---|
509 | } |
---|
510 | } |
---|
511 | |
---|
512 | @SuppressWarnings({ "rawtypes", "unchecked" }) |
---|
513 | public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs, String key, String value) |
---|
514 | throws SQLException { |
---|
515 | while (rs.next()) { |
---|
516 | mappedValues.put(rs.getObject(key), rs.getObject(value)); |
---|
517 | } |
---|
518 | } |
---|
519 | |
---|
520 | public static Map<Object, Object> calculateDifferences(Map<?,?> map1, Map<?,?> map2) { |
---|
521 | Map<Object, Object> diffMap = new HashMap<Object, Object>(); |
---|
522 | |
---|
523 | for (Map.Entry<?,?> entry : map1.entrySet()) { |
---|
524 | Object key = entry.getKey(); |
---|
525 | |
---|
526 | Number value1 = null; |
---|
527 | Number value2 = null; |
---|
528 | |
---|
529 | if (entry.getValue() instanceof Number) { |
---|
530 | |
---|
531 | value1 = (Number) entry.getValue(); |
---|
532 | value2 = (Number) map2.get(key); |
---|
533 | } else { |
---|
534 | try { |
---|
535 | value1 = new Double(entry.getValue().toString()); |
---|
536 | value2 = new Double(map2.get(key).toString()); |
---|
537 | } catch (NumberFormatException nfe) { |
---|
538 | continue; |
---|
539 | } |
---|
540 | } |
---|
541 | |
---|
542 | if (value1.equals(value2)) { |
---|
543 | continue; |
---|
544 | } |
---|
545 | |
---|
546 | if (value1 instanceof Byte) { |
---|
547 | diffMap.put(key, Byte.valueOf( |
---|
548 | (byte) (((Byte) value2).byteValue() - ((Byte) value1) |
---|
549 | .byteValue()))); |
---|
550 | } else if (value1 instanceof Short) { |
---|
551 | diffMap.put(key, Short.valueOf((short) (((Short) value2) |
---|
552 | .shortValue() - ((Short) value1).shortValue()))); |
---|
553 | } else if (value1 instanceof Integer) { |
---|
554 | diffMap.put(key, Integer.valueOf( |
---|
555 | (((Integer) value2).intValue() - ((Integer) value1) |
---|
556 | .intValue()))); |
---|
557 | } else if (value1 instanceof Long) { |
---|
558 | diffMap.put(key, Long.valueOf( |
---|
559 | (((Long) value2).longValue() - ((Long) value1) |
---|
560 | .longValue()))); |
---|
561 | } else if (value1 instanceof Float) { |
---|
562 | diffMap.put(key, Float.valueOf(((Float) value2).floatValue() |
---|
563 | - ((Float) value1).floatValue())); |
---|
564 | } else if (value1 instanceof Double) { |
---|
565 | diffMap.put(key, Double.valueOf( |
---|
566 | (((Double) value2).shortValue() - ((Double) value1) |
---|
567 | .shortValue()))); |
---|
568 | } else if (value1 instanceof BigDecimal) { |
---|
569 | diffMap.put(key, ((BigDecimal) value2) |
---|
570 | .subtract((BigDecimal) value1)); |
---|
571 | } else if (value1 instanceof BigInteger) { |
---|
572 | diffMap.put(key, ((BigInteger) value2) |
---|
573 | .subtract((BigInteger) value1)); |
---|
574 | } |
---|
575 | } |
---|
576 | |
---|
577 | return diffMap; |
---|
578 | } |
---|
579 | |
---|
580 | public static List<Extension> loadExtensions(Connection conn, |
---|
581 | Properties props, String extensionClassNames, |
---|
582 | String errorMessageKey, ExceptionInterceptor exceptionInterceptor) throws SQLException { |
---|
583 | List<Extension> extensionList = new LinkedList<Extension>(); |
---|
584 | |
---|
585 | List<String> interceptorsToCreate = StringUtils.split(extensionClassNames, ",", |
---|
586 | true); |
---|
587 | |
---|
588 | Iterator<String> iter = interceptorsToCreate.iterator(); |
---|
589 | |
---|
590 | String className = null; |
---|
591 | |
---|
592 | try { |
---|
593 | while (iter.hasNext()) { |
---|
594 | className = iter.next().toString(); |
---|
595 | Extension extensionInstance = (Extension) Class.forName( |
---|
596 | className).newInstance(); |
---|
597 | extensionInstance.init(conn, props); |
---|
598 | |
---|
599 | extensionList.add(extensionInstance); |
---|
600 | } |
---|
601 | } catch (Throwable t) { |
---|
602 | SQLException sqlEx = SQLError.createSQLException(Messages |
---|
603 | .getString(errorMessageKey, new Object[] { className }), exceptionInterceptor); |
---|
604 | sqlEx.initCause(t); |
---|
605 | |
---|
606 | throw sqlEx; |
---|
607 | } |
---|
608 | |
---|
609 | return extensionList; |
---|
610 | } |
---|
611 | |
---|
612 | } |
---|