cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jheym...@apache.org
Subject svn commit: r330548 [38/132] - in /cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/ cocoon-ajax-block/api/ cocoon-ajax-block/api/src/ cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/ cocoon-ajax-block/api/src/main/...
Date Thu, 03 Nov 2005 14:00:48 GMT
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/WiringNotFoundException.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/WiringNotFoundException.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/WiringNotFoundException.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/WiringNotFoundException.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core;
+
+/**
+ * Throw this exception in the case that the wiring.xml is not found.
+ * 
+ * @version $Id: WiringNotFoundException.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public class WiringNotFoundException extends RuntimeException {
+
+    public WiringNotFoundException(String message) {
+        super(message);
+    }
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/WiringNotFoundException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/AbstractServiceManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/AbstractServiceManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/AbstractServiceManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/AbstractServiceManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,192 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.handler.AbstractComponentHandler;
+import org.apache.cocoon.core.container.handler.ComponentHandler;
+
+/**
+ * Base class for all service managers: ServiceManager and ServiceSelector
+ *
+ * @version $Id: AbstractServiceManager.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public abstract class AbstractServiceManager
+extends AbstractLogEnabled
+implements Contextualizable, ThreadSafe, Disposable, Initializable {
+    
+    /** The application context for components */
+    protected Context context;
+
+    /** Static component mapping handlers. */
+    protected final Map componentMapping = Collections.synchronizedMap(new HashMap());
+
+    /** Used to map roles to ComponentHandlers. */
+    protected final Map componentHandlers = Collections.synchronizedMap(new HashMap());
+
+    /** Is the Manager disposed or not? */
+    protected boolean disposed;
+
+    /** Is the Manager initialized? */
+    protected boolean initialized;
+
+    /** RoleInfos. */
+    protected RoleManager roleManager;
+
+    /** LoggerManager. */
+    protected LoggerManager loggerManager;
+    
+    protected ComponentEnvironment componentEnv;
+
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize( final Context context ) {
+        this.context = context;
+    }
+
+    public void setRoleManager( final RoleManager roles ) {
+        this.roleManager = roles;
+    }
+
+    /**
+     * Configure the LoggerManager.
+     */
+    public void setLoggerManager( final LoggerManager manager ) {
+        this.loggerManager = manager;
+    }
+    
+    /**
+     * Obtain a new ComponentHandler for the specified component. 
+     * 
+     * @param role the component's role.
+     * @param componentClass Class of the component for which the handle is
+     *                       being requested.
+     * @param configuration The configuration for this component.
+     * @param serviceManager The service manager which will be managing the Component.
+     *
+     * @throws Exception If there were any problems obtaining a ComponentHandler
+     */
+    protected ComponentHandler getComponentHandler( final String role,
+                                                    final Class componentClass,
+                                                    final Configuration configuration,
+                                                    final ServiceManager serviceManager,
+                                                    final ComponentInfo  baseInfo)
+    throws Exception {
+        if (this.componentEnv == null) {
+            this.componentEnv = new ComponentEnvironment(null, getLogger(), this.roleManager,
+                    this.loggerManager, this.context, serviceManager);
+        }
+        // FIXME - we should always get an info here
+        ComponentInfo info;
+        if ( baseInfo != null ) {
+            info = baseInfo.duplicate();
+        } else {
+            info = new ComponentInfo();
+            info.fill(configuration);
+        }
+        info.setConfiguration(configuration);
+        info.setServiceClassName(componentClass.getName());
+        
+        return AbstractComponentHandler.getComponentHandler(role,
+                                                     this.componentEnv,
+                                                     info);
+    }
+
+    protected void addComponent(String className,
+                                String role,
+                                Configuration configuration,
+                                ComponentInfo info) 
+    throws ConfigurationException {
+        // check for old excalibur class names - we only test against the selector
+        // implementation
+        if ( "org.apache.cocoon.components.ExtendedComponentSelector".equals(className)) {
+            className = DefaultServiceSelector.class.getName();
+        }
+        
+        try {
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "Adding component (" + role + " = " + className + ")" );
+            }
+            // FIXME - use different classloader
+            final Class clazz = this.getClass().getClassLoader().loadClass( className );
+            this.addComponent( role, clazz, configuration, info );
+        } catch( final ClassNotFoundException cnfe ) {
+            final String message = "Could not get class (" + className + ") for role "
+                                 + role + " at " + configuration.getLocation();
+
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message, cnfe );
+            }
+
+            throw new ConfigurationException( message, cnfe );
+        } catch( final ServiceException ce ) {
+            final String message = "Cannot setup class "+ className + " for role " + role
+                                 + " at " + configuration.getLocation();
+
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message, ce );
+            }
+
+            throw new ConfigurationException( message, ce );
+        } catch( final Exception e ) {
+            final String message = "Unexpected exception when setting up role " + role + " at " + configuration.getLocation();
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message, e );
+            }
+            throw new ConfigurationException( message, e );
+        }        
+    }
+    
+    protected abstract void addComponent(String role, 
+                                         Class clazz, 
+                                         Configuration config,
+                                         ComponentInfo info)
+    throws ServiceException;
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.disposed = true;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+        this.initialized = true;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/AbstractServiceManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentEnvironment.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentEnvironment.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentEnvironment.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentEnvironment.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,95 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.io.InputStream;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.Settings;
+
+/**
+ * The component enviromnent contains all objects necessary to create
+ * a new component; it's just a "container" of objects.
+ *
+ * @version $Id: ComponentEnvironment.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public class ComponentEnvironment {
+
+    public final ServiceManager serviceManager;
+    public final Context context;
+    public final Logger logger;
+    public final RoleManager roleManager;
+    public final LoggerManager loggerManager;
+    private final ClassLoader classLoader;
+    private Core core;
+
+    public ComponentEnvironment(ClassLoader classLoader, Logger logger, RoleManager roleManager, LoggerManager loggerManager,
+            Context context, ServiceManager serviceManager) {
+
+        // Find a class loader
+        if (classLoader == null) {
+            classLoader = Thread.currentThread().getContextClassLoader();
+            if (classLoader == null) {
+                classLoader = this.getClass().getClassLoader();
+            }            
+        }
+
+        this.classLoader = classLoader;
+        this.logger = logger;
+        this.roleManager = roleManager;
+        this.loggerManager = loggerManager;
+        this.context = context;
+        this.serviceManager = serviceManager;
+        // FIXME - we should ensure that the context is never null!
+        if ( this.context != null ) {
+            try {
+                this.core = (Core)this.context.get(Core.ROLE);
+            } catch (ContextException ignore) {
+                // this can never happen
+            }
+        }
+    }
+
+    public Class loadClass(String name) throws ClassNotFoundException {
+        return this.classLoader.loadClass(name);
+    }
+    
+    public ComponentInfo loadComponentInfo(String name) 
+    throws Exception {
+        final StringBuffer bu = new StringBuffer(name);
+        bu.append(".xconf");
+        ComponentInfo ci = null;
+        final InputStream is = this.classLoader.getResourceAsStream(bu.toString());
+        if ( is != null ) {
+            final Settings settings = (this.core == null ? null : this.core.getSettings());
+            final ConfigurationBuilder cb = new ConfigurationBuilder(settings);
+            final Configuration conf = cb.build(is);
+            ci = new ComponentInfo();
+            ci.fill(conf);
+        }
+        return ci;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentEnvironment.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentFactory.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentFactory.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentFactory.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,214 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.lang.reflect.Method;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.Core;
+
+/**
+ * Factory for Avalon based components.
+ *
+ * @version $Id: ComponentFactory.java 312861 2005-10-11 11:46:08Z cziegeler $
+ * @since 2.2
+ */
+public class ComponentFactory {
+    
+    protected final ComponentInfo serviceInfo;
+    
+    protected final ComponentEnvironment environment;
+    
+    /**
+     * The component's logger, which may be different from the environment's logger
+     */
+    protected final Logger componentLogger;
+    
+    /** The parameters for this component
+     */
+    protected final Parameters parameters;
+    
+    protected final Class serviceClass;
+    protected final Method initMethod;
+    protected final Method destroyMethod;
+    protected final Method poolInMethod;
+    protected final Method poolOutMethod;
+    protected Method configureSettingsMethod;
+    protected Core core;
+
+    /**
+     * Construct a new component factory for the specified component.
+     *
+     * @param environment Describes the environment for the component.
+     * @param info Describes the configuration/settings for the component.
+     *
+     */
+    public ComponentFactory( final ComponentEnvironment environment,
+                             final ComponentInfo info) 
+    throws Exception {
+        // FIXME - we should ensure that the context is never null!
+        if ( environment.context != null ) {
+            try {
+                this.core = (Core)environment.context.get(Core.ROLE);
+            } catch (ContextException ignore) {
+                // this can never happen
+            }
+        }
+        this.environment = environment;
+        this.serviceInfo = info;
+        
+        // this is our default logger:
+        Logger actualLogger = this.environment.logger;
+        final String category = this.serviceInfo.getLoggerCategory();
+        if ( category != null ) {
+            // If the handler is created "manually" (e.g. XSP engine), loggerManager can be null
+            if( this.environment.loggerManager != null ) {
+                actualLogger = this.environment.loggerManager.getLoggerForCategory(category);
+            }
+        }
+        this.componentLogger = actualLogger;
+        
+        this.serviceClass = this.environment.loadClass(this.serviceInfo.getServiceClassName());
+        if ( Parameterizable.class.isAssignableFrom(this.serviceClass) ) {
+            this.parameters = Parameters.fromConfiguration( this.serviceInfo.getConfiguration() );            
+        } else {
+            this.parameters = null;
+        }
+        if ( this.serviceInfo.getDestroyMethodName() != null ) {
+            this.destroyMethod = this.serviceClass.getMethod(this.serviceInfo.getDestroyMethodName(), null);
+        } else {
+            this.destroyMethod = null;
+        }
+        if ( this.serviceInfo.getInitMethodName() != null ) {
+            this.initMethod = this.serviceClass.getMethod(this.serviceInfo.getInitMethodName(), null);
+        } else {
+            this.initMethod = null;
+        }
+        if ( this.serviceInfo.getPoolInMethodName() != null ) {
+            this.poolInMethod = this.serviceClass.getMethod(this.serviceInfo.getPoolInMethodName(), null);
+        } else {
+            this.poolInMethod = null;
+        }
+        if ( this.serviceInfo.getPoolOutMethodName() != null ) {
+            this.poolOutMethod = this.serviceClass.getMethod(this.serviceInfo.getPoolOutMethodName(), null);
+        } else {
+            this.poolOutMethod = null;
+        }
+        try {
+            this.configureSettingsMethod = this.serviceClass.getMethod("configure", new Class[] {Core.class});
+        } catch (Throwable ignore) {
+            // we have to catch throwable here, as the above test can
+            // result in NoClassDefFound exceptions etc.
+            this.configureSettingsMethod = null;
+        }
+    }
+    
+    /**
+     * Create a new instance
+     */
+    public final Object newInstance()
+    throws Exception {
+        final Object component = this.serviceClass.newInstance();
+
+        setupInstance(component);
+        return component;
+    }
+    
+    /**
+     * Invoke the various lifecycle interfaces to setup a newly created component
+     * @param component
+     * @throws Exception
+     */
+    protected void setupInstance(Object component) throws Exception {
+        if( this.environment.logger.isDebugEnabled() ) {
+            this.environment.logger.debug( "ComponentFactory creating new instance of " +
+                    this.serviceClass.getName() + "." );
+        }
+
+        ContainerUtil.enableLogging(component, this.componentLogger);
+        ContainerUtil.contextualize( component, this.environment.context );
+        ContainerUtil.service( component, this.environment.serviceManager );
+        if ( this.configureSettingsMethod != null && this.core != null) {
+            this.configureSettingsMethod.invoke( component, new Object[] {this.core});
+        }
+        ContainerUtil.configure( component, this.serviceInfo.getConfiguration() );
+
+        if( component instanceof Parameterizable ) {
+            ContainerUtil.parameterize( component, this.parameters );
+        }
+
+        ContainerUtil.initialize( component );
+
+        if ( this.initMethod != null ) {
+            this.initMethod.invoke(component, null);
+        }
+
+        ContainerUtil.start( component );
+    }
+
+    public Class getCreatedClass() {
+        return this.serviceClass;
+    }
+
+    /**
+     * Destroy an instance
+     */
+    public void decommission( final Object component )
+    throws Exception {
+        if( this.environment.logger.isDebugEnabled() ) {
+            this.environment.logger.debug( "ComponentFactory decommissioning instance of " +
+                    this.serviceClass.getName() + "." );
+        }
+
+        ContainerUtil.stop( component );
+        ContainerUtil.dispose( component );
+
+        if ( this.destroyMethod != null ) {
+            this.destroyMethod.invoke(component, null);
+        }
+    }
+
+    /**
+     * Handle service specific methods for getting it out of the pool
+     */
+    public void exitingPool( final Object component )
+    throws Exception {
+        if ( this.poolOutMethod != null ) {
+            this.poolOutMethod.invoke(component, null);
+        }         
+    }
+
+    /**
+     * Handle service specific methods for putting it into the pool
+     */
+    public void enteringPool( final Object component )
+    throws Exception {
+        // Handle Recyclable objects
+        if( component instanceof Recyclable ) {
+            ( (Recyclable)component ).recycle();
+        }
+        if ( this.poolInMethod != null ) {
+            this.poolInMethod.invoke(component, null);
+        }         
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,65 @@
+/* 
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.sitemap.ComponentLocator;
+
+/**
+ * Wrapper for a service manager.
+ *
+ * @version Id: ComponentLocatorWrapper.java 179038 2005-05-30 08:19:24Z cziegeler $
+ * @since 2.2
+ */
+final public class ComponentLocatorWrapper
+implements ComponentLocator {
+
+    protected final ServiceManager manager;
+
+    public ComponentLocatorWrapper(ServiceManager m) {
+        this.manager = m;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#hasComponent(java.lang.String)
+     */
+    public boolean hasComponent(String key) {
+        return this.manager.hasService(key);
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#getComponent(java.lang.String)
+     */
+    public Object getComponent(String key) 
+    throws ProcessingException {
+        try {
+            return this.manager.lookup(key);
+        } catch (ServiceException se) {
+            throw new ProcessingException("Unable to lookup component for key: " + key, se);
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#release(java.lang.Object)
+     */
+    public void release(Object component) {
+        this.manager.release(component);
+    }
+
+}
\ No newline at end of file

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/CoreServiceManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/CoreServiceManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/CoreServiceManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/CoreServiceManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,885 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Startable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.components.Preloadable;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.CoreResourceNotFoundException;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.core.container.handler.AbstractComponentHandler;
+import org.apache.cocoon.core.container.handler.AliasComponentHandler;
+import org.apache.cocoon.core.container.handler.ComponentHandler;
+import org.apache.cocoon.core.container.handler.InstanceComponentHandler;
+import org.apache.cocoon.core.container.handler.LazyHandler;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.sitemap.impl.ComponentManager;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * Default service manager for Cocoon's components.
+ *
+ * @version $Id: CoreServiceManager.java 328027 2005-10-24 10:38:36Z cziegeler $
+ * @since 2.2
+ */
+public class CoreServiceManager
+        extends AbstractLogEnabled
+        implements Contextualizable, ThreadSafe, Disposable, Initializable, ServiceManager, Configurable {
+
+    /**
+     * An empty configuration object, that can be used when no configuration is known but one
+     * is needed.
+     */
+    public static final Configuration EMPTY_CONFIGURATION = new DefaultConfiguration("-", "unknown location");
+
+    /** Parameter map for the context protocol */
+    protected static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    /** The application context for components */
+    protected Context context;
+
+    /** Static component mapping handlers. */
+    protected final Map componentMapping = Collections.synchronizedMap(new HashMap());
+
+    /** Used to map roles to ComponentHandlers. */
+    protected final Map componentHandlers = Collections.synchronizedMap(new HashMap());
+
+    /** Is the Manager disposed or not? */
+    protected boolean disposed;
+
+    /** Is the Manager initialized? */
+    protected boolean initialized;
+
+    /** RoleInfos. */
+    protected RoleManager roleManager;
+
+    /** LoggerManager. */
+    protected LoggerManager loggerManager;
+
+    protected ComponentEnvironment componentEnv;
+
+    /** The settings */
+    private Settings settings;
+
+    /** The location where this manager is defined */
+    protected String location;
+
+    /** The parent ServiceManager */
+    protected ServiceManager parentManager;
+
+    /** The classloader to get classes from */
+    protected ClassLoader classloader;
+
+    /** The resolver used to resolve includes. It is lazily loaded in {@link #setupSourceResolver()}. */
+    private SourceResolver cachedSourceResolver;
+
+    /** Create the ServiceManager with a parent ServiceManager */
+    public CoreServiceManager( final ServiceManager parent ) {
+        this(parent, null);
+    }
+
+    /** Create the ServiceManager with a parent ServiceManager and a ClassLoader */
+    public CoreServiceManager( final ServiceManager parent, final ClassLoader classloader ) {
+        this.parentManager = parent;
+        this.classloader = classloader;
+
+        RoleManager parentRoleManager = null;
+        // FIXME - We should change this to a cleaner way!
+        ServiceManager coreServicemanager = parent;
+        if ( parent instanceof ComponentManager ) {
+            coreServicemanager = ((ComponentManager)parent).getServiceManager();
+        }
+        // get role manager and logger manager
+        if ( coreServicemanager instanceof CoreServiceManager ) {
+            parentRoleManager = ((CoreServiceManager)coreServicemanager).roleManager;
+            this.loggerManager = ((CoreServiceManager)coreServicemanager).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);
+    }
+
+    //=============================================================================================
+    // Avalon lifecycle
+    //=============================================================================================
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
+     */
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        this.roleManager.enableLogging(logger);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize( final Context context ) 
+    throws ContextException {
+        this.context = context;
+        this.settings = ((Core)context.get(Core.ROLE)).getSettings();
+    }
+
+    /**
+     * Configure the LoggerManager.
+     */
+    public void setLoggerManager( final LoggerManager manager ) {
+        this.loggerManager = manager;
+    }
+
+    public void setRoleManager (RoleManager rm) {
+        if (rm != null) {
+            // Override the one eventually got in the parent (see constructor)
+            this.roleManager = new RoleManager(rm);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        this.componentEnv = new ComponentEnvironment(this.classloader, getLogger(), this.roleManager, this.loggerManager, this.context, this);
+
+        // Setup location
+        this.location = configuration.getLocation();
+
+        // Find the current URI
+        String currentURI;
+        int pos = this.location.lastIndexOf(':');
+        if (pos == -1) {
+            // No available location: start at the context
+            currentURI = "context://";
+        } else {
+            pos = this.location.lastIndexOf(':', pos);
+            currentURI = this.location.substring(0, pos-1);
+        }
+
+        try {
+            // and load configuration with a empty list of loaded configurations
+            parseConfiguration(configuration, currentURI, new HashSet());
+        } finally {
+            // Release any source resolver that may have been created to load includes
+            releaseCachedSourceResolver();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize()
+    throws Exception {
+        this.initialized = true;
+
+        // Initialize component handlers. This is done in no particular order, but initializing a
+        // handler may indirectly initialize another handler through a call to lookup().
+        // This isn't a problem as a handler's initialize() method can be called several times.
+
+        // We copy the list of handlers as the componentHandler Map may change if implicitely declared
+        // components are looked up.
+        ComponentHandler[] handlers = (ComponentHandler[])this.componentHandlers.values().toArray(
+                new ComponentHandler[this.componentHandlers.size()]);
+
+        for( int i = 0; i < handlers.length; i++ ) {
+            try {
+                handlers[i].initialize();
+            } catch( Exception e ) {
+                if( this.getLogger().isErrorEnabled() ) {
+                    this.getLogger().error( "Caught an exception trying to initialize "
+                                       + "the component handler.", e );
+                }
+                // Rethrow the exception
+                throw e;
+            }
+        }
+
+//        Object[] keyArray = this.componentHandlers.keySet().toArray();
+//        java.util.Arrays.sort(keyArray);
+//        for (int i = 0; i < keyArray.length; i++) {
+//            System.err.println("Component key = " + keyArray[i]);
+//        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        boolean forceDisposal = false;
+
+        final List disposed = new ArrayList();
+
+        while( componentHandlers.size() > 0 ) {
+            for( Iterator iterator = componentHandlers.keySet().iterator();
+                 iterator.hasNext(); ) {
+                final Object role = iterator.next();
+
+                final ComponentHandler handler =
+                    (ComponentHandler)componentHandlers.get( role );
+
+                if( forceDisposal || handler.canBeDisposed() ) {
+                    if( forceDisposal && getLogger().isWarnEnabled() ) {
+                        this.getLogger().warn
+                            ( "disposing of handler for unreleased component."
+                              + " role [" + role + "]" );
+                    }
+
+                    handler.dispose();
+                    disposed.add( role );
+                }
+            }
+
+            if( disposed.size() > 0 ) {
+                final Iterator i = disposed.iterator();
+                while ( i.hasNext() ) {
+                    this.componentHandlers.remove( i.next() );
+                }
+                disposed.clear();
+            } else {   
+                // no more disposable handlers!
+                forceDisposal = true;
+            }
+        }
+        this.disposed = true;
+    }
+
+    //=============================================================================================
+    // ServiceManager implementation
+    //=============================================================================================
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService( final String role ) {
+        if( !this.initialized || this.disposed ) return false;
+
+        boolean exists = this.componentHandlers.containsKey( role );
+
+        if( !exists && null != this.parentManager ) {
+            exists = this.parentManager.hasService( role );
+        }
+
+        return exists;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+     */
+    public Object lookup( final String role )
+    throws ServiceException {
+        if( !this.initialized ) {
+            if( this.getLogger().isWarnEnabled() ) {
+                this.getLogger().warn(
+                    "Looking up component on an uninitialized CoreServiceManager [" + role + "]" );
+            }
+        }
+
+        if( this.disposed ) {
+            throw new IllegalStateException(
+                "You cannot lookup components on a disposed CoreServiceManager" );
+        }
+
+        if( role == null ) {
+            final String message =
+                "CoreServiceManager attempted to retrieve service with null role.";
+
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message );
+            }
+            throw new ServiceException( role, message );
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get( role );
+
+        // Retrieve the instance of the requested component
+        if ( handler == null ) {
+            if( this.parentManager != null ) {
+                try {
+                    return this.parentManager.lookup( role );
+                } catch( Exception e ) {
+                    if( this.getLogger().isWarnEnabled() ) {
+                        final String message =
+                            "ComponentLocator exception from parent SM during lookup.";
+                        this.getLogger().warn( message, e );
+                    }
+                    // ignore.  If the exception is thrown, we try to
+                    // create the component next
+                }
+            }
+
+            if( this.roleManager != null ) {
+                final ComponentInfo info = this.roleManager.getDefaultServiceInfoForRole( role );
+
+                if( info != null ) {
+                    if( this.getLogger().isDebugEnabled() ) {
+                        this.getLogger().debug( "Could not find ComponentHandler, attempting to create "
+                            + "one for role [" + role + "]" );
+                    }
+
+                    try {
+                        final Configuration configuration = new DefaultConfiguration( "", "-" );
+
+                        handler = this.getComponentHandler(role,
+                                                           info.getServiceClassName(),
+                                                           configuration.getChild(role),
+                                                           info);
+
+                    } catch (ServiceException se) {
+                        throw se;
+                    } catch( final Exception e ) {
+                        final String message = "Could not find component for role [" + role + "]";
+                        if( this.getLogger().isDebugEnabled() ) {
+                            this.getLogger().debug( message, e );
+                        }
+                        throw new ServiceException( role, message, e );
+                    }
+                    try {
+                        handler.initialize();
+                    } catch (ServiceException se) {
+                        throw se;
+                    } catch( final Exception e ) {
+                        final String message = "Could not create component for role [" + role + "]: " + handler.getClass();
+                        if( this.getLogger().isDebugEnabled() ) {
+                            this.getLogger().debug( message, e );
+                        }
+                        throw new ServiceException( role, message, e );
+                    }
+
+                    this.componentHandlers.put( role, handler );
+                }
+            } else {
+                this.getLogger().debug( "Component requested without a RoleManager set.\n"
+                    + "That means setRoleManager() was not called during initialization." );
+            }
+        }
+
+        if( handler == null ) {
+            final String message = "Could not find component for role: [" + role + "]";
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( message );
+            }
+            throw new ServiceException( role, message );
+        }
+
+        Object component = null;
+
+        try {
+            component = handler.get();
+        } catch ( ServiceException se) {
+            // Rethrow insteand of wrapping it again
+            throw se;
+        } catch( final Exception e ) {
+            final String message = "Could not access the component for role [" + role + "]";
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( message, e );
+            }
+
+            throw new ServiceException( role, message, e );
+        }
+        this.initialize( role, component );
+
+        // Add a mapping between the component and its handler.
+        //  In the case of a ThreadSafeComponentHandler, the same component will be mapped
+        //  multiple times but because each put will overwrite the last, this is not a
+        //  problem.  Checking to see if the put has already been done would be slower.
+        this.componentMapping.put( component, handler );
+
+        return component;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+     */
+    public void release( final Object component ) {
+        if( null == component ) {
+            return;
+        }
+
+        // The componentMapping StaticBucketMap itself is threadsafe, and because the same component
+        //  will never be released by more than one thread, this method does not need any
+        //  synchronization around the access to the map.
+
+        final ComponentHandler handler =
+            (ComponentHandler)this.componentMapping.get( component );
+
+        if ( handler != null ) {
+            // ThreadSafe components will always be using a ThreadSafeComponentHandler,
+            //  they will only have a single entry in the m_componentMapping map which
+            //  should not be removed until the ComponentLocator is disposed.  All
+            //  other components have an entry for each instance which should be
+            //  removed.
+            if( !handler.isSingleton() ) {
+                // Remove the component before calling put.  This is critical to avoid the
+                //  problem where another thread calls put on the same component before
+                //  remove can be called.
+                this.componentMapping.remove( component );
+            }
+
+            try {
+                handler.put( component );
+            } catch( Exception e ) {
+                if( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug( "Error trying to release component.", e );
+                }
+            }
+        }
+        else if( this.parentManager != null ) {
+            this.parentManager.release( component );
+        } else {
+            this.getLogger().warn( "Attempted to release a " + component.getClass().getName() +
+                              " but its handler could not be located." );
+        }
+    }
+
+    //=============================================================================================
+    // Additional public & protected contract
+    //=============================================================================================
+
+    /**
+     * Add a new component to the manager.
+     *
+     * @param role the role name for the new component.
+     * @param className the class of this component.
+     * @param configuration the configuration for this component.
+     */
+    public void addComponent( String role,
+                              String className,
+                              Configuration configuration,
+                              ComponentInfo info)
+    throws ConfigurationException {
+        if( this.initialized ) {
+            throw new IllegalStateException("Cannot add components to an initialized CoreServiceManager." );
+        }
+
+        // check for old excalibur class names - we only test against the selector
+        // implementation
+        if ( "org.apache.cocoon.components.ExtendedComponentSelector".equals(className)) {
+            className = DefaultServiceSelector.class.getName();
+        }
+
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "Adding component (" + role + " = " + className + ")" );
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role);
+        if (handler != null) {
+            // Check that override is allowed. If yes, the handler will be redefined below, allowing
+            // the new definition to feed this manager with its components.
+            checkComponentOverride(role, className, configuration, handler);
+        }
+
+        try {
+            handler = this.getComponentHandler(role, className, configuration, info);
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "Handler type = " + handler.getClass().getName() );
+            }
+
+            this.componentHandlers.put( role, handler );
+        } catch ( final ConfigurationException ce ) {
+            throw ce;
+        } catch( final Exception e ) {
+            throw new ConfigurationException( "Could not add component defined at " + configuration.getLocation(), e );
+        }
+
+//        // Initialize shadow selector now, it will feed this service manager
+//        if ( DefaultServiceSelector.class.isAssignableFrom( component )) {
+//            try {
+//                handler.initialize();
+//            } catch(ServiceException se) {
+//                throw se;
+//            } catch(Exception e) {
+//                throw new ServiceException(role, "Could not initialize selector", e);
+//            }
+//        }
+    }
+
+    /**
+     * Add an existing object to the manager. The object should be fully configured as no
+     * setup lifecycle methods are called. On manager disposal, the <code>Disposable</code>
+     * method is considered.
+     * 
+     * @param role the role under which the object will be known
+     * @param instance the component instance
+     * @throws ServiceException
+     */
+    public void addInstance(String role, Object instance) throws ServiceException {
+        if( this.initialized ) {
+            throw new ServiceException(role,
+                "Cannot add components to an initialized CoreServiceManager.");
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role);
+        if (handler != null) {
+            ComponentInfo info = handler.getInfo();
+            throw new ServiceException(role, "Component already defined at " + info.getLocation()); 
+        }
+
+        this.componentHandlers.put(role, new InstanceComponentHandler(getLogger(), instance));
+    }
+
+    /**
+     * Add an alias to a role, i.e. define a synonym for the role.
+     * 
+     * @param existingRole the existing role that will be aliased
+     * @param newRole the new role
+     * @throws ServiceException if the existing role could not be found in the current
+     *         manager and its ancestors
+     */
+    public void addRoleAlias(String existingRole, String newRole) throws ServiceException {
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(existingRole);
+        if (handler == null) {
+            // Aliased component not found here, but can be defined by an ancestor
+            CoreServiceManager current = this;
+            while(handler == null && current.parentManager != null) {
+                if (!(current.parentManager instanceof CoreServiceManager)) {
+                    throw new ServiceException(newRole, "Cannot alias to components not managed by CoreServiceManager");
+                }
+                current = (CoreServiceManager)current.parentManager;
+                handler = (ComponentHandler)current.componentHandlers.get(existingRole);
+            }
+        }
+
+        if (handler == null) {
+            throw new ServiceException(newRole, "Cannot alias non-existing role " + existingRole);
+        }
+
+        this.componentHandlers.put(newRole, new AliasComponentHandler(this.getLogger(), handler));
+    }
+
+    /**
+     * Initialize the component
+     * @throws ServiceException
+     */
+    protected void initialize(String role, Object component) 
+    throws ServiceException {
+        // we do nothing here, can be used in subclasses
+    }
+
+    //=============================================================================================
+    // Private methods
+    //=============================================================================================
+    
+    /**
+     * Obtain a new ComponentHandler for the specified component. 
+     * 
+     * @param role the component's role.
+     * @param className Class of the component for which the handle is
+     *                       being requested.
+     * @param configuration The configuration for this component.
+     * @param baseInfo The information for managing the component, like service manager etc.
+     *
+     * @throws Exception If there were any problems obtaining a ComponentHandler
+     */
+    private ComponentHandler getComponentHandler( final String role,
+                                                  final String className,
+                                                  final Configuration configuration,
+                                                  final ComponentInfo baseInfo)
+    throws Exception {
+
+        boolean lazyLoad;
+
+        if (configuration.getAttribute("preload", null) != null) {
+            // This one has precedence
+            lazyLoad = configuration.getAttributeAsBoolean("preload");
+
+        } else {
+            lazyLoad = this.settings.isLazyMode();
+
+            if (lazyLoad) {
+                // Check if the class implements Startable or Preloadable
+                Class componentClass;
+                try {
+                    componentClass = componentEnv.loadClass(className);
+                } catch (ClassNotFoundException cnfe) {
+                    throw new Exception("Cannot find class " + className + " for component at " +
+                            configuration.getLocation(), cnfe);
+                }
+                if (Startable.class.isAssignableFrom(componentClass) ||
+                    Preloadable.class.isAssignableFrom(componentClass)) {
+                    lazyLoad = false;
+                }
+            }
+        }
+
+        if (lazyLoad) {
+            return new LazyHandler(role, className, configuration, componentEnv);
+        }
+        
+        // FIXME - we should ensure that we always get an info
+        ComponentInfo info;
+        if ( baseInfo != null ) {
+            info = baseInfo.duplicate();
+        } else {
+            info = new ComponentInfo();
+            info.fill(configuration);
+        }
+        info.setConfiguration(configuration);
+        info.setServiceClassName(className);
+
+        return AbstractComponentHandler.getComponentHandler(role, this.componentEnv, info);
+    }
+
+    private void parseConfiguration(final Configuration configuration, String contextURI, Set loadedURIs) 
+        throws ConfigurationException {
+
+        final Configuration[] configurations = configuration.getChildren();
+
+        for( int i = 0; i < configurations.length; i++ ) {
+            final Configuration componentConfig = configurations[i];
+
+            final String componentName = componentConfig.getName();
+
+            if ("include".equals(componentName)) {
+                handleInclude(contextURI, loadedURIs, componentConfig);
+
+            } else {
+                // Component declaration
+                // Find the role
+                String role = componentConfig.getAttribute("role", null);
+                if (role == null) {
+                    // Get the role from the role manager if not explicitely specified
+                    role = roleManager.getRoleForName(componentName);
+                    if (role == null) {
+                        // Unknown role
+                        throw new ConfigurationException("Unknown component type '" + componentName +
+                            "' at " + componentConfig.getLocation());
+                    }
+                }
+
+                // Find the className
+                String className = componentConfig.getAttribute("class", null);
+                if (className == null) {
+                    // Get the default class name for this role
+                    final ComponentInfo info = roleManager.getDefaultServiceInfoForRole(role);
+                    if (info == null) {
+                        throw new ConfigurationException("Cannot find a class for role " + role + " at " + componentConfig.getLocation());
+                    }
+                    className = info.getServiceClassName();
+                }
+
+                // If it has a "name" attribute, add it to the role (similar to the
+                // declaration within a service selector)
+                // Note: this has to be done *after* finding the className above as we change the role
+                String name = componentConfig.getAttribute("name", null);
+                if (name != null) {
+                    role = role + "/" + name;
+                }
+
+                this.addComponent(role, className, componentConfig, null);
+            }
+        }
+    }
+
+    private void handleInclude(String contextURI, Set loadedURIs, Configuration includeStatement)
+            throws ConfigurationException {
+        String includeURI = includeStatement.getAttribute("src", null);
+        String directoryURI = null;
+        if ( includeURI == null ) {
+            // check for directories
+            directoryURI = includeStatement.getAttribute("dir", null);                    
+        }
+        if ( includeURI == null && directoryURI == null ) {
+            throw new ConfigurationException("Include statement must either have a 'src' or 'dir' attribute, at " +
+                    includeStatement.getLocation());
+        }
+
+        // Setup the source resolver if needed
+        setupSourceResolver();
+
+        if ( includeURI != null ) {
+            Source src;
+            try {
+                src = this.cachedSourceResolver.resolveURI(includeURI, contextURI, null);
+            } catch (Exception e) {
+                throw new ConfigurationException("Cannot load '" + includeURI + "' at " + includeStatement.getLocation(), e);
+            }
+            
+            loadURI(src, loadedURIs, includeStatement);
+        } else {
+            final String pattern = includeStatement.getAttribute("pattern", null);
+            int[] parsedPattern = null;
+            if ( pattern != null ) {
+                parsedPattern = WildcardHelper.compilePattern(pattern);
+            }
+            Source directory = null;
+            try {
+                directory = this.cachedSourceResolver.resolveURI(directoryURI, contextURI, CONTEXT_PARAMETERS);
+                if ( directory instanceof TraversableSource ) {
+                    final Iterator children = ((TraversableSource)directory).getChildren().iterator();
+                    while ( children.hasNext() ) {
+                        final Source s = (Source)children.next();
+                        if ( parsedPattern == null || this.match(s.getURI(), parsedPattern)) {
+                            this.loadURI(s, loadedURIs, includeStatement);
+                        }
+                    }
+                } else {
+                    throw new ConfigurationException("Include.dir must point to a directory, '" + directory.getURI() + "' is not a directory.'");
+                }
+            } catch (IOException ioe) {
+                throw new ConfigurationException("Unable to read configurations from " + directoryURI);
+            } finally {
+                this.cachedSourceResolver.release(directory);
+            }
+        }
+    }
+
+    private void loadURI(Source src, Set loadedURIs, Configuration includeStatement) 
+    throws ConfigurationException {
+        // If already loaded: do nothing
+        try {
+
+            String uri = src.getURI();
+
+            if (!loadedURIs.contains(uri)) {
+                if ( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug("Loading configuration from: " + uri);
+                }
+                // load it and store it in the read set
+                Configuration includeConfig = null;
+                try {
+                    ConfigurationBuilder builder = new ConfigurationBuilder(this.settings);
+                    includeConfig = builder.build(src.getInputStream(), uri);
+                } catch (Exception e) {
+                    throw new ConfigurationException("Cannot load '" + uri + "' at " + includeStatement.getLocation(), e);
+                }
+                loadedURIs.add(uri);
+
+                // what is it?
+                String includeKind = includeConfig.getName();
+                if (includeKind.equals("components")) {
+                    // more components
+                    parseConfiguration(includeConfig, uri, loadedURIs);
+                } else if (includeKind.equals("role-list")) {
+                    // more roles
+                    this.roleManager.configure(includeConfig);
+                } else {
+                    throw new ConfigurationException("Unknow document '" + includeKind + "' included at " +
+                            includeStatement.getLocation());
+                }
+            }
+        } finally {
+            this.cachedSourceResolver.release(src);
+        }
+    }
+
+    /**
+     * If the parent manager does not exist or does not
+     * provide a source resolver, a simple one is created here to load the file.
+     */
+    private void setupSourceResolver() {
+        if (this.cachedSourceResolver == null) {
+
+            if (this.parentManager != null && this.parentManager.hasService(SourceResolver.ROLE)) {
+                try {
+                    this.cachedSourceResolver = (SourceResolver)this.parentManager.lookup(SourceResolver.ROLE);
+                } catch(ServiceException se) {
+                    // Unlikely to happen
+                    throw new CoreResourceNotFoundException("Cannot get source resolver from parent, at " + location, se);
+                }
+            } else {
+                // Create our own
+                SimpleSourceResolver simpleSR = new SimpleSourceResolver();
+                simpleSR.enableLogging(getLogger());
+                try {
+                    simpleSR.contextualize(this.context);
+                } catch (ContextException ce) {
+                    throw new CoreResourceNotFoundException("Cannot setup source resolver, at " + location, ce);
+                }
+                this.cachedSourceResolver = simpleSR;
+            }
+        }        
+    }
+
+    private boolean match(String uri, int[] parsedPattern ) {
+        int pos = uri.lastIndexOf('/');
+        if ( pos != -1 ) {
+            uri = uri.substring(pos+1);
+        }
+        return WildcardHelper.match(null, uri, parsedPattern);      
+    }
+
+    /**
+     * Release the source resolver that may have been created by the first call to
+     * loadConfiguration().
+     */
+    private void releaseCachedSourceResolver() {
+        if (this.cachedSourceResolver != null &&
+            this.parentManager != null && this.parentManager.hasService(SourceResolver.ROLE)) {
+            this.parentManager.release(this.cachedSourceResolver);
+        }
+        this.cachedSourceResolver = null;
+    }
+
+    /** 
+     * Check if a component can be overriden. Only {@link DefaultServiceSelector} or its subclasses can be
+     * overriden, as they directly feed this manager with their component definitions and are empty
+     * shells delegating to this manager afterwards.
+     */
+    private void checkComponentOverride(String role, String className, Configuration config,
+            ComponentHandler existingHandler) throws ConfigurationException {
+        
+        // We only allow selectors to be overloaded
+        ComponentInfo info = existingHandler.getInfo();
+        if (!className.equals(info.getServiceClassName())) {
+            throw new ConfigurationException("Role " + role + " redefined with a different class name, at " +
+                    config.getLocation());
+        }
+
+        Class clazz;
+        try {
+            clazz = this.componentEnv.loadClass(className);
+        } catch(ClassNotFoundException cnfe) {
+            throw new ConfigurationException("Cannot load class " + className + " for component at " +
+                    config.getLocation(), cnfe);
+        }
+
+        if (!DefaultServiceSelector.class.isAssignableFrom(clazz)) {
+            throw new ConfigurationException("Component declared at " + info.getLocation() + " is redefined at " +
+                    config.getLocation());
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/CoreServiceManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/DefaultServiceSelector.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/DefaultServiceSelector.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/DefaultServiceSelector.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/DefaultServiceSelector.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,220 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.components.Preloadable;
+
+/**
+ * Default component selector for Cocoon's components. This selector "flattens" its declaration
+ * by adding them as components of its containing ServiceManager. This allows a smooth transition towards
+ * a fully flat configuration by allowing the use of selectors in legacy components and also
+ * declaration of hinted components (i.e. with a role of type "rolename/hint") in the service manager.
+ *
+ * @version $Id: DefaultServiceSelector.java 326062 2005-10-18 09:31:53Z sylvain $
+ * @since 2.2
+ */
+public class DefaultServiceSelector extends AbstractLogEnabled implements ThreadSafe, Preloadable, Serviceable, Configurable, ServiceSelector {
+
+    /** Synthetic hint to alias the default component */
+    public static final String DEFAULT_HINT = "$default$";
+
+    private CoreServiceManager manager;
+    private RoleManager roleManager;
+    private String roleName;
+    private String rolePrefix;
+    
+    public void service(ServiceManager manager) throws ServiceException {
+        try {
+            this.manager = (CoreServiceManager)manager;
+        } catch (ClassCastException cce) {
+            throw new ServiceException ("DefaultServiceSelector", 
+                                        "A DefaultServiceSelector can only be hosted by a CoreServiceManager");
+        }
+    }
+    
+    public void setRole(String role) {
+        this.roleName = role;
+    }
+    
+    public void setRoleManager(RoleManager roles) {
+        this.roleManager = roles;
+    }
+
+    public void configure(Configuration config) throws ConfigurationException {
+
+        if (roleName == null) {
+            throw new ConfigurationException("No role given for DefaultServiceSelector at " + config.getLocation());
+        }
+        
+        // Remove "Selector" suffix, if any and add a trailing "/"
+        if (roleName.endsWith("Selector")) {
+            this.rolePrefix = roleName.substring(0, roleName.length() - 8) + "/";
+        } else {
+            this.rolePrefix = roleName + "/";
+        }
+
+        // Add components
+        String compInstanceName = getComponentInstanceName();
+
+        Configuration[] instances = config.getChildren();
+
+        for (int i = 0; i < instances.length; i++) {
+
+            Configuration instance = instances[i];
+            ComponentInfo info = null;
+
+            String key = instance.getAttribute("name");
+
+            String classAttr = instance.getAttribute(getClassAttributeName(), null);
+            String className;
+
+            if (compInstanceName == null) {
+                // component-instance implicitly defined by the presence of the 'class' attribute
+                if (classAttr == null) {
+                    info = this.roleManager.getDefaultServiceInfoForKey(roleName, instance.getName());
+                    className = info.getServiceClassName();
+                } else {
+                    className = classAttr;
+                }
+
+            } else {
+                // component-instances names explicitly defined
+                if (compInstanceName.equals(instance.getName())) {
+                    className = (classAttr == null) ? null : classAttr;
+                } else {
+                    info = this.roleManager.getDefaultServiceInfoForKey(roleName, instance.getName());
+                    className = info.getServiceClassName();
+                }
+            }
+
+            if (className == null) {
+                String message = "Unable to determine class name for component named '" + key +
+                    "' at " + instance.getLocation();
+
+                getLogger().error(message);
+                throw new ConfigurationException(message);
+            }
+            
+            // Add this component in the manager
+            this.manager.addComponent(this.rolePrefix + key, className, instance, info);
+        }
+        
+        // Register default key, if any
+        String defaultKey = config.getAttribute(this.getDefaultKeyAttributeName(), null);
+        if (defaultKey != null) {
+            try {
+                this.manager.addRoleAlias(this.rolePrefix + defaultKey, this.rolePrefix + DEFAULT_HINT);
+            } catch (ServiceException e) {
+                throw new ConfigurationException("Cannot set default to " + defaultKey + " at " + config.getLocation(), e);
+            }
+        }
+    }
+    
+    public Object select(Object hint) throws ServiceException {
+        String key = (hint == null) ? DEFAULT_HINT : hint.toString();
+
+        return this.manager.lookup(this.rolePrefix + key);
+    }
+
+    public boolean isSelectable(Object hint) {
+        String key = hint == null ? DEFAULT_HINT : hint.toString();
+        
+        return key != null && this.manager.hasService(this.rolePrefix + key);
+    }
+
+    public void release(Object obj) {
+        this.manager.release(obj);
+    }
+
+    // ---------------------------------------------------------------
+    /**
+     * Get the name for component-instance elements (i.e. components not defined
+     * by their role shortcut. If <code>null</code>, any element having a 'class'
+     * attribute will be considered as a component instance.
+     * <p>
+     * The default here is to return <code>null</code>, and subclasses can redefine
+     * this method to return particular values.
+     *
+     * @return <code>null</code>, but can be changed by subclasses
+     */
+    protected String getComponentInstanceName() {
+        return null;
+    }
+
+    /**
+     * Get the name of the attribute giving the class name of a component.
+     * The default here is "class", but this can be overriden in subclasses.
+     *
+     * @return "<code>class</code>", but can be changed by subclasses
+     */
+    protected String getClassAttributeName() {
+        return "class";
+    }
+
+    /**
+     * Get the name of the attribute giving the default key to use if
+     * none is given. The default here is "default", but this can be
+     * overriden in subclasses. If this method returns <code>null</code>,
+     * no default key can be specified.
+     *
+     * @return "<code>default</code>", but can be changed by subclasses
+     */
+    protected String getDefaultKeyAttributeName() {
+        return "default";
+    }
+    
+    /**
+     * A special factory for <code>DefaultServiceSelector</code>, that passes it the
+     * <code>RoleManager</code> and its role name.
+     */
+    public static class Factory extends ComponentFactory {
+        private final String role;
+        
+        public Factory(ComponentEnvironment env, ComponentInfo info, String role) 
+        throws Exception {
+            super(env, info);
+            this.role = role;
+        }
+        
+        protected void setupInstance(Object object)
+        throws Exception {
+            DefaultServiceSelector component = (DefaultServiceSelector)object;
+            
+            ContainerUtil.enableLogging(component, this.environment.logger);
+            ContainerUtil.contextualize(component, this.environment.context);
+            ContainerUtil.service(component, this.environment.serviceManager);
+            
+            component.setRoleManager(this.environment.roleManager);
+            component.setRole(this.role);
+            
+            ContainerUtil.configure(component, this.serviceInfo.getConfiguration());
+            ContainerUtil.initialize(component);
+            ContainerUtil.start(component);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/DefaultServiceSelector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/RoleManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/RoleManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/RoleManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/RoleManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,251 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.components.ComponentInfo;
+
+/**
+ * Default RoleManager implementation.  It populates the RoleManager
+ * from a configuration file.
+ *
+ * @version $Id: RoleManager.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public class RoleManager
+extends AbstractLogEnabled
+implements Configurable {
+    
+    /** Map for shorthand to role mapping */
+    private final Map shorthands = new HashMap();
+
+    /** Map for role to default classname mapping */
+    private final Map classNames = new HashMap();
+
+    /** Map for role->key to classname mapping */
+    private final Map keyClassNames = new HashMap();
+
+    /** Parent role manager for nested resolution */
+    private final RoleManager parent;
+
+    /**
+     * Default constructor--this RoleManager has no parent.
+     */
+    public RoleManager() {
+        this.parent = null;
+    }
+
+    /**
+     * Alternate constructor--this RoleManager has the specified
+     * parent.
+     *
+     * @param parent  The parent <code>RoleManager</code>.
+     */
+    public RoleManager( RoleManager parent ) {
+        this.parent = parent;
+    }
+
+    /**
+     * Retrieves the real role name from a shorthand name.  Usually
+     * the shorthand name refers to a configuration element name.  If
+     * this RoleManager does not have the match, and there is a parent
+     * RoleManager, the parent will be asked to resolve the role.
+     *
+     * @param shorthandName  The shortname that is an alias for the role.
+     * @return the official role name.
+     */
+    public final String getRoleForName( final String shorthandName ) {
+        final String role = (String)this.shorthands.get( shorthandName );
+
+        if( null == role && null != this.parent ) {
+            return this.parent.getRoleForName( shorthandName );
+        }
+
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "looking up shorthand " + shorthandName +
+                               ", returning " + role );
+        }
+
+        return role;
+    }
+
+    /**
+     * Retrieves the default class name for the specified role.  This
+     * is only called when the configuration does not specify the
+     * class explicitly.  If this RoleManager does not have the match,
+     * and there is a parent RoleManager, the parent will be asked
+     * to resolve the class name.
+     *
+     * @param role  The role that has a default implementation.
+     * @return the Fully Qualified Class Name (FQCN) for the role.
+     */
+    public final ComponentInfo getDefaultServiceInfoForRole( final String role ) {
+        final ComponentInfo info = (ComponentInfo)this.classNames.get( role );
+
+        if( info == null && this.parent != null ) {
+            return this.parent.getDefaultServiceInfoForRole( role );
+        }
+
+        return info;
+    }
+
+    /**
+     * Retrieves a default class name for a role/key combination.
+     * This is only called when a role is mapped to a
+     * StandaloneServiceSelector, and the configuration elements use
+     * shorthand names for the type of component.  If this RoleManager
+     * does not have the match, and there is a parent RoleManager, the
+     * parent will be asked to resolve the class name.
+     *
+     * @param role  The role that this shorthand refers to.
+     * @param shorthand  The shorthand name for the type of component
+     * @return the FQCN for the role/key combination.
+     */
+    public final ComponentInfo getDefaultServiceInfoForKey( final String role,
+                                                          final String shorthand ) {
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "looking up keymap for role " + role );
+        }
+
+        final Map keyMap = (Map)this.keyClassNames.get( role );
+
+        if( null == keyMap ) {
+            if( null != this.parent ) {
+                return this.parent.getDefaultServiceInfoForKey( role, shorthand );
+            } 
+            return null;
+        }
+
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "looking up classname for key " + shorthand );
+        }
+
+        final ComponentInfo s = ( ComponentInfo ) keyMap.get( shorthand );
+
+        if( s == null && this.parent != null ) {
+            return this.parent.getDefaultServiceInfoForKey( role, shorthand );
+        } 
+        return s;
+    }
+
+    /**
+     * Reads a configuration object and creates the role, shorthand,
+     * and class name mapping.
+     *
+     * @param configuration  The configuration object.
+     * @throws ConfigurationException if the configuration is malformed
+     */
+    public final void configure( final Configuration configuration )
+    throws ConfigurationException {
+        
+        // When reading a roles file, we only want "role" elements.
+        boolean strictMode = "roles-list".equals(configuration.getName());
+
+        final Configuration[] roles = configuration.getChildren();
+
+        for( int i = 0; i < roles.length; i++ ) {
+            Configuration role = roles[i];
+            
+            if (!"role".equals(role.getName())) {
+                if (strictMode) {
+                    throw new ConfigurationException("Unexpected '" + role.getName() + "' element at " + role.getLocation());
+                }
+                // Skip to next one
+                continue;
+            }
+            
+            final String roleName = role.getAttribute("name");
+            final String shorthand = role.getAttribute("shorthand", null);
+            final String defaultClassName = role.getAttribute("default-class", null);
+
+            if (shorthand != null) {
+                // Store the shorthand and check that its consistent with any previous one
+                Object previous = this.shorthands.put( shorthand, roleName );
+                if (previous != null && !previous.equals(roleName)) {
+                    throw new ConfigurationException("Shorthand '" + shorthand + "' already used for role " +
+                            previous + ": inconsistent declaration at " + role.getLocation());
+                }
+            }
+
+            if( defaultClassName != null ) {
+                ComponentInfo info = (ComponentInfo)this.classNames.get(roleName);
+                if (info == null) {
+                    // Create a new info and store it
+                    info = new ComponentInfo();
+                    info.setServiceClassName(defaultClassName);
+                    info.fill(role);
+                    this.classNames.put(roleName, info);
+                } else {
+                    // Check that it's consistent with the existing info
+                    if (!defaultClassName.equals(info.getServiceClassName())) {
+                        throw new ConfigurationException("Invalid redeclaration: default class already set to " + info.getServiceClassName() +
+                                " for role " + roleName + " at " + role.getLocation());
+                    }
+                    //FIXME: should check also other ServiceInfo members
+                }
+            }
+
+            final Configuration[] keys = role.getChildren( "hint" );
+            if( keys.length > 0 ) {
+                Map keyMap = (Map)this.keyClassNames.get(roleName);
+                if (keyMap == null) {
+                    keyMap = new HashMap();
+                    this.keyClassNames.put(roleName, keyMap);
+                }
+
+                for( int j = 0; j < keys.length; j++ ) {
+                    Configuration key = keys[j];
+                    
+                    final String shortHand = key.getAttribute( "shorthand" ).trim();
+                    final String className = key.getAttribute( "class" ).trim();
+
+                    ComponentInfo info = (ComponentInfo)keyMap.get(shortHand);
+                    if (info == null) {       
+                        info = new ComponentInfo();
+                        info.setServiceClassName(className);
+                        info.fill(key);
+    
+                        keyMap.put( shortHand, info );
+                        if( this.getLogger().isDebugEnabled() ) {
+                            this.getLogger().debug( "Adding key type " + shortHand +
+                                                    " associated with role " + roleName +
+                                                    " and class " + className );
+                        }
+                    } else {
+                        // Check that it's consistent with the existing info
+                        if (!className.equals(info.getServiceClassName())) {
+                            throw new ConfigurationException("Invalid redeclaration: class already set to " + info.getServiceClassName() +
+                                    " for hint " + shortHand + " at " + key.getLocation());
+                        }
+                        //FIXME: should check also other ServiceInfo members
+                    }
+                }
+            }
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "added Role " + roleName + " with shorthand " +
+                                   shorthand + " for " + defaultClassName );
+            }
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/container/RoleManager.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message