1 56 package org.objectstyle.cayenne.conf; 57 58 import java.io.InputStream ; 59 import java.io.IOException ; 60 import java.net.URL ; 61 import java.util.Collection ; 62 import java.util.Collections ; 63 import java.util.Iterator ; 64 import java.util.Map ; 65 import java.util.HashMap ; 66 import java.util.List ; 67 import java.util.ArrayList ; 68 69 import org.apache.commons.lang.Validate; 70 import org.apache.commons.collections.Predicate; 71 import org.apache.log4j.BasicConfigurator; 72 import org.apache.log4j.Level; 73 import org.apache.log4j.Logger; 74 import org.apache.log4j.PropertyConfigurator; 75 import org.objectstyle.cayenne.CayenneRuntimeException; 76 import org.objectstyle.cayenne.ConfigurationException; 77 import org.objectstyle.cayenne.access.DataDomain; 78 import org.objectstyle.cayenne.util.CayenneMap; 79 import org.objectstyle.cayenne.util.ResourceLocator; 80 import org.objectstyle.cayenne.dataview.DataView; 81 82 96 public abstract class Configuration { 97 98 private static Logger logObj = Logger.getLogger(Configuration.class); 99 100 public static final String DEFAULT_LOGGING_PROPS_FILE = ".cayenne/cayenne-log.properties"; 101 public static final String DEFAULT_DOMAIN_FILE = "cayenne.xml"; 102 public static final Class DEFAULT_CONFIGURATION_CLASS = DefaultConfiguration.class; 103 104 protected static Configuration sharedConfiguration = null; 105 private static boolean loggingConfigured = false; 106 107 public static final Predicate ACCEPT_ALL_DATAVIEWS = new Predicate() { 108 109 public boolean evaluate(Object dataViewName) { 110 return true; 111 } 112 }; 113 114 118 protected static ClassLoader resourceLoader; 119 120 125 protected static ThreadLocal threadClassLoader = new ThreadLocal (); 126 127 128 protected CayenneMap dataDomains = new CayenneMap(this); 129 protected Collection dataDomainsRef = Collections.unmodifiableCollection(dataDomains 130 .values()); 131 protected DataSourceFactory overrideFactory; 132 protected ConfigStatus loadStatus = new ConfigStatus(); 133 protected String domainConfigurationName = DEFAULT_DOMAIN_FILE; 134 protected boolean ignoringLoadFailures; 135 protected ConfigLoaderDelegate loaderDelegate; 136 protected ConfigurationShutdownHook configurationShutdownHook = new ConfigurationShutdownHook(); 137 protected Map dataViewLocations = new HashMap (); 138 protected String projectVersion; 139 140 145 protected ClassLoader classLoader; 146 147 152 public static void bootstrapSharedConfiguration(Class cl) { 153 if (cl.getClassLoader() != null) { 154 resourceLoader = cl.getClassLoader(); 155 } 156 else { 157 logObj 158 .debug("An attempt to bootstrap configuration with null class loader for class " 159 + cl.getName()); 160 } 161 } 162 163 168 public synchronized static void configureCommonLogging() { 169 if (!Configuration.isLoggingConfigured()) { 170 ResourceLocator locator = new ResourceLocator(); 172 locator.setSkipAbsolutePath(true); 173 locator.setSkipClasspath(false); 174 locator.setSkipCurrentDirectory(true); 175 locator.setSkipHomeDirectory(false); 176 177 URL configURL = locator.findResource(DEFAULT_LOGGING_PROPS_FILE); 179 Configuration.configureCommonLogging(configURL); 180 } 181 } 182 183 186 public synchronized static void configureCommonLogging(URL propsFile) { 187 if (!Configuration.isLoggingConfigured()) { 188 if (propsFile != null) { 189 PropertyConfigurator.configure(propsFile); 190 logObj.debug("configured log4j from: " + propsFile); 191 } 192 else { 193 BasicConfigurator.configure(); 194 logObj.debug("configured log4j with BasicConfigurator."); 195 } 196 197 Configuration.setLoggingConfigured(true); 199 } 200 } 201 202 207 public static boolean isLoggingConfigured() { 208 if (!loggingConfigured) { 209 if (Logger.getRootLogger().getAllAppenders().hasMoreElements()) { 211 Configuration.setLoggingConfigured(true); 212 } 213 } 214 215 return loggingConfigured; 216 } 217 218 222 public synchronized static void setLoggingConfigured(boolean state) { 223 loggingConfigured = state; 224 } 225 226 233 public synchronized static Configuration getSharedConfiguration() { 234 if (Configuration.sharedConfiguration == null) { 235 Configuration.initializeSharedConfiguration(); 236 } 237 238 return Configuration.sharedConfiguration; 239 } 240 241 247 public static ClassLoader getResourceLoader() { 248 ClassLoader loader = (ClassLoader ) threadClassLoader.get(); 249 if (loader == null) { 250 loader = Configuration.resourceLoader; 251 } 252 253 if (loader == null) { 254 loader = Thread.currentThread().getContextClassLoader(); 255 } 256 257 return loader; 258 } 259 260 public static void setThreadClassLoader(ClassLoader classLoader) { 261 threadClassLoader.set(classLoader); 262 } 263 264 268 public static Level getLoggingLevel() { 269 Level l = logObj.getLevel(); 270 return (l != null ? l : Level.DEBUG); 271 } 272 273 276 public static void setLoggingLevel(Level logLevel) { 277 logObj.setLevel(logLevel); 278 } 279 280 285 public static void initializeSharedConfiguration() { 286 Configuration.initializeSharedConfiguration(DEFAULT_CONFIGURATION_CLASS); 287 } 288 289 293 public static void initializeSharedConfiguration(Class configurationClass) { 294 Configuration conf = null; 295 296 try { 297 conf = (Configuration) configurationClass.newInstance(); 298 } 299 catch (Exception ex) { 300 logObj.error("Error creating shared Configuration: ", ex); 301 throw new ConfigurationException("Error creating shared Configuration." 302 + ex.getMessage(), ex); 303 } 304 305 Configuration.initializeSharedConfiguration(conf); 306 } 307 308 313 public static void initializeSharedConfiguration(Configuration conf) { 314 if (!conf.canInitialize()) { 316 throw new ConfigurationException("Configuration of class " 317 + conf.getClass().getName() 318 + " refused to be initialized."); 319 } 320 321 try { 322 conf.initialize(); 324 325 conf.didInitialize(); 327 328 Configuration.sharedConfiguration = conf; 330 } 331 catch (Exception ex) { 332 throw new ConfigurationException( 333 "Error during Configuration initialization. " + ex.getMessage(), 334 ex); 335 } 336 } 337 338 344 protected Configuration() { 345 this(DEFAULT_DOMAIN_FILE); 346 } 347 348 354 protected Configuration(String domainConfigurationName) { 355 super(); 356 357 this.configureLogging(); 359 360 this.setDomainConfigurationName(domainConfigurationName); 362 } 363 364 368 public abstract boolean canInitialize(); 369 370 375 public abstract void initialize() throws Exception ; 376 377 380 public abstract void didInitialize(); 381 382 385 protected abstract ResourceLocator getResourceLocator(); 386 387 390 protected abstract InputStream getDomainConfiguration(); 393 394 397 protected abstract InputStream getMapConfiguration(String name); 398 399 protected abstract InputStream getViewConfiguration(String location); 400 401 405 protected void configureLogging() { 406 Configuration.configureCommonLogging(); 407 } 408 409 413 public String getDomainConfigurationName() { 414 return this.domainConfigurationName; 415 } 416 417 423 protected void setDomainConfigurationName(String domainConfigurationName) { 424 this.domainConfigurationName = domainConfigurationName; 425 } 426 427 430 public String getProjectVersion() { 431 return projectVersion; 432 } 433 434 437 public void setProjectVersion(String projectVersion) { 438 this.projectVersion = projectVersion; 439 } 440 441 447 public DataSourceFactory getDataSourceFactory() { 448 return this.overrideFactory; 449 } 450 451 public void setDataSourceFactory(DataSourceFactory overrideFactory) { 452 this.overrideFactory = overrideFactory; 453 } 454 455 458 public void addDomain(DataDomain domain) { 459 this.dataDomains.put(domain.getName(), domain); 460 logObj.debug("added domain: " + domain.getName()); 461 } 462 463 467 public DataDomain getDomain(String name) { 468 return (DataDomain) this.dataDomains.get(name); 469 } 470 471 478 public DataDomain getDomain() { 479 int size = this.dataDomains.size(); 480 if (size == 0) { 481 return null; 482 } 483 else if (size == 1) { 484 return (DataDomain) this.dataDomains.values().iterator().next(); 485 } 486 else { 487 throw new CayenneRuntimeException( 488 "More than one domain is configured; use 'getDomain(String name)' instead."); 489 } 490 } 491 492 498 public void removeDomain(String name) { 499 this.dataDomains.remove(name); 500 logObj.debug("removed domain: " + name); 501 } 502 503 506 public Collection getDomains() { 507 return this.dataDomainsRef; 508 } 509 510 515 public boolean isIgnoringLoadFailures() { 516 return this.ignoringLoadFailures; 517 } 518 519 524 protected void setIgnoringLoadFailures(boolean ignoringLoadFailures) { 525 this.ignoringLoadFailures = ignoringLoadFailures; 526 } 527 528 533 public ConfigStatus getLoadStatus() { 534 return this.loadStatus; 535 } 536 537 540 protected void setLoadStatus(ConfigStatus status) { 541 this.loadStatus = status; 542 } 543 544 547 public ConfigLoaderDelegate getLoaderDelegate() { 548 return loaderDelegate; 549 } 550 551 555 public void setLoaderDelegate(ConfigLoaderDelegate loaderDelegate) { 556 this.loaderDelegate = loaderDelegate; 557 } 558 559 565 public void setDataViewLocations(Map dataViewLocations) { 566 if (dataViewLocations == null) 567 this.dataViewLocations = new HashMap (); 568 else 569 this.dataViewLocations = dataViewLocations; 570 } 571 572 575 public Map getDataViewLocations() { 576 return dataViewLocations; 577 } 578 579 582 public boolean loadDataView(DataView dataView) throws IOException { 583 return loadDataView(dataView, Configuration.ACCEPT_ALL_DATAVIEWS); 584 } 585 586 589 public boolean loadDataView(DataView dataView, Predicate dataViewNameFilter) 590 throws IOException { 591 592 Validate.notNull(dataView, "DataView cannot be null."); 593 594 if (dataViewLocations.size() == 0 || dataViewLocations.size() > 512) { 595 return false; 596 } 597 598 if (dataViewNameFilter == null) 599 dataViewNameFilter = Configuration.ACCEPT_ALL_DATAVIEWS; 600 601 List viewXMLSources = new ArrayList (dataViewLocations.size()); 602 int index = 0; 603 for (Iterator i = dataViewLocations.entrySet().iterator(); i.hasNext(); index++) { 604 Map.Entry entry = (Map.Entry ) i.next(); 605 String name = (String ) entry.getKey(); 606 if (!dataViewNameFilter.evaluate(name)) 607 continue; 608 String location = (String ) entry.getValue(); 609 InputStream in = getViewConfiguration(location); 610 if (in != null) 611 viewXMLSources.add(in); 612 } 613 614 if (viewXMLSources.isEmpty()) 615 return false; 616 617 dataView.load((InputStream []) viewXMLSources 618 .toArray(new InputStream [viewXMLSources.size()])); 619 return true; 620 } 621 622 625 public void shutdown() { 626 Collection domains = getDomains(); 627 for (Iterator i = domains.iterator(); i.hasNext();) { 628 DataDomain domain = (DataDomain) i.next(); 629 domain.shutdown(); 630 } 631 } 632 633 private class ConfigurationShutdownHook extends Thread { 634 635 public void run() { 636 shutdown(); 637 } 638 } 639 640 public void installConfigurationShutdownHook() { 641 uninstallConfigurationShutdownHook(); 642 Runtime.getRuntime().addShutdownHook(configurationShutdownHook); 643 } 644 645 public void uninstallConfigurationShutdownHook() { 646 Runtime.getRuntime().removeShutdownHook(configurationShutdownHook); 647 } 648 649 655 public ClassLoader getClassLoader() { 656 return classLoader != null ? classLoader : Configuration.getResourceLoader(); 657 } 658 659 662 public void setClassLoader(ClassLoader classLoader) { 663 this.classLoader = classLoader; 664 } 665 } | Popular Tags |