Adrian Crum wrote:
> --- On Wed, 2/10/10, Adam Heath <[email protected]> wrote:
>> From: Adam Heath <[email protected]>
>> Subject: Re: svn commit: r908713 - in
>> /ofbiz/trunk/framework/base/src/org/ofbiz/base/conversion:
>> CollectionConverters.java test/MiscTests.java
>> To: [email protected]
>> Date: Wednesday, February 10, 2010, 9:19 PM
>> Adrian Crum wrote:
>>> --- On Wed, 2/10/10, Adam Heath <[email protected]>
>> wrote:
>>>> From: Adam Heath <[email protected]>
>>>> Subject: Re: svn commit: r908713 - in
>> /ofbiz/trunk/framework/base/src/org/ofbiz/base/conversion:
>> CollectionConverters.java test/MiscTests.java
>>>> To: [email protected]
>>>> Date: Wednesday, February 10, 2010, 7:05 PM
>>>> Adrian Crum wrote:
>>>>> Every programmer has their own design style.
>> This
>>>> would be mine:
>>>>> class JsonString {
>>>>> public String toString() {
>>>>> ...
>>>>> }
>>>>> }
>>>>>
>>>>> public static class ListToJsonString<T>
>> extends
>>>> AbstractConverter<List<T>, JsonString>
>> {
>>>>> public ListToJsonString() {
>>>>> super(List.class,
>> JsonString
>>>> .class);
>>>>> }
>>>>> ...
>>>>> }
>>>>>
>>>>> The problem I have with your approach is the
>> fact that
>>>> there is no way to know that converting object x
>> to a String
>>>> will result in a JSON string. In addition, I was
>> hoping we
>>>> could stick to this pattern: Converting any Java
>> type to a
>>>> String is the same as calling the object's
>> toString()
>>>> method.
>>>>> -Adrian
>>>> Yeah, I thought you would comment on this.
>>>>
>>>> Should ListToString and StringToList be
>> reflective?
>>>> As they used to
>>>> be, they weren't.
>>> That's a good question. The original List conversions
>> were copied from the ObjectType code and I never looked into
>> that code in detail - I just wanted to maintain the original
>> behavior.
>>> When I picture java types being converted to strings,
>> I imagine them being displayed - kind of like how they would
>> appear if you did something like:
>>> String prompt = "The List is: " + someList;
>>>
>>> Making the converters reflective is a worthwhile goal
>> - I just never considered it.
>>> What you're trying to accomplish is great. We can take
>> that concept even further by having type x to XML converters
>> - so that java objects can be serialized to XML.
>>> So, that's why I commented on it. What if I wanted to
>> convert a List to an XML string? Or a [insert encoding
>> method here] string?
>>
>> Here's a summary of what you have said, and what I have
>> been thinking:
>>
>> 1: I've got an object, I want to convert it for
>> display. This could
>> call to string, or something else, maybe multiple
>> converters in series.
>>
>> 2: I want to change the format of an object; an object is
>> nothing
>> without the data it encapsulates, and there are different
>> ways of
>> encapsulating said data. So, converting a
>> List<Map> to JSON, still
>> ends up carrying the exact same set of data. This is
>> simliar to
>> serialization, but hopefully allows for a human to edit the
>> converted
>> state.
>>
>> 3: JSON kinda has a hard-coded registry; it can only handle
>> very
>> simple basic types. If it was made to use a large
>> registry of
>> converters, it would need to have the basic types use the
>> internal
>> json, but then all other types use the resolve() syntax.
>>
>> 4: XML output is similiar to JSON, but there are no
>> intrinsic types,
>> so there doesn't have to be any special casing.
>>
>> What this is saying to me, is we need a third parameter to
>> this
>> conversion framework; first is source class, second is
>> target class,
>> and third would be maybe 'flavor' or 'method'. Method
>> as in
>> request.METHOD, or output method, or some such.
>
> Nope, we need separate converters:
>
> <set field="listAsJsonString" from-field="someList" type="JsonString"/>
> <set field="listAsXmlString" from-field="someList" type="XmlString"/>
> <set field="listAsFooString" from-field="someList" type="FooString"/>
Stop thinking top level.
(borrowing json syntax)
{"numbers": [1, 2, 3, 4], "map": {"a": "b"}}
In your example, "someList" is equal to the above example object. But
then the method that is doing the encoding(JsonString, XmlString,
FooString) will *itself* call *back* into Converters, asking for a
conversion for the embed String keys, the embeded list, and the
embedded map. Then, for the list and map, they too will have to again
call into Converters, asking for each number and String to be encoded.
What I am suggesting is getting rid of the else if block in
JSONWriter, *and* the hard-coded xml serialization stuff, and just
making that *all* use Converters as it's registry.
Hmm, I was going to write more here, but then I realized something
else. While keeping the above 2 paragraphs is useful, what I am about
to suggest is an even more radical approach.
If the supposed xml converter existed, how would it actually function?
Would it have each nested object get converted to a *string*, then
parse that string back into DOM, and append it to the current
document? Of course not. So, the next way to do that might be to
have a FooToElement type converter. This is better. However, each
FooToElement converter would end up creating a dummy document, just to
create the singleton element that would be representing of it's data.
So, maybe we need to be able to pass down a 'context' variable, in
this specific case, a 'node', to which the converter can attach it's
element.
This would also work well for JSON output, because the IndentingWriter
class could be the context variable that is passed to child converters.
Even doing a normal FooToString converter could make use of this, by
passing a StringBuilder around.