KickJava   Java API By Example, From Geeks To Geeks.

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


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.security.AccessController JavaDoc;
25 import java.security.PrivilegedActionException JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import oracle.toplink.essentials.exceptions.QueryException;
31 import oracle.toplink.essentials.internal.helper.DatabaseField;
32 import oracle.toplink.essentials.internal.localization.ExceptionLocalization;
33 import oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager;
34 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper;
35 import oracle.toplink.essentials.internal.security.PrivilegedClassForName;
36 import oracle.toplink.essentials.mappings.DatabaseMapping;
37 import oracle.toplink.essentials.descriptors.ClassDescriptor;
38 import oracle.toplink.essentials.exceptions.ValidationException;
39 import oracle.toplink.essentials.expressions.ExpressionBuilder;
40 import oracle.toplink.essentials.mappings.OneToOneMapping;
41 import oracle.toplink.essentials.sessions.DatabaseRecord;
42
43 /**
44  * <p><b>Purpose</b>:
45  * Concrete class to represent the EntityResult structure as defined by
46  * the EJB 3.0 Persistence specification. This class is a subcompent of the
47  * SQLResultSetMapping
48  *
49  * @see SQLResultSetMapping
50  * @author Gordon Yorke
51  * @since TopLink Java Essentials
52  */

53
54 public class EntityResult extends SQLResult {
55     /** Stores the class name of result */
56     protected String JavaDoc entityClassName;
57     protected Class JavaDoc entityClass;
58     
59     /** Stores the list of FieldResult */
60     protected Map JavaDoc fieldResults;
61     
62     /** Stores the column that will contain the value to determine the correct subclass
63      * to create if applicable.
64      */

65     protected String JavaDoc discriminatorColumn;
66     
67     public EntityResult(Class JavaDoc entityClass){
68         this.entityClass = entityClass;
69         if (this.entityClass == null){
70             throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("null_value_for_entity_result"));
71         }
72     }
73     
74     public EntityResult(String JavaDoc entityClassName){
75         this.entityClassName = entityClassName;
76         if (this.entityClassName == null){
77             throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("null_value_for_entity_result"));
78         }
79     }
80     
81     public void addFieldResult(FieldResult fieldResult){
82         if (fieldResult == null || fieldResult.getAttributeName() == null){
83             return;
84         }
85         FieldResult existingFieldResult = (FieldResult)getFieldResults().get(fieldResult.getAttributeName());
86         if (existingFieldResult==null){
87             getFieldResults().put(fieldResult.getAttributeName(), fieldResult);
88         }else{
89             existingFieldResult.add(fieldResult);
90         }
91     }
92     
93     /**
94      * INTERNAL:
95      * Convert all the class-name-based settings in this query to actual class-based
96      * settings. This method is used when converting a project that has been built
97      * with class names to a project with classes.
98      * @param classLoader
99      */

100     public void convertClassNamesToClasses(ClassLoader JavaDoc classLoader){
101         super.convertClassNamesToClasses(classLoader);
102         Class JavaDoc entityClass = null;
103         try{
104             if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
105                 try {
106                     entityClass = (Class JavaDoc)AccessController.doPrivileged(new PrivilegedClassForName(entityClassName, true, classLoader));
107                 } catch (PrivilegedActionException JavaDoc exception) {
108                     throw ValidationException.classNotFoundWhileConvertingClassNames(entityClassName, exception.getException());
109                 }
110             } else {
111                 entityClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(entityClassName, true, classLoader);
112             }
113         } catch (ClassNotFoundException JavaDoc exc){
114             throw ValidationException.classNotFoundWhileConvertingClassNames(entityClassName, exc);
115         }
116         this.entityClass = entityClass;
117     };
118
119     /**
120      * Accessor for the internally stored list of FieldResult. Calling this
121      * method will result in a collection being created to store the FieldResult
122      */

123     public Map JavaDoc getFieldResults(){
124         if (this.fieldResults == null){
125             this.fieldResults = new HashMap JavaDoc();
126         }
127         return this.fieldResults;
128     }
129     
130     /**
131      * Returns the column name for the column that will store the value used to
132      * determine the subclass type if applicable.
133      */

134     public String JavaDoc getDiscriminatorColumn(){
135         return this.discriminatorColumn;
136     }
137
138     /**
139      * Sets the column name for the column that will store the value used to
140      * determine the subclass type if applicable.
141      */

142     public void setDiscriminatorColumn(String JavaDoc column){
143         if (column == null){
144             return;
145         }
146         this.discriminatorColumn = column;
147     }
148
149     /**
150      * INTERNAL:
151      * This method is a convience method for extracting values from Results
152      */

153     public Object JavaDoc getValueFromRecord(DatabaseRecord record, ResultSetMappingQuery query){
154         //from the row data build result entity.
155
// To do this let's collect the column based data for this entity from
156
// the results and call build object with this new row.
157
ClassDescriptor descriptor = query.getSession().getDescriptor(this.entityClass);
158         DatabaseRecord entityRecord = new DatabaseRecord(descriptor.getFields().size());
159         if (descriptor.hasInheritance()){
160             if (this.discriminatorColumn != null){
161                 Object JavaDoc value = record.get(this.discriminatorColumn);
162                 if (value == null){
163                     throw QueryException.discriminatorColumnNotSelected(this.discriminatorColumn, query.getSQLResultSetMapping().getName());
164                 }
165                 entityRecord.put(descriptor.getInheritancePolicy().getClassIndicatorField(), record.get(this.discriminatorColumn));
166             }else{
167                 entityRecord.put(descriptor.getInheritancePolicy().getClassIndicatorField(), record.get(descriptor.getInheritancePolicy().getClassIndicatorField()));
168             }
169             // if the descriptor uses inheritance and multiple types may have been read
170
//get the correct descriptor.
171
if (descriptor.hasInheritance() && descriptor.getInheritancePolicy().shouldReadSubclasses()) {
172                 Class JavaDoc classValue = descriptor.getInheritancePolicy().classFromRow(entityRecord, query.getSession());
173                 descriptor = query.getSession().getDescriptor(classValue);
174             }
175         }
176         for (Iterator JavaDoc mappings = descriptor.getMappings().iterator(); mappings.hasNext();){
177             DatabaseMapping mapping = (DatabaseMapping)mappings.next();
178             FieldResult fieldResult = (FieldResult)this.getFieldResults().get(mapping.getAttributeName());
179             if (fieldResult != null){
180                 if (mapping.getFields().size() == 1 ){
181                     entityRecord.put(mapping.getFields().firstElement(), record.get(fieldResult.getColumnName()));
182                 }else if (mapping.getFields().size() >1){
183                     getValueFromRecordForMapping(entityRecord,mapping,fieldResult,record);
184                 }
185             }else{
186                 for (Iterator JavaDoc fields = mapping.getFields().iterator(); fields.hasNext();){
187                     DatabaseField field = (DatabaseField)fields.next();
188                     entityRecord.put(field, record.get(field));
189                 }
190             }
191         }
192         query.setReferenceClass(this.entityClass);
193         query.setDescriptor(descriptor);
194         return descriptor.getObjectBuilder().buildObject(query, entityRecord, new JoinedAttributeManager(descriptor, (ExpressionBuilder)null, query));
195     }
196
197     public boolean isEntityResult(){
198         return true;
199     }
200     
201     /**
202      * INTERNAL:
203      * This method is for processing all FieldResults for a mapping. Adds DatabaseFields to the passed in entityRecord
204      */

205     public void getValueFromRecordForMapping(DatabaseRecord entityRecord,DatabaseMapping mapping, FieldResult fieldResult, DatabaseRecord databaseRecord){
206         ClassDescriptor currentDescriptor = mapping.getReferenceDescriptor();
207         /** check if this FieldResult contains any other FieldResults, process it if it doesn't */
208         if (fieldResult.getFieldResults()==null){
209             DatabaseField dbfield = processValueFromRecordForMapping(currentDescriptor,fieldResult.getMultipleFieldIdentifiers(),1);
210             /** If it is a 1:1 mapping we need to do the target to source field conversion. If it is an aggregate, it is fine as it is*/
211             if (mapping.isOneToOneMapping()){
212                 dbfield = (DatabaseField)(((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(dbfield));
213             }
214             entityRecord.put(dbfield, databaseRecord.get(fieldResult.getColumnName()));
215             return;
216         }
217         /** This processes each FieldResult stored in the collection of FieldResults individually */
218         Iterator JavaDoc fieldResults = fieldResult.getFieldResults().iterator();
219         while (fieldResults.hasNext()){
220             FieldResult tempFieldResult = ((FieldResult)fieldResults.next());
221             DatabaseField dbfield = processValueFromRecordForMapping(currentDescriptor,tempFieldResult.getMultipleFieldIdentifiers(),1);
222              if (mapping.isOneToOneMapping()){
223                 dbfield = (DatabaseField)(((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(dbfield));
224             }
225             entityRecord.put(dbfield, databaseRecord.get(tempFieldResult.getColumnName()));
226         }
227     }
228     
229     /**
230      * INTERNAL:
231      * This method is for processing a single FieldResult, returning the DatabaseField it refers to.
232      */

233     public DatabaseField processValueFromRecordForMapping(ClassDescriptor descriptor, String JavaDoc[] attributeNames, int currentLoc){
234         DatabaseMapping mapping = descriptor.getMappingForAttributeName(attributeNames[currentLoc]);
235         if (mapping==null){throw QueryException.mappingForFieldResultNotFound(attributeNames,currentLoc);}
236         currentLoc++;
237         if (attributeNames.length!=currentLoc){
238             ClassDescriptor currentDescriptor = mapping.getReferenceDescriptor();
239             DatabaseField df= processValueFromRecordForMapping(currentDescriptor, attributeNames, currentLoc);
240             if (mapping.isOneToOneMapping()){
241                 return (DatabaseField)(((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(df));
242             }
243             return df;
244         }else{
245             //this is it.. return this mapping's field
246
return (DatabaseField) mapping.getFields().firstElement();
247         }
248     }
249     
250 }
251
Popular Tags