Package org.apache.commons.configuration2

# Class INIConfiguration

java.lang.Object
org.apache.commons.configuration2.event.BaseEventSource
org.apache.commons.configuration2.AbstractConfiguration
org.apache.commons.configuration2.AbstractHierarchicalConfiguration<ImmutableNode>
org.apache.commons.configuration2.BaseHierarchicalConfiguration
org.apache.commons.configuration2.INIConfiguration

All Implemented Interfaces:
  `Cloneable`, `Configuration`, `EventSource`, `FileBasedConfiguration`, `HierarchicalConfiguration<ImmutableNode>`, `ImmutableConfiguration`, `ImmutableHierarchicalConfiguration`, `FileBased`, `SynchronizerSupport`, `InMemoryNodeModelSupport`, `NodeKeyResolver<ImmutableNode>`, `NodeModelSupport<ImmutableNode>`

public class INIConfiguration extends BaseHierarchicalConfiguration implements FileBasedConfiguration

A specialized hierarchical configuration implementation for parsing ini files.

An initialization or ini file is a configuration file typically found on Microsoft's Windows operating system and contains data for Windows based applications.

Although popularized by Windows, ini files can be used on any system or platform due to the fact that they are merely text files that can easily be parsed and modified by both humans and computers.

A typical ini file could look something like:

     [section1]
     ; this is a comment!
     var1 = foo
     var2 = bar

     [section2]
     var1 = doo

The format of ini files is fairly straight forward and is composed of three components:

- Sections: Ini files are split into sections, each section starting with a section declaration. A section declaration starts with a '[' and ends with a ']'. Sections occur on one line only.
- Parameters: Items in a section are known as parameters. Parameters have a typical `key = value` format.
- Comments: Lines starting with a ';' are assumed to be comments.

There are various implementations of the ini file format by various vendors which has caused a number of differences to appear. As far as possible this configuration tries to be lenient and support most of the differences.

Some of the differences supported are as follows:

- Comments: The '#' character is also accepted as a comment signifier.
- Key value separator: The ':' character is also accepted in place of '=' to separate keys and values in parameters, for example `var1 : foo`.
- Duplicate sections: Typically duplicate sections are not allowed, this configuration does however support this feature. In the event of a duplicate section, the two section's values are merged so that there is only a single section. Note: This also affects the internal data of the configuration. If it is saved, only a single section is written!
- Duplicate parameters: Typically duplicate parameters are only allowed if they are in two different sections, thus they are local to sections; this configuration simply merges duplicates; if a section has a duplicate parameter the values are then added to the key as a list.

Global parameters are also allowed; any parameters declared before a section is declared are added to a global section. It is important to note that this global section does not have a name.

In all instances, a parameter's key is prepended with its section name and a '.' (period). Thus a parameter named "var1" in "section1" will have the key `section1.var1` in this configuration. (This is the default behavior. Because this is a hierarchical configuration you can change this by setting a different `ExpressionEngine`.)

Implementation Details: Consider the following ini file:

      default = ok

      [section1]
      var1 = foo
      var2 = doodle

      [section2]
      ; a comment
      var1 = baz
      var2 = shoodle
      bad =
      = worse

      [section3]
      # another comment
      var1 : foo
      var2 : bar
      var5 : test1

      [section3]
      var3 = foo
      var4 = bar
      var5 = test2

      [sectionSeparators]
      passwd : abc=def
      a:b = "value"

      []
      var = emptySection

This ini file will be parsed without error. Note:

- The parameter named "default" is added to the global section, it's value is accessed simply using `getProperty("default")`.
- Section 1's parameters can be accessed using `getProperty("section1.var1")`.
- The parameter named "bad" simply adds the parameter with an empty value.
- The empty key with value "= worse" is added using a key consisting of a single space character. This key is still added to section 2 and the value can be accessed using `getProperty("section2. ")`, notice the period '.' and the space following the section name.
- Section three uses both '=' and ':' to separate keys and values.
- Section 3 has a duplicate key named "var5". The value for this key is [test1, test2], and is represented as a List.
- The section called sectionSeparators demonstrates how the configuration deals with multiple occurrences of separator characters. Per default the first separator character in a line is detected and used to split the key from the value. Therefore the first property definition in this section has the key `passwd` and the value `abc=def`. This default behavior can be changed by using quotes. If there is a separator character before the first quote character (ignoring whitespace), this character is used as separator. Thus the second property definition in the section has the key `a:b` and the value `value`.
- The empty section is added using a key consisting of a single space character. The parameters can be accessed using `getProperty(" .var")`

Internally, this configuration maps the content of the represented ini file to its node structure in the following way:

- Sections are represented by direct child nodes of the root node.
- For the content of a section, corresponding nodes are created as children of the section node.

This explains how the keys for the properties can be constructed. You can also use other methods of `HierarchicalConfiguration` for querying or manipulating the hierarchy of configuration nodes, for instance the `configurationAt()` method for obtaining the data of a specific section. However, be careful that the storage scheme described above is not violated (for example by adding multiple levels of nodes or inserting duplicate section nodes). Otherwise, the special methods for ini configurations may not work correctly!

The set of sections in this configuration can be retrieved using the `getSections()` method. For obtaining a `SubnodeConfiguration` with the content of a specific section the `getSection()` method can be used.

Like other `Configuration` implementations, this class uses a `Synchronizer` object to control concurrent access. By choosing a suitable implementation of the `Synchronizer` interface, an instance can be made thread-safe or not. Note that access to most of the properties typically set through a builder is not protected by the `Synchronizer`. The intended usage is that these properties are set once at construction time through the builder and after that remain constant. If you wish to change such properties during life time of an instance, you have to use the `lock()` and `unlock()` methods manually to ensure that other threads see your changes.

As this class extends `AbstractConfiguration`, all basic features like variable interpolation, list handling, or data type conversions are available as well. This is described in the chapter Basic features and AbstractConfiguration of the user's guide.

Note that this configuration does not support properties with null values. Such properties are considered to be section nodes.

Since:
  1.6

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `INIConfiguration.Builder`
  Builds instances of INIConfiguration.

  ## Nested classes/interfaces inherited from class org.apache.commons.configuration2.BaseHierarchicalConfiguration

  `BaseHierarchicalConfiguration.BuilderVisitor`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected static final String`
  `COMMENT_CHARS`
  The default characters that signal the start of a comment line.
  `protected static final String`
  `SEPARATOR_CHARS`
  The default characters used to separate keys from values.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `INIConfiguration()`
  Create a new empty INI Configuration.
  `INIConfiguration(HierarchicalConfiguration<ImmutableNode> c)`
  Creates a new instance of `INIConfiguration` with the content of the specified `HierarchicalConfiguration`.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static INIConfiguration.Builder`
  `builder()`
  Creates a new builder.
  `String`
  `getCommentLeadingCharsUsedInInput()`
  Gets comment leading separator used in INI reading. see `setCommentLeadingCharsUsedInInput` for further explanation
  `SubnodeConfiguration`
  `getSection(String name)`
  Gets a configuration with the content of the specified section.
  `Set<String>`
  `getSections()`
  Gets a set containing the sections in this INI configuration.
  `String`
  `getSeparatorUsedInInput()`
  Gets separator used in INI reading. see `setSeparatorUsedInInput` for further explanation
  `String`
  `getSeparatorUsedInOutput()`
  Gets separator used in INI output. see `setSeparatorUsedInOutput` for further explanation
  `protected boolean`
  `isCommentLine(String line)`
  Determine if the given line is a comment line.
  `protected boolean`
  `isSectionLine(String line)`
  Determine if the given line is a section.
  `void`
  `read(Reader in)`
  Load the configuration from the given reader.
  `void`
  `setCommentLeadingCharsUsedInInput(String separator)`
  Allows setting the leading comment separator which is used in reading an INI file
  `void`
  `setSeparatorUsedInInput(String separator)`
  Allows setting the key and value separator which is used in reading an INI file
  `void`
  `setSeparatorUsedInOutput(String separator)`
  Allows setting the key and value separator which is used for the creation of the resulting INI output
  `void`
  `write(Writer writer)`
  Save the configuration to the specified writer.

  ### Methods inherited from class org.apache.commons.configuration2.BaseHierarchicalConfiguration

  `childConfigurationsAt, childConfigurationsAt, cloneNodeModel, configurationAt, configurationAt, configurationsAt, configurationsAt, createSubConfigurationForTrackedNode, getNodeModel, getSubConfigurationNodeSelector, getSubConfigurationParentModel, immutableChildConfigurationsAt, immutableConfigurationAt, immutableConfigurationAt, immutableConfigurationsAt, initSubConfigurationForThisParent, interpolatedConfiguration, subnodeConfigurationChanged, subset`

  ### Methods inherited from class org.apache.commons.configuration2.AbstractHierarchicalConfiguration

  `addNodes, addNodesInternal, addPropertyDirect, addPropertyInternal, clearInternal, clearPropertyDirect, clearTree, clearTreeInternal, clone, containsKeyInternal, containsValueInternal, fetchNodeList, getExpressionEngine, getKeysInternal, getKeysInternal, getKeysInternal, getMaxIndex, getMaxIndexInternal, getModel, getPropertyInternal, getRootElementName, getRootElementNameInternal, isEmptyInternal, nodeDefined, nodeKey, resolveAddKey, resolveKey, resolveNodeKey, resolveUpdateKey, setExpressionEngine, setPropertyInternal, sizeInternal, toString`

  ### Methods inherited from class org.apache.commons.configuration2.AbstractConfiguration

  `addErrorLogListener, addProperty, append, beginRead, beginWrite, clear, clearProperty, cloneInterpolator, contains, containsKey, containsValue, copy, endRead, endWrite, get, get, getArray, getArray, getBigDecimal, getBigDecimal, getBigInteger, getBigInteger, getBoolean, getBoolean, getBoolean, getByte, getByte, getByte, getCollection, getCollection, getConfigurationDecoder, getConversionHandler, getDouble, getDouble, getDouble, getDuration, getDuration, getEncodedString, getEncodedString, getFloat, getFloat, getFloat, getInt, getInt, getInteger, getInterpolator, getKeys, getKeys, getKeys, getList, getList, getList, getList, getListDelimiterHandler, getLogger, getLong, getLong, getLong, getProperties, getProperties, getProperty, getShort, getShort, getShort, getString, getString, getStringArray, getSynchronizer, immutableSubset, initLogger, installInterpolator, interpolate, interpolate, isEmpty, isScalarValue, isThrowExceptionOnMissing, lock, setConfigurationDecoder, setConversionHandler, setDefaultLookups, setInterpolator, setListDelimiterHandler, setLogger, setParentInterpolator, setPrefixLookups, setProperty, setSynchronizer, setThrowExceptionOnMissing, size, unlock`

  ### Methods inherited from class org.apache.commons.configuration2.event.BaseEventSource

  `addEventListener, clearErrorListeners, clearEventListeners, copyEventListeners, createErrorEvent, createEvent, fireError, fireEvent, getEventListenerRegistrations, getEventListeners, isDetailEvents, removeEventListener, setDetailEvents`

  ### Methods inherited from class java.lang.Object

  `equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface org.apache.commons.configuration2.Configuration

  `addProperty, clear, clearProperty, getInterpolator, installInterpolator, setInterpolator, setProperty, subset`

  ### Methods inherited from interface org.apache.commons.configuration2.ImmutableConfiguration

  `containsKey, containsValue, get, get, getArray, getArray, getBigDecimal, getBigDecimal, getBigInteger, getBigInteger, getBoolean, getBoolean, getBoolean, getByte, getByte, getByte, getCollection, getCollection, getDouble, getDouble, getDouble, getDuration, getDuration, getEncodedString, getEncodedString, getEnum, getEnum, getFloat, getFloat, getFloat, getInt, getInt, getInteger, getKeys, getKeys, getKeys, getList, getList, getList, getList, getLong, getLong, getLong, getProperties, getProperty, getShort, getShort, getShort, getString, getString, getStringArray, immutableSubset, isEmpty, size`

  ### Methods inherited from interface org.apache.commons.configuration2.sync.SynchronizerSupport

  `getSynchronizer, lock, setSynchronizer, unlock`

- ## Field Details

  - ### COMMENT_CHARS

    protected static final String COMMENT_CHARS
    The default characters that signal the start of a comment line.
    See Also:
      - Constant Field Values

  - ### SEPARATOR_CHARS

    protected static final String SEPARATOR_CHARS
    The default characters used to separate keys from values.
    See Also:
      - Constant Field Values

- ## Constructor Details

  - ### INIConfiguration

    public INIConfiguration()
    Create a new empty INI Configuration.

  - ### INIConfiguration

    public INIConfiguration(HierarchicalConfiguration<ImmutableNode> c)
    Creates a new instance of `INIConfiguration` with the content of the specified `HierarchicalConfiguration`.
    Parameters:
      `c` - the configuration to be copied
    Since:
      2.0

- ## Method Details

  - ### builder

    public static INIConfiguration.Builder builder()
    Creates a new builder.
    Returns:
      a new builder.
    Since:
      2.9.0

  - ### getCommentLeadingCharsUsedInInput

    public String getCommentLeadingCharsUsedInInput()
    Gets comment leading separator used in INI reading. see `setCommentLeadingCharsUsedInInput` for further explanation
    Returns:
      the current separator for reading the INI input
    Since:
      2.5

  - ### getSection

    public SubnodeConfiguration getSection(String name)
    Gets a configuration with the content of the specified section. This provides an easy way of working with a single section only. The way this configuration is structured internally, this method is very similar to calling `HierarchicalConfiguration.configurationAt(String)` with the name of the section in question. There are the following differences however:
    - This method never throws an exception. If the section does not exist, it is created now. The configuration returned in this case is empty.
    - If section is contained multiple times in the configuration, the configuration returned by this method is initialized with the first occurrence of the section. (This can only happen if `addProperty()` has been used in a way that does not conform to the storage scheme used by `INIConfiguration`. If used correctly, there will not be duplicate sections.)
    - There is special support for the global section: Passing in null as section name returns a configuration with the content of the global section (which may also be empty).
    Parameters:
      `name` - the name of the section in question; null represents the global section
    Returns:
      a configuration containing only the properties of the specified section

  - ### getSections

    public Set<String> getSections()
    Gets a set containing the sections in this INI configuration. Note that changes to this set do not affect the configuration.
    Returns:
      a set containing the sections.

  - ### getSeparatorUsedInInput

    public String getSeparatorUsedInInput()
    Gets separator used in INI reading. see `setSeparatorUsedInInput` for further explanation
    Returns:
      the current separator for reading the INI input
    Since:
      2.5

  - ### getSeparatorUsedInOutput

    public String getSeparatorUsedInOutput()
    Gets separator used in INI output. see `setSeparatorUsedInOutput` for further explanation
    Returns:
      the current separator for writing the INI output
    Since:
      2.2

  - ### isCommentLine

    protected boolean isCommentLine(String line)
    Determine if the given line is a comment line.
    Parameters:
      `line` - The line to check.
    Returns:
      true if the line is empty or starts with one of the comment characters

  - ### isSectionLine

    protected boolean isSectionLine(String line)
    Determine if the given line is a section.
    Parameters:
      `line` - The line to check.
    Returns:
      true if the line contains a section

  - ### read

    public void read(Reader in) throws ConfigurationException, IOException
    Load the configuration from the given reader. Note that the `clear()` method is not called so the configuration read in will be merged with the current configuration.
    Specified by:
      `read` in interface `FileBased`
    Parameters:
      `in` - the reader to read the configuration from.
    Throws:
      `ConfigurationException` - If an error occurs while reading the configuration
      `IOException` - if an I/O error occurs.

  - ### setCommentLeadingCharsUsedInInput

    public void setCommentLeadingCharsUsedInInput(String separator)
    Allows setting the leading comment separator which is used in reading an INI file
    Parameters:
      `separator` - String of the new separator for INI reading
    Since:
      2.5

  - ### setSeparatorUsedInInput

    public void setSeparatorUsedInInput(String separator)
    Allows setting the key and value separator which is used in reading an INI file
    Parameters:
      `separator` - String of the new separator for INI reading
    Since:
      2.5

  - ### setSeparatorUsedInOutput

    public void setSeparatorUsedInOutput(String separator)
    Allows setting the key and value separator which is used for the creation of the resulting INI output
    Parameters:
      `separator` - String of the new separator for INI output
    Since:
      2.2

  - ### write

    public void write(Writer writer) throws ConfigurationException, IOException
    Save the configuration to the specified writer.
    Specified by:
      `write` in interface `FileBased`
    Parameters:
      `writer` - The writer to save the configuration to.
    Throws:
      `ConfigurationException` - If an error occurs while writing the configuration
      `IOException` - if an I/O error occurs.