Tuesday, March 1, 2011

Hello World with Java Architecture for XML Binding - JAXB

What is JAXB?

JAXB (Java Architecture for XML Binding) facilitates you to read or write to a XML file. since XML involves with Java everywhere, It will be very useful when working with Java. Here I'm assuming you are having some knowledge on XML.

What you should have

1. JAXB 

Download it and add its bin  folder to your classpath.

I have used eclipse as the IDE.

Let's start...

1. Create a project in eclipse called JAXB.
2. Create the library  directory and copy all the JAXB jars there. (lets call its "lib")
3. Add lib to the build path.
4. You should have a XML schema definition file, so let's create one. Let's name it as GSCProfile.xsd
5. Copy following content to the schema file.

GSCProfile.xsd


<schema xmlns="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.example.org/GSCProfile" 
xmlns:tns="http://www.example.org/GSCProfile" elementFormDefault="qualified">


<complexType name="GSC">
<sequence>
<element name="Name" type="string"></element>
<element name="Rating" type="int"></element>
</sequence>
</complexType>

<complexType name="Profile">
<sequence>
<element name="ProfileName" type="string"></element>
<element name="GSCElements" type="tns:GSC" maxOccurs="14" minOccurs="14">
</element>
</sequence>
</complexType>

<complexType name="GSCProfiles">
<sequence>
<element name="Profile" type="tns:Profile" maxOccurs="unbounded" minOccurs="1">
</element>
</sequence>
</complexType>

</schema>
There are 3 complex types called,
1.GSCProfiles
2.Profile
3.GSC
GSCProfiles is the root of all. here how is the relationship goes, 

GSCProfiles  ---< Profile ---< GSC

Once you have added the bin folder to the classpath,  go to the src folder of your project from command line and issue the following command,

xjc -d binding -p com.jaxb.gsc GSCProfiles.xsd


This will generates several classes in the above mentioned package (com.jaxb.gsc) one class for each complex type and an object factory and a package info class.

create another class called JAXBTest  in a diffrernt package, lets name that as com.jaxb.test

JAXBTest.java

Create this variable at class level. and variable to hold the xml file name.
private static Map<String, Map<String, String>> gscProfileMap = new HashMap<String, Map<String, String>>();
/**
* Output xml file name.
*/
private static File xmlFile = new File("xml/GSCProfile.xml");
 
1. create a method called saveGSCProfiles and add following code fragments there. this method will save the content for it.
public static void saveGSCProfiles() {
try {
Map<String, String> gscValueMap = new HashMap<String, String>();

// Adding GSC Elements

gscValueMap.put("Data Communications", "0");
gscValueMap.put("Distributed Data Processing", "0");
gscValueMap.put("Performance", "0");
gscValueMap.put("Heavily Used Configuration", "0");
gscValueMap.put("Transaction Rate", "0");
gscValueMap.put("Online Data Entry", "0");
gscValueMap.put("End User Efficiency", "0");
gscValueMap.put("Online Update", "0");
gscValueMap.put("Complex Processing", "0");
gscValueMap.put("Reusability", "0");
gscValueMap.put("Installation Ease", "0");
gscValueMap.put("Operational Ease", "0");
gscValueMap.put("Multiple Sites", "0");
gscValueMap.put("Facilitate Change", "0");
gscProfileMap.put("ProfileName", gscValueMap);
Set<String> pofileNames = gscProfileMap.keySet();

ObjectFactory factory = new ObjectFactory();

GSCProfiles gscProfiles = factory.createGSCProfiles();

for (String profileKey : pofileNames) {

Profile profile = factory.createProfile();

// Setting profile name.

profile.setProfileName(profileKey);
gscValueMap = gscProfileMap.get(profileKey);
Set<String> gscSet = gscValueMap.keySet();

for (String gscKey : gscSet) {

GSC gsc = factory.createGSC();
gsc.setName(gscKey);
gsc.setRating(Integer.parseInt(gscValueMap.get(gscKey)));
profile.getGSCElements().add(gsc);
}

gscProfiles.getProfile().add(profile);

}

JAXBContext jaxbContext = JAXBContext.newInstance("com.jaxb.gsc");

// Creating marshaller.
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

FileOutputStream outputStream = new FileOutputStream(xmlFile);

// Marshalling object in to the XML file.

marshaller.marshal(gscProfiles, outputStream);

} catch (JAXBException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
 
 
 2. Create another method to read from the XML file. let's name this as loadGSCProfiles

public static void loadGSCProfiles() {
try {

JAXBContext jaxbContext = JAXBContext.newInstance("com.jaxb.gsc");

// Create unmarshaller.
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 

GSCProfiles gscProfiles = (GSCProfiles) unmarshaller.unmarshal(xmlFile);

// Retrieving list of profiles.
List<Profile> profile = gscProfiles.getProfile();

for (Profile profile2 : profile) {

Map<String, String> gscValueMap = new HashMap<String, String>();

List<GSC> gsc = profile2.getGSCElements();

for (GSC gsc2 : gsc) {
gscValueMap.put(gsc2.getName(), gsc2.getRating() + "");
}

gscProfileMap.put(profile2.getProfileName(), gscValueMap);
}
} catch (JAXBException e) {
e.printStackTrace();
}

Create a directory inside your eclipse project and name it as xml, and create a xml file called  GSCProfile.xml

Write the main method in JAXBTest class and execute,

   
 public static void   main(String[] args)   {
             loadGSCProfiles();

             saveGSCProfiles();
    }

Open your GSCProfile.xml file and see... :)

Finally your eclipse project directory structure should like this,


2 comments:

  1. Hi Kushan,

    You should check out the JAXB tooling being done for Eclipse by the Dali team:

    - http://www.eclipse.org/webtools/releases/3.2.0/NewAndNoteworthy/jpa.php

    -Blaise

    ReplyDelete
  2. Hi Blaise,

    That's a great tool, I will definitely use it hereafter, Thank you very much for the info.. :)

    ReplyDelete