You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Ron Blaschke <ma...@rblasch.org> on 2004/03/21 14:20:03 UTC

Re: [convert] Initial ideas (was: conversion with default values)

Sunday, March 21, 2004, 2:59:12 AM, you wrote:
SC> Basically the sooner you can make available ideas/designs/code the more it
SC> can be talked about ;-)

Point taken.  Please find attached a summary of my thoughts (well, not
all of them; just those related to convert).

Ron

Re: [convert] Initial ideas (was: conversion with default values)

Posted by Ron Blaschke <ma...@rblasch.org>.
>> RB> Don't know if the images made it to the list, so you'd better get
>> RB> http://www.rblasch.org/convert/convert-docs.zip
>> A snapshot of my prototype is also available at
>> http://www.rblasch.org/convert/convert-proto2.zip

SC> The complex conversions involving Type I didn't manage to grok, but maybe I
SC> will if more awake. I'd like to keep [convert] simple if possible, maybe you
SC> could have a think about whether the %age match stuff in the CVS is of any
SC> use.

If I understood it correctly, the percentage is used to provide some
means select the "best" converter (or chain of converters).  The
weight in the edges of the graph I used serve the same purpose.  I
have used only the value "1", but any other positive value will do.
The shortest path algorithm then searches for the converters with a
minimal sum.

Say, you have got the converters
Integer -(80)-> Byte
Byte -(80)-> Boolean

To get from Integer to Boolean you have a weight of 160, which is the
shortest path (the only one).  If you add the Integer -(60)-> Boolean
converter, it would be chosen because its weight would be 60.

The prototype currently provides no way to set the weights, but would
be easy to add.

I think the percentage stuff is useful, though I'd call (and maybe
use) it a little different, as I got used to to the term "weight" from
graph theory.

SC> Stephen
SC> PS: I'm on holiday for a week from Wednesday ;-)

Enjoy your holidays! :-)


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [convert] Initial ideas (was: conversion with default values)

Posted by Stephen Colebourne <sc...@btopenworld.com>.
Thanks for the code and docs. I tried to take a look, but my eyes are
closing ATM so I didn't get far.

Separating ConverterRegistry and ConverterLookup looks like an interesting
idea, as does allowing ConverterRegistry to be a view of a config file.

The complex conversions involving Type I didn't manage to grok, but maybe I
will if more awake. I'd like to keep [convert] simple if possible, maybe you
could have a think about whether the %age match stuff in the CVS is of any
use.

Stephen
PS: I'm on holiday for a week from Wednesday ;-)

----- Original Message -----
From: "Ron Blaschke" <ma...@rblasch.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Sunday, March 21, 2004 3:14 PM
Subject: Re: [convert] Initial ideas (was: conversion with default values)


> SC>>> Basically the sooner you can make available
> SC>>> ideas/designs/code the more it
> SC>>> can be talked about ;-)
>
> RB>> Point taken.  Please find attached a summary of my thoughts (well,
not
> RB>> all of them; just those related to convert).
>
> RB> Don't know if the images made it to the list, so you'd better get
> RB> http://www.rblasch.org/convert/convert-docs.zip
>
> A snapshot of my prototype is also available at
> http://www.rblasch.org/convert/convert-proto2.zip
>
> The code is A Real Mess and may cause brain damage.  You have been
> warned.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [convert] Initial ideas (was: conversion with default values)

Posted by Ron Blaschke <ma...@rblasch.org>.
OH> I had a look at your ideas and now I have a few questions and remarks.
Great!

OH> At first let me say that I like the idea of using a graph representation
[...]
I definitely agree.  Things get a lot easier that way.  Besides, we
could even support a special debug mode, where we plug in a graph renderer
and thereby provide an image of the registered converters (just like
the ones in the document I posted, and had drawn by hand).  If a
conversion succeeds we could provide an image of the path chosen (may
be useful if an unexpected result pops up.)

OH> The idea to use a separate lookup class seems interesting, too. But
OH> after thinking a while about it I am not sure if this really helps
[...]
OH> registry. So this would imply that for different lookup classes other
OH> data has to be stored in the registry. Can this be handled in a generic
OH> way or wouldn't it be better to leave the lookup mechanism in the 
OH> registry and use different registry implementations?

In my current line of thought the registry and lookup are quite
tightly coupled, but serve different purposes.  The Registry is just a
plain storage, whereas the Lookup provides the algorithm(s?) to work
on them.  For example, the ClassConverterRegistry provides/should
provide all Converters the Java language uses for a class (inheritance,
toString()).  But then again, something simpler like a Set or List
might be better suited for that.


OH> 2. A lookup might be expensive, especially if a search in a complex
OH> graph has to be performed. So it might make sense to implement some
OH> caching functionality. I am not sure if this can be done efficiently in
OH> a lookup class implementation because in your example code always a new
OH> lookup instance is created (though I might miss something here).

You are right, the lookup should definitely be cached, but I didn't go
that far in my implementation.  I guess there are a number of things
we can do, though I haven't thought them through yet.  First, we could
build a single graph for a Lookup and incrementally extend it (there
may be times when it has to be rebuild, eg when a converter is
removed, or the graph gets too big).  Then, we could cache some paths,
in case they are reused.  The shortest path algorithm provides the
shortest path to all destinations from a source, so this computation
may somehow be reused, too.

OH> The approach with the Types handles inheritence, but does it cover all
OH> cases? I am not sure if the following use case could be handled: imagine
OH> a user has the classes A, B, C, and D with B and C extending A. Then
OH> there are special conversion implementations for A->D and B->D. If now
OH> an object of class C is provided, will then the A->D conversion be used?
OH> With other words: inheritence in direction towards the base classes is
OH> surely supported, but can derived classes be handled without extra means?

Yes.  In my model, everything is a conversion, even inheritance,
implementation of an interface, or the String conversion (toString) of
any object.  In your example, a chained converter would be build, to
provide the conversion C -> A -> D.  In the prototype, this is done via
extension of the graph with the converters of the class C (see
addTypeConverters for both the source and destination type).  So, in
the beginning you only have the converter A -> D, but as you ask for a
conversion of an object of type C, the conversion C -> A is added.

public ExtendedConverter lookup(final Type sourceType,
    final Type destinationType) throws NoSuchConversionException {
    addTypeConverters(graph, sourceType);
    addTypeConverters(graph, destinationType);
    return new ChainedExtendedConverter(getConvertersForPath(getShortestPath(sourceType, destinationType)));
}

OH> What about structural conversions, e.g. a String[] to a int[] or a
OH> collection of Integers to a byte[]? Where would these conversions take
OH> place? (I think this is slightly different from constructing a chain of
OH> conversions because here a base conversion has to be performed multiple
OH> times.)

I started to think about that too, but postponed that for a version 2
of convert.  Here is how far I got:
I think it's better to think about String[] or int[] as a parametric
type, like Array<String> or Array<int>.  That way, it will be easier
to think about conversions as Array<int> to List<Integer> (aside
from supporting Java 1.5).  Now, a converter needs to worry about the
outer structure (Array -> List) and the meat (int -> Integer) (this
would apply for other structures too, eg List -> Set).  I could
imagine an implementation like this:

public class ListToSetConverter extends AbstractConverter {
    final Type srcParam, destParam;
    public ListToSetConverter(final Type srcParam, final Type destParam) {
        this.srcParam = srcParam;
        this.destParam = destParam;
    }
    
    public Type getSourceType() {
        return Types.parse("List<*>", srcParam);
    }

    public Type getDestinationType() {
        return Types.parse("Set<*>", destParam);
    }

    protected ConversionContext convert(final ConversionContext context)
    throws NoSuchConversionException, ConversionFailedException {
        final Set s = new HashSet();
        for (final Iterator i = context.getValue(); i.hasNext();) {
            s.add(context.convert(i.next(), destParam));
        }
        return context.update(s, getDestinationType());
    }
}

"context.convert()" would provide access to the Lookup that found the
converter, thereby allowing the converter to ask for conversions /
call other converters.

Then, "new ListToSetConverter(Integer.class, Integer.TYPE)" (or
something like that) can be plugged into the graph, and be used like
any other.  (Of course, the Lookup must be prepared to handle
parametric types, like the implicit LinkedList<Integer> ->
List<Number> -> List<Number> conversion).

OH> One last remark about the extended converter interface: I think I 
OH> understand why this ConversionContext is needed - to allow a single
OH> object being treated as of different types. But I strongly agree with a
OH> statement mentioned on this thread: that the converter interface should
OH> be as simple as possible. So if it is possible, I would try to get rid
OH> off this additional complexity.

The ConversionContext would be used to supply additional information
for a conversion.  Currently, it only holds the perceived type and the
object to convert, but could also include
- reference to the Lookup, to allow a converter to ask for other
  conversions
- isCopy field, that states that the input object is a copy (maybe
  from another converter) and may be used for a "destructive"
  conversion, eg List<Integer> -> List<String> might simply transform
  the Integers to String in the List, without creating a new List.
- isImmutable field, that states that the given input object may not
  be modified, even if the object is mutable.
- ...

I am quite a bit torn between the possible functionality that can be
provided with this information, and the simplicity of the Converter
interface.  Maybe we could come up with some different Converter
interfaces that get increasingly complex, and would be suitable for
different situations.  Adapters (with additional metadata),
could be used to get from the simpler to the more complex converters.

We could even provide a "dynamic converter adapter" that scans any
given object for convert methods (eg, any method that starts with
"convert") and provides adapters for them:

public class Any {
   public String convert(Integer i) throws SomeException {
       ...
   }
}

...getSourceType() -> Integer
...getDestinationType() -> String
...

Ron
--


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [convert] Initial ideas (was: conversion with default values)

Posted by Oliver Heger <Ol...@t-online.de>.
I had a look at your ideas and now I have a few questions and remarks.

At first let me say that I like the idea of using a graph representation 
and a kind of shortest path algorithm to determine a conversion chain 
very much. I think this is something we will need to make [convert] 
really flexible. With the percentage values used at the moment on the 
other hand I belief it is very difficult to define an appropriate 
priority order, especially if those values are hard coded in the factory 
classes.

The idea to use a separate lookup class seems interesting, too. But 
after thinking a while about it I am not sure if this really helps 
because of the following points:

1. A lookup class will probably need some meta information to find the 
group of converters to use for the actual query. This meta information 
can be different for different implementations, e.g. weights for the 
graph's edges. The place to store this information is certainly the 
registry. So this would imply that for different lookup classes other 
data has to be stored in the registry. Can this be handled in a generic 
way or wouldn't it be better to leave the lookup mechanism in the 
registry and use different registry implementations?

2. A lookup might be expensive, especially if a search in a complex 
graph has to be performed. So it might make sense to implement some 
caching functionality. I am not sure if this can be done efficiently in 
a lookup class implementation because in your example code always a new 
lookup instance is created (though I might miss something here).

No my further questions:

The approach with the Types handles inheritence, but does it cover all 
cases? I am not sure if the following use case could be handled: imagine 
a user has the classes A, B, C, and D with B and C extending A. Then 
there are special conversion implementations for A->D and B->D. If now 
an object of class C is provided, will then the A->D conversion be used? 
With other words: inheritence in direction towards the base classes is 
surely supported, but can derived classes be handled without extra means?

What about structural conversions, e.g. a String[] to a int[] or a 
collection of Integers to a byte[]? Where would these conversions take 
place? (I think this is slightly different from constructing a chain of 
conversions because here a base conversion has to be performed multiple 
times.)

One last remark about the extended converter interface: I think I 
understand why this ConversionContext is needed - to allow a single 
object being treated as of different types. But I strongly agree with a 
statement mentioned on this thread: that the converter interface should 
be as simple as possible. So if it is possible, I would try to get rid 
off this additional complexity.

Oliver

Ron Blaschke wrote:

>SC>>> Basically the sooner you can make available
>SC>>> ideas/designs/code the more it
>SC>>> can be talked about ;-)
>
>RB>> Point taken.  Please find attached a summary of my thoughts (well, not
>RB>> all of them; just those related to convert).
>
>RB> Don't know if the images made it to the list, so you'd better get
>RB> http://www.rblasch.org/convert/convert-docs.zip
>
>A snapshot of my prototype is also available at
>http://www.rblasch.org/convert/convert-proto2.zip
>
>The code is A Real Mess and may cause brain damage.  You have been
>warned.
>
>Ron
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
>  
>



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [convert] Initial ideas (was: conversion with default values)

Posted by Ron Blaschke <ma...@rblasch.org>.
SC>>> Basically the sooner you can make available
SC>>> ideas/designs/code the more it
SC>>> can be talked about ;-)

RB>> Point taken.  Please find attached a summary of my thoughts (well, not
RB>> all of them; just those related to convert).

RB> Don't know if the images made it to the list, so you'd better get
RB> http://www.rblasch.org/convert/convert-docs.zip

A snapshot of my prototype is also available at
http://www.rblasch.org/convert/convert-proto2.zip

The code is A Real Mess and may cause brain damage.  You have been
warned.

Ron


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [convert] Initial ideas (was: conversion with default values)

Posted by Ron Blaschke <ma...@rblasch.org>.
RB> Sunday, March 21, 2004, 2:59:12 AM, you wrote:
SC>> Basically the sooner you can make available
SC>> ideas/designs/code the more it
SC>> can be talked about ;-)

RB> Point taken.  Please find attached a summary of my thoughts (well, not
RB> all of them; just those related to convert).

Don't know if the images made it to the list, so you'd better get
http://www.rblasch.org/convert/convert-docs.zip

Ron


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org