jsr341-experts@el-spec.java.net

[jsr341-experts] Re: Bean names with namespace

From: Pete Muir <pmuir_at_redhat.com>
Date: Fri, 12 Aug 2011 18:29:56 +0100

Sorry for the late reply.

On 9 Aug 2011, at 21:25, Kin-man Chung wrote:

> On 08/09/11 12:03, Pete Muir wrote:
>> On 9 Aug 2011, at 18:02, Kin-man Chung wrote:
>>
>>
>>> I recall that it is a CDI requirement that bean names can have namespaces, such as "org.goofy.configs". Pete, is this still the case?
>>>
>> Yes. This is in the CDI spec, so can't be removed right away, we need to support this for at least the next revision.
>>
>>
> I am curious about how it got in the CDI spec in the first place? It is just a little strange that CDI can write into its spec about some functionalities in another spec that is currently not supported, to say the least.

Sure. CDI doesn't require UEL to support namespaced beans generally, however it does require that:

* CDI beans can have names which include namespaces as above
* CDI beans with names are resolvable by UEL

So I don't *think* CDI is specifying a UEL feature, but simply specifying it's own features and integrations.

>
>>> Are there any other things that EL needs to do, other than the ability to parse and evaluates it?
>>>
>> No.
>>
>>
>>> Since names that contains a "." creates ambiguities are parse time, we'll need to resolve it. I propose that we introduce another syntax notation for it, like what we did for static fields. For instance, we can write
>>>
>>> #{N(org.goofy.configs).memSize}.
>>>
>>> to denote the bean org.goofy.configs with the property memSize. What do you think?
>>>
>> This wouldn't work for CDI due to backwards compatibility.
>>
>>
> What backwards compatibility? It is not working currently! Did you really got it to work with EL 2.2? How?

Yes it works with UEL 2.2. As we know at deployment time all the bean names, including namespaces, we can create synthetic objects for each node in the namespace hierarchy needed. For example we would create an "org" object, with a "goofy" child object (and perhaps a "jboss" child object were org.jboss.plmuir.Foo a bean we have as well). When "org" is passed to our namespace EL resolver, we return this org synthetic object. This is then passed in as the base when "goofy" is the property to resolve, and we return the Goofy object (and so on). If we don't have a namespace object, of course we return null.

Then, in our bean resolver, if the base is a namespace object, we can cast to it, and simply call a method on it to retrieve the fully-qualified namespace, concatenate the current property name, and do a bean lookup.

>
> What I like about the N() notation is that it is easy on the parser as well as on the user. It provides a visual indication about what the expression does. In general, it is just not a good language design to contain ambiguities that cannot be easily resolved.

Understood.

>
>> Instead (or as well?), could we offer a registerNamespace() method (similar to how we are handling imports)? Then EL will have a static list of namespaces that an (optional?) namespace resolver could resolve against before other resolvers are used. CDI knows namespaces at startup so could register all it needs.
>>
>> WDYT?
> If we have to support it without any syntax aid, we'll need to have something like registerNamespace(). I am not sure how and when the information can be best used. Ideally, we'd like to be able to recognize the namespaces early, at parse time, so that we don't need to change how it works at evaluation, so ELResolvers may not be the right solution. Even at the parse time, it'll require either a deep look-ahead or backtracking. Also, a simple typo can produce errors that are hard to track down.
>
> Can CDI deprecate the current namespace support in favor of the N() notation?

Yes, I can make it "optional" in 1.1 I guess, introduce the N() notation and then we can remove it in CDI 1.1+1.

I'm not wedded to the syntax, just looking for the best solution all around.

> Can CDI implementation provides a tools to turn #{org.goofy.configs.memSize} into #{N(org.goofy.configs).memSize}?

I guess, because we know the namespaces up front, we can simply check if org.goofy.configs is a registered namespace, and if it is, rewrite the EL expression. Does that sound reasonable?