commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <>
Subject [Jakarta-commons Wiki] Update of "Betwixt/TipsAndHints/CustomObjectStringConverter" by JesseSweetland
Date Thu, 10 Aug 2006 14:10:43 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Jakarta-commons Wiki" for change notification.

The following page has been changed by JesseSweetland:

New page:
Betwixt only allows the registration of a single object/string converter strategy class. 
This class serves as a mediator to route conversion calls
to helper classes depending based on type.  Converters are registered and by deregistered
via calls to the register and deregister methods, respectively, and resolved via the {@link
#resolve} method.  Only one ObjectStringConverter can be registered per class at any given
time.  If there is no ObjectStringConverter registered for a given class, then the resolve
method checks to see if there is an ObjectStringConverter registered for its super class or
any of its interfaces (recursively).  The first ObjectStringConverter found in the class hierarchy
is used. (Note that if the class implements many interfaces, and there are converters for
more than one of those interfaces, the resulting behavior will be undefined.)

import java.util.*;
import org.apache.commons.betwixt.expression.*;
import org.apache.commons.betwixt.strategy.*;

 * @author Jesse Sweetland
public class CustomObjectStringConverter extends ObjectStringConverter {
    private final Map<Class, ObjectStringConverter> _converters = new HashMap<Class,
    public void register(ObjectStringConverter converter, Class forType) {
        _converters.put(forType, converter);
    public void deregister(Class forType) {

    public ObjectStringConverter resolve(Class forType) {
        int minDistance = Integer.MAX_VALUE;
        ObjectStringConverter converter = null;
        for(Map.Entry<Class, ObjectStringConverter> entry: _converters.entrySet()) {
            int distance = getDistance(entry.getKey(), forType);
            if((distance >= 0) && (distance < minDistance)) {
                minDistance = distance;
                converter = entry.getValue();
        return converter;
    private int getDistance(Class superClass, Class type) {
        if(superClass.isAssignableFrom(type)) {
            Class temp = type;
            int distance = 0;
            while(temp != null) {
                if(temp.equals(superClass)) return distance;
                for(Class ifc: temp.getInterfaces()) {
                    if(ifc.equals(superClass)) return distance;
                temp = temp.getSuperclass();
        return -1;
    public String objectToString(Object object, Class type, Context context) {
        if(object == null) return null;
        ObjectStringConverter converter = resolve(type);
        if(converter != null) {
            return converter.objectToString(object, type, context);
        } else {
            return super.objectToString(object, type, context);
    public Object stringToObject(String value, Class type, Context context) {
        if(value == null) return null;
        ObjectStringConverter converter = resolve(type);
        if(converter != null) {
            return converter.stringToObject(value, type, context);
        } else {
            return super.stringToObject(value, type, context);


StringWriter sw = new StringWriter();
BeanWriter bw = new BeanWriter(sw);
CustomObjectStringConverter osc = new CustomObjectStringConverter();
osc.register(new EnumObjectStringConverter(), Enum.class);
osc.register(new DateObjectStringConverter(), Date.class);

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message