1 package org.apache.torque; 2 3 21 22 import java.sql.Connection ; 23 import java.sql.SQLException ; 24 import java.util.Collections ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.Map ; 28 29 import org.apache.commons.configuration.Configuration; 30 import org.apache.commons.configuration.ConfigurationException; 31 import org.apache.commons.configuration.PropertiesConfiguration; 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.DataSourceFactory; 37 import org.apache.torque.manager.AbstractBaseManager; 38 import org.apache.torque.map.DatabaseMap; 39 import org.apache.torque.map.MapBuilder; 40 import org.apache.torque.oid.IDBroker; 41 import org.apache.torque.oid.IDGeneratorFactory; 42 43 60 public class TorqueInstance 61 { 62 63 private static Log log = LogFactory.getLog(TorqueInstance.class); 64 65 66 private static final String DEFAULT_NAME = "default"; 67 68 69 private String defaultDBName = null; 70 71 76 private Map databases = Collections.synchronizedMap(new HashMap ()); 77 78 79 private Map managers; 80 81 82 private Configuration conf; 83 84 85 private boolean isInit = false; 86 87 93 private boolean defaultDsfIsReference = false; 94 95 101 private Map mapBuilderCache = null; 102 103 108 public TorqueInstance() 109 { 110 resetConfiguration(); 111 } 112 113 120 private synchronized void initialize() throws TorqueException 121 { 122 log.debug("initialize()"); 123 124 if (isInit) 125 { 126 log.debug("Multiple initializations of Torque attempted"); 127 return; 128 } 129 130 if (conf == null || conf.isEmpty()) 131 { 132 throw new TorqueException("Torque cannot be initialized without " 133 + "a valid configuration. Please check the log files " 134 + "for further details."); 135 } 136 137 143 Configuration subConf = conf.subset(Torque.TORQUE_KEY); 144 if (subConf == null || subConf.isEmpty()) 145 { 146 String error = ("Invalid configuration. No keys starting with " 147 + Torque.TORQUE_KEY 148 + " found in configuration"); 149 log.error(error); 150 throw new TorqueException(error); 151 } 152 setConfiguration(subConf); 153 154 initDefaultDbName(conf); 155 initAdapters(conf); 156 initDataSourceFactories(conf); 157 158 initManagerMappings(conf); 160 161 isInit = true; 162 163 synchronized (mapBuilderCache) 165 { 166 for (Iterator i = mapBuilderCache.entrySet().iterator(); i.hasNext();) 167 { 168 Map.Entry entry = (Map.Entry )i.next(); 169 170 if (null == entry.getValue()) 171 { 172 try 173 { 174 MapBuilder builder = (MapBuilder) Class.forName((String ) entry.getKey()).newInstance(); 176 177 if (!builder.isBuilt()) 178 { 179 builder.doBuild(); 180 } 181 182 entry.setValue(builder); 183 } 184 catch (Exception e) 185 { 186 throw new TorqueException(e); 187 } 188 } 189 } 190 } 191 } 192 193 194 203 private void initDefaultDbName(Configuration conf) 204 throws TorqueException 205 { 206 defaultDBName = 208 conf.getString( 209 Torque.DATABASE_KEY 210 + "." 211 + Torque.DEFAULT_KEY); 212 if (defaultDBName == null) 213 { 214 String error = "Invalid configuration: Key " 215 + Torque.TORQUE_KEY 216 + "." 217 + Torque.DATABASE_KEY 218 + "." 219 + Torque.DEFAULT_KEY 220 + " not set"; 221 log.error(error); 222 throw new TorqueException(error); 223 } 224 } 225 226 236 private void initAdapters(Configuration conf) 237 throws TorqueException 238 { 239 log.debug("initAdapters(" + conf + ")"); 240 241 Configuration c = conf.subset(Torque.DATABASE_KEY); 242 if (c == null || c.isEmpty()) 243 { 244 String error = "Invalid configuration : " 245 + "No keys starting with " 246 + Torque.TORQUE_KEY 247 + "." 248 + Torque.DATABASE_KEY 249 + " found in configuration"; 250 log.error(error); 251 throw new TorqueException(error); 252 } 253 254 try 255 { 256 for (Iterator it = c.getKeys(); it.hasNext();) 257 { 258 String key = (String ) it.next(); 259 if (key.endsWith(DB.ADAPTER_KEY) 260 || key.endsWith(DB.DRIVER_KEY)) 261 { 262 String adapter = c.getString(key); 263 String handle = key.substring(0, key.indexOf('.')); 264 265 DB db; 266 267 db = DBFactory.create(adapter); 268 269 if (db == null) 271 { 272 String adapterClassName = c.getString(key + "." + adapter + ".className", null); 273 db = DBFactory.create(adapter, adapterClassName); 274 } 275 276 Database database = getOrCreateDatabase(handle); 277 278 database.setAdapter(db); 280 log.debug("Adding " + adapter + " -> " 281 + handle + " as Adapter"); 282 283 285 getDatabaseMap(handle); 290 for (int i = 0; 291 i < IDGeneratorFactory.ID_GENERATOR_METHODS.length; 292 i++) 293 { 294 database.addIdGenerator( 295 IDGeneratorFactory.ID_GENERATOR_METHODS[i], 296 IDGeneratorFactory.create(db, handle)); 297 } 298 } 299 } 300 } 301 catch (InstantiationException e) 302 { 303 log.error("Error creating a database adapter instance", e); 304 throw new TorqueException(e); 305 } 306 catch (TorqueException e) 307 { 308 log.error("Error reading configuration seeking database " 309 + "adapters", e); 310 throw new TorqueException(e); 311 } 312 313 Database defaultDatabase 315 = (Database) databases.get(Torque.getDefaultDB()); 316 if (defaultDatabase == null 317 || defaultDatabase.getAdapter() == null) 318 { 319 String error = "Invalid configuration : " 320 + "No adapter definition found for default DB " 321 + "An adapter must be defined under " 322 + Torque.TORQUE_KEY 323 + "." 324 + Torque.DATABASE_KEY 325 + "." 326 + Torque.getDefaultDB() 327 + "." 328 + DB.ADAPTER_KEY; 329 log.error(error); 330 throw new TorqueException(error); 331 } 332 } 333 334 346 private void initDataSourceFactories(Configuration conf) 347 throws TorqueException 348 { 349 log.debug("initDataSourceFactories(" + conf + ")"); 350 351 Configuration c = conf.subset(DataSourceFactory.DSFACTORY_KEY); 352 if (c == null || c.isEmpty()) 353 { 354 String error = "Invalid configuration: " 355 + "No keys starting with " 356 + Torque.TORQUE_KEY 357 + "." 358 + DataSourceFactory.DSFACTORY_KEY 359 + " found in configuration"; 360 log.error(error); 361 throw new TorqueException(error); 362 } 363 364 try 365 { 366 for (Iterator it = c.getKeys(); it.hasNext();) 367 { 368 String key = (String ) it.next(); 369 if (key.endsWith(DataSourceFactory.FACTORY_KEY)) 370 { 371 String classname = c.getString(key); 372 String handle = key.substring(0, key.indexOf('.')); 373 log.debug("handle: " + handle 374 + " DataSourceFactory: " + classname); 375 Class dsfClass = Class.forName(classname); 376 DataSourceFactory dsf = 377 (DataSourceFactory) dsfClass.newInstance(); 378 dsf.initialize(c.subset(handle)); 379 380 Database database = getOrCreateDatabase(handle); 381 database.setDataSourceFactory(dsf); 382 } 383 } 384 } 385 catch (RuntimeException e) 386 { 387 log.error("Runtime Error reading adapter configuration", e); 388 throw new TorqueRuntimeException(e); 389 } 390 catch (Exception e) 391 { 392 log.error("Error reading adapter configuration", e); 393 throw new TorqueException(e); 394 } 395 396 Database defaultDatabase 397 = (Database) databases.get(defaultDBName); 398 if (defaultDatabase == null 399 || defaultDatabase.getDataSourceFactory() == null) 400 { 401 String error = "Invalid configuration : " 402 + "No DataSourceFactory definition for default DB found. " 403 + "A DataSourceFactory must be defined under the key" 404 + Torque.TORQUE_KEY 405 + "." 406 + DataSourceFactory.DSFACTORY_KEY 407 + "." 408 + defaultDBName 409 + "." 410 + DataSourceFactory.FACTORY_KEY; 411 log.error(error); 412 throw new TorqueException(error); 413 } 414 415 429 { 430 Database databaseInfoForKeyDefault 431 = getOrCreateDatabase(DEFAULT_NAME); 432 if ((!defaultDBName.equals(DEFAULT_NAME)) 433 && databaseInfoForKeyDefault.getDataSourceFactory() == null) 434 { 435 log.debug("Adding the DatasourceFactory from database " 436 + defaultDBName 437 + " onto database " + DEFAULT_NAME); 438 databaseInfoForKeyDefault.setDataSourceFactory( 439 defaultDatabase.getDataSourceFactory()); 440 this.defaultDsfIsReference = true; 441 } 442 } 443 444 } 445 446 453 public void init(String configFile) 454 throws TorqueException 455 { 456 log.debug("init(" + configFile + ")"); 457 try 458 { 459 Configuration configuration 460 = new PropertiesConfiguration(configFile); 461 462 log.debug("Config Object is " + configuration); 463 init(configuration); 464 } 465 catch (ConfigurationException e) 466 { 467 throw new TorqueException(e); 468 } 469 } 470 471 478 public synchronized void init(Configuration conf) 479 throws TorqueException 480 { 481 log.debug("init(" + conf + ")"); 482 setConfiguration(conf); 483 initialize(); 484 } 485 486 487 509 protected void initManagerMappings(Configuration conf) 510 throws TorqueException 511 { 512 int pref = Torque.MANAGER_PREFIX.length(); 513 int suff = Torque.MANAGER_SUFFIX.length(); 514 515 for (Iterator it = conf.getKeys(); it.hasNext();) 516 { 517 String key = (String ) it.next(); 518 519 if (key.startsWith(Torque.MANAGER_PREFIX) 520 && key.endsWith(Torque.MANAGER_SUFFIX)) 521 { 522 String managedClassKey = key.substring(pref, 523 key.length() - suff); 524 if (!managers.containsKey(managedClassKey)) 525 { 526 String managerClass = conf.getString(key); 527 log.info("Added Manager for Class: " + managedClassKey 528 + " -> " + managerClass); 529 try 530 { 531 initManager(managedClassKey, managerClass); 532 } 533 catch (TorqueException e) 534 { 535 log.error("", e); 539 e.printStackTrace(); 540 throw e; 541 } 542 } 543 } 544 } 545 } 546 547 555 private synchronized void initManager(String name, String className) 556 throws TorqueException 557 { 558 AbstractBaseManager manager = (AbstractBaseManager) managers.get(name); 559 560 if (manager == null) 561 { 562 if (className != null && className.length() != 0) 563 { 564 try 565 { 566 manager = (AbstractBaseManager) 567 Class.forName(className).newInstance(); 568 managers.put(name, manager); 569 } 570 catch (Exception e) 571 { 572 throw new TorqueException("Could not instantiate " 573 + "manager associated with class: " 574 + name, e); 575 } 576 } 577 } 578 } 579 580 585 public boolean isInit() 586 { 587 return isInit; 588 } 589 590 597 public void setConfiguration(Configuration conf) 598 { 599 log.debug("setConfiguration(" + conf + ")"); 600 this.conf = conf; 601 } 602 603 608 public Configuration getConfiguration() 609 { 610 log.debug("getConfiguration() = " + conf); 611 return conf; 612 } 613 614 620 public AbstractBaseManager getManager(String name) 621 { 622 AbstractBaseManager m = (AbstractBaseManager) managers.get(name); 623 if (m == null) 624 { 625 log.error("No configured manager for key " + name + "."); 626 } 627 return m; 628 } 629 630 638 public AbstractBaseManager getManager(String name, 639 String defaultClassName) 640 { 641 AbstractBaseManager m = (AbstractBaseManager) managers.get(name); 642 if (m == null) 643 { 644 log.debug("Added late Manager mapping for Class: " 645 + name + " -> " + defaultClassName); 646 647 try 648 { 649 initManager(name, defaultClassName); 650 } 651 catch (TorqueException e) 652 { 653 log.error(e.getMessage(), e); 654 } 655 656 m = (AbstractBaseManager) managers.get(name); 658 } 659 660 return m; 661 } 662 663 673 public synchronized void shutdown() 674 throws TorqueException 675 { 676 synchronized (databases) 678 { 679 for (Iterator it = databases.values().iterator(); it.hasNext();) 680 { 681 Database database = (Database) it.next(); 682 IDBroker idBroker = database.getIDBroker(); 683 if (idBroker != null) 684 { 685 idBroker.stop(); 686 } 687 } 688 } 689 690 TorqueException exception = null; 692 synchronized (databases) 693 { 694 for (Iterator it = databases.keySet().iterator(); it.hasNext();) 695 { 696 Object databaseKey = it.next(); 697 698 Database database 699 = (Database) databases.get(databaseKey); 700 if (DEFAULT_NAME.equals(databaseKey) && defaultDsfIsReference) 701 { 702 database.setDataSourceFactory(null); 707 break; 708 } 709 710 try 711 { 712 DataSourceFactory dataSourceFactory 713 = database.getDataSourceFactory(); 714 if (dataSourceFactory != null) 715 { 716 dataSourceFactory.close(); 717 database.setDataSourceFactory(null); 718 } 719 } 720 catch (TorqueException e) 721 { 722 log.error("Error while closing the DataSourceFactory " 723 + databaseKey, 724 e); 725 if (exception == null) 726 { 727 exception = e; 728 } 729 } 730 } 731 } 732 if (exception != null) 733 { 734 throw exception; 735 } 736 resetConfiguration(); 737 } 738 739 743 private void resetConfiguration() 744 { 745 mapBuilderCache = Collections.synchronizedMap(new HashMap ()); 746 managers = new HashMap (); 747 isInit = false; 748 } 749 750 757 public DatabaseMap getDatabaseMap() 758 throws TorqueException 759 { 760 return getDatabaseMap(getDefaultDB()); 761 } 762 763 773 public DatabaseMap getDatabaseMap(String name) 774 throws TorqueException 775 { 776 if (name == null) 777 { 778 throw new TorqueException ("DatabaseMap name was null!"); 779 } 780 781 Database database = getOrCreateDatabase(name); 782 return database.getDatabaseMap(); 783 } 784 785 791 public Map getMapBuilders() 792 { 793 return mapBuilderCache; 794 } 795 796 801 public void registerMapBuilder(String className) 802 { 803 mapBuilderCache.put(className, null); 804 } 805 806 812 public void registerMapBuilder(MapBuilder builder) 813 { 814 mapBuilderCache.put(builder.getClass().getName(), builder); 815 } 816 817 825 public MapBuilder getMapBuilder(String className) 826 throws TorqueException 827 { 828 try 829 { 830 MapBuilder mb = (MapBuilder)mapBuilderCache.get(className); 831 832 if (mb == null) 833 { 834 mb = (MapBuilder) Class.forName(className).newInstance(); 835 mapBuilderCache.put(className, mb); 837 } 838 839 if (mb.isBuilt()) 840 { 841 return mb; 842 } 843 844 try 845 { 846 mb.doBuild(); 847 } 848 catch (Exception e) 849 { 850 mapBuilderCache.remove(className); 852 throw e; 853 } 854 855 return mb; 856 } 857 catch (Exception e) 858 { 859 log.error("getMapBuilder failed trying to instantiate: " 860 + className, e); 861 throw new TorqueException(e); 862 } 863 } 864 865 872 public Connection getConnection() 873 throws TorqueException 874 { 875 return getConnection(getDefaultDB()); 876 } 877 878 887 public Connection getConnection(String name) 888 throws TorqueException 889 { 890 if (!Torque.isInit()) 891 { 892 throw new TorqueException("Torque is not initialized"); 893 } 894 try 895 { 896 return getDatabase(name) 897 .getDataSourceFactory() 898 .getDataSource() 899 .getConnection(); 900 } 901 catch (SQLException se) 902 { 903 throw new TorqueException(se); 904 } 905 } 906 907 916 public DataSourceFactory getDataSourceFactory(String name) 917 throws TorqueException 918 { 919 Database database = getDatabase(name); 920 921 DataSourceFactory dsf = null; 922 if (database != null) 923 { 924 dsf = database.getDataSourceFactory(); 925 } 926 927 if (dsf == null) 928 { 929 throw new TorqueException( 930 "There was no DataSourceFactory " 931 + "configured for the connection " + name); 932 } 933 934 return dsf; 935 } 936 937 949 public Connection getConnection(String name, String username, 950 String password) 951 throws TorqueException 952 { 953 if (!Torque.isInit()) 954 { 955 throw new TorqueException("Torque is not initialized"); 956 } 957 try 958 { 959 return getDataSourceFactory(name) 960 .getDataSource().getConnection(username, password); 961 } 962 catch (SQLException se) 963 { 964 throw new TorqueException(se); 965 } 966 } 967 968 977 public DB getDB(String name) throws TorqueException 978 { 979 Database database = getDatabase(name); 980 if (database == null) 981 { 982 return null; 983 } 984 return database.getAdapter(); 985 } 986 987 989 994 public String getDefaultDB() 995 { 996 return defaultDBName; 997 } 998 999 1004 public void closeConnection(Connection con) 1005 { 1006 if (con != null) 1007 { 1008 try 1009 { 1010 con.close(); 1011 } 1012 catch (SQLException e) 1013 { 1014 log.error("Error occured while closing connection.", e); 1015 } 1016 } 1017 } 1018 1019 1027 public void setSchema(String name, String schema) 1028 throws TorqueException 1029 { 1030 getOrCreateDatabase(name).setSchema(schema); 1031 } 1032 1033 1041 public String getSchema(String name) 1042 throws TorqueException 1043 { 1044 Database database = getDatabase(name); 1045 if (database == null) 1046 { 1047 return null; 1048 } 1049 return database.getSchema(); 1050 } 1051 1052 1060 public Database getDatabase(String databaseName) throws TorqueException 1061 { 1062 if (!isInit()) 1063 { 1064 throw new TorqueException("Torque is not initialized."); 1065 } 1066 return (Database) databases.get(databaseName); 1067 } 1068 1069 1081 public Map getDatabases() throws TorqueException 1082 { 1083 if (!isInit()) 1084 { 1085 throw new TorqueException("Torque is not initialized."); 1086 } 1087 return Collections.unmodifiableMap(databases); 1088 } 1089 1090 1099 public Database getOrCreateDatabase(String databaseName) 1100 { 1101 synchronized (databases) 1102 { 1103 Database result = (Database) databases.get(databaseName); 1104 if (result == null) 1105 { 1106 result = new Database(databaseName); 1107 databases.put(databaseName, result); 1108 } 1109 return result; 1110 } 1111 } 1112} 1113 | Popular Tags |