1 package org.apache.ojb.broker.util.batch; 2 3 17 18 19 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor; 20 import org.apache.ojb.broker.platforms.PlatformFactory; 21 import org.apache.ojb.broker.platforms.PlatformException; 22 import org.apache.ojb.broker.platforms.Platform; 23 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.InvocationTargetException ; 26 import java.math.BigDecimal ; 27 import java.sql.Connection ; 28 import java.sql.PreparedStatement ; 29 import java.sql.SQLException ; 30 import java.util.ArrayList ; 31 32 import java.lang.reflect.InvocationHandler ; 34 38 40 47 public class PreparedStatementInvocationHandler implements InvocationHandler 48 { 49 50 private final static Integer ONE = new Integer (1); 51 52 private static Method ADD_BATCH; 53 54 private final static Method SET_BIG_DECIMAL; 55 56 static 57 { 58 Method setBigDecimal = null; 59 try 60 { 61 setBigDecimal = PreparedStatement .class.getMethod("setBigDecimal", 62 new Class [] {Integer.TYPE, BigDecimal .class}); 63 } 64 catch ( Exception ex ) 65 { 66 } 68 SET_BIG_DECIMAL = setBigDecimal; 69 } 70 71 private final BatchConnection _batchConn; 72 73 private final String _sql; 74 75 private ArrayList _methods = new ArrayList (); 76 77 private ArrayList _params = new ArrayList (); 78 79 private Platform m_platform = null; 80 81 public PreparedStatementInvocationHandler(BatchConnection batchConn, String sql, JdbcConnectionDescriptor jcd) 82 { 83 _batchConn = batchConn; 84 _sql = sql; 85 m_platform = PlatformFactory.getPlatformFor(jcd); 86 try 87 { 88 ADD_BATCH = m_platform.getClass().getMethod("addBatch",new Class []{PreparedStatement .class}); 89 } 90 catch ( NoSuchMethodException e ) 91 { 92 95 ADD_BATCH = null; 96 } 97 catch ( SecurityException e ) 98 { 99 } 101 } 102 103 public Object invoke(Object proxy, Method method, Object [] args) 104 throws Throwable 105 { 106 String name = method.getName(); 107 if ( name.equals("executeUpdate") ) 108 { 109 _methods.add(ADD_BATCH); 110 _params.add(null); 111 _batchConn.nextExecuted(_sql); 112 return ONE; 113 } 114 else if ( name.equals("doExecute") ) 115 { 116 doExecute((Connection ) args[0]); 117 } 118 else if ( name.startsWith("set") ) 119 { 120 if ( name.equals("setLong") ) 122 { 123 method = SET_BIG_DECIMAL; 124 args[1] = BigDecimal.valueOf(((Long ) args[1]).longValue()); 125 } 126 _methods.add(method); 127 _params.add(args); 128 } 129 return null; 130 } 131 132 135 private void doExecute(Connection conn) throws SQLException 136 { 137 PreparedStatement stmt; 138 int size; 139 140 size = _methods.size(); 141 if ( size == 0 ) 142 { 143 return; 144 } 145 stmt = conn.prepareStatement(_sql); 146 try 147 { 148 m_platform.afterStatementCreate(stmt); 149 } 150 catch ( PlatformException e ) 151 { 152 if ( e.getCause() instanceof SQLException ) 153 { 154 throw (SQLException )e.getCause(); 155 } 156 else 157 { 158 throw new SQLException (e.getMessage()); 159 } 160 } 161 try 162 { 163 m_platform.beforeBatch(stmt); 164 } 165 catch ( PlatformException e ) 166 { 167 if ( e.getCause() instanceof SQLException ) 168 { 169 throw (SQLException )e.getCause(); 170 } 171 else 172 { 173 throw new SQLException (e.getMessage()); 174 } 175 } 176 try 177 { 178 for ( int i = 0; i < size; i++ ) 179 { 180 Method method = (Method ) _methods.get(i); 181 try 182 { 183 if ( method.equals(ADD_BATCH) ) 184 { 185 188 m_platform.addBatch(stmt); 189 } 190 else 191 { 192 method.invoke(stmt, (Object []) _params.get(i)); 193 } 194 } 195 catch (IllegalArgumentException ex) 196 { 197 StringBuffer buffer = generateExceptionMessage(i, stmt, ex); 198 throw new SQLException (buffer.toString()); 199 } 200 catch ( IllegalAccessException ex ) 201 { 202 StringBuffer buffer = generateExceptionMessage(i, stmt, ex); 203 throw new SQLException (buffer.toString()); 204 } 205 catch ( InvocationTargetException ex ) 206 { 207 Throwable th = ex.getTargetException(); 208 209 if ( th == null ) 210 { 211 th = ex; 212 } 213 if ( th instanceof SQLException ) 214 { 215 throw ((SQLException ) th); 216 } 217 else 218 { 219 throw new SQLException (th.toString()); 220 } 221 } 222 catch (PlatformException e) 223 { 224 throw new SQLException (e.toString()); 225 } 226 } 227 try 228 { 229 232 m_platform.executeBatch(stmt); 233 } 234 catch ( PlatformException e ) 235 { 236 if ( e.getCause() instanceof SQLException ) 237 { 238 throw (SQLException )e.getCause(); 239 } 240 else 241 { 242 throw new SQLException (e.getMessage()); 243 } 244 } 245 246 } 247 finally 248 { 249 stmt.close(); 250 _methods.clear(); 251 _params.clear(); 252 } 253 } 254 255 private StringBuffer generateExceptionMessage(int i, PreparedStatement stmt, Exception ex) 256 { 257 StringBuffer buffer = new StringBuffer (); 258 buffer.append("Method of type: "); 259 buffer.append(_methods.get(i)); 260 buffer.append(" invoking on instance: "); 261 if (( _methods.get(i)).equals(ADD_BATCH)) 262 buffer.append(m_platform); 263 else 264 buffer.append(stmt); 265 buffer.append(" with parameters: "); 266 if ((_methods.get(i)).equals(ADD_BATCH)) 267 buffer.append(stmt); 268 else 269 buffer.append(_params.get(i)); 270 buffer.append(" with root: "); 271 buffer.append(ex.toString()); 272 return buffer; 273 } 274 } 275 276 | Popular Tags |