Adrian Crum wrote: > --- On Wed, 2/10/10, Adam Heath <doo...@brainfood.com> wrote: >> From: Adam Heath <doo...@brainfood.com> >> Subject: Re: svn commit: r908713 - in >> /ofbiz/trunk/framework/base/src/org/ofbiz/base/conversion: >> CollectionConverters.java test/MiscTests.java >> To: dev@ofbiz.apache.org >> Date: Wednesday, February 10, 2010, 9:53 PM >> Adrian Crum wrote: >>> --- On Wed, 2/10/10, Adam Heath <doo...@brainfood.com> >> wrote: >>>> From: Adam Heath <doo...@brainfood.com> >>>> Subject: Re: svn commit: r908713 - in >> /ofbiz/trunk/framework/base/src/org/ofbiz/base/conversion: >> CollectionConverters.java test/MiscTests.java >>>> To: dev@ofbiz.apache.org >>>> Date: Wednesday, February 10, 2010, 9:19 PM >>>> Adrian Crum wrote: >>>>> --- On Wed, 2/10/10, Adam Heath <doo...@brainfood.com> >>>> wrote: >>>>>> From: Adam Heath <doo...@brainfood.com> >>>>>> Subject: Re: svn commit: r908713 - in >> /ofbiz/trunk/framework/base/src/org/ofbiz/base/conversion: >>>> CollectionConverters.java test/MiscTests.java >>>>>> To: dev@ofbiz.apache.org >>>>>> 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. > > I call it "Imagine the possibilities..." > >> (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? > > Probably by using an existing Java object to XML conversion library. > >> 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. > > If it was me I would design a JsonString class that hides all of those > implementation details from the conversion framework. I try to avoid feature > envy.
Hmm, I've just done this locally. I've changed the ListToString and MapToString converters back to calling toString. I finally decided to do this, when I noticed exceptions in a test run; they didn't fail the test, as the code just ended up falling back into ObjectType, but it didn't sit well with me. I still need to do a JSONString->Foo converter, but at least I'm happy with this, and it's what you suggested. Currently, I have 15 separate patches queued, mostly all going to the conversion system, almost all ready to go, implementing what we have discussesd the pass 2 days. All while maintaining 13 other patches from the commons-vfs/cow stuff, that I am importing from webslinger.