Joerg Heinicke pisze:

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.

It will be bean's ID pointing that this particular bean implements "short" variant. We use powerful Spring configurator[1] stuff for doing the trick, see this[2] for an example:
  <bean id="org.apache.cocoon.components.expression.ExpressionFactory"
        
class="org.apache.cocoon.components.expression.DefaultExpressionFactory">
    <property name="expressionCompilers">
      <configurator:bean-map 
type="org.apache.cocoon.components.expression.ExpressionCompiler"/>
    </property>
  </bean>

The expressionCompilers property is a Map.

Yes, there is still a registry but neither EL user nor EL implementation must 
care about it.


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.

The ${} and #{} will be simplified. Could you elaborate on the "impedance mismatch"? I would like to see concrete examples to know what you mean. I'm curious because I used to really like JXPath.

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 :-)

LOL ;-)
At least I understand you, now :-)

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.

Count me in, I agree too.

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.

+1

"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.

Yes, we don't want converter narrowed to Forms processing only.

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.

Now I get your point, and understand your arguments. However, as we seen already Daniel proposed very neat solution. To elaborate a little I guess there are two cases when data is returned to the server:
1. Forms submission
2. Ajax/Rest/Other client that is capable to much more than just present HTML 
nicely

In first case we could encode needed information in parameter's name (if browsers can handle it). When it comes to second case, you are more free to choose data representation and you can always annotate data with meta-information rich enough to direct server how to interpret it.

As for now I much prefer such solution because playing with registries keeping PropertyEditors attached to some paths is not the most elegant solution, IMHO.

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. :-)

This mail helped a lot not only to understand your stand but to bring issues 
that I have not been thinking about before.

Thanks! I hope we can continue to discuss.

[1] http://cocoon.zones.apache.org/daisy/cdocs-spring-configurator/g1/1304.html
[2] http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/resources/META-INF/cocoon/spring/DefaultExpressionFactory.xml?view=markup

--
Grzegorz Kossakowski
http://reflectingonthevicissitudes.wordpress.com/

Reply via email to