KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > tags > MondrianModelFactory


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  *
12  */

13 package com.tonbeller.jpivot.tags;
14
15 import java.io.IOException JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.sql.Connection JavaDoc;
18 import java.sql.SQLException JavaDoc;
19
20 import javax.naming.InitialContext JavaDoc;
21 import javax.sql.DataSource JavaDoc;
22
23 import org.apache.log4j.Logger;
24 import org.xml.sax.SAXException JavaDoc;
25
26 import com.tonbeller.jpivot.core.ModelFactory;
27 import com.tonbeller.jpivot.mondrian.MondrianModel;
28 import com.tonbeller.tbutils.res.Resources;
29 import com.tonbeller.wcf.controller.RequestContext;
30 import com.tonbeller.wcf.expr.ExprUtils;
31
32 /**
33  * creates a MondrianModel from config.xml
34  * @author av
35  */

36 public class MondrianModelFactory {
37   private static Logger logger = Logger.getLogger(MondrianModelFactory.class);
38
39   private MondrianModelFactory() {
40   }
41
42   static String JavaDoc makeConnectString(Config cfg) {
43
44     // for an external datasource, we do not need JdbcUrl *and* data source
45

46     // if ((cfg.getJdbcUrl() == null) == (cfg.getDataSource() == null))
47
// throw new IllegalArgumentException("exactly one of jdbcUrl or dataSource must be specified");
48

49     // provider=Mondrian;Jdbc=jdbc:odbc:MondrianFoodMart;Catalog=file:///c:/dev/mondrian/demo/FoodMart.xml
50
StringBuffer JavaDoc sb = new StringBuffer JavaDoc("provider=Mondrian");
51     if (cfg.getJdbcUrl() != null) {
52       String JavaDoc jdbcUrl = cfg.getJdbcUrl();
53       sb.append(";Jdbc=");
54       // if the url contains a semicolon, it must be in quotes
55
if (jdbcUrl.indexOf(';') >= 0) {
56         char c = jdbcUrl.charAt(0);
57         if (c != '"' && c != '\'') {
58           char escape = '"';
59           if (jdbcUrl.indexOf('"') >= 0) {
60             if (jdbcUrl.indexOf('\'') >= 0) {
61               // this is not valid
62
throw new IllegalArgumentException JavaDoc(
63                   "jdbcUrl is not valid - contains single and double quotes");
64             }
65             escape = '\'';
66           }
67           sb.append(escape);
68           sb.append(jdbcUrl);
69           sb.append(escape);
70         } else
71           sb.append(jdbcUrl); // already quoted
72
} else
73         sb.append(jdbcUrl); // no quotes neccessary
74

75       if (cfg.getJdbcUser() != null)
76         sb.append(";JdbcUser=").append(cfg.getJdbcUser());
77       if (cfg.getJdbcPassword() != null && cfg.getJdbcPassword().length() > 0)
78         sb.append(";JdbcPassword=").append(cfg.getJdbcPassword());
79     } else if (cfg.getDataSource() != null) {
80       sb.append(";DataSource=java:comp/env/").append(cfg.getDataSource());
81       testDataSource(cfg.getDataSource());
82     }
83     sb.append(";Catalog=").append(cfg.getSchemaUrl());
84
85     if (cfg.getDynLocale() != null)
86       sb.append(";Locale=").append(cfg.getDynLocale());
87
88     // debug
89
if (cfg.getRole() != null) {
90       sb.append(";Role=").append(cfg.getRole());
91     }
92     if (cfg.getDataSourceChangeListener() != null) {
93         sb.append(";dataSourceChangeListener=").append(cfg.getDataSourceChangeListener());
94     }
95     // sb.append(";Role=California manager");
96
return sb.toString();
97   }
98
99   private static void testDataSource(String JavaDoc dataSourceName) {
100     final DataSource JavaDoc dataSource;
101     Connection JavaDoc connection = null;
102     String JavaDoc dsName = "java:comp/env/" + dataSourceName;
103     try {
104       dataSource = (DataSource JavaDoc) new InitialContext JavaDoc().lookup(dsName);
105       connection = dataSource.getConnection();
106     } catch (Throwable JavaDoc e) {
107       String JavaDoc msg = "Datasource " + dsName + " is not configured properly";
108       logger.error(msg, e);
109       throw new RuntimeException JavaDoc(msg, e);
110     } finally {
111       if (connection != null)
112         try {
113           connection.close();
114         } catch (SQLException JavaDoc e) {
115           logger.error("could not close SQL Connection for DataSource " + dataSourceName, e);
116         }
117     }
118   }
119
120   public static MondrianModel instance() throws SAXException JavaDoc, IOException JavaDoc {
121     URL JavaDoc url = MondrianModel.class.getResource("config.xml");
122     return (MondrianModel) ModelFactory.instance(url);
123   }
124
125   public static MondrianModel instance(Config cfg) throws SAXException JavaDoc, IOException JavaDoc {
126     URL JavaDoc url = MondrianModel.class.getResource("config.xml");
127     return instance(url, cfg);
128   }
129
130   public static MondrianModel instance(URL JavaDoc url, Config cfg) throws SAXException JavaDoc, IOException JavaDoc {
131     if (logger.isInfoEnabled()) {
132       logger.info(cfg.toString());
133       logger.info("ConnectString=" + makeConnectString(cfg));
134     }
135     MondrianModel mm = (MondrianModel) ModelFactory.instance(url);
136     mm.setMdxQuery(cfg.getMdxQuery());
137     mm.setConnectString(makeConnectString(cfg));
138     mm.setJdbcDriver(cfg.getJdbcDriver());
139     mm.setDynresolver(cfg.getDynResolver());
140     mm.setDynLocale(cfg.getDynLocale());
141     mm.setDataSourceChangeListener( cfg.getDataSourceChangeListener());
142
143     if ("false".equalsIgnoreCase(cfg.getConnectionPooling()))
144       mm.setConnectionPooling(false);
145     mm.setExternalDataSource(cfg.getExternalDataSource());
146     return mm;
147   }
148
149   public static class Config {
150     String JavaDoc jdbcUrl;
151     String JavaDoc jdbcDriver;
152     String JavaDoc jdbcUser;
153     String JavaDoc jdbcPassword;
154     // name of datasource, i.e. "jdbc/JPivotDS"
155
String JavaDoc dataSource;
156     String JavaDoc schemaUrl;
157     String JavaDoc mdxQuery;
158     String JavaDoc role;
159     String JavaDoc dynResolver;
160     // Locale requested
161
String JavaDoc dynLocale;
162
163     String JavaDoc connectionPooling;
164     // external DataSource to be used by Mondrian
165
DataSource JavaDoc externalDataSource = null;
166     
167     String JavaDoc dataSourceChangeListener;
168
169     /**
170      * allows to override the current JDBC settings.
171      * <p>
172      * All properties are allowed
173      * to contain ${some.name} that refer to other properties except the
174      * dataSource attribute where ${bean.property} is interpreted as bean EL that
175      * references session beans.
176      * <p>
177      * If a dataSource name is given, it is looked up as bean EL. If the result
178      * is a DataSource, its used (e.g. the session contains a DataSource). If not,
179      * its interpreted as JNDI name.
180      * <p>
181      * If no dataSource name is given, values for jdbcDriver etc are needed. If these
182      * values are present, they are taken. Otherwise, they are looked up in the resources
183      * with the keys "jdbc.driver", "jdbc.url", "jdbc.user" and "jdbc.password".
184      */

185     public void allowOverride(RequestContext context) {
186       Resources res = context.getResources();
187
188       // get default values
189
setRole(getDefault(res, "mondrian.role", getRole()));
190       setDynResolver(getDefault(res, "mondrian.dynResolver", getDynResolver()));
191       setDynLocale(getDefault(res, "mondrian.dynLocale", getDynLocale()));
192       
193       setDataSourceChangeListener(getDefault(res, "mondrian.dataSourceChangeListener", getDataSourceChangeListener()));
194
195       // if the data source is configured, use it
196
if (externalDataSource != null) {
197         logger.info("using external data source");
198         return;
199       }
200
201       // support $-variables
202
setJdbcDriver(replace(res, getJdbcDriver()));
203       setJdbcUrl(replace(res, getJdbcUrl()));
204       setJdbcUser(replace(res, getJdbcUser()));
205       setJdbcPassword(replace(res, getJdbcPassword()));
206       setConnectionPooling(replace(res, getConnectionPooling()));
207       setDataSource(replace(res, getDataSource()));
208
209       // if a data source name was given, use it
210
if (!empty(dataSource)) {
211         logger.info("using data source " + dataSource);
212         findDataSource(context);
213         return;
214       }
215       
216       // if a jdbc driver was given, use it
217
if (!empty(jdbcDriver)) {
218         logger.info("using driver manager " + jdbcUrl);
219         return;
220       }
221       
222       // try default data source
223
setDataSource(getDefault(res, "jdbc.datasource", getDataSource()));
224       if (!empty(dataSource)) {
225         logger.info("using default data source " + dataSource);
226         findDataSource(context);
227         return;
228       }
229
230       // try default jdbc drivermanager
231
logger.info("using default driver manager " + jdbcUrl);
232       setJdbcDriver(getDefault(res, "jdbc.driver", getJdbcDriver()));
233       setJdbcUrl(getDefault(res, "jdbc.url", getJdbcUrl()));
234       setJdbcUser(getDefault(res, "jdbc.user", getJdbcUser()));
235       setJdbcPassword(getDefault(res, "jdbc.password", getJdbcPassword()));
236       setConnectionPooling(getDefault(res, "jdbc.connectionPooling", getConnectionPooling()));
237     }
238
239     /**
240      * tries to find a DataSource as a bean EL in the current request or session. If not
241      * found, <code>dataSource</code> is interpreted as JNDI data source.
242      */

243     private void findDataSource(RequestContext context) {
244       Object JavaDoc obj;
245       if (ExprUtils.isExpression(dataSource)) {
246         // try "${bean.dataSource}"
247
obj = context.getModelReference(dataSource);
248       } else {
249         // try "beanName"
250
obj = context.getSession().getAttribute(dataSource);
251       }
252       if (obj instanceof DataSource JavaDoc) {
253         logger.info("using app dataSource " + dataSource);
254         this.dataSource = null;
255         this.externalDataSource = (DataSource JavaDoc) obj;
256       }
257       // otherwise use it as jndi name
258
}
259
260     /**
261      * falls <code>val == null</code>, wird der default aus den resources geladen.
262      * $-Variablen werden ersetzt.
263      */

264     private String JavaDoc getDefault(Resources res, String JavaDoc key, String JavaDoc val) {
265       // if given, dont change
266
val = replace(res, val);
267       if (val != null)
268         return val;
269       return res.getOptionalString(key, null);
270     }
271     
272     /**
273      * returns null for empty strings
274      */

275     private String JavaDoc replace(Resources res, String JavaDoc val) {
276       if (empty(val))
277         return null;
278       return res.replace(val);
279     }
280
281     private boolean empty(String JavaDoc s) {
282       return s == null || s.trim().length() == 0;
283     }
284
285     /**
286      * Returns the jdbcDriver.
287      * @return String
288      */

289     public String JavaDoc getJdbcDriver() {
290       return jdbcDriver;
291     }
292
293     /**
294      * Returns the jdbcPassword.
295      * @return String
296      */

297     public String JavaDoc getJdbcPassword() {
298       return jdbcPassword;
299     }
300
301     /**
302      * Returns the jdbcUrl.
303      * @return String
304      */

305     public String JavaDoc getJdbcUrl() {
306       return jdbcUrl;
307     }
308
309     /**
310      * Returns the jdbcUser.
311      * @return String
312      */

313     public String JavaDoc getJdbcUser() {
314       return jdbcUser;
315     }
316
317     /**
318      * Returns the mdxQuery.
319      * @return String
320      */

321     public String JavaDoc getMdxQuery() {
322       return mdxQuery;
323     }
324
325     /**
326      * Returns the schemaUrl.
327      * @return String
328      */

329     public String JavaDoc getSchemaUrl() {
330       return schemaUrl;
331     }
332
333     /**
334      * Returns the role.
335      * @return String
336      */

337     public String JavaDoc getRole() {
338       return role;
339     }
340
341     /**
342      * Sets the role.
343      * @param role The role to set
344      */

345     public void setRole(String JavaDoc role) {
346       this.role = role;
347     }
348
349     /**
350      * Sets the jdbcDriver.
351      * @param jdbcDriver The jdbcDriver to set
352      */

353     public void setJdbcDriver(String JavaDoc jdbcDriver) {
354       this.jdbcDriver = jdbcDriver;
355     }
356
357     /**
358      * Sets the jdbcPassword.
359      * @param jdbcPassword The jdbcPassword to set
360      */

361     public void setJdbcPassword(String JavaDoc jdbcPassword) {
362       this.jdbcPassword = jdbcPassword;
363     }
364
365     /**
366      * Sets the jdbcUrl.
367      * @param jdbcUrl The jdbcUrl to set
368      */

369     public void setJdbcUrl(String JavaDoc jdbcUrl) {
370       this.jdbcUrl = jdbcUrl;
371     }
372
373     /**
374      * Sets the jdbcUser.
375      * @param jdbcUser The jdbcUser to set
376      */

377     public void setJdbcUser(String JavaDoc jdbcUser) {
378       this.jdbcUser = jdbcUser;
379     }
380
381     /**
382      * Sets the mdxQuery.
383      * @param mdxQuery The mdxQuery to set
384      */

385     public void setMdxQuery(String JavaDoc mdxQuery) {
386       this.mdxQuery = mdxQuery;
387     }
388
389     /**
390      * Sets the schemaUrl.
391      * @param schemaUrl The schemaUrl to set
392      */

393     public void setSchemaUrl(String JavaDoc schemaUrl) {
394       this.schemaUrl = schemaUrl;
395     }
396
397     /**
398      * @return
399      */

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

407     public void setDataSource(String JavaDoc string) {
408       dataSource = string;
409     }
410
411     public String JavaDoc getDynResolver() {
412       return dynResolver;
413     }
414
415     public void setDynResolver(String JavaDoc dynResolver) {
416       this.dynResolver = dynResolver;
417     }
418
419     public String JavaDoc getConnectionPooling() {
420       return connectionPooling;
421     }
422
423     public void setConnectionPooling(String JavaDoc connectionPooling) {
424       this.connectionPooling = connectionPooling;
425     }
426
427     public DataSource JavaDoc getExternalDataSource() {
428       return externalDataSource;
429     }
430
431     public void setExternalDataSource(DataSource JavaDoc externalDataSource) {
432       this.externalDataSource = externalDataSource;
433     }
434
435     /**
436      * Getter for property dynLocale.
437      * @return Value of property dynLocale.
438      */

439     public String JavaDoc getDynLocale() {
440       return this.dynLocale;
441     }
442
443     /**
444      * Setter for property dynLocale.
445      * @param dynLocale New value of property dynLocale.
446      */

447     public void setDynLocale(String JavaDoc dynLocale) {
448       this.dynLocale = dynLocale;
449     }
450
451     public String JavaDoc toString() {
452       return "Config[" + "jdbcUrl=" + jdbcUrl + ", jdbcDriver=" + jdbcDriver + ", jdbcUser="
453           + jdbcUser + ", jdbcPassword=" + jdbcPassword + ", dataSource=" + dataSource
454           + ", schemaUrl=" + schemaUrl + ", mdxQuery=" + mdxQuery + ", role=" + role
455           + ", dynResolver=" + dynResolver + ", connectionPooling=" + connectionPooling
456           + ", externalDataSource=" + externalDataSource + ", dynLocale=" + dynLocale + ", dataSourceChangeListener=" + dataSourceChangeListener + "]";
457     }
458     /**
459      * Getter for property dataSourceChangeListener.
460      * @return Value of property dataSourceChangeListener.
461      */

462
463     public String JavaDoc getDataSourceChangeListener() {
464         return dataSourceChangeListener;
465     }
466     /**
467      * Setter for property dataSourceChangeListener.
468      * @param dataSourceChangeListener New value of property dataSourceChangeListener.
469      */

470
471     public void setDataSourceChangeListener(String JavaDoc dataSourceChangeListener) {
472         this.dataSourceChangeListener = dataSourceChangeListener;
473     }
474   }
475 }
Popular Tags