Clover coverage report -
Coverage timestamp: Do Okt 21 2004 12:21:23 CEST
file stats: LOC: 1.028   Methods: 76
NCLOC: 574   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
DefaultConfiguration.java 66,9% 79,9% 84,2% 77,4%
coverage coverage
 1    /*
 2    * Configuration.java
 3    *
 4    * Created on 19. November 2002, 22:27
 5    */
 6   
 7    package org.jconfig;
 8   
 9    import java.io.Serializable;
 10    import java.util.Enumeration;
 11    import java.util.HashMap;
 12    import java.util.Iterator;
 13    import java.util.Properties;
 14    import java.util.Set;
 15    import java.util.SortedMap;
 16    import java.util.StringTokenizer;
 17    import java.util.TreeMap;
 18    import java.util.Vector;
 19    import javax.swing.event.EventListenerList;
 20   
 21    import org.jconfig.event.CategoryChangedEvent;
 22    import org.jconfig.event.CategoryListener;
 23    import org.jconfig.event.ConfigurationChangedEvent;
 24    import org.jconfig.event.ConfigurationChangedEventImpl;
 25    import org.jconfig.event.ConfigurationListener;
 26    import org.jconfig.event.PropertyChangedEvent;
 27    import org.jconfig.event.PropertyListener;
 28    import org.jconfig.utils.IncludeEntry;
 29    /**
 30    * This class is the configuration itself. The Configuration is
 31    * useful if one wants to manage multiple configurations. A single
 32    * instance of the Configuration may contain, for example, information
 33    * for one application or user.
 34    *
 35    * @author Andreas Mecky andreas.mecky@xcom.de
 36    * @author Terry Dye terry.dye@xcom.de
 37    */
 38    public class DefaultConfiguration implements Serializable,Configuration {
 39   
 40    protected static final VariableManager vm = VariableManager.getInstance();
 41    // the name of the configuration
 42    protected String configName;
 43    // a map containing all properties for each category
 44    protected HashMap categories;
 45    // the name of the default category
 46    protected String mainCategory;
 47    // The List of ConfigurationListeners
 48    private EventListenerList configurationListenerList = new EventListenerList();
 49    // flag to determine if this is a newly created configuration
 50    private boolean created = true;
 51   
 52    private String encoding;
 53   
 54    protected String baseConfigName;
 55   
 56    private boolean dirtyFlag = false;
 57   
 58    private Vector includes = new Vector();
 59   
 60  0 protected DefaultConfiguration() {
 61    }
 62    /**
 63    * The constructor that creates a new configuration
 64    * with one empty category called "general". This
 65    * category is also the default category.
 66    *
 67    * @param configName the name of the configuration
 68    */
 69  89 public DefaultConfiguration(String configName) {
 70  89 categories = new HashMap();
 71  89 this.configName = configName;
 72  89 setCategory("general", true);
 73  89 created = true;
 74    }
 75   
 76    /**
 77    * This method sets a category but it does not set
 78    * this category as default.
 79    *
 80    * @param name the name of the category
 81    */
 82  58 public void setCategory(String name) {
 83  58 setCategory(name, false);
 84    }
 85   
 86    /**
 87    * Besides setting the category, it will also set this
 88    * category as default category if main is true. It will
 89    * only set (ie create) the category if it does not exist. If you
 90    * want delete a category then use @see #removeCategory(String)
 91    *
 92    * @param name the name of the category
 93    * @param main if true then this category is the default category
 94    */
 95  120 public void setCategory(String name, boolean main) {
 96  120 if (name != null) {
 97  120 if (main) {
 98  65 mainCategory = name;
 99    }
 100  120 if (!categories.containsKey(name)) {
 101  109 Category category = new DefaultCategory(name);
 102  109 category.setConfigurationName(configName);
 103  109 category.addCategoryListener(new MyCategoryListener());
 104  109 categories.put(name, category);
 105  109 markDirty();
 106  109 category.fireCategoryChangedEvent(
 107    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.CATEGORY_ADDED, category, null, null, null ));
 108  109 fireConfigurationChangedEvent(
 109    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.CATEGORY_ADDED, category, null, null, null ));
 110    }
 111    }
 112    }
 113   
 114  5 public void setCategory(Category category) {
 115  5 if (!categories.containsKey(category.getCategoryName())) {
 116  3 category.setConfigurationName(configName);
 117  3 category.addCategoryListener(new MyCategoryListener());
 118  3 categories.put(category.getCategoryName(), category);
 119  3 category.fireCategoryChangedEvent(
 120    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.CATEGORY_ADDED, category, null, null, null ));
 121  3 fireConfigurationChangedEvent(
 122    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.CATEGORY_ADDED, category, null, null, null ));
 123    }
 124    }
 125    /**
 126    * This method returns the name of the
 127    * default category
 128    *
 129    * @return name of the default category
 130    */
 131  2 public String getMainCategoryName() {
 132  2 return mainCategory;
 133    }
 134   
 135    /**
 136    * This method returns a string array with all
 137    * category names.
 138    *
 139    * @return a string array with all category names
 140    */
 141  11 public String[] getCategoryNames() {
 142  11 return getCategoryNames(true);
 143    }
 144   
 145  14 protected String[] getCategoryNames(boolean includeParent) {
 146  14 Set allCategories = categories.keySet();
 147  14 Vector all = new Vector(allCategories);
 148  14 if ( baseConfigName != null && includeParent ) {
 149  0 Configuration cfg = ConfigurationManager.getConfiguration(baseConfigName);
 150  0 String[] parentCategories = cfg.getCategoryNames();
 151  0 for ( int i = 0 ; i < parentCategories.length ; i++) {
 152  0 if ( all.indexOf(parentCategories[i]) == -1 ) {
 153  0 all.add(parentCategories[i]);
 154    }
 155    }
 156    }
 157  14 return (String[]) all.toArray(new String[0]);
 158    }
 159   
 160    /**
 161    * This method returns the String value based on the given key.
 162    *
 163    * Implementation details: It calls getProperty(name,null,null).
 164    * It searches inside the default category for the property.
 165    *
 166    * @param key the name of the property
 167    * @return the value as String if it is found or null
 168    */
 169  14 public String getProperty(String key) {
 170  14 return getProperty(key, null, null);
 171    }
 172   
 173    /**
 174    * This method is the same as getProperty(key) but it
 175    * returns the defaultValue if the property cannot be found.
 176    *
 177    * Implementation details: It calls getProperty(key,defaultValue,null).
 178    *
 179    * @param key the name of the property
 180    * @param defaultValue the defaultValue that will be returned if the property cannot be found
 181    * @return the value as String
 182    */
 183  1 public String getProperty(String key, String defaultValue) {
 184  1 return getProperty(key, defaultValue, null);
 185    }
 186   
 187    /**
 188    * This is the real implementation. It will return the value of the property
 189    * with the specific name. First of all, it checks if the name of the category
 190    * exists. If not, then it will use the name of the default category.
 191    * The next step is that it will look for the property. If it is not found in
 192    * the category, it will look inside the default category (inheritance). If
 193    * it still cannot find the property, it will return the defaultValue
 194    *
 195    * @param key the name of the property
 196    * @param defaultValue the default value
 197    * @param categoryName the name of the category
 198    * @return the value as String
 199    */
 200  49 public String getProperty(String key,String defaultValue,String categoryName) {
 201  49 boolean isMainCat = false;
 202  49 if (key == null) {
 203  0 return defaultValue;
 204    }
 205  49 if (!categories.containsKey(categoryName)) {
 206  12 isMainCat = true;
 207  12 categoryName = mainCategory;
 208    }
 209  49 Category category = getCategory(categoryName);
 210  49 if ( category.getCategoryName().equals(mainCategory)) {
 211  24 isMainCat = true;
 212    }
 213  49 String tmp = category.getProperty(key);
 214    // property not found so look in mainCategory
 215    // if it is not already the mainCategory
 216  49 if ( tmp == null && !isMainCat) {
 217  3 category = getCategory(mainCategory);
 218  3 tmp = category.getProperty(key);
 219    }
 220  49 if ( tmp == null ) {
 221  8 if ( baseConfigName != null ) {
 222  1 Configuration cfg = ConfigurationManager.getConfiguration(baseConfigName);
 223  1 tmp = cfg.getProperty(key,defaultValue,categoryName);
 224    }
 225    else {
 226  7 tmp = defaultValue;
 227    }
 228    }
 229  49 return tmp;
 230    }
 231   
 232    /**
 233    * This method sets a property with the name and the value
 234    * in the default category. It calls setProperty(name.value,null).
 235    *
 236    * @param name the name of the property
 237    * @param value the value as String
 238    */
 239  33 public void setProperty(String name, String value) {
 240  33 setProperty(name, value, null);
 241    }
 242   
 243    /**
 244    * This method sets the value for a property for the given
 245    * category. It also raises a PropertyEvent. If the category
 246    * is null then it uses the default category.
 247    *
 248    * @param name the name of the property
 249    * @param value the value as String
 250    * @param categoryName the name of the category
 251    */
 252  215 public void setProperty(String name, String value, String categoryName) {
 253  215 if (name != null) {
 254  215 if (categoryName == null) {
 255  33 categoryName = mainCategory;
 256    }
 257  215 Category category = getCategory(categoryName);
 258  215 category.setProperty(name, value);
 259  215 markDirty();
 260  215 fireConfigurationChangedEvent(
 261    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.PROPERTY_CHANGED, category, name, value,null ));
 262    }
 263    }
 264   
 265    /**
 266    * This method deletes a property from the default category.
 267    * It calls removeProperty(name,null).
 268    *
 269    * @param name the name of the property
 270    */
 271  1 public void removeProperty(String name) {
 272  1 if (name != null) {
 273  1 removeProperty(name, null);
 274    }
 275    }
 276   
 277    /**
 278    * This method deletes a property with the given name
 279    * from the specific category. If the category is null
 280    * then it will delete the property from the default category.
 281    *
 282    * @param name the name of the property
 283    * @param category the name of the category
 284    */
 285  3 public void removeProperty(String name, String category) {
 286  3 if (category == null) {
 287  1 category = mainCategory;
 288    }
 289  3 if (name != null) {
 290    //if (categories.containsKey(category)) {
 291  3 Category cat = getCategory(category);
 292  3 String tmp = cat.getProperty(name,null);
 293  3 cat.setProperty(name, null);
 294  3 fireConfigurationChangedEvent(
 295    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.PROPERTY_REMOVED,cat, name, tmp,null ));
 296  3 markDirty();
 297    }
 298   
 299    }
 300   
 301    /**
 302    * The method returns the number of categories inside this configuration.
 303    *
 304    * @return the number of categories
 305    */
 306  4 public int getNumberOfCategories() {
 307  4 return getCategoryNames().length;
 308    }
 309   
 310    /**
 311    * This method deletes a category with all its properties
 312    *
 313    * @param category the name of the category
 314    */
 315  1 public void removeCategory(String category) {
 316  1 if (categories.containsKey(category)) {
 317  1 Category cat = getCategory(category);
 318  1 categories.remove(category);
 319  1 cat.fireCategoryChangedEvent(
 320    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.CATEGORY_REMOVED, cat, null, null, null));
 321  1 fireConfigurationChangedEvent(
 322    new ConfigurationChangedEventImpl(ConfigurationChangedEvent.CATEGORY_REMOVED,cat, null, null,null ));
 323  1 cat = null;
 324  1 markDirty();
 325    }
 326    }
 327   
 328  1 public Properties getProperties(String category) {
 329  1 return getProperties(category,true);
 330    }
 331   
 332  1 public Properties getProperties() {
 333  1 return getProperties(mainCategory,true);
 334    }
 335   
 336  30 protected Properties getProperties(String category,boolean includeParent) {
 337  30 Category cat = getCategory(category);
 338  30 Properties props = new Properties();
 339  30 if ( cat != null ) {
 340  30 props = (Properties)cat.getProperties().clone();
 341    }
 342  30 if ( baseConfigName != null && includeParent ) {
 343  1 Configuration cfg = ConfigurationManager.getConfiguration(baseConfigName);
 344  1 Properties parentProps = cfg.getProperties(category);
 345  1 Enumeration num = parentProps.keys();
 346  1 while ( num.hasMoreElements() ) {
 347  5 String name = (String)num.nextElement();
 348  5 if ( !props.contains(name) ) {
 349  5 props.setProperty(name, (String)parentProps.get(name));
 350    }
 351    }
 352    }
 353  30 return props;
 354    }
 355   
 356    /**
 357    * This method returns all the names of the properties
 358    * for the specific category
 359    *
 360    * @param category the name of the category
 361    * @return the names as string array
 362    */
 363  1 public String[] getPropertyNames(String category) {
 364  1 if ( containsCategory(category) ) {
 365    // FIXME: include parent properties
 366  0 Properties properties = getProperties(category);
 367  0 if (properties != null) {
 368  0 Enumeration en = properties.propertyNames();
 369  0 Vector keys = new Vector();
 370  0 while ( en.hasMoreElements() ) {
 371  0 String nm = (String)en.nextElement();
 372  0 keys.add(nm);
 373    }
 374    /*
 375    Set keys = properties.keySet();
 376    */
 377  0 return (String[]) keys.toArray(new String[0]);
 378    }
 379    }
 380  1 return null;
 381    }
 382   
 383    /**
 384    * This method sets a variable inside the configuration.
 385    *
 386    * @param name the name of the variable
 387    * @param value the value of the variable
 388    */
 389  79 public void setVariable(String name, String value) {
 390  79 if (name != null && value != null) {
 391  79 vm.addVariable(name, value,configName);
 392    }
 393    }
 394   
 395    /**
 396    * It returns a HashMap with all variables with the
 397    * variable name as key
 398    *
 399    * @return a HashMap with all variables
 400    */
 401  3 public HashMap getVariables() {
 402  3 return vm.getVariables(configName);
 403    }
 404   
 405  14 public String getVariable(String name) {
 406  14 return vm.getVariable(configName, name);
 407    }
 408   
 409   
 410    /**
 411    * @param name
 412    * @param defaultValue
 413    * @return
 414    */
 415  4 public int getIntProperty(String name, int defaultValue) {
 416  4 return getIntProperty(name, defaultValue, mainCategory);
 417    }
 418   
 419    /**
 420    * @param name
 421    * @param defaultValue
 422    * @param category
 423    * @return
 424    */
 425  7 public int getIntProperty(String name, int defaultValue, String category) {
 426  7 String value = getProperty(name,null,category);
 427  7 if (value == null) {
 428  0 return defaultValue;
 429    } else {
 430  7 try {
 431  7 return Integer.parseInt(vm.replaceVariables(value,configName));
 432    } catch (NumberFormatException nfe) {
 433  0 return defaultValue;
 434    }
 435    }
 436    }
 437   
 438    /**
 439    * Wrapper method to keep API simple
 440    *
 441    * @see Category#getBooleanProperty(String, boolean)
 442    * @param name
 443    * @param defaultValue
 444    * @return
 445    */
 446  2 public boolean getBooleanProperty(String name, boolean defaultValue) {
 447  2 return getBooleanProperty(name, defaultValue, mainCategory);
 448    }
 449   
 450    /**
 451    * Wrapper method to Category method
 452    *
 453    * @see Category#getBooleanProperty(String, boolean, String)
 454    * @param defaultValue
 455    * @param categoryName
 456    * @return
 457    */
 458  5 public boolean getBooleanProperty(String name,boolean defaultValue,String categoryName) {
 459  5 String value = getProperty(name,null,categoryName);
 460  5 if ( value == null ) {
 461  1 return defaultValue;
 462    } else {
 463  4 try {
 464  4 return Boolean.valueOf(vm.replaceVariables(value,configName)).booleanValue();
 465    } catch (Exception e) {
 466  0 return defaultValue;
 467    }
 468    }
 469    }
 470   
 471    /**
 472    * Wrapper method to Category method
 473    *
 474    * @param key
 475    * @param value
 476    */
 477  2 public void setBooleanProperty(String key, boolean value) {
 478  2 getCategory().setBooleanProperty(key, value);
 479   
 480    }
 481   
 482    /**
 483    * Wrapper method to Category method
 484    *
 485    * @param key
 486    * @param value
 487    * @param category
 488    */
 489  1 public void setBooleanProperty(String key, boolean value, String category) {
 490  1 getCategory(category).setBooleanProperty(key, value);
 491    }
 492   
 493    /**
 494    * Wrapper method to Category method
 495    *
 496    * @param name
 497    * @param defaultValue
 498    * @return
 499    */
 500  2 public long getLongProperty(String name, long defaultValue) {
 501  2 return getLongProperty(name, defaultValue, mainCategory);
 502    }
 503   
 504    /**
 505    * Wrapper method to Category method
 506    *
 507    * @param name
 508    * @param defaultValue
 509    * @param category
 510    * @return
 511    */
 512  7 public long getLongProperty(String name,long defaultValue,String categoryName) {
 513  7 String value = getProperty(name,null,categoryName);
 514  7 if (value == null) {
 515  0 return defaultValue;
 516    } else {
 517  7 try {
 518  7 return Long.parseLong(vm.replaceVariables(value,configName));
 519    } catch (NumberFormatException nfe) {
 520  0 return defaultValue;
 521    }
 522    }
 523    }
 524   
 525    /**
 526    * Wrapper method to Category method
 527    *
 528    * @param name
 529    * @param defaultValue
 530    * @return
 531    */
 532  2 public double getDoubleProperty(String name, double defaultValue) {
 533  2 return getDoubleProperty(name, defaultValue, mainCategory);
 534    }
 535   
 536    /**
 537    * Wrapper method to Category method
 538    *
 539    * @param name
 540    * @param defaultValue
 541    * @param category
 542    * @return
 543    */
 544  5 public double getDoubleProperty(String name,double defaultValue,String category) {
 545  5 String value = getProperty(name,null,category);
 546  5 if (value == null) {
 547  0 return defaultValue;
 548    } else {
 549  5 try {
 550  5 return Double.parseDouble(vm.replaceVariables(value,configName));
 551    } catch (Exception e) {
 552  0 return defaultValue;
 553    }
 554    }
 555    }
 556   
 557    /**
 558    * Wrapper method to Category method
 559    *
 560    * @param name
 561    * @param defaultValue
 562    * @return
 563    */
 564  2 public char getCharProperty(String name, char defaultValue) {
 565  2 return getCharProperty(name, defaultValue, mainCategory);
 566    }
 567   
 568    /**
 569    * Wrapper method to Category method
 570    *
 571    * @param name
 572    * @param defaultValue
 573    * @param category
 574    * @return
 575    */
 576  5 public char getCharProperty(
 577    String name,
 578    char defaultValue,
 579    String category) {
 580  5 Category cat = getCategory(category);
 581  5 return cat.getCharProperty(name, defaultValue);
 582    }
 583   
 584    /**
 585    * This method creates a string representation of the configuration.
 586    *
 587    * @return a string with the configuration
 588    */
 589  0 public String toString() {
 590  0 StringBuffer buffer = new StringBuffer();
 591  0 String[] cats = getCategoryNames(false);
 592  0 for (int i = 0; i < cats.length; i++) {
 593  0 buffer.append("Category=");
 594  0 buffer.append(cats[i]);
 595  0 Properties props = getProperties(cats[i],false);
 596  0 if (props != null) {
 597  0 buffer.append("\n");
 598  0 Iterator nit = props.keySet().iterator();
 599  0 while (nit.hasNext()) {
 600  0 String name = (String) nit.next();
 601  0 String value = props.getProperty(name);
 602  0 buffer.append(" ");
 603  0 buffer.append(name);
 604  0 buffer.append("=");
 605  0 buffer.append(value);
 606  0 buffer.append("\n");
 607    }
 608    }
 609    }
 610  0 return buffer.toString();
 611    }
 612   
 613    /**
 614    * This method converts the Configuration into a String
 615    * which looks like XML.
 616    *
 617    * @return the Configuration as String in XML format
 618    */
 619  3 public String getXMLAsString() {
 620  3 StringBuffer buffer = new StringBuffer();
 621    // first we will write out the variable block
 622    // if we have some
 623  3 buffer.append("<?xml version=\"1.0\"");
 624  3 if ( getEncoding() != null ) {
 625  0 buffer.append(" encoding=\""+getEncoding()+"\"");
 626    }
 627  3 buffer.append(" ?>\n");
 628  3 buffer.append("<properties");
 629  3 if ( baseConfigName != null ) {
 630  0 buffer.append(" extends=\"");
 631  0 buffer.append(baseConfigName);
 632  0 buffer.append("\"");
 633    }
 634  3 buffer.append(">\n");
 635  3 addIncludeBlock(buffer);
 636  3 addVariableBlock(buffer);
 637    // now we are writing out all categories with
 638    // their properties
 639  3 String[] cats = getCategoryNames(false);
 640  3 for (int i = 0; i < cats.length; i++) {
 641  12 buffer.append(" <category name=\"");
 642  12 buffer.append(escapeForXML(cats[i]));
 643  12 buffer.append("\">\n");
 644  12 SortedMap sm = getSortedProperties(cats[i],false);
 645  12 if (sm != null) {
 646  12 Iterator nit = sm.keySet().iterator();
 647  12 while (nit.hasNext()) {
 648  57 String name = (String) nit.next();
 649  57 String value = (String)sm.get(name);
 650  57 buffer.append(" <property name=\"");
 651  57 buffer.append(escapeForXML(name));
 652  57 buffer.append("\" value=\"");
 653    // do not convert the value
 654  57 buffer.append(escapeForXML(value));
 655  57 buffer.append("\"/>\n");
 656    }
 657  12 buffer.append(" </category>\n");
 658    }
 659    }
 660  3 buffer.append("</properties>\n");
 661  3 return buffer.toString();
 662    }
 663   
 664  28 protected SortedMap getSortedProperties(String categoryName,boolean includeParent) {
 665  28 Properties props = getProperties(categoryName,includeParent);
 666  28 SortedMap sm = new TreeMap();
 667  28 if (props != null) {
 668  28 Iterator nit = props.keySet().iterator();
 669  28 while (nit.hasNext()) {
 670  78 String name = (String) nit.next();
 671  78 String value = props.getProperty(name);
 672  78 sm.put(name,value);
 673    }
 674  28 return sm;
 675    }
 676  0 return null;
 677    }
 678   
 679  5 protected void addIncludeBlock(StringBuffer buffer) {
 680  5 if ( includes.size() > 0 ) {
 681  4 for ( int i = 0; i < includes.size();i++) {
 682  4 IncludeEntry ie = (IncludeEntry)includes.get(i);
 683  4 buffer.append(" <include ");
 684  4 if ( ie.getType() == IncludeEntry.PROPERTIES ) {
 685  4 buffer.append("properties=\"");
 686  4 buffer.append(ie.getName());
 687  4 buffer.append("\"/>\n");
 688    }
 689    }
 690    }
 691    }
 692   
 693  5 protected void addVariableBlock(StringBuffer buffer) {
 694  5 Iterator it = vm.getVariables(configName).keySet().iterator();
 695  5 boolean vars = false;
 696  5 if (it.hasNext()) {
 697  4 buffer.append(" <variables>\n");
 698  4 vars = true;
 699    }
 700  5 while (it.hasNext()) {
 701  13 String varName = (String) it.next();
 702  13 String varText = (String) vm.getVariables(configName).get(varName);
 703  13 buffer.append(" <variable name=\"");
 704  13 buffer.append(escapeForXML(varName));
 705  13 buffer.append("\" value=\"");
 706  13 buffer.append(escapeForXML(varText));
 707  13 buffer.append("\"/>\n");
 708    }
 709  5 if (vars) {
 710  4 buffer.append(" </variables>\n");
 711    }
 712    }
 713   
 714  231 protected String escapeForXML(String text) {
 715  231 StringBuffer result = new StringBuffer();
 716  231 for ( int i = 0; i < text.length();i++) {
 717  2556 char character = text.charAt(i);
 718  2556 if (character == '<') {
 719  1 result.append("&lt;");
 720    }
 721  2555 else if (character == '>') {
 722  1 result.append("&gt;");
 723    }
 724  2554 else if (character == '\"') {
 725  1 result.append("&quot;");
 726    }
 727  2553 else if (character == '\'') {
 728  0 result.append("&#039;");
 729    }
 730  2553 else if (character == '\\') {
 731  0 result.append("&#092;");
 732    }
 733  2553 else if (character == '&') {
 734  0 result.append("&amp;");
 735    }
 736    else {
 737  2553 result.append(character);
 738    }
 739    }
 740  231 return result.toString();
 741    }
 742   
 743    /**
 744    * Adds the PropertyListener to the main category.
 745    *
 746    * If the main category changes after the listener has
 747    * already been added, the listener is still registered,
 748    * but not to the main category any longer. One way to
 749    * handle this behavior is to remove the listener from
 750    * the old main category and add it to the new main
 751    * category.
 752    *
 753    * @param listener
 754    */
 755  0 public void addPropertyListener(PropertyListener listener) {
 756  0 addPropertyListener(listener, mainCategory);
 757    }
 758   
 759    /**
 760    * Adds the PropertyListener to the given category.
 761    */
 762  1 public void addPropertyListener(PropertyListener listener, String categoryName) {
 763  1 getCategory(categoryName).addPropertyListener(listener);
 764    }
 765   
 766  0 public void addCategoryListener(CategoryListener listener) {
 767  0 addCategoryListener(listener,mainCategory);
 768    }
 769   
 770  0 public void addCategoryListener(CategoryListener listener,String categoryName) {
 771  0 getCategory(categoryName).addCategoryListener(listener);
 772    }
 773    /**
 774    * Return the name of the current configuration.
 775    * @return
 776    */
 777  72 public String getConfigName() {
 778  72 return configName;
 779    }
 780   
 781  0 public void setConfigName(String configName) {
 782  0 this.configName = configName;
 783    }
 784   
 785    /**
 786    * Adds the specified configuration listener to receive configuration
 787    * changed events from this configuration.
 788    *
 789    * @param listener The ConfigurationListener
 790    */
 791  0 public void addConfigurationListener(ConfigurationListener listener) {
 792  0 configurationListenerList.add(ConfigurationListener.class, listener);
 793    }
 794   
 795    /**
 796    * Removes the specified configuration listener from the configuration
 797    * change events from this configuration.
 798    *
 799    * @param listener The ConfigurationListener
 800    */
 801  0 public void removeConfigurationListener(ConfigurationListener listener) {
 802  0 configurationListenerList.remove(ConfigurationListener.class, listener);
 803    }
 804   
 805    /**
 806    * Deliver configuration changed event to all listeners that are registered
 807    * with our listener list.
 808    *
 809    * @param event The ConfigurationChangedEvent
 810    */
 811  931 public void fireConfigurationChangedEvent(ConfigurationChangedEvent event) {
 812    // Guaranteed to return a non-null array
 813  931 Object[] listeners = configurationListenerList.getListenerList();
 814    // Process the listeners last to first, notifying
 815    // those that are interested in this event
 816  931 for (int i = listeners.length - 2; i >= 0; i -= 2) {
 817  0 if (listeners[i] == ConfigurationListener.class) {
 818    // Lazily create the event:
 819  0 ((ConfigurationListener) listeners[i + 1]).configurationChanged(event);
 820    }
 821    }
 822    }
 823   
 824    /**
 825    * Returns the main category for this configuration
 826    *
 827    * @return The main category
 828    */
 829  23 public Category getCategory() {
 830  23 return getCategory(mainCategory);
 831    }
 832   
 833    /**
 834    * Returns a category based on the name provided.
 835    * @param name The name of the category (if null, main category will be used)
 836    * @return The category object (new instance if necessary)
 837    */
 838  355 public Category getCategory(String name) {
 839  355 if(name == null) {
 840  3 name = mainCategory;
 841    }
 842  355 Category category = (Category)categories.get(name);
 843  355 if( category == null ) {
 844  18 category = new DefaultCategory(name);
 845  18 categories.put(name, category);
 846    }
 847  355 return category;
 848    }
 849   
 850   
 851    /**
 852    * Wrapper method to Category method
 853    *
 854    * @param key
 855    * @param value
 856    */
 857  1 public void setLongProperty(String key, long value) {
 858  1 getCategory().setLongProperty(key, value);
 859    }
 860   
 861   
 862    /**
 863    * Wrapper method to Category method
 864    *
 865    * @param key
 866    * @param value
 867    */
 868  1 public void setIntProperty(String key, int value) {
 869  1 getCategory().setIntProperty(key, value);
 870   
 871    }
 872   
 873   
 874    /**
 875    * Wrapper method to Category method
 876    *
 877    * @param key
 878    * @param value
 879    */
 880  1 public void setCharProperty(String key, char value) {
 881  1 getCategory().setCharProperty(key, value);
 882    }
 883   
 884    /**
 885    * Wrapper method to Category method
 886    *
 887    * @param key
 888    * @param value
 889    * @param category
 890    */
 891  1 public void setCharProperty(String key, char value, String category) {
 892  1 getCategory(category).setCharProperty(key, value);
 893    }
 894   
 895    /**
 896    * Wrapper method to Category method
 897    *
 898    * @param key
 899    * @param value
 900    */
 901  1 public void setDoubleProperty(String key, double value) {
 902  1 getCategory().setDoubleProperty(key, value);
 903   
 904    }
 905   
 906    /**
 907    * Wrapper method to Category method
 908    *
 909    * @param key
 910    * @param value
 911    * @param category
 912    */
 913  1 public void setLongProperty(String key, long value, String category) {
 914  1 getCategory(category).setLongProperty(key, value);
 915    }
 916   
 917    /**
 918    * Wrapper method to Category method
 919    *
 920    * @param key
 921    * @param value
 922    * @param category
 923    */
 924  1 public void setIntProperty(String key, int value, String category) {
 925  1 getCategory(category).setIntProperty(key, value);
 926    }
 927   
 928    /**
 929    * Wrapper method to Category method
 930    *
 931    * @param key
 932    * @param value
 933    * @param category
 934    */
 935  1 public void setDoubleProperty(String key, double value, String category) {
 936  1 getCategory(category).setDoubleProperty(key, value);
 937    }
 938   
 939  0 public boolean hasChanged() {
 940  0 return dirtyFlag;
 941    }
 942   
 943  2 public String[] getArray(String key) {
 944  2 return getArray(key,null);
 945    }
 946   
 947  4 public String[] getArray(String key, String[] defaultValue) {
 948  4 return getArray(key,defaultValue,mainCategory);
 949    }
 950   
 951  6 public String[] getArray(String key, String[] defaultValue, String category) {
 952  6 String value = getProperty(key,null,category);
 953  6 if ( value == null ) {
 954  3 return defaultValue;
 955    }
 956  3 Vector all = new Vector();
 957  3 StringTokenizer sto = new StringTokenizer(value,",");
 958  3 while ( sto.hasMoreElements() ) {
 959  12 String val = (String)sto.nextElement();
 960  12 val = vm.replaceVariables(val,configName);
 961  12 all.add(val);
 962    }
 963  3 return (String[])all.toArray(new String[0]);
 964    }
 965   
 966  3 public boolean isNew() {
 967  3 return created;
 968    }
 969   
 970  40 public void resetCreated() {
 971  40 created = false;
 972    }
 973   
 974  5 public String getEncoding() {
 975  5 return encoding;
 976    }
 977   
 978  480 protected void markDirty() {
 979  480 dirtyFlag = true;
 980    }
 981   
 982  0 public void setEncoding(String encoding) {
 983  0 this.encoding = encoding;
 984    }
 985   
 986  1 public boolean containsCategory(String categoryName) {
 987  1 if(categoryName == null) {
 988  0 return false;
 989    }
 990  1 Category category = (Category)categories.get(categoryName);
 991  1 if( category != null ) {
 992  0 return true;
 993    }
 994  1 return false;
 995    }
 996   
 997  30 public void addInclude(int type, String name) {
 998  30 IncludeEntry ie = new IncludeEntry(name,type);
 999  30 includes.add(ie);
 1000    }
 1001   
 1002  0 public Vector getIncludes() {
 1003  0 return includes;
 1004    }
 1005   
 1006  16 public void setBaseConfiguration(String name) {
 1007  16 baseConfigName = name;
 1008    }
 1009   
 1010    protected class MyCategoryListener implements CategoryListener {
 1011   
 1012    /* (non-Javadoc)
 1013    * @see org.jconfig.event.CategoryListener#categoryChanged(org.jconfig.event.CategoryChangedEvent)
 1014    */
 1015  600 public void categoryChanged(CategoryChangedEvent event) {
 1016  600 fireConfigurationChangedEvent((ConfigurationChangedEvent)event);
 1017   
 1018    }
 1019   
 1020    /* (non-Javadoc)
 1021    * @see org.jconfig.event.PropertyListener#propertyChanged(org.jconfig.event.PropertyChangedEvent)
 1022    */
 1023  0 public void propertyChanged(PropertyChangedEvent e) {
 1024    }
 1025   
 1026    }
 1027   
 1028    }