el-next@uel.java.net

Re: Namespaced bases

From: Kin-man Chung <kinman.chung_at_oracle.com>
Date: Thu, 29 Apr 2010 16:10:55 -0700

On 04/29/10 04:28, Pete Muir wrote:
> On 28 Apr 2010, at 18:40, Kin-man Chung wrote:
>
>
>> Sorry for the late reply. I have more thoughts on this.
>>
> Great :-)
>
>
>> On 04/12/10 03:56, Pete Muir wrote:
>>
>>> On 9 Apr 2010, at 19:11, Kin-man Chung wrote:
>>>
>>>
>>>
>>>> On 04/09/10 06:47, Pete Muir wrote:
>>>>
>>>>
>>>>> The CDI spec calls for namespaced bean names (see section 2.5). It says
>>>>>
>>>>> "A bean may have a bean EL name. A bean with an EL name may be referred to by its name in Unified EL expressions. A valid bean EL name is a period-separated list of valid EL identifiers.
>>>>>
>>>>> The following strings are valid EL names:
>>>>>
>>>>> * org.mydomain.myapp.settings
>>>>> * orderManager"
>>>>>
>>>>>
>>>>>
>>>> Just need to make sure I understand, and showing my ignorance about CDI:
>>>>
>>>> The expression #{org.mydomain.myapp.settings.standard} actually means getting the property "standard" from the bean
>>>>
>>>> org.mydomain.myapp.settings, right?
>>>>
>>>>
>>> Exactly.
>>>
>>>
>>>
>>>> How can this work with the current EL? Wouldn't the expression be parsed as getting the bean "org" and then get its property "mydomain", and then its property "myapp" etc?
>>>>
>>>>
>>> We know up front (at deployment time) all bean names (and their namespaces) in a CDI module. Before checking if the property matches a bean, we check if the property matches the root of a namespace (and the base is null). If it does we return a Namespace object, otherwise we try to return the bean or say we can't resolve anything.
>>>
>>>
>> So the root of a namespace takes precedence over a bean name? Would it be OK if we check a match for a bean first?
>>
> The only thing to be aware of here, is that beans can end up hiding namespaces. Using CDI beans as an example:
>
> @Named("com") class ComBean {}
>
> @Named("com.acme.roadRunner") class RoadRunnerBean { public String getName() {...} }
>
> if you had an expression like #{com.acme.roadRunner.name}, then it would end up trying to resolve the ComBean:getAcme() -> getRoadRunner() -> getName() which isn't what you intended...
>
> NB in the CDI case, we also validate at startup that no bean names collide, and that bean names don't collide with namespace sections, so we never have a problem where a bean name can "hide" a namespace whichever way around we do the namespace resolution.
>
>
I think it's OK for beans to hide namesapces, as long as this is stated
clearly in the spec. This would make it easier to recognize namespaces,
when we don't know all nemaspces up front.

>> If we do that, then even if we don't know all the namespaces up front, if it is not a bean, we'll return a Nanmspace object, meaning that it may be the root of a namspace. When we have all the pieces of the namespace at the end, we can check for its existence.
>>
> Yes, this works.
>
>
>>> Once we have resolved a root namespace, we get passed a base. If the base is a Namespace, we can then inspect the possible nodes of the namespace that it can have. If one matches, we return that Namespace object. Otherwise we try to resolve a bean (if this fails we say we can't resolve anything). And so on.
>>>
>>> This works reasonably well (and quickly) as we know the tree of namespaces up front, it wouldn't work so well if we didn't have this info...
>>>
>>>
>> This scheme works at expression evaluation time. If we can have a way to identify namespaces at parse time, it would simpler and more efficient.
>>
> Yes, this is the primary concern we had about doing it at evaluation time (we used to do this) - performance.
>
>
>> We'll need to tell EL about all the namespaces, I'll think about this more.
>>
>> You seem to imply that in CDI, all bean names are known at deployment time,
>>
> They are.
>
>
>> and have the life time of an application. Is this true?
>>
> A Bean (analagous to Class) cannot be added or removed during the lifecycle of the application. You can create many instances of the bean during the application, but it will always have the same name (it just has a different context e.g. HttpSession or Request).
>
>
Good, then such info will make it possible to resolve namespaces at
parse time.

However, there will be EL users (non CDI) who cannot determine if an EL
identifier is a bean name (or not) until expression evaluation time, in
which case namespace resolution can only be done then. Since this may
be an important performance issue, we may need make the ability to
resolve namespaces at parse time an EL environment property.

>> Can beans (including those with namespaces) be created and destroyed in between EL expressions? The reason I ask is that if we cannot determine the existence of a bean until execution time, we probably cannot do namespace resolution at parse time.
>>
>> Also, would it be useful to be able to "import" namespace so that names can be used without the namespaces?
>>
> Yes. We spent some time talking about this last week. This is something that is definitely needed to make namespaces userfriendly. We differentiated between local imports (e.g. in JSF scoping an import to the page ala imports in Java) and global imports (being able to import a namespace for an entire application).
>
> Obviously, local imports are "better", however without tooling, they impose a big burden on the user. Initially we have decided to implement global imports (with aliases) so that you can write your bean in the "com.acme" namespace, but alias that globally to acme, thus shortening what you must write all the time...
>
>
This is definitely something that EL can help, since it affects the
evaluation of EL expressions.

The things that come to mind right now is maybe we can have an import of
a namespcae and an unimport of the same namespace. Or we can have a
scopeBegin and a scopeEnd to delimit the scope of the imports. I'd like
to use the same mechanism for referencing static methods and enum
constants, if possible.

-Kin-man
> Pete
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: el-next-unsubscribe_at_uel.dev.java.net
> For additional commands, e-mail: el-next-help_at_uel.dev.java.net
>
>