KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > es > ScriptClosure


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.es;
30
31 import com.caucho.util.Exit;
32
33 /**
34  * ScriptClosure lets Java programs call JavaScript functions. It contains
35  * the state of an executing JavaScript program.
36  */

37 final public class ScriptClosure {
38   private Script script;
39   private Global resin;
40   private ESGlobal global;
41
42   ScriptClosure(Global resin, ESGlobal global, Script script)
43   {
44     this.script = script;
45     this.resin = resin;
46     this.global = global;
47   }
48
49   /**
50    * Returns the lastModified time of the script. The last modified
51    * time is the maximum of all imported script modified times.
52    *
53    * <p>getLastModified is vital for dynamic applications like JSP
54    * which need to reload the script when it changes.
55    */

56   public boolean isModified()
57   {
58     return script.isModified();
59   }
60
61   /**
62    * Calls the JavaScript function 'name' with no arguments.
63    *
64    * @param name JavaScript function name.
65    * @return The Java object returned by the JavaScript function.
66    */

67   public synchronized Object JavaDoc call(String JavaDoc name)
68     throws Throwable JavaDoc
69   {
70     Call call = resin.getCall();
71     call.caller = call;
72     call.top = 1;
73     call.setArg(-1, global);
74
75     Object JavaDoc value = call(getFunction(name), call, 0);
76
77     resin.freeCall(call);
78
79     return value;
80   }
81
82   /**
83    * Calls the JavaScript function 'name' with a single argument.
84    * <p>Arguments are automatically wrapped, and return values automatically
85    * unwrapped.
86    *
87    * @param name JavaScript function name.
88    * @param a First argument passed to JavaScript.
89    * @return The Java object returned by the JavaScript function.
90    */

91   public synchronized Object JavaDoc call(String JavaDoc name, Object JavaDoc a)
92     throws Throwable JavaDoc
93   {
94     Call call = resin.getCall();
95     call.caller = call;
96     call.top = 1;
97     call.setArg(-1, global);
98     call.setArg(0, resin.objectWrap(a));
99
100     Object JavaDoc value = call(getFunction(name), call, 1);
101
102     resin.freeCall(call);
103
104     return value;
105   }
106
107   /**
108    * Calls the JavaScript function 'name' with two arguments.
109    * <p>Arguments are automatically wrapped, and return values automatically
110    * unwrapped.
111    *
112    * @param name JavaScript function name.
113    * @param a First argument passed to JavaScript.
114    * @param b Second argument passed to JavaScript.
115    * @return The Java object returned by the JavaScript function.
116    */

117   public synchronized Object JavaDoc call(String JavaDoc name, Object JavaDoc a, Object JavaDoc b)
118     throws Throwable JavaDoc
119   {
120     Call call = resin.getCall();
121     call.caller = call;
122     call.top = 1;
123     call.setArg(-1, global);
124     call.setArg(0, resin.objectWrap(a));
125     call.setArg(1, resin.objectWrap(b));
126
127     Object JavaDoc value = call(getFunction(name), call, 2);
128
129     resin.freeCall(call);
130
131     return value;
132   }
133
134   /**
135    * Calls the JavaScript function 'name' with three arguments.
136    * <p>Arguments are automatically wrapped, and return values automatically
137    * unwrapped.
138    *
139    * @param name JavaScript function name.
140    * @param a First argument passed to JavaScript.
141    * @param b Second argument passed to JavaScript.
142    * @param c Third argument passed to JavaScript.
143    * @return The Java object returned by the JavaScript function.
144    */

145   public synchronized Object JavaDoc call(String JavaDoc name, Object JavaDoc a, Object JavaDoc b, Object JavaDoc c)
146     throws Throwable JavaDoc
147   {
148     Call call = resin.getCall();
149     call.caller = call;
150     call.top = 1;
151     call.setArg(-1, global);
152     call.setArg(0, resin.objectWrap(a));
153     call.setArg(1, resin.objectWrap(b));
154     call.setArg(2, resin.objectWrap(c));
155
156     Object JavaDoc value = call(getFunction(name), call, 3);
157
158     resin.freeCall(call);
159
160     return value;
161   }
162
163   /**
164    * Calls the JavaScript function 'name' with four arguments.
165    * <p>Arguments are automatically wrapped, and return values automatically
166    * unwrapped.
167    *
168    * @param name JavaScript function name.
169    * @param a First argument passed to JavaScript.
170    * @param b Second argument passed to JavaScript.
171    * @param c Third argument passed to JavaScript.
172    * @param d Fourth argument passed to JavaScript.
173    * @return The Java object returned by the JavaScript function.
174    */

175   public synchronized Object JavaDoc call(String JavaDoc name, Object JavaDoc a, Object JavaDoc b,
176                   Object JavaDoc c, Object JavaDoc d)
177     throws Throwable JavaDoc
178   {
179     Call call = resin.getCall();
180     call.caller = call;
181     call.top = 1;
182     call.setArg(-1, global);
183     call.setArg(0, resin.objectWrap(a));
184     call.setArg(1, resin.objectWrap(b));
185     call.setArg(2, resin.objectWrap(c));
186     call.setArg(3, resin.objectWrap(d));
187
188     Object JavaDoc value = call(getFunction(name), call, 4);
189
190     resin.freeCall(call);
191
192     return value;
193   }
194
195   /**
196    * Calls the JavaScript function 'name' with an array of arguments.
197    * <p>Arguments are automatically wrapped, and return values automatically
198    * unwrapped.
199    *
200    * @param name JavaScript function name.
201    * @param args Arguments to pass to the JavaScript function.
202    * @return The Java object returned by the JavaScript function.
203    */

204   public synchronized Object JavaDoc call(String JavaDoc name, Object JavaDoc []args)
205     throws Throwable JavaDoc
206   {
207     Call call = resin.getCall();
208     call.caller = call;
209     call.setArg(0, global);
210     call.top = 1;
211     for (int i = 0; i < args.length; i++)
212       call.setArg(i, resin.objectWrap(args[i]));
213
214     Object JavaDoc value = call(getFunction(name), call, args.length);
215
216     resin.freeCall(call);
217
218     return value;
219   }
220
221   private ESClosure getFunction(String JavaDoc name)
222     throws Throwable JavaDoc
223   {
224     ESBase fun = global.hasProperty(ESString.create(name));
225
226     if (fun == null)
227       throw new ESException("no such function `" + name + "'");
228
229     if (! (fun instanceof ESClosure))
230       throw new ESException(name + " should be function: " + fun);
231
232     return (ESClosure) fun;
233   }
234
235   private Object JavaDoc call(ESClosure closure, Call call, int length)
236     throws Throwable JavaDoc
237   {
238     int scopeLength = closure.scopeLength;
239     call.scopeLength = scopeLength;
240     for (int i = 0; i < scopeLength; i++)
241       call.scope[i] = closure.scope[i];
242
243     /* XXX: use this to test the test.
244     call.scopeLength = closure.scopeLength;
245     call.scope = closure.scope;
246     */

247
248     boolean doExit = Exit.addExit();
249     Global old = resin.begin();
250     try {
251       ESBase value = closure.call(call, length);
252
253       return value == null ? null : value.toJavaObject();
254     } finally {
255       resin.end(old);
256       if (doExit)
257     Exit.exit();
258     }
259   }
260
261   /**
262    * Returns a global property of the closure.
263    *
264    * @param name name of the global property
265    * @return unwrapped Java object of the global property.
266    */

267   public synchronized Object JavaDoc getProperty(String JavaDoc name)
268   {
269     try {
270       ESBase object = global.getProperty(name);
271
272       return object.toJavaObject();
273     } catch (Throwable JavaDoc e) {
274       return null;
275     }
276   }
277
278   /**
279    * Sets a global property of the closure.
280    *
281    * @param name name of the global property
282    * @param value Java object to assign to the global property.
283    */

284   public synchronized void setProperty(String JavaDoc name, Object JavaDoc value)
285   {
286     try {
287       global.setProperty(name, resin.objectWrap(value));
288     } catch (Throwable JavaDoc e) {
289     }
290   }
291 }
292
Popular Tags