April 20, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Introducing Betwixt, Page 4

  • September 30, 2005
  • By Vikram Goyal
  • Send Email »
  • More Articles »

Working with multiple values

To show how Betwixt works with collections and maps, consider listing 9. It shows the code for converting a Meal object to XML and vice versa. Note that the Meal class contains the ingredients as a HashMap.

Listing 9. Converting a Meal object to XML and back

package com.manning.commons.chapter05;
import java.io.File;
import java.io.FileWriter;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
public class MultipleValues {
public static void main(String args[]) throws Exception {
FileWriter fWriter = new FileWriter("output.xml");
BeanWriter bWriter = new BeanWriter(fWriter);
Meal meal = new Meal(1, 1, "Potato Bake");
Ingredient ingredient1 = new Ingredient("POT", "Potato", "None");
Ingredient ingredient2 = new Ingredient("CRM", "Cream", "None");
meal.addIngredient(ingredient1);
meal.addIngredient(ingredient2);
bWriter.enablePrettyPrint();
bWriter.write("meal", meal);
bWriter.flush();
BeanReader reader = new BeanReader();
reader.registerBeanClass("meal", Meal.class);
Meal mealReadFromFile =
(Meal)reader.parse(new File("output.xml"));
System.err.println(mealReadFromFile);
}
}

Most of this code doesn't change from listing 4.The output.xml file created by running this code is shown in listing 10.

Listing 10. output.xml for multiple values represented as a HashMap

<meal>
<ingredients>
<entry>
<key>POT</key>
<value>
<key>POT</key>
<name>Potato</name>
<alternate>None</alternate>
</value>
</entry>
<entry>
<key>CRM</key>
<value>
<key>CRM</key>
<name>Cream</name>
<alternate>None</alternate>
</value>
</entry>
</ingredients>
<mealName>Potato Bake</mealName>
<mealType>1</mealType>
<weekday>1</weekday>
</meal>

As expected, the meal root element contains an ingredients element that represents the map. Each value in the map is entered in the XML as a separate entry element. Each entry element contains two elements: the key element, representing the key; and the value element, representing the value associated with that key (in this case, an Ingredient object with its own properties marked as elements). The rest of the meal properties are listed at the end.

If, instead of a Map, we were dealing with a collection-based object, the output would be similar. But instead of the entry element, we'd have the actual name of the object (); and, of course, there would be no key element.

The reverse process relies on the presence of an addXXX method in the original object. Thus, the Meal object is faithfully re-created with the right ingredients, because Betwixt recognizes the presence of an addIngredient method in the Meal class. You can plug in your own method by specifying the update attribute in a .betwixt file, for the matching element. For example:

<element name="ingredients" property="ingredients"
         updater="customAddMethod" />

You now know how to read and write multiple values using Betwixt. In the next section, we'll consider the custom conversion process, which lest you specify specially built patterns for String --> Object and Object --> String conversions.

Custom conversions

Betwixt uses the ConvertUtils component of Commons BeanUtils for converting Objects to Strings and vice versa. However, at times, this default behavior may not be what you want. For example, you may want the dates in your output to be printed in a particular format (the default format prints the date as EEE MMM dd HH:mm:ss zzz yyyy, using the UK as its locale). You can do this by using a custom implementation of the ObjectStringConverter class and installing it as the default on the BindingConfiguration class.

Listing 11 shows an implementation of the ObjectStringConverter class for converting dates in a format that is different from the default implementation. Note that this class only extends the objectToString method, which enables bean --> XML conversion, and not the stringToObject method, which you would have to override for XML --> bean conversion.

Listing 11. Converting dates in a special format

package com.manning.commons.chapter05;
import java.text.SimpleDateFormat;
import org.apache.commons.betwixt.expression.Context;
import org.apache.commons.betwixt.strategy.ObjectStringConverter;
public class DateConvertor extends ObjectStringConverter {
private static final SimpleDateFormat formatter
= new SimpleDateFormat("dd-MMM-yyyy");
public String objectToString(
Object object, Class type, String flavor,
Context context) {
if(object != null) {
if(object instanceof java.util.Date) {
return formatter.format( (java.util.Date) object );
}
}
return super.objectToString(object, type, flavor, context);
}
}

To use this special converter, we need to install it on Betwixt using the BindingConfiguration class, as shown in listing 12.

Listing 12. Installing and using the custom converter

package com.manning.commons.chapter05;
import java.io.File;
import java.io.FileWriter;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.betwixt.BindingConfiguration;
public class CustomConversion {
public static void main(String args[]) throws Exception {
FileWriter fWriter = new FileWriter("output.xml");
BeanWriter bWriter = new BeanWriter(fWriter);
MealPlan plan = new MealPlan();
Meal meal = new Meal(1, 1, "Potato Bake");
Ingredient ingredient1 = new Ingredient("POT", "Potato", "None");
Ingredient ingredient2 = new Ingredient("CRM", "Cream", "None");
meal.addIngredient(ingredient1);
meal.addIngredient(ingredient2);
plan.addMeal(meal);
bWriter.enablePrettyPrint();
BindingConfiguration bConfig =
bWriter.getBindingConfiguration();
bConfig.setObjectStringConverter(new DateConvertor());
bWriter.setBindingConfiguration(bConfig);
bWriter.write("mealplan", plan);
bWriter.flush();
}
}

The output of running the code in listing 12 is as shown in listing 13. Notice that the dates are written in the special format dd-MMM-yyyy. If you run the code in listing 12 without installing the special converter, the dates will be printed in the default format EEE MMM dd HH:mm:ss zzz yyyy.

Listing 13. output.xml, using a special converter on the MealPlan object

<mealplan>
<endDate>>23-Apr-2004</endDate>
<meals>
<meal>
<ingredients>
<entry>
<key>POT</key>
<value>
<key>POT</key>
<name>Potato</name>
<alternate>None</alternate>
</value>
</entry>
<entry>
<key>CRM</key>
<value>
<key>CRM</key>
<name>Cream</name>
<alternate>None</alternate>
</value>
</entry>
</ingredients>
<mealName>Potato Bake</mealName>
<mealType>1</mealType>
<weekday>1</weekday>
</meal>
</meals>
<startDate>16-Apr-2004</startDate>
</mealplan>

While reading this XML file, we can't use the default converter: It expects the date in the default format, but the date here is in the special format. To make a complete round trip, the stringToObject method also needs to be overwritten in listing 8. We'll leave that as an exercise for you!

Summary

Betwixt is a utility tool for converting JavaBeans to XML and vice versa. It's a flexible tool that uses Digester rules to create objects from XML files. It also converts JavaBeans to XML in a manner that can be customized to a high degree.

About the Author

Vikram Goyal is a Java Developer by day and a technical writer by night. Vikram has worked with Java since its inception and remembers the time when Tomcat meant an animal and not a servlet engine. Vikram regularly writes how-to articles on open source projects and his series of articles on Jakarta Commons was the first such effort to make some sense out of the chaotic world that Jakarta Commons is. This article series is still reflected in the official main entry page of Jakarta Commons as the only online series covering these components.

Vikram enjoys working with Open Source technologies, Team Leading and Civilization 3. He lives in Brisbane, Australia, with his wife.

Source of This Material

Jakarta Commons Online Bookshelf
By Vikram Goyal



Published: March, 2005, 402 pages
Published by Manning Publications
PDF ebook: $39.95
Jakarta Commons Online Bookshelf provides detailed technical information about 18 components from Jakarta Commons Proper and 1 component from the Commons Sandbox (Chain, module 13). Modules can be purchased individually from the Manning web site at www.manning.com/goyal. This material is from Module 5 of the book.





Page 4 of 4



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel