Taking TreeConf into use

So let's follow a concrete example, to see how to take TreeConf into use.

1. First, let's assume you prefer to create a package for your configuration classes, to keep things cleaner. Let's call that package com.yourcompany.example.cfg.

2. Then, you need to create a "master" configuration class, that extends the abstract class org.treeconf.ConfigRoot. Let's call that class com.yourcompany.example.cfg.Configuration. The class will look something like this:

package com.yourcompany.example.cfg;

import java.io.File;
import org.treeconf.*;
import org.treeconf.io.*;

public class Configuration extends ConfigRoot {
public final CN_Server server = new CN_Server();

private final ConfigReader configReader;
private final ConfigWriter configWriter;


public Configuration(final File file) {
configReader = new IniConfigReader(file);
configWriter = new IniConfigWriter(file);
}


public void load() throws Exception {
super.load(configReader);
}


public void save() throws Exception {
super.save(configWriter);
}
}

The public final fields in this class (e.g. "server"), belong to the configuration. Avoid using other public final fields that you don't wat to include in your configuration. As an extension to the previous sentence, do not declare any fields as public final that don't have a base type from the org.treeconf package. Otherwise the TreeConf framework will not work as expected.

The load() and save() methods are basically not doing anything, only delegating to the super class. They were added in order to enable the loading and saving of the configuration using the provided ConfigReader and ConfigWriter. You can use the ready made INI... configuration reader and writer (in the org.treeconf.io package), implement your own ConfigReader and ConfigWriter classes, or simply drop the support for loading and saving configurations by not implementing those 2 methods at all in your Configuration class.

As you can see in the previous code snapshot, the server field has the type CN_Server. The name itself is not important. What is important is that CN_Server extends from org.treeconf.ConfigNode class, as below.

3. Implement the CN_Server class, extending from org.treeconf.ConfigNode:

package com.yourcompany.example.cfg;

import org.treeconf.*;

public class CN_Server extends ConfigNode {
public final CN_Database database = new CN_Database();
}

4. Same as above, implement the CN_Database class, extending from org.treeconf.ConfigNode:

package com.yourcompany.example.cfg;

import org.treeconf.*;

public class CN_Database extends ConfigNode {
public final CN_Connection connection = new CN_Connection();
public final CN_Auth authentication = new CN_Auth();
}

5. Same as above, implement the CN_Connection and CN_Auth classes, extending from org.treeconf.ConfigNode:

package com.yourcompany.example.cfg;

import org.treeconf.*;

public class CN_Connection extends ConfigNode {
public final ConfigLeaf port = new ConfigLeaf();
public final ConfigLeaf hostname = new ConfigLeaf("localhost");
public final ConfigLeaf timeout = new ConfigLeaf();
}
package com.yourcompany.example.cfg;

import org.treeconf.*;

public class CN_Auth extends ConfigNode {
public final CN_User port = new CN_User();
public final ConfigLeaf algorithm = new ConfigLeaf();
}

Here the things get a little bit interesting.

First, you can see that the CN_Connection class has only org.treeconf.ConfigLeaf fields (no more branches). On the second hand, the CN_Auth class has a mix of leafs and non-leafs classes. And last but not least, it is possible to define the default values in the same place where creating them.

6. Same as above, implement the CN_User class extending from org.treeconf.ConfigNode. The code snippet is not shown here, since hopefully you know how to do that by now.

7. Now you should have all the configuration you need, and should be able to start using it. An example code that will use the fresh configuration is shown below:

package com.yourcompany.example;

import org.yourcompany.example.cfg.*;

public class Application {
final Configuration cfg = new Configuration(new File("file.cfg"));

public static void main(String[] args) throws Exception {
final Application app = new Application();
app.play();
}

private void play() throws Exception{
cfg.server.database.connection.port.setValue("0");
int nextPort = cfg.server.database.connection.port.toInt()+1;
...
System.out.println(cfg.server.database.connection.port);
System.out.println(cfg.server.database.connection.hostname);
...
cfg.save();
...
cfg.load();
}
}

Notice how you don't anymore use the TreeConf library in your application. What you use are the classes you have created yourself in your .cfg package. The only place where you need TreeConf is in the .cfg package.

Now picture in your head the same code written with (let's say) the Property class.

Hopefully, by now you can imagine how much simpler it is to write code using TreeConf as opposed to any existing flat configuration framework. And, the added effort of creating classes for each configuration item is not that big, because the classes are rather simple and stupid. The only thing a developer has to plan is the structure of the configuration tree, and the names of the nodes and leafs, in order to make his/her life easy.

Design downloaded from Free Templates - your source for free web templates