KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > tools > scriptengine > core > nodes > SubExpressionNode


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, is permitted provided that the following conditions are met: -
6  * Redistributions of source code must retain the above copyright notice, this
7  * list of conditions and the following disclaimer. - Redistributions in binary
8  * form must reproduce the above copyright notice, this list of conditions and
9  * the following disclaimer in the documentation and/or other materials
10  * provided with the distribution. - All advertising materials mentioning
11  * features or use of this software must display the following acknowledgment:
12  * "This product includes Djeneric." - Products derived from this software may
13  * not be called "Djeneric" nor may "Djeneric" appear in their names without
14  * prior written permission of Genimen BV. - Redistributions of any form
15  * whatsoever must retain the following acknowledgment: "This product includes
16  * Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG, OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.tools.scriptengine.core.nodes;
31
32 import java.math.BigDecimal JavaDoc;
33 import java.util.HashMap JavaDoc;
34
35 import com.genimen.djeneric.language.Messages;
36 import com.genimen.djeneric.repository.DjExtent;
37 import com.genimen.djeneric.repository.DjObject;
38 import com.genimen.djeneric.repository.exceptions.ObjectNotDefinedException;
39 import com.genimen.djeneric.tools.scriptengine.core.DjScriptParserEngine;
40 import com.genimen.djeneric.tools.scriptengine.core.ParseException;
41 import com.genimen.djeneric.tools.scriptengine.core.SimpleNode;
42 import com.genimen.djeneric.tools.scriptengine.core.util.DjScriptCompileTimeScope;
43 import com.genimen.djeneric.tools.scriptengine.core.util.DjScriptExecutionException;
44 import com.genimen.djeneric.tools.scriptengine.core.util.DjScriptExecutionTimeScope;
45
46 public class SubExpressionNode extends SimpleNode implements BooleanExpression
47 {
48   private static final String JavaDoc INSTANCEOF = "instanceof";
49   public static final String JavaDoc UNARY = "unary";
50
51   String JavaDoc _operator = UNARY;
52
53   public SubExpressionNode(int i)
54   {
55     super(i);
56   }
57
58   public SubExpressionNode(DjScriptParserEngine p, int i)
59   {
60     super(p, i);
61   }
62
63   public String JavaDoc getName()
64   {
65     return toString();
66   }
67
68   public void setOperator(String JavaDoc op)
69   {
70     _operator = op;
71   }
72
73   public String JavaDoc getOperator()
74   {
75     return _operator;
76   }
77
78   public String JavaDoc toString()
79   {
80     return getOperator() + " (sub)";
81   }
82
83   public boolean isUnary()
84   {
85     return getOperator().equals(UNARY);
86   }
87
88   public Object JavaDoc getValue(DjScriptExecutionTimeScope context) throws DjScriptExecutionException
89   {
90     return new Boolean JavaDoc(isTrue(context));
91   }
92
93   public boolean isTrue(DjScriptExecutionTimeScope context) throws DjScriptExecutionException
94   {
95     if (isUnary())
96     {
97       if (getChild(0) instanceof BooleanExpression)
98       {
99         return ((BooleanExpression) getChild(0)).isTrue(context);
100       }
101       throw new DjScriptExecutionException(Messages.getString("SubExpressionNode.UnsupportedUnary"), getChild(0));
102     }
103
104     // instanceof?
105
if (getOperator().equals(INSTANCEOF))
106     {
107       if ((!(getChild(0) instanceof ValueExpression)) || (!(getChild(1) instanceof PropertyOrFunctionNode))) throw new DjScriptExecutionException(
108           Messages.getString("SubExpressionNode.ObjectsAndTypesOnly"), this);
109       PropertyOrFunctionNode pof = (PropertyOrFunctionNode) getChild(1);
110       if (pof.isFunction()) throw new DjScriptExecutionException(Messages
111           .getString("SubExpressionNode.ObjectsAndTypesOnly"), this);
112
113       ValueExpression left = (ValueExpression) getChild(0);
114       PropertyPathNode right = (PropertyPathNode) pof.getChild(0);
115       Object JavaDoc leftVal = left.getValue(context);
116
117       String JavaDoc matchType = right.getPath();
118       String JavaDoc actualType = leftVal.getClass().getName();
119       if (leftVal instanceof DjObject)
120       {
121         actualType = ((DjObject) leftVal).getExtent().getObjectType();
122       }
123       if (matchType.indexOf(".") == -1)
124       {
125         int idx = actualType.lastIndexOf(".");
126         if (idx != -1)
127         {
128           actualType = actualType.substring(idx + 1);
129         }
130       }
131
132       // First try the extents
133
try
134       {
135         context.getPersistenceManager().getExtentByObjectType(matchType);
136
137         return actualType.equals(matchType);
138       }
139       catch (ObjectNotDefinedException onde)
140       { // ignore
141
}
142
143       boolean validType = matchType.equals("String") || matchType.equals("java.lang.String")
144                           || matchType.equals("Integer") || matchType.equals("java.lang.Integer")
145                           || matchType.equals("Long") || matchType.equals("java.lang.Long")
146                           || matchType.equals("Timestamp") || matchType.equals("java.sql.Timestamp");
147       if (!validType) throw new DjScriptExecutionException("Unknown type: " + matchType, this);
148
149       return actualType.equals(matchType);
150     }
151
152     // Boolean comparison?
153
if ((getChild(0) instanceof BooleanExpression) && (getChild(1) instanceof BooleanExpression))
154     {
155       BooleanExpression left = (BooleanExpression) getChild(0);
156       BooleanExpression right = (BooleanExpression) getChild(1);
157       if (getOperator().equals("=="))
158       {
159         return left.isTrue(context) == right.isTrue(context);
160       }
161       if (getOperator().equals("!="))
162       {
163         return left.isTrue(context) != right.isTrue(context);
164       }
165       throw new DjScriptExecutionException(Messages.getString("SubExpressionNode.BoolOnly"), this);
166     }
167
168     if ((getChild(0) instanceof ValueExpression) && (getChild(1) instanceof ValueExpression))
169     {
170       ValueExpression left = (ValueExpression) getChild(0);
171       ValueExpression right = (ValueExpression) getChild(1);
172       Object JavaDoc leftVal = left.getValue(context);
173       Object JavaDoc rightVal = right.getValue(context);
174
175       // First handle null stuff
176
if (leftVal == null || rightVal == null)
177       {
178         if (getOperator().equals("==")) return leftVal == rightVal;
179         if (getOperator().equals("!=")) return leftVal != rightVal;
180         return false;
181       }
182
183       // String comparison?
184
if ((leftVal instanceof String JavaDoc) || (rightVal instanceof String JavaDoc))
185       {
186         if (getOperator().equals("=="))
187         {
188           return leftVal.toString().equals(rightVal.toString());
189         }
190         if (getOperator().equals("!="))
191         {
192           return !leftVal.toString().equals(rightVal.toString());
193         }
194         if (getOperator().equals(">="))
195         {
196           return leftVal.toString().compareTo(rightVal.toString()) >= 0;
197         }
198         if (getOperator().equals("<="))
199         {
200           return leftVal.toString().compareTo(rightVal.toString()) <= 0;
201         }
202         if (getOperator().equals("<"))
203         {
204           return leftVal.toString().compareTo(rightVal.toString()) < 0;
205         }
206         if (getOperator().equals(">"))
207         {
208           return leftVal.toString().compareTo(rightVal.toString()) > 0;
209         }
210       }
211
212       // Float comparison?
213
if ((leftVal instanceof Float JavaDoc) || (rightVal instanceof Float JavaDoc))
214       {
215         Float JavaDoc l = toFloat(leftVal);
216         Float JavaDoc r = toFloat(rightVal);
217
218         if (getOperator().equals("=="))
219         {
220           return l.equals(r);
221         }
222         if (getOperator().equals("!="))
223         {
224           return !l.equals(r);
225         }
226         if (getOperator().equals(">="))
227         {
228           return l.floatValue() >= r.floatValue();
229         }
230         if (getOperator().equals("<="))
231         {
232           return l.floatValue() <= r.floatValue();
233         }
234         if (getOperator().equals("<"))
235         {
236           return l.floatValue() < r.floatValue();
237         }
238         if (getOperator().equals(">"))
239         {
240           return l.floatValue() > r.floatValue();
241         }
242       }
243
244       // BigDecimal comparison?
245
if ((leftVal instanceof BigDecimal JavaDoc) || (rightVal instanceof BigDecimal JavaDoc))
246       {
247         BigDecimal JavaDoc l = toBigDecimal(leftVal);
248         BigDecimal JavaDoc r = toBigDecimal(rightVal);
249
250         if (getOperator().equals("=="))
251         {
252           return l.equals(r);
253         }
254         if (getOperator().equals("!="))
255         {
256           return !l.equals(r);
257         }
258         if (getOperator().equals(">="))
259         {
260           return l.floatValue() >= r.floatValue();
261         }
262         if (getOperator().equals("<="))
263         {
264           return l.floatValue() <= r.floatValue();
265         }
266         if (getOperator().equals("<"))
267         {
268           return l.floatValue() < r.floatValue();
269         }
270         if (getOperator().equals(">"))
271         {
272           return l.floatValue() > r.floatValue();
273         }
274       }
275
276       // Integer comparison?
277
if ((leftVal instanceof Long JavaDoc) || (rightVal instanceof Long JavaDoc))
278       {
279         Long JavaDoc l = toLong(leftVal);
280         Long JavaDoc r = toLong(rightVal);
281
282         if (getOperator().equals("=="))
283         {
284           return l.equals(r);
285         }
286         if (getOperator().equals("!="))
287         {
288           return !l.equals(r);
289         }
290         if (getOperator().equals(">="))
291         {
292           return l.floatValue() >= r.floatValue();
293         }
294         if (getOperator().equals("<="))
295         {
296           return l.floatValue() <= r.floatValue();
297         }
298         if (getOperator().equals("<"))
299         {
300           return l.floatValue() < r.floatValue();
301         }
302         if (getOperator().equals(">"))
303         {
304           return l.floatValue() > r.floatValue();
305         }
306       }
307
308       // Boolean comparison?
309
if ((leftVal instanceof Boolean JavaDoc) && (rightVal instanceof Boolean JavaDoc))
310       {
311         boolean l = ((Boolean JavaDoc) leftVal).booleanValue();
312         boolean r = ((Boolean JavaDoc) rightVal).booleanValue();
313
314         if (getOperator().equals("=="))
315         {
316           return l == r;
317         }
318         if (getOperator().equals("!="))
319         {
320           return l != r;
321         }
322         throw new DjScriptExecutionException(Messages.getString("SubExpressionNode.BoolOnly"), this);
323       }
324       throw new DjScriptExecutionException(Messages.getString("SubExpressionNode.CanNotPerform", classOnly(leftVal),
325                                                               getOperator(), classOnly(leftVal)), this);
326     }
327
328     throw new DjScriptExecutionException(Messages.getString("SubExpressionNode.CanNotPerformOn", getOperator()), this);
329
330   }
331
332   public void translateOql(DjScriptExecutionTimeScope ctxt, StringBuffer JavaDoc result, HashMap JavaDoc parameters)
333       throws ParseException
334   {
335     result.append("(");
336     getChild(0).translateOql(ctxt, result, parameters);
337
338     if (((ValueExpression) getChild(1)).getValue(ctxt) == null)
339     {
340       if (_operator.equals("==")) result.append(" is null ");
341       else if (_operator.equals("!=")) result.append(" is not null ");
342       else result.append(" " + _operator + " null ");
343     }
344     else
345     {
346       if (_operator.equals("==")) result.append(" = ");
347       else if (_operator.equals("!=")) result.append(" <> ");
348       else result.append(" " + _operator + " ");
349
350       getChild(1).translateOql(ctxt, result, parameters);
351     }
352
353     result.append(")");
354   }
355
356   public String JavaDoc getValidatedTypeName(DjScriptCompileTimeScope context) throws DjScriptExecutionException
357   {
358     if (isUnary())
359     {
360       if (getChild(0) instanceof BooleanExpression) return Boolean JavaDoc.class.getName();
361       throw new DjScriptExecutionException("Expressie moet boolean zijn", this);
362     }
363
364     if ((getChild(0) instanceof BooleanExpression) && (getChild(1) instanceof BooleanExpression))
365     {
366       return Boolean JavaDoc.class.getName();
367     }
368
369     if ((getChild(0) instanceof ValueExpression) && (getChild(1) instanceof ValueExpression))
370     {
371       ValueExpression left = (ValueExpression) getChild(0);
372       ValueExpression right = (ValueExpression) getChild(1);
373       String JavaDoc leftType = left.getValidatedTypeName(context);
374
375       if (getOperator().equals(INSTANCEOF))
376       {
377         if (!(right instanceof PropertyOrFunctionNode))
378         {
379           throw new DjScriptExecutionException("Type aanduiding verwacht", this);
380         }
381         try
382         {
383           PropertyOrFunctionNode pfnode = (PropertyOrFunctionNode) right;
384           DjExtent le = context.getPersistenceManager().getExtentByObjectType(leftType);
385           DjExtent re = context.getPersistenceManager().getExtentByObjectType(
386                                                                               ((PropertyOrFunctionNode) right)
387                                                                                   .getValidatedTypeName(context));
388           // Both extents exist? Then the result will be boolean
389
return Boolean JavaDoc.class.getName();
390         }
391         catch (ObjectNotDefinedException e)
392         {
393           throw new DjScriptExecutionException(e, this);
394         }
395       }
396       String JavaDoc rightType = right.getValidatedTypeName(context);
397
398       if (leftType.equals(rightType)) return Boolean JavaDoc.class.getName();
399
400       // String vs. something is ok
401
if (leftType.equals(String JavaDoc.class.getName()) || rightType.equals(String JavaDoc.class.getName())) return Boolean JavaDoc.class
402           .getName();
403
404       boolean leftNumeric = leftType.equals(Integer JavaDoc.class.getName()) || leftType.equals(Long JavaDoc.class.getName())
405                             || leftType.equals(BigDecimal JavaDoc.class.getName()) || leftType.equals(Float JavaDoc.class.getName());
406
407       boolean rightNumeric = rightType.equals(Integer JavaDoc.class.getName()) || rightType.equals(Long JavaDoc.class.getName())
408                              || rightType.equals(BigDecimal JavaDoc.class.getName()) || rightType.equals(Float JavaDoc.class.getName());
409
410       // Numeric vs. Numeric is ok
411

412       if (leftNumeric && rightNumeric) return Boolean JavaDoc.class.getName();
413
414       if (!leftNumeric && rightType.equals(NullNode.NULL_TYPE))
415       {
416         if (_operator.equals("==") || _operator.equals("!=")) return Boolean JavaDoc.class.getName();
417       }
418
419       // Anything else fails
420
}
421
422     throw new DjScriptExecutionException(Messages.getString("SubExpressionNode.CanNotPerformOn", getOperator()), this);
423   }
424
425   public void validateScript(DjScriptCompileTimeScope ctxt) throws DjScriptExecutionException
426   {
427     getValidatedTypeName(ctxt);
428   }
429
430 }
Popular Tags