View Javadoc

1   /*
2    * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/config/DbFormsConfig.java,v 1.32 2006/01/28 10:14:06 hkollmann Exp $
3    * $Revision: 1.32 $
4    * $Date: 2006/01/28 10:14:06 $
5    *
6    */
7   
8   package org.dbforms.config;
9   
10  import org.apache.commons.logging.Log;
11  import org.apache.commons.logging.LogFactory;
12  
13  import org.dbforms.dom.DOMFactory;
14  import org.dbforms.interfaces.IEscaper;
15  
16  import org.dbforms.util.ReflectionUtil;
17  import org.dbforms.util.Util;
18  
19  import java.io.File;
20  import java.sql.Connection;
21  import java.sql.SQLException;
22  
23  import java.util.ArrayList;
24  import java.util.Hashtable;
25  import java.util.Vector;
26  
27  import javax.servlet.ServletConfig;
28  import javax.servlet.ServletContext;
29  
30  import javax.sql.DataSource;
31  
32  import javax.servlet.jsp.el.ELException;
33  import javax.servlet.jsp.el.ExpressionEvaluator;
34  import javax.servlet.jsp.el.VariableResolver;
35  
36  /***
37   * <p>
38   * This class gets populated with data from the dbforms-config.xml file by the
39   * ConfigServlet. This class is a kind of "single point of entry" for
40   * configuration data: it contains the definitions of tables, fields,
41   * fieldtypes, keys etc. and even the definitions of data sources (see
42   * dbforms-config.xml) Many components of the dbforms-frameworks use the data
43   * stored in this class.
44   * </p>
45   * 
46   * @author Joe Peer
47   */
48  public class DbFormsConfig {
49  	/*** DOCUMENT ME! */
50  	public static final String CONFIG = "dbformsConfig";
51  
52  	/*** contains connection put by addDbConnection */
53  	private ArrayList dbConnectionsList = new ArrayList();
54  
55  	/*** the default db connection */
56  	private DbConnection defaultDbConnection;
57  
58  	private IEscaper escaper = null;
59  
60  	private Hashtable dbConnectionsHash = new Hashtable();
61  
62  	/*** for quicker lookup by name */
63  	private Hashtable tableNameHash = new Hashtable();
64  
65  	private Log logCat = LogFactory.getLog(this.getClass().getName());
66  
67  	private ServletConfig servletConfig;
68  
69  	private String defaultEscaperClass = "org.dbforms.util.DefaultEscaperImpl";
70  
71  	private String defaultFormatterClass = "org.dbforms.util.DefaultFormatEmbeddedDataImpl";
72  
73  	/*** global application hookups */
74  	private Vector interceptors = new Vector();
75  
76  	private Vector tables = new Vector();
77  
78  	private String resolveConfigPropertyClass;
79  
80  	private Hashtable params = new Hashtable();
81  
82  	/***
83  	 * Creates a new DbFormsConfig object.
84  	 * 
85  	 * @param realPath
86  	 *            local path to the application on local server
87  	 */
88  	public DbFormsConfig() {
89  	}
90  
91  	/***
92  	 * Just returns the default connection
93  	 * 
94  	 * @return a JDBC connection object
95  	 * 
96  	 * @throws IllegalArgumentException
97  	 *             if any error occurs
98  	 */
99  	public Connection getConnection() throws IllegalArgumentException,
100 			SQLException {
101 		return getConnection(null);
102 	}
103 
104 	/***
105 	 * Get a connection using the connection name specified into the xml
106 	 * configuration file.
107 	 * 
108 	 * @param dbConnectionName
109 	 *            the name of the DbConnection element
110 	 * 
111 	 * @return a JDBC connection object
112 	 * 
113 	 * @throws IllegalArgumentException
114 	 *             if any error occurs
115 	 */
116 	public Connection getConnection(String dbConnectionName)
117 			throws IllegalArgumentException, SQLException {
118 		DataSource dbConnection = null;
119 		Connection con = null;
120 
121 		// get the DbConnection object having the input name;
122 		if ((dbConnection = getDataSource(dbConnectionName)) == null) {
123 			throw new IllegalArgumentException(
124 					"No DbConnection object configured with name '"
125 							+ dbConnectionName + "'");
126 		}
127 
128 		// now try to get the JDBC connection from the retrieved DbConnection
129 		// object;
130 		if ((con = dbConnection.getConnection()) == null) {
131 			throw new IllegalArgumentException(
132 					"JDBC-Troubles:  was not able to create connection from "
133 							+ dbConnection);
134 		}
135 
136 		return con;
137 	}
138 
139 	/***
140 	 * DOCUMENT ME!
141 	 * 
142 	 * @param string
143 	 */
144 	public void setDOMFactoryClass(String string) {
145 		DOMFactory.setFactoryClass(string);
146 	}
147 
148 	public void setResolveConfigPropertyClass(String resolveConfigPropertyClass) {
149 		this.resolveConfigPropertyClass = resolveConfigPropertyClass;
150 	}
151 
152 	/***
153 	 * DOCUMENT ME!
154 	 * 
155 	 * @param dbConnectionName
156 	 *            DOCUMENT ME!
157 	 * 
158 	 * @return DOCUMENT ME!
159 	 */
160 	public DataSource getDataSource(String dbConnectionName) {
161 		DbConnection connection = null;
162 
163 		if (!Util.isNull(dbConnectionName)) {
164 			try {
165 				connection = (DbConnection) dbConnectionsList.get(Integer
166 						.parseInt(dbConnectionName));
167 			} catch (Exception ex) {
168 				// wanted! logCat.error("getDbConnection", ex);
169 				connection = null;
170 			}
171 
172 			if (connection == null) {
173 				connection = (DbConnection) dbConnectionsHash
174 						.get(dbConnectionName);
175 			}
176 		}
177 
178 		if (connection == null) {
179 			connection = defaultDbConnection;
180 		}
181 
182 		if ((connection != null)
183 				&& !Util.isNull(connection.getContextDataSource())) {
184 			DataSource ds = (DataSource) getServletContext().getAttribute(
185 					connection.getContextDataSource());
186 
187 			if (ds != null) {
188 				return ds;
189 			}
190 		}
191 
192 		return connection;
193 	}
194 
195 	/***
196 	 * DOCUMENT ME!
197 	 * 
198 	 * @param string
199 	 */
200 	public void setDefaultEscaperClass(String string) {
201 		defaultEscaperClass = string;
202 	}
203 
204 	/***
205 	 * DOCUMENT ME!
206 	 * 
207 	 * @return
208 	 */
209 	public String getDefaultEscaperClass() {
210 		return defaultEscaperClass;
211 	}
212 
213 	/***
214 	 * DOCUMENT ME!
215 	 * 
216 	 * @param string
217 	 */
218 	public void setDefaultFormatterClass(String string) {
219 		defaultFormatterClass = string;
220 	}
221 
222 	/***
223 	 * DOCUMENT ME!
224 	 * 
225 	 * @return
226 	 */
227 	public String getDefaultFormatterClass() {
228 		return defaultFormatterClass;
229 	}
230 
231 	/***
232 	 * DOCUMENT ME!
233 	 * 
234 	 * @return DOCUMENT ME!
235 	 */
236 	public IEscaper getEscaper() {
237 		if (escaper == null) {
238 			String s = getDefaultEscaperClass();
239 
240 			if (!Util.isNull(s)) {
241 				try {
242 					escaper = (IEscaper) ReflectionUtil.newInstance(s);
243 				} catch (Exception e) {
244 					logCat
245 							.error("cannot create the new escaper [" + s + "]",
246 									e);
247 				}
248 			}
249 		}
250 
251 		return escaper;
252 	}
253 
254 	/***
255 	 * Get all the global interceptor objects
256 	 * 
257 	 * @return a vector containing all the interceptor objects
258 	 */
259 	public Vector getInterceptors() {
260 		return interceptors;
261 	}
262 
263 	public String getRealPath() {
264 		String realPath = getServletConfig().getServletContext().getRealPath("/");
265 		if (!Util.isNull(realPath)) {
266 			realPath = realPath.replace('/', File.separatorChar);
267 			realPath = realPath.replace('//', File.separatorChar);
268 			// 20030604-HKK: Bugfixing for different engine, e.g. cactus. Path
269 			// maybe without trailing '/'!!!
270 			if (realPath.charAt(realPath.length() - 1) != File.separatorChar) {
271 				realPath = realPath + File.separatorChar;
272 			}
273 		}
274 		return realPath;
275 	}
276 
277 	/***
278 	 * DOCUMENT ME!
279 	 * 
280 	 * @param servletConfig
281 	 *            DOCUMENT ME!
282 	 */
283 	public void setServletConfig(ServletConfig servletConfig) {
284 		this.servletConfig = servletConfig;
285 	}
286 
287 	/***
288 	 * get access to configuration of config servlet
289 	 * 
290 	 * @return the store config
291 	 */
292 	public ServletConfig getServletConfig() {
293 		return servletConfig;
294 	}
295 
296 	/***
297 	 * Get access to servlet context in order to interoperate with other
298 	 * components of the web application
299 	 * 
300 	 * @return the stored context
301 	 */
302 	public ServletContext getServletContext() {
303 		return servletConfig.getServletContext();
304 	}
305 
306 	/***
307 	 * DOCUMENT ME!
308 	 * 
309 	 * @param index
310 	 *            DOCUMENT ME!
311 	 * 
312 	 * @return DOCUMENT ME!
313 	 */
314 	public Table getTable(int index) {
315 		try {
316 			return (Table) tables.elementAt(index);
317 		} catch (Exception e) {
318 			return null;
319 		}
320 	}
321 
322 	/***
323 	 * DOCUMENT ME!
324 	 * 
325 	 * @param name
326 	 *            DOCUMENT ME!
327 	 * 
328 	 * @return DOCUMENT ME!
329 	 */
330 	public Table getTableByName(String name) {
331 		try {
332 			return (Table) tableNameHash.get(name);
333 		} catch (Exception e) {
334 			return null;
335 		}
336 	}
337 
338 	/***
339 	 * DOCUMENT ME!
340 	 * 
341 	 * @param dbConnection
342 	 *            DOCUMENT ME!
343 	 */
344 	public void addDbConnection(DbConnection dbConnection) {
345 		dbConnection.setName(replaceVariables(dbConnection.getName()));
346 		dbConnectionsList.add(dbConnection);
347 
348 		if (!Util.isNull(dbConnection.getId())) {
349 			dbConnectionsHash.put(dbConnection.getId(), dbConnection);
350 		}
351 
352 		// if a default connection does not exist yet,
353 		// use the input connection as the default one;
354 		if ((dbConnection.isDefaultConnection() && ((defaultDbConnection == null) || !defaultDbConnection
355 				.isDefaultConnection()))
356 				|| (defaultDbConnection == null)) {
357 			defaultDbConnection = dbConnection;
358 			dbConnection.setDefaultConnection(true);
359 		}
360 
361 		logCat.info("::addDbConnection - added the dbConnection ["
362 				+ dbConnection + "]");
363 	}
364 
365 	/***
366 	 * Add an global interceptor
367 	 * 
368 	 * @param interceptor
369 	 *            the interceptor to add
370 	 */
371 	public void addInterceptor(Interceptor interceptor) {
372 		interceptors.addElement(interceptor);
373 	}
374 
375 	public void addParam(String name, String value) {
376 		params.put(name, value);
377 	}
378 
379 	/***
380 	 * DOCUMENT ME!
381 	 * 
382 	 * @param table
383 	 *            DOCUMENT ME!
384 	 */
385 	public void addTable(Table table) {
386 		logCat.info("add table called");
387 		table.setId(tables.size());
388 		table.initDefaultOrder();
389 		tables.addElement(table);
390 		tableNameHash.put(table.getName(), table);
391 	}
392 
393 	/***
394 	 * Check if this table has got interceptors.
395 	 * 
396 	 * @return true if the table contains interceptors, false otherwise
397 	 */
398 	public boolean hasInterceptors() {
399 		return (interceptors != null) && (interceptors.size() > 0);
400 	}
401 
402 	/***
403 	 * DOCUMENT ME!
404 	 * 
405 	 * @return DOCUMENT ME!
406 	 */
407 	public String toString() {
408 		StringBuffer buf = new StringBuffer();
409 
410 		for (int i = 0; i < tables.size(); i++) {
411 			Table t = (Table) tables.elementAt(i);
412 			buf.append("table:\n");
413 			buf.append(t.toString());
414 		}
415 
416 		return buf.toString();
417 	}
418 
419 	/***
420 	 * Replaces the occurens from REALPATH in s with realpath.
421 	 * 
422 	 * @param s
423 	 *            the string containing the REALPATH token
424 	 * @param realpath
425 	 *            the value used to replace the REALPATH token
426 	 * 
427 	 * @return the input string, with the REALPATH token replaced with the
428 	 *         realpath value
429 	 */
430 	public String replaceVariables(String s) {
431 		ExpressionEvaluator elExprEval = new org.apache.commons.el.ExpressionEvaluatorImpl();
432 		VariableResolver extResolver = null;
433 		if (!Util.isNull(resolveConfigPropertyClass)) {
434 			try {
435 				extResolver = (VariableResolver) ReflectionUtil
436 						.newInstance(resolveConfigPropertyClass);
437 			} catch (Exception e) {
438 				logCat.error("cannot create the new resolver ["
439 						+ resolveConfigPropertyClass + "]", e);
440 			}
441 		}
442 		VariableResolver resolver = new Resolver(this, extResolver);
443 		try {
444 			s = (String) elExprEval.evaluate(s, String.class, resolver, null);
445 		} catch (Exception ex) {
446 			logCat.error(ex);
447 		}
448 		return s;
449 	}
450 
451 	private class Resolver implements VariableResolver {
452 
453 		private static final String REALPATH = "SERVLETCONTEXT_REALPATH";
454 
455 		DbFormsConfig conf;
456 
457 		VariableResolver resolver;
458 
459 		private Resolver(DbFormsConfig conf, VariableResolver resolver) {
460 			this.conf = conf;
461 			this.resolver = resolver;
462 		}
463 
464 		public Object resolveVariable(String arg0) throws ELException {
465 			if (REALPATH.equals(arg0)) {
466 				return conf.getRealPath();
467 			}
468 			Object res = null;
469 			res = params.get(arg0);
470 			if (Util.isNull((String) res) && (resolver != null)) {
471 				res = resolver.resolveVariable(arg0);
472 			}
473 			return res;
474 		}
475 	}
476 }