You see it as forcing, I see it as enabling. The design enables developers to define and convert their own types. The goal is to be able to pass custom object types around the framework, instead of having to convert everything into java.* library types.

Thank you for the Spring info. I thought someone might have already come up with the same idea (great minds think alike) but I didn't know what was out there. I will look into it.

-Adrian

Harmeet Bedi wrote:
This forces users to have objects for everything they want to convert to and 
from causing large number of objects in system. Very OO, looks fine to me. 
PhoneNumber logic could be easily wrapped into object.


convert signature seems nicer than 'to'.

Looked  a bit at spring. Maybe sharing some code from there would be better.. 
They have a well contained package  org.springframework.core.convert.converter. 
it is apache license


/**
 * A factory for "ranged" converters that can convert objects from S to 
subtypes of R.
 *
 * @author Keith Donald
* @since 3.0 * @param <S> The source type converters created by this factory can convert from
 * @param <R> The target range (or base) type converters created by this 
factory can convert to;
 * for example {...@link Number} for a set of number subtypes.
 */
public interface ConverterFactory<S, R> {

        /**
         * Get the converter to convert from S to target type T, where T is 
also an instance of R.
         * @param <T> the target type
         * @param targetType the target type to convert to
         * @return A converter from S to T
         */
        <T extends R> Converter<S, T> getConverter(Class<T> targetType);

}


/**
 * A converter converts a source object of type S to a target of type T.
 * Implementations of this interface are thread-safe and can be shared.
 *
 * @author Keith Donald
 * @since 3.0
 */
public interface Converter<S, T> {

        /**
         * Convert the source of type S to target type T.
         * @param source the source object to convert, which must be an 
instance of S
         * @return the converted object, which must be an instance of T
         * @throws IllegalArgumentException if the source could not be 
converted to the desired target type
         */
        T convert(S source);

}


They also have
ConverterInfo: A meta interface a Converter may implement to describe what 
types he can convert between.
ConverterRegistry: For registering converters with a type conversion system.


Harmeet

----- Original Message -----
From: "Adrian Crum" <adri...@hlmksw.com>
To: dev@ofbiz.apache.org
Sent: Thursday, November 5, 2009 10:41:03 AM GMT -05:00 US/Canada Eastern
Subject: Re: Discussion: Improved Java Object Type Conversion

Harmeet,

This is a great idea, and a good example of how the conversion framework could be extended.

My personal preference would be stay with the current interface, and use wrappers or facades for the arguments:

PhoneNumber phoneNumber = new PhoneNumber(someMap);
Converter<String, PhoneNumber> converter = ConverterFactory.getConverter(String.class, PhoneNumber.class);
String phoneNumberStr = converter.to(phoneNumber);

By the way, the Converter interface can be made more semantic by using a better method name:

public interface Converter<T, F> {
      public T convert(F obj);
}

so the code above would look like this:

String phoneNumberStr = converter.convert(phoneNumber);

In my trial code, the interface was bidirectional - with from() and to() methods. I realized that could be confusing and changed it to the single convert() method.

-Adrian


Harmeet Bedi wrote:
Looks nice. For primitive type conversion it seems sufficient.

Wondering if this should be expanded to have more than one conversion mechanism 
for a conversion pair
The 2 spots where we convert in Emforium are
- Take a map and convert to formatted name, phone numbers etc.
- Take an object and convert it to Map for addition into generic map, calling 
services etc.

It seems like this could easily fit into Converter Factory structure if you had 
one more method on ConverterFactory

public class ConverterFactory {
public static <T, F> Converter<T, F> getConverter(Class<T> toClass, Class<F> fromClass) {}

// new public static <T, F> Converter<T, F> getConverter(String converterType,Class<T> toClass, Class<F> fromClass) {}
}


So then one could register specific converter strategies and then use them in 
code. Something like this.

Converter<Long, Map<?,?>> converter = 
ConverterFactory.getConverter("PhoneNumberConverter",String.class, Map.class);
String phoneNumber = converter.to(map);

or Converter<Long, Map<?,?>> converter = ConverterFactory.getConverter("AddressConverter",String.class, Map.class);
String phoneNumber = converter.to(map);


Would get us away from hardcoded class and method names where we do these 
conversions.
There is some overlap with services in this. We have used these static calls as 
they seemed more lightweight. Our calls are only within Java callable space.

Harmeet
----- Original Message -----
From: "Adrian Crum" <adri...@hlmksw.com>
To: dev@ofbiz.apache.org
Sent: Wednesday, November 4, 2009 7:08:56 PM GMT -05:00 US/Canada Eastern
Subject: Discussion: Improved Java Object Type Conversion

I have an idea for improved Java object type conversion (converting from one Java object type to another), and I would like to solicit comments from the community.

Currently, the project handles object type conversions in the ObjectType.simpleTypeConvert(...) method, and there are small conversion code snippets in other classes (UtilDateTime for example). Basically, object type conversion is scattered all over the project. This can lead to code inconsistency, or inconsistent conversion results.

I think it would be helpful to consolidate object type conversion into a simple "framework" that can be easily extended to handle additional conversions.

I came up with a simple interface:

public interface Converter<T, F> {
     public T to(F obj);
}

where T is the object type to convert to, and F is the object type to convert from.

A factory class is used to get a Converter instance:

public class ConverterFactory {
public static <T, F> Converter<T, F> getConverter(Class<T> toClass, Class<F> fromClass) {}
}

To convert an object:

String str = "1234";
Converter<Long, String> converter = ConverterFactory .getConverter(Long.class, String.class);
Long result = converter.to(str);

The framework would include converter implementations for all the conversions currently being used. The ObjectType.simpleTypeConvert(...) method's complicated if-else code would be replaced with the simpler converter code.

Users can write their own converters and "register" them with the converter framework.

What do you think?

-Adrian


Reply via email to