|
From: <jue...@we...> - 2003-03-17 11:18:40
|
Tony,
Let me move this discussion to the developer list.
I consider "getControlledBy()" a method of a MessageSourceResolvable =
implementation, not of the interface itself. I simply don't see a reason =
for it needing to be in the interface. The toString() method is an =
implementation detail, not to be respected in the interface. A concrete =
MessageSourceResolvable can add any internal properties that it likes =
to, or be implemented as inner class to have access to the state of the =
surrounding "controlling" class.
Furthermore, your MessageSourceResolvableImpl.toString() implementation =
tries to actually resolve the message. IMO it shouldn't: =
MessageSourceResolvable(Impl) is a message specification, a parameter =
object used in the MessageSource interface. It shouldn't in turn know =
about the MessageSource interface, this creates an unnecessary two-way =
association. For use within the framework and especially within the =
validation package, a parameter object with a simple toString() is =
perfectly sufficient.
Concerning the locale property in the resolvable, I don't think that =
this does make sense. The locale is an attribute used at message =
resolution time, not at message creation time, at least not in the 99% =
normal case. Introducing double support here by giving =
MessageSourceResolvable a locale attribute is confusing and inconsistent =
with locale handling in the rest of the framework. I plead for one =
straightforward approach.
I'm aware that "getMessage(MessageSourceResolvable)" is in the =
MessageSource interface. It's just that this overloaded version is not =
necessary once that MessageSourceResolvable does not support a locale =
property anymore. I've also adapted the parameter order in the other =
getMessage versions, i.e. moved the locale to the end, to reflect the =
special role of the locale.
I consider the above mentioned simplifications necessary for keeping the =
framework clear and straightforward. We can add extra sophistication in =
the form of specialized subclasses in the future - if we ever need it. =
Thus, I've already applied the simplifications, including some according =
parameter renaming (no "error" names in the message source core) and =
slight refinement of the validation API (adding support for error =
arguments to the reject methods).
I will check this stuff in soon, together with the mock object moving =
and the minor new features described in a previous mail - if you haven't =
any strong objections.
Regards,
Juergen
-----Original Message-----
From: Tony Falabella [mailto:ton...@ya...]=20
Sent: Monday, March 17, 2003 12:15 AM
To: j=FCrgen h=F6ller [werk3AT]; rod...@in...
Subject: Re: ErrorCoded stuff ready for integration
Juergen,=20
In response to your questions:=20
-- What does "getControlledBy()" return? It returns an object, that =
being the object that it the "parent" or "owner" of this =
MessageSourceResolvable. This is a handle back to an object that might =
have a MsgSourceResolvable as an internal attribute. It allows the =
MsgSourceResolvable to make calls back to the parent if need be. Right =
now, you will see in the MessageSourceResolvableImpl that the toString() =
method uses this. =20
-- I'm not sure why the resolvable contains a locale. This may be a bad =
example, but it's what I can come up with right now. Suppose a request =
comes in for Locale A that contains an eror and we don't want to resolve =
it right now. Let's say we store it in the database. Suppose later on =
we want to then reconstitue it to merely log the error to a file (thus =
no "HTTPRequest" was received for this to happen). Storing the locale =
with the object allows us to do this. =20
-- Remove the "getMessage(MessageSourceResolvable)" method. Actually =
this is on the MessageSource interface, not on the =
MessageSourceResolvable interface. Similarly to being able to resolve a =
message from a MessageSource via getMessage(errorCode, errorArgs, =
locale, defaultMessage) why not allow the caller to just pass in a =
MessageSourceResolvable? They could do this by newing one themselves - =
an unlikely use of it, or by passing in one they already have a handle =
to - see examples in the code that already do this. Remember, a =
MessageSourceResolvable basically is just the 4 attributes you are =
passing into the "getMessage(errorCode, errorArgs, locale, =
defaultMessage)" method anyway. Let the caller decide what method is =
easier for them to call.
-----Original Message-----
From: Tony Falabella [mailto:ton...@ya...]=20
Sent: Sunday, March 16, 2003 11:38 PM
To: spr...@li...
Subject: [Springframework-developer] ErrorCoded changes integrated
I have just integrated a lot of changes to accomplish 2 main goals:
1) To resolve messages from a MessageSource (ResourceBundle) using a =
"code"+locale
as the key that message.
2) To allow messages being resolved to take arguments in and have them =
be substituted
in the message returned.
I'll start with the high level description of what I've done. First, I =
changed the
MessageSource interface to have the following API:
String getMessage(MessageSourceResolvable resolvable) throws =
NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale =
locale) throws NoSuchMessageException;
String getMessage(String code, Locale locale, Object args[]) =
throws NoSuchMessageException;
String getMessage(String code, Locale locale, Object args[], =
String defaultMessage);
You'll notice 2 new overloads that take in a "MessageSourceResolvable". =
This is a new
interface I've introduced and it has this API:
public Object getControlledBy();
public String getDefaultMessage();
public Object[] getErrorArgs();
public String getErrorCode();
public Locale getLocale();
Basically, the thought is anyone that wishes to have something resolve =
it's messages from a MessageSource
need only implement this interface and the MessageSource will know how =
to return the message.
Notice that there are no setters on this interface - thus from the point =
of view of
a method receiving a MessageSourceResolvable object it is immutable. =20
Generally anyone implementing this interface will provide appropriate =
constructors taking in similar arguments. =20
The "MessageSourceResolvableImpl" class is a default implementation of =
this interface with the=20
appropriate constructors and a good toString() method for showing the =
internal state.
Also notice the "getMessage(MessageSourceResolvable resolvable, Locale =
locale)" overload.
Since a MessageSourceResolvable is immutable it's values will generally =
be set only during
it's construction. It is quite possible that the =
MessageSourceResolvable might be
created during one HTTPRequest. The message to be displayed to the user =
might not occur
until another HTTPRequest arrives. Since the Spring Framework =
accommodates being able to
change the Locale on a HTTPRequest level, you need the ability to pass =
in a locale to the=20
getMessage(...) method. This version of the method will use the locale =
arg passed in rather
than any locale attribute value that may have already been stored on the =
immutable MessageSourceResolvable.
for message resolution.
Also, a convience class named com.interface21.util.ObjectArrayUtils was =
introduced. This is
a static helper class that aids you in converting scalars into Object =
arrays. Perhaps useful
in the creation of the "Object[] args" parameter.
|