KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > queryframework > ReportQueryResult


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.queryframework;
23
24 import java.io.*;
25 import java.lang.reflect.Constructor JavaDoc;
26 import java.security.AccessController JavaDoc;
27 import java.security.PrivilegedActionException JavaDoc;
28 import java.util.*;
29
30 import oracle.toplink.essentials.exceptions.*;
31 import oracle.toplink.essentials.internal.helper.*;
32 import oracle.toplink.essentials.internal.queryframework.*;
33 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper;
34 import oracle.toplink.essentials.internal.security.PrivilegedGetConstructorFor;
35 import oracle.toplink.essentials.internal.security.PrivilegedInvokeConstructor;
36 import oracle.toplink.essentials.mappings.*;
37 import oracle.toplink.essentials.mappings.foundation.AbstractDirectMapping;
38 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
39 import oracle.toplink.essentials.sessions.DatabaseRecord;
40 import oracle.toplink.essentials.sessions.Session;
41
42 /**
43  * <b>Purpose</b>: A single row (type) result for a ReportQuery<p>
44  *
45  * <b>Description</b>: Represents a single row of attribute values (converted using mapping) for
46  * a ReportQuery. The attributes can be from various objects.
47  *
48  * <b>Responsibilities</b>:<ul>
49  * <li> Converted field values into object attribute values.
50  * <li> Provide acces to values by index or item name
51  * </ul>
52  *
53  * @author Doug Clarke
54  * @since TOPLink/Java 2.0
55  */

56 public class ReportQueryResult implements Serializable, Map {
57
58     /** Item names to lookup result values */
59     protected Vector names;
60
61     /** Actual converted attribute values */
62     protected Vector results;
63
64     /** PK values if the retrievPKs flag was set on the ReportQuery. These can be used to get the actual object */
65     protected Vector primaryKeyValues;
66     
67     /** If an objectLevel distinct is used then generate unique key for this result */
68     // GF_ISSUE_395
69
protected StringBuffer JavaDoc key;
70
71     /**
72      * INTERNAL:
73      * Used to create test results
74      */

75     public ReportQueryResult(Vector results, Vector primaryKeyValues) {
76         this.results = results;
77         this.primaryKeyValues = primaryKeyValues;
78     }
79
80     public ReportQueryResult(ReportQuery query, AbstractRecord row, Vector toManyResults) {
81         super();
82         this.names = query.getNames();
83         buildResult(query, row, toManyResults);
84     }
85
86     /**
87      * INTERNAL:
88      * Create an array of attribute values (converted from raw field values using the mapping).
89      */

90     protected void buildResult(ReportQuery query, AbstractRecord row, Vector toManyData) {
91         //GF_ISSUE_395
92
if (query.shouldDistinctBeUsed()){
93             this.key = new StringBuffer JavaDoc();
94         }
95         //end GF_ISSUE
96
int numberOfPrimaryKeyFields = 0;
97         Vector results = new Vector(query.getItems().size());
98
99         if (query.shouldRetrievePrimaryKeys()) {
100             numberOfPrimaryKeyFields = query.getDescriptor().getPrimaryKeyFields().size();
101             setPrimaryKeyValues(query.getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(row, query.getSession()));
102             // For bug 3115576 this is only used for EXISTS subselects so no result is needed.
103
} else if (query.shouldRetrieveFirstPrimaryKey()) {
104             numberOfPrimaryKeyFields = 1;
105         }
106
107         // CR 4240
108
// rowIndex is seperate as there may be place holders in the query that are not in the
109
// result set. So we can not compare the index to row size as there may be less
110
// objects in the row then there will be in the result set.
111

112         for (int index = 0; index < query.getItems().size(); index++) {
113             ReportItem item = (ReportItem)query.getItems().elementAt(index);
114             if (item.isContructorItem()){
115                 ConstructorReportItem citem = (ConstructorReportItem)item;
116                 Class JavaDoc[] constructorArgTypes = citem.getConstructorArgTypes();
117                 List constructorMappings = citem.getConstructorMappings();
118                 int numberOfItems = citem.getReportItems().size();
119                 Object JavaDoc[] constructorArgs = new Object JavaDoc[numberOfItems];
120                 if (constructorArgTypes==null){
121                     constructorArgTypes = new Class JavaDoc[numberOfItems];
122                 }
123                 
124                 for (int i=0;i<numberOfItems;i++){
125                     ReportItem ritem = (ReportItem)citem.getReportItems().get(i);
126                     if (constructorArgTypes[i]==null){
127                         if((constructorMappings != null)&&(constructorMappings.get(i)!=null)){
128                             constructorArgTypes[i] = ((DatabaseMapping)constructorMappings.get(i)).getAttributeClassification();
129                         }else if (ritem.getResultType() != null) {
130                             constructorArgTypes[i] = ritem.getResultType();
131                         }else if (ritem.getDescriptor() != null) {
132                             constructorArgTypes[i] = ritem.getDescriptor().getJavaClass();
133                         }
134                     }
135                     Object JavaDoc result = processItem(query, row, toManyData, (ReportItem)citem.getReportItems().get(i));
136                     constructorArgs[i] = ConversionManager.getDefaultManager().convertObject(result, constructorArgTypes[i]);
137                     //no type was specified, so use the object class itself.
138
if (constructorArgTypes[i]==null){
139                         constructorArgTypes[i] = constructorArgs[i].getClass();
140                     }
141                 }
142                 try{
143                     java.lang.reflect.Constructor JavaDoc constructor = null;
144                     Object JavaDoc returnValue = null;
145                     if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
146                         try {
147                             constructor = (Constructor JavaDoc)AccessController.doPrivileged(new PrivilegedGetConstructorFor(citem.getResultType(), constructorArgTypes, true));
148                             returnValue = AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, constructorArgs));
149                         } catch (PrivilegedActionException JavaDoc exception) {
150                             throw QueryException.exceptionWhileUsingConstructorExpression(exception.getException(), query); }
151                     } else {
152                         constructor = PrivilegedAccessHelper.getConstructorFor(citem.getResultType(), constructorArgTypes, true);
153                         returnValue = PrivilegedAccessHelper.invokeConstructor(constructor, constructorArgs);
154                     }
155                     results.addElement(returnValue);
156                 } catch (NoSuchMethodException JavaDoc exc){
157                     throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
158                 } catch (IllegalAccessException JavaDoc exc){
159                     throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
160                 } catch (java.lang.reflect.InvocationTargetException JavaDoc exc){
161                     throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
162                 } catch (InstantiationException JavaDoc exc){
163                     throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
164                 }
165                 
166             }else{
167                 Object JavaDoc value = processItem(query, row, toManyData, item);
168                 results.addElement(value);
169             }
170         }
171
172         setResults(results);
173     }
174     
175     /**
176      * INTERNAL:
177      * Return a value from an item and database row (converted from raw field values using the mapping).
178      */

179     protected Object JavaDoc processItem(ReportQuery query, AbstractRecord row, Vector toManyData, ReportItem item) {
180         JoinedAttributeManager joinManager = item.getJoinedAttributeManager();
181         if (joinManager.isToManyJoin()){
182                     joinManager.setDataResults(toManyData, query.getSession());
183         }
184         DatabaseMapping mapping = item.getMapping();
185         Object JavaDoc value = null;
186         if (!item.isPlaceHolder()) {
187             if (mapping != null){
188                 //if mapping is not null then it must be a direct mapping - see Reportitem.init
189
value = row.getValues().get(item.getResultIndex());
190                 value = ((AbstractDirectMapping)mapping).getAttributeValue(value, query.getSession());
191                 // GF_ISSUE_395
192
if (this.key != null){
193                     this.key.append(value);
194                     this.key.append("_");
195                 }
196                 // end GF_ISSUE
197
}else if (item.getDescriptor() != null){
198                 //item is for an object result.
199
if (item.getDescriptor().getAllFields().size() + item.getResultIndex() > row.size()) {
200                     throw QueryException.reportQueryResultSizeMismatch(item.getDescriptor().getAllFields().size() + item.getResultIndex(), row.size());
201                 }
202                 Vector trimedFields = Helper.copyVector(row.getFields(), item.getResultIndex(), row.size());
203                 Vector trimedValues = Helper.copyVector(row.getValues(), item.getResultIndex(), row.size());
204                 AbstractRecord subRow = new DatabaseRecord(trimedFields, trimedValues);
205                 value = item.getDescriptor().getObjectBuilder().buildObject(query, subRow, joinManager);
206                 // GF_ISSUE_395
207
if (this.key != null){
208                     List list = item.getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(subRow, query.getSession());
209                     for (Iterator iterator = list.iterator(); iterator.hasNext();){
210                         this.key.append(iterator.next());
211                         this.key.append("-");
212                     }
213                     this.key.append("_");
214                 }
215                 // end GF_ISSUE
216
}else{
217                 value = row.getValues().get(item.getResultIndex());
218                 // GF_ISSUE_395
219
if (this.key != null){
220                     this.key.append(value);
221                 }
222                 // end GF_ISSUE
223
}
224         }
225         return value;
226     }
227     
228
229     /**
230      * PUBLIC:
231      * Clear the contents of the result.
232      */

233     public void clear() {
234         this.names = new Vector();
235         this.results = new Vector();
236     }
237
238     /**
239      * PUBLIC:
240      * Check if the value is contained in the result.
241      */

242     public boolean contains(Object JavaDoc value) {
243         return containsValue(value);
244     }
245
246     /**
247      * PUBLIC:
248      * Check if the key is contained in the result.
249      */

250     public boolean containsKey(Object JavaDoc key) {
251         return getNames().contains(key);
252     }
253
254     /**
255      * PUBLIC:
256      * Check if the value is contained in the result.
257      */

258     public boolean containsValue(Object JavaDoc value) {
259         return getResults().contains(value);
260     }
261
262     /**
263      * PUBLIC:
264      * Return an enumeration of the result values.
265      */

266     public Enumeration elements() {
267         return getResults().elements();
268     }
269
270     /**
271      * PUBLIC:
272      * Returns a set of the keys.
273      */

274     public Set entrySet() {
275         // bug 2669127
276
// implemented this method exactly the same way as DatabaseRow.entrySet()
277
int size = this.size();
278         Map tempMap = new HashMap(size);
279         for (int i = 0; i < size; i++) {
280             tempMap.put(this.getNames().elementAt(i), this.getResults().elementAt(i));
281         }
282         return tempMap.entrySet();
283     }
284
285     /**
286      * PUBLIC:
287      * Compare if the two results are equal.
288      */

289     public boolean equals(Object JavaDoc anObject) {
290         if (anObject instanceof ReportQueryResult) {
291             return equals((ReportQueryResult)anObject);
292         }
293
294         return false;
295     }
296
297     /**
298      * INTERNAL:
299      * Used in testing to compare if results are correct.
300      */

301     public boolean equals(ReportQueryResult result) {
302         if (this == result) {
303             return true;
304         }
305         if (!Helper.compareOrderedVectors(getResults(), result.getResults())) {
306             return false;
307         }
308
309         // Compare PKs
310
if (getPrimaryKeyValues() != null) {
311             if (result.getPrimaryKeyValues() == null) {
312                 return false;
313             }
314             return Helper.compareOrderedVectors(getPrimaryKeyValues(), result.getPrimaryKeyValues());
315         }
316
317         return true;
318     }
319
320     /**
321      * PUBLIC:
322      * Return the value for given item name.
323      */

324     public Object JavaDoc get(Object JavaDoc name) {
325         if (name instanceof String JavaDoc) {
326             return get((String JavaDoc)name);
327         }
328
329         return null;
330     }
331
332     /**
333      * PUBLIC:
334      * Return the value for given item name.
335      */

336     public Object JavaDoc get(String JavaDoc name) {
337         int index = getNames().indexOf(name);
338         if (index == -1) {
339             return null;
340         }
341
342         return getResults().elementAt(index);
343     }
344
345     /**
346      * PUBLIC:
347      * Return the indexed value from result.
348      */

349     public Object JavaDoc getByIndex(int index) {
350         return getResults().elementAt(index);
351     }
352
353     /**
354      * INTERNAL:
355      * Return the unique key for this result
356      */

357     public String JavaDoc getResultKey(){
358         if (this.key != null){
359             return this.key.toString();
360         }
361         return null;
362     }
363      
364     
365     /**
366      * PUBLIC:
367      * Return the names of report items, provided to ReportQuery.
368      */

369     public Vector getNames() {
370         return names;
371     }
372
373     /**
374      * PUBLIC:
375      * Return the PKs for the corresponding object or null if not requested.
376      */

377     public Vector getPrimaryKeyValues() {
378         return primaryKeyValues;
379     }
380
381     /**
382      * PUBLIC:
383      * Return the results.
384      */

385     public Vector getResults() {
386         return results;
387     }
388
389     /**
390      * PUBLIC:
391      * Return if the result is empty.
392      */

393     public boolean isEmpty() {
394         return getNames().isEmpty();
395     }
396
397     /**
398      * PUBLIC:
399      * Return an enumeration of the result names.
400      */

401     public Enumeration keys() {
402         return getNames().elements();
403     }
404
405     /**
406      * PUBLIC:
407      * Returns a set of the keys.
408      */

409     public Set keySet() {
410         return new HashSet(getNames());
411     }
412
413     /**
414      * ADVANCED:
415      * Set the value for given item name.
416      */

417     public Object JavaDoc put(Object JavaDoc name, Object JavaDoc value) {
418         int index = getNames().indexOf(name);
419         if (index == -1) {
420             getNames().addElement(name);
421             getResults().addElement(value);
422             return null;
423         }
424
425         Object JavaDoc oldValue = getResults().elementAt(index);
426         getResults().setElementAt(value, index);
427         return oldValue;
428     }
429
430     /**
431      * PUBLIC:
432      * Add all of the elements.
433      */

434     public void putAll(Map map) {
435         Iterator entriesIterator = map.entrySet().iterator();
436         while (entriesIterator.hasNext()) {
437             Map.Entry entry = (Map.Entry)entriesIterator.next();
438             put(entry.getKey(), entry.getValue());
439         }
440     }
441
442     /**
443      * PUBLIC:
444      * If the PKs were retrieved with the attributes then this method can be used to read the real object from the database.
445      */

446     public Object JavaDoc readObject(Class JavaDoc javaClass, Session session) {
447         if (getPrimaryKeyValues() == null) {
448             throw QueryException.reportQueryResultWithoutPKs(this);
449         }
450
451         ReadObjectQuery query = new ReadObjectQuery(javaClass);
452         query.setSelectionKey(getPrimaryKeyValues());
453
454         return session.executeQuery(query);
455     }
456
457     /**
458      * INTERNAL:
459      * Remove the name key and value from the result.
460      */

461     public Object JavaDoc remove(Object JavaDoc name) {
462         int index = getNames().indexOf(name);
463         if (index >= 0) {
464             getNames().removeElementAt(index);
465             Object JavaDoc value = getResults().elementAt(index);
466             getResults().removeElementAt(index);
467             return value;
468         }
469         return null;
470     }
471
472     protected void setNames(Vector names) {
473         this.names = names;
474     }
475
476     /**
477      * INTERNAL:
478      * Set the PK values for the result row's object.
479      */

480     protected void setPrimaryKeyValues(Vector primaryKeyValues) {
481         this.primaryKeyValues = primaryKeyValues;
482     }
483
484     /**
485      * INTERNAL:
486      * Set the results.
487      */

488     public void setResults(Vector results) {
489         this.results = results;
490     }
491
492     /**
493      * PUBLIC:
494      * Return the number of name/value pairs in the result.
495      */

496     public int size() {
497         return getNames().size();
498     }
499
500     /**
501      * INTERNAL:
502      * Converts the ReportQueryResult to a simple array of values.
503      */

504     public Object JavaDoc[] toArray(){
505        List list = getResults();
506        return (list == null) ? null : list.toArray();
507     }
508
509     /**
510      * INTERNAL:
511      * Converts the ReportQueryResult to a simple list of values.
512      */

513     public List toList(){
514         return this.getResults();
515     }
516     
517     public String JavaDoc toString() {
518         java.io.StringWriter JavaDoc writer = new java.io.StringWriter JavaDoc();
519         writer.write("ReportQueryResult(");
520         for (int index = 0; index < getResults().size(); index++) {
521             writer.write(String.valueOf(getResults().elementAt(index)));
522             if (index < (getResults().size() - 1)) {
523                 writer.write(", ");
524             }
525         }
526         writer.write(")");
527         return writer.toString();
528     }
529
530     /**
531      * PUBLIC:
532      * Returns an collection of the values.
533      */

534     public Collection values() {
535         return getResults();
536     }
537 }
538
Popular Tags