%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.torque.TorqueInstance |
|
|
1 | package org.apache.torque; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-2004 The Apache Software Foundation. |
|
5 | * |
|
6 | * Licensed under the Apache License, Version 2.0 (the "License") |
|
7 | * you may not use this file except in compliance with the License. |
|
8 | * You may obtain a copy of the License at |
|
9 | * |
|
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 | * |
|
12 | * Unless required by applicable law or agreed to in writing, software |
|
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 | * See the License for the specific language governing permissions and |
|
16 | * limitations under the License. |
|
17 | */ |
|
18 | ||
19 | import java.sql.Connection; |
|
20 | import java.sql.SQLException; |
|
21 | import java.util.ArrayList; |
|
22 | import java.util.Collections; |
|
23 | import java.util.HashMap; |
|
24 | import java.util.Iterator; |
|
25 | import java.util.List; |
|
26 | import java.util.Map; |
|
27 | ||
28 | import org.apache.commons.configuration.Configuration; |
|
29 | import org.apache.commons.configuration.ConfigurationException; |
|
30 | import org.apache.commons.configuration.PropertiesConfiguration; |
|
31 | import org.apache.commons.lang.StringUtils; |
|
32 | import org.apache.commons.logging.Log; |
|
33 | import org.apache.commons.logging.LogFactory; |
|
34 | import org.apache.torque.adapter.DB; |
|
35 | import org.apache.torque.adapter.DBFactory; |
|
36 | import org.apache.torque.dsfactory.AbstractDataSourceFactory; |
|
37 | import org.apache.torque.dsfactory.DataSourceFactory; |
|
38 | import org.apache.torque.manager.AbstractBaseManager; |
|
39 | import org.apache.torque.map.DatabaseMap; |
|
40 | import org.apache.torque.map.TableMap; |
|
41 | import org.apache.torque.oid.IDBroker; |
|
42 | import org.apache.torque.oid.IDGeneratorFactory; |
|
43 | import org.apache.torque.util.BasePeer; |
|
44 | ||
45 | /** |
|
46 | * The core of Torque's implementation. Both the classic {@link |
|
47 | * org.apache.torque.Torque} static wrapper and the {@link |
|
48 | * org.apache.torque.avalon.TorqueComponent} <a |
|
49 | * href="http://avalon.apache.org/">Avalon</a> implementation leverage |
|
50 | * this class. |
|
51 | * |
|
52 | * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> |
|
53 | * @author <a href="mailto:magnus@handtolvur.is">Magn�s ��r Torfason</a> |
|
54 | * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> |
|
55 | * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> |
|
56 | * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a> |
|
57 | * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> |
|
58 | * @author <a href="mailto:kschrader@karmalab.org">Kurt Schrader</a> |
|
59 | * @version $Id: TorqueInstance.java,v 1.13 2005/07/08 17:53:34 tfischer Exp $ |
|
60 | */ |
|
61 | public class TorqueInstance |
|
62 | { |
|
63 | /** Logging */ |
|
64 | 6 | private static Log log = LogFactory.getLog(TorqueInstance.class); |
65 | ||
66 | /** The db name that is specified as the default in the property file */ |
|
67 | 3 | private String defaultDBName = null; |
68 | ||
69 | /** The global cache of database maps */ |
|
70 | private Map dbMaps; |
|
71 | ||
72 | /** The cache of DataSourceFactory's */ |
|
73 | private Map dsFactoryMap; |
|
74 | ||
75 | /** The cache of DB adapter keys */ |
|
76 | private Map adapterMap; |
|
77 | ||
78 | /** A repository of Manager instances. */ |
|
79 | private Map managers; |
|
80 | ||
81 | /** Torque-specific configuration. */ |
|
82 | private Configuration conf; |
|
83 | ||
84 | /** flag to set to true once this class has been initialized */ |
|
85 | 3 | private boolean isInit = false; |
86 | ||
87 | /** |
|
88 | * Store mapbuilder classnames for peers that have been referenced prior |
|
89 | * to Torque being initialized. This can happen if torque om/peer objects |
|
90 | * are serialized then unserialized prior to Torque being reinitialized. |
|
91 | * This condition exists in a normal catalina restart. |
|
92 | */ |
|
93 | 3 | private List mapBuilders = null; |
94 | ||
95 | /** |
|
96 | * Creates a new instance with default configuration. |
|
97 | * |
|
98 | * @see #resetConfiguration() |
|
99 | */ |
|
100 | public TorqueInstance() |
|
101 | 3 | { |
102 | 3 | resetConfiguration(); |
103 | 3 | } |
104 | ||
105 | /** |
|
106 | * Initializes this instance of Torque. |
|
107 | * |
|
108 | * @see org.apache.stratum.lifecycle.Initializable |
|
109 | * @throws TorqueException Any exceptions caught during processing will be |
|
110 | * rethrown wrapped into a TorqueException. |
|
111 | */ |
|
112 | private synchronized void initialize() throws TorqueException |
|
113 | { |
|
114 | 3 | log.debug("initialize()"); |
115 | ||
116 | 3 | if (isInit) |
117 | { |
|
118 | 0 | log.debug("Multiple initializations of Torque attempted"); |
119 | 0 | return; |
120 | } |
|
121 | ||
122 | 3 | if (conf == null || conf.isEmpty()) |
123 | { |
|
124 | 0 | throw new TorqueException("Torque cannot be initialized without " |
125 | + "a valid configuration. Please check the log files " |
|
126 | + "for further details."); |
|
127 | } |
|
128 | ||
129 | // Now that we have dealt with processing the log4j properties |
|
130 | // that may be contained in the configuration we will make the |
|
131 | // configuration consist only of the remain torque specific |
|
132 | // properties that are contained in the configuration. First |
|
133 | // look for properties that are in the "torque" namespace. |
|
134 | ||
135 | 3 | Configuration subConf = conf.subset(Torque.TORQUE_KEY); |
136 | 3 | if (subConf == null || subConf.isEmpty()) |
137 | { |
|
138 | 0 | String error = ("Invalid configuration. No keys starting with " |
139 | + Torque.TORQUE_KEY |
|
140 | + " found in configuration"); |
|
141 | 0 | log.error(error); |
142 | 0 | throw new TorqueException(error); |
143 | } |
|
144 | 3 | setConfiguration(subConf); |
145 | ||
146 | 3 | initDefaultDbName(conf); |
147 | 3 | initAdapters(conf); |
148 | 3 | initDataSourceFactories(conf); |
149 | ||
150 | 3 | dbMaps = new HashMap(); |
151 | 3 | for (Iterator i = mapBuilders.iterator(); i.hasNext();) |
152 | { |
|
153 | //this will add any maps in this builder to the proper database map |
|
154 | 0 | BasePeer.getMapBuilder((String) i.next()); |
155 | } |
|
156 | // any further mapBuilders will be called/built on demand |
|
157 | 3 | mapBuilders = null; |
158 | ||
159 | // setup manager mappings |
|
160 | 3 | initManagerMappings(conf); |
161 | ||
162 | 3 | isInit = true; |
163 | 3 | } |
164 | ||
165 | ||
166 | /** |
|
167 | * initializes the name of the default database |
|
168 | * @param conf the configuration representing the torque section |
|
169 | * of the properties file |
|
170 | * @throws TorqueException if the appropriate key is not set |
|
171 | */ |
|
172 | private final void initDefaultDbName(Configuration conf) |
|
173 | throws TorqueException |
|
174 | { |
|
175 | // Determine default database name. |
|
176 | 3 | defaultDBName = |
177 | conf.getString( |
|
178 | Torque.DATABASE_KEY |
|
179 | + "." |
|
180 | + Torque.DEFAULT_KEY); |
|
181 | 3 | if (defaultDBName == null) |
182 | { |
|
183 | 0 | String error = "Invalid configuration: Key " |
184 | + Torque.TORQUE_KEY |
|
185 | + "." |
|
186 | + Torque.DATABASE_KEY |
|
187 | + "." |
|
188 | + Torque.DEFAULT_KEY |
|
189 | + " not set"; |
|
190 | 0 | log.error(error); |
191 | 0 | throw new TorqueException(error); |
192 | } |
|
193 | 3 | } |
194 | ||
195 | /** |
|
196 | * |
|
197 | * @param conf the Configuration representing the torque section of the |
|
198 | * properties file |
|
199 | * @throws TorqueException Any exceptions caught during processing will be |
|
200 | * rethrown wrapped into a TorqueException. |
|
201 | */ |
|
202 | private final void initAdapters(Configuration conf) |
|
203 | throws TorqueException |
|
204 | { |
|
205 | 3 | log.debug("initAdapters(" + conf + ")"); |
206 | 3 | adapterMap = new HashMap(); |
207 | ||
208 | 3 | Configuration c = conf.subset(Torque.DATABASE_KEY); |
209 | 3 | if (c == null || c.isEmpty()) |
210 | { |
|
211 | 0 | String error = "Invalid configuration : " |
212 | + "No keys starting with " |
|
213 | + Torque.TORQUE_KEY |
|
214 | + "." |
|
215 | + Torque.DATABASE_KEY |
|
216 | + " found in configuration"; |
|
217 | 0 | log.error(error); |
218 | 0 | throw new TorqueException(error); |
219 | } |
|
220 | ||
221 | try |
|
222 | { |
|
223 | 3 | for (Iterator it = c.getKeys(); it.hasNext(); ) |
224 | { |
|
225 | 6 | String key = (String) it.next(); |
226 | 6 | if (key.endsWith(DB.ADAPTER_KEY)) |
227 | { |
|
228 | 3 | String adapter = c.getString(key); |
229 | 3 | String handle = key.substring(0, key.indexOf('.')); |
230 | 3 | DB db = DBFactory.create(adapter); |
231 | // register the adapter for this name |
|
232 | 3 | adapterMap.put(handle, db); |
233 | 3 | log.debug("Adding " + adapter + " -> " + handle + " as Adapter"); |
234 | } |
|
235 | } |
|
236 | } |
|
237 | 0 | catch (Exception e) |
238 | { |
|
239 | 0 | log.error("Error reading configuration seeking database " |
240 | + "adapters", e); |
|
241 | 0 | throw new TorqueException(e); |
242 | 3 | } |
243 | ||
244 | 3 | if (adapterMap.get(Torque.getDefaultDB()) == null) |
245 | { |
|
246 | 0 | String error = "Invalid configuration : " |
247 | + "No adapter definition found for default DB " |
|
248 | + "An adapter must be defined under " |
|
249 | + Torque.TORQUE_KEY |
|
250 | + "." |
|
251 | + Torque.DATABASE_KEY |
|
252 | + "." |
|
253 | + Torque.getDefaultDB() |
|
254 | + "." |
|
255 | + DB.ADAPTER_KEY; |
|
256 | 0 | log.error(error); |
257 | 0 | throw new TorqueException(error); |
258 | } |
|
259 | 3 | } |
260 | ||
261 | /** |
|
262 | * |
|
263 | * @param conf the Configuration representing the properties file |
|
264 | * @throws TorqueException Any exceptions caught during processing will be |
|
265 | * rethrown wrapped into a TorqueException. |
|
266 | */ |
|
267 | private void initDataSourceFactories(Configuration conf) |
|
268 | throws TorqueException |
|
269 | { |
|
270 | 3 | log.debug("initDataSourceFactories(" + conf + ")"); |
271 | 3 | dsFactoryMap = new HashMap(); |
272 | ||
273 | 3 | Configuration c = conf.subset(DataSourceFactory.DSFACTORY_KEY); |
274 | 3 | if (c == null || c.isEmpty()) |
275 | { |
|
276 | 0 | String error = "Invalid configuration: " |
277 | + "No keys starting with " |
|
278 | + Torque.TORQUE_KEY |
|
279 | + "." |
|
280 | + DataSourceFactory.DSFACTORY_KEY |
|
281 | + " found in configuration"; |
|
282 | 0 | log.error(error); |
283 | 0 | throw new TorqueException(error); |
284 | } |
|
285 | ||
286 | try |
|
287 | { |
|
288 | 3 | for (Iterator it = c.getKeys(); it.hasNext();) |
289 | { |
|
290 | 3 | String key = (String) it.next(); |
291 | 3 | if (key.endsWith(DataSourceFactory.FACTORY_KEY)) |
292 | { |
|
293 | 3 | String classname = c.getString(key); |
294 | 3 | String handle = key.substring(0, key.indexOf('.')); |
295 | 3 | log.debug("handle: " + handle |
296 | + " DataSourceFactory: " + classname); |
|
297 | 3 | Class dsfClass = Class.forName(classname); |
298 | 3 | DataSourceFactory dsf = |
299 | (DataSourceFactory) dsfClass.newInstance(); |
|
300 | 3 | dsf.initialize(c.subset(handle)); |
301 | 3 | dsFactoryMap.put(handle, dsf); |
302 | } |
|
303 | } |
|
304 | } |
|
305 | 0 | catch (Exception e) |
306 | { |
|
307 | 0 | log.error("Error reading adapter configuration", e); |
308 | 0 | throw new TorqueException(e); |
309 | 3 | } |
310 | ||
311 | 3 | if (dsFactoryMap.get(Torque.getDefaultDB()) == null) |
312 | { |
|
313 | 0 | String error = "Invalid configuration : " |
314 | + "No DataSourceFactory definition for default DB found. " |
|
315 | + "A DataSourceFactory must be defined under the key" |
|
316 | + Torque.TORQUE_KEY |
|
317 | + "." |
|
318 | + DataSourceFactory.DSFACTORY_KEY |
|
319 | + "." |
|
320 | + Torque.getDefaultDB() |
|
321 | + "." |
|
322 | + DataSourceFactory.FACTORY_KEY; |
|
323 | 0 | log.error(error); |
324 | 0 | throw new TorqueException(error); |
325 | } |
|
326 | 3 | } |
327 | ||
328 | /** |
|
329 | * Initialization of Torque with a properties file. |
|
330 | * |
|
331 | * @param configFile The absolute path to the configuration file. |
|
332 | * @throws TorqueException Any exceptions caught during processing will be |
|
333 | * rethrown wrapped into a TorqueException. |
|
334 | */ |
|
335 | public void init(String configFile) |
|
336 | throws TorqueException |
|
337 | { |
|
338 | 3 | log.debug("init(" + configFile + ")"); |
339 | try |
|
340 | { |
|
341 | 3 | Configuration conf = new PropertiesConfiguration(configFile); |
342 | ||
343 | 3 | log.debug("Config Object is " + conf); |
344 | 3 | init(conf); |
345 | } |
|
346 | 0 | catch (ConfigurationException e) |
347 | { |
|
348 | 0 | throw new TorqueException(e); |
349 | 3 | } |
350 | 3 | } |
351 | ||
352 | /** |
|
353 | * Initialization of Torque with a properties file. |
|
354 | * |
|
355 | * @param conf The Torque configuration. |
|
356 | * @throws TorqueException Any exceptions caught during processing will be |
|
357 | * rethrown wrapped into a TorqueException. |
|
358 | */ |
|
359 | public void init(Configuration conf) |
|
360 | throws TorqueException |
|
361 | { |
|
362 | 3 | log.debug("init(" + conf + ")"); |
363 | 3 | setConfiguration(conf); |
364 | 3 | initialize(); |
365 | 3 | } |
366 | ||
367 | ||
368 | /** |
|
369 | * Creates a mapping between classes and their manager classes. |
|
370 | * |
|
371 | * The mapping is built according to settings present in |
|
372 | * properties file. The entries should have the |
|
373 | * following form: |
|
374 | * |
|
375 | * <pre> |
|
376 | * torque.managed_class.com.mycompany.Myclass.manager= \ |
|
377 | * com.mycompany.MyManagerImpl |
|
378 | * services.managed_class.com.mycompany.Myotherclass.manager= \ |
|
379 | * com.mycompany.MyOtherManagerImpl |
|
380 | * </pre> |
|
381 | * |
|
382 | * <br> |
|
383 | * |
|
384 | * Generic ServiceBroker provides no Services. |
|
385 | * |
|
386 | * @param conf the Configuration representing the properties file |
|
387 | * @throws TorqueException Any exceptions caught during processing will be |
|
388 | * rethrown wrapped into a TorqueException. |
|
389 | */ |
|
390 | protected void initManagerMappings(Configuration conf) |
|
391 | throws TorqueException |
|
392 | { |
|
393 | 3 | int pref = Torque.MANAGER_PREFIX.length(); |
394 | 3 | int suff = Torque.MANAGER_SUFFIX.length(); |
395 | ||
396 | 3 | for (Iterator it = conf.getKeys(); it.hasNext();) |
397 | { |
|
398 | 12 | String key = (String) it.next(); |
399 | ||
400 | 12 | if (key.startsWith(Torque.MANAGER_PREFIX) |
401 | && key.endsWith(Torque.MANAGER_SUFFIX)) |
|
402 | { |
|
403 | 0 | String managedClassKey = key.substring(pref, |
404 | key.length() - suff); |
|
405 | 0 | if (!managers.containsKey(managedClassKey)) |
406 | { |
|
407 | 0 | String managerClass = conf.getString(key); |
408 | 0 | log.info("Added Manager for Class: " + managedClassKey |
409 | + " -> " + managerClass); |
|
410 | try |
|
411 | { |
|
412 | 0 | initManager(managedClassKey, managerClass); |
413 | } |
|
414 | 0 | catch (TorqueException e) |
415 | { |
|
416 | // the exception thrown here seems to disappear. |
|
417 | // At least when initialized by Turbine, should find |
|
418 | // out why, but for now make sure it is noticed. |
|
419 | 0 | log.error("", e); |
420 | 0 | e.printStackTrace(); |
421 | 0 | throw e; |
422 | 12 | } |
423 | } |
|
424 | } |
|
425 | } |
|
426 | 3 | } |
427 | ||
428 | /** |
|
429 | * Initialize a manager |
|
430 | * |
|
431 | * @param name name of the manager |
|
432 | * @param className name of the manager class |
|
433 | * @throws TorqueException Any exceptions caught during processing will be |
|
434 | * rethrown wrapped into a TorqueException. |
|
435 | */ |
|
436 | private synchronized void initManager(String name, String className) |
|
437 | throws TorqueException |
|
438 | { |
|
439 | 0 | AbstractBaseManager manager = (AbstractBaseManager) managers.get(name); |
440 | ||
441 | 0 | if (manager == null) |
442 | { |
|
443 | 0 | if (className != null && className.length() != 0) |
444 | { |
|
445 | try |
|
446 | { |
|
447 | 0 | manager = (AbstractBaseManager) |
448 | Class.forName(className).newInstance(); |
|
449 | 0 | managers.put(name, manager); |
450 | } |
|
451 | 0 | catch (Exception e) |
452 | { |
|
453 | 0 | throw new TorqueException("Could not instantiate " |
454 | + "manager associated with class: " |
|
455 | + name, e); |
|
456 | 0 | } |
457 | } |
|
458 | } |
|
459 | 0 | } |
460 | ||
461 | /** |
|
462 | * Determine whether Torque has already been initialized. |
|
463 | * |
|
464 | * @return true if Torque is already initialized |
|
465 | */ |
|
466 | public boolean isInit() |
|
467 | { |
|
468 | 60 | return isInit; |
469 | } |
|
470 | ||
471 | /** |
|
472 | * Sets the configuration for Torque and all dependencies. |
|
473 | * |
|
474 | * @param conf the Configuration |
|
475 | */ |
|
476 | public void setConfiguration(Configuration conf) |
|
477 | { |
|
478 | 6 | log.debug("setConfiguration(" + conf + ")"); |
479 | 6 | this.conf = conf; |
480 | 6 | } |
481 | ||
482 | /** |
|
483 | * Get the configuration for this component. |
|
484 | * |
|
485 | * @return the Configuration |
|
486 | */ |
|
487 | public Configuration getConfiguration() |
|
488 | { |
|
489 | 12 | log.debug("getConfiguration() = " + conf); |
490 | 12 | return conf; |
491 | } |
|
492 | ||
493 | /** |
|
494 | * This method returns a Manager for the given name. |
|
495 | * |
|
496 | * @param name name of the manager |
|
497 | * @return a Manager |
|
498 | */ |
|
499 | public AbstractBaseManager getManager(String name) |
|
500 | { |
|
501 | 0 | AbstractBaseManager m = (AbstractBaseManager) managers.get(name); |
502 | 0 | if (m == null) |
503 | { |
|
504 | 0 | log.error("No configured manager for key " + name + "."); |
505 | } |
|
506 | 0 | return m; |
507 | } |
|
508 | ||
509 | /** |
|
510 | * This methods returns either the Manager from the configuration file, |
|
511 | * or the default one provided by the generated code. |
|
512 | * |
|
513 | * @param name name of the manager |
|
514 | * @param defaultClassName the class to use if name has not been configured |
|
515 | * @return a Manager |
|
516 | */ |
|
517 | public AbstractBaseManager getManager(String name, |
|
518 | String defaultClassName) |
|
519 | { |
|
520 | 0 | AbstractBaseManager m = (AbstractBaseManager) managers.get(name); |
521 | 0 | if (m == null) |
522 | { |
|
523 | 0 | log.debug("Added late Manager mapping for Class: " |
524 | + name + " -> " + defaultClassName); |
|
525 | ||
526 | try |
|
527 | { |
|
528 | 0 | initManager(name, defaultClassName); |
529 | } |
|
530 | 0 | catch (TorqueException e) |
531 | { |
|
532 | 0 | log.error(e.getMessage(), e); |
533 | 0 | } |
534 | ||
535 | // Try again now that the default manager should be in the map |
|
536 | 0 | m = (AbstractBaseManager) managers.get(name); |
537 | } |
|
538 | ||
539 | 0 | return m; |
540 | } |
|
541 | ||
542 | /** |
|
543 | * Shuts down the service. |
|
544 | * |
|
545 | * This method halts the IDBroker's daemon thread in all of |
|
546 | * the DatabaseMap's. It also closes all SharedPoolDataSourceFactories |
|
547 | * and PerUserPoolDataSourceFactories initialized by Torque. |
|
548 | * @exception TorqueException if a DataSourceFactory could not be closed |
|
549 | * cleanly. Only the first exception is rethrown, any following |
|
550 | * exceptions are logged but ignored. |
|
551 | */ |
|
552 | public synchronized void shutdown() |
|
553 | throws TorqueException |
|
554 | { |
|
555 | 0 | if (dbMaps != null) |
556 | { |
|
557 | 0 | for (Iterator it = dbMaps.values().iterator(); it.hasNext();) |
558 | { |
|
559 | 0 | DatabaseMap map = (DatabaseMap) it.next(); |
560 | 0 | IDBroker idBroker = map.getIDBroker(); |
561 | 0 | if (idBroker != null) |
562 | { |
|
563 | 0 | idBroker.stop(); |
564 | } |
|
565 | } |
|
566 | } |
|
567 | 0 | TorqueException exception = null; |
568 | 0 | for (Iterator it = dsFactoryMap.keySet().iterator(); it.hasNext();) |
569 | { |
|
570 | 0 | Object dsfKey = it.next(); |
571 | 0 | DataSourceFactory dsf |
572 | = (DataSourceFactory) dsFactoryMap.get(dsfKey); |
|
573 | try |
|
574 | { |
|
575 | 0 | dsf.close(); |
576 | 0 | it.remove(); |
577 | } |
|
578 | 0 | catch (TorqueException e) |
579 | { |
|
580 | 0 | log.error("Error while closing the DataSourceFactory " |
581 | + dsfKey, |
|
582 | e); |
|
583 | 0 | if (exception == null) |
584 | { |
|
585 | 0 | exception = e; |
586 | } |
|
587 | 0 | } |
588 | } |
|
589 | 0 | if (exception != null) |
590 | { |
|
591 | 0 | throw exception; |
592 | } |
|
593 | 0 | resetConfiguration(); |
594 | 0 | } |
595 | ||
596 | /** |
|
597 | * Resets some internal configuration variables to |
|
598 | * their defaults. |
|
599 | */ |
|
600 | private void resetConfiguration() |
|
601 | { |
|
602 | 3 | mapBuilders = Collections.synchronizedList(new ArrayList()); |
603 | 3 | managers = new HashMap(); |
604 | 3 | isInit = false; |
605 | 3 | } |
606 | ||
607 | /** |
|
608 | * Returns the default database map information. |
|
609 | * |
|
610 | * @return A DatabaseMap. |
|
611 | * @throws TorqueException Any exceptions caught during processing will be |
|
612 | * rethrown wrapped into a TorqueException. |
|
613 | */ |
|
614 | public DatabaseMap getDatabaseMap() |
|
615 | throws TorqueException |
|
616 | { |
|
617 | 0 | return getDatabaseMap(getDefaultDB()); |
618 | } |
|
619 | ||
620 | /** |
|
621 | * Returns the database map information. Name relates to the name |
|
622 | * of the connection pool to associate with the map. |
|
623 | * |
|
624 | * @param name The name of the database corresponding to the |
|
625 | * <code>DatabaseMap</code> to retrieve. |
|
626 | * @return The named <code>DatabaseMap</code>. |
|
627 | * @throws TorqueException Any exceptions caught during processing will be |
|
628 | * rethrown wrapped into a TorqueException. |
|
629 | */ |
|
630 | public DatabaseMap getDatabaseMap(String name) |
|
631 | throws TorqueException |
|
632 | { |
|
633 | 39 | if (name == null) |
634 | { |
|
635 | 0 | throw new TorqueException ("DatabaseMap name was null!"); |
636 | } |
|
637 | ||
638 | 39 | if (dbMaps == null) |
639 | { |
|
640 | 0 | throw new TorqueException("Torque was not initialized properly."); |
641 | } |
|
642 | ||
643 | 39 | synchronized (dbMaps) |
644 | { |
|
645 | 39 | DatabaseMap map = (DatabaseMap) dbMaps.get(name); |
646 | 39 | if (map == null) |
647 | { |
|
648 | // Still not there. Create and add. |
|
649 | 3 | map = initDatabaseMap(name); |
650 | } |
|
651 | 39 | return map; |
652 | 0 | } |
653 | } |
|
654 | ||
655 | /** |
|
656 | * Creates and initializes the mape for the named database. |
|
657 | * Assumes that <code>dbMaps</code> member is sync'd. |
|
658 | * |
|
659 | * @param name The name of the database to map. |
|
660 | * @return The desired map. |
|
661 | * @throws TorqueException Any exceptions caught during processing will be |
|
662 | * rethrown wrapped into a TorqueException. |
|
663 | */ |
|
664 | private final DatabaseMap initDatabaseMap(String name) |
|
665 | throws TorqueException |
|
666 | { |
|
667 | 3 | DatabaseMap map = new DatabaseMap(name); |
668 | ||
669 | // Add info about IDBroker's table. |
|
670 | 3 | setupIdTable(map); |
671 | ||
672 | // Setup other ID generators for this map. |
|
673 | try |
|
674 | { |
|
675 | 3 | String key = getDatabaseProperty(name, "adapter"); |
676 | 3 | if (StringUtils.isEmpty(key)) |
677 | { |
|
678 | 0 | key = getDatabaseProperty(name, "driver"); |
679 | } |
|
680 | 3 | DB db = DBFactory.create(key); |
681 | 3 | for (int i = 0; i < IDGeneratorFactory.ID_GENERATOR_METHODS.length; |
682 | 9 | i++) |
683 | { |
|
684 | 9 | map.addIdGenerator(IDGeneratorFactory.ID_GENERATOR_METHODS[i], |
685 | IDGeneratorFactory.create(db, name)); |
|
686 | } |
|
687 | } |
|
688 | 0 | catch (java.lang.InstantiationException e) |
689 | { |
|
690 | 0 | throw new TorqueException(e); |
691 | 3 | } |
692 | ||
693 | // Avoid possible ConcurrentModificationException by |
|
694 | // constructing a copy of dbMaps. |
|
695 | 3 | Map newMaps = new HashMap(dbMaps); |
696 | 3 | newMaps.put(name, map); |
697 | 3 | dbMaps = newMaps; |
698 | ||
699 | 3 | return map; |
700 | } |
|
701 | ||
702 | /** |
|
703 | * Register a MapBuilder |
|
704 | * |
|
705 | * @param className the MapBuilder |
|
706 | */ |
|
707 | public void registerMapBuilder(String className) |
|
708 | { |
|
709 | 0 | mapBuilders.add(className); |
710 | 0 | } |
711 | ||
712 | /** |
|
713 | * Returns the specified property of the given database, or the empty |
|
714 | * string if no value is set for the property. |
|
715 | * |
|
716 | * @param db The name of the database whose property to get. |
|
717 | * @param prop The name of the property to get. |
|
718 | * @return The property's value. |
|
719 | */ |
|
720 | private String getDatabaseProperty(String db, String prop) |
|
721 | { |
|
722 | 3 | return conf.getString(new StringBuffer("database.") |
723 | .append(db) |
|
724 | .append('.') |
|
725 | .append(prop) |
|
726 | .toString(), ""); |
|
727 | } |
|
728 | ||
729 | /** |
|
730 | * Setup IDBroker's table information within given database map. |
|
731 | * |
|
732 | * This method should be called on all new database map to ensure that |
|
733 | * IDBroker functionality is available in all databases used by the |
|
734 | * application. |
|
735 | * |
|
736 | * @param map the DataBaseMap to setup. |
|
737 | */ |
|
738 | private final void setupIdTable(DatabaseMap map) |
|
739 | { |
|
740 | 3 | map.setIdTable("ID_TABLE"); |
741 | 3 | TableMap tMap = map.getIdTable(); |
742 | 3 | tMap.addPrimaryKey("ID_TABLE_ID", new Integer(0)); |
743 | 3 | tMap.addColumn("TABLE_NAME", ""); |
744 | 3 | tMap.addColumn("NEXT_ID", new Integer(0)); |
745 | 3 | tMap.addColumn("QUANTITY", new Integer(0)); |
746 | 3 | } |
747 | ||
748 | /** |
|
749 | * This method returns a Connection from the default pool. |
|
750 | * |
|
751 | * @return The requested connection. |
|
752 | * @throws TorqueException Any exceptions caught during processing will be |
|
753 | * rethrown wrapped into a TorqueException. |
|
754 | */ |
|
755 | public Connection getConnection() |
|
756 | throws TorqueException |
|
757 | { |
|
758 | 0 | return getConnection(getDefaultDB()); |
759 | } |
|
760 | ||
761 | /** |
|
762 | * |
|
763 | * @param name The database name. |
|
764 | * @return a database connection |
|
765 | * @throws TorqueException Any exceptions caught during processing will be |
|
766 | * rethrown wrapped into a TorqueException. |
|
767 | */ |
|
768 | public Connection getConnection(String name) |
|
769 | throws TorqueException |
|
770 | { |
|
771 | 3 | Connection con = null; |
772 | 3 | DataSourceFactory dsf = null; |
773 | ||
774 | try |
|
775 | { |
|
776 | 3 | return getDataSourceFactory(name).getDataSource().getConnection(); |
777 | } |
|
778 | 3 | catch(SQLException se) |
779 | { |
|
780 | 3 | throw new TorqueException(se); |
781 | } |
|
782 | } |
|
783 | ||
784 | /** |
|
785 | * Returns a DataSourceFactory |
|
786 | * |
|
787 | * @param name Name of the DSF to get |
|
788 | * @return A DataSourceFactory object |
|
789 | */ |
|
790 | protected DataSourceFactory getDataSourceFactory(String name) |
|
791 | throws TorqueException |
|
792 | { |
|
793 | 60 | if (!isInit()) |
794 | { |
|
795 | 0 | throw new TorqueException("Torque is not initialized."); |
796 | } |
|
797 | ||
798 | 60 | DataSourceFactory dsf = null; |
799 | ||
800 | try |
|
801 | { |
|
802 | 60 | dsf = (DataSourceFactory) dsFactoryMap.get(name); |
803 | } |
|
804 | 0 | catch (Exception e) |
805 | { |
|
806 | 0 | throw new TorqueException(e); |
807 | 60 | } |
808 | ||
809 | 60 | if (dsf == null) |
810 | { |
|
811 | 0 | throw new NullPointerException( |
812 | "There was no DataSourceFactory " |
|
813 | + "configured for the connection " + name); |
|
814 | } |
|
815 | ||
816 | 60 | return dsf; |
817 | } |
|
818 | ||
819 | /** |
|
820 | * This method returns a Connecton using the given parameters. |
|
821 | * You should only use this method if you need user based access to the |
|
822 | * database! |
|
823 | * |
|
824 | * @param name The database name. |
|
825 | * @param username The name of the database user. |
|
826 | * @param password The password of the database user. |
|
827 | * @return A Connection. |
|
828 | * @throws TorqueException Any exceptions caught during processing will be |
|
829 | * rethrown wrapped into a TorqueException. |
|
830 | */ |
|
831 | public Connection getConnection(String name, String username, |
|
832 | String password) |
|
833 | throws TorqueException |
|
834 | { |
|
835 | try |
|
836 | { |
|
837 | 0 | return getDataSourceFactory(name).getDataSource().getConnection(username, password); |
838 | } |
|
839 | 0 | catch(SQLException se) |
840 | { |
|
841 | 0 | throw new TorqueException(se); |
842 | } |
|
843 | } |
|
844 | ||
845 | /** |
|
846 | * Returns database adapter for a specific connection pool. |
|
847 | * |
|
848 | * @param name A pool name. |
|
849 | * @return The corresponding database adapter. |
|
850 | * @throws TorqueException Any exceptions caught during processing will be |
|
851 | * rethrown wrapped into a TorqueException. |
|
852 | */ |
|
853 | public DB getDB(String name) throws TorqueException |
|
854 | { |
|
855 | 138 | return (DB) adapterMap.get(name); |
856 | } |
|
857 | ||
858 | /////////////////////////////////////////////////////////////////////////// |
|
859 | ||
860 | /** |
|
861 | * Returns the name of the default database. |
|
862 | * |
|
863 | * @return name of the default DB, or null if Torque is not initialized yet |
|
864 | */ |
|
865 | public String getDefaultDB() |
|
866 | { |
|
867 | 81 | return defaultDBName; |
868 | } |
|
869 | ||
870 | /** |
|
871 | * Closes a connection. |
|
872 | * |
|
873 | * @param con A Connection to close. |
|
874 | */ |
|
875 | public void closeConnection(Connection con) |
|
876 | { |
|
877 | 0 | if (con != null) |
878 | { |
|
879 | try |
|
880 | { |
|
881 | 0 | con.close(); |
882 | } |
|
883 | 0 | catch (SQLException e) |
884 | { |
|
885 | 0 | log.error("Error occured while closing connection.", e); |
886 | 0 | } |
887 | } |
|
888 | 0 | } |
889 | ||
890 | /** |
|
891 | * Sets the current schema for a database connection |
|
892 | * |
|
893 | * @param name The database name. |
|
894 | * @param schema The current schema name |
|
895 | * @throws TorqueException Any exceptions caught during processing will be |
|
896 | * rethrown wrapped into a TorqueException. |
|
897 | */ |
|
898 | public void setSchema(String name, String schema) |
|
899 | throws TorqueException |
|
900 | { |
|
901 | 0 | getDataSourceFactory(name).setSchema(schema); |
902 | 0 | } |
903 | ||
904 | /** |
|
905 | * This method returns the current schema for a database connection |
|
906 | * |
|
907 | * @param name The database name. |
|
908 | * @return The current schema name. Null means, no schema has been set. |
|
909 | * @throws TorqueException Any exceptions caught during processing will be |
|
910 | * rethrown wrapped into a TorqueException. |
|
911 | */ |
|
912 | public String getSchema(String name) |
|
913 | throws TorqueException |
|
914 | { |
|
915 | 57 | return getDataSourceFactory(name).getSchema(); |
916 | } |
|
917 | ||
918 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |