I was looking for a simple, straightforward tutorial on how to use JAXB (Java Architecture for XML Binding) with Eclipse, as myself am kind of newbie to Java, although worked some time ago with this programming language. So, here it is some example that I hope will help some other programmer when trying to serialize objects to XML:
Step 1: Install JAXB plugin for Eclipse, named XJC
For this, download the latest version of the JAXB XJC generator plugin; copy the content of the archive into the %Eclipse_Folder%/plugins folder. Restart Eclipse if required.
Step 2: Create a new Eclipse project as shown bellow (I called it DrawGraph, as it handles nodes and edges of a graph):
Step 3: Add a new folder under src directory, called xsd; under this folder, create a new XML Schema file, using Eclipse wizard. The content of the file is displayed below:
As you can see, the BaseGraph.xsd file defines restrictions on how to format an XML file that will represent a graph object containing vertices/nodes and edges/lines; the graph will contain a list of nodes and one of lines, and also a start and end node, if necessary.
Step 4: Run XJC plugin in order to generate Java classes associated with the business objects described by the XML schema. This is done by using the context menu of the BaseGraph.xsd file:
After setting the Package name (drawgraph.objects in my case) and the Output directory (for my project I used D:\Work\Java\Projects\DrawGraph\src), if the xsd is well defined, the plugin will generate six classes under drawgraph.objects package:
- BaseGraph.java – the graph object containing the list of lines and nodes
- Line.java – the line/edge object
- LineList.java – an object containing a list with lines/edges
- Node.java – the node/vertex object
- NodeList.java – an object containing a list with nodes/vertices
- ObjectFactory.java – class for creating the upper-mentioned class instances
If you’d like to run the XJC from the command line, you can try something like:
xjc -p outputFolder BaseGraph.xsd
Step 5: Use JAXBContext, Marshaller and Unmarshaller classes from javax.xml.bind.* package in order to serialize/deserialize to/from XML file. In my case, I extended BaseGraph.java class by implementing Graph.java, which contains the marshalling and unmarshalling methods (and some other extra methods, for handling graph entities), as presented below:
package drawgraph.objects;
import java.io.*;
import java.util.List;
import javax.xml.bind.*;
public class Graph extends BaseGraph
{
protected ObjectFactory objectFactory = new objectFactory();
public Graph() {
this.setNodeList(objectFactory.createNodeList());
this.setLineList(objectFactory.createLineList());
}
public Graph(BaseGraph baseGraph) {
this.setNodeList(baseGraph.getNodeList());
this.setLineList(baseGraph.getLineList());
}
public List getLines() {
return this.getLineList().getLineList();
}
public List getNodes() {
return this.getNodeList().getNodeList();
}
public void addNode(int x, int y) {
Node node = objectFactory.createNode();
node.setX(x);
node.setY(y);
node.setIndex(this.getNodes().size());
this.getNodes().add(node);
}
public void addLine(int start, int end) {
Line line = objectFactory.createLine();
line.setStartNode(start);
line.setEndNode(end);
this.getLines().add(line);
}
public void marshalToFile(String fileName) {
try {
JAXBContext jc = JAXBContext.newInstance(“drawgraph.objects”);
Marshaller m = jc.createMarshaller();
m.marshal( this, new FileOutputStream(fileName) );
} catch (Exception e) {
e.printStackTrace();
}
}
public static Graph unmarshalFromFile(String fileName) {
try {
JAXBContext jc = JAXBContext.newInstance(“drawgraph.objects”);
Unmarshaller um = jc.createUnmarshaller();
BaseGraph baseGraph = (BaseGraph) um.unmarshal(new File(fileName));
return new Graph(baseGraph);
} catch (Exception e) {
return new Graph();
}
}
}
Step 6:Test the marshalling and unmarshalling, using JUnit capabilities (or just test 🙂 ):
package drawgraph.objects;
import org.junit.*;
import static org.junit.Assert.*;
public class GraphTest {
Graph graph;
@Test
public void test_graph() {
createGraph();
graph.marshalToFile(“graphOutput.xml”);
Graph secondGraph = Graph.unmarshalFromFile(“graphOutput.xml”);
assertTrue(secondGraph.getLines().size() == 2);
assertTrue(secondGraph.getNodes().size() == 3);
}
private void createGraph() {
graph = new Graph();
graph.addNode(50, 50);
graph.addNode(100, 100);
graph.addNode(50, 100);
graph.addLine(1, 2);
graph.addLine(2, 3);
}
}