KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > mondrian > script > ScriptableMondrianDrillThroughTableModel


1 /*
2  * ====================================================================
3  * This software is subject to the terms of the Common Public License
4  * Agreement, available at the following URL:
5  * http://www.opensource.org/licenses/cpl.html .
6  * Copyright (C) 2003-2004 TONBELLER AG.
7  * All Rights Reserved.
8  * You must accept the terms of that agreement to use this software.
9  * ====================================================================
10  */

11 package com.tonbeller.jpivot.mondrian.script;
12
13 import groovy.lang.Binding;
14 import groovy.util.GroovyScriptEngine;
15
16 import java.io.InputStream JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.sql.Connection JavaDoc;
19 import java.sql.DriverManager JavaDoc;
20 import java.sql.ResultSet JavaDoc;
21 import java.sql.ResultSetMetaData JavaDoc;
22 import java.sql.SQLException JavaDoc;
23 import java.sql.Statement JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.ListIterator JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import javax.naming.Context JavaDoc;
31 import javax.naming.InitialContext JavaDoc;
32 import javax.naming.NamingException JavaDoc;
33 import javax.sql.DataSource JavaDoc;
34
35 import mondrian.rolap.RolapConnectionProperties;
36
37 import org.apache.commons.digester.Digester;
38 import org.apache.log4j.Logger;
39
40 import com.tonbeller.jpivot.mondrian.MondrianDrillThroughTableModel;
41 import com.tonbeller.wcf.table.AbstractTableModel;
42 import com.tonbeller.wcf.table.DefaultCell;
43 import com.tonbeller.wcf.table.DefaultTableRow;
44 import com.tonbeller.wcf.table.TableRow;
45
46 /**
47  * @author Engineering Ingegneria Informatica S.p.A. - Luca Barozzi
48  *
49  * A wcf table model for drill through data,
50  * requires an sql query and connection information to be set.
51  */

52
53 public class ScriptableMondrianDrillThroughTableModel extends AbstractTableModel {
54   private static Logger logger = Logger.getLogger(MondrianDrillThroughTableModel.class);
55   private String JavaDoc title = "Drill Through Table";
56   private String JavaDoc caption = "";
57   private String JavaDoc sql = "";
58   private String JavaDoc jdbcUser;
59   private String JavaDoc jdbcUrl;
60   private String JavaDoc jdbcPassword;
61   private String JavaDoc jdbcDriver;
62   private String JavaDoc dataSourceName;
63   private String JavaDoc catalogExtension;
64   private int maxResults;
65   private String JavaDoc scriptRootUrl;
66   private List JavaDoc scripts = new ArrayList JavaDoc();
67   private GroovyScriptEngine scriptEngine = null;
68
69   private DataSource JavaDoc dataSource;
70   private static Context JavaDoc jndiContext;
71
72   private boolean ready = false;
73
74   private TableRow[] rows = new TableRow[0];
75   private String JavaDoc[] columnTitles = new String JavaDoc[0];
76
77   public ScriptableMondrianDrillThroughTableModel() {
78   }
79
80   public int getRowCount() {
81     if (!ready) {
82       executeQuery();
83     }
84     return rows.length;
85   }
86
87   public TableRow getRow(int rowIndex) {
88     if (!ready) {
89       executeQuery();
90     }
91     return rows[rowIndex];
92   }
93
94   public String JavaDoc getTitle() {
95     return title;
96   }
97
98   /**
99    * @return
100    */

101   public String JavaDoc getSql() {
102     return sql;
103   }
104
105   /**
106    * @param sql
107    */

108   public void setSql(String JavaDoc sql) {
109     this.sql = sql;
110     this.ready = false;
111   }
112
113   /**
114    * @param title
115    */

116   public void setTitle(String JavaDoc title) {
117     this.title = title;
118   }
119
120   /**
121    * wcf table component calls this method from it's constructor
122    * to get the number of columns
123    *
124    */

125   public int getColumnCount() {
126     if (!ready) {
127       executeQuery();
128     }
129     return columnTitles.length;
130   }
131
132   public String JavaDoc getColumnTitle(int columnIndex) {
133     if (!ready) {
134       executeQuery();
135     }
136     return columnTitles[columnIndex];
137   }
138
139   /**
140    * execute sql query
141    * @throws Exception
142    */

143   private void executeQuery() {
144     Connection JavaDoc con = null;
145     try {
146       InputStream JavaDoc catExtIs = ScriptableMondrianDrillThroughTableModel.class.getClassLoader().getResourceAsStream(
147           "/" + catalogExtension);
148       if (catExtIs != null) {
149         Digester catExtDigester = new Digester();
150         catExtDigester.push(this);
151         catExtDigester.addSetProperties("extension");
152         catExtDigester.addObjectCreate("extension/script", "com.tonbeller.jpivot.mondrian.script.ScriptColumn");
153         catExtDigester.addSetProperties("extension/script");
154         catExtDigester.addSetNext("extension/script", "addScript");
155         catExtDigester.parse(catExtIs);
156
157         URL JavaDoc scriptsBaseURL = Thread.currentThread().getContextClassLoader().getResource(scriptRootUrl);
158         scriptEngine = new GroovyScriptEngine(new URL JavaDoc[] { scriptsBaseURL});
159       }
160       con = getConnection();
161       Statement JavaDoc s = con.createStatement();
162       s.setMaxRows(maxResults);
163       ResultSet JavaDoc rs = s.executeQuery(sql);
164       ResultSetMetaData JavaDoc md = rs.getMetaData();
165       int numCols = md.getColumnCount();
166       List JavaDoc columnTitlesList = new ArrayList JavaDoc();
167       // set column headings
168
for (int i = 0; i < numCols; i++) {
169         // columns are 1 based
170
columnTitlesList.add(i, md.getColumnName(i + 1));
171       }
172       // loop on script columns
173
for (ListIterator JavaDoc sIt = scripts.listIterator(); sIt.hasNext();) {
174         final ScriptColumn sc = (ScriptColumn) sIt.next();
175         columnTitlesList.add(sc.getPosition() - 1, sc.getTitle());
176       }
177       columnTitles = (String JavaDoc[]) columnTitlesList.toArray(new String JavaDoc[0]);
178       // loop through rows
179
List JavaDoc tempRows = new ArrayList JavaDoc();
180       Map JavaDoc scriptInput = new HashMap JavaDoc();
181       Binding binding = new Binding();
182       while (rs.next()) {
183         List JavaDoc rowList = new ArrayList JavaDoc();
184         scriptInput.clear();
185         // loop on columns, 1 based
186
for (int i = 0; i < numCols; i++) {
187           rowList.add(i, rs.getObject(i + 1));
188           scriptInput.put(columnTitles[i], rs.getObject(i + 1));
189         }
190         binding.setVariable("input", scriptInput);
191         // loop on script columns
192
for (ListIterator JavaDoc sIt = scripts.listIterator(); sIt.hasNext();) {
193           final ScriptColumn sc = (ScriptColumn) sIt.next();
194           scriptEngine.run(sc.getFile(), binding);
195           final Object JavaDoc output = binding.getVariable("output");
196           if (output instanceof Map JavaDoc) {
197             Map JavaDoc outMap = (Map JavaDoc) output;
198             rowList
199                 .add(sc.getPosition() - 1, new DefaultCell((String JavaDoc) outMap.get("URL"), (String JavaDoc) outMap.get("Value")));
200           } else if (output instanceof String JavaDoc) {
201             rowList.add(sc.getPosition() - 1, (String JavaDoc) output);
202           } else {
203             throw new Exception JavaDoc("Unknown groovy script return type (not a Map nor String).");
204           }
205         }
206         tempRows.add(new DefaultTableRow(rowList.toArray()));
207       }
208       rs.close();
209       rows = (TableRow[]) tempRows.toArray(new TableRow[0]);
210     } catch (Exception JavaDoc e) {
211       e.printStackTrace();
212       logger.error("?", e);
213       // problem occured, set table model to zero size
214
rows = new TableRow[1];
215       columnTitles = new String JavaDoc[1];
216       columnTitles[0] = "An error occured";
217       Object JavaDoc[] row = new Object JavaDoc[1];
218       row[0] = e.toString();
219       rows[0] = new DefaultTableRow(row);
220       ready = false;
221       return;
222     } finally {
223       try {
224         con.close();
225       } catch (Exception JavaDoc e1) {
226         // ignore
227
}
228     }
229     ready = true;
230   }
231
232   /**
233    * get sql connection
234    * @return
235    * @throws SQLException
236    */

237   private Connection JavaDoc getConnection() throws SQLException JavaDoc {
238     if (dataSourceName == null) {
239
240       if (jdbcUrl == null) { throw new RuntimeException JavaDoc("Mondrian Connect string '" + "' must contain either '"
241           + RolapConnectionProperties.Jdbc + "' or '" + RolapConnectionProperties.DataSource + "'"); }
242       return DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
243     } else {
244       return getDataSource().getConnection();
245     }
246   }
247
248   private DataSource JavaDoc getDataSource() {
249     if (dataSource == null) {
250       // Get connection from datasource.
251
try {
252         dataSource = (DataSource JavaDoc) getJndiContext().lookup(dataSourceName);
253       } catch (NamingException JavaDoc e) {
254         throw new RuntimeException JavaDoc("Error while looking up data source (" + dataSourceName + ")", e);
255       }
256     }
257     return dataSource;
258   }
259
260   private Context JavaDoc getJndiContext() throws NamingException JavaDoc {
261     if (jndiContext == null) {
262       jndiContext = new InitialContext JavaDoc();
263     }
264     return jndiContext;
265   }
266
267   /**
268    * @return
269    */

270   public String JavaDoc getJdbcDriver() {
271     return jdbcDriver;
272   }
273
274   /**
275    * @param jdbcDriver
276    */

277   public void setJdbcDriver(String JavaDoc jdbcDriver) {
278     this.jdbcDriver = jdbcDriver;
279   }
280
281   /**
282    * @return
283    */

284   public String JavaDoc getJdbcPassword() {
285     return jdbcPassword;
286   }
287
288   /**
289    * @param jdbcPassword
290    */

291   public void setJdbcPassword(String JavaDoc jdbcPassword) {
292     this.jdbcPassword = jdbcPassword;
293   }
294
295   /**
296    * @return
297    */

298   public String JavaDoc getJdbcUrl() {
299     return jdbcUrl;
300   }
301
302   /**
303    * @param jdbcUrl
304    */

305   public void setJdbcUrl(String JavaDoc jdbcUrl) {
306     this.jdbcUrl = jdbcUrl;
307   }
308
309   /**
310    * @return
311    */

312   public String JavaDoc getJdbcUser() {
313     return jdbcUser;
314   }
315
316   /**
317    * @param jdbcUser
318    */

319   public void setJdbcUser(String JavaDoc jdbcUser) {
320     this.jdbcUser = jdbcUser;
321   }
322
323   /**
324    * @return
325    */

326   public String JavaDoc getCaption() {
327     return caption;
328   }
329
330   /**
331    * @param caption
332    */

333   public void setCaption(String JavaDoc caption) {
334     this.caption = caption;
335   }
336
337   /**
338    * @return
339    */

340   public String JavaDoc getDataSourceName() {
341     return dataSourceName;
342   }
343
344   /**
345    * @param string
346    */

347   public void setDataSourceName(String JavaDoc string) {
348     dataSourceName = string;
349   }
350
351   /**
352    * @return
353    */

354   public String JavaDoc getCatalogExtension() {
355     return catalogExtension;
356   }
357
358   /**
359    * @param string
360    */

361   public void setCatalogExtension(String JavaDoc string) {
362     catalogExtension = string;
363   }
364
365   /**
366    * @return
367    */

368   public int getMaxResults() {
369     return maxResults;
370   }
371
372   /**
373    * @param string
374    */

375   public void setMaxResults(int maxResults) {
376     this.maxResults = maxResults;
377   }
378
379   /**
380    * @return
381    */

382   public List JavaDoc getScripts() {
383     return scripts;
384   }
385
386   /**
387    * @param List
388    */

389   public void setScripts(List JavaDoc scripts) {
390     this.scripts = scripts;
391   }
392
393   public void addScript(ScriptColumn column) {
394     this.scripts.add(column);
395   }
396
397   /**
398    * @return
399    */

400   public String JavaDoc getScriptRootUrl() {
401     return scriptRootUrl;
402   }
403
404   /**
405    * @param String
406    */

407   public void setScriptRootUrl(String JavaDoc scriptRootUrl) {
408     this.scriptRootUrl = scriptRootUrl;
409   }
410
411 }
412
Popular Tags