1 22 package org.jboss.ejb.plugins.cmp.jdbc2; 23 24 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2; 25 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2; 26 import org.jboss.ejb.plugins.cmp.jdbc2.schema.Schema; 27 import org.jboss.ejb.plugins.cmp.jdbc.JDBCUtil; 28 import org.jboss.ejb.plugins.cmp.jdbc.QueryParameter; 29 import org.jboss.ejb.plugins.cmp.ejbql.SelectFunction; 30 import org.jboss.ejb.GenericEntityObjectFactory; 31 import org.jboss.logging.Logger; 32 33 import javax.ejb.FinderException ; 34 import javax.ejb.ObjectNotFoundException ; 35 import java.util.Collection ; 36 import java.util.ArrayList ; 37 import java.util.Collections ; 38 import java.util.List ; 39 import java.util.Set ; 40 import java.util.HashSet ; 41 import java.sql.Connection ; 42 import java.sql.PreparedStatement ; 43 import java.sql.ResultSet ; 44 import java.sql.SQLException ; 45 46 50 public abstract class AbstractQueryCommand implements QueryCommand 51 { 52 static final CollectionFactory COLLECTION_FACTORY = new CollectionFactory() 53 { 54 public Collection newCollection() 55 { 56 return new ArrayList (); 57 } 58 }; 59 60 static final CollectionFactory SET_FACTORY = new CollectionFactory() 61 { 62 public Collection newCollection() 63 { 64 return new HashSet (); 65 } 66 }; 67 68 protected String sql; 69 protected Logger log; 70 protected JDBCEntityBridge2 entity; 71 protected QueryParameter[] params = null; 72 private CollectionFactory collectionFactory; 73 private CollectionStrategy collectionStrategy; 74 private ResultReader resultReader; 75 76 78 protected void setResultType(Class clazz) 79 { 80 if(Set .class.isAssignableFrom(clazz)) 81 { 82 collectionFactory = SET_FACTORY; 83 } 84 else if(Collection .class.isAssignableFrom(clazz)) 85 { 86 collectionFactory = COLLECTION_FACTORY; 87 } 88 initCollectionStrategy(); 89 } 90 91 protected void setFieldReader(JDBCCMPFieldBridge2 field) 92 { 93 this.resultReader = new FieldReader(field); 94 initCollectionStrategy(); 95 } 96 97 protected void setFunctionReader(SelectFunction func) 98 { 99 this.resultReader = new FunctionReader(func); 100 initCollectionStrategy(); 101 } 102 103 protected void setEntityReader(JDBCEntityBridge2 entity, boolean searchableOnly) 104 { 105 this.entity = entity; 106 this.resultReader = new EntityReader(entity, searchableOnly); 107 initCollectionStrategy(); 108 } 109 110 private void initCollectionStrategy() 111 { 112 if(collectionFactory != null && resultReader != null) 113 { 114 collectionStrategy = new EagerCollectionStrategy(collectionFactory, resultReader, log); 115 } 116 } 117 118 120 public JDBCStoreManager2 getStoreManager() 121 { 122 return (JDBCStoreManager2) entity.getManager(); 123 } 124 125 public Collection fetchCollection(Schema schema, GenericEntityObjectFactory factory, Object [] args) 126 throws FinderException 127 { 128 return fetchCollection(entity, sql, params, collectionStrategy, schema, factory, args, log); 129 } 130 131 public Object fetchOne(Schema schema, GenericEntityObjectFactory factory, Object [] args) throws FinderException 132 { 133 schema.flush(); 134 return executeFetchOne(args, factory); 135 } 136 137 139 protected Object executeFetchOne(Object [] args, GenericEntityObjectFactory factory) throws FinderException 140 { 141 return fetchOne(entity, sql, params, resultReader, args, factory, log); 142 } 143 144 static Collection fetchCollection(JDBCEntityBridge2 entity, 145 String sql, 146 QueryParameter[] params, 147 CollectionStrategy collectionStrategy, 148 Schema schema, 149 GenericEntityObjectFactory factory, 150 Object [] args, 151 Logger log) 152 throws FinderException 153 { 154 schema.flush(); 155 156 Collection result; 157 158 Connection con = null; 159 PreparedStatement ps = null; 160 ResultSet rs = null; 161 boolean throwRuntimeExceptions = entity.getMetaData().getThrowRuntimeExceptions(); 162 163 if (throwRuntimeExceptions) 166 { 167 try 168 { 169 con = entity.getDataSource().getConnection(); 170 } 171 catch (SQLException sqle) 172 { 173 javax.ejb.EJBException ejbe = new javax.ejb.EJBException ("Could not get a connection; " + sqle); 174 ejbe.initCause(sqle); 175 throw ejbe; 176 } 177 } 178 try 179 { 180 if(log.isDebugEnabled()) 181 { 182 log.debug("executing: " + sql); 183 } 184 185 if ( ! throwRuntimeExceptions) 187 { 188 con = entity.getDataSource().getConnection(); 189 } 190 ps = con.prepareStatement(sql); 191 192 if(params != null) 193 { 194 for(int i = 0; i < params.length; i++) 195 { 196 params[i].set(log, ps, i + 1, args); 197 } 198 } 199 200 rs = ps.executeQuery(); 201 } 202 catch(Exception e) 203 { 204 JDBCUtil.safeClose(rs); 205 JDBCUtil.safeClose(ps); 206 JDBCUtil.safeClose(con); 207 208 log.error("Finder failed: " + e.getMessage(), e); 209 FinderException fe = new FinderException (e.getMessage()); 210 fe.initCause(e); 211 throw fe; 212 } 213 214 result = collectionStrategy.readResultSet(con, ps, rs, factory); 215 216 return result; 217 } 218 219 static Object fetchOne(JDBCEntityBridge2 entity, 220 String sql, 221 QueryParameter[] params, 222 ResultReader resultReader, 223 Object [] args, 224 GenericEntityObjectFactory factory, 225 Logger log) 226 throws FinderException 227 { 228 Object pk; 229 Connection con = null; 230 PreparedStatement ps = null; 231 ResultSet rs = null; 232 boolean throwRuntimeExceptions = entity.getMetaData().getThrowRuntimeExceptions(); 233 234 if (throwRuntimeExceptions) 237 { 238 try 239 { 240 con = entity.getDataSource().getConnection(); 241 } 242 catch (SQLException sqle) 243 { 244 javax.ejb.EJBException ejbe = new javax.ejb.EJBException ("Could not get a connection; " + sqle); 245 throw ejbe; 247 } 248 } 249 try 250 { 251 if(log.isDebugEnabled()) 252 { 253 log.debug("executing: " + sql); 254 } 255 256 if ( ! throwRuntimeExceptions) 258 { 259 con = entity.getDataSource().getConnection(); 260 } 261 ps = con.prepareStatement(sql); 262 263 if(params != null) 264 { 265 for(int i = 0; i < params.length; i++) 266 { 267 params[i].set(log, ps, i + 1, args); 268 } 269 } 270 271 rs = ps.executeQuery(); 272 if(rs.next()) 273 { 274 pk = resultReader.readRow(rs, factory); 275 if(rs.next()) 276 { 277 List list = new ArrayList (); 278 list.add(pk); 279 list.add(resultReader.readRow(rs, factory)); 280 while(rs.next()) 281 { 282 list.add(resultReader.readRow(rs, factory)); 283 } 284 throw new FinderException ("More than one instance matches the single-object finder criteria: " + list); 285 } 286 } 287 else 288 { 289 throw new ObjectNotFoundException (); 290 } 291 } 292 catch(FinderException e) 293 { 294 throw e; 295 } 296 catch(Exception e) 297 { 298 FinderException fe = new FinderException (e.getMessage()); 299 fe.initCause(e); 300 throw fe; 301 } 302 finally 303 { 304 JDBCUtil.safeClose(rs); 305 JDBCUtil.safeClose(ps); 306 JDBCUtil.safeClose(con); 307 } 308 309 return pk; 310 } 311 312 protected void setParameters(List p) 313 { 314 if(p.size() > 0) 315 { 316 params = new QueryParameter[p.size()]; 317 for(int i = 0; i < p.size(); i++) 318 { 319 Object pi = p.get(i); 320 if(!(pi instanceof QueryParameter)) 321 { 322 throw new IllegalArgumentException ("Element " 323 + 324 i 325 + 326 " of list is not an instance of QueryParameter, but " + 327 p.get(i).getClass().getName()); 328 } 329 params[i] = (QueryParameter) pi; 330 } 331 } 332 } 333 334 336 static interface CollectionFactory 337 { 338 Collection newCollection(); 339 } 340 341 static interface ResultReader 342 { 343 Object readRow(ResultSet rs, GenericEntityObjectFactory factory) throws SQLException ; 344 } 345 346 static class EntityReader implements ResultReader 347 { 348 private final JDBCEntityBridge2 entity; 349 private final boolean searchableOnly; 350 351 public EntityReader(JDBCEntityBridge2 entity, boolean searchableOnly) 352 { 353 this.entity = entity; 354 this.searchableOnly = searchableOnly; 355 } 356 357 public Object readRow(ResultSet rs, GenericEntityObjectFactory factory) 358 { 359 final Object pk = entity.getTable().loadRow(rs, searchableOnly); 360 return pk == null ? null : factory.getEntityEJBObject(pk); 361 } 362 }; 363 364 static class FieldReader implements ResultReader 365 { 366 private final JDBCCMPFieldBridge2 field; 367 368 public FieldReader(JDBCCMPFieldBridge2 field) 369 { 370 this.field = field; 371 } 372 373 public Object readRow(ResultSet rs, GenericEntityObjectFactory factory) throws SQLException 374 { 375 return field.loadArgumentResults(rs, 1); 376 } 377 } 378 379 static class FunctionReader implements ResultReader 380 { 381 private final SelectFunction function; 382 383 public FunctionReader(SelectFunction function) 384 { 385 this.function = function; 386 } 387 388 public Object readRow(ResultSet rs, GenericEntityObjectFactory factory) throws SQLException 389 { 390 return function.readResult(rs); 391 } 392 } 393 394 interface CollectionStrategy 395 { 396 Collection readResultSet(Connection con, PreparedStatement ps, ResultSet rs, GenericEntityObjectFactory factory) 397 throws FinderException ; 398 } 399 400 static class EagerCollectionStrategy 401 implements CollectionStrategy 402 { 403 private final CollectionFactory collectionFactory; 404 private final ResultReader resultReader; 405 private final Logger log; 406 407 public EagerCollectionStrategy(CollectionFactory collectionFactory, 408 ResultReader resultReader, Logger log) 409 { 410 this.collectionFactory = collectionFactory; 411 this.resultReader = resultReader; 412 this.log = log; 413 } 414 415 public Collection readResultSet(Connection con, 416 PreparedStatement ps, 417 ResultSet rs, 418 GenericEntityObjectFactory factory) 419 throws FinderException 420 { 421 Collection result; 422 try 423 { 424 if(rs.next()) 425 { 426 result = collectionFactory.newCollection(); 427 Object instance = resultReader.readRow(rs, factory); 428 result.add(instance); 429 while(rs.next()) 430 { 431 instance = resultReader.readRow(rs, factory); 432 result.add(instance); 433 } 434 } 435 else 436 { 437 result = Collections.EMPTY_SET; 438 } 439 } 440 catch(Exception e) 441 { 442 log.error("Finder failed: " + e.getMessage(), e); 443 throw new FinderException (e.getMessage()); 444 } 445 finally 446 { 447 JDBCUtil.safeClose(rs); 448 JDBCUtil.safeClose(ps); 449 JDBCUtil.safeClose(con); 450 } 451 return result; 452 } 453 } 454 } 455 | Popular Tags |