/java-properties

A simple Java Properties parser that retains the exact format of the input file, including any comments

Primary LanguageJavaApache License 2.0Apache-2.0

Java Properties

Java Properties is a drop-in replacement of the ubiquitous java.util.Properties that everybody knows and loves (hates?).

It's an alternative implementation whose most important advantage over its standard Java sibling is that it fully supports comments in input and output.

Meaning that a properties table like this can not only be read, but also created, changed and be written back without losing any of the comments or formatting.

# Server configuration file

# Host name for remote server
remoteHost=myserver.example.com

# Port number
remotePort=8080

# Password hash algorithm to use
# (choose between MD5, SHA256 or SHA512)
passwordHash=SHA512

Setup

Add it to your build file with:

<dependency>
    <groupId>org.codejive</groupId>
    <artifactId>java-properties</artifactId>
    <version>0.0.6</version>
</dependency>

or

implementation 'org.codejive:java-properties:0.0.6'

And add this import to your code:

import org.codejive.properties.Properties;

Usage

After which you can do something like:

Properties p = new Properties();
p.setProperty("port", "8080");
p.setComment("port", "Port number to use for the server");

or just directly in a single line:

Properties p = new Properties();
p.setProperty("port", "8080", "Port number to use for the server");

And if you would write this out:

p.store(System.out)

you'll get:

# Port number to use for the server
port=8080

You can also set multi-line comments simply like this:

p.setComment("port", "Port number to", "use for the server");
p.setProperty("port", "8080", "Port number to", "use for the server");

which would both result in:

# Port number to
# use for the server
port=8080

Retrieving values is simple:

p.get("port"); // Returns "8080"
p.getProperty("port"); // Also returns "8080"
p.getComment("port") // Returns ["# Port number to", "# use for the server"]

Comments

Just like with the original Properties implementation, lines starting with a # or a ! are considered comments. Consecutive comments lines (even the ones that start with another comment character) and have no other lines in between (not even empty lines) are considered a single multi-line comment.

# A single comment line

! A multi-line comment
! spanning two lines

# This is also a multi-line comment
! but using different comment chars
two=Second value

Comments are considered either "free" or "attached", which you could see as either being just part of the file or attached to a property. For example:

# A header comment (free)

one=First value (that has no comment)

! Another free comment

# An attached comment
two=Second value

Any comments that directly precede a property, so no empty lines in between, are considered "attached" to that property, which also means the comment can be retrieved using props.getComment(key). On the other hand "free" comments are not attached to anything and there's no way to retrieve their values except when they are written out using store() or list().

This is also the reason that, when using store() with a comment, eg. props.store(out, "The first line"), it will actually insert an empty line after that comment, so it won't be considered attached to the first property.

Another thing to take into account is that when retrieving comment, by using getComment(key), you'll get a list of strings that will include the comment character. So, for example in the table above, running getComment("two") will return "# An attached comment".

In the same way, when setting comments, either by using setComment(key, comment) or setProperty(key, value, comment), the comment lines are expected to start with a comment character. Fortunately, it isn't an error to pass in lines that do not start with a comment character and the code will try its best to figure out what comment character to use and prepend that to the lines.

Compatibility

The org.codejive.Properties class is mostly a drop-in replacement of java.util.Properties with only a couple of differences:

  • the API now uses String everywhere instead of having Object in certain places
  • the class does not extend Hashtable, it's a completely outdated class that shouldn't be used anymore
  • the store() methods do not write a timestamp at the top of the output
  • the store() methods will write an empty line between any comments at the top of the output and the actual data

Development

To build the project simply run:

./mvnw spotless:apply clean install