cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rolf Kulemann <r...@apache.org>
Subject [C2.2] Problem with SpringComponentLocator and with ComponentManagers in general
Date Wed, 04 May 2005 16:41:18 GMT
Hi Spring fans,

I played around with the Cocoon Spring integration. the spring-app block
works fine until it comes to sub-sitemap mounting. The problem there is,
that the subsitemap service manager is not able to locate any roles like
for generators and transformers when the sitemap is setup. I  tracked
that problem down a bit, and did some hacks to solve that problem, but
imho, there is general conceptual problem with the core.

Here is what I found out:

The problem starts in SitemapLanguage.createServiceManager

------------
newManager = new CocoonServiceManager(this.parentProcessorManager,
newClassLoader);
    
            // Go through the component lifecycle
            ContainerUtil.enableLogging(newManager, this.getLogger());
            ContainerUtil.contextualize(newManager, context);
            // before we pass the configuration we have to strip the
            // additional configuration parts, like classpath etc. as these
            // are not configurations for the service manager
            final DefaultConfiguration c = new DefaultConfiguration(config.getName(), 
                                                                    config.getLocation(),
                                                                    config.getNamespace(),
                                                                    "");
            c.addAll(config);
            c.removeChild(config.getChild("application-container"));
            c.removeChild(config.getChild("classpath"));
            c.removeChild(config.getChild("listeners"));

            ContainerUtil.configure(newManager, c);
            ContainerUtil.initialize(newManager);

            // check for an application specific container
            final Configuration appContainer = config.getChild("application-container", false);
            if ( appContainer != null ) {
                final String clazzName = appContainer.getAttribute("class");

                final ComponentLocator cl = (ComponentLocator)ClassUtils.newInstance(clazzName);

                // Go through the component lifecycle
                LifecycleHelper.setupComponent(cl, this.getLogger(), context, newManager,
appContainer);

                this.applicationContainer = cl;

                newManager = new ComponentManager(newManager, cl);
            }
---------


The first/root sitemap which uses an app-container gets a
ComponentManager set as ServiceManager/ComponentLocator. Up to now
everything is fine, since the ComponentManager delegates the offending
component lookups to the CoreServiceManager.

Now the subsitemap. If the subsitemap does not define a app-container
itself the ServiceManager for that sitemap is a CoreServiceManager with
the ComponentManager of the root sitemap as the parent ServiceManager.

The CoreServiceManager does the follwoing in the constructor:

-----
if ( parent instanceof CoreServiceManager ) {
            parentRoleManager = ((CoreServiceManager)parent).roleManager;
            this.loggerManager = ((CoreServiceManager)parent).loggerManager;
        }

        // Always create a role manager, it can be filled several times either through
        // the root "roles" attribute or through loading of includes
        this.roleManager = new RoleManager(parentRoleManager);
-----

It tests if the parent is an instance of CoreServiceManager. Which in our case it is not,
it is a ComponentManager.
That is the reason why the subsitemap's components/roles can not be found, since this ServiceManager
will not delegate calls to the parent ServiceManager.

So, the obvoius solution here is to test wehter the parent ServiceManager has a RoleManager
doesn't matter if parent is an instance of CoreServiceManager.
E.g. a new interface can be introduced like RolableServiceManager or so (i do not like that).

Would look like

if ( parent instanceof RolableServiceManager ) {
            parentRoleManager = ((RolableServiceManager)parent).getRoleManager();
            this.loggerManager = ((RolableServiceManager)parent).loggerManager;
        }

The logger manager is the next problem, which is another topic.

I spent quite some time thinking about a good solution, but didn't found one. 
I do not understand the  difference between the ServiceManager and RoleManager. What are the
responsibilities of both?
Woulnd't it make sense to collapse both concepts? 

AFAIC's the RoleManager also just looks up components as well as the RoleManager does.

WDYT?
-- 
Rolf Kulemann


Mime
View raw message