cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joerg Heinicke <joerg.heini...@gmx.de>
Subject Re: Clarification on converter concept
Date Sat, 07 Jul 2007 05:31:44 GMT
On 05.07.2007 00:47, Grzegorz Kossakowski wrote:

> As Daniel pointed out, it has been discussed but I must admit I'm not 
> completely sure that I "feel" the concept.

I like Daniel's post [1] a lot. It goes very much into the direction of 
PropertyEditors. Quoting him:

"As a solution to the problem he sugests MVCR
(Model-View-Controller-Renderer), where the renderer is responsible for
converting (Java) data types to displayable strings. The renderer can be
responsible for localization of numbers etc as well. The renderer is an
extra step between model and view."

The renderer applies very much to the original idea of PropertyEditor. 
"Displayable" in the GUI programming might be a bit more complex. That's 
why there is a method getCustomEditor() returning a java.awt.Component 
for example. For web programming to and from string conversion should be 
sufficient.

"The simplest possible renderer is to just implement toString() in the
classes one is going to access in the view. But a better SoC is to have
a separate rendering component. In this case the object from the model
is first accessed by an expression in a suitable expression language and
then the object is rendered to a displayable string by the rendering
component and at last the displayable string is emited by the template
engine."

The externalized toString() describes quite perfectly what 
PropertyEditor actually does.

How does it work (pseudo code and simplified):

BeanWrapper wrappedOM = new BeanWrapper(objectModel);
String displayString = wrappedOM.getProperty(aPath);

Internally BeanWrapper does:
Object value = getPropertyValue(objectModel, aPath);
Class valueType = getPropertyType(objectModel, aPath);
PropertyEditor editor = 
PropertyEditorRegistry.findCustomEditor(valueType, aPath);
editor.setValue(value);
return editor.getAsText();

> From purist's point of view it is really _bad_ idea to use interfaces 
> and classes for something that they were not invented for.

See above, it's not that far away. Unfortunately, Java started with GUI 
programming before it founds its niche, the web programming. That's what 
you still can find on this interface.

> To be honest I'm not Spring specialist so I do not understand which 
> infrastructure exactly and how it helps. Even more confusing is that 
> something is going to be replaced by something else. I really don't know 
> what replaces what and what's for. Sorry.

I feared that my first collection of thoughts was too confusing. Will 
focus on the important stuff now.

> Do you want to state that you can define only one Converter for Foo 
> class? Or do you want to say that in Spring MVC you can register 
> converter for Foo class that is available by using particular epxression 
> (like xyz/bar/foo)?

The latter. If xyz/bar/foo would not be of type Foo it would not match.

> What do you mean by registering? The idea for converters is that you 
> just create a bean (that implements necessary interface) and you are done.

Where does the template know from which converter to apply? For the 
example ${myobj.startDate#short} "short" must actually be defined and 
registered somewhere, doesn't it? How did you say: "short date (whatever 
it means)" :-) That's defined by a particular converter which can be 
looked up by the template in the registry.

>> I always found the JEXL/JXPath syntax rather counterintuitive.
> 
> What was counter-intuitive apart from switching between both that I do 
> not like either?

The ${} and #{}, the impedance mismatch between objects and xml model: 
JXPath on beans does not behave like on xml.

> How Spring syntax looks like and how it is better than JXPath/JEXL?

Bean property syntax which as used in other template languages like 
Velocity and scripting languages as well: object1.object2.property.

>> 3. Locale. PropertyEditors have no support for i18n/l10n. [..]
>> I had a look at Spring's CustomDateEditor [9]. It's set up with a
>> DateFormat. Since PropertyEditors should be prototypes anyway I
>> don't see a problem to inject the Locale into the editor on
>> registration as done via DateFormat for the CustomDateEditor.
>> That works without the PropertyEditors being locale-aware.
> 
> It all looks like plumbing and is counter-intuitive for my taste. It may 
> be that I miss the idea totally. If you could explain it and say way 
> such solution is better than proposed one it would be very helpful.

Ok, recently somebody posted the SimpleFormController Lifecycle Cheat 
Sheet[2] in the Spring forum, which shows the request processing in the 
controller. Don't try to understand it, I just want to show where we 
are. One of the first things in the request processing is initBinder 
which actually takes the request as parameter. That means you can 
determine the locale in that method. You are supposed to register your 
PropertyEditors in this method:

Binder.registerCustomEditor(Class, ProperyEditor);

So for the date converter:

Locale locale = // determine from request
DateFormat dateFormat = DateFormat.getDateInstance(SHORT, locale)
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, 
..));

So it's not the PropertyEditor being locale-aware but the PropertyEditor 
instantiation. It creates the proper (= correct locale) PropertyEditor.

But yes, I don't like it that much anyway. Actually I used it very 
rarely in my project. There is a much better way to do this than those 
scattering the PropertyEditors all over the place. So you might drop 
that complete section from mind :-)

Now the better approach while answering Daniel's mail:

On 05.07.2007 14:24, Daniel Fagerstrom wrote:

> Locale awareness is part of the idea.

Yes, of course. Somehow it has to come into play. But you see above that 
it is at least possible with locale-unaware converters.

> Architecture
> ============
> 
> The "converter architecture" as I imagine it consist of three parts.
> 
> * Converters:
> * Converter registry:
> * Integration:

I agree completely. It's only about the details. The only difference I 
see actually is on which parameters the converter is chosen.

> Converters
> ----------

> IMO it would be cleaner to have the locale dependency in the registry
> instead of in the converter.

I agree. This means locale is removed from the converter methods.

> Next the convertor needs a format cache, this is IIRC because date and
> number formating objects not are thread safe and takes some work to construct.

They are not [3]:

"Date formats are not synchronized. It is recommended to create separate 
format instances for each thread. If multiple threads access a format 
concurrently, it must be synchronized externally."

Same for NumberFormat and probably others as well. So no advantage over 
PropertyEditors which suffer from the same problem. I don't think we 
need a "real" format cache, it only seems to complicate stuff. The 
proposed ThreadLocal might be a solution. Spring holds them on the 
binder where they get registered once. Might be limiting since it's 
targetted to form processing obviously.

> Last the convertFromString returns a ConversionResult while setAsText
> throws a IllegalArgumentException for badly formated input strings.

BeanWrapper does that part (mapping IllegalArgumentException to 
something "controllable", similar as you work with ConversionResult).

> As a conclusion I think that PropertyEditors would work fine for us if
> we find it worthwhile.

Fine. I do :-)

> Converter Registry
> ----------

> For a Cocoon framework I would prefer looking up a converter based on
> class, locale and variant, while I don't see any obvious use cases for
> property path.

Indeed the PropertyEditorRegistry seems not to meet our requirements.

(copied from further above, better fits in here)
> The framework select based on data type and locale. But for e.g. dates
> there are several different string representations (short, medium, full
> and long or maybe some custom format) that the template or form author
> needs to choose between. To me it seem reasonable to have a syntax for
> making this possible in e.g. the template.

As I wrote repeatedly the possibility to influence the formatting from 
the template breaks the two-way process. You can't parse a date 
expecting a FULL pattern string when receiving a string formatted with 
SHORT pattern. And there is no chance to get informed about this mismatch.

The property path could be used to determine the variant instead of 
specifying it explicitly. It's obviously not that flexible - but can't 
be broken in that way. That's why I would opt for class, locale and 
path, so add locale to Spring's PropertyEditorRegistry methods.

> So as a conclusion: it would be nice to reuse the Spring stuff and
> there are big overlaps, but especially for locale handling it is not
> obvious to me how to use it. Then of course there is the question if
> it is worthwhile to reuse.

The concepts seem to be totally equal. We only extend the registry with 
the locale. Then I mentioned a new way of registering PropertyEditors, 
the PropertyEditorRegistrar. That's actually a PropertyEditor factory 
which also does the registering shown above when talking about the 
initBinder() method. It is possible to set up such a registrar once (!) 
in the application context and reuse it in the application context 
itself (e.g. for custom data types) or in the controllers. The point I 
want to make is the following: This PropertyEditorRegistrar is in 
contrary to initBinder() not even request-aware and so not locale-aware 
at all. So I wonder how it is supposed to be done in Spring now. Maybe 
filing an issue for an extension of the registry brings this into 2.1 
and we do not have to invent anything new. And even if not there is 
still so much to reuse and it's IMO absolutely worthwile to do it.

I hope, I did not write too much non-sense in my hurry. Have to get to 
the plane to the US (finally!) soon. Maybe I could even clarify a bit of 
the confusion I caused with the last mail. :-)

Regards,
Joerg

[1] http://article.gmane.org/gmane.text.xml.cocoon.devel/42968
[2] 
http://home.exetel.com.au/cweatures/dev/SimpleFormControllerCheatSheet.pdf
[3] http://java.sun.com/j2se/1.4.2/docs/api/java/text/DateFormat.html

Mime
View raw message