Getting Started

You are viewing an old version (v. 6) of this page.
The latest version is v. 25, last edited on Feb 18, 2010 (view differences | )
<< View previous version | view page history | view next version >>

We demonstrate usage of this tool with a simple tutorial. Assume a Task class below with a prioritized field indicating whether it is a prioritized task:

package example;

public class Task {
        public boolean prioritized;
}

With XStream, we can serialize object of this class to XML like below:

import com.thoughtworks.xstream.XStream;

Task task = new Task();
task.prioritized = true;
String xml = new XStream().toXML(task);
saveXmlToFileOrDatabase(xml);

The resulting XML will be:

<example.Task>
  <prioritized>true</prioritized>
</example.Task>

And you can deserialize the XML to get back task object:

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

String xml = readXmlFromFileOrDatabase();
Task task = (Task)(new XStream(new DomDriver()).fromXML(xml));

Everything is fine. Now we find a prioritized flag is not enough, so we enhance the Task class to use a numeric priority field ranging from 1 to 10:

package example;

public class Task {
        public int priority;
}

However deserialization of previously saved xml is no longer possible since the new Task class is not compatible with previous version. XMT comes to rescue: it introduces class VersionedDocument to version serialized XMLs and handles the migration. With XMT, serialization of task object can be written as:

package example;
import com.pmease.commons.xmt.VersionedDocument;

Task task = new Task();
task.prioritized = true;
String xml = VersionedDocument.fromBean(task).toXML();
saveXmlToFileOrDatabase(xml);

The resulting XML will be:

<?xml version="1.0" encoding="UTF-8"?>

<example.Task version="0">
  <prioritized>true</prioritized>
</example.Task>

Compared with the XML generated by directly using XStream, an additional attribute version is added to the root element indicating version of associated class. The value is set to 0 unless there are migration methods defined in the class as we will introduce below.

When Task class is evolved to use numeric priority field, we add a migrate method like below:

package com.pmease.commons.xmt.bean;

import java.util.List;
import org.dom4j.Element;
import com.pmease.commons.xmt.VersionedDocument;

public class Task {
	private int priority;

	public int getPriority() {
		return priority;
	}

	public void setPriority(int priority) {
		this.priority = priority;
	}
	
	@SuppressWarnings("unused")
	private void migrate1(VersionedDocument dom, List<String> versions) {
		Element element = dom.getRootElement().element("prioritized");
		element.setName("priority");
		if (element.getText().equals("true"))
			element.setText("10");
		else
			element.setText("1");
	}
}

Here method migrate1 migrates the XML from version 0 to 1. The XML to be migrated is passed as a VersionedDocument object which implements dom4j Document interface and you may use dom4j to migrate it to be compatible with current version of the class. The versions parameter is used to handle the migration if class inheritance hierarchy is changed and will be introduced in [class hierarchy migration chapter].
In this migration method, we read back the "prioritized" element of version 0, rename it as "priority", and then set the value as "10" if the task is originally a prioritized task; otherwise, set the value as "0".

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.