KickJava   Java API By Example, From Geeks To Geeks.

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


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.expressions;
23
24 import java.io.*;
25 import java.util.*;
26 import oracle.toplink.essentials.exceptions.*;
27 import oracle.toplink.essentials.internal.helper.*;
28 import oracle.toplink.essentials.expressions.*;
29 import oracle.toplink.essentials.internal.databaseaccess.*;
30
31 /**
32  * Abstract class for expression that have exactly two children, such as and/or and relations.
33  */

34 public abstract class CompoundExpression extends Expression {
35     protected ExpressionOperator operator;
36     protected transient ExpressionOperator platformOperator;
37     protected Expression firstChild;
38     protected Expression secondChild;
39
40     public CompoundExpression() {
41         super();
42     }
43
44     /**
45      * INTERNAL:
46      * Find the alias for a given table from the first or second child in the additionalOuterJoinCriteria
47      */

48     public DatabaseTable aliasForTable(DatabaseTable table) {
49         DatabaseTable alias = null;
50         if (getFirstChild() != null) {
51             alias = getFirstChild().aliasForTable(table);
52         }
53
54         if ((alias == null) && (getSecondChild() != null)) {
55             alias = getSecondChild().aliasForTable(table);
56         }
57
58         return alias;
59     }
60
61     /**
62      * INTERNAL:
63      */

64     public Expression create(Expression base, Object JavaDoc singleArgument, ExpressionOperator operator) {
65         setFirstChild(base);
66         Expression argument = Expression.from(singleArgument, base);
67         setSecondChild(argument);
68         setOperator(operator);
69         return this;
70     }
71
72     /**
73      * INTERNAL:
74      */

75     public Expression create(Expression base, Vector arguments, ExpressionOperator operator) {
76         setFirstChild(base);
77         if (!arguments.isEmpty()) {
78             setSecondChild((Expression)arguments.firstElement());
79         }
80         setOperator(operator);
81         return this;
82     }
83
84     /**
85      * INTERNAL:
86      * Used for debug printing.
87      */

88     public String JavaDoc descriptionOfNodeType() {
89         return "Compound Expression";
90     }
91
92     /**
93      * Return the expression builder which is the ultimate base of this expression, or
94      * null if there isn't one (shouldn't happen if we start from a root)
95      */

96     public ExpressionBuilder getBuilder() {
97         ExpressionBuilder builder = getFirstChild().getBuilder();
98         if (builder == null) {
99             return getSecondChild().getBuilder();
100         } else {
101             return builder;
102         }
103     }
104
105     public Expression getFirstChild() {
106         return firstChild;
107     }
108
109     public ExpressionOperator getOperator() {
110         return operator;
111     }
112
113     public ExpressionOperator getPlatformOperator(DatabasePlatform platform) {
114         if (platformOperator == null) {
115             initializePlatformOperator(platform);
116         }
117         return platformOperator;
118     }
119
120     public Expression getSecondChild() {
121         return secondChild;
122     }
123
124     /**
125      * INTERNAL:
126      */

127     public void initializePlatformOperator(DatabasePlatform platform) {
128         if (getOperator().isComplete()) {
129             platformOperator = getOperator();
130             return;
131         }
132         platformOperator = platform.getOperator(getOperator().getSelector());
133         if (platformOperator == null) {
134             throw QueryException.invalidOperator(getOperator().toString());
135         }
136     }
137
138     public boolean isCompoundExpression() {
139         return true;
140     }
141
142     /**
143      * INTERNAL:
144      * For iterating using an inner class
145      */

146     public void iterateOn(ExpressionIterator iterator) {
147         super.iterateOn(iterator);
148         if (getFirstChild() != null) {
149             getFirstChild().iterateOn(iterator);
150         }
151         if (getSecondChild() != null) {
152             getSecondChild().iterateOn(iterator);
153         }
154     }
155
156     /**
157      * INTERNAL:
158      * Normalize into a structure that is printable.
159      * Also compute printing information such as outer joins.
160      */

161     public Expression normalize(ExpressionNormalizer normalizer) {
162         validateNode();
163         if (getFirstChild() != null) {
164             //let's make sure a session is available in the case of a parallel expression
165
ExpressionBuilder builder = getFirstChild().getBuilder();
166             if (builder != null){
167                 builder.setSession(normalizer.getSession());
168             }
169             setFirstChild(getFirstChild().normalize(normalizer));
170         }
171         if (getSecondChild() != null) {
172             //let's make sure a session is available in the case of a parallel expression
173
ExpressionBuilder builder = getSecondChild().getBuilder();
174              if (builder != null){
175                  builder.setSession(normalizer.getSession());
176              }
177             setSecondChild(getSecondChild().normalize(normalizer));
178         }
179
180         // For CR2456, it is now possible for normalize to remove redundant
181
// conditions from the where clause.
182
if (getFirstChild() == null) {
183             return getSecondChild();
184         } else if (getSecondChild() == null) {
185             return getFirstChild();
186         }
187         return this;
188     }
189     
190     /**
191      * Do any required validation for this node. Throw an exception if it's incorrect.
192      * Ensure that both sides are not data expressions.
193      */

194     public void validateNode() {
195         if (getFirstChild() != null) {
196             if (getFirstChild().isDataExpression() || getFirstChild().isConstantExpression()) {
197                 throw QueryException.invalidExpression(this);
198             }
199         }
200         if (getSecondChild() != null) {
201             if (getSecondChild().isDataExpression() || getSecondChild().isConstantExpression()) {
202                 throw QueryException.invalidExpression(this);
203             }
204         }
205     }
206
207     /**
208      * INTERNAL:
209      * Used for cloning.
210      */

211     protected void postCopyIn(Dictionary alreadyDone) {
212         super.postCopyIn(alreadyDone);
213         if (getFirstChild() != null) {
214             setFirstChild(getFirstChild().copiedVersionFrom(alreadyDone));
215         }
216         if (getSecondChild() != null) {
217             setSecondChild(getSecondChild().copiedVersionFrom(alreadyDone));
218         }
219     }
220
221     /**
222      * INTERNAL:
223      * Print SQL
224      */

225     public void printSQL(ExpressionSQLPrinter printer) {
226         ExpressionOperator realOperator = getPlatformOperator(printer.getPlatform());
227         printer.printString("(");
228         realOperator.printDuo(getFirstChild(), getSecondChild(), printer);
229         printer.printString(")");
230     }
231
232     /**
233      * INTERNAL:
234      * Print java for project class generation
235      */

236     public void printJava(ExpressionJavaPrinter printer) {
237         ExpressionOperator realOperator = getPlatformOperator(printer.getPlatform());
238         realOperator.printJavaDuo(getFirstChild(), getSecondChild(), printer);
239     }
240
241     /**
242      * INTERNAL:
243      * This expression is built on a different base than the one we want. Rebuild it and
244      * return the root of the new tree
245      */

246     public Expression rebuildOn(Expression newBase) {
247         Vector arguments;
248
249         Expression first = getFirstChild().rebuildOn(newBase);
250         if (getSecondChild() == null) {
251             arguments = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(0);
252         } else {
253             arguments = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(1);
254             arguments.addElement(getSecondChild().rebuildOn(newBase));
255         }
256         return first.performOperator(getOperator(), arguments);
257     }
258
259     protected void setFirstChild(Expression firstChild) {
260         this.firstChild = firstChild;
261     }
262
263     public void setOperator(ExpressionOperator newOperator) {
264         operator = newOperator;
265     }
266
267     protected void setSecondChild(Expression secondChild) {
268         this.secondChild = secondChild;
269     }
270
271     /**
272      * INTRENAL:
273      * Used to change an expression off of one base to an expression off of a different base.
274      * i.e. expression on address to an expression on an employee's address.
275      */

276     public Expression twistedForBaseAndContext(Expression newBase, Expression context) {
277         Vector arguments;
278
279         if (getSecondChild() == null) {
280             arguments = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(0);
281         } else {
282             arguments = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(1);
283             arguments.addElement(getSecondChild().twistedForBaseAndContext(newBase, context));
284         }
285
286         Expression first = getFirstChild().twistedForBaseAndContext(newBase, context);
287         return first.performOperator(getOperator(), arguments);
288     }
289
290     /**
291      * INTERNAL:
292      * Used to print a debug form of the expression tree.
293      */

294     public void writeDescriptionOn(BufferedWriter writer) throws IOException {
295         writer.write(operator.toString());
296     }
297
298     /**
299      * INTERNAL:
300      * Used for toString for debugging only.
301      */

302     public void writeSubexpressionsTo(BufferedWriter writer, int indent) throws IOException {
303         if (getFirstChild() != null) {
304             getFirstChild().toString(writer, indent);
305         }
306         if (getSecondChild() != null) {
307             getSecondChild().toString(writer, indent);
308         }
309     }
310 }
311
Popular Tags