<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div><div>Hello&nbsp;Rick</div><div><br></div><div>I have this use-case experience.</div><div><br></div><div>I think your suggestion has two problems.</div><div>Message class you suggested isn't immutable. Object is call by reference.</div><div>And Message class must implement Serializable because Exception is serialized in RMI. However Object isn't ensure to implement Serializable.</div><div><br></div><div>I think message need to be build as soon as possible to reduce several problems.</div><div><br></div><div><div>If we want to change Locale of MessageConveyor by request or user,&nbsp;</div><div>we can do it to use dependency injection. It is no need to know Locale.</div><div><br></div></div></div></div><div>Takeshi Kondo</div><div><br><div><div>On 2009/08/29, at 8:22, Rick Beton wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Hi,<br><br>First of all, I'm new to this project and I'd like to congratulate you on putting it together with your typical no-nonsense approach to APIs.&nbsp; Particular praise is worthy for the IMessageConveyor interface hiding the ugliness of ResourceBundle and MessageFormat within a single method with varargs - inspired simplicity!<br> <br>Secondly, I would like to suggest a use-case that your API does not (yet?) cover.&nbsp; Maybe this is an idea you could consider incorporating.<br><br>Within an enterprise application, especially a web-based application for example, resources frequently need to be looked up and corresponding strings returned to the user's display. But I have found that there are times in such applications where I would prefer to defer the choice of locale.&nbsp; For example, I may have some 'library' code not concerned with the UI yet which produces messages that are fed back to the user.&nbsp; These are status messages, error messages etc.&nbsp; The classic way to deal with these is to return separate transfer objects and later construct messages from them, but this can make the parameterisation awkward and adds complexity.&nbsp; Maybe it would be simpler to return the message directly.<br> <br>The problem with the Cal10n API as it stands is that I need to know the locale before I can construct a MessageConveyor.&nbsp; Only then can I call the <span style="font-family: courier new,monospace;">getMessage(E&nbsp;e, Object...&nbsp;args)</span> method to get the string, including its formatted parameters.&nbsp; The problem with web applications is that only the UI tier knows the locale.&nbsp; It is incorrect for other tiers to assume a different locale and unwieldy to pass the correct locale through as a parameter.&nbsp; So it would typically be wrong for the lower tiers to use MessageConveyor.<br> <br>This is a shame and my suggestion is simply that an additional data transfer object is required as part of the Cal10n API to fill the gap. This is essentially a <span style="font-family: courier new,monospace;">Message</span> class containing the enumeration and the args but without the resource bundle/message format lookup having yet been performed.&nbsp; At a later stage, a <span style="font-family: courier new,monospace;"></span><font style="font-family: courier new,monospace;" size="2">getLocalizedMessage</font><font size="2"><span style="font-family: courier new,monospace;">(Locale locale)</span></font> method will yield the required String for a given locale.<br> <br>A desirable characteristic of <span style="font-family: courier new,monospace;">Message</span> is that it be immutable because this would make it safe to hold within Exceptions or to be shared between threads.&nbsp; In other words, it would be better for it not to be a classic mutable JavaBean data transfer object. Therefore it is arguable that a general interface is not needed and a concrete and final <span style="font-family: courier new,monospace;">Message</span> class would be completely sufficient.&nbsp; So here is a possible implementation for <span style="font-family: courier new,monospace;">Message</span>:<br> <br> <span style="font-family: courier new,monospace;">public final class Message {</span><br style="font-family: courier new,monospace;"> <span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; private final Enum&lt;?> e;<br> &nbsp; &nbsp; private final Object[] args;</span><br style="font-family: courier new,monospace;"> <span style="font-family: courier new,monospace;"><br> &nbsp;&nbsp;&nbsp; public Message(Enum&lt;?> e, Object... args) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.e = e;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.args = args;<br> &nbsp;&nbsp;&nbsp; }<br> <br> &nbsp;&nbsp;&nbsp; public String </span><font style="font-family: courier new,monospace;" size="2">getLocalizedMessage(Locale locale) {<br> </font><span style="font-family: courier new,monospace;">&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; final IMessageConveyor mc = new MessageConveyor(locale);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mc.getMessage(e, args);<br> </span><font style="font-family: courier new,monospace;" size="2">&nbsp;&nbsp;&nbsp; }<br> <br> &nbsp;&nbsp;&nbsp; @Override<br> &nbsp;&nbsp;&nbsp; public String toString() {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final StringBuilder b = new StringBuilder("Message(");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b.append(<a href="http://e.name/" target="_blank">e.name</a>());<br></font><font style="font-family: courier new,monospace;" size="2"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b.append(", [");<br> </font><font style="font-family: courier new,monospace;" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (args != null) {<br></font><font style="font-family: courier new,monospace;" size="2"> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String comma = "";<br></font><font style="font-family: courier new,monospace;" size="2"> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font style="font-family: courier new,monospace;" size="2">for (Object o : args) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b.append(comma).append(o);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; comma = ", ";<br></font><font style="font-family: courier new,monospace;" size="2"> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br><font style="font-family: courier new,monospace;" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b.append("])");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return b.toString();<br> &nbsp;&nbsp;&nbsp; }<br> </font><span style="font-family: courier new,monospace;">}</span><br> <br>In use, the 'library' (non-UI) code will have its own resource bundle and corresponding enum. It will create instances of Message to return to the UI tier, where the message string for the appropriate locale can be looked up and then presented to the user.<br> <br>It would be beneficial to override hashcode() and equals() methods appropriately but I haven't included that here. There may also be some performance value in holding transient caches of the toString() result and the hashcode, although I omitted this also.<br> <br> I wish the project success and I look forward to recommending it to my clients when it reaches a sufficient level of maturity.<br> <br>Regards,<br>Rick Beton<br><font color="#888888">-- <br>Big Bee Consultants Limited : Registered in England &amp; Wales No. 6397941<br>Registered Office: 71 The Hundred, Romsey, Hampshire, SO51 8BZ<br></font><br> _______________________________________________<br>cal10n-dev mailing list<br><a href="mailto:cal10n-dev@qos.ch">cal10n-dev@qos.ch</a><br>http://qos.ch/mailman/listinfo/cal10n-dev<br></blockquote></div><br></div></body></html>