PropertiesTree

Note: This will likely be removed from jCIFS in the future. In hindsight a regular Properties object would have been more than adequate.

The jcifs.util.PropertiesTree class uses a simple but powerful mechanism for retrieving and storing properties. For simple configuration files, properties may simply be specified using their last label. For example, the property:

living_room.chair.wood = pine
may also be specified as:
wood = pine
But the property resolution mechanism used by PropertiesTree can be leveraged to create sophisticated hierarchical data stores. This method is also very convenient for handling dynamic data storage requirements. You can change, load, and store properties at runtime. This method is also extremely easy to use; the Config class provides static access to methods for converting values to int, boolean, InetAddress, etc. This can all be done in an un-intrusive way.

How PropertiesTree Retrieves Properties

It is vital to understand how the PropertiesTree class retrieves properties. Any application can use the PropertiesTree class, or more simply it's helper the Config class, to retrieve properties with Config.getXxx calls. For example, the following might be used to retrieve the property living_room.chair.wood:

String wood = Config.getProperty( "living_room.chair.wood" );
Here, the Config class simply provides convienent access to properties of a static PropertiesTree. The important work is being performed by the PropertiesTree itself. In the example above the living_room.chair.wood property is searched for in the following order:
living_room.chair.wood
living_room.wood
wood
The most specific key living_room.chair.wood is queried first. Then the less specific living_room.wood key is tried, and, if still not resolved, finally just wood. This has important implications when setting properties that will be described later.

The PropertiesTree File Format

The PropertiesTree class actually has two formats. There is the traditional format that looks like a standard Properties file:

#living room furniture
#Sat Mar 17 20:06:23 EST 2001
living_room.wood=oak
living_room.bookcase.height=42
living_room.chair.wood=pine
living_room.nightstand.height=26

and the tagged format:

#living room furniture
#Sat Mar 17 20:06:23 EST 2001
<living_room>
	wood = oak
	<nightstand>
		height = 26
	</nightstand>
	<chair>
		wood = pine
	</chair>
	<bookcase>
		height = 42
	</bookcase>
</living_room>

Both formats can be read and written at runtime without recourse(actually the formats may be mixed together within one file).

A Key Principle

Considering the mechanism used by PropertiesTree to retrieve properties and the file formats available, data may be organized such that properties overload parent properties of the same name. The effect is that defaults may be specified. In the above example, living_room.nightstand.wood and living_room.bookcase.wood would resolve to oak. The living_room.chair.wood property has been overloaded to specify pine.

Potential Problems

1 The above described principle can be the source of some confusion. For example, the Config class reads System properties after any PropertiesTree file properties are loaded. So if a property is specified in the commandline like:
$ java -Dwood=maple FurnitureStore
The idea here is that commandline specified properties are paramount and should overwrite any with the same name. So with the above command one might think that the default for all wood properties would now be maple. However this is not really what happends. The default wood does in fact become maple however the living_room.wood and living_room.chair.wood properties are more specific and therefore overload the property specified on the commandline. To override these properties it must be done specifically like:
$ java -Dliving_room.chair.wood=maple FurnitureStore

I'm not sure yet if this is a feature or a bug :~)

2 Another potential problem is that you cannot have an empty section. For example:


#living room furniture
#Sat Mar 17 20:06:23 EST 2001
<living_room>
	<nightstand>
	</nightstand>
	<chair>
		wood = pine
	</chair>
</living_room>

The living_room.nightstand section here is empty. This is not congruent with how PropertiesTree works. If this file is only to be read and not written then this is okay. However, whatever the case, such sections are simply ignored. To clarify on the problem, it is most evident when reasoning about the traditional representation of this property, such as perhaps:
living_room.nightstand
This is an invalid PropertiesTree property because it does not have an equals sign.