cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Fagerstrom <>
Subject Re: Problems with lazy loading components
Date Wed, 19 Oct 2005 10:33:00 GMT
Carsten Ziegeler wrote:

>Daniel Fagerstrom wrote:
>>The current behaviour is flawed as we already know from e.g. the case 
>>with the I18N transformer where dynamic resolution is used when static 
>>is what would have been expected. With lazy loading things get even 
>>worse as resolution during the setup phase also can become dynamic.
>>It is time that we solve this problem once and for all.
>Yeah, sure, I totally agree. But providing two different source
>resolvers creates imho more confusion than it really helps.
No, it is the current solution where two fundamentally different 
behaviours are tried to be solved with one component through a clever 
(and AFAIK completely undocumented) hack.

The solution I propose will remove the confussion as the resolvers 
behave in a intuitive and easy to understand way. Let me explain.

Static resolution

If you have relative path in a component configuration most (all?) would 
suspect that the relative path would be relative to the location of the 
file the configuration is part of. This behaviour is called static 
resolution as it is resolved relative to its configuration

Now in the implementation of your component you need a resolver to 
resolve the relative path. You get that resolver from the service 
manager that the component is part of. IMO the resolver should resolve 
relative the base path of the service manager (i.e. the base path of the 
configuration file) *always*. I.e. both during setup and during use, and 
both if the component is eager or lazy loaded.

This should be the default situation and follows the principle of least 
supprise. It would be great if we could make this the behaviour of the 
CocoonSourceResolver, but that would probably break user code somewhere 
so we can't. We should at least offer and recomend this kind of resolver 
and migrate our own code to use it.

Sitemap components

Sitemap components are setup in two steps first in the component 
configuration where they are defined and then in the sitemap where they 
are used. The expected behaviour is relative paths in the component 
configuration is resolved relative to the location of the component 
configuration. And that relative paths in the use of the sitemap 
component is resolved relative to the location of the sitemap where it 
is used.

If the sitemap component is defined and used in different locations we 
see that we need two different reolvers to get resolution right. In 
Cocoon that is solved by geting a resolver from the service manager for 
the resolution relative to the component configuration (or this would be 
the case with a static resolver as described above, the current 
situation is more complicated).

Sitemap components implements the interface SitemapModelComponent, that 
has a setUp method that is called when the component is used. The setUp 
method have a resolver as parameter, the surrounding infrastructure 
calls it with a resolver that resolves relative the location of the 
sitemap where the sitemap component is used. By using this resolver the 
sitemap component implementer can get relative paths in the use of the 
sitemap component resolved in the right way.

                          --- o0o ---

These two cases takes care about almost all situations. And it solves 
the issues we have from e.g. the I18N transformer as well as the new 
ones from lazy loading. What needs to be done (besides from implementing 
the mechanism as described in an earlier mail), is to replace uses of 
the CocoonSourceResolver with the static variant and to be more careful 
about what resolver is used for component configuration relative 
respectively use relative resolution in some sitemap components.

For those who don't want to update their code the CocoonSourceResolver 
will work as it has all the time, including its quirks in lazy mode.

Dynamic resolution

 For completeness I describe a more special case that we might or might 
not want to support. Suppose that you want to implement a component that 
behaves like a sitemap component in the way that it can get relative 
paths both when you configure it and when you use it. But that you not 
is using it from the tree engine and because of that cannot use the 
infrastructure that takes care of SitemapModelComponents. An example of 
that could be a component that you are using in a flowscript.

For such a component you might want to resolve paths that you get during 
use of it relative to the context it is used in. For this case we also 
need a dynamic resolver.

The current situation

So what about the current situation? The CocoonSourceResolver resolves a 
relative path relative to the currently used processor (sitemap) if 
there is one, otherwise it resolves relative the context root.

For an eager loading component this means that during setup of a global 
component (in cocoon.xconf) the resolution will be relative the context 
root. And for a component that is defined in a sitemap it will be setup 
relative that sitemap which is the current one.

This far everything is fine. But if one wait with the resolution of a 
relative path from the setup phase to the use phase as for the I18N 
transformer, there will be a suprise. The relative path will be resolved 
relative the (sub) sitemap where it was used instead, there is no 
mechanism to get resolution relative the configuration anymore.

Also for sitemap components one can use the resolver from the service 
manager instead of that injected with the SitemapModelComponent 
interaface, as the resolver change behaviour from setup to use.

For lazy loading the situation is even worse as all resolution will be 
relative the sitemap where the component happen to be used instead of 
relative the configuration location.

                          --- o0o ---

>You say that it's the developer who decides how sources are resolved
>(what the base for relative resolving is). Now, what about having an
>i18n transformer configured in the main sitemap once with all the
>configuration and then the transformer is used in several sub sitemaps.
>Each sub sitemaps has the same set of catalogs. So in this case, the
>transformer is configured once in the main sitemap with relative paths
>and the paths are resolved in a sub sitemap relative to the sub sitemap.
>Ok, this might be a constructed case, but I think the point is, the
>developer can't always decide.
>So, again why not using the following:
> <map:transform src="my-class">
>   <map:parameter name="config-file"
> <map:transform src="my-class">
>   <map:parameter name="config-file" value="relativ_to_the_usage_sitemap"/>
I agree about that your case is constructed ;) I have explained above 
what the main cases are and that it in general it is the components 
designers responsibility to decide what resolution strategy that should 
be used. For the I18N case I find the current (dynamic resolution) 
behaviour rather unintuitive, and considering user complaints I'm not 
the only one. So the default behaviour should instead be static resolution.

If you find a real use case for needing to let the user decide, we could 
instead have a dynamic protocol for dynamic reolution for the few cases 
where somebody would like that.

>Everything stays the way it is and you can force source resolving to be
>relative to the defining sitemap by using the protocol.
I don't want it to stay as it is as the current behavior is flawed and 
that it gets even worse with lazy component loading.

What I propose is similar to the current system but behaves in an 
intuitive way, and we also keep back compability for those who don't 
need lazy loading and can live with the current behaviour.


View raw message