View Javadoc
1 /* 2 * ==================================================================== 3 * 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, if 22 * any, must include the following acknowlegement: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowlegement may appear in the software itself, 26 * if and wherever such third-party acknowlegements normally appear. 27 * 28 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 29 * Foundation" must not be used to endorse or promote products derived 30 * from this software without prior written permission. For written 31 * permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache" 34 * nor may "Apache" appear in their names without prior written 35 * permission of the Apache Group. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 * 56 */ 57 package net.sf.voruta; 58 59 import net.sf.cglib.*; 60 61 import java.sql.*; 62 import java.util.*; 63 import java.lang.reflect.*; 64 import java.lang.reflect.Array; 65 66 67 /*** helper methods */ 68 public final class DbUtils { 69 70 public static final String JDBC_CONNECTION = Connection.class.getName(); 71 public static final String DEBUG = "voruta.debug"; 72 73 static java.util.Map DEFAULTS = new java.util.Hashtable(); 74 75 static final Log NOP_LOG = new Log(){ 76 public void debug( Object str){} 77 public void info( Object str){} 78 public void warn( Object str){} 79 public void traceQuery(String sql,Object[] args,Object result){} 80 public void traceUpdate(String sql,Object[] args,int updateCount){} 81 public void cachedValue(Object str){} 82 }; 83 84 static private Log log ; 85 86 87 88 /*** Used to set custom logger 89 * @param log Log interface implementation 90 */ 91 public static void setLog(Log log){ 92 DbUtils.log = (log == null) ? NOP_LOG : log ; 93 } 94 95 static boolean isDebug(){ 96 97 return "on".equals( Db.getProperty(DEBUG,"off") ); 98 99 } 100 101 public static Log getLog(){ 102 if(log == null){ 103 104 if(isDebug()){ 105 106 log = new Debug(); 107 108 }else { 109 110 log = NOP_LOG; 111 112 } 113 } 114 return log; 115 } 116 117 118 static{ 119 120 DEFAULTS.put(int.class, new Integer(0)); 121 DEFAULTS.put(short.class, new Short((short)0)); 122 DEFAULTS.put(byte.class, new Byte((byte)0)); 123 DEFAULTS.put(float.class, new Float(0f)); 124 DEFAULTS.put(double.class, new Double(0.0)); 125 DEFAULTS.put(long.class, new Long(0L)); 126 DEFAULTS.put(boolean.class, Boolean.FALSE); 127 DEFAULTS.put(char.class, new Character('\u0000')); 128 129 } 130 131 static final MethodFilter FILTER = new Filter(); 132 133 static class Filter implements MethodFilter{ 134 135 private Filter(){} 136 137 public boolean accept(Member member) { 138 return Modifier.isAbstract(member.getModifiers()); 139 } 140 public boolean equals(Object obj){ 141 return obj != null && obj.getClass() == this.getClass(); 142 } 143 144 public int hashCode(){ 145 return 11; 146 } 147 148 } 149 150 static class InterfaceFilter implements MethodFilter{ 151 152 Class cls; 153 InterfaceFilter(Class cls){ 154 this.cls = cls; 155 } 156 157 public boolean accept(Member member) { 158 Method method = (Method)member; 159 try{ 160 cls.getMethod(method.getName(),method.getParameterTypes()); 161 return false; 162 }catch(NoSuchMethodException e){ 163 return true; 164 } 165 } 166 167 } 168 169 170 static class ResultSetAdapter implements DbResultSet{ 171 172 ResultSet rs; 173 String names[]; 174 175 public ResultSetAdapter(ResultSet rs){ 176 this.rs = rs; 177 } 178 179 180 public String[] getNames()throws Exception { 181 182 if(names == null){ 183 184 ResultSetMetaData md = rs.getMetaData(); 185 int cnt = md.getColumnCount(); 186 names = new String[cnt]; 187 188 for( int i = 1; i<= cnt; i++ ){ 189 names[i - 1] = md.getColumnName(i); 190 } 191 } 192 return names; 193 194 } 195 196 197 public Object get(int index)throws Exception { 198 return rs.getObject(index + 1); 199 } 200 201 202 public boolean next() throws Exception{ 203 return rs.next(); 204 } 205 206 public void close() throws Exception{ 207 rs.close(); 208 } 209 210 public java.sql.ResultSet getResultSet() { 211 return rs; 212 } 213 214 } 215 216 217 public static DbResultSet adapter(final ResultSet rs){ 218 219 return new ResultSetAdapter(rs); 220 221 } 222 223 224 225 /*** executes SQL query 226 * @param connection 227 * @param query 228 * @param vals 229 * @param rsh 230 * @param userObject 231 * @return 232 */ 233 public static Object executeQuery( String name, 234 String query, 235 Object[] vals, 236 ResultSetHandler rsh, 237 Class type, 238 Object[] userObject ) throws Exception{ 239 240 if(rsh == null){ 241 throw new NullPointerException("handler is null \n query: \n " + query); 242 } 243 Connection connection = ThreadLocalConnection.get(name); 244 245 PreparedStatement stmt = null; 246 ResultSet rs = null; 247 248 try { 249 250 stmt = connection.prepareStatement(query); 251 fillStatement(stmt, vals); 252 253 try{ 254 255 long time = System.currentTimeMillis(); 256 if( isDebug() ){ 257 getLog().debug(query); 258 } 259 rs = stmt.executeQuery(); 260 261 if( isDebug() ){ 262 getLog().debug( ( ( System.currentTimeMillis() - time ) + " ms.")); 263 } 264 265 }catch(SQLException sqle){ 266 rethrow( sqle, query, vals); 267 throw new InternalError(); 268 } 269 Object value = rsh.handle(adapter(rs),type,userObject); 270 271 if(connection.getWarnings() != null){ 272 DbUtils.getLog().warn(connection.getWarnings()); 273 connection.clearWarnings(); 274 } 275 276 277 return value; 278 279 } finally { 280 close(rs); 281 close(stmt); 282 } 283 284 285 } 286 287 static void rethrow(SQLException cause, String sql,Object[] vals )throws Exception{ 288 289 if(isDebug()){ 290 291 StringBuffer msg = 292 new StringBuffer(cause.getMessage() + " \n query: \n" + sql); 293 if (vals != null && vals.length > 0) { 294 msg.append("\n parameters: \n" + java.util.Arrays.asList(vals).toString()); 295 } 296 297 SQLException e = new SQLException(msg.toString()); 298 e.setNextException(cause); 299 throw e; 300 301 }else{ 302 throw cause; 303 } 304 305 } 306 307 308 309 310 static void fillStatement(PreparedStatement stmt, Object[] vals) 311 throws SQLException { 312 if (vals != null) { 313 int size = vals.length; 314 for (int i = 0; i < size; i++) { 315 if( vals[i] != null ){ 316 stmt.setObject((i + 1), vals[i]); 317 }else{ 318 stmt.setNull((i + 1), Types.OTHER); 319 } 320 } 321 } 322 323 } 324 325 /*** 326 * executes SQL update statement 327 * @param connection 328 * @param query 329 * @param vals 330 * @return 331 */ 332 public static int executeUpdate(String name, String query,Object[] vals) 333 throws Exception{ 334 335 Connection connection = ThreadLocalConnection.get(name); 336 337 338 PreparedStatement stmt = connection.prepareStatement(query); 339 fillStatement(stmt, vals); 340 341 try { 342 long time = System.currentTimeMillis(); 343 344 if( isDebug() ){ 345 getLog().debug(query); 346 } 347 348 int result = stmt.executeUpdate(); 349 350 if( isDebug() ){ 351 getLog().debug(( ( System.currentTimeMillis() - time ) + " ms.")); 352 } 353 354 if(connection.getWarnings() != null){ 355 DbUtils.getLog().warn(connection.getWarnings()); 356 connection.clearWarnings(); 357 } 358 return result; 359 360 } catch(SQLException sqle) { 361 362 rethrow( sqle, query, vals); 363 throw new InternalError(); 364 365 } finally { 366 close(stmt); 367 } 368 369 } 370 371 372 373 374 /*** 375 * Create an Map from a ResultSet. 376 * It is assumed that next() has already been called on the ResultSet. 377 */ 378 379 public static void resultSetToMap(DbResultSet rs, Map result)throws Exception{ 380 381 String names[] = rs.getNames(); 382 383 for( int i = 0, l = names.length; i < l; i++ ){ 384 Object value = rs.get(i); 385 if( value != null ){ 386 result.put(names[i],value); 387 } 388 } 389 390 391 } 392 393 /*** 394 * Create an Bean from a ResultSet. 395 * It is assumed that next() has already been called on the ResultSet. 396 */ 397 398 public static Object resultSetToBean(DbResultSet rs, Object obj) throws Exception { 399 400 401 402 java.beans.BeanInfo bInfo = java.beans.Introspector.getBeanInfo( 403 obj.getClass()); 404 java.beans.PropertyDescriptor pd[] = bInfo.getPropertyDescriptors(); 405 406 String names[] = rs.getNames(); 407 LOOP: 408 for( int i = 0, cnt = names.length; i < cnt; i++ ){ 409 String name = names[i].toLowerCase(); 410 for( int j = 0; j < pd.length; j++ ){ 411 if(name.equals(pd[j].getName().toLowerCase())){ 412 Object value = rs.get(i); 413 if( value == null && pd[j].getPropertyType().isPrimitive() ){ 414 value = DEFAULTS.get( pd[j].getPropertyType() ); 415 } 416 try{ 417 pd[j].getWriteMethod().invoke(obj, new Object[]{ value }); 418 continue LOOP; 419 }catch(Throwable e){ 420 if(e instanceof InvocationTargetException ){ 421 e = ((InvocationTargetException)e).getTargetException(); 422 } 423 throw new DbException( "can not set property " + 424 pd[j].getPropertyType() + " " + 425 pd[j].getName() + "; value type: " + 426 value.getClass().getName() , e); 427 } 428 429 430 } 431 } 432 } 433 434 return obj; 435 } 436 437 public static void resultSetToBeanMap(DbResultSet rs, Class cls, Map results, String propertyName)throws Exception { 438 439 if(rs.next()){ 440 441 java.beans.BeanInfo bInfo = java.beans.Introspector.getBeanInfo(cls); 442 java.beans.PropertyDescriptor pd[] = bInfo.getPropertyDescriptors(); 443 String names[] = rs.getNames(); 444 int cnt = names.length; 445 int nameToIndex[] = new int[ cnt ]; 446 int propertyIndex = -1; 447 LOOP: 448 for( int i = 0; i < cnt; i++ ){ 449 String name = names[i].toLowerCase(); 450 if( name.equals(propertyName.toLowerCase()) ){ 451 propertyIndex = i; 452 } 453 for( int j = 0; j < pd.length; j++ ){ 454 if( name.equals( pd[j].getName(). 455 toLowerCase() ) ){ 456 nameToIndex[i] = j; 457 continue LOOP; 458 } 459 } 460 throw new DbException(" index not found for " + name ); 461 } 462 463 if( propertyIndex == -1 ){ 464 465 throw new DbException( " index not found for map key " + propertyName ); 466 467 } 468 469 do{ 470 471 Object obj; 472 try{ 473 474 obj = cls.newInstance(); 475 476 }catch(Exception e){ 477 throw new DbException( "can not create " + 478 cls.getName() , e); 479 } 480 481 for(int i = 0; i < cnt; i++){ 482 Object value = rs.get(i); 483 if( value == null ){ 484 continue; 485 } 486 int index = nameToIndex[i]; 487 try{ 488 489 pd[index].getWriteMethod().invoke(obj, new Object[]{ value }); 490 if( i == propertyIndex ){ 491 results.put(value, obj); 492 } 493 494 }catch(Throwable e){ 495 if(e instanceof InvocationTargetException ){ 496 e = ((InvocationTargetException)e).getTargetException(); 497 } 498 throw new DbException( "can not set property " + 499 pd[index].getPropertyType() + " " + 500 pd[index].getName() + "; value type: " + 501 value.getClass().getName() , e); 502 } 503 } 504 505 }while(rs.next()); 506 } 507 508 509 510 511 } 512 513 514 515 /*** 516 * optimized for collections of beans 517 * 518 */ 519 public static void resultSetToBeanCollection( DbResultSet rs, 520 Class cls, 521 Collection results) throws Exception { 522 523 524 String names[] = rs.getNames(); 525 int cnt = names.length; 526 527 if( Map.class.isAssignableFrom(cls) ){ 528 529 while(rs.next()){ 530 531 Map map = (Map)(cls.isInterface() ? 532 new HashMap() : cls.newInstance()); 533 534 for( int i = 0; i < cnt; i++ ){ 535 map.put( names[i], rs.get(i) ); 536 } 537 results.add(map); 538 } 539 540 return; 541 } 542 543 if(rs.next()){ 544 545 java.beans.BeanInfo bInfo = java.beans.Introspector.getBeanInfo(cls); 546 java.beans.PropertyDescriptor pd[] = bInfo.getPropertyDescriptors(); 547 548 549 int nameToIndex[] = new int[ cnt ]; 550 551 LOOP: 552 for( int i = 0; i < cnt; i++ ){ 553 String name = names[i].toLowerCase(); 554 for( int j = 0; j < pd.length; j++ ){ 555 if(name.equals(pd[j].getName().toLowerCase())){ 556 nameToIndex[i] = j; 557 continue LOOP; 558 } 559 } 560 throw new DbException(" index not found for " + name ); 561 } 562 do{ 563 564 Object obj; 565 try{ 566 567 obj = cls.newInstance(); 568 569 }catch(Exception e){ 570 throw new DbException( "can not create " + 571 cls.getName() , e); 572 } 573 574 for(int i = 0; i < cnt; i++){ 575 Object value = rs.get(i); 576 if( value == null ){ 577 continue; 578 } 579 int index = nameToIndex[i]; 580 try{ 581 582 pd[index].getWriteMethod().invoke(obj, new Object[]{ value }); 583 584 585 }catch(Throwable e){ 586 if(e instanceof InvocationTargetException ){ 587 e = ((InvocationTargetException)e).getTargetException(); 588 } 589 throw new DbException( "can not set property " + 590 pd[index].getPropertyType() + " " + 591 pd[index].getName() + "; value type: " + 592 value.getClass().getName() , e); 593 } 594 } 595 results.add(obj); 596 }while(rs.next()); 597 } 598 599 600 601 602 } 603 604 605 /*** 606 * Create an Object array from a ResultSet. 607 * It is assumed that next() has already been called on the ResultSet. 608 */ 609 public static Object resultSetToArray(DbResultSet rs, Class type) throws Exception{ 610 611 String names[] = rs.getNames(); 612 int sz = names.length; 613 614 if(type.isArray()){ 615 616 Object objs = Array.newInstance(type.getComponentType(),sz); 617 for (int i = 0; i < sz; i++) { 618 Object obj = rs.get(i ); 619 Array.set( objs, i , obj ); 620 } 621 return objs; 622 623 }else if(List.class.isAssignableFrom(type)){ 624 List vector = new Vector(); 625 for (int i = 0; i < sz; i++) { 626 vector.add( rs.get( i ) ); 627 } 628 return vector; 629 }else { 630 631 throw new IllegalArgumentException(type.toString()); 632 633 } 634 635 } 636 637 638 639 /*** 640 * Close a statement, avoid closing if null and hide 641 * any exceptions that occur. 642 */ 643 static void close(Statement stat) { 644 try { 645 stat.close(); 646 } catch (Throwable t) { 647 log.warn(t); 648 } 649 } 650 651 /*** 652 * Close a result set, avoid closing if null and hide 653 * any exceptions that occur. 654 */ 655 static void close(ResultSet rs) { 656 try { 657 rs.close(); 658 } catch (Throwable t) { 659 log.warn(t); 660 } 661 } 662 663 664 665 /*** 666 * @param sqle 667 * @param ps 668 */ 669 public static void printStackTrace(SQLException sqle, java.io.PrintWriter ps){ 670 671 SQLException next = sqle; 672 while( next != null ){ 673 next.printStackTrace(ps); 674 next = next.getNextException(); 675 if(next != null){ 676 ps.println("Next SQLException:"); 677 } 678 } 679 680 681 } 682 683 /*** 684 * @param sqle 685 */ 686 public static void printStackTrace(SQLException sqle){ 687 688 printStackTrace( sqle, new java.io.PrintWriter( System.err ) ); 689 690 } 691 692 /*** 693 * @param connection 694 * @param ps 695 */ 696 public static void printWarnings(Connection connection, java.io.PrintWriter ps){ 697 if( connection != null ){ 698 try{ 699 printStackTrace(connection.getWarnings(), ps); 700 }catch(SQLException sqle){ 701 printStackTrace(sqle, ps); 702 } 703 } 704 705 } 706 707 /*** 708 * @param connection 709 */ 710 public static void printWarnings(Connection connection ){ 711 printWarnings(connection, new java.io.PrintWriter(System.err)); 712 } 713 714 715 static CacheRegions getRegions(String config){ 716 717 return ThreadLocalConnection.getRegions(config); 718 } 719 720 721 }

This page was automatically generated by Maven