KickJava   Java API By Example, From Geeks To Geeks.

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


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.lang.reflect.InvocationTargetException JavaDoc;
33 import java.lang.reflect.Method JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.HashMap JavaDoc;
36
37 import com.genimen.djeneric.language.Messages;
38 import com.genimen.djeneric.tools.scriptengine.core.DjScriptParserEngine;
39 import com.genimen.djeneric.tools.scriptengine.core.ParseException;
40 import com.genimen.djeneric.tools.scriptengine.core.SimpleNode;
41 import com.genimen.djeneric.tools.scriptengine.core.util.DjScriptCallable;
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 import com.genimen.djeneric.tools.scriptengine.core.util.FunctionSupport;
46
47 public class PropertyOrFunctionNode extends SimpleNode implements ValueExpression
48 {
49   public static final String JavaDoc FUNCTION_DETERMINED = "[function determined]";
50   boolean _isFunction = false;
51
52   public PropertyOrFunctionNode(int i)
53   {
54     super(i);
55   }
56
57   public PropertyOrFunctionNode(DjScriptParserEngine p, int i)
58   {
59     super(p, i);
60   }
61
62   public String JavaDoc getName()
63   {
64     if (_isFunction) return "function";
65     return "property";
66   }
67
68   public String JavaDoc toString()
69   {
70     return getName();
71   }
72
73   public boolean isFunction()
74   {
75     return _isFunction;
76   }
77
78   public void setFunction(boolean b)
79   {
80     _isFunction = b;
81   }
82
83   public Object JavaDoc getValue(DjScriptExecutionTimeScope context) throws DjScriptExecutionException
84   {
85     if (isFunction())
86     {
87       PropertyPathNode function = (PropertyPathNode) getChild(0);
88       Object JavaDoc result = evalFunction(context);
89       if (function.isNegated())
90       {
91         if (!(result instanceof Boolean JavaDoc)) throw new DjScriptExecutionException(Messages
92             .getString("PropertyNode.CanNotNegate"), this);
93         result = new Boolean JavaDoc(!((Boolean JavaDoc) result).booleanValue());
94       }
95       return result;
96     }
97     else
98     {
99       ValueExpression prop = (ValueExpression) getChild(0);
100       return prop.getValue(context);
101     }
102   }
103
104   protected Object JavaDoc[] getParams(DjScriptExecutionTimeScope context) throws DjScriptExecutionException
105   {
106     ArrayList JavaDoc paramList = new ArrayList JavaDoc();
107     for (int i = 1; i < getChildCount(); i++)
108     {
109       if (!(getChild(i) instanceof ValueExpression))
110       {
111         throw new DjScriptExecutionException(Messages.getString("PropertyOrFunctionNode.Parameter1", getChild(i)), this);
112       }
113       ValueExpression val = (ValueExpression) getChild(i);
114       paramList.add(val.getValue(context));
115     }
116     return paramList.toArray(new Object JavaDoc[0]);
117   }
118
119   protected Object JavaDoc evalFunction(Object JavaDoc obj, DjScriptExecutionTimeScope context) throws Exception JavaDoc
120   {
121     PropertyPathNode function = (PropertyPathNode) getChild(0);
122     String JavaDoc path = function.getPath();
123
124     Object JavaDoc result = evalFunction(obj, path, context);
125     return result;
126   }
127
128   protected Object JavaDoc evalFunction(Object JavaDoc obj, String JavaDoc functionName, DjScriptExecutionTimeScope context) throws Exception JavaDoc
129   {
130     FunctionSupport functionSupport = context.getFunctionSupport();
131     return functionSupport.call(obj, functionName, getParams(context), context);
132   }
133
134   protected Object JavaDoc evalFunction(DjScriptExecutionTimeScope context) throws DjScriptExecutionException
135   {
136     try
137     {
138       PropertyPathNode function = (PropertyPathNode) getChild(0);
139       String JavaDoc path = function.getPath();
140       String JavaDoc functionName = null;
141
142       int idx = path.lastIndexOf(".");
143       if (idx == -1)
144       {
145         functionName = path;
146         path = null;
147       }
148       else
149       {
150         functionName = path.substring(idx + 1);
151         path = path.substring(0, idx);
152       }
153
154       if (path != null)
155       {
156         Object JavaDoc obj = context.getPropertyValue(path, this);
157         if (obj instanceof DjScriptCallable) return evalCallable((DjScriptCallable) obj, functionName, context);
158         else return evalFunction(obj, functionName, context);
159       }
160       else
161       {
162         return context.getFunctionSupport().staticCall(functionName, getParams(context), context);
163       }
164     }
165     catch (Exception JavaDoc x)
166     {
167       throw new DjScriptExecutionException(x, this);
168     }
169   }
170
171   private Object JavaDoc evalCallable(DjScriptCallable callable, String JavaDoc functionName, DjScriptExecutionTimeScope context)
172       throws DjScriptExecutionException
173   {
174     Method JavaDoc[] ms = callable.getClass().getMethods();
175     Method JavaDoc method = null;
176
177     for (int i = 0; i < ms.length; i++)
178       if (ms[i].getName().equals(functionName))
179       {
180         method = ms[i];
181         break;
182       }
183
184     if (method == null) throw new DjScriptExecutionException(Messages.getString("PropertyOrFunctionNode.Method",
185                                                                                 functionName), this);
186
187     try
188     {
189       callable.setContext(context);
190       return method.invoke(callable, coerseArgs(method.getParameterTypes(), getParams(context)));
191     }
192     catch (InvocationTargetException JavaDoc e)
193     {
194       throw new DjScriptExecutionException(e.getCause(), this);
195     }
196     catch (IllegalArgumentException JavaDoc e)
197     {
198       throw new DjScriptExecutionException(e, this);
199     }
200     catch (IllegalAccessException JavaDoc e)
201     {
202       throw new DjScriptExecutionException(e, this);
203     }
204   }
205
206   private Object JavaDoc[] coerseArgs(Class JavaDoc[] classes, Object JavaDoc[] objects) throws DjScriptExecutionException
207   {
208     Object JavaDoc[] result = new Object JavaDoc[objects.length];
209
210     for (int i = 0; i < classes.length && i < objects.length; i++)
211     {
212       if (objects[i] != null)
213       {
214         if (classes[i].isAssignableFrom(objects[i].getClass())) result[i] = objects[i];
215         else throw new DjScriptExecutionException(Messages.getString("PropertyOrFunctionNode.Parameter", String
216             .valueOf(i + 1), classes[i].getName(), objects[i].getClass().getName()));
217       }
218     }
219
220     return result;
221   }
222
223   public void execute(DjScriptExecutionTimeScope ctxt) throws DjScriptExecutionException
224   {
225     getValue(ctxt);
226   }
227
228   public void translateOql(DjScriptExecutionTimeScope ctxt, StringBuffer JavaDoc result, HashMap JavaDoc parameters)
229       throws ParseException
230   {
231     if (isFunction())
232     {
233       String JavaDoc pname = "param" + parameters.size();
234       result.append(":");
235       result.append(pname);
236       parameters.put(pname, evalFunction(ctxt));
237     }
238     else
239     {
240       PropertyPathNode prop = (PropertyPathNode) getChild(0);
241
242       if (ctxt.isVariable(prop.getPath()))
243       {
244         String JavaDoc pname = "param" + parameters.size();
245         result.append(":");
246         result.append(pname);
247         parameters.put(pname, ctxt.getValue(prop.getPath()));
248       }
249       else result.append(prop.getPath());
250     }
251   }
252
253   public String JavaDoc getFunctionName()
254   {
255     PropertyPathNode function = (PropertyPathNode) getChild(0);
256     return function.getPath();
257   }
258
259   public boolean isNegated()
260   {
261     PropertyPathNode function = (PropertyPathNode) getChild(0);
262     return function.isNegated();
263   }
264
265   public String JavaDoc getValidatedTypeName(DjScriptCompileTimeScope context) throws DjScriptExecutionException
266   {
267     if (isFunction())
268     {
269       boolean isOk = false;
270
271       String JavaDoc fname = getFunctionName();
272       int idx = fname.lastIndexOf(".");
273       if (idx == -1) isOk = context.getFunctionSupport().isStaticCall(getFunctionName());
274       else
275       {
276         String JavaDoc path = fname.substring(0, idx);
277         if (context.isKnownJavaBean(path)) isOk = true;
278         else isOk = context.getFunctionSupport().isCall(getFunctionName());
279       }
280
281       if (!isOk) throw new DjScriptExecutionException("Function " + getFunctionName() + " not defined", this);
282
283       return FUNCTION_DETERMINED;
284     }
285     ValueExpression prop = (ValueExpression) getChild(0);
286     return prop.getValidatedTypeName(context);
287   }
288
289   public void validateScript(DjScriptCompileTimeScope ctxt) throws DjScriptExecutionException
290   {
291     getValidatedTypeName(ctxt);
292     super.validateScript(ctxt);
293   }
294
295 }
Popular Tags