KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > ql > BinaryExpr


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.ejb.ql;
30
31 import com.caucho.config.ConfigException;
32 import com.caucho.util.CharBuffer;
33
34 /**
35  * A binary expression
36  */

37 class BinaryExpr extends Expr {
38   // binary operation
39
private int _op;
40   // left expression
41
private Expr _left;
42   // right expression
43
private Expr _right;
44
45   /**
46    * Creates a binary expression.
47    *
48    * @param op the operation
49    * @param left the left expression
50    * @param right the right expression
51    */

52   BinaryExpr(Query query, int op, Expr left, Expr right)
53     throws ConfigException
54   {
55     _query = query;
56     _op = op;
57     _left = left;
58     _right = right;
59
60     evalTypes();
61   }
62
63   Expr getLeft()
64   {
65     return _left;
66   }
67
68   /**
69    * Evaluates the types for the expression
70    */

71   void evalTypes()
72     throws ConfigException
73   {
74     /*
75     if (_left.getComponentCount() != _right.getComponentCount()) {
76       throw error(L.l("`{0}' has mismatched types `{1}' != `{2}'",
77                       this, _left.getJavaType().getName(),
78                       _right.getJavaType().getName()));
79     }
80     */

81     
82     switch (_op) {
83     case Query.EQ:
84     case Query.NE:
85       if (! _left.getJavaType().equals(_right.getJavaType()) &&
86           _left.isNumeric() != _right.isNumeric() &&
87           ! (_left.isDate() && _right.isDate()))
88         throw error(L.l("`{0}' has mismatched types `{1}' != `{2}'",
89                         this, _left.getJavaType().getName(),
90                         _right.getJavaType().getName()));
91       setJavaType(boolean.class);
92       break;
93       
94     case Query.LT:
95     case Query.GT:
96     case Query.LE:
97     case Query.GE:
98       if (_left.isDate() && _right.isDate()) {
99       }
100       else if (! _left.isNumeric())
101         throw error(L.l("`{0}' expects a numeric value at {1}. Less-than and greater-than comparisons only make sense with numbers and dates.",
102                         this, _left.getJavaType().getName()));
103       else if (! _right.isNumeric())
104         throw error(L.l("`{0}' expects a numeric value at {1}. Less-than and greater-than comparisons only make sense with numbers and dates.",
105                         this, _right.getJavaType().getName()));
106       
107       setJavaType(boolean.class);
108       break;
109       
110     case Query.AND:
111     case Query.OR:
112       if (! _left.isBoolean())
113         throw error(L.l("`{0}' expects a boolean value at {1}",
114                         _left, _left.getJavaType().getName()));
115       if (! _right.isBoolean())
116         throw error(L.l("`{0}' expects a boolean value at {1}",
117                         _right, _right.getJavaType().getName()));
118       
119       setJavaType(boolean.class);
120       break;
121
122     case '+':
123     case '-':
124     case '*':
125     case '/':
126       if (! _left.isNumeric())
127         throw error(L.l("`{0}' expects a numeric value at {1}",
128                         _left, _left.getJavaType().getName()));
129       if (! _right.isNumeric())
130         throw error(L.l("`{0}' expects a numeric value at {1}",
131                         _right, _right.getJavaType().getName()));
132
133       /*
134       if (int.class.isAssignableFrom(_left.getJavaType()) &&
135           int.class.isAssignableFrom(_right.getJavaType()))
136         setJavaType(int.class);
137       else if (long.class.isAssignableFrom(_left.getJavaType()) &&
138                long.class.isAssignableFrom(_right.getJavaType()))
139         setJavaType(long.class);
140       else
141         setJavaType(double.class);
142       */

143       if (isInteger(_left.getJavaType()) &&
144           isInteger(_right.getJavaType()))
145         setJavaType(long.class);
146       else
147         setJavaType(double.class);
148       break;
149
150     default:
151       throw new RuntimeException JavaDoc("unknown binary op:" + _op + " " + (char) _op);
152     }
153   }
154   
155   /**
156    * Prints the where SQL for this expression
157    *
158    * @param gen the java code generator
159    */

160   void generateWhere(CharBuffer cb)
161   {
162     if (_left.isKey()) {
163       int componentCount = _left.getComponentCount();
164       
165       generateWhereComponents(cb, componentCount);
166
167       return;
168     }
169     else if (_right.isKey()) {
170       int componentCount = _right.getComponentCount();
171       
172       generateWhereComponents(cb, componentCount);
173       
174       return;
175     }
176     
177     //_left.generateWhereSubExpr(cb);
178
_left.generateComponent(cb, 0);
179
180     switch (_op) {
181     case Query.EQ:
182       cb.append(" = ");
183       break;
184     case Query.NE:
185       cb.append(" <> ");
186       break;
187     case Query.LT:
188       cb.append(" < ");
189       break;
190     case Query.GT:
191       cb.append(" > ");
192       break;
193     case Query.LE:
194       cb.append(" <= ");
195       break;
196     case Query.GE:
197       cb.append(" >= ");
198       break;
199       
200     case Query.AND:
201       cb.append(" AND ");
202       break;
203     case Query.OR:
204       cb.append(" OR ");
205       break;
206
207     default:
208       cb.append(" " + ((char) _op) + " ");
209       break;
210     }
211
212     //_right.generateWhereSubExpr(cb);
213
_right.generateComponent(cb, 0);
214   }
215
216   private void generateWhereComponents(CharBuffer cb, int componentCount)
217   {
218     for (int i = 0; i < componentCount; i++) {
219       if (i != 0)
220         cb.append(" AND ");
221
222       _left.generateComponent(cb, i);
223
224       if (_op == Query.EQ)
225         cb.append(" = ");
226       else if (_op == Query.NE)
227         cb.append(" <> ");
228
229       _right.generateComponent(cb, i);
230     }
231   }
232
233   /**
234    * Generates the where SQL for this expression
235    */

236   void generateWhereSubExpr(CharBuffer cb)
237   {
238     cb.append("(");
239     generateWhere(cb);
240     cb.append(")");
241   }
242   
243   void generateSelect(CharBuffer cb)
244   {
245     cb.append("(");
246     generateWhere(cb);
247     cb.append(")");
248   }
249
250   public String JavaDoc toString()
251   {
252     CharBuffer value = CharBuffer.allocate();
253
254     if (_left instanceof BinaryExpr) {
255       value.append("(");
256       value.append(_left.toString());
257       value.append(")");
258     }
259     else
260       value.append(_left.toString());
261
262     switch (_op) {
263     case Query.EQ:
264       value.append(" = ");
265       break;
266     case Query.NE:
267       value.append(" <> ");
268       break;
269     case Query.LT:
270       value.append(" < ");
271       break;
272     case Query.GT:
273       value.append(" > ");
274       break;
275     case Query.LE:
276       value.append(" <= ");
277       break;
278     case Query.GE:
279       value.append(" >= ");
280       break;
281       
282     case Query.AND:
283       value.append(" AND ");
284       break;
285     case Query.OR:
286       value.append(" OR ");
287       break;
288
289     default:
290       value.append(" " + ((char) _op) + " ");
291       break;
292     }
293
294     if (_right instanceof BinaryExpr) {
295       value.append("(");
296       value.append(_right.toString());
297       value.append(")");
298     }
299     else
300       value.append(_right.toString());
301
302     return value.close();
303   }
304 }
305
Popular Tags