001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: * @created Sep 12, 2005
014: * @author James Dixon
015: */
016: package org.pentaho.data.connection.javascript;
017:
018: import java.text.SimpleDateFormat;
019:
020: import org.mozilla.javascript.Context;
021: import org.mozilla.javascript.Function;
022: import org.mozilla.javascript.NativeArray;
023: import org.mozilla.javascript.NativeJavaObject;
024: import org.mozilla.javascript.Scriptable;
025: import org.mozilla.javascript.ScriptableObject;
026: import org.pentaho.commons.connection.IPentahoMetaData;
027: import org.pentaho.commons.connection.IPentahoResultSet;
028: import org.pentaho.commons.connection.memory.MemoryMetaData;
029: import org.pentaho.commons.connection.memory.MemoryResultSet;
030: import org.pentaho.core.system.PentahoSystem;
031:
032: public class JavaScriptResultSet extends ScriptableObject implements
033: IPentahoResultSet {
034: /**
035: *
036: */
037: private static final long serialVersionUID = -2303805979176976941L;
038:
039: private IPentahoResultSet results;
040:
041: private MemoryResultSet writeableResults;
042:
043: // private IPentahoMetaData metaData;
044: // private List rows;
045: // private Iterator iterator = null;
046: private StringBuffer description;
047:
048: public JavaScriptResultSet() {
049: description = new StringBuffer();
050: results = null;
051: }
052:
053: public void setResultSet(IPentahoResultSet pResults) {
054: this .results = pResults;
055: if (results instanceof MemoryResultSet) {
056: writeableResults = (MemoryResultSet) results;
057: }
058: }
059:
060: public String getClassName() {
061: return "JavaScriptResultSet"; //$NON-NLS-1$
062: }
063:
064: public static Object jsFunction_getColumnCount(Context cx,
065: Scriptable this Obj, Object[] args, Function funObj) {
066: if (PentahoSystem.ignored)
067: cx.getClass();
068: if (PentahoSystem.ignored)
069: funObj.getClass();
070: if (args != null && args.length > 0) {
071: return null;
072: }
073: JavaScriptResultSet resultSet = (JavaScriptResultSet) this Obj;
074: return new Integer(resultSet.getColumnCount());
075: }
076:
077: public static Object jsFunction_getRowCount(Context cx,
078: Scriptable this Obj, Object[] args, Function funObj) {
079: if (PentahoSystem.ignored)
080: cx.getClass();
081: if (PentahoSystem.ignored)
082: funObj.getClass();
083: if (args != null && args.length > 0) {
084: return null;
085: }
086: JavaScriptResultSet resultSet = (JavaScriptResultSet) this Obj;
087: return new Integer(resultSet.getRowCount());
088: }
089:
090: public static Object jsFunction_getValueAt(Context cx,
091: Scriptable this Obj, Object[] args, Function funObj) {
092: if (PentahoSystem.ignored)
093: cx.getClass();
094: if (PentahoSystem.ignored)
095: funObj.getClass();
096: if (args == null) {
097: return null;
098: }
099: if (args.length < 2) {
100: return null;
101: }
102: JavaScriptResultSet resultSet = (JavaScriptResultSet) this Obj;
103: int row = 0, column = 0;
104: try {
105: if (args[0] instanceof Number) {
106: row = ((Number) args[0]).intValue();
107: } else if (args[0] instanceof String) {
108: row = Integer.parseInt((String) args[0]);
109: } else {
110: return null;
111: }
112: if (args[1] instanceof Number) {
113: column = ((Number) args[1]).intValue();
114: } else if (args[1] instanceof String) {
115: column = Integer.parseInt((String) args[1]);
116: } else {
117: return null;
118: }
119: } catch (Exception e) {
120: return null;
121: }
122: return resultSet.getValueAt(row, column);
123: }
124:
125: public static Object jsFunction_setColumnHeaders(Context cx,
126: Scriptable this Obj, Object[] args, Function funObj) {
127: if (PentahoSystem.ignored)
128: cx.getClass();
129: if (PentahoSystem.ignored)
130: funObj.getClass();
131: if (args == null) {
132: return null;
133: }
134: if (args.length == 0) {
135: return null;
136: }
137: JavaScriptResultSet resultSet = (JavaScriptResultSet) this Obj;
138: if (args.length == 1 && args[0] instanceof NativeArray) {
139: NativeArray array = (NativeArray) args[0];
140: resultSet.setMetaData(createMetadata(array, this Obj));
141: } else if (args.length == 2 && args[0] instanceof NativeArray
142: && args[1] instanceof NativeArray) {
143: NativeArray array = (NativeArray) args[0];
144: MemoryMetaData metaData = createMetadata(array, this Obj);
145: // create some metadata objects
146: array = (NativeArray) args[1];
147: int length = (int) array.getLength();
148: String columnTypes[] = new String[length];
149: for (int i = 0; i < length; i++) {
150: columnTypes[i] = array.get(i, this Obj).toString();
151: }
152: metaData.setColumnTypes(columnTypes);
153: resultSet.setMetaData(metaData);
154: } else {
155: int length = args.length;
156: String columnHeaders[] = new String[length];
157: for (int i = 0; i < length; i++) {
158: columnHeaders[i] = args[i].toString();
159: }
160: MemoryMetaData metaData = new MemoryMetaData(
161: new String[][] { columnHeaders }, null);
162: resultSet.setMetaData(metaData);
163: }
164: return null;
165: }
166:
167: private static MemoryMetaData createMetadata(NativeArray array,
168: Scriptable this Obj) {
169: int length = (int) array.getLength();
170: String columnHeaders[] = new String[length];
171: for (int i = 0; i < length; i++) {
172: columnHeaders[i] = array.get(i, this Obj).toString();
173: }
174: return new MemoryMetaData(new String[][] { columnHeaders },
175: null);
176: }
177:
178: public static Object jsFunction_addRow(Context cx,
179: Scriptable this Obj, Object[] args, Function funObj) {
180: if (PentahoSystem.ignored)
181: cx.getClass();
182: if (PentahoSystem.ignored)
183: funObj.getClass();
184: if (args == null) {
185: return null;
186: }
187: if (args.length == 0) {
188: return null;
189: }
190: // TODO support dates
191: JavaScriptResultSet resultSet = (JavaScriptResultSet) this Obj;
192: if (args.length == 1 && args[0] instanceof NativeArray) {
193: NativeArray array = (NativeArray) args[0];
194: int length = (int) array.getLength();
195: Object row[] = new Object[length];
196: String columnTypes[] = ((MemoryMetaData) resultSet
197: .getMetaData()).getColumnTypes();
198: for (int i = 0; i < length; i++) {
199: Object data = array.get(i, this Obj);
200: if (data == null) {
201: row[i] = null;
202: } else if (columnTypes != null) {
203: if (data instanceof NativeJavaObject) {
204: // see if we can force a conversion
205: Object outputClass = null;
206: if ("string".equalsIgnoreCase(columnTypes[i])) { //$NON-NLS-1$
207: outputClass = java.lang.String.class;
208: } else if ("date".equalsIgnoreCase(columnTypes[i])) { //$NON-NLS-1$
209: outputClass = java.util.Date.class;
210: } else if ("int".equalsIgnoreCase(columnTypes[i])) { //$NON-NLS-1$
211: outputClass = java.lang.Integer.class;
212: } else if ("float".equalsIgnoreCase(columnTypes[i])) { //$NON-NLS-1$
213: outputClass = java.lang.Float.class;
214: } else if ("double".equalsIgnoreCase(columnTypes[i])) { //$NON-NLS-1$
215: outputClass = java.lang.Double.class;
216: }
217: if ((NativeJavaObject.canConvert(data,
218: outputClass.getClass()))) {
219: row[i] = Context.jsToJava(data,
220: java.lang.String.class);
221: } else {
222: row[i] = null;
223: }
224: }
225: if ("string".equalsIgnoreCase(columnTypes[i])) { //$NON-NLS-1$
226: row[i] = data.toString();
227: } else if ("date".equalsIgnoreCase(columnTypes[i]) && data instanceof String) { //$NON-NLS-1$
228: SimpleDateFormat format = new SimpleDateFormat(
229: "yyyy-MM-dd"); //$NON-NLS-1$
230: try {
231: row[i] = format.parse((String) data);
232: } catch (Throwable t) {
233: row[i] = null;
234: }
235: } else if ("int".equalsIgnoreCase(columnTypes[i]) && data instanceof Integer) { //$NON-NLS-1$
236: row[i] = data;
237: } else if ("int".equalsIgnoreCase(columnTypes[i]) && data instanceof Double) { //$NON-NLS-1$
238: row[i] = new Integer(((Double) data).intValue());
239: } else if ("int".equalsIgnoreCase(columnTypes[i]) && data instanceof String) { //$NON-NLS-1$
240: row[i] = new Integer((String) data);
241: } else if ("float".equalsIgnoreCase(columnTypes[i]) && data instanceof Double) { //$NON-NLS-1$
242: row[i] = data;
243: } else if ("float".equalsIgnoreCase(columnTypes[i]) && data instanceof Integer) { //$NON-NLS-1$
244: row[i] = new Double(((Integer) data)
245: .floatValue());
246: } else if ("float".equalsIgnoreCase(columnTypes[i]) && data instanceof String) { //$NON-NLS-1$
247: row[i] = new Integer((String) data);
248: } else if ("double".equalsIgnoreCase(columnTypes[i]) && data instanceof Double) { //$NON-NLS-1$
249: row[i] = data;
250: }
251: } else if (data instanceof NativeJavaObject) {
252: Object obj = ((NativeJavaObject) data).unwrap();
253: row[i] = obj;
254: } else {
255: row[i] = data;
256: }
257: }
258: resultSet.addRow(row);
259: } else {
260: int length = args.length;
261: String row[] = new String[length];
262: for (int i = 0; i < length; i++) {
263: row[i] = args[i].toString();
264: }
265: resultSet.addRow(row);
266: }
267: return null;
268: }
269:
270: public void setMetaData(IPentahoMetaData metaData) {
271: results = new MemoryResultSet(metaData);
272: writeableResults = (MemoryResultSet) results;
273: // this.metaData = metaData;
274: // rows = new ArrayList();
275: }
276:
277: /* IPentahoResultSet methods */
278: public void addRow(String[] row) {
279: if (writeableResults != null) {
280: writeableResults.addRow(row);
281: }
282: // rows.add( row );
283: if (description.length() < 100) {
284: description.append(row);
285: }
286: }
287:
288: public void addRow(Object[] row) {
289: if (writeableResults != null) {
290: writeableResults.addRow(row);
291: }
292: // rows.add( row );
293: if (description.length() < 100) {
294: description.append(row);
295: }
296: }
297:
298: public String toString() {
299: if (results.getMetaData().getColumnHeaders() != null) {
300: return results.getMetaData().getColumnHeaders().toString()
301: + description.toString();
302: }
303: return description.toString();
304: }
305:
306: public IPentahoMetaData getMetaData() {
307: return results.getMetaData();
308: }
309:
310: public Object[] next() {
311: return results.next();
312: /*
313: * if( iterator == null ) { iterator = rows.iterator(); } if( iterator.hasNext() ) { return (Object[]) iterator.next(); } else { return null; }
314: */
315: }
316:
317: public void close() {
318: // dispose of the iterator so the rows can be iterated again
319: results.close();
320: }
321:
322: public void closeConnection() {
323: close();
324: }
325:
326: public void dispose() {
327: close();
328: }
329:
330: public boolean isScrollable() {
331: return true;
332: }
333:
334: public int getColumnCount() {
335: return results.getMetaData().getColumnCount();
336: }
337:
338: public int getRowCount() {
339: return results.getRowCount();
340: }
341:
342: public Object getValueAt(int row, int column) {
343: return results.getValueAt(row, column);
344: }
345:
346: public IPentahoResultSet memoryCopy() {
347: return results.memoryCopy();
348: }
349:
350: public void beforeFirst() {
351: results.beforeFirst();
352: }
353:
354: public Object[] getDataColumn(int column) {
355: return results.getDataColumn(column);
356: }
357:
358: public Object[] getDataRow(int row) {
359: return results.getDataRow(row);
360: }
361: }
|