Simple XML-deserialization using SimpleXML

Whenever you need to read-in some parameters to your java-application you have to chose the right format. In order to make the right descision, it is necessary to know what kind of data to store. Things are clear when you have key-value-data like this:
parameter1 = 1
parameter2 = 10
parameter3 = 25

To store such key-value-data you should use java.util.Properties. You can easily load such a file in three lines of code:

//Load
File f = new File(fileName);
Properties properties = new Properties();
properties.load(new FileReader(f));
//Retrieve data
String parameterName = "parameter1";
String property1 = properties.getProperty(parameterName);

However a key-value-store is not appropriate when the data to store

  • has it’s own format or
  • when a key can have more than one property or
  • when you want to map objects to your properties.

If one point is true for your data then you should have a look at XML-format. However, some years ago, it was pain to handle XML in Java (and I don’t speak of object-mapping here…). Gladly, things have changed and there exists the wonderful SimpleXML Framework in the Java-universe that helps you with both XML-serialization (write POJOs to XML) and XML-deserialization (read XML and map them to POJOs).

Read a XML-file

This example refers to the Strategy-Pattern-post I made earlier.

Imagine you want to read-in some calculations via XML. When you have a look at the Strategy-Pattern-Example you will find out, that a calculation consists of:

  • an operator
  • and two variables

Let’s define the class Calculation which stores those properties.

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Root;

@Root(name="calculation")
public class Calculation {

	@Attribute
	private Operator operator;

	@Attribute
	private int valueA;

	@Attribute
	private int valueB;

}

The @Root-annotation says that this class needs can be serialized and mapped to an XML-element. The name-parameter defines the name of this element inside the XML-file. When no name is given, it defaults to the name of the class or field. The @Attribute-annotation specifies fields that are attribues (of an element) in terms of XML-specification.
Because one should have the possibility to calculate more than one calculation, we define the Calculations-class:

import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

@Root(name="config")
public class Calculations {

	@ElementList(name="calculations")
	private List calculations;

}

This mapping-class is also pretty much straightforward. The @ElementList-annotation allows you to load multiple data-sets from the XML-file. You can also use @ElementArray for arrays of data or @ElementMap for java.util.Map-equivalent. (Note that you have to define the length of the array in your XML-file (length=”123″) as an attribute of the element that holds the annotation when using @ElementArray.)

Now let’s take a look to the XML-file with some example-data:

<config>
	<calculations>
		<calculation operator="ADD" valueA="1" valueB="2"/>
	</calculations>
</config>

We found out that mapping the XML to a POJO was easy. What about loading that file? As you will see, loading files with SimpleXML is also no rocket-science:

Serializer serializer = new Persister();
File file = new File("calculations.xml");
Calculations calculations = serializer.read(Calculations.class, file);

That’s all! No complex file-handling, no new lines of code (except of adding some annotations).
Watch out for my next posts that will show you how to:

Advertisements

Simple XML-serialization using Simple XML

In my last post I introduced Simple XML as an easy to use XML-Object mapper. I showed how to map XML-files to POJOs.
In this post I’ll deal with the other way round: store POJOs to XML-files. To show you how this is done with Simple XML, I’ll utilize and extend the calculator-example again.
After we have loaded the calculations, we should calculate them and store the results to our new Result-classes:

@Root(name=&quot;result&quot;)
public class Result {

	@Attribute
	private final int result;

	public Result(int result) {
		super();
		this.result = result;
	}

}
@Root(name=&quot;config&quot;)
public class Results {

	@ElementList
	private List results;

	public Results(List results) {
		this.results = results;
	}

}

There are no new annotations, just POJOs. In order to store the results, I modified the existing Calculation(s)-classes:

@Root(name=&quot;calculation&quot;)
public class Calculation {

	@Attribute
	private Operator operator;

	@Attribute
	private int valueA;

	@Attribute
	private int valueB;

	public Result getResult(){
		return new Result(operator.calculate(valueA, valueB));
	}
}
@Root(name=&quot;config&quot;)
public class Calculations {

	@ElementList(name=&quot;calculations&quot;)
	private List calculations;

	public List calculateAll(){
		List results = new ArrayList();
		for(Calculation c:calculations){
			results.add(c.getResult());
		}
		return results;
	}

}

What steps do we have to perform now?

  • Read the calculations from calculations.xml
  • Calculate the results
  • Store the results into results.xml

Translated into code, this is what it looks like:

        public static void main(String[] args) throws Exception {
		write(calculate(read()));
	}

	public static Calculations read() throws Exception{
		Serializer serializer = new Persister();
		File file = new File(&quot;calculations.xml&quot;);
		return serializer.read(Calculations.class, file);
	}

	public static Results calculate(Calculations calculations){
		return new Results(calculations.calculateAll());
	}

	public static void write(Results results) throws Exception{
		Serializer serializer = new Persister();
		File file = new File(&quot;results.xml&quot;);
		serializer.write(results, file);
	}

As you can see, serializing to XML is also pretty easy and nothing compared to the common DOM or SAX-frameworks.
Finally, let’s take a look at the written xml-file:

&lt;config&gt;
  &lt;results class=&quot;java.util.ArrayList&quot;&gt;
    &lt;result result=&quot;3&quot;/&gt;
  &lt;/results&gt;
&lt;/config&gt;

This is almost what we expected, except of the new class-attribute in results-element. This attribute is automatically generated by Simple XML to determine the implementation of the java.util.List-interface that was used while the file was serialized (we created a new ArrayList instance in line 8 of Calculations-class). Whenever the file gets deserialized an instance of this class will be used to store the results (defaults to java.util.ArrayList).

JPA EntityManager.unwrap()-method

Last week I came in touch with the very useful

EntityManager.<T>unwrap(Class<T>)

-method from the javax.persistence-package. The method can be used to gain access of JPA-vendor-specific classes. At work, we are running Hibernate in “JPA-mode” which means we do only have access to methods that are provided by the EntityManager-interface. It was ok to us, until we wanted to get rid of those SELECT-statements that the EntityManager.merge()-method does before the UPDATE-statement is fired to the database. If we were running Hibernate in “Hibernate-mode” we wouldn’t have any problems at all: the EntityManager-equivalent Session-class offers a update()-method which fires only the UPDATE-Statement without any SELECTs. This is where the unwrap-method comes into play. Just fetch an EntityManager-instance via injection or create a new one on your own via EntityManagerFactory and place the following snippet into your code:

EntityManager em = ...
Session session = em.unwrap(Session.class);
//em.merge(myEntity);
session.update(myEntity);

Thanks to axtavt for his/her advice.