1 61 62 package org.apache.commons.dbutils; 63 64 import java.beans.BeanInfo ; 65 import java.beans.IntrospectionException ; 66 import java.beans.Introspector ; 67 import java.beans.PropertyDescriptor ; 68 import java.lang.reflect.InvocationTargetException ; 69 import java.lang.reflect.Method ; 70 import java.sql.ResultSet ; 71 import java.sql.ResultSetMetaData ; 72 import java.sql.SQLException ; 73 import java.util.ArrayList ; 74 import java.util.HashMap ; 75 import java.util.Iterator ; 76 import java.util.List ; 77 import java.util.Map ; 78 79 90 public class BasicRowProcessor implements RowProcessor { 91 92 97 private static final Map primitiveDefaults = new HashMap (); 98 99 static { 100 primitiveDefaults.put(Integer.TYPE, new Integer (0)); 101 primitiveDefaults.put(Short.TYPE, new Short ((short) 0)); 102 primitiveDefaults.put(Byte.TYPE, new Byte ((byte) 0)); 103 primitiveDefaults.put(Float.TYPE, new Float (0)); 104 primitiveDefaults.put(Double.TYPE, new Double (0)); 105 primitiveDefaults.put(Long.TYPE, new Long (0)); 106 primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE); 107 primitiveDefaults.put(Character.TYPE, new Character ('\u0000')); 108 } 109 110 114 private static final int PROPERTY_NOT_FOUND = -1; 115 116 119 private static final BasicRowProcessor instance = new BasicRowProcessor(); 120 121 126 public static BasicRowProcessor instance() { 127 return instance; 128 } 129 130 133 protected BasicRowProcessor() { 134 super(); 135 } 136 137 145 public Object [] toArray(ResultSet rs) throws SQLException { 146 ResultSetMetaData meta = rs.getMetaData(); 147 int cols = meta.getColumnCount(); 148 Object [] result = new Object [cols]; 149 150 for (int i = 0; i < cols; i++) { 151 result[i] = rs.getObject(i + 1); 152 } 153 154 return result; 155 } 156 157 185 public Object toBean(ResultSet rs, Class type) throws SQLException { 186 187 PropertyDescriptor [] props = this.propertyDescriptors(type); 188 189 ResultSetMetaData rsmd = rs.getMetaData(); 190 191 int[] columnToProperty = this.mapColumnsToProperties(rsmd, props); 192 193 int cols = rsmd.getColumnCount(); 194 195 return this.createBean(rs, type, props, columnToProperty, cols); 196 } 197 198 226 public List toBeanList(ResultSet rs, Class type) throws SQLException { 227 List results = new ArrayList (); 228 229 if (!rs.next()) { 230 return results; 231 } 232 233 PropertyDescriptor [] props = this.propertyDescriptors(type); 234 ResultSetMetaData rsmd = rs.getMetaData(); 235 int[] columnToProperty = this.mapColumnsToProperties(rsmd, props); 236 int cols = rsmd.getColumnCount(); 237 238 do { 239 results.add(this.createBean(rs, type, props, columnToProperty, cols)); 240 241 } while (rs.next()); 242 243 return results; 244 } 245 246 257 private Object createBean( 258 ResultSet rs, 259 Class type, 260 PropertyDescriptor [] props, 261 int[] columnToProperty, 262 int cols) 263 throws SQLException { 264 265 Object bean = this.newInstance(type); 266 267 for (int i = 1; i <= cols; i++) { 268 269 if (columnToProperty[i] == PROPERTY_NOT_FOUND) { 270 continue; 271 } 272 273 Object value = rs.getObject(i); 274 275 PropertyDescriptor prop = props[columnToProperty[i]]; 276 Class propType = prop.getPropertyType(); 277 278 if (propType != null && value == null && propType.isPrimitive()) { 279 value = primitiveDefaults.get(propType); 280 } 281 282 this.callSetter(bean, prop, value); 283 } 284 285 return bean; 286 } 287 288 301 private int[] mapColumnsToProperties( 302 ResultSetMetaData rsmd, 303 PropertyDescriptor [] props) 304 throws SQLException { 305 306 int cols = rsmd.getColumnCount(); 307 int columnToProperty[] = new int[cols + 1]; 308 309 for (int col = 1; col <= cols; col++) { 310 String columnName = rsmd.getColumnName(col); 311 for (int i = 0; i < props.length; i++) { 312 313 if (columnName.equalsIgnoreCase(props[i].getName())) { 314 columnToProperty[col] = i; 315 break; 316 317 } else { 318 columnToProperty[col] = PROPERTY_NOT_FOUND; 319 } 320 } 321 } 322 323 return columnToProperty; 324 } 325 326 333 public Map toMap(ResultSet rs) throws SQLException { 334 Map result = new CaseInsensitiveHashMap(); 335 ResultSetMetaData rsmd = rs.getMetaData(); 336 int cols = rsmd.getColumnCount(); 337 338 for (int i = 1; i <= cols; i++) { 339 result.put(rsmd.getColumnName(i), rs.getObject(i)); 340 } 341 342 return result; 343 } 344 345 353 private void callSetter( 354 Object target, 355 PropertyDescriptor prop, 356 Object value) 357 throws SQLException { 358 359 Method setter = prop.getWriteMethod(); 360 361 if (setter == null) { 362 return; 363 } 364 365 Class [] params = setter.getParameterTypes(); 366 try { 367 if (this.isCompatibleType(value, params[0])) { 369 setter.invoke(target, new Object [] { value }); 370 } 371 372 } catch (IllegalArgumentException e) { 373 throw new SQLException ( 374 "Cannot set " + prop.getName() + ": " + e.getMessage()); 375 376 } catch (IllegalAccessException e) { 377 throw new SQLException ( 378 "Cannot set " + prop.getName() + ": " + e.getMessage()); 379 380 } catch (InvocationTargetException e) { 381 throw new SQLException ( 382 "Cannot set " + prop.getName() + ": " + e.getMessage()); 383 } 384 } 385 386 397 private boolean isCompatibleType(Object value, Class type) { 398 if (value == null || type.isInstance(value)) { 400 return true; 401 402 } else if ( 403 type.equals(Integer.TYPE) && Integer .class.isInstance(value)) { 404 return true; 405 406 } else if (type.equals(Long.TYPE) && Long .class.isInstance(value)) { 407 return true; 408 409 } else if ( 410 type.equals(Double.TYPE) && Double .class.isInstance(value)) { 411 return true; 412 413 } else if (type.equals(Float.TYPE) && Float .class.isInstance(value)) { 414 return true; 415 416 } else if (type.equals(Short.TYPE) && Short .class.isInstance(value)) { 417 return true; 418 419 } else if (type.equals(Byte.TYPE) && Byte .class.isInstance(value)) { 420 return true; 421 422 } else if ( 423 type.equals(Character.TYPE) && Character .class.isInstance(value)) { 424 return true; 425 426 } else if ( 427 type.equals(Boolean.TYPE) && Boolean .class.isInstance(value)) { 428 return true; 429 430 } else { 431 return false; 432 } 433 434 } 435 436 443 private Object newInstance(Class c) throws SQLException { 444 try { 445 return c.newInstance(); 446 447 } catch (InstantiationException e) { 448 throw new SQLException ( 449 "Cannot create " + c.getName() + ": " + e.getMessage()); 450 451 } catch (IllegalAccessException e) { 452 throw new SQLException ( 453 "Cannot create " + c.getName() + ": " + e.getMessage()); 454 } 455 } 456 457 464 private PropertyDescriptor [] propertyDescriptors(Class c) 465 throws SQLException { 466 BeanInfo beanInfo = null; 468 try { 469 beanInfo = Introspector.getBeanInfo(c); 470 471 } catch (IntrospectionException e) { 472 throw new SQLException ( 473 "Bean introspection failed: " + e.getMessage()); 474 } 475 476 return beanInfo.getPropertyDescriptors(); 477 } 478 479 484 private static class CaseInsensitiveHashMap extends HashMap { 485 486 489 public boolean containsKey(Object key) { 490 return super.containsKey(key.toString().toLowerCase()); 491 } 492 493 496 public Object get(Object key) { 497 return super.get(key.toString().toLowerCase()); 498 } 499 500 503 public Object put(Object key, Object value) { 504 return super.put(key.toString().toLowerCase(), value); 505 } 506 507 510 public void putAll(Map m) { 511 Iterator iter = m.keySet().iterator(); 512 while (iter.hasNext()) { 513 Object key = iter.next(); 514 Object value = m.get(key); 515 this.put(key, value); 516 } 517 } 518 519 522 public Object remove(Object key) { 523 return super.remove(key.toString().toLowerCase()); 524 } 525 } 526 527 } 528 | Popular Tags |