1 21 package oracle.toplink.essentials.internal.ejb.cmp3.base; 23 24 import java.util.*; 25 import oracle.toplink.essentials.ejb.cmp3.EJBQuery; 26 import oracle.toplink.essentials.exceptions.*; 27 import oracle.toplink.essentials.internal.helper.ClassConstants; 28 import oracle.toplink.essentials.internal.helper.Helper; 29 import oracle.toplink.essentials.internal.helper.BasicTypeHelperImpl; 30 import oracle.toplink.essentials.queryframework.*; 31 import oracle.toplink.essentials.sessions.Session; 32 import oracle.toplink.essentials.internal.parsing.EJBQLParseTree; 33 import oracle.toplink.essentials.internal.parsing.ejbql.*; 34 import oracle.toplink.essentials.internal.localization.ExceptionLocalization; 35 import oracle.toplink.essentials.sessions.DatabaseRecord; 36 37 49 public abstract class EJBQueryImpl { 50 protected DatabaseQuery databaseQuery = null; 51 protected EntityManagerImpl entityManager = null; 52 protected String queryName = null; 53 protected Map parameters = null; 54 protected int firstResultIndex = -1; protected int maxResults = -1; protected int maxRows = -1; 58 abstract protected void throwNoResultException(String message); 59 abstract protected void throwNonUniqueResultException(String message); 60 61 64 protected EJBQueryImpl(EntityManagerImpl entityManager) { 65 parameters = new HashMap(); 66 this.entityManager = entityManager; 67 } 68 69 73 public EJBQueryImpl(DatabaseQuery query, EntityManagerImpl entityManager) { 74 this(entityManager); 75 this.databaseQuery = query; 76 } 77 78 83 public EJBQueryImpl(String ejbql, EntityManagerImpl entityManager) { 84 this(ejbql, entityManager, false); 85 } 86 87 93 public EJBQueryImpl(String queryDescription, EntityManagerImpl entityManager, boolean isNamedQuery) { 94 this(entityManager); 95 if (isNamedQuery) { 96 this.queryName = queryDescription; 97 } else { 98 if (databaseQuery == null) { 99 databaseQuery = buildEJBQLDatabaseQuery(queryDescription, getActiveSession()); 100 } 101 } 102 } 103 104 107 protected void setAsSQLModifyQuery(){ 108 if (getDatabaseQuery().isDataReadQuery()){ 109 DataModifyQuery query = new DataModifyQuery(); 110 query.setSQLString(databaseQuery.getSQLString()); 111 query.setIsUserDefined(databaseQuery.isUserDefined()); 112 query.setFlushOnExecute(databaseQuery.getFlushOnExecute()); 113 databaseQuery = query; 114 } 115 } 116 117 120 protected void setAsSQLReadQuery(){ 121 if(getDatabaseQuery().isDataModifyQuery()){ 122 DataReadQuery query = new DataReadQuery(); 123 query.setUseAbstractRecord(false); 124 query.setSQLString(databaseQuery.getSQLString()); 125 query.setIsUserDefined(databaseQuery.isUserDefined()); 126 query.setFlushOnExecute(databaseQuery.getFlushOnExecute()); 127 databaseQuery = query; 128 } 129 } 130 131 137 public static DatabaseQuery buildEJBQLDatabaseQuery(String ejbql, Session session) { 138 return buildEJBQLDatabaseQuery(ejbql, null, session); 139 } 140 141 149 public static DatabaseQuery buildEJBQLDatabaseQuery(String ejbql, Session session, HashMap hints) { 150 return buildEJBQLDatabaseQuery(ejbql, null, session, hints, null); 151 } 152 153 162 public static DatabaseQuery buildEJBQLDatabaseQuery(String ejbql, Session session, HashMap hints, ClassLoader classLoader) { 163 return buildEJBQLDatabaseQuery(ejbql, null, session, hints, classLoader); 164 } 165 166 173 public static DatabaseQuery buildEJBQLDatabaseQuery(String ejbql, Boolean flushOnExecute, Session session) { 174 return buildEJBQLDatabaseQuery(ejbql, flushOnExecute, session, null, null); 175 } 176 177 184 public static DatabaseQuery buildEJBQLDatabaseQuery(String ejbql, Boolean flushOnExecute, Session session, ClassLoader classLoader) { 185 return buildEJBQLDatabaseQuery(ejbql, flushOnExecute, session, null, classLoader); 186 } 187 188 197 public static DatabaseQuery buildEJBQLDatabaseQuery(String ejbql, Boolean flushOnExecute, Session session, HashMap hints, ClassLoader classLoader) { 198 DatabaseQuery databaseQuery = null; 199 EJBQLParser parser = EJBQLParserBase.parseEJBQLString(ejbql); 200 EJBQLParseTree parseTree = (EJBQLParseTree)parser.getParseTree(); 201 parseTree.setClassLoader(classLoader); 202 if ((parseTree.getQueryNode() != null) && (parseTree.getQueryNode().isSelectNode())) { 203 databaseQuery = new ReportQuery(); 204 databaseQuery.setEJBQLString(ejbql); 205 ((ReadAllQuery)databaseQuery).conformResultsInUnitOfWork(); 206 } else if ((parseTree.getQueryNode() != null) && (parseTree.getQueryNode().isUpdateNode())) { 207 databaseQuery = new UpdateAllQuery(); 208 databaseQuery.setEJBQLString(ejbql); 209 ((UpdateAllQuery)databaseQuery).setShouldDeferExecutionInUOW(false); 210 } else if ((parseTree.getQueryNode() != null) && (parseTree.getQueryNode().isDeleteNode())) { 211 databaseQuery = new DeleteAllQuery(); 212 databaseQuery.setEJBQLString(ejbql); 213 ((DeleteAllQuery)databaseQuery).setShouldDeferExecutionInUOW(false); 214 } 215 parseTree.populateQuery(databaseQuery, (oracle.toplink.essentials.internal.sessions.AbstractSession)session); 216 parseTree.addParametersToQuery(databaseQuery); 218 ((EJBQLCallQueryMechanism)databaseQuery.getQueryMechanism()).getEJBQLCall().setIsParsed(true); 219 databaseQuery.setFlushOnExecute(flushOnExecute); 220 221 applyHints(hints, databaseQuery); 223 224 return databaseQuery; 225 } 226 227 235 public static DatabaseQuery buildSQLDatabaseQuery(Class resultClass, String sqlString) { 236 return buildSQLDatabaseQuery(resultClass, sqlString, null); 237 } 238 239 248 public static DatabaseQuery buildSQLDatabaseQuery(Class resultClass, String sqlString, HashMap hints) { 249 ReadAllQuery query = new ReadAllQuery(resultClass); 250 query.setSQLString(sqlString); 251 query.setIsUserDefined(true); 252 253 applyHints(hints, query); 255 256 return query; 257 } 258 266 public static DatabaseQuery buildSQLDatabaseQuery(String sqlResultSetMappingName, String sqlString) { 267 return buildSQLDatabaseQuery(sqlResultSetMappingName, sqlString, null); 268 } 269 270 279 public static DatabaseQuery buildSQLDatabaseQuery(String sqlResultSetMappingName, String sqlString, HashMap hints) { 280 ResultSetMappingQuery query = new ResultSetMappingQuery(); 281 query.setSQLResultSetMappingName(sqlResultSetMappingName); 282 query.setSQLString(sqlString); 283 query.setIsUserDefined(true); 284 285 applyHints(hints, query); 287 288 return query; 289 } 290 291 294 public static DatabaseQuery buildSQLDatabaseQuery(String sqlString, Boolean flushOnExecute) { 295 return buildSQLDatabaseQuery(sqlString, new HashMap()); 296 } 297 298 301 public static DatabaseQuery buildSQLDatabaseQuery(String sqlString, HashMap hints) { 302 DataReadQuery query = new DataReadQuery(); 303 query.setUseAbstractRecord(false); 304 query.setSQLString(sqlString); 305 query.setIsUserDefined(true); 306 307 applyHints(hints, query); 309 310 return query; 311 } 312 313 318 protected Object executeReadQuery() { 319 Vector parameterValues = processParameters(); 320 boolean shouldResetConformResultsInUnitOfWork = false; 336 if(isFlushModeAUTO()) { 337 performPreQueryFlush(); 338 if(getDatabaseQuery().isObjectLevelReadQuery()) { 339 if(((ObjectLevelReadQuery)getDatabaseQuery()).shouldConformResultsInUnitOfWork()) { 340 ((ObjectLevelReadQuery)getDatabaseQuery()).setCacheUsage(ObjectLevelReadQuery.UseDescriptorSetting); 341 shouldResetConformResultsInUnitOfWork = true; 342 } 343 } 344 } 345 try { 346 return getActiveSession().executeQuery(getDatabaseQuery(), parameterValues); 347 } finally { 348 if(shouldResetConformResultsInUnitOfWork) { 349 ((ObjectLevelReadQuery)getDatabaseQuery()).conformResultsInUnitOfWork(); 350 } 351 } 352 } 353 354 358 public int executeUpdate() { 359 entityManager.verifyOpen(); 361 setAsSQLModifyQuery(); 362 if ( !(getDatabaseQuery() instanceof ModifyQuery) ){ 364 throw new IllegalStateException (ExceptionLocalization.buildMessage("incorrect_query_for_execute_update")); 365 } 366 Vector parameterValues = processParameters(); 368 if(isFlushModeAUTO()) { 369 performPreQueryFlush(); 370 } 371 Integer changedRows = (Integer )((Session)getActiveSession()).executeQuery(databaseQuery, parameterValues); 372 return changedRows.intValue(); 373 } 374 375 380 public DatabaseQuery getDatabaseQuery() { 381 if ((queryName != null) && (databaseQuery == null)) { 382 databaseQuery = getActiveSession().getQuery(queryName); 384 if (databaseQuery != null) { 385 if (!databaseQuery.isPrepared()){ 386 databaseQuery.prepareCall(getActiveSession(), new DatabaseRecord()); 388 } 389 databaseQuery = (DatabaseQuery)databaseQuery.clone(); 391 } else { 392 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("unable_to_find_named_query", new Object [] {queryName})); 393 } 394 395 } 396 return databaseQuery; 397 } 398 399 404 public Collection getResultCollection() { 405 entityManager.verifyOpen(); 407 setAsSQLReadQuery(); 408 propagateResultProperties(); 409 if (getDatabaseQuery() instanceof ReadAllQuery){ 411 Class containerClass = ((ReadAllQuery)getDatabaseQuery()).getContainerPolicy().getContainerClass(); 412 if (! Helper.classImplementsInterface(containerClass, ClassConstants.Collection_Class)){ 413 throw QueryException.invalidContainerClass( containerClass, ClassConstants.Collection_Class ); 414 } 415 } else if (getDatabaseQuery() instanceof ReadObjectQuery){ 416 throw QueryException.incorrectQueryObjectFound( getDatabaseQuery(), ReadAllQuery.class ); 418 } else if (!(getDatabaseQuery() instanceof ReadQuery)){ 419 throw new IllegalStateException (ExceptionLocalization.buildMessage("incorrect_query_for_get_result_collection")); 420 } 421 Object result = executeReadQuery(); 422 return (Collection)result; 423 } 424 425 430 public List getResultList() { 431 entityManager.verifyOpen(); 433 setAsSQLReadQuery(); 434 propagateResultProperties(); 435 if (getDatabaseQuery() instanceof ReadAllQuery){ 437 Class containerClass = ((ReadAllQuery)getDatabaseQuery()).getContainerPolicy().getContainerClass(); 438 if (! Helper.classImplementsInterface(containerClass, ClassConstants.List_Class)){ 439 throw QueryException.invalidContainerClass( containerClass, ClassConstants.List_Class ); 440 } 441 } else if (getDatabaseQuery() instanceof ReadObjectQuery){ 442 throw QueryException.incorrectQueryObjectFound( getDatabaseQuery(), ReadAllQuery.class ); 444 } else if (!(getDatabaseQuery() instanceof ReadQuery)){ 445 throw new IllegalStateException (ExceptionLocalization.buildMessage("incorrect_query_for_get_result_list")); 446 } 447 Object result = executeReadQuery(); 448 return (List)result; 449 } 450 451 457 public Object getSingleResult() { 458 entityManager.verifyOpen(); 460 setAsSQLReadQuery(); 461 propagateResultProperties(); 462 if (getDatabaseQuery() instanceof ReadAllQuery){ 464 Class containerClass = ((ReadAllQuery)getDatabaseQuery()).getContainerPolicy().getContainerClass(); 465 if (! Helper.classImplementsInterface(containerClass, ClassConstants.List_Class)){ 466 throw QueryException.invalidContainerClass( containerClass, ClassConstants.List_Class ); 467 } 468 } else if (!(getDatabaseQuery() instanceof ReadQuery)){ 469 throw new IllegalStateException (ExceptionLocalization.buildMessage("incorrect_query_for_get_single_result")); 470 } 471 Object result = executeReadQuery(); 472 if (result instanceof List){ 473 List results = (List)result; 474 if (results.isEmpty()) { 475 throwNoResultException(ExceptionLocalization.buildMessage("no_entities_retrieved_for_get_single_result", (Object [])null)); 476 } else if (results.size() > 1) { 477 throwNonUniqueResultException(ExceptionLocalization.buildMessage("too_many_results_for_get_single_result", (Object [])null)); 478 } 479 return results.get(0); 480 }else{ 481 if (result == null) { 482 throwNoResultException(ExceptionLocalization.buildMessage("no_entities_retrieved_for_get_single_result", (Object [])null)); 483 } 484 return result; 485 } 486 } 487 488 493 protected Vector processParameters() { 494 if (databaseQuery == null) { 495 getDatabaseQuery(); 496 } 497 List arguments = databaseQuery.getArguments(); 498 if (arguments.isEmpty()) { 499 Iterator params = parameters.keySet().iterator(); 500 while (params.hasNext()) { 501 databaseQuery.addArgument((String )params.next()); 502 } 503 arguments = databaseQuery.getArguments(); 504 } 505 Vector parameterValues = new Vector(arguments.size()); 507 for (Iterator i = arguments.iterator(); i.hasNext();) { 508 String name = (String )i.next(); 509 if (parameters.containsKey(name)) { 510 parameterValues.add(parameters.get(name)); 511 } else { 512 throw new IllegalStateException (ExceptionLocalization.buildMessage("missing_parameter_value", new Object []{name})); 514 } 515 } 516 return parameterValues; 517 } 518 519 522 public void setDatabaseQuery(DatabaseQuery query) { 523 databaseQuery = query; 524 } 525 526 530 protected void setFirstResultInternal(int startPosition) { 531 if (startPosition < 0) { 532 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("negative_start_position", (Object [])null)); 533 } 534 firstResultIndex = startPosition; 535 } 536 537 543 protected static void applyHints(HashMap hints, DatabaseQuery query) { 544 QueryHintsHandler.apply(hints, query); 545 } 546 547 548 557 protected boolean isFlushModeAUTO() { 558 if(getDatabaseQuery().getFlushOnExecute() != null) { 559 return getDatabaseQuery().getFlushOnExecute().booleanValue(); 560 } else { 561 return entityManager.isFlushModeAUTO(); 562 } 563 } 564 565 573 protected void setHintInternal(String hintName, Object value) { 574 QueryHintsHandler.apply(hintName, value, getDatabaseQuery()); 575 } 576 577 581 public void setMaxResultsInternal(int maxResult) { 582 if (maxResult < 0) { 583 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("negative_max_result", (Object [])null)); 584 } 585 this.maxResults = maxResult; 586 } 587 588 589 protected void propagateResultProperties() { 590 DatabaseQuery databaseQuery = getDatabaseQuery(); 591 if (databaseQuery.isReadQuery()) { 592 ReadQuery readQuery = (ReadQuery)databaseQuery; 593 if (maxResults >= 0) { 594 maxRows = maxResults + ((firstResultIndex >= 0) ? firstResultIndex : 0); 595 readQuery.setMaxRows(maxRows); 596 maxResults = -1; 597 } 598 if (firstResultIndex > -1) { 599 readQuery.setFirstResult(firstResultIndex); 600 firstResultIndex = -1; 601 } 602 } 603 } 604 605 610 protected void setParameterInternal(String name, Object value) { 611 int index = getDatabaseQuery().getArguments().indexOf(name); 612 if (getDatabaseQuery().getEJBQLString() != null){ if (index == -1){ 614 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("ejb30-wrong-argument-name",new Object []{name, getDatabaseQuery().getEJBQLString()})); 615 } 616 if (!isValidActualParameter(value, getDatabaseQuery().getArgumentTypes().get(index))) { 617 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("ejb30-incorrect-parameter-type", new Object [] {name, value.getClass(), getDatabaseQuery().getArgumentTypes().get(index), getDatabaseQuery().getEJBQLString()})); 618 } 619 } 620 parameters.put(name, value); 621 } 622 623 628 protected void setParameterInternal(int position, Object value) { 629 String pos = (new Integer (position)).toString(); 630 int index = getDatabaseQuery().getArguments().indexOf(pos); 631 if (getDatabaseQuery().getEJBQLString() != null){ if (index == -1) { 633 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("ejb30-wrong-argument-index", new Object []{position, getDatabaseQuery().getEJBQLString()})); 634 } 635 if (!isValidActualParameter(value, getDatabaseQuery().getArgumentTypes().get(index))) { 636 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("ejb30-incorrect-parameter-type", new Object [] {position, value.getClass(), getDatabaseQuery().getArgumentTypes().get(index), getDatabaseQuery().getEJBQLString()})); 637 } 638 } 639 parameters.put(pos, value); 640 } 641 642 protected boolean isValidActualParameter(Object value, Object parameterType) { 643 if (value == null) { 644 return true; 645 } else { 646 return BasicTypeHelperImpl.getInstance().isAssignableFrom(parameterType, value.getClass()); 647 } 648 } 649 650 protected Session getActiveSession() { 651 return entityManager.getActiveSession(); 652 } 653 654 protected void performPreQueryFlush(){ 655 if (this.entityManager.shouldFlushBeforeQuery()){ 656 this.entityManager.flush(); 657 } 658 } 659 660 } 661 | Popular Tags |