Skip to main content

Converting objects from A to B and back - there ought to be a library

Posted by timboudreau on May 1, 2009 at 11:33 AM PDT

One pattern that is an incredibly frequent recurring theme is converting an Object of type A into an object of type B for something that understands B to consume. Tons of libraries have something like this embedded in them - beans binding, pretty much anything that validates strings. If there were ever something that deserves a simple common library, it's this.

I was just looking at Fabrizio Guiduci's Better Beans Binding project, which took me to the original beans binding project. Embedded in it is a mini-framework for converting objects back and forth between types - an application provides a List, a JList wants a ListModel.

Last week as part of my new Simple Validation project I wrote into it a mini framework for object conversion and a converter registry:

public abstract class Converter<From,To> {
    public abstract <To> convert (From from);
    public static <From,To> Converter<From,To> find (Class<From> from, Class<To> to);
}

alt="Cat Eyes Macro Photo" src="http://weblogs.java.net/blog/timboudreau/archive/cateyes.png" width="350" height="274" />
Java Beans property editors are de-facto Object -> String -> Object convertors - I've long thought that one of the bigger messes in the beans spec (there are so many!) is the fact that type conversion is a completely orthagonal concern that should have been factored out.

And on it goes - I'm sure there are many, many more examples. All of the subclasses of java.text.Format in the JDK count. Pretty much anything that communicates via HTTP and uses an object-oriented language is one.

Perhaps something like this already exists and I don't know about it.

But what I would really like to see is a simple framework that solves the problem, that the rest of these projects could use - it's really an area where there is endless spinning of wheels. The characteristics something like that would be:

  • Simple - if the framework exposes more API classes than you can count on your fingers, it's overcomplicated
  • Converters are injected - i.e. you ask for a Converter for Date -> String -> Date; you do not ever refer to the actual implementation type of the converter unless you are writing it yourself. Getting a stable of converters for the preexisting types you need should be as simple as putting the right JAR on the classpath. Only if there are really multiple right ways to approach the problem should you need to instantiate a converter yourself.
  • Does not assume bi-directionality (the Beans Binding version does this, but it needs that for some cases) - i.e. you have
    Converter<From,To> {
       To convert (From from);
    }

    and
    BidiConverter<From,To> extends Converter<From,To< {
       From reverseConvert (To to);
    }

    or maybe skip the bi-directionality assumption altogether.
  • Comes with an optional set of useful converters for common things such as JDK classes
  • Conversion errors are unchecked exceptions with meaningful error messages, and few but useful-if-present exception subtypes

Jon Locke definitely deserves credit for making me think about this problem, as he has been thinking about it himself — I sent him a pre-open-source version of SimpleValidation, and one comment was “i do think that validation and conversion are actually two completely independent things. and that a reusable toolkit for doing this stuff would have two independently reusable packages.” - and also mentions “wicket already has a pretty general conversion framework built-in” (everybody's got one!)

I don't generally propose One Library To Rule Them All approaches - but in this case, the problem is general enough that the goal is to provide a library useful enough that people would use it and simple enough that people would contribute. And since the pattern is the same almost everywhere, all the mini-frameworks could easily wrap another framework's converters - in the current fragmented state, nobody really wants to do that because they'd have to drag in the rest of the library when it's not needed - for example, SimpleValidation could have probably used Wicket's validation - but I wouldn't force someone who just wants to validate a URL to drag around all the JARs needed to borrow that from Wicket - and everybody is in the same situation.

I mean, this seems like such a boring and simple thing that it should be a Solved Problem. So how much time do we all spend writing mindless code to marshal data between types?

Related Topics >>

Comments

Thanks for the links! I'll take a look at both of these...

FWIW, we tried Dozer and found some features lacking--and the source was a relative mess at the time. We had much better luck with Morph: http://morph.sourceforge.net/

Maybe Dozer would help: http://dozer.sourceforge.net/ It's a framework for copying information from a to b, configurable with xml files, using convention over configuration. It really can do a lot of things, I've been using it for very simple things though. regards, amusi

I always wanted this to be implemented properly: http://java.sun.com/j2se/1.5.0/docs/api/java/beans/Beans.html#getInstanceOf(java.lang.Object,%20java.lang.Class) Best, Laird