KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > expressions > FieldExpression


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
22 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
23
package oracle.toplink.essentials.internal.expressions;
24
25 import java.util.*;
26 import java.io.*;
27 import oracle.toplink.essentials.exceptions.*;
28 import oracle.toplink.essentials.mappings.*;
29 import oracle.toplink.essentials.queryframework.*;
30 import oracle.toplink.essentials.internal.helper.*;
31 import oracle.toplink.essentials.expressions.*;
32 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
33 import oracle.toplink.essentials.internal.sessions.AbstractSession;
34
35 /**
36  * Field expressions represent a field of a table.
37  * Their base is either a table or object expression.
38  * This is used for mapping queries and to allow queries on non-mapped field or tables.
39  */

40 public class FieldExpression extends DataExpression {
41     protected DatabaseField field;
42     protected transient DatabaseField aliasedField;
43
44     /**
45      * FieldExpression constructor comment.
46      */

47     public FieldExpression() {
48         super();
49     }
50
51     /**
52      * FieldExpression constructor comment.
53      */

54     public FieldExpression(DatabaseField newField) {
55         super();
56         field = newField;
57     }
58
59     /**
60      * FieldExpression constructor comment.
61      */

62     public FieldExpression(DatabaseField newField, Expression myBase) {
63         super();
64         field = newField;
65         baseExpression = myBase;
66     }
67
68     /**
69      * INTERNAL:
70      */

71     public void clearAliases() {
72         super.clearAliases();
73         aliasedField = null;
74     }
75
76     /**
77      * INTERNAL:
78      * Used for debug printing.
79      */

80     public String JavaDoc descriptionOfNodeType() {
81         return "Field";
82     }
83
84     /**
85      * INTERNAL:
86      * Return the field appropriately aliased
87      */

88     public DatabaseField getAliasedField() {
89         if (aliasedField == null) {
90             initializeAliasedField();
91         }
92         return aliasedField;
93
94     }
95
96     /**
97      * Return the alias for our table
98      */

99     private DatabaseTable getAliasedTable() {
100         DataExpression base = (DataExpression)getBaseExpression();
101         if (!getField().hasTableName()) {
102             base.getDescriptor().buildField(getField());
103         }
104
105         DatabaseTable alias = base.aliasForTable(getField().getTable());
106         if (alias == null) {
107             return getField().getTable();
108         } else {
109             return alias;
110         }
111     }
112
113     /**
114      * INTERNAL:
115      * If there are any fields associated with this expression, return them
116      */

117     public DatabaseField getClonedField() {
118         return (DatabaseField)getField().clone();
119     }
120
121     /**
122      * INTERNAL:
123      * If there are any fields associated with this expression, return them
124      */

125     public Vector getClonedFields() {
126         Vector result = new Vector(1);
127         result.addElement(getField().clone());
128         return result;
129     }
130
131     /**
132      * INTERNAL:
133      */

134     public DatabaseField getField() {
135         return field;
136     }
137
138     /**
139      * INTERNAL:
140      * Return all the fields
141      */

142     public Vector getFields() {
143         Vector result = new Vector(1);
144         result.addElement(getField());
145         return result;
146     }
147
148     /**
149      * INTERNAL:
150      * Alias the database field for our current environment
151      */

152     private void initializeAliasedField() {
153         DatabaseField tempField = (DatabaseField)getField().clone();
154         DatabaseTable aliasedTable = getAliasedTable();
155
156         // Put in a special check here so that if the aliasing does nothing we don't cache the
157
// result because it's invalid. This saves us from caching premature data if e.g. debugging
158
// causes us to print too early"
159
// if (aliasedTable.equals(getField().getTable())) {
160
// return;
161
// } else {
162
aliasedField = tempField;
163         aliasedField.setTable(aliasedTable);
164         // }
165
}
166
167     /**
168      * INTERNAL:
169      */

170     public boolean isAttribute() {
171         return true;
172     }
173
174     public boolean isFieldExpression() {
175         return true;
176     }
177
178     /**
179      * INTERNAL:
180      * Print SQL onto the stream, using the ExpressionPrinter for context
181      */

182     public void printSQL(ExpressionSQLPrinter printer) {
183         printer.printField(getAliasedField());
184     }
185
186     /**
187      * INTERNAL:
188      * Print java for project class generation
189      */

190     public void printJava(ExpressionJavaPrinter printer) {
191         getBaseExpression().printJava(printer);
192         printer.printString(".getField(\"" + getField().getQualifiedName() + "\")");
193     }
194
195     /**
196      * INTERNAL:
197      * This expression is built on a different base than the one we want. Rebuild it and
198      * return the root of the new tree
199      */

200     public Expression rebuildOn(Expression newBase) {
201         FieldExpression expression = new FieldExpression(getField(), getBaseExpression().rebuildOn(newBase));
202         expression.setSelectIfOrderedBy(selectIfOrderedBy());
203         return expression;
204     }
205
206     /**
207      * INTERNAL:
208      * Set the field in the mapping.
209      */

210     public void setField(DatabaseField newField) {
211         field = newField;
212     }
213
214     /**
215      * INTERNAL:
216      * Rebuild myself against the base, with the values of parameters supplied by the context
217      * expression. This is used for transforming a standalone expression (e.g. the join criteria of a mapping)
218      * into part of some larger expression. You normally would not call this directly, instead calling twist
219      * See the comment there for more details"
220      */

221     public Expression twistedForBaseAndContext(Expression newBase, Expression context) {
222         Expression twistedBase = getBaseExpression().twistedForBaseAndContext(newBase, context);
223         return twistedBase.getField(getField());
224     }
225
226     /**
227      * Do any required validation for this node. Throw an exception if it's incorrect.
228      */

229     public void validateNode() {
230         DataExpression base = (DataExpression)getBaseExpression();
231         if (getField().getTable().hasName()) {
232             Vector tables = base.getOwnedTables();
233             if ((tables != null) && (!tables.contains((getField().getTable())))) {
234                 throw QueryException.invalidTableForFieldInExpression(getField());
235             }
236         }
237     }
238
239     /**
240      * INTERNAL:
241      * Return the value for in memory comparison.
242      * This is only valid for valueable expressions.
243      */

244     public Object JavaDoc valueFromObject(Object JavaDoc object, AbstractSession session, AbstractRecord translationRow, InMemoryQueryIndirectionPolicy valueHolderPolicy, boolean isObjectUnregistered) {
245         // Joins not supported.
246
if (getBuilder() != getBaseExpression()) {
247             throw QueryException.cannotConformExpression();
248         }
249
250         // For bug 2780817 get the mapping directly from the object. In EJB 2.0
251
// inheritance, each child must override mappings defined in an abstract
252
// class with its own.
253
DatabaseMapping mapping = session.getDescriptor(object.getClass()).getObjectBuilder().getMappingForField(getField());
254         if (mapping == null) {
255             throw QueryException.cannotConformExpression();
256         }
257
258         return mapping.valueFromObject(object, getField(), session);
259     }
260
261     /**
262      * INTERNAL:
263      * Used to print a debug form of the expression tree.
264      */

265     public void writeDescriptionOn(BufferedWriter writer) throws IOException {
266         writer.write(getField().toString());
267     }
268
269     /**
270      * INTERNAL: called from SQLSelectStatement.writeFieldsFromExpression(...)
271      */

272     public void writeFields(ExpressionSQLPrinter printer, Vector newFields, SQLSelectStatement statement) {
273         DatabaseField field = getField();
274
275         if (field != null) {
276             newFields.addElement(field);
277             writeField(printer, field, statement);
278         }
279     }
280 }
Popular Tags