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
  • [Forum] XML at... List for Users of Carlsbad Cubes' Technologies and Products
    • Re: [Foru... List for Users of Carlsbad Cubes' Technologies and Products
      • Re: [... List for Users of Carlsbad Cubes' Technologies and Products
    • Re: [Foru... List for Users of Carlsbad Cubes' Technologies and Products
      • Re: [... List for Users of Carlsbad Cubes' Technologies and Products
        • R... List for Users of Carlsbad Cubes' Technologies and Products
          • ... List for Users of Carlsbad Cubes' Technologies and Products
            • ... List for Users of Carlsbad Cubes' Technologies and Products
    • Re: [Foru... List for Users of Carlsbad Cubes' Technologies and Products
      • Re: [... List for Users of Carlsbad Cubes' Technologies and Products

Reply via email to