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/