1 21 package oracle.toplink.essentials.internal.queryframework; 23 24 import java.util.ArrayList ; 25 import java.util.List ; 26 import oracle.toplink.essentials.expressions.Expression; 27 import java.util.Map ; 28 import java.util.HashMap ; 29 import java.util.Vector ; 30 31 import oracle.toplink.essentials.expressions.ExpressionBuilder; 32 import oracle.toplink.essentials.internal.expressions.QueryKeyExpression; 33 import oracle.toplink.essentials.internal.expressions.ObjectExpression; 34 import oracle.toplink.essentials.descriptors.ClassDescriptor; 35 import oracle.toplink.essentials.internal.sessions.AbstractSession; 36 import oracle.toplink.essentials.mappings.ForeignReferenceMapping; 37 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 38 import java.util.Iterator ; 39 import oracle.toplink.essentials.internal.descriptors.ObjectBuilder; 40 import oracle.toplink.essentials.internal.expressions.ForUpdateOfClause; 41 import oracle.toplink.essentials.exceptions.QueryException; 42 import oracle.toplink.essentials.queryframework.ObjectBuildingQuery; 43 import oracle.toplink.essentials.queryframework.ObjectLevelReadQuery; 44 45 54 55 public class JoinedAttributeManager implements Cloneable { 56 57 58 protected ArrayList joinedAttributeExpressions_; 59 60 61 protected ArrayList joinedMappingExpressions_; 62 63 64 protected ArrayList joinedAttributes_; 65 66 67 protected boolean isToManyJoin = false; 68 69 70 protected boolean hasOuterJoinedAttribute = true; 71 72 73 protected transient HashMap joinedMappingIndexes_; 74 75 76 protected transient HashMap joinedMappingQueries_; 77 78 79 protected List dataResults; 80 81 82 protected ClassDescriptor descriptor; 83 84 85 protected ExpressionBuilder baseExpressionBuilder; 86 87 88 protected ObjectBuildingQuery baseQuery; 89 90 91 protected int parentResultIndex; 92 93 public JoinedAttributeManager(){ 94 } 95 96 public JoinedAttributeManager(ClassDescriptor descriptor, ExpressionBuilder baseBuilder, ObjectBuildingQuery baseQuery){ 97 this.descriptor = descriptor; 98 this.baseQuery = baseQuery; 99 this.baseExpressionBuilder = baseBuilder; 100 this.parentResultIndex = 0; 101 } 102 103 106 public void addJoinedAttribute(String attributeExpression) { 107 this.getJoinedAttributes().add(attributeExpression); 108 } 109 110 113 public void addJoinedAttributeExpression(Expression attributeExpression) { 114 getJoinedAttributeExpressions().add(attributeExpression); 115 } 116 117 123 public void addJoinedMappingExpression(Expression mappingExpression) { 124 getJoinedMappingExpressions().add(mappingExpression); 125 } 126 127 133 public void addJoinedMapping(String attributeName) { 134 addJoinedMappingExpression(this.baseExpressionBuilder.get(attributeName)); 135 } 136 137 138 142 public Object clone(){ 143 JoinedAttributeManager joinManager = new JoinedAttributeManager(); 144 joinManager.baseExpressionBuilder = this.baseExpressionBuilder; 145 joinManager.baseQuery = this.baseQuery; 146 joinManager.descriptor = this.descriptor; 147 if (this.joinedAttributeExpressions_ != null){ 148 joinManager.joinedAttributeExpressions_ = (ArrayList )this.joinedAttributeExpressions_.clone(); 149 } 150 if (this.joinedMappingExpressions_ != null){ 151 joinManager.joinedMappingExpressions_ = (ArrayList )this.joinedMappingExpressions_.clone(); 152 } 153 if (this.joinedAttributes_ != null){ 154 joinManager.joinedAttributes_ = (ArrayList )this.joinedAttributes_.clone(); 155 } 156 if (this.joinedMappingIndexes_ != null){ 157 joinManager.joinedMappingIndexes_ = (HashMap )this.joinedMappingIndexes_.clone(); 158 } 159 if (this.joinedMappingQueries_ != null){ 160 joinManager.joinedMappingQueries_ = (HashMap )this.joinedMappingQueries_.clone(); 161 } 162 joinManager.isToManyJoin = this.isToManyJoin; 163 joinManager.hasOuterJoinedAttribute = this.hasOuterJoinedAttribute; 164 return joinManager; 165 166 } 167 168 174 public int computeJoiningMappingIndexes(boolean includeAllSubclassFields, AbstractSession session, int offset) { 175 if (!hasJoinedExpressions()) { 176 return offset; 177 } 178 setJoinedMappingIndexes_(new HashMap (getJoinedAttributeExpressions().size() + getJoinedMappingExpressions().size())); 179 int fieldIndex = 0; 180 if (includeAllSubclassFields) { 181 fieldIndex = getDescriptor().getAllFields().size(); 182 } else { 183 fieldIndex = getDescriptor().getFields().size(); 184 } 185 fieldIndex += offset; 186 fieldIndex = computeIndexesForJoinedExpressions(getJoinedAttributeExpressions(), fieldIndex, session); 187 computeIndexesForJoinedExpressions(getJoinedMappingExpressions(), fieldIndex, session); 188 return fieldIndex; 189 } 190 191 196 protected void computeNestedQueriesForJoinedExpressions(List joinedExpressions, AbstractSession session, ObjectLevelReadQuery readQuery) { 197 for (int index = 0; index < joinedExpressions.size(); index++) { 198 ObjectExpression objectExpression = (ObjectExpression)joinedExpressions.get(index); 199 200 objectExpression.getBuilder().setSession(session); 202 objectExpression.getBuilder().setQueryClass(getDescriptor().getJavaClass()); 203 204 ObjectExpression baseExpression = objectExpression; 206 while (!baseExpression.getBaseExpression().isExpressionBuilder()) { 207 baseExpression = (ObjectExpression)((QueryKeyExpression)baseExpression).getBaseExpression(); 208 } 209 this.addJoinedAttribute(baseExpression.getName()); 210 211 if ((objectExpression.getBaseExpression() == objectExpression.getBuilder()) && objectExpression.getMapping().isForeignReferenceMapping()) { 213 ForeignReferenceMapping mapping = (ForeignReferenceMapping)objectExpression.getMapping(); 214 215 ObjectLevelReadQuery nestedQuery = mapping.prepareNestedJoins(this, session); 217 218 getJoinedMappingQueries_().put(mapping, nestedQuery); 220 } 221 } 222 } 223 224 228 public void computeJoiningMappingQueries(AbstractSession session) { 229 if (hasJoinedExpressions()) { 230 this.joinedAttributes_ = new ArrayList (getJoinedAttributeExpressions().size() + getJoinedMappingExpressions().size()); 231 setJoinedMappingQueries_(new HashMap (getJoinedAttributeExpressions().size() + getJoinedMappingExpressions().size())); 232 computeNestedQueriesForJoinedExpressions(getJoinedAttributeExpressions(), session, (ObjectLevelReadQuery)this.baseQuery); 233 computeNestedQueriesForJoinedExpressions(getJoinedMappingExpressions(), session, (ObjectLevelReadQuery)this.baseQuery); 234 } 235 } 236 237 245 protected int computeIndexesForJoinedExpressions(List joinedExpressions, int currentIndex, AbstractSession session) { 246 for (int index = 0; index < joinedExpressions.size(); index++) { 247 ObjectExpression objectExpression = (ObjectExpression)joinedExpressions.get(index); 248 249 if ((objectExpression.getBaseExpression() == objectExpression.getBuilder()) && objectExpression.getMapping() != null && objectExpression.getMapping().isForeignReferenceMapping()) { 251 getJoinedMappingIndexes_().put(objectExpression.getMapping(), new Integer (currentIndex)); 252 } 253 ClassDescriptor descriptor = objectExpression.getMapping().getReferenceDescriptor(); 254 int nFields; 255 if(objectExpression.isQueryKeyExpression() && ((QueryKeyExpression)objectExpression).isUsingOuterJoinForMultitableInheritance()) { 256 nFields = descriptor.getAllFields().size(); 257 } else { 258 nFields = descriptor.getFields().size(); 259 } 260 currentIndex = currentIndex + nFields; 261 } 262 return currentIndex; 263 } 264 265 269 public ExpressionBuilder getBaseExpressionBuilder(){ 270 return this.baseExpressionBuilder; 271 } 272 273 277 public ObjectBuildingQuery getBaseQuery(){ 278 return this.baseQuery; 279 } 280 281 285 public List getDataResults_() { 286 return dataResults; 287 } 288 289 292 public ClassDescriptor getDescriptor(){ 293 return this.descriptor; 294 } 295 296 300 public List getJoinedAttributes() { 301 if (this.joinedAttributes_ == null){ 302 this.joinedAttributes_ = new ArrayList (); 303 } 304 return this.joinedAttributes_; 305 } 306 307 311 public List getJoinedAttributeExpressions() { 312 if (this.joinedAttributeExpressions_ == null){ 313 this.joinedAttributeExpressions_ = new ArrayList (); 314 } 315 return joinedAttributeExpressions_; 316 } 317 318 323 public List getJoinedMappingExpressions() { 324 if (this.joinedMappingExpressions_ == null){ 325 this.joinedMappingExpressions_ = new ArrayList (); 326 } 327 return joinedMappingExpressions_; 328 } 329 330 334 public boolean hasJoinedAttributeExpressions() { 335 return this.joinedAttributeExpressions_ != null && !this.joinedAttributeExpressions_.isEmpty(); 336 } 337 338 343 public boolean hasJoinedExpressions() { 344 return hasJoinedAttributeExpressions() || hasJoinedMappingExpressions(); 345 } 346 347 351 public boolean hasJoinedMappingExpressions() { 352 return this.joinedMappingExpressions_ != null && !this.joinedMappingExpressions_.isEmpty(); 353 } 354 355 360 public boolean hasJoinedAttributes() { 361 return this.joinedAttributes_ != null && !this.joinedAttributes_.isEmpty(); 362 } 363 364 368 public boolean hasOuterJoinedAttributeQuery() { 369 return this.hasOuterJoinedAttribute; 370 } 371 372 376 public boolean isToManyJoin() { 377 return this.isToManyJoin; 378 } 379 380 384 public boolean isAttributeJoined(ClassDescriptor mappingDescriptor, String attributeName) { 385 if (mappingDescriptor.isAggregateDescriptor() && (mappingDescriptor != getDescriptor())) { 388 return false; 389 } 390 if (this.hasJoinedAttributes()) { 391 return this.joinedAttributes_.contains(attributeName); 392 } 393 return isAttributeExpressionJoined(attributeName) || isAttributeMappingJoined(attributeName); 394 } 395 396 400 protected boolean isAttributeNameInJoinedExpressionList(String attributeName, List joinedExpressionList) { 401 for (Iterator joinEnum = joinedExpressionList.iterator(); joinEnum.hasNext();) { 402 QueryKeyExpression expression = (QueryKeyExpression)joinEnum.next(); 403 while (!expression.getBaseExpression().isExpressionBuilder()) { 404 expression = (QueryKeyExpression)expression.getBaseExpression(); 405 } 406 if (expression.getName().equals(attributeName)) { 407 return true; 408 } 409 } 410 return false; 411 } 412 413 417 protected boolean isAttributeExpressionJoined(String attributeName) { 418 return isAttributeNameInJoinedExpressionList(attributeName, getJoinedAttributeExpressions()); 419 } 420 421 425 protected boolean isAttributeMappingJoined(String attributeName) { 426 return isAttributeNameInJoinedExpressionList(attributeName, getJoinedMappingExpressions()); 427 } 428 429 434 public void setJoinedAttributeExpressions_(List joinedExpressions) { 435 this.joinedAttributeExpressions_ = new ArrayList (joinedExpressions); 436 } 437 438 443 public void setJoinedMappingExpressions_(List joinedMappingExpressions) { 444 this.joinedMappingExpressions_ = new ArrayList (joinedMappingExpressions); 445 } 446 447 451 public Map getJoinedMappingIndexes_() { 452 return joinedMappingIndexes_; 453 } 454 455 459 public Map getJoinedMappingQueries_() { 460 return joinedMappingQueries_; 461 } 462 463 467 protected void setJoinedMappingQueries_(HashMap joinedMappingQueries) { 468 this.joinedMappingQueries_ = joinedMappingQueries; 469 } 470 471 475 public void setJoinedMappingIndexes_(HashMap joinedMappingIndexes) { 476 this.joinedMappingIndexes_ = joinedMappingIndexes; 477 } 478 479 483 488 492 protected void setIsOuterJoinedAttributeQuery(boolean isOuterJoinedAttribute) { 493 this.hasOuterJoinedAttribute = isOuterJoinedAttribute; 494 } 495 496 500 protected void setIsToManyJoinQuery(boolean isToManyJoin) { 501 this.isToManyJoin = isToManyJoin; 502 } 503 504 505 509 public void prepareJoinExpressions(AbstractSession session) { 510 setIsOuterJoinedAttributeQuery(false); 512 for (int index = 0; index < getJoinedAttributeExpressions().size(); index++) { 513 Expression expression = (Expression)getJoinedAttributeExpressions().get(index); 514 if(expression.isObjectExpression()) { 515 ((ObjectExpression)expression).setShouldUseOuterJoinForMultitableInheritance(true); 516 } 517 prepareJoinExpression(expression, session); 518 } 519 for (int index = 0; index < getJoinedMappingExpressions().size(); index++) { 520 Expression expression = (Expression)getJoinedMappingExpressions().get(index); 521 if(expression.isObjectExpression()) { 522 ((ObjectExpression)expression).setShouldUseOuterJoinForMultitableInheritance(true); 523 } 524 prepareJoinExpression(expression, session); 525 } 526 computeJoiningMappingQueries(session); 527 } 528 529 532 protected void prepareJoinExpression(Expression expression, AbstractSession session) { 533 if (!expression.isQueryKeyExpression()) { 535 throw QueryException.mappingForExpressionDoesNotSupportJoining(expression); 536 } 537 QueryKeyExpression objectExpression = (QueryKeyExpression)expression; 538 539 objectExpression.getBuilder().setSession(session); 541 if (objectExpression.getBuilder().getQueryClass() == null){ 542 objectExpression.getBuilder().setQueryClass(this.descriptor.getJavaClass()); 543 } 544 if ((objectExpression.getMapping() == null) || (!objectExpression.getMapping().isJoiningSupported())) { 546 throw QueryException.mappingForExpressionDoesNotSupportJoining(objectExpression); 547 } 548 549 ObjectExpression baseExpression = objectExpression; 551 while (!baseExpression.isExpressionBuilder()) { 552 if (((QueryKeyExpression)baseExpression).shouldQueryToManyRelationship()) { 553 setIsToManyJoinQuery(true); 554 } 555 if (((QueryKeyExpression)baseExpression).shouldUseOuterJoin()) { 556 setIsOuterJoinedAttributeQuery(true); 557 } 558 baseExpression = (ObjectExpression)((QueryKeyExpression)baseExpression).getBaseExpression(); 559 } 560 } 561 562 567 public void processJoinedMappings(){ 568 ObjectBuilder objectBuilder = getDescriptor().getObjectBuilder(); 569 if (objectBuilder.hasJoinedAttributes()) { 570 Vector mappingJoinedAttributes = objectBuilder.getJoinedAttributes(); 571 if (!hasJoinedExpressions()) { 572 for (int i = 0; i < mappingJoinedAttributes.size(); i++) { 573 addJoinedMapping((String )mappingJoinedAttributes.get(i)); 574 } 575 } else { 576 for (int i = 0; i < mappingJoinedAttributes.size(); i++) { 577 String attribute = (String )mappingJoinedAttributes.get(i); 578 if (!isAttributeExpressionJoined(attribute)) { 579 addJoinedMapping(attribute); 580 } 581 } 582 } 583 } 584 } 585 586 590 public void reset(){ 591 this.joinedMappingExpressions_ = null; 592 this.joinedAttributes_ = null; 593 this.isToManyJoin = false; 594 this.hasOuterJoinedAttribute = true; 595 this.joinedMappingIndexes_ = null; 596 this.joinedMappingQueries_ = null; 597 this.dataResults = null; 598 } 599 600 605 public void setBaseQuery(ObjectLevelReadQuery query){ 606 this.baseQuery = query; 607 } 608 609 614 protected void setBaseExpressionBuilder(ExpressionBuilder builder){ 615 this.baseExpressionBuilder = builder; 616 } 617 618 622 public void setDataResults(List dataResults, AbstractSession session) { 623 this.dataResults = dataResults; 624 if(getJoinedMappingQueries_() != null && !getJoinedMappingQueries_().isEmpty() && dataResults != null && !dataResults.isEmpty()) { 625 Iterator it = getJoinedMappingQueries_().entrySet().iterator(); 626 while(it.hasNext()) { 627 Map.Entry entry = (Map.Entry )it.next(); 628 ObjectLevelReadQuery nestedQuery = (ObjectLevelReadQuery)entry.getValue(); 629 if(nestedQuery.getJoinedAttributeManager().isToManyJoin()) { 630 ForeignReferenceMapping frMapping = (ForeignReferenceMapping)entry.getKey(); 631 Object indexObject = getJoinedMappingIndexes_().get(entry.getKey()); 632 List nestedDataResults = new ArrayList (dataResults.size()); 633 for(int i=0; i < dataResults.size(); i++) { 634 AbstractRecord row = (AbstractRecord)dataResults.get(i); 635 nestedDataResults.add(frMapping.trimRowForJoin(row, indexObject, session)); 636 } 637 nestedQuery.getJoinedAttributeManager().setDataResults(nestedDataResults, session); 638 } 639 } 640 } 641 } 642 643 648 public void setDescriptor (ClassDescriptor descriptor){ 649 this.descriptor = descriptor; 650 } 651 652 658 public ForUpdateOfClause setupLockingClauseForJoinedExpressions(ForUpdateOfClause lockingClause, AbstractSession session) { 659 if (hasJoinedAttributeExpressions()){ 660 setupLockingClauseForJoinedExpressions(getJoinedAttributeExpressions(), session); 661 } 662 if (hasJoinedMappingExpressions()){ 663 setupLockingClauseForJoinedExpressions(getJoinedMappingExpressions(), session); 664 } 665 return lockingClause; 666 } 667 668 674 private void setupLockingClauseForJoinedExpressions(List joinedExpressions, AbstractSession session) { 675 for (Iterator e = joinedExpressions.iterator(); e.hasNext();) { 678 Expression expression = (Expression)e.next(); 679 680 if (expression.isObjectExpression()) { 682 ObjectExpression joinedAttribute = (ObjectExpression)expression; 683 684 joinedAttribute.getBuilder().setSession(session); 686 joinedAttribute.getBuilder().setQueryClass(getDescriptor().getJavaClass()); 687 688 ClassDescriptor nestedDescriptor = null; 690 if (nestedDescriptor == null) { 692 return; 693 } 694 } 695 } 696 return; 697 } 698 699 public void setParentResultIndex(int parentsResultIndex) { 700 this.parentResultIndex = parentsResultIndex; 701 } 702 703 public int getParentResultIndex() { 704 return parentResultIndex; 705 } 706 } 707 | Popular Tags |