KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > flow > javascript > ScriptableConnection


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components.flow.javascript;
17 import java.sql.Connection JavaDoc;
18 import java.sql.PreparedStatement JavaDoc;
19 import java.sql.ResultSet JavaDoc;
20 import java.sql.ResultSetMetaData JavaDoc;
21 import java.sql.SQLException JavaDoc;
22
23 import org.mozilla.javascript.Context;
24 import org.mozilla.javascript.Function;
25 import org.mozilla.javascript.JavaScriptException;
26 import org.mozilla.javascript.Scriptable;
27 import org.mozilla.javascript.ScriptableObject;
28 import org.mozilla.javascript.Undefined;
29 import org.mozilla.javascript.Wrapper;
30
31 /**
32  * Wraps a JDBC connection and provides an API similar to JSTL
33  * A ScriptableConnection provides two methods:
34  *
35  * <UL>
36  * <LI>query([String] stmt, [Array] parameters, [Number] startRow, [Number] maxRows, [Function] fun)</LI>
37  * <LI>update([String] stmt, [Array] parameters)</LI>
38  * </UL>
39  * If the <code>fun</code> argument is provided to <code>query</code> it
40  * will be called for each row returned (the row object will be passed as its
41  * argument). For example:
42  * <pre>
43  * var db = Database.getConnection(...);
44  * var queryVal = ...;
45  * var startRow = 0;
46  * var maxRows = 100;
47  *
48  * db.query("select * from table where column = ?",
49  * [queryVal],
50  * startRow,
51  * maxRows,
52  * function(row) {
53  * print("column = " + row.column);
54  * });
55  *
56  * </pre>
57  * If <code>fun</code> is undefined, an object containing the following
58  * properties will be returned instead:
59  * <UL>
60  * <LI>[Array] rows - an array of row objects</LI>
61  * <LI>[Array] rowsByIndex - An array with an array per row of column values</LI>
62  * <LI>[Array] columnNames - An array of column names</LI>
63  * <LI>[Number] rowCount - Number of rows returned</LI>
64  * <LI>[Boolean] limitedByMaxRows - true if not all rows are included due to matching a maximum value </LI>
65  * </UL>
66  *
67  * A ScriptableConnection is also a wrapper around a real JDBC Connection and thus
68  * provides all of methods of Connection as well
69  *
70  * @version CVS $Id: ScriptableConnection.java 124610 2005-01-08 02:53:56Z antonio $
71  */

72 public class ScriptableConnection extends ScriptableObject {
73
74     Connection JavaDoc connection;
75     Scriptable wrapper;
76
77     static Object JavaDoc wrap(final Scriptable wrapper,
78                        final Scriptable wrapped,
79                        Object JavaDoc obj) {
80         if (obj instanceof Function) {
81             return wrap(wrapper, wrapped, (Function)obj);
82         }
83         return obj;
84     }
85
86
87     static Function wrap(final Scriptable wrapper,
88                          final Scriptable wrapped,
89                          final Function fun) {
90         return new Function() {
91                 public Object JavaDoc call(Context cx, Scriptable scope, Scriptable thisObj,
92                                    Object JavaDoc[] args) throws JavaScriptException {
93                     if (thisObj == wrapper) {
94                         thisObj = wrapped;
95                     }
96                     return fun.call(cx, scope, thisObj, args);
97                 }
98
99                 public Scriptable construct(Context cx, Scriptable scope,
100                                             Object JavaDoc[] args)
101                     throws JavaScriptException {
102                     return fun.construct(cx, scope, args);
103                 }
104
105                 public String JavaDoc getClassName() {
106                     return fun.getClassName();
107                 }
108                 
109                 public Object JavaDoc get(String JavaDoc name, Scriptable start) {
110                     return fun.get(name, fun);
111                 }
112
113                 public Object JavaDoc get(int index, Scriptable start) {
114                     return fun.get(index, fun);
115                 }
116
117                 public boolean has(String JavaDoc name, Scriptable start) {
118                     return fun.has(name, start);
119                 }
120
121                 public boolean has(int index, Scriptable start) {
122                     return fun.has(index, start);
123                 }
124
125                 public void put(String JavaDoc name, Scriptable start, Object JavaDoc value) {
126                     fun.put(name, start, value);
127                 }
128
129                 public void put(int index, Scriptable start, Object JavaDoc value) {
130                     fun.put(index, start, value);
131                 }
132
133                 public void delete(String JavaDoc name) {
134                     fun.delete(name);
135                 }
136
137                 public void delete(int index) {
138                     fun.delete(index);
139                 }
140
141                 public Scriptable getPrototype() {
142                     return fun.getPrototype();
143                 }
144
145                 public void setPrototype(Scriptable prototype) {
146                 }
147
148                 public Scriptable getParentScope() {
149                     return fun.getParentScope();
150                 }
151
152                 public void setParentScope(Scriptable parent) {
153                 }
154
155                 public Object JavaDoc[] getIds() {
156                     return fun.getIds();
157                 }
158
159                 public Object JavaDoc getDefaultValue(Class JavaDoc hint) {
160                     return fun.getDefaultValue(hint);
161                 }
162
163                 public boolean hasInstance(Scriptable instance) {
164                     return fun.hasInstance(instance);
165                 }
166
167             };
168     }
169
170     public String JavaDoc getClassName() {
171         return "Database";
172     }
173
174     public ScriptableConnection() {
175     }
176
177     public static void finishInit(Scriptable proto) {
178     }
179
180     public static Scriptable jsConstructor(Context cx, Object JavaDoc[] args,
181                                            Function ctorObj,
182                                            boolean inNewExpr)
183         throws Exception JavaDoc {
184         Connection JavaDoc conn = null;
185         if (args.length > 0) {
186             Object JavaDoc arg = args[0];
187             if (arg instanceof Wrapper) {
188                 arg = ((Wrapper)arg).unwrap();
189             }
190             if (arg instanceof Connection JavaDoc) {
191                 conn = (Connection JavaDoc)arg;
192             }
193         }
194         if (conn == null) {
195             throw new JavaScriptException("expected an instance of java.sql.Connection");
196         }
197         ScriptableConnection result = new ScriptableConnection(ctorObj, conn);
198         return result;
199     }
200
201
202     public ScriptableConnection(Scriptable parent, Connection JavaDoc conn) {
203         this.connection = conn;
204         this.wrapper = Context.toObject(connection, parent);
205     }
206
207     public Object JavaDoc jsFunction_query(String JavaDoc sql, Object JavaDoc params,
208                                    int startRow, int maxRows,
209                                    Object JavaDoc funObj)
210             throws JavaScriptException {
211
212         PreparedStatement JavaDoc stmt = null;
213         try {
214             stmt = connection.prepareStatement(sql);
215             Scriptable array = (Scriptable)params;
216             if (array != Undefined.instance) {
217                 int len = (int)
218                     Context.toNumber(ScriptableObject.getProperty(array, "length"));
219                 for (int i = 0; i < len; i++) {
220                     Object JavaDoc val = ScriptableObject.getProperty(array, i);
221                     if (val instanceof Wrapper) {
222                         val = ((Wrapper)val).unwrap();
223                     }
224                     if (val == Scriptable.NOT_FOUND) {
225                         val = null;
226                     }
227                     stmt.setObject(i + 1, val);
228                 }
229             }
230             ResultSet JavaDoc rs = stmt.executeQuery();
231             if (maxRows == 0) {
232                 maxRows = -1;
233             }
234             if (funObj instanceof Function) {
235                 Context cx = Context.getCurrentContext();
236                 Function fun = (Function)funObj;
237                 ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
238                 int noOfColumns = rsmd.getColumnCount();
239                 // Throw away all rows upto startRow
240
for (int i = 0; i < startRow; i++) {
241                     rs.next();
242                 }
243                 // Process the remaining rows upto maxRows
244
int processedRows = 0;
245                 Scriptable scope = getTopLevelScope(this);
246                 Scriptable proto = getObjectPrototype(scope);
247                 Object JavaDoc[] args;
248                 while (rs.next()) {
249                     if ((maxRows != -1) && (processedRows == maxRows)) {
250                         break;
251                     }
252                     Scriptable row = new ScriptableResult.Row();
253                     row.setParentScope(scope);
254                     row.setPrototype(proto);
255                     for (int i = 1; i <= noOfColumns; i++) {
256                         Object JavaDoc value = rs.getObject(i);
257                         if (rs.wasNull()) {
258                             value = null;
259                         }
260                         row.put(rsmd.getColumnName(i), row, value);
261                     }
262                     args = new Object JavaDoc[1];
263                     args[0] = row;
264                     fun.call(cx, scope, scope, args);
265                 }
266                 return Undefined.instance;
267             } else {
268                 ScriptableResult s = new ScriptableResult(this, rs,
269                                                           startRow, maxRows);
270                 s.setParentScope(getTopLevelScope(this));
271                 s.setPrototype(getClassPrototype(this, s.getClassName()));
272                 return s;
273             }
274         } catch (JavaScriptException e) {
275             throw e;
276         } catch (Exception JavaDoc e) {
277             throw new JavaScriptException(e);
278         } finally {
279             try {
280                 if (stmt != null) {
281                     stmt.close();
282                 }
283             } catch (SQLException JavaDoc sqle) {
284                 throw new JavaScriptException(sqle);
285             }
286         }
287     }
288
289     public int jsFunction_update(String JavaDoc sql, Object JavaDoc params)
290         throws JavaScriptException {
291         PreparedStatement JavaDoc stmt = null;
292         try {
293             stmt = connection.prepareStatement(sql);
294             Scriptable array = (Scriptable)params;
295             if (array != Undefined.instance) {
296                 int len = (int)
297                     Context.toNumber(ScriptableObject.getProperty(array, "length"));
298                 for (int i = 0; i < len; i++) {
299                     Object JavaDoc val = ScriptableObject.getProperty(array, i);
300                     if (val instanceof Wrapper) {
301                         val = ((Wrapper)val).unwrap();
302                     }
303                     if (val == Scriptable.NOT_FOUND) {
304                         val = null;
305                     }
306                     stmt.setObject(i + 1, val);
307                 }
308             }
309             stmt.execute();
310             return stmt.getUpdateCount();
311         } catch (Exception JavaDoc e) {
312             throw new JavaScriptException(e);
313         } finally {
314             try {
315                 if (stmt != null) {
316                     stmt.close();
317                 }
318             } catch (SQLException JavaDoc sqle) {
319                 throw new JavaScriptException(sqle);
320             }
321         }
322     }
323
324     public Object JavaDoc get(String JavaDoc name, Scriptable start) {
325         if (wrapper != null) {
326             Object JavaDoc result = wrapper.get(name, wrapper);
327             if (result != NOT_FOUND) {
328                 return wrap(this, wrapper, result);
329             }
330         }
331         return super.get(name, start);
332     }
333
334     public boolean has(String JavaDoc name, Scriptable start) {
335         if (wrapper != null) {
336             if (wrapper.has(name, wrapper)) {
337                 return true;
338             }
339         }
340         return super.has(name, start);
341     }
342
343     public boolean has(int index, Scriptable start) {
344         if (wrapper != null) {
345             if (wrapper.has(index, start)) {
346                 return true;
347             }
348         }
349         return super.has(index, start);
350     }
351
352     public Object JavaDoc get(int index, Scriptable start) {
353         if (wrapper != null) {
354             Object JavaDoc result = wrapper.get(index, start);
355             if (result != NOT_FOUND) {
356                 return wrap(this, wrapper, result);
357             }
358         }
359         return super.get(index, start);
360     }
361
362     public void put(String JavaDoc name, Scriptable start, Object JavaDoc value) {
363         if (wrapper != null) {
364             wrapper.put(name, wrapper, value);
365             return;
366         }
367         super.put(name, start, value);
368     }
369
370 }
371
372
373
374
Popular Tags