Coverage Report - org.ini4j.ConfigParser
 
Classes in this File Line Coverage Branch Coverage Complexity
ConfigParser
100%
95/95
97%
41/42
1.94
ConfigParser$1
N/A
N/A
1.94
ConfigParser$ConfigParserException
100%
2/2
N/A
1.94
ConfigParser$DuplicateSectionException
100%
3/3
N/A
1.94
ConfigParser$InterpolationException
100%
2/2
N/A
1.94
ConfigParser$InterpolationMissingOptionException
100%
3/3
N/A
1.94
ConfigParser$NoOptionException
100%
3/3
N/A
1.94
ConfigParser$NoSectionException
100%
3/3
N/A
1.94
ConfigParser$ParsingException
100%
4/4
N/A
1.94
ConfigParser$PyIni
98%
54/55
92%
24/26
1.94
 
 1  
 /*
 2  
  * Copyright 2005,2009 Ivan SZKIBA
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.ini4j;
 17  
 
 18  
 import org.ini4j.spi.IniHandler;
 19  
 import org.ini4j.spi.Warnings;
 20  
 
 21  
 import java.io.File;
 22  
 import java.io.FileReader;
 23  
 import java.io.FileWriter;
 24  
 import java.io.IOException;
 25  
 import java.io.InputStream;
 26  
 import java.io.OutputStream;
 27  
 import java.io.Reader;
 28  
 import java.io.Serializable;
 29  
 import java.io.Writer;
 30  
 
 31  
 import java.net.URL;
 32  
 
 33  
 import java.util.ArrayList;
 34  
 import java.util.Collections;
 35  
 import java.util.HashMap;
 36  
 import java.util.List;
 37  
 import java.util.Map;
 38  
 import java.util.regex.Matcher;
 39  
 import java.util.regex.Pattern;
 40  
 
 41  
 public class ConfigParser implements Serializable
 42  
 {
 43  
     private static final long serialVersionUID = 9118857036229164353L;
 44  
     private PyIni _ini;
 45  
 
 46  
     @SuppressWarnings(Warnings.UNCHECKED)
 47  
     public ConfigParser()
 48  
     {
 49  24
         this(Collections.EMPTY_MAP);
 50  24
     }
 51  
 
 52  
     public ConfigParser(Map<String, String> defaults)
 53  29
     {
 54  29
         _ini = new PyIni(defaults);
 55  29
     }
 56  
 
 57  
     public boolean getBoolean(String section, String option) throws NoSectionException, NoOptionException, InterpolationException
 58  
     {
 59  
         boolean ret;
 60  11
         String value = get(section, option);
 61  
 
 62  11
         if ("1".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value))
 63  
         {
 64  5
             ret = true;
 65  
         }
 66  6
         else if ("0".equalsIgnoreCase(value) || "no".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)
 67  
               || "off".equalsIgnoreCase(value))
 68  
         {
 69  5
             ret = false;
 70  
         }
 71  
         else
 72  
         {
 73  1
             throw new IllegalArgumentException(value);
 74  
         }
 75  
 
 76  10
         return ret;
 77  
     }
 78  
 
 79  
     public double getDouble(String section, String option) throws NoSectionException, NoOptionException, InterpolationException
 80  
     {
 81  1
         return Double.parseDouble(get(section, option));
 82  
     }
 83  
 
 84  
     public float getFloat(String section, String option) throws NoSectionException, NoOptionException, InterpolationException
 85  
     {
 86  1
         return Float.parseFloat(get(section, option));
 87  
     }
 88  
 
 89  
     public int getInt(String section, String option) throws NoSectionException, NoOptionException, InterpolationException
 90  
     {
 91  1
         return Integer.parseInt(get(section, option));
 92  
     }
 93  
 
 94  
     public long getLong(String section, String option) throws NoSectionException, NoOptionException, InterpolationException
 95  
     {
 96  1
         return Long.parseLong(get(section, option));
 97  
     }
 98  
 
 99  
     public void addSection(String section) throws DuplicateSectionException
 100  
     {
 101  20
         if (_ini.containsKey(section))
 102  
         {
 103  1
             throw new DuplicateSectionException(section);
 104  
         }
 105  19
         else if (PyIni.DEFAULT_SECTION_NAME.equalsIgnoreCase(section))
 106  
         {
 107  1
             throw new IllegalArgumentException(section);
 108  
         }
 109  
 
 110  18
         _ini.add(section);
 111  18
     }
 112  
 
 113  
     public Map<String, String> defaults()
 114  
     {
 115  4
         return _ini.getDefaults();
 116  
     }
 117  
 
 118  
     @SuppressWarnings(Warnings.UNCHECKED)
 119  
     public String get(String section, String option) throws NoSectionException, NoOptionException, InterpolationException
 120  
     {
 121  64
         return get(section, option, false, Collections.EMPTY_MAP);
 122  
     }
 123  
 
 124  
     @SuppressWarnings(Warnings.UNCHECKED)
 125  
     public String get(String section, String option, boolean raw) throws NoSectionException, NoOptionException, InterpolationException
 126  
     {
 127  1
         return get(section, option, raw, Collections.EMPTY_MAP);
 128  
     }
 129  
 
 130  
     public String get(String sectionName, String optionName, boolean raw, Map<String, String> variables) throws NoSectionException,
 131  
         NoOptionException, InterpolationException
 132  
     {
 133  66
         String value = requireOption(sectionName, optionName);
 134  
 
 135  64
         if (!raw && (value != null) && (value.indexOf(PyIni.SUBST_CHAR) >= 0))
 136  
         {
 137  17
             value = _ini.fetch(sectionName, optionName, variables);
 138  
         }
 139  
 
 140  60
         return value;
 141  
     }
 142  
 
 143  
     public boolean hasOption(String sectionName, String optionName)
 144  
     {
 145  5
         Ini.Section section = _ini.get(sectionName);
 146  
 
 147  5
         return (section != null) && section.containsKey(optionName);
 148  
     }
 149  
 
 150  
     public boolean hasSection(String sectionName)
 151  
     {
 152  3
         return _ini.containsKey(sectionName);
 153  
     }
 154  
 
 155  
     @SuppressWarnings(Warnings.UNCHECKED)
 156  
     public List<Map.Entry<String, String>> items(String sectionName) throws NoSectionException, InterpolationMissingOptionException
 157  
     {
 158  1
         return items(sectionName, false, Collections.EMPTY_MAP);
 159  
     }
 160  
 
 161  
     @SuppressWarnings(Warnings.UNCHECKED)
 162  
     public List<Map.Entry<String, String>> items(String sectionName, boolean raw) throws NoSectionException,
 163  
         InterpolationMissingOptionException
 164  
     {
 165  1
         return items(sectionName, raw, Collections.EMPTY_MAP);
 166  
     }
 167  
 
 168  
     public List<Map.Entry<String, String>> items(String sectionName, boolean raw, Map<String, String> variables) throws NoSectionException,
 169  
         InterpolationMissingOptionException
 170  
     {
 171  2
         Ini.Section section = requireSection(sectionName);
 172  
         Map<String, String> ret;
 173  
 
 174  2
         if (raw)
 175  
         {
 176  1
             ret = new HashMap<String, String>(section);
 177  
         }
 178  
         else
 179  
         {
 180  1
             ret = new HashMap<String, String>();
 181  1
             for (String key : section.keySet())
 182  
             {
 183  5
                 ret.put(key, _ini.fetch(section, key, variables));
 184  
             }
 185  
         }
 186  
 
 187  2
         return new ArrayList<Map.Entry<String, String>>(ret.entrySet());
 188  
     }
 189  
 
 190  
     public List<String> options(String sectionName) throws NoSectionException
 191  
     {
 192  3
         requireSection(sectionName);
 193  
 
 194  3
         return new ArrayList<String>(_ini.get(sectionName).keySet());
 195  
     }
 196  
 
 197  
     public void read(String... filenames) throws IOException, ParsingException
 198  
     {
 199  4
         for (String filename : filenames)
 200  
         {
 201  2
             read(new File(filename));
 202  
         }
 203  2
     }
 204  
 
 205  
     public void read(Reader reader) throws IOException, ParsingException
 206  
     {
 207  
         try
 208  
         {
 209  2
             _ini.load(reader);
 210  
         }
 211  1
         catch (InvalidFileFormatException x)
 212  
         {
 213  1
             throw new ParsingException(x);
 214  1
         }
 215  1
     }
 216  
 
 217  
     public void read(URL url) throws IOException, ParsingException
 218  
     {
 219  
         try
 220  
         {
 221  2
             _ini.load(url);
 222  
         }
 223  1
         catch (InvalidFileFormatException x)
 224  
         {
 225  1
             throw new ParsingException(x);
 226  1
         }
 227  1
     }
 228  
 
 229  
     public void read(File file) throws IOException, ParsingException
 230  
     {
 231  
         try
 232  
         {
 233  10
             _ini.load(new FileReader(file));
 234  
         }
 235  1
         catch (InvalidFileFormatException x)
 236  
         {
 237  1
             throw new ParsingException(x);
 238  9
         }
 239  9
     }
 240  
 
 241  
     public void read(InputStream stream) throws IOException, ParsingException
 242  
     {
 243  
         try
 244  
         {
 245  2
             _ini.load(stream);
 246  
         }
 247  1
         catch (InvalidFileFormatException x)
 248  
         {
 249  1
             throw new ParsingException(x);
 250  1
         }
 251  1
     }
 252  
 
 253  
     public boolean removeOption(String sectionName, String optionName) throws NoSectionException
 254  
     {
 255  1
         Ini.Section section = requireSection(sectionName);
 256  1
         boolean ret = section.containsKey(optionName);
 257  
 
 258  1
         section.remove(optionName);
 259  
 
 260  1
         return ret;
 261  
     }
 262  
 
 263  
     public boolean removeSection(String sectionName)
 264  
     {
 265  1
         boolean ret = _ini.containsKey(sectionName);
 266  
 
 267  1
         _ini.remove(sectionName);
 268  
 
 269  1
         return ret;
 270  
     }
 271  
 
 272  
     public List<String> sections()
 273  
     {
 274  11
         return new ArrayList<String>(_ini.keySet());
 275  
     }
 276  
 
 277  
     public void set(String sectionName, String optionName, Object value) throws NoSectionException
 278  
     {
 279  17
         Ini.Section section = requireSection(sectionName);
 280  
 
 281  16
         if (value == null)
 282  
         {
 283  1
             section.remove(optionName);
 284  
         }
 285  
         else
 286  
         {
 287  15
             section.put(optionName, value.toString());
 288  
         }
 289  16
     }
 290  
 
 291  
     public void write(Writer writer) throws IOException
 292  
     {
 293  1
         _ini.store(writer);
 294  1
     }
 295  
 
 296  
     public void write(OutputStream stream) throws IOException
 297  
     {
 298  1
         _ini.store(stream);
 299  1
     }
 300  
 
 301  
     public void write(File file) throws IOException
 302  
     {
 303  1
         _ini.store(new FileWriter(file));
 304  1
     }
 305  
 
 306  
     protected Ini getIni()
 307  
     {
 308  58
         return _ini;
 309  
     }
 310  
 
 311  
     private String requireOption(String sectionName, String optionName) throws NoSectionException, NoOptionException
 312  
     {
 313  66
         Ini.Section section = requireSection(sectionName);
 314  65
         String option = section.get(optionName);
 315  
 
 316  65
         if (option == null)
 317  
         {
 318  1
             throw new NoOptionException(optionName);
 319  
         }
 320  
 
 321  64
         return option;
 322  
     }
 323  
 
 324  
     private Ini.Section requireSection(String sectionName) throws NoSectionException
 325  
     {
 326  89
         Ini.Section section = _ini.get(sectionName);
 327  
 
 328  89
         if (section == null)
 329  
         {
 330  2
             throw new NoSectionException(sectionName);
 331  
         }
 332  
 
 333  87
         return section;
 334  
     }
 335  
 
 336  
     public static class ConfigParserException extends Exception
 337  
     {
 338  
 
 339  
         /** Use serialVersionUID for interoperability. */ private static final long serialVersionUID = -6845546313519392093L;
 340  
 
 341  
         public ConfigParserException(String message)
 342  
         {
 343  8
             super(message);
 344  8
         }
 345  
     }
 346  
 
 347  1
     public static final class DuplicateSectionException extends ConfigParserException
 348  
     {
 349  
 
 350  
         /** Use serialVersionUID for interoperability. */ private static final long serialVersionUID = -5244008445735700699L;
 351  
 
 352  
         private DuplicateSectionException(String message)
 353  
         {
 354  1
             super(message);
 355  1
         }
 356  
     }
 357  
 
 358  
     public static class InterpolationException extends ConfigParserException
 359  
     {
 360  
 
 361  
         /** Use serialVersionUID for interoperability. */ private static final long serialVersionUID = 8924443303158546939L;
 362  
 
 363  
         protected InterpolationException(String message)
 364  
         {
 365  4
             super(message);
 366  4
         }
 367  
     }
 368  
 
 369  4
     public static final class InterpolationMissingOptionException extends InterpolationException
 370  
     {
 371  
 
 372  
         /** Use serialVersionUID for interoperability. */ private static final long serialVersionUID = 2903136975820447879L;
 373  
 
 374  
         private InterpolationMissingOptionException(String message)
 375  
         {
 376  4
             super(message);
 377  4
         }
 378  
     }
 379  
 
 380  1
     public static final class NoOptionException extends ConfigParserException
 381  
     {
 382  
 
 383  
         /** Use serialVersionUID for interoperability. */ private static final long serialVersionUID = 8460082078809425858L;
 384  
 
 385  
         private NoOptionException(String message)
 386  
         {
 387  1
             super(message);
 388  1
         }
 389  
     }
 390  
 
 391  2
     public static final class NoSectionException extends ConfigParserException
 392  
     {
 393  
 
 394  
         /** Use serialVersionUID for interoperability. */ private static final long serialVersionUID = 8553627727493146118L;
 395  
 
 396  
         private NoSectionException(String message)
 397  
         {
 398  2
             super(message);
 399  2
         }
 400  
     }
 401  
 
 402  4
     public static final class ParsingException extends IOException
 403  
     {
 404  
 
 405  
         /** Use serialVersionUID for interoperability. */ private static final long serialVersionUID = -5395990242007205038L;
 406  
 
 407  
         private ParsingException(Throwable cause)
 408  
         {
 409  4
             super(cause.getMessage());
 410  4
             initCause(cause);
 411  4
         }
 412  
     }
 413  
 
 414  
     static class PyIni extends Ini
 415  
     {
 416  
         private static final char SUBST_CHAR = '%';
 417  1
         private static final Pattern EXPRESSION = Pattern.compile("(?<!\\\\)\\%\\(([^\\)]+)\\)");
 418  
         private static final int G_OPTION = 1;
 419  
         protected static final String DEFAULT_SECTION_NAME = "DEFAULT";
 420  
         private static final long serialVersionUID = -7152857626328996122L;
 421  
         private final Map<String, String> _defaults;
 422  
         private Ini.Section _defaultSection;
 423  
 
 424  
         public PyIni(Map<String, String> defaults)
 425  29
         {
 426  29
             _defaults = defaults;
 427  29
             Config cfg = getConfig().clone();
 428  
 
 429  29
             cfg.setEscape(false);
 430  29
             cfg.setMultiOption(false);
 431  29
             cfg.setMultiSection(false);
 432  29
             cfg.setLowerCaseOption(true);
 433  29
             cfg.setLowerCaseSection(true);
 434  29
             super.setConfig(cfg);
 435  29
         }
 436  
 
 437  
         @Override public void setConfig(Config value)
 438  
         {
 439  
             assert true;
 440  0
         }
 441  
 
 442  
         public Map<String, String> getDefaults()
 443  
         {
 444  4
             return _defaults;
 445  
         }
 446  
 
 447  
         @Override public Section add(String name)
 448  
         {
 449  
             Section section;
 450  
 
 451  90
             if (DEFAULT_SECTION_NAME.equalsIgnoreCase(name))
 452  
             {
 453  13
                 if (_defaultSection == null)
 454  
                 {
 455  9
                     _defaultSection = newSection(name);
 456  
                 }
 457  
 
 458  13
                 section = _defaultSection;
 459  
             }
 460  
             else
 461  
             {
 462  77
                 section = super.add(name);
 463  
             }
 464  
 
 465  90
             return section;
 466  
         }
 467  
 
 468  
         public String fetch(String sectionName, String optionName, Map<String, String> variables) throws InterpolationMissingOptionException
 469  
         {
 470  17
             return fetch(get(sectionName), optionName, variables);
 471  
         }
 472  
 
 473  
         protected Ini.Section getDefaultSection()
 474  
         {
 475  8
             return _defaultSection;
 476  
         }
 477  
 
 478  
         protected String fetch(Ini.Section section, String optionName, Map<String, String> variables)
 479  
             throws InterpolationMissingOptionException
 480  
         {
 481  22
             String value = section.get(optionName);
 482  
 
 483  22
             if ((value != null) && (value.indexOf(SUBST_CHAR) >= 0))
 484  
             {
 485  19
                 StringBuilder buffer = new StringBuilder(value);
 486  
 
 487  19
                 resolve(buffer, section, variables);
 488  15
                 value = buffer.toString();
 489  
             }
 490  
 
 491  18
             return value;
 492  
         }
 493  
 
 494  
         protected void resolve(StringBuilder buffer, Ini.Section owner, Map<String, String> vars) throws InterpolationMissingOptionException
 495  
         {
 496  19
             Matcher m = EXPRESSION.matcher(buffer);
 497  
 
 498  34
             while (m.find())
 499  
             {
 500  19
                 String optionName = m.group(G_OPTION);
 501  19
                 String value = owner.get(optionName);
 502  
 
 503  19
                 if (value == null)
 504  
                 {
 505  15
                     value = vars.get(optionName);
 506  
                 }
 507  
 
 508  19
                 if (value == null)
 509  
                 {
 510  14
                     value = _defaults.get(optionName);
 511  
                 }
 512  
 
 513  19
                 if ((value == null) && (_defaultSection != null))
 514  
                 {
 515  10
                     value = _defaultSection.get(optionName);
 516  
                 }
 517  
 
 518  19
                 if (value == null)
 519  
                 {
 520  4
                     throw new InterpolationMissingOptionException(optionName);
 521  
                 }
 522  
 
 523  15
                 buffer.replace(m.start(), m.end(), value);
 524  15
                 m.reset(buffer);
 525  15
             }
 526  15
         }
 527  
 
 528  
         @Override protected void store(IniHandler formatter)
 529  
         {
 530  3
             formatter.startIni();
 531  3
             if (_defaultSection != null)
 532  
             {
 533  3
                 store(formatter, _defaultSection);
 534  
             }
 535  
 
 536  3
             for (Ini.Section s : values())
 537  
             {
 538  21
                 store(formatter, s);
 539  
             }
 540  
 
 541  3
             formatter.endIni();
 542  3
         }
 543  
 
 544  
         @Override protected void store(IniHandler formatter, Section section)
 545  
         {
 546  24
             formatter.startSection(section.getName());
 547  24
             for (String name : section.keySet())
 548  
             {
 549  120
                 formatter.handleOption(name, section.get(name));
 550  
             }
 551  
 
 552  24
             formatter.endSection();
 553  24
         }
 554  
     }
 555  
 }