1 package net.myvietnam.mvncore.configuration; 2 55 import java.io.File ; 56 import java.io.InputStream ; 57 import java.net.URL ; 58 import java.util.Collection ; 59 import java.util.Iterator ; 60 import java.util.LinkedList ; 61 import java.util.Stack ; 62 63 import org.apache.commons.digester.AbstractObjectCreationFactory; 64 import org.apache.commons.digester.Digester; 65 import org.apache.commons.digester.ObjectCreationFactory; 66 import org.apache.commons.digester.xmlrules.DigesterLoader; 67 import org.apache.commons.lang.StringUtils; 68 import org.apache.commons.logging.Log; 69 import org.apache.commons.logging.LogFactory; 70 import org.xml.sax.Attributes ; 71 import org.xml.sax.SAXException ; 72 84 public class ConfigurationFactory implements BasePathLoader 85 { 86 87 private static final String SEC_ROOT = "configuration/"; 88 89 90 private static final String SEC_OVERRIDE = SEC_ROOT + "override/"; 91 92 93 private static final String SEC_ADDITIONAL = SEC_ROOT + "additional/"; 94 95 96 private static final String METH_LOAD = "load"; 97 98 99 private static final String DEF_BASE_PATH = "."; 100 101 102 private String configurationFileName; 103 106 private URL configurationURL; 107 112 private String impliciteBasePath; 113 114 private String basePath; 115 116 private static Log log = LogFactory.getLog(ConfigurationFactory.class); 117 118 private URL digesterRules; 119 120 private String digesterRuleNamespaceURI; 121 124 public ConfigurationFactory() 125 { 126 setBasePath(DEF_BASE_PATH); 127 } 128 133 public ConfigurationFactory(String configurationFileName) 134 { 135 this.configurationFileName = configurationFileName; 136 } 137 147 public Configuration getConfiguration() throws Exception 148 { 149 Digester digester; 150 ConfigurationBuilder builder = new ConfigurationBuilder(); 151 URL url = getConfigurationURL(); 152 if(url == null) 153 { 154 url = ConfigurationUtils.getURL(impliciteBasePath, 155 getConfigurationFileName()); 156 } 157 InputStream input = url.openStream(); 158 159 if (getDigesterRules() == null) 160 { 161 digester = new Digester(); 162 configureNamespace(digester); 163 initDefaultDigesterRules(digester); 164 } 165 else 166 { 167 digester = DigesterLoader.createDigester(getDigesterRules()); 168 configureNamespace(digester); 171 } 172 digester.push(builder); 174 try 176 { 177 digester.parse(input); 178 input.close(); 179 } 180 catch (SAXException e) 181 { 182 log.error("SAX Exception caught", e); 183 throw e; 184 } 185 return builder.getConfiguration(); 186 } 187 192 public String getConfigurationFileName() 193 { 194 return configurationFileName; 195 } 196 200 public void setConfigurationFileName(String configurationFileName) 201 { 202 File file = new File (configurationFileName).getAbsoluteFile(); 203 this.configurationFileName = file.getName(); 204 impliciteBasePath = file.getParent(); 205 } 206 207 211 public URL getConfigurationURL() 212 { 213 return configurationURL; 214 } 215 216 221 public void setConfigurationURL(URL url) 222 { 223 configurationURL = url; 224 impliciteBasePath = url.toString(); 225 226 if(DEF_BASE_PATH.equals(getBasePath())) 231 { 232 setBasePath(null); 233 } 234 } 235 236 240 public URL getDigesterRules() 241 { 242 return digesterRules; 243 } 244 248 public void setDigesterRules(URL digesterRules) 249 { 250 this.digesterRules = digesterRules; 251 } 252 262 protected void initDefaultDigesterRules(Digester digester) 263 { 264 initDigesterSectionRules(digester, SEC_ROOT, false); 265 initDigesterSectionRules(digester, SEC_OVERRIDE, false); 266 initDigesterSectionRules(digester, SEC_ADDITIONAL, true); 267 } 268 269 277 protected void initDigesterSectionRules(Digester digester, 278 String matchString, boolean additional) 279 { 280 setupDigesterInstance( 281 digester, 282 matchString + "properties", 283 new BasePathConfigurationFactory(PropertiesConfiguration.class), 284 METH_LOAD, 285 additional); 286 setupDigesterInstance( 287 digester, 288 matchString + "dom4j", 289 new BasePathConfigurationFactory(DOM4JConfiguration.class), 290 METH_LOAD, 291 additional); 292 setupDigesterInstance( 293 digester, 294 matchString + "hierarchicalDom4j", 295 new BasePathConfigurationFactory(HierarchicalDOM4JConfiguration.class), 296 METH_LOAD, 297 additional); 298 setupDigesterInstance( 299 digester, 300 matchString + "jndi", 301 new JNDIConfigurationFactory(), 302 null, 303 additional); 304 } 305 306 316 protected void setupDigesterInstance( 317 Digester digester, 318 String matchString, 319 ObjectCreationFactory factory, 320 String method, 321 boolean additional) 322 { 323 if(additional) 324 { 325 setupUnionRules(digester, matchString); 326 } 327 digester.addFactoryCreate(matchString, factory); 328 digester.addSetProperties(matchString); 329 if(method != null) 330 { 331 digester.addCallMethod(matchString, method); 332 } 333 digester.addSetNext( 334 matchString, 335 "addConfiguration", 336 Configuration.class.getName()); 337 } 338 339 344 protected void setupUnionRules(Digester digester, String matchString) 345 { 346 digester.addObjectCreate(matchString, 347 AdditionalConfigurationData.class); 348 digester.addSetProperties(matchString); 349 digester.addSetNext(matchString, "addAdditionalConfig", 350 AdditionalConfigurationData.class.getName()); 351 } 352 357 public String getDigesterRuleNamespaceURI() 358 { 359 return digesterRuleNamespaceURI; 360 } 361 366 public void setDigesterRuleNamespaceURI(String digesterRuleNamespaceURI) 367 { 368 this.digesterRuleNamespaceURI = digesterRuleNamespaceURI; 369 } 370 377 private void configureNamespace(Digester digester) 378 { 379 if (getDigesterRuleNamespaceURI() != null) 380 { 381 digester.setNamespaceAware(true); 382 digester.setRuleNamespaceURI(getDigesterRuleNamespaceURI()); 383 } 384 else 385 { 386 digester.setNamespaceAware(false); 387 } 388 digester.setValidating(false); 389 } 390 397 public String getBasePath() 398 { 399 String path = StringUtils.isEmpty(basePath) ? 400 impliciteBasePath : basePath; 401 return StringUtils.isEmpty(path) ? "." : path; 402 } 403 414 public void setBasePath(String basePath) 415 { 416 this.basePath = basePath; 417 } 418 419 424 public class DigesterConfigurationFactory 425 extends AbstractObjectCreationFactory 426 implements ObjectCreationFactory 427 { 428 429 private Class clazz; 430 431 435 public DigesterConfigurationFactory(Class clazz) 436 { 437 this.clazz = clazz; 438 } 439 440 446 public Object createObject(Attributes attribs) throws Exception 447 { 448 return clazz.newInstance(); 449 } 450 } 451 452 458 public class BasePathConfigurationFactory 459 extends DigesterConfigurationFactory 460 { 461 466 public BasePathConfigurationFactory(Class clazz) 467 { 468 super(clazz); 469 } 470 471 478 public Object createObject(Attributes attributes) throws Exception 479 { 480 BasePathLoader bpl = 481 (BasePathLoader) super.createObject(attributes); 482 bpl.setBasePath(getBasePath()); 483 return bpl; 484 } 485 } 486 487 492 public class JNDIConfigurationFactory 493 extends DigesterConfigurationFactory 494 { 495 498 public JNDIConfigurationFactory() 499 { 500 super(JNDIConfiguration.class); 501 } 502 } 503 504 508 public static class AdditionalConfigurationData 509 { 510 511 private Configuration configuration; 512 513 514 private String at; 515 516 520 public String getAt() 521 { 522 return at; 523 } 524 525 529 public void setAt(String string) 530 { 531 at = string; 532 } 533 534 538 public Configuration getConfiguration() 539 { 540 return configuration; 541 } 542 543 550 public void addConfiguration(Configuration config) 551 { 552 configuration = config; 553 } 554 } 555 556 560 public static class ConfigurationBuilder 561 { 562 563 private CompositeConfiguration config; 564 565 566 private Collection additionalConfigs; 567 568 571 public ConfigurationBuilder() 572 { 573 config = new CompositeConfiguration(); 574 additionalConfigs = new LinkedList (); 575 } 576 577 582 public void addConfiguration(Configuration conf) 583 { 584 config.addConfiguration(conf); 585 } 586 587 592 public void addAdditionalConfig(AdditionalConfigurationData data) 593 { 594 additionalConfigs.add(data); 595 } 596 597 601 public CompositeConfiguration getConfiguration() 602 { 603 if(!additionalConfigs.isEmpty()) 604 { 605 Configuration unionConfig = 606 createAdditionalConfiguration(additionalConfigs); 607 if(unionConfig != null) 608 { 609 addConfiguration(unionConfig); 610 } 611 additionalConfigs.clear(); 612 } 613 614 return config; 615 } 616 617 626 protected Configuration createAdditionalConfiguration( 627 Collection configs) 628 { 629 HierarchicalConfiguration result = new HierarchicalConfiguration(); 630 631 for(Iterator it = configs.iterator(); it.hasNext();) 632 { 633 AdditionalConfigurationData cdata = 634 (AdditionalConfigurationData) it.next(); 635 result.addNodes(cdata.getAt(), 636 createRootNode(cdata).getChildren().asVector()); 637 } 638 639 return (result.isEmpty()) ? null : result; 640 } 641 642 647 private HierarchicalConfiguration.Node createRootNode( 648 AdditionalConfigurationData cdata) 649 { 650 if(cdata.getConfiguration() instanceof HierarchicalConfiguration) 651 { 652 return ((HierarchicalConfiguration) cdata.getConfiguration()) 654 .getRoot(); 655 } 656 657 else 658 { 659 HierarchicalConfigurationNodeConverter conv = 661 new HierarchicalConfigurationNodeConverter(); 662 conv.process(cdata.getConfiguration()); 663 return conv.getRootNode(); 664 } 665 } 666 } 667 668 675 static class HierarchicalConfigurationNodeConverter 676 extends HierarchicalConfigurationConverter 677 { 678 679 private Stack nodes; 680 681 682 private HierarchicalConfiguration.Node root; 683 684 687 public HierarchicalConfigurationNodeConverter() 688 { 689 nodes = new Stack (); 690 root = new HierarchicalConfiguration.Node(); 691 nodes.push(root); 692 } 693 694 700 protected void elementStart(String name, Object value) 701 { 702 HierarchicalConfiguration.Node parent = 703 (HierarchicalConfiguration.Node) nodes.peek(); 704 HierarchicalConfiguration.Node child = 705 new HierarchicalConfiguration.Node(name); 706 if(value != null) 707 { 708 child.setValue(value); 709 } 710 parent.addChild(child); 711 nodes.push(child); 712 } 713 714 718 protected void elementEnd(String name) 719 { 720 nodes.pop(); 721 } 722 723 727 public HierarchicalConfiguration.Node getRootNode() 728 { 729 return root; 730 } 731 } 732 } 733 | Popular Tags |