List for Users of Carlsbad Cubes' Technologies and Products
Mon, 10 Oct 2005 22:21:45 -0700
Here's a diff on my quick hack in Parser.java that does the trick for
me, at least:
685,690d682
< // Begin BF
< String key = attr.getValue();
< String value = getChainedLocalizer().getString(key);
< if (!key.equals(value))
< attr.setValue(value);
< // End BF
974,1120d965
<
< private ChainedProperties getChainedLocalizer()
< {
< if (chainedLocalizer == null)
< chainedLocalizer
< = ChainedProperties.createInstance(engine.getLocalizer());
< return chainedLocalizer;
< }
< private ChainedProperties chainedLocalizer;
< }
<
<
<
<
<
< /**
< * Released under the terms of the above license...
< *
< * Utility for chaining property values. For example, if a
< * properties file contains
< * <pre>
< * font.general = SansSerif--12
< * menu.font = @font.general
< * </pre>
< * then looking up <code>menu.font</code> gives you
< * "SansSerif--12".
< *
< * @author Babak Farhang
< */
< abstract class ChainedProperties {
<
< private final String prefix;
<
< protected ChainedProperties(String prefix) {
< if (prefix == null)
< throw new IllegalArgumentException("Null prefix");
< this.prefix = prefix;
< }
<
< public final String getString(String key) {
< if (key == null)
< throw new IllegalArgumentException("Null key");
< return getStringImpl(key, 0);
< }
<
< private String getStringImpl(String key, int depth)
< {
< if (depth > 64)
< throw new IllegalStateException("Indirection overflow.
key: " + key);
< final String tkey = translateKey(key);
< if (tkey == null)
< return key;
< final String value = findValue(tkey);
< if (value == null)
< return key;
< return getStringImpl(value, depth + 1);
< }
<
< private String translateKey(String key) {
< return key.startsWith(prefix) ? key.substring(prefix.length()) : null;
< }
<
< protected abstract String findValue(String key);
<
<
< private static class ResourceBundleImpl extends ChainedProperties
< {
< private final ResourceBundle bundle;
<
< ResourceBundleImpl(ResourceBundle bundle, String prefix) {
< super(prefix);
< this.bundle = bundle;
< }
<
< protected String findValue(String key) {
< return bundle.getString(key);
< }
< }
<
<
< private static class PropertiesImpl extends ChainedProperties
< {
< private final Properties properties;
<
< PropertiesImpl(Properties properties, String prefix) {
< super(prefix);
< this.properties = properties;
< }
<
< protected String findValue(String key) {
< return properties.getProperty(key);
< }
<
< }
<
<
< private static class LocalizerImpl extends ChainedProperties
< {
< private final Localizer localizer;
<
< LocalizerImpl(Localizer localizer, String prefix) {
< super(prefix);
< this.localizer = localizer;
< }
<
< protected String findValue(String key) {
< return localizer.getString(key);
< }
<
< }
<
<
<
< public static ChainedProperties createInstance(Properties properties) {
< return createInstance(properties, "@");
< }
<
< public static ChainedProperties createInstance(Properties properties,
< String prefix)
< {
< return new PropertiesImpl(properties, prefix);
< }
<
<
<
< public static ChainedProperties createInstance(ResourceBundle bundle) {
< return createInstance(bundle, "@");
< }
<
< public static ChainedProperties createInstance(ResourceBundle bundle,
< String prefix)
< {
< return new ResourceBundleImpl(bundle, prefix);
< }
<
<
<
< public static ChainedProperties createInstance(Localizer localizer) {
< return createInstance(localizer, "@");
< }
<
< public static ChainedProperties createInstance(Localizer localizer,
< String prefix)
< {
< return new LocalizerImpl(localizer, prefix);
< }
<
Actually, the above does a little more. (See the "javadoc" comment.)
I suggest that the Localizer should not be a parameter of Converter.convert().
By the time Converter.convert(Class type, Attribute attr) would be
called, any kind
of localization / indirection will have already taken place in the Parser.
That would be better separation of concerns for the Converter implementations...
Regards,
-b.
On 10/10/05, List for Users of Carlsbad Cubes' Technologies and
Products <Forum@carlsbadcubes.com> wrote:
> Hi all,
>
> This does sound as a not bad idea to me.
> The main reason is that it makes localization (or more generally
> indirection) explicit.
> Indeed, looking at the following snippet you can't really say whether
> "ok" is a text or a key in the localization file.
> ...
> <button text="ok" />
> ..
> while this is selfexplained
> <button text="@ok" />
>
> Second, this approach makes it very easy to write some automated tool
> to check whether every key in swixml descriptor has corresponding
> entry in localization file.
> This could be an issue while refactoring large applications.
>
> Thanks,
> Vitali
>
>
> 2005/9/26, List for Users of Carlsbad Cubes' Technologies and Products
> <Forum@carlsbadcubes.com>:
> > Hi there,
> >
> > I'm a new SwixML user and would like to submit
> > a proposal.
> >
> > The Need:
> > ========
> >
> > Looking at how the StringConverter classes localizes
> > attribute values using essentially a properties file, it
> > seems to me it would be useful if we could extend this
> > model so that *all* attribute values could be indirected,
> > when necessary.
> >
> > In the following snippet ...
> >
> > <frame name="mainframe"
> > size="640,480"
> > title="S W I X M L"
> > defaultCloseOperation="JFrame.EXIT_ON_CLOSE"
> > defaultLookAndFeelDecorated="true"
> > bundle="ui.locale.swix">
> >
> > <menubar name="menubar">
> > <menu name="filemenu" text="mus_File" font="SansSerif--12">
> > <menuitem name="mi_new"
> > text="mus_New" font="SansSerif--12"
> > icon="ui/icons/new.gif"
> > mnemonic="VK_N"
> > accelerator="control N"
> > action="newAction" />
> >
> > ...the font attribute assignment (font="SansSerif--12")
> > will likely be sprinkled liberally elsewhere across the
> > file. If I change that font value in one place, I will
> > likely need to change the other font values elsewhere
> > in the file, also. So you can see a basic need for
> > indirection: I need a central place to be able to assign
> > font values to a whole bunch of components.
> >
> > Besides fonts, other component attributes might need
> > to be centralized in one place (e.g. the background
> > color).
> >
> > The Problem:
> > ==========
> >
> > I *could* try...
> >
> > <frame name="mainframe"
> > size="640,480"
> > title="S W I X M L"
> > defaultCloseOperation="JFrame.EXIT_ON_CLOSE"
> > defaultLookAndFeelDecorated="true"
> > bundle="ui.locale.swix">
> >
> > <menubar name="menubar">
> > <menu name="filemenu" text="mus_File" font="menu.font">
> > <menuitem name="mi_new"
> > text="mus_New" font="menu.font"
> > icon="ui/icons/new.gif"
> > mnemonic="VK_N"
> > accelerator="control N"
> > action="newAction" />
> >
> > ...with...
> >
> > menu.font = SansSerif--12
> >
> > ...defined in the swix.properties file.
> >
> > This wont work of course, because only StringConverter
> > applies the PropertyResourceBundle to the parsed attribute
> > values.
> >
> >
> > Proposal:
> > =======
> >
> > If an attribute value starts with an escape character, say '@'
> > (perhaps with '@@' escaping itself), then the *parser*--not the
> > converter, attempts to "localize" the XML attribute value before
> > passing it off to the converter.
> >
> > Alternatively, we could forget about the special escape character
> > and attempt to "localize" all attribute values, willy nilly. Personally,
> > I'm not for this: it would be better to make the indirection more
> > explicit: right now, in order to see if a string is localized, you have
> > to check the properties file; you can't tell just from looking at the
> > XML.
> >
> > What do you think?
> >
> > -Babak
> >
> > _______________________________________________
> > Forum mailing list
> > Forum@carlsbadcubes.com
> > http://carlsbadcubes.com/mailman/listinfo/forum_carlsbadcubes.com
> >
>
> _______________________________________________
> Forum mailing list
> Forum@carlsbadcubes.com
> http://carlsbadcubes.com/mailman/listinfo/forum_carlsbadcubes.com
>
_______________________________________________
Forum mailing list
Forum@carlsbadcubes.com
http://carlsbadcubes.com/mailman/listinfo/forum_carlsbadcubes.com