HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Reusable configuration reader for Java

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
javareusableforconfigurationreader

Problem

This is related to a question I posted on Stack Overflow. The consensus was to use JAXB, which is what I did.

One of the requirements was that it needed to work with legacy XML configuration files. The code needed to be able to start reading new configuration settings from XML files already used to configure pre-existing applications.

In trying to make the code reusable, I added the generic type parameter. However, this causes some yuckiness for the user, as it requires user to pass in the class type. (It shouldn't be necessary - but due to Java implementation of generics, there's no easy way around that).

I had to throw this together very quickly, so I would welcome any suggestions on improvement (or finding errors). I wasn't very skilled with JAXB, so perhaps there is a better solution I overlooked.

```
package com.eztech.config;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import com.eztech.xml.XmlUtils;

public class JAXBConfigurator {

private String filePath;
private Class clazz;
public JAXBConfigurator(Class toConfigure, String xmlFilePath) {
this.clazz = toConfigure;
this.filePath = xmlFilePath;
}

/**
* Parses Xml and reads configuration from Document element. Using this method
* assumes that the configuration xml starts at the top of the xml document.
* @return
* @throws Exception
*/
public T createAndConfigure() throws Exception {
return createAndConfigure(null);
}

/**
* Selects specified element from the parsed Xml document to use as the base
* for reading the configuration.
*
* @param tagName
* @return
*/
public T createAndConfigure(String tagName) throws Exception {
Document doc = XmlUtils.parse(filePath);
Node startNode;
if (tagName == null) {

Solution

Two things which are good to know about JAXB:

  • You can annotate private methods and fields, JAXB can call/modify them. It could help hiding internal data structure from clients.



  • Marshaller as well as Unmarshaller has event callbacks. They can help handing deprecated or compound fields.



Just two small notes about the code:

-
I would call the class JaxbConfigurator. Lowercase letters are easier to read. (Effective Java, Second Edition, Item 56: Adhere to generally accepted naming conventions)

-
It would be worth checking input parameters in the constructor to avoid latter mysterious NullPonterExceptions:

import static com.google.common.base.Preconditions.*;

...

public JaxbConfigurator(final Class toConfigure, final String xmlFilePath) {
    this.clazz = checkNotNull(toConfigure, "toConfigure cannot be null");
    this.filePath = checkNotNull(xmlFilePath, "xmlFilePath cannot be null");
}

Code Snippets

import static com.google.common.base.Preconditions.*;

...

public JaxbConfigurator(final Class<T> toConfigure, final String xmlFilePath) {
    this.clazz = checkNotNull(toConfigure, "toConfigure cannot be null");
    this.filePath = checkNotNull(xmlFilePath, "xmlFilePath cannot be null");
}

Context

StackExchange Code Review Q#6845, answer score: 4

Revisions (0)

No revisions yet.