%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.torque.TorqueInstance |
|
|
1 | package org.apache.torque; |
|
2 | ||
3 | /* |
|
4 | * Licensed to the Apache Software Foundation (ASF) under one |
|
5 | * or more contributor license agreements. See the NOTICE file |
|
6 | * distributed with this work for additional information |
|
7 | * regarding copyright ownership. The ASF licenses this file |
|
8 | * to you under the Apache License, Version 2.0 (the |
|
9 | * "License"); you may not use this file except in compliance |
|
10 | * with the License. You may obtain a copy of the License at |
|
11 | * |
|
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
13 | * |
|
14 | * Unless required by applicable law or agreed to in writing, |
|
15 | * software distributed under the License is distributed on an |
|
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
17 | * KIND, either express or implied. See the License for the |
|
18 | * specific language governing permissions and limitations |
|
19 | * under the License. |
|
20 | */ |
|
21 | ||
22 | import java.sql.Connection; |
|
23 | import java.sql.SQLException; |
|
24 | import java.util.ArrayList; |
|
25 | import java.util.Collections; |
|
26 | import java.util.HashMap; |
|
27 | import java.util.Iterator; |
|
28 | import java.util.List; |
|
29 | import java.util.Map; |
|
30 | ||
31 | import org.apache.commons.configuration.Configuration; |
|
32 | import org.apache.commons.configuration.ConfigurationException; |
|
33 | import org.apache.commons.configuration.PropertiesConfiguration; |
|
34 | import org.apache.commons.logging.Log; |
|
35 | import org.apache.commons.logging.LogFactory; |
|
36 | import org.apache.torque.adapter.DB; |
|
37 | import org.apache.torque.adapter.DBFactory; |
|
38 | import org.apache.torque.dsfactory.DataSourceFactory; |
|
39 | import org.apache.torque.manager.AbstractBaseManager; |
|
40 | import org.apache.torque.map.DatabaseMap; |
|
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 | * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a> |
|
60 | * @version $Id: TorqueInstance.java 476550 2006-11-18 16:08:37Z tfischer $ |
|
61 | */ |
|
62 | public class TorqueInstance |
|
63 | { |
|
64 | /** Logging */ |
|
65 | 128 | private static Log log = LogFactory.getLog(TorqueInstance.class); |
66 | ||
67 | /** A constant for <code>default</code>. */ |
|
68 | private static final String DEFAULT_NAME = "default"; |
|
69 | ||
70 | /** The db name that is specified as the default in the property file */ |
|
71 | 64 | private String defaultDBName = null; |
72 | ||
73 | /** |
|
74 | * The Map which contains all known databases. All iterations over the map |
|
75 | * and other operations where the databaase map needs to stay |
|
76 | * in a defined state must be synchronized to this map. |
|
77 | */ |
|
78 | 64 | private Map databases = Collections.synchronizedMap(new HashMap()); |
79 | ||
80 | /** A repository of Manager instances. */ |
|
81 | private Map managers; |
|
82 | ||
83 | /** Torque-specific configuration. */ |
|
84 | private Configuration conf; |
|
85 | ||
86 | /** flag to set to true once this class has been initialized */ |
|
87 | 64 | private boolean isInit = false; |
88 | ||
89 | /** |
|
90 | * a flag which indicates whether the DataSourceFactory in the database |
|
91 | * named <code>DEFAULT</code> is a reference to another |
|
92 | * DataSourceFactory. This is important to know when closing the |
|
93 | * DataSourceFactories on shutdown(); |
|
94 | */ |
|
95 | 64 | private boolean defaultDsfIsReference = false; |
96 | ||
97 | /** |
|
98 | * Store mapbuilder classnames for peers that have been referenced prior |
|
99 | * to Torque being initialized. This can happen if torque om/peer objects |
|
100 | * are serialized then unserialized prior to Torque being reinitialized. |
|
101 | * This condition exists in a normal catalina restart. |
|
102 | */ |
|
103 | 64 | private List mapBuilders = null; |
104 | ||
105 | /** |
|
106 | * Creates a new instance with default configuration. |
|
107 | * |
|
108 | * @see #resetConfiguration() |
|
109 | */ |
|
110 | public TorqueInstance() |
|
111 | 64 | { |
112 | 64 | resetConfiguration(); |
113 | 64 | } |
114 | ||
115 | /** |
|
116 | * Initializes this instance of Torque. |
|
117 | * |
|
118 | * @see org.apache.stratum.lifecycle.Initializable |
|
119 | * @throws TorqueException Any exceptions caught during processing will be |
|
120 | * rethrown wrapped into a TorqueException. |
|
121 | */ |
|
122 | private synchronized void initialize() throws TorqueException |
|
123 | { |
|
124 | 64 | log.debug("initialize()"); |
125 | ||
126 | 64 | if (isInit) |
127 | { |
|
128 | 0 | log.debug("Multiple initializations of Torque attempted"); |
129 | 0 | return; |
130 | } |
|
131 | ||
132 | 64 | if (conf == null || conf.isEmpty()) |
133 | { |
|
134 | 0 | throw new TorqueException("Torque cannot be initialized without " |
135 | + "a valid configuration. Please check the log files " |
|
136 | + "for further details."); |
|
137 | } |
|
138 | ||
139 | // Now that we have dealt with processing the log4j properties |
|
140 | // that may be contained in the configuration we will make the |
|
141 | // configuration consist only of the remain torque specific |
|
142 | // properties that are contained in the configuration. First |
|
143 | // look for properties that are in the "torque" namespace. |
|
144 | ||
145 | 64 | Configuration subConf = conf.subset(Torque.TORQUE_KEY); |
146 | 64 | if (subConf == null || subConf.isEmpty()) |
147 | { |
|
148 | 0 | String error = ("Invalid configuration. No keys starting with " |
149 | + Torque.TORQUE_KEY |
|
150 | + " found in configuration"); |
|
151 | 0 | log.error(error); |
152 | 0 | throw new TorqueException(error); |
153 | } |
|
154 | 64 | setConfiguration(subConf); |
155 | ||
156 | 64 | initDefaultDbName(conf); |
157 | 64 | initAdapters(conf); |
158 | 64 | initDataSourceFactories(conf); |
159 | ||
160 | 64 | for (Iterator i = mapBuilders.iterator(); i.hasNext();) |
161 | { |
|
162 | //this will add any maps in this builder to the proper database map |
|
163 | 16 | BasePeer.getMapBuilder((String) i.next()); |
164 | 16 | } |
165 | // any further mapBuilders will be called/built on demand |
|
166 | 64 | mapBuilders = null; |
167 | ||
168 | // setup manager mappings |
|
169 | 64 | initManagerMappings(conf); |
170 | ||
171 | 64 | isInit = true; |
172 | 64 | } |
173 | ||
174 | ||
175 | /** |
|
176 | * Initializes the name of the default database and |
|
177 | * associates the database with the name <code>DEFAULT_NAME</code> |
|
178 | * to the default database. |
|
179 | * |
|
180 | * @param conf the configuration representing the torque section. |
|
181 | * of the properties file. |
|
182 | * @throws TorqueException if the appropriate key is not set. |
|
183 | */ |
|
184 | private void initDefaultDbName(Configuration conf) |
|
185 | throws TorqueException |
|
186 | { |
|
187 | // Determine default database name. |
|
188 | 64 | defaultDBName = |
189 | conf.getString( |
|
190 | Torque.DATABASE_KEY |
|
191 | + "." |
|
192 | + Torque.DEFAULT_KEY); |
|
193 | 64 | if (defaultDBName == null) |
194 | { |
|
195 | 0 | String error = "Invalid configuration: Key " |
196 | + Torque.TORQUE_KEY |
|
197 | + "." |
|
198 | + Torque.DATABASE_KEY |
|
199 | + "." |
|
200 | + Torque.DEFAULT_KEY |
|
201 | + " not set"; |
|
202 | 0 | log.error(error); |
203 | 0 | throw new TorqueException(error); |
204 | } |
|
205 | 64 | } |
206 | ||
207 | /** |
|
208 | * Reads the adapter settings from the configuration and |
|
209 | * assigns the appropriate database adapters and Id Generators |
|
210 | * to the databases. |
|
211 | * |
|
212 | * @param conf the Configuration representing the torque section of the |
|
213 | * properties file |
|
214 | * @throws TorqueException Any exceptions caught during processing will be |
|
215 | * rethrown wrapped into a TorqueException. |
|
216 | */ |
|
217 | private void initAdapters(Configuration conf) |
|
218 | throws TorqueException |
|
219 | { |
|
220 | 64 | log.debug("initAdapters(" + conf + ")"); |
221 | ||
222 | 64 | Configuration c = conf.subset(Torque.DATABASE_KEY); |
223 | 64 | if (c == null || c.isEmpty()) |
224 | { |
|
225 | 0 | String error = "Invalid configuration : " |
226 | + "No keys starting with " |
|
227 | + Torque.TORQUE_KEY |
|
228 | + "." |
|
229 | + Torque.DATABASE_KEY |
|
230 | + " found in configuration"; |
|
231 | 0 | log.error(error); |
232 | 0 | throw new TorqueException(error); |
233 | } |
|
234 | ||
235 | try |
|
236 | { |
|
237 | 64 | for (Iterator it = c.getKeys(); it.hasNext();) |
238 | { |
|
239 | 192 | String key = (String) it.next(); |
240 | 192 | if (key.endsWith(DB.ADAPTER_KEY) |
241 | || key.endsWith(DB.DRIVER_KEY)) |
|
242 | { |
|
243 | 64 | String adapter = c.getString(key); |
244 | 64 | String handle = key.substring(0, key.indexOf('.')); |
245 | ||
246 | DB db; |
|
247 | ||
248 | 64 | db = DBFactory.create(adapter); |
249 | ||
250 | // Not supported, try manually defined adapter class |
|
251 | 64 | if (db == null) |
252 | { |
|
253 | 64 | String adapterClassName = c.getString(key + "." + adapter + ".className", null); |
254 | 64 | db = DBFactory.create(adapter, adapterClassName); |
255 | } |
|
256 | ||
257 | 64 | Database database = getOrCreateDatabase(handle); |
258 | ||
259 | // register the adapter for this name |
|
260 | 64 | database.setAdapter(db); |
261 | 64 | log.debug("Adding " + adapter + " -> " |
262 | + handle + " as Adapter"); |
|
263 | ||
264 | // add Id generators |
|
265 | ||
266 | // first make sure that the dtabaseMap exists for the name |
|
267 | // as the idGenerators are still stored in the database map |
|
268 | // TODO: change when the idGenerators are stored in the |
|
269 | // database |
|
270 | 64 | getDatabaseMap(handle); |
271 | 64 | for (int i = 0; |
272 | 256 | i < IDGeneratorFactory.ID_GENERATOR_METHODS.length; |
273 | 192 | i++) |
274 | { |
|
275 | 192 | database.addIdGenerator( |
276 | IDGeneratorFactory.ID_GENERATOR_METHODS[i], |
|
277 | IDGeneratorFactory.create(db, handle)); |
|
278 | } |
|
279 | } |
|
280 | 192 | } |
281 | } |
|
282 | 0 | catch (InstantiationException e) |
283 | { |
|
284 | 0 | log.error("Error creating a database adapter instance", e); |
285 | 0 | throw new TorqueException(e); |
286 | } |
|
287 | 0 | catch (TorqueException e) |
288 | { |
|
289 | 0 | log.error("Error reading configuration seeking database " |
290 | + "adapters", e); |
|
291 | 0 | throw new TorqueException(e); |
292 | 64 | } |
293 | ||
294 | // check that at least the default database has got an adapter. |
|
295 | 64 | Database defaultDatabase |
296 | = (Database) databases.get(Torque.getDefaultDB()); |
|
297 | 64 | if (defaultDatabase == null |
298 | || defaultDatabase.getAdapter() == null) |
|
299 | { |
|
300 | 0 | String error = "Invalid configuration : " |
301 | + "No adapter definition found for default DB " |
|
302 | + "An adapter must be defined under " |
|
303 | + Torque.TORQUE_KEY |
|
304 | + "." |
|
305 | + Torque.DATABASE_KEY |
|
306 | + "." |
|
307 | + Torque.getDefaultDB() |
|
308 | + "." |
|
309 | + DB.ADAPTER_KEY; |
|
310 | 0 | log.error(error); |
311 | 0 | throw new TorqueException(error); |
312 | } |
|
313 | 64 | } |
314 | ||
315 | /** |
|
316 | * Reads the settings for the DataSourceFactories from the configuration |
|
317 | * and creates and/or cinfigures the DataSourceFactories for the databases. |
|
318 | * If no DataSorceFactory is assigned to the database with the name |
|
319 | * <code>DEFAULT_NAME</code>, a reference to the DataSourceFactory |
|
320 | * of the default daztabase is made from the database with the name |
|
321 | * <code>DEFAULT_NAME</code>. |
|
322 | * |
|
323 | * @param conf the Configuration representing the properties file |
|
324 | * @throws TorqueException Any exceptions caught during processing will be |
|
325 | * rethrown wrapped into a TorqueException. |
|
326 | */ |
|
327 | private void initDataSourceFactories(Configuration conf) |
|
328 | throws TorqueException |
|
329 | { |
|
330 | 64 | log.debug("initDataSourceFactories(" + conf + ")"); |
331 | ||
332 | 64 | Configuration c = conf.subset(DataSourceFactory.DSFACTORY_KEY); |
333 | 64 | if (c == null || c.isEmpty()) |
334 | { |
|
335 | 0 | String error = "Invalid configuration: " |
336 | + "No keys starting with " |
|
337 | + Torque.TORQUE_KEY |
|
338 | + "." |
|
339 | + DataSourceFactory.DSFACTORY_KEY |
|
340 | + " found in configuration"; |
|
341 | 0 | log.error(error); |
342 | 0 | throw new TorqueException(error); |
343 | } |
|
344 | ||
345 | try |
|
346 | { |
|
347 | 64 | for (Iterator it = c.getKeys(); it.hasNext();) |
348 | { |
|
349 | 64 | String key = (String) it.next(); |
350 | 64 | if (key.endsWith(DataSourceFactory.FACTORY_KEY)) |
351 | { |
|
352 | 64 | String classname = c.getString(key); |
353 | 64 | String handle = key.substring(0, key.indexOf('.')); |
354 | 64 | log.debug("handle: " + handle |
355 | + " DataSourceFactory: " + classname); |
|
356 | 64 | Class dsfClass = Class.forName(classname); |
357 | 64 | DataSourceFactory dsf = |
358 | (DataSourceFactory) dsfClass.newInstance(); |
|
359 | 64 | dsf.initialize(c.subset(handle)); |
360 | ||
361 | 64 | Database database = getOrCreateDatabase(handle); |
362 | 64 | database.setDataSourceFactory(dsf); |
363 | } |
|
364 | 64 | } |
365 | } |
|
366 | 0 | catch (RuntimeException e) |
367 | { |
|
368 | 0 | log.error("Runtime Error reading adapter configuration", e); |
369 | 0 | throw new TorqueRuntimeException(e); |
370 | } |
|
371 | 0 | catch (Exception e) |
372 | { |
|
373 | 0 | log.error("Error reading adapter configuration", e); |
374 | 0 | throw new TorqueException(e); |
375 | 64 | } |
376 | ||
377 | 64 | Database defaultDatabase |
378 | = (Database) databases.get(defaultDBName); |
|
379 | 64 | if (defaultDatabase == null |
380 | || defaultDatabase.getDataSourceFactory() == null) |
|
381 | { |
|
382 | 0 | String error = "Invalid configuration : " |
383 | + "No DataSourceFactory definition for default DB found. " |
|
384 | + "A DataSourceFactory must be defined under the key" |
|
385 | + Torque.TORQUE_KEY |
|
386 | + "." |
|
387 | + DataSourceFactory.DSFACTORY_KEY |
|
388 | + "." |
|
389 | + defaultDBName |
|
390 | + "." |
|
391 | + DataSourceFactory.FACTORY_KEY; |
|
392 | 0 | log.error(error); |
393 | 0 | throw new TorqueException(error); |
394 | } |
|
395 | ||
396 | // As there might be a default database configured |
|
397 | // to map "default" onto an existing datasource, we |
|
398 | // must check, whether there _is_ really an entry for |
|
399 | // the "default" in the dsFactoryMap or not. If it is |
|
400 | // not, then add a dummy entry for the "default" |
|
401 | // |
|
402 | // Without this, you can't actually access the "default" |
|
403 | // data-source, even if you have an entry like |
|
404 | // |
|
405 | // database.default = bookstore |
|
406 | // |
|
407 | // in your Torque.properties |
|
408 | // |
|
409 | ||
410 | { |
|
411 | 64 | Database databaseInfoForKeyDefault |
412 | = getOrCreateDatabase(DEFAULT_NAME); |
|
413 | 64 | if ((!defaultDBName.equals(DEFAULT_NAME)) |
414 | && databaseInfoForKeyDefault.getDataSourceFactory() == null) |
|
415 | { |
|
416 | 64 | log.debug("Adding the DatasourceFactory from database " |
417 | + defaultDBName |
|
418 | + " onto database " + DEFAULT_NAME); |
|
419 | 64 | databaseInfoForKeyDefault.setDataSourceFactory( |
420 | defaultDatabase.getDataSourceFactory()); |
|
421 | 64 | this.defaultDsfIsReference = true; |
422 | } |
|
423 | } |
|
424 | ||
425 | 64 | } |
426 | ||
427 | /** |
|
428 | * Initialization of Torque with a properties file. |
|
429 | * |
|
430 | * @param configFile The absolute path to the configuration file. |
|
431 | * @throws TorqueException Any exceptions caught during processing will be |
|
432 | * rethrown wrapped into a TorqueException. |
|
433 | */ |
|
434 | public void init(String configFile) |
|
435 | throws TorqueException |
|
436 | { |
|
437 | 48 | log.debug("init(" + configFile + ")"); |
438 | try |
|
439 | { |
|
440 | 48 | Configuration configuration |
441 | = new PropertiesConfiguration(configFile); |
|
442 | ||
443 | 48 | log.debug("Config Object is " + configuration); |
444 | 48 | init(configuration); |
445 | } |
|
446 | 0 | catch (ConfigurationException e) |
447 | { |
|
448 | 0 | throw new TorqueException(e); |
449 | 48 | } |
450 | 48 | } |
451 | ||
452 | /** |
|
453 | * Initialization of Torque with a Configuration object. |
|
454 | * |
|
455 | * @param conf The Torque configuration. |
|
456 | * @throws TorqueException Any exceptions caught during processing will be |
|
457 | * rethrown wrapped into a TorqueException. |
|
458 | */ |
|
459 | public synchronized void init(Configuration conf) |
|
460 | throws TorqueException |
|
461 | { |
|
462 | 64 | log.debug("init(" + conf + ")"); |
463 | 64 | setConfiguration(conf); |
464 | 64 | initialize(); |
465 | 64 | } |
466 | ||
467 | ||
468 | /** |
|
469 | * Creates a mapping between classes and their manager classes. |
|
470 | * |
|
471 | * The mapping is built according to settings present in |
|
472 | * properties file. The entries should have the |
|
473 | * following form: |
|
474 | * |
|
475 | * <pre> |
|
476 | * torque.managed_class.com.mycompany.Myclass.manager= \ |
|
477 | * com.mycompany.MyManagerImpl |
|
478 | * services.managed_class.com.mycompany.Myotherclass.manager= \ |
|
479 | * com.mycompany.MyOtherManagerImpl |
|
480 | * </pre> |
|
481 | * |
|
482 | * <br> |
|
483 | * |
|
484 | * Generic ServiceBroker provides no Services. |
|
485 | * |
|
486 | * @param conf the Configuration representing the properties file |
|
487 | * @throws TorqueException Any exceptions caught during processing will be |
|
488 | * rethrown wrapped into a TorqueException. |
|
489 | */ |
|
490 | protected void initManagerMappings(Configuration conf) |
|
491 | throws TorqueException |
|
492 | { |
|
493 | 64 | int pref = Torque.MANAGER_PREFIX.length(); |
494 | 64 | int suff = Torque.MANAGER_SUFFIX.length(); |
495 | ||
496 | 64 | for (Iterator it = conf.getKeys(); it.hasNext();) |
497 | { |
|
498 | 320 | String key = (String) it.next(); |
499 | ||
500 | 320 | if (key.startsWith(Torque.MANAGER_PREFIX) |
501 | && key.endsWith(Torque.MANAGER_SUFFIX)) |
|
502 | { |
|
503 | 0 | String managedClassKey = key.substring(pref, |
504 | key.length() - suff); |
|
505 | 0 | if (!managers.containsKey(managedClassKey)) |
506 | { |
|
507 | 0 | String managerClass = conf.getString(key); |
508 | 0 | log.info("Added Manager for Class: " + managedClassKey |
509 | + " -> " + managerClass); |
|
510 | try |
|
511 | { |
|
512 | 0 | initManager(managedClassKey, managerClass); |
513 | } |
|
514 | 0 | catch (TorqueException e) |
515 | { |
|
516 | // the exception thrown here seems to disappear. |
|
517 | // At least when initialized by Turbine, should find |
|
518 | // out why, but for now make sure it is noticed. |
|
519 | 0 | log.error("", e); |
520 | 0 | e.printStackTrace(); |
521 | 0 | throw e; |
522 | 0 | } |
523 | } |
|
524 | } |
|
525 | 320 | } |
526 | 64 | } |
527 | ||
528 | /** |
|
529 | * Initialize a manager |
|
530 | * |
|
531 | * @param name name of the manager |
|
532 | * @param className name of the manager class |
|
533 | * @throws TorqueException Any exceptions caught during processing will be |
|
534 | * rethrown wrapped into a TorqueException. |
|
535 | */ |
|
536 | private synchronized void initManager(String name, String className) |
|
537 | throws TorqueException |
|
538 | { |
|
539 | 0 | AbstractBaseManager manager = (AbstractBaseManager) managers.get(name); |
540 | ||
541 | 0 | if (manager == null) |
542 | { |
|
543 | 0 | if (className != null && className.length() != 0) |
544 | { |
|
545 | try |
|
546 | { |
|
547 | 0 | manager = (AbstractBaseManager) |
548 | Class.forName(className).newInstance(); |
|
549 | 0 | managers.put(name, manager); |
550 | } |
|
551 | 0 | catch (Exception e) |
552 | { |
|
553 | 0 | throw new TorqueException("Could not instantiate " |
554 | + "manager associated with class: " |
|
555 | + name, e); |
|
556 | 0 | } |
557 | } |
|
558 | } |
|
559 | 0 | } |
560 | ||
561 | /** |
|
562 | * Determine whether Torque has already been initialized. |
|
563 | * |
|
564 | * @return true if Torque is already initialized |
|
565 | */ |
|
566 | public boolean isInit() |
|
567 | { |
|
568 | 1280 | return isInit; |
569 | } |
|
570 | ||
571 | /** |
|
572 | * Sets the configuration for Torque and all dependencies. |
|
573 | * The prefix <code>TORQUE_KEY</code> needs to be removed from the |
|
574 | * configuration keys for the provided configuration. |
|
575 | * |
|
576 | * @param conf the Configuration. |
|
577 | */ |
|
578 | public void setConfiguration(Configuration conf) |
|
579 | { |
|
580 | 128 | log.debug("setConfiguration(" + conf + ")"); |
581 | 128 | this.conf = conf; |
582 | 128 | } |
583 | ||
584 | /** |
|
585 | * Get the configuration for this component. |
|
586 | * |
|
587 | * @return the Configuration |
|
588 | */ |
|
589 | public Configuration getConfiguration() |
|
590 | { |
|
591 | 192 | log.debug("getConfiguration() = " + conf); |
592 | 192 | return conf; |
593 | } |
|
594 | ||
595 | /** |
|
596 | * This method returns a Manager for the given name. |
|
597 | * |
|
598 | * @param name name of the manager |
|
599 | * @return a Manager |
|
600 | */ |
|
601 | public AbstractBaseManager getManager(String name) |
|
602 | { |
|
603 | 0 | AbstractBaseManager m = (AbstractBaseManager) managers.get(name); |
604 | 0 | if (m == null) |
605 | { |
|
606 | 0 | log.error("No configured manager for key " + name + "."); |
607 | } |
|
608 | 0 | return m; |
609 | } |
|
610 | ||
611 | /** |
|
612 | * This methods returns either the Manager from the configuration file, |
|
613 | * or the default one provided by the generated code. |
|
614 | * |
|
615 | * @param name name of the manager |
|
616 | * @param defaultClassName the class to use if name has not been configured |
|
617 | * @return a Manager |
|
618 | */ |
|
619 | public AbstractBaseManager getManager(String name, |
|
620 | String defaultClassName) |
|
621 | { |
|
622 | 0 | AbstractBaseManager m = (AbstractBaseManager) managers.get(name); |
623 | 0 | if (m == null) |
624 | { |
|
625 | 0 | log.debug("Added late Manager mapping for Class: " |
626 | + name + " -> " + defaultClassName); |
|
627 | ||
628 | try |
|
629 | { |
|
630 | 0 | initManager(name, defaultClassName); |
631 | } |
|
632 | 0 | catch (TorqueException e) |
633 | { |
|
634 | 0 | log.error(e.getMessage(), e); |
635 | 0 | } |
636 | ||
637 | // Try again now that the default manager should be in the map |
|
638 | 0 | m = (AbstractBaseManager) managers.get(name); |
639 | } |
|
640 | ||
641 | 0 | return m; |
642 | } |
|
643 | ||
644 | /** |
|
645 | * Shuts down the service. |
|
646 | * |
|
647 | * This method halts the IDBroker's daemon thread in all of |
|
648 | * the DatabaseMap's. It also closes all SharedPoolDataSourceFactories |
|
649 | * and PerUserPoolDataSourceFactories initialized by Torque. |
|
650 | * @exception TorqueException if a DataSourceFactory could not be closed |
|
651 | * cleanly. Only the first exception is rethrown, any following |
|
652 | * exceptions are logged but ignored. |
|
653 | */ |
|
654 | public synchronized void shutdown() |
|
655 | throws TorqueException |
|
656 | { |
|
657 | // stop the idbrokers |
|
658 | 32 | synchronized (databases) |
659 | { |
|
660 | 32 | for (Iterator it = databases.values().iterator(); it.hasNext();) |
661 | { |
|
662 | 64 | Database database = (Database) it.next(); |
663 | 64 | IDBroker idBroker = database.getIDBroker(); |
664 | 64 | if (idBroker != null) |
665 | { |
|
666 | 0 | idBroker.stop(); |
667 | } |
|
668 | 64 | } |
669 | 32 | } |
670 | ||
671 | // shut down the data source factories |
|
672 | 32 | TorqueException exception = null; |
673 | 32 | synchronized (databases) |
674 | { |
|
675 | 32 | for (Iterator it = databases.keySet().iterator(); it.hasNext();) |
676 | { |
|
677 | 64 | Object databaseKey = it.next(); |
678 | ||
679 | 64 | Database database |
680 | = (Database) databases.get(databaseKey); |
|
681 | 64 | if (DEFAULT_NAME.equals(databaseKey) && defaultDsfIsReference) |
682 | { |
|
683 | // the DataSourceFactory of the database with the name |
|
684 | // DEFAULT_NAME is just a reference to aynother entry. |
|
685 | // Do not close because this leads to closing |
|
686 | // the same DataSourceFactory twice. |
|
687 | 32 | database.setDataSourceFactory(null); |
688 | 32 | break; |
689 | } |
|
690 | ||
691 | try |
|
692 | { |
|
693 | 32 | DataSourceFactory dataSourceFactory |
694 | = database.getDataSourceFactory(); |
|
695 | 32 | if (dataSourceFactory != null) |
696 | { |
|
697 | 16 | dataSourceFactory.close(); |
698 | 0 | database.setDataSourceFactory(null); |
699 | } |
|
700 | } |
|
701 | 16 | catch (TorqueException e) |
702 | { |
|
703 | 16 | log.error("Error while closing the DataSourceFactory " |
704 | + databaseKey, |
|
705 | e); |
|
706 | 16 | if (exception == null) |
707 | { |
|
708 | 16 | exception = e; |
709 | } |
|
710 | 16 | } |
711 | 32 | } |
712 | 32 | } |
713 | 32 | if (exception != null) |
714 | { |
|
715 | 16 | throw exception; |
716 | } |
|
717 | 16 | resetConfiguration(); |
718 | 16 | } |
719 | ||
720 | /** |
|
721 | * Resets some internal configuration variables to |
|
722 | * their defaults. |
|
723 | */ |
|
724 | private void resetConfiguration() |
|
725 | { |
|
726 | 80 | mapBuilders = Collections.synchronizedList(new ArrayList()); |
727 | 80 | managers = new HashMap(); |
728 | 80 | isInit = false; |
729 | 80 | } |
730 | ||
731 | /** |
|
732 | * Returns the default database map information. |
|
733 | * |
|
734 | * @return A DatabaseMap. |
|
735 | * @throws TorqueException Any exceptions caught during processing will be |
|
736 | * rethrown wrapped into a TorqueException. |
|
737 | */ |
|
738 | public DatabaseMap getDatabaseMap() |
|
739 | throws TorqueException |
|
740 | { |
|
741 | 0 | return getDatabaseMap(getDefaultDB()); |
742 | } |
|
743 | ||
744 | /** |
|
745 | * Returns the database map information. Name relates to the name |
|
746 | * of the connection pool to associate with the map. |
|
747 | * |
|
748 | * @param name The name of the database corresponding to the |
|
749 | * <code>DatabaseMap</code> to retrieve. |
|
750 | * @return The named <code>DatabaseMap</code>. |
|
751 | * @throws TorqueException Any exceptions caught during processing will be |
|
752 | * rethrown wrapped into a TorqueException. |
|
753 | */ |
|
754 | public DatabaseMap getDatabaseMap(String name) |
|
755 | throws TorqueException |
|
756 | { |
|
757 | 368 | if (name == null) |
758 | { |
|
759 | 0 | throw new TorqueException ("DatabaseMap name was null!"); |
760 | } |
|
761 | ||
762 | 368 | Database database = getOrCreateDatabase(name); |
763 | 368 | return database.getDatabaseMap(); |
764 | } |
|
765 | ||
766 | /** |
|
767 | * Register a MapBuilder |
|
768 | * |
|
769 | * @param className the MapBuilder |
|
770 | */ |
|
771 | public void registerMapBuilder(String className) |
|
772 | { |
|
773 | 16 | mapBuilders.add(className); |
774 | 16 | } |
775 | ||
776 | /** |
|
777 | * This method returns a Connection from the default pool. |
|
778 | * |
|
779 | * @return The requested connection, never null. |
|
780 | * @throws TorqueException Any exceptions caught during processing will be |
|
781 | * rethrown wrapped into a TorqueException. |
|
782 | */ |
|
783 | public Connection getConnection() |
|
784 | throws TorqueException |
|
785 | { |
|
786 | 0 | return getConnection(getDefaultDB()); |
787 | } |
|
788 | ||
789 | /** |
|
790 | * Returns a database connection to the database with the key |
|
791 | * <code>name</code>. |
|
792 | * @param name The database name. |
|
793 | * @return a database connection, never null. |
|
794 | * @throws TorqueException If no DataSourceFactory is configured for the |
|
795 | * named database, the connection information is wrong, or the |
|
796 | * connection cannot be returned for any other reason. |
|
797 | */ |
|
798 | public Connection getConnection(String name) |
|
799 | throws TorqueException |
|
800 | { |
|
801 | try |
|
802 | { |
|
803 | 0 | return getDatabase(name) |
804 | .getDataSourceFactory() |
|
805 | .getDataSource() |
|
806 | .getConnection(); |
|
807 | } |
|
808 | 0 | catch (SQLException se) |
809 | { |
|
810 | 0 | throw new TorqueException(se); |
811 | } |
|
812 | } |
|
813 | ||
814 | /** |
|
815 | * Returns the DataSourceFactory for the database with the name |
|
816 | * <code>name</code>. |
|
817 | * |
|
818 | * @param name The name of the database to get the DSF for. |
|
819 | * @return A DataSourceFactory object, never null. |
|
820 | * @throws TorqueException if Torque is not initiliaized, or |
|
821 | * no DatasourceFactory is configured for the given name. |
|
822 | */ |
|
823 | public DataSourceFactory getDataSourceFactory(String name) |
|
824 | throws TorqueException |
|
825 | { |
|
826 | 32 | Database database = getDatabase(name); |
827 | ||
828 | 32 | DataSourceFactory dsf = null; |
829 | 32 | if (database != null) |
830 | { |
|
831 | 32 | dsf = database.getDataSourceFactory(); |
832 | } |
|
833 | ||
834 | 32 | if (dsf == null) |
835 | { |
|
836 | 0 | throw new TorqueException( |
837 | "There was no DataSourceFactory " |
|
838 | + "configured for the connection " + name); |
|
839 | } |
|
840 | ||
841 | 32 | return dsf; |
842 | } |
|
843 | ||
844 | /** |
|
845 | * This method returns a Connection using the given parameters. |
|
846 | * You should only use this method if you need user based access to the |
|
847 | * database! |
|
848 | * |
|
849 | * @param name The database name. |
|
850 | * @param username The name of the database user. |
|
851 | * @param password The password of the database user. |
|
852 | * @return A Connection. |
|
853 | * @throws TorqueException Any exceptions caught during processing will be |
|
854 | * rethrown wrapped into a TorqueException. |
|
855 | */ |
|
856 | public Connection getConnection(String name, String username, |
|
857 | String password) |
|
858 | throws TorqueException |
|
859 | { |
|
860 | try |
|
861 | { |
|
862 | 0 | return getDataSourceFactory(name) |
863 | .getDataSource().getConnection(username, password); |
|
864 | } |
|
865 | 0 | catch (SQLException se) |
866 | { |
|
867 | 0 | throw new TorqueException(se); |
868 | } |
|
869 | } |
|
870 | ||
871 | /** |
|
872 | * Returns the database adapter for a specific database. |
|
873 | * |
|
874 | * @param name the name of the database to get the adapter for. |
|
875 | * @return The corresponding database adapter, or null if no database |
|
876 | * adapter is defined for the given database. |
|
877 | * @throws TorqueException Any exceptions caught during processing will be |
|
878 | * rethrown wrapped into a TorqueException. |
|
879 | */ |
|
880 | public DB getDB(String name) throws TorqueException |
|
881 | { |
|
882 | 624 | Database database = getDatabase(name); |
883 | 624 | if (database == null) |
884 | { |
|
885 | 0 | return null; |
886 | } |
|
887 | 624 | return database.getAdapter(); |
888 | } |
|
889 | ||
890 | /////////////////////////////////////////////////////////////////////////// |
|
891 | ||
892 | /** |
|
893 | * Returns the name of the default database. |
|
894 | * |
|
895 | * @return name of the default DB, or null if Torque is not initialized yet |
|
896 | */ |
|
897 | public String getDefaultDB() |
|
898 | { |
|
899 | 720 | return defaultDBName; |
900 | } |
|
901 | ||
902 | /** |
|
903 | * Closes a connection. |
|
904 | * |
|
905 | * @param con A Connection to close. |
|
906 | */ |
|
907 | public void closeConnection(Connection con) |
|
908 | { |
|
909 | 0 | if (con != null) |
910 | { |
|
911 | try |
|
912 | { |
|
913 | 0 | con.close(); |
914 | } |
|
915 | 0 | catch (SQLException e) |
916 | { |
|
917 | 0 | log.error("Error occured while closing connection.", e); |
918 | 0 | } |
919 | } |
|
920 | 0 | } |
921 | ||
922 | /** |
|
923 | * Sets the current schema for a database connection |
|
924 | * |
|
925 | * @param name The database name. |
|
926 | * @param schema The current schema name. |
|
927 | * @throws TorqueException Any exceptions caught during processing will be |
|
928 | * rethrown wrapped into a TorqueException. |
|
929 | */ |
|
930 | public void setSchema(String name, String schema) |
|
931 | throws TorqueException |
|
932 | { |
|
933 | 0 | getOrCreateDatabase(name).setSchema(schema); |
934 | 0 | } |
935 | ||
936 | /** |
|
937 | * This method returns the current schema for a database connection |
|
938 | * |
|
939 | * @param name The database name. |
|
940 | * @return The current schema name. Null means, no schema has been set. |
|
941 | * @throws TorqueException Any exceptions caught during processing will be |
|
942 | * rethrown wrapped into a TorqueException. |
|
943 | */ |
|
944 | public String getSchema(String name) |
|
945 | throws TorqueException |
|
946 | { |
|
947 | 496 | Database database = getDatabase(name); |
948 | 496 | if (database == null) |
949 | { |
|
950 | 0 | return null; |
951 | } |
|
952 | 496 | return database.getSchema(); |
953 | } |
|
954 | ||
955 | /** |
|
956 | * Returns the database for the key <code>databaseName</code>. |
|
957 | * |
|
958 | * @param databaseName the key to get the database for. |
|
959 | * @return the database for the specified key, or null if the database |
|
960 | * does not exist. |
|
961 | * @throws TorqueException if Torque is not yet initialized. |
|
962 | */ |
|
963 | public Database getDatabase(String databaseName) throws TorqueException |
|
964 | { |
|
965 | 1216 | if (!isInit()) |
966 | { |
|
967 | 0 | throw new TorqueException("Torque is not initialized."); |
968 | } |
|
969 | 1216 | return (Database) databases.get(databaseName); |
970 | } |
|
971 | ||
972 | /** |
|
973 | * Returns a Map containing all Databases registered to Torque. |
|
974 | * The key of the Map is the name of the database, and the value is the |
|
975 | * database instance. <br/> |
|
976 | * Note that in the very special case where a new database which |
|
977 | * is not configured in Torque's configuration gets known to Torque |
|
978 | * at a later time, the returned map may change, and there is no way to |
|
979 | * protect you against this. |
|
980 | * |
|
981 | * @return a Map containing all Databases known to Torque, never null. |
|
982 | * @throws TorqueException if Torque is not yet initialized. |
|
983 | */ |
|
984 | public Map getDatabases() throws TorqueException |
|
985 | { |
|
986 | 32 | if (!isInit()) |
987 | { |
|
988 | 16 | throw new TorqueException("Torque is not initialized."); |
989 | } |
|
990 | 16 | return Collections.unmodifiableMap(databases); |
991 | } |
|
992 | ||
993 | /** |
|
994 | * Returns the database for the key <code>databaseName</code>. |
|
995 | * If no database is associated to the specified key, |
|
996 | * a new database is created, mapped to the specified key, and returned. |
|
997 | * |
|
998 | * @param databaseName the key to get the database for. |
|
999 | * @return the database associated with specified key, or the newly created |
|
1000 | * database, never null. |
|
1001 | */ |
|
1002 | public Database getOrCreateDatabase(String databaseName) |
|
1003 | { |
|
1004 | 560 | synchronized (databases) |
1005 | { |
|
1006 | 560 | Database result = (Database) databases.get(databaseName); |
1007 | 560 | if (result == null) |
1008 | { |
|
1009 | 128 | result = new Database(databaseName); |
1010 | 128 | databases.put(databaseName, result); |
1011 | } |
|
1012 | 560 | return result; |
1013 | 0 | } |
1014 | } |
|
1015 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |