KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > queryframework > JoinedAttributeManager


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.queryframework;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.List JavaDoc;
26 import oracle.toplink.essentials.expressions.Expression;
27 import java.util.Map JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Vector JavaDoc;
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 JavaDoc;
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 /**
46  * <p><b>Purpose</b>:
47  * A common class to be used by ObjectLevelReadQueries and ReportItems. This
48  * Class will be used to store Joined Attribute Expressions. It will also
49  * store the indexes for object construction.
50  *
51  * @author Gordon Yorke
52  * @since EJB3.0 RI
53  */

54
55 public class JoinedAttributeManager implements Cloneable JavaDoc{
56
57     /** Stores the joined attributes added through the query */
58     protected ArrayList JavaDoc joinedAttributeExpressions_;
59     
60     /** Stores the joined attributes as specified in the descriptor */
61     protected ArrayList JavaDoc joinedMappingExpressions_;
62     
63     /** PERF: Cache the local joined attribute names. */
64     protected ArrayList JavaDoc joinedAttributes_;
65     
66     /** Used to determine if -m joining has been used. */
67     protected boolean isToManyJoin = false;
68
69     /** PERF: Used to avoid null checks for inner attribute joining. */
70     protected boolean hasOuterJoinedAttribute = true;
71     
72     /** Used internally for joining. */
73     protected transient HashMap JavaDoc joinedMappingIndexes_;
74
75     /** Used internally for joining. */
76     protected transient HashMap JavaDoc joinedMappingQueries_;
77
78     /** Stored all row results to -m joining. */
79     protected List JavaDoc dataResults;
80     
81     /** Stores the descriptor that these joins apply on */
82     protected ClassDescriptor descriptor;
83     
84     /** Stores the base builder for resolving joined attributes by name */
85     protected ExpressionBuilder baseExpressionBuilder;
86     
87     /** Stores the baseQuery */
88     protected ObjectBuildingQuery baseQuery;
89     
90     /** Stores the result index of the parent, used for oneToMany joins */
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     /**
104      * INTERNAL:
105      */

106     public void addJoinedAttribute(String JavaDoc attributeExpression) {
107         this.getJoinedAttributes().add(attributeExpression);
108     }
109
110     /**
111      * INTERNAL:
112      */

113     public void addJoinedAttributeExpression(Expression attributeExpression) {
114         getJoinedAttributeExpressions().add(attributeExpression);
115     }
116     
117     /**
118     * INTERNAL:
119     * Add an attribute represented by the given attribute name to the list of joins
120     * for this query.
121     * Note: Mapping level joins are represented separately from query level joins
122     */

123     public void addJoinedMappingExpression(Expression mappingExpression) {
124         getJoinedMappingExpressions().add(mappingExpression);
125     }
126
127     /**
128      * INTERNAL:
129      * Add an attribute represented by the given attribute name to the list of joins
130      * for this query.
131      * Note: Mapping level joins are represented separately from query level joins
132      */

133     public void addJoinedMapping(String JavaDoc attributeName) {
134         addJoinedMappingExpression(this.baseExpressionBuilder.get(attributeName));
135     }
136
137
138     /**
139      * INTERNAL:
140      * Clones the Joined Attribute Manager. Generally called from Query.clone()
141      */

142     public Object JavaDoc 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 JavaDoc)this.joinedAttributeExpressions_.clone();
149         }
150         if (this.joinedMappingExpressions_ != null){
151             joinManager.joinedMappingExpressions_ = (ArrayList JavaDoc)this.joinedMappingExpressions_.clone();
152         }
153         if (this.joinedAttributes_ != null){
154             joinManager.joinedAttributes_ = (ArrayList JavaDoc)this.joinedAttributes_.clone();
155         }
156         if (this.joinedMappingIndexes_ != null){
157             joinManager.joinedMappingIndexes_ = (HashMap JavaDoc)this.joinedMappingIndexes_.clone();
158         }
159         if (this.joinedMappingQueries_ != null){
160             joinManager.joinedMappingQueries_ = (HashMap JavaDoc)this.joinedMappingQueries_.clone();
161         }
162         joinManager.isToManyJoin = this.isToManyJoin;
163         joinManager.hasOuterJoinedAttribute = this.hasOuterJoinedAttribute;
164         return joinManager;
165         
166     }
167
168     /**
169      * INTERNAL:
170      * For joining the resulting rows include the field/values for many objects.
171      * As some of the objects may have the same field names, these row partitions need to be calculated.
172      * The indexes are stored in the query and used later when building the objects.
173      */

174     public int computeJoiningMappingIndexes(boolean includeAllSubclassFields, AbstractSession session, int offset) {
175         if (!hasJoinedExpressions()) {
176             return offset;
177         }
178         setJoinedMappingIndexes_(new HashMap JavaDoc(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     /**
192      * INTERNAL:
193      * This method is used when computing the nested queries for joined mappings.
194      * It recurses computing the nested mapping queries and their join indexes.
195      */

196     protected void computeNestedQueriesForJoinedExpressions(List JavaDoc joinedExpressions, AbstractSession session, ObjectLevelReadQuery readQuery) {
197         for (int index = 0; index < joinedExpressions.size(); index++) {
198             ObjectExpression objectExpression = (ObjectExpression)joinedExpressions.get(index);
199
200             // Expression may not have been initialized.
201
objectExpression.getBuilder().setSession(session);
202             objectExpression.getBuilder().setQueryClass(getDescriptor().getJavaClass());
203             
204             // PERF: Cache join attribute names.
205
ObjectExpression baseExpression = objectExpression;
206             while (!baseExpression.getBaseExpression().isExpressionBuilder()) {
207                 baseExpression = (ObjectExpression)((QueryKeyExpression)baseExpression).getBaseExpression();
208             }
209             this.addJoinedAttribute(baseExpression.getName());
210             
211             // Ignore nested
212
if ((objectExpression.getBaseExpression() == objectExpression.getBuilder()) && objectExpression.getMapping().isForeignReferenceMapping()) {
213                 ForeignReferenceMapping mapping = (ForeignReferenceMapping)objectExpression.getMapping();
214
215                 // A nested query must be built to pass to the descriptor that looks like the real query execution would.
216
ObjectLevelReadQuery nestedQuery = mapping.prepareNestedJoins(this, session);
217
218                 // Register the nested query to be used by the mapping for all the objects.
219
getJoinedMappingQueries_().put(mapping, nestedQuery);
220             }
221         }
222     }
223
224     /**
225      * INTERNAL:
226      * Used to optimize joining by pre-computing the nested join queries for the mappings.
227      */

228     public void computeJoiningMappingQueries(AbstractSession session) {
229         if (hasJoinedExpressions()) {
230             this.joinedAttributes_ = new ArrayList JavaDoc(getJoinedAttributeExpressions().size() + getJoinedMappingExpressions().size());
231             setJoinedMappingQueries_(new HashMap JavaDoc(getJoinedAttributeExpressions().size() + getJoinedMappingExpressions().size()));
232             computeNestedQueriesForJoinedExpressions(getJoinedAttributeExpressions(), session, (ObjectLevelReadQuery)this.baseQuery);
233             computeNestedQueriesForJoinedExpressions(getJoinedMappingExpressions(), session, (ObjectLevelReadQuery)this.baseQuery);
234         }
235     }
236
237     /**
238      * INTERNAL:
239      * This method is used when computing the indexes for joined mappings.
240      * It iterates through a list of join expressions and adds an index that represents where the
241      * fields represented by that expression will appear in the row returned by a read query.
242      *
243      * @see #computeJoiningMappingIndexes(boolean, AbstractSession)
244      */

245     protected int computeIndexesForJoinedExpressions(List JavaDoc joinedExpressions, int currentIndex, AbstractSession session) {
246         for (int index = 0; index < joinedExpressions.size(); index++) {
247             ObjectExpression objectExpression = (ObjectExpression)joinedExpressions.get(index);
248
249             // Ignore nested
250
if ((objectExpression.getBaseExpression() == objectExpression.getBuilder()) && objectExpression.getMapping() != null && objectExpression.getMapping().isForeignReferenceMapping()) {
251                 getJoinedMappingIndexes_().put(objectExpression.getMapping(), new Integer JavaDoc(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     /**
266      * INTERNAL:
267      * Returns the base expression builder for this query.
268      */

269     public ExpressionBuilder getBaseExpressionBuilder(){
270         return this.baseExpressionBuilder;
271     }
272     
273     /**
274      * INTERNAL:
275      * Returns the base query.
276      */

277     public ObjectBuildingQuery getBaseQuery(){
278         return this.baseQuery;
279     }
280     
281     /**
282      * INTERNAL:
283      * Return all of the rows fetched by the query, used for 1-m joining.
284      */

285     public List JavaDoc getDataResults_() {
286         return dataResults;
287     }
288
289     /**
290      * INTERNAL:
291      */

292     public ClassDescriptor getDescriptor(){
293         return this.descriptor;
294     }
295     
296     /**
297      * INTERNAL:
298      * Return the attributes that must be joined.
299      */

300     public List JavaDoc getJoinedAttributes() {
301         if (this.joinedAttributes_ == null){
302             this.joinedAttributes_ = new ArrayList JavaDoc();
303         }
304         return this.joinedAttributes_;
305     }
306     
307     /**
308      * INTERNAL:
309      * Return the attributes that must be joined.
310      */

311     public List JavaDoc getJoinedAttributeExpressions() {
312         if (this.joinedAttributeExpressions_ == null){
313             this.joinedAttributeExpressions_ = new ArrayList JavaDoc();
314         }
315         return joinedAttributeExpressions_;
316     }
317     
318     /**
319      * INTERNAL:
320      * Get the list of expressions that represent elements that are joined because of their
321      * mapping for this query.
322      */

323     public List JavaDoc getJoinedMappingExpressions() {
324         if (this.joinedMappingExpressions_ == null){
325             this.joinedMappingExpressions_ = new ArrayList JavaDoc();
326         }
327         return joinedMappingExpressions_;
328     }
329
330     /**
331      * INTERNAL:
332      * Return the attributes that must be joined.
333      */

334     public boolean hasJoinedAttributeExpressions() {
335         return this.joinedAttributeExpressions_ != null && !this.joinedAttributeExpressions_.isEmpty();
336     }
337
338     /**
339      * INTERNAL:
340      * THis methos checks bot attribute expressions and mapping expressions and
341      * determines if there are any joins to be made
342      */

343     public boolean hasJoinedExpressions() {
344         return hasJoinedAttributeExpressions() || hasJoinedMappingExpressions();
345     }
346     
347     /**
348      * INTERNAL:
349      * Return the attributes that must be joined.
350      */

351     public boolean hasJoinedMappingExpressions() {
352         return this.joinedMappingExpressions_ != null && !this.joinedMappingExpressions_.isEmpty();
353     }
354
355     /**
356      * INTERNAL:
357      * Return if any attributes are joined. This is a convience method that
358      * is only valid after prepare.
359      */

360     public boolean hasJoinedAttributes() {
361         return this.joinedAttributes_ != null && !this.joinedAttributes_.isEmpty();
362     }
363
364     /**
365      * INTERNAL:
366      * PERF: Return if the query uses any outer attribute joins, used to avoid null checks in building objects.
367      */

368     public boolean hasOuterJoinedAttributeQuery() {
369         return this.hasOuterJoinedAttribute;
370     }
371
372     /**
373      * INTERNAL:
374      * Return if the query uses any -m joins, and thus return duplicate/multiple rows.
375      */

376     public boolean isToManyJoin() {
377         return this.isToManyJoin;
378     }
379     
380     /**
381      * INTERNAL:
382      * Return if the attribute is specified for joining.
383      */

384     public boolean isAttributeJoined(ClassDescriptor mappingDescriptor, String JavaDoc attributeName) {
385         // Since aggregates share the same query as their parent, must avoid the aggregate thinking
386
// the parents mappings is for it, (queries only share if the aggregate was not joined).
387
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     /**
397      * Iterate through a list of expressions searching for the given attribute name.
398      * Return true if it is found, false otherwise.
399      */

400     protected boolean isAttributeNameInJoinedExpressionList(String JavaDoc attributeName, List JavaDoc joinedExpressionList) {
401         for (Iterator JavaDoc 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     /**
414      * INTERNAL:
415      * Return if the attribute is specified for joining.
416      */

417     protected boolean isAttributeExpressionJoined(String JavaDoc attributeName) {
418         return isAttributeNameInJoinedExpressionList(attributeName, getJoinedAttributeExpressions());
419     }
420
421     /**
422      * INTERNAL:
423      * Return whether the given attribute is joined as a result of a join on a mapping
424      */

425     protected boolean isAttributeMappingJoined(String JavaDoc attributeName) {
426         return isAttributeNameInJoinedExpressionList(attributeName, getJoinedMappingExpressions());
427     }
428
429     /**
430      * INTERNAL:
431      * Set the list of expressions that represent elements that are joined because of their
432      * mapping for this query.
433      */

434     public void setJoinedAttributeExpressions_(List JavaDoc joinedExpressions) {
435         this.joinedAttributeExpressions_ = new ArrayList JavaDoc(joinedExpressions);
436     }
437
438     /**
439      * INTERNAL:
440      * Set the list of expressions that represent elements that are joined because of their
441      * mapping for this query.
442      */

443     public void setJoinedMappingExpressions_(List JavaDoc joinedMappingExpressions) {
444         this.joinedMappingExpressions_ = new ArrayList JavaDoc(joinedMappingExpressions);
445     }
446
447     /**
448      * INTERNAL:
449      * Return the joined mapping indexes, used to compute mapping row partitions.
450      */

451     public Map JavaDoc getJoinedMappingIndexes_() {
452         return joinedMappingIndexes_;
453     }
454
455     /**
456      * INTERNAL:
457      * Return the joined mapping queries, used optimize joining, only compute the nested queries once.
458      */

459     public Map JavaDoc getJoinedMappingQueries_() {
460         return joinedMappingQueries_;
461     }
462
463     /**
464      * INTERNAL:
465      * Set the joined mapping queries, used optimize joining, only compute the nested queries once.
466      */

467     protected void setJoinedMappingQueries_(HashMap JavaDoc joinedMappingQueries) {
468         this.joinedMappingQueries_ = joinedMappingQueries;
469     }
470
471     /**
472      * INTERNAL:
473      * Set the joined mapping indexes, used to compute mapping row partitions.
474      */

475     public void setJoinedMappingIndexes_(HashMap JavaDoc joinedMappingIndexes) {
476         this.joinedMappingIndexes_ = joinedMappingIndexes;
477     }
478
479     /**
480      * INTERNAL:
481      * Set the attributes that must be joined.
482      */

483 /* public void setJoinedAttributeExpressions(List joinedAttributeExpressions) {
484         this.joinedAttributeExpressions = joinedAttributeExpressions;
485         setIsPrePrepared(false);
486     }
487 */

488     /**
489      * INTERNAL:
490      * PERF: Set if the query uses any outer attribute joins, used to avoid null checks in building objects.
491      */

492     protected void setIsOuterJoinedAttributeQuery(boolean isOuterJoinedAttribute) {
493         this.hasOuterJoinedAttribute = isOuterJoinedAttribute;
494     }
495     
496     /**
497      * INTERNAL:
498      * Set if the query uses any -m joins, and thus return duplicate/multiple rows.
499      */

500     protected void setIsToManyJoinQuery(boolean isToManyJoin) {
501         this.isToManyJoin = isToManyJoin;
502     }
503     
504
505     /**
506      * INTERNAL:
507      * Validate and prepare join expressions.
508      */

509     public void prepareJoinExpressions(AbstractSession session) {
510         // The prepareJoinExpression check for outer-joins to set this to true.
511
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     /**
530      * Validate and prepare the join expression.
531      */

532     protected void prepareJoinExpression(Expression expression, AbstractSession session) {
533         // Must be query key expression.
534
if (!expression.isQueryKeyExpression()) {
535             throw QueryException.mappingForExpressionDoesNotSupportJoining(expression);
536         }
537         QueryKeyExpression objectExpression = (QueryKeyExpression)expression;
538
539         // Expression may not have been initialized.
540
objectExpression.getBuilder().setSession(session);
541         if (objectExpression.getBuilder().getQueryClass() == null){
542             objectExpression.getBuilder().setQueryClass(this.descriptor.getJavaClass());
543         }
544         // Can only join relationships.
545
if ((objectExpression.getMapping() == null) || (!objectExpression.getMapping().isJoiningSupported())) {
546             throw QueryException.mappingForExpressionDoesNotSupportJoining(objectExpression);
547         }
548
549         // Search if any of the expression traverse a 1-m.
550
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     /**
563      * INTERNAL:
564      * This method collects the Joined Mappings from the descriptor and initializes
565      * them
566      */

567     public void processJoinedMappings(){
568         ObjectBuilder objectBuilder = getDescriptor().getObjectBuilder();
569         if (objectBuilder.hasJoinedAttributes()) {
570             Vector JavaDoc mappingJoinedAttributes = objectBuilder.getJoinedAttributes();
571             if (!hasJoinedExpressions()) {
572                 for (int i = 0; i < mappingJoinedAttributes.size(); i++) {
573                     addJoinedMapping((String JavaDoc)mappingJoinedAttributes.get(i));
574                 }
575             } else {
576                 for (int i = 0; i < mappingJoinedAttributes.size(); i++) {
577                     String JavaDoc attribute = (String JavaDoc)mappingJoinedAttributes.get(i);
578                     if (!isAttributeExpressionJoined(attribute)) {
579                         addJoinedMapping(attribute);
580                     }
581                 }
582             }
583         }
584     }
585     
586     /**
587      * INTERNAL:
588      * Reset the JoinedAttributeManager. This will be called when the Query is re-prepared
589      */

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     /**
601      * INTERNAL:
602      * This method is called from within this package it is used when
603      * initializing a report Item
604      */

605     public void setBaseQuery(ObjectLevelReadQuery query){
606         this.baseQuery = query;
607     }
608     
609     /**
610      * INTERNAL:
611      * This method is called from within this package, it is used when
612      * initializing a ReportItem
613      */

614     protected void setBaseExpressionBuilder(ExpressionBuilder builder){
615         this.baseExpressionBuilder = builder;
616     }
617     
618     /**
619      * INTERNAL:
620      * Set all of the rows fetched by the query, used for 1-m joining.
621      */

622     public void setDataResults(List JavaDoc dataResults, AbstractSession session) {
623         this.dataResults = dataResults;
624         if(getJoinedMappingQueries_() != null && !getJoinedMappingQueries_().isEmpty() && dataResults != null && !dataResults.isEmpty()) {
625             Iterator JavaDoc it = getJoinedMappingQueries_().entrySet().iterator();
626             while(it.hasNext()) {
627                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
628                 ObjectLevelReadQuery nestedQuery = (ObjectLevelReadQuery)entry.getValue();
629                 if(nestedQuery.getJoinedAttributeManager().isToManyJoin()) {
630                     ForeignReferenceMapping frMapping = (ForeignReferenceMapping)entry.getKey();
631                     Object JavaDoc indexObject = getJoinedMappingIndexes_().get(entry.getKey());
632                     List JavaDoc nestedDataResults = new ArrayList JavaDoc(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     /**
644      * INTERNAL:
645      * Called to set the descriptor on a Join Managerwith in a ReportItem, durring
646      * initialization, and durring DatabaseQuery.checkDescriptor
647      */

648     public void setDescriptor (ClassDescriptor descriptor){
649         this.descriptor = descriptor;
650     }
651     
652     /**
653      * INTERNAL:
654      * Used for joining in conjunction with pessimistic locking
655      * Iterate through a list of joined expressions and ensure expression is set on the locking
656      * clause for each expression that represents a pessimisically locked descriptor.
657      */

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     /**
669      * INTERNAL:
670      * Used for joining in conjunction with pessimistic locking
671      * Iterate through a list of joined expressions and ensure expression is set on the locking
672      * clause for each expression that represents a pessimisically locked descriptor.
673      */

674     private void setupLockingClauseForJoinedExpressions(List JavaDoc joinedExpressions, AbstractSession session) {
675         // Must iterate over all of the joined attributes, just check
676
// if any of them have pessimistic locking defined on the descriptor.
677
for (Iterator JavaDoc e = joinedExpressions.iterator(); e.hasNext();) {
678             Expression expression = (Expression)e.next();
679
680             // Expression has not yet been validated.
681
if (expression.isObjectExpression()) {
682                 ObjectExpression joinedAttribute = (ObjectExpression)expression;
683
684                 // Expression may not have been initialized.
685
joinedAttribute.getBuilder().setSession(session);
686                 joinedAttribute.getBuilder().setQueryClass(getDescriptor().getJavaClass());
687
688                 ClassDescriptor nestedDescriptor = null;// joinedAttribute.getDescriptor();
689

690                 // expression may not be valid, no descriptor, validation occurs later.
691
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