You are viewing a plain text version of this content. The canonical link for it is here.
Posted to taglibs-dev@jakarta.apache.org by Stu Robertson <sr...@nvisia.com> on 2005/07/20 16:02:39 UTC

[RDC] Multi-lingual support in RDCs: resource bundle usage for app-specific configs?

First, thanks for such detailed responses.  Much appreciated.

As we plan for the RDC portion of our application infrastructure, I  
_think_ a couple of things in the current RDC implementation are  
going to cause us problems.  One is an inconsistency in RDC design,  
the other is an assumption that I don't think is valid.  NOTE: this  
isn't intended as criticism, and I think there are resolutions to  
both.  Normal stuff for evolving libraries, right?

First the inconsistency.  I've looked over the i18n support in the  
codebase.  I see how it supports using resource bundles to vary the  
defaultConfig according to the locale, where each RDC tag file  
references it's defaultConfig via a key into a resource bundle.   
That's fine.  But when it comes to app-supplied grammars, the config  
is not a key into a resource bundle, but rather interpreted as a uri  
for the config itself.  So if I understand correctly, default configs  
can support i18n, but app-specific configs do not.  Bummer, since  
almost no real world applications will actually use the default  
configs.  Further, as implemented, since the config for a tag  
instance is cached after being used, it isn't possible to get around  
this by varying the value of the config attribute, since the first  
value seen will have been cached, so it won't be loaded again.  Does  
this mean that the RDCs can't support i18n for app-specific configs  
without modifying each of the RDC tag files to perform a message  
bundle lookup on the config value to get the URI rather than using  
the config value as the URI itself?  I suggest this will be the  
normal requirement for RDC end-user apps requiring i18n support.

If so, the most obvious way to deal with this would be to have RDCs  
consider the config value to be an app-specific key into a resource  
bundle, (which would live in the classpath of the application), and  
lookup the URI of the actual config in the same manner as the RDCs  
lookup default grammars.  This is not unusual in the java web  
development: it will be very familiar to developers using most web  
frameworks, where keys for errors and other messages are typically  
keys into resource bundles.

The second issue is with the assumption that for a particular  
instance of an RDC, there would only need to be one config parsed.   
This is fine if configs vary only by i18n (why would a user start in  
spanish, then switch to english - good point).  But the implicit  
assumption is that there is no _other_ reason that a config might  
vary for a particular tag instance.  This assumption is built into  
the implementation of every current RDC, meaning that an application  
needing different behavior has to rewrite significant portions of the  
RDC implementation.  Here's the specific example I'm talking about,  
which I don't think is unrealistic.  In fact, it's one of our  
application requirements.

In addition to internationalization, we need to support voice input  
with the option of falling back to pure DTMF input.  So for example,  
if a user seems to be having trouble with voice input, or if they  
request to switch into DTMF only (by pressing * for example, because  
they have background noise, are from the bayou, etc) we disable voice  
input and provide prompts for DTMF only.  In most cases this is as  
simple as changing the prompts (config), though in cases where alpha  
input is required, it's obviously more complex.  The issue is, the  
same RDC instances will have different config values within a single  
user's session.  Currently the RDCs can't support this.

If I understand this limitation correctly, the problem is that the  
parsed config is stored in the stateMap by 'id' only.  This is where  
the assumption that the config will only have one value is tied into  
the implementation.  If instead it were stored in the stateMap under  
the key 'id + config' this would not be a problem.  The same RDCs  
would now support varying the prompts for whatever application- 
specific needs, like in our example.

Combined with the fix for i18n, this would allow the RDCs to be used  
in more real-world applications than the current implementation allows.

I'm looking forward to feedback on this.  I can take a stab at the  
changes, but want to make sure that 1) I understand things correctly  
and 2) any changes made are ones that we want to see in the RDCs at  
large.  If #1 is the case I'll have to make these changes regardless,  
but would prefer that the work not be duplicated, by me or anyone else.

Stu

On Jul 19, 2005, at 12:03 AM, Rahul P Akolkar wrote:

> On 7/18/05, Stu Robertson <sr...@nvisia.com> wrote:
>
>> The patch for unit testing voiceXML apps was just accepted to  
>> htmlunit.
>>
> <snip/>
>
> Yup, saw the blanket application/*+xml. Thanks.
>
>
>> Regarding my validation issue, you're right -- I can get what I  
>> need by
>> setting size=7 for min and max and making the messages the same in  
>> the
>> config.  And actually that is acceptable for me.  It would be nice if
>> there were a separate validation for exact size so that the default
>> error message would be more appropriate, but that's a pretty fine  
>> point.
>> Doing it at the grammar would be tricky because grammars are static
>> resources in the jars, right?  I wasn't thinking of that, though it's
>> interesting.  How would that impact error messages?  Would that  
>> mean the
>> interpreter would generate a no-match event if the input were the  
>> wrong
>> size?  If so, I don't like that because it wouldn't give a very
>> meaningful message (speaking name and giving 6 digits would give same
>> error msg).  Having the RDC generate the message seems like the most
>> flexible and user-friendly approach.
>>
> <snap/>
>
> A colleague of mine, Jeff Kusnitz, was of the opinion that the  
> grammars be
> constrained based on instance data. You're right that would probably
> produce more nomatch'es. You're also right that the static grammar  
> will
> need to be replaced (more below on your question about dynamic  
> grammars).
> Its more work for the RDC author; I personally do not have a  
> preference on
> this one -- its upto the RDC author.
>
>
>>
>> As for the property files for specifying grammars, I noticed those  
>> went
>> in a while ago, but haven't taken a look.  Do I need to change  
>> them in
>> the rdc source, or is there something I can do in app-space to  
>> make the
>> new grammars active for a locale?
>>
> <snip/>
>
> You don't need to go to the source in the sense of re-building the
> sources, but you will need to edit the properties file for the locales
> that exist in the distro (currently, thats US English). The properties
> files for the other locales can just be dropped in WEB-INF/classes.
>
>
>> We'll be doing a multi-lingual app,
>> so the locale-per-app granularity is what we're looking for.  I'll  
>> read
>> through your comments more carefully a bit later when we get to this
>> stage.  It sounds like overriding these on a per-locale basis is
>> possible...which was my hope.
>>
> <snap/>
>
> Its possible :-)
>
>
>>
>> Btw, what is a dynamic grammar?
>>
> <snip/>
>
> Sorry, I was probably a little too brief there. A RDC could use a URI
> grammar where the URI points to a JSP/servlet that emits grammar  
> based on
> some request params (which are in turn influenced by the values of  
> the RDC
> tag attributes).
>
>
>> Also, what did you mean by "vary
>> validation rules suitably?"  Did you mean change rdc validation to do
>> things that could also be done in the grammar, as per your example?
>>
> <snap/>
>
> The point there was -- to constrain the input from the user  
> further, one
> can either produce a restricted grammar or introduce more stringent
> validation rules. One can work in the other direction to get a more
> forgiving UI widget. And finally, one can author a RDC where the tag
> attribute values affect the grammars and validation rules so that two
> instances of the same component behave differently (going back to our
> example, the date component may cause the year to be required or  
> optional
> or absent based on a "mode" attribute).
>
>
>>
>> Regarding the possible JSP writer buffering issue during forwards,  
>> would
>> you like me to send you my application offline?  It should be an  
>> ideal
>> testbed since I get it instantly when I stop redirecting.
>>
> <snip/>
>
> The first priority right now is to get the RDC release out, but  
> feel free
> to send me an email with a simple test case attached (and the  
> redirecting
> solution you use). Also attach some patience ;-)
>
> Thanks,
> -Rahul
>

---------------------------------------------------------------------
To unsubscribe, e-mail: taglibs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: taglibs-dev-help@jakarta.apache.org


Re: [RDC] Multi-lingual support in RDCs (correction)

Posted by Stu Robertson <sr...@nvisia.com>.
On Jul 20, 2005, at 9:02 AM, Stu Robertson wrote:
> key into a resource bundle.  That's fine.  But when it comes to app- 
> supplied grammars, the config is not a key into a resource bundle,  
> but rather interpreted as a uri for the config itself.  So if I  
> understand correctly, default configs can support i18n, but app- 
> specific configs do not.  Bummer, since almost no real world  
> applications will actually use the

I meant "app-supplied configs"

---------------------------------------------------------------------
To unsubscribe, e-mail: taglibs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: taglibs-dev-help@jakarta.apache.org


Re: [RDC] Multi-lingual support in RDCs: resource bundle usage for app-specific configs?

Posted by Rahul P Akolkar <ak...@us.ibm.com>.
Stu Robertson <sr...@nvisia.com> wrote on 07/20/2005 10:02:39 AM:
> First, thanks for such detailed responses.  Much appreciated.
<snip/>

You're welcome.
 
> As we plan for the RDC portion of our application infrastructure, I 
> _think_ a couple of things in the current RDC implementation are 
> going to cause us problems.  One is an inconsistency in RDC design, 
> the other is an assumption that I don't think is valid.  NOTE: this 
> isn't intended as criticism, and I think there are resolutions to 
> both.  Normal stuff for evolving libraries, right?
<snap/>

You really don't need that disclaimer ;-) I know you have the right 
intentions; please, feel free to point out as many things as you feel need 
improvement. For now though, I'm not convinced about any urgency on either 
issue. More below.

> 
> First the inconsistency.  I've looked over the i18n support in the 
> codebase.  I see how it supports using resource bundles to vary the 
> defaultConfig according to the locale, where each RDC tag file 
> references it's defaultConfig via a key into a resource bundle. 
> That's fine.  But when it comes to app-supplied grammars, the config 
> is not a key into a resource bundle, but rather interpreted as a uri 
> for the config itself.  So if I understand correctly, default configs 
> can support i18n, but app-specific configs do not.  Bummer, since 
> almost no real world applications will actually use the default 
> configs.  Further, as implemented, since the config for a tag 
> instance is cached after being used, it isn't possible to get around 
> this by varying the value of the config attribute, since the first 
> value seen will have been cached, so it won't be loaded again.  Does 
> this mean that the RDCs can't support i18n for app-specific configs 
> without modifying each of the RDC tag files to perform a message 
> bundle lookup on the config value to get the URI rather than using 
> the config value as the URI itself?  I suggest this will be the 
> normal requirement for RDC end-user apps requiring i18n support.
>
> If so, the most obvious way to deal with this would be to have RDCs 
> consider the config value to be an app-specific key into a resource 
> bundle, (which would live in the classpath of the application), and 
> lookup the URI of the actual config in the same manner as the RDCs 
> lookup default grammars.  This is not unusual in the java web 
> development: it will be very familiar to developers using most web 
> frameworks, where keys for errors and other messages are typically 
> keys into resource bundles.
<snip/>

Think layers. Think taglib as a product consumed by applications (mostly 
the view layer). Think i18n as an "aspect" that spans layers. Just as the 
taglib i18n'zes its resources, any app-specific resources can be i18n'zed 
by the app developers. Indeed, since the taglib knows nothing about 
app-specific resources (how can it?), a taglib might be going out of its 
way (a.k.a code bloat) to accomodate that.

Lets work with concrete examples:

A) <rdc:date id="foo" />

The VUI will be in the default RDC locale (can be set per webapp).

B) <rdc:date id="foo" locale="${userPrefs.locale}" />

The VUI will be in this user's preferred locale, and will use the default 
date config (for that locale).

C) <rdc:date id="foo" config="bestDateVUI.xml" />

If you use an app-specific config like this, it needs to be in the default 
RDC locale (since thats what the xml:lang is going to say). 

And finally, the one most relevant to this discussion:

D) 
<rdc:date id="foo" locale="${userPrefs.locale}" 
config="${myfns:getConfig('config.uri.date.foo', userPrefs.locale}" />

Not saying you have to use a EL function to get the config URI, but trying 
to illustrate that the config URI might be set previously in the JSP, in a 
preceeding Struts action, or someplace else; based on a resource id and 
the locale for this instance.

Sure, we can imagine this too:

E) <rdc:date id="foo" locale="${userPrefs.locale}" 
configBundle="com.foo.bar.bestvui.configs" configKey="config.uri.date.foo" 
/>

but, IMO, that just puts too much noise in the date tag impl. Moreover, I 
see no urgency go chase this down (option D is quite acceptable to me, and 
is a fairly insignificant bit of work for the app author).

> 
> The second issue is with the assumption that for a particular 
> instance of an RDC, there would only need to be one config parsed. 
> This is fine if configs vary only by i18n (why would a user start in 
> spanish, then switch to english - good point).  But the implicit 
> assumption is that there is no _other_ reason that a config might 
> vary for a particular tag instance.  This assumption is built into 
> the implementation of every current RDC, meaning that an application 
> needing different behavior has to rewrite significant portions of the 
> RDC implementation.  Here's the specific example I'm talking about, 
> which I don't think is unrealistic.  In fact, it's one of our 
> application requirements.
> 
> In addition to internationalization, we need to support voice input 
> with the option of falling back to pure DTMF input.  So for example, 
> if a user seems to be having trouble with voice input, or if they 
> request to switch into DTMF only (by pressing * for example, because 
> they have background noise, are from the bayou, etc) we disable voice 
> input and provide prompts for DTMF only.  In most cases this is as 
> simple as changing the prompts (config), though in cases where alpha 
> input is required, it's obviously more complex.  The issue is, the 
> same RDC instances will have different config values within a single 
> user's session.  Currently the RDCs can't support this.
<snap/>

I've always used voice + DTMF together. Its understandable that DTMF 
usually will be preferred by users in noisy situations, but I've never 
"turned off voice input" (I believe by that you mean disable the voice 
grammar, since if you mute the channel, you won't get DTMF input either, 
and likewise, if the channel is listening, you'll get voice too). Usually, 
the config artifacts will look like:

Initial prompt: Please speak the amount or enter it using the buttons on 
your phone.
And, the third nomatch might be: Enter the amount using the buttons on 
your phone.

The Apache RDC distribution will give you a 80-20 when it comes to 
components. Its real job is to demonstrate the framework. If you want more 
from your components, you can always roll your own variants. Its a cut and 
paste job, grab the bit that initializes the config in the first request 
and paste it after the bit and retrieves the cached data model, 
understanding that there will be a performance penalty.

> 
> If I understand this limitation correctly, the problem is that the 
> parsed config is stored in the stateMap by 'id' only.  This is where 
> the assumption that the config will only have one value is tied into 
> the implementation.  If instead it were stored in the stateMap under 
> the key 'id + config' this would not be a problem.  The same RDCs 
> would now support varying the prompts for whatever application- 
> specific needs, like in our example.
<snip/>

Changing configs has no connection with the stateMap. Those entries need 
to be keyed by RDC ids.

> 
> Combined with the fix for i18n, this would allow the RDCs to be used 
> in more real-world applications than the current implementation allows.
> 
> I'm looking forward to feedback on this.  I can take a stab at the 
> changes, but want to make sure that 1) I understand things correctly 
> and 2) any changes made are ones that we want to see in the RDCs at 
> large.  If #1 is the case I'll have to make these changes regardless, 
> but would prefer that the work not be duplicated, by me or anyone else.
<snap/>

Yes, duplication would be a waste :-) I think the first step here should 
be to author a helper tag (<rdc:fsm-run> is an example of a helper tag 
that most RDCs use in their tag impl) that will do the bit of initializing 
a data model, caching and retrieving it; and hence remove the redundancy 
that currently exists in every component's tag file (credits to my 
colleague, T V Raman, who first pointed this out in one of our 
discussions). If you do that, it will give us a single point in the distro 
where we can make changes such as the two you discuss here. That will give 
you some bang for your buck, and help mitigate the code bloat argument.

-Rahul

> 
> Stu