cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From vgritse...@apache.org
Subject svn commit: r123716 - in cocoon/trunk/src: core/java/org/apache/cocoon/components core/java/org/apache/cocoon/core/container core/test/org/apache/cocoon/core/container documentation/xdocs/userdocs/selectors
Date Thu, 30 Dec 2004 14:16:04 GMT
Author: vgritsenko
Date: Thu Dec 30 06:16:00 2004
New Revision: 123716

URL: http://svn.apache.org/viewcvs?view=rev&rev=123716
Log:
set properties!

Modified:
   cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentHandler.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java   (contents, props changed)
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java   (contents, props changed)
   cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java   (contents, props changed)
   cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java   (contents, props changed)
   cocoon/trunk/src/documentation/xdocs/userdocs/selectors/regular-expression-header-selector.xml   (props changed)

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java	Thu Dec 30 06:16:00 2004
@@ -1,225 +1,225 @@
-/*
- * Copyright 1999-2004 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.components;
-
-import java.lang.reflect.Method;
-
-import org.apache.avalon.framework.configuration.Configuration;
-
-/**
- * Meta-information about a service
- *  
- * @version CVS $Id: LifecycleHelper.java 55255 2004-10-21 19:41:15Z cziegeler $
- */
-public class ServiceInfo {
-
-    public static final int MODEL_PRIMITIVE = 0;
-    public static final int MODEL_SINGLETON = 1;
-    public static final int MODEL_POOLED    = 2;
-    
-    private int model;
-    private String initMethodName;
-    private String destroyMethodName;
-    private String poolInMethodName;
-    private String poolOutMethodName;
-    private Class serviceClass;
-    private String serviceClassName;
-    private Method initMethod;
-    private Method destroyMethod;
-    private Method poolInMethod;
-    private Method poolOutMethod;
-    private Configuration configuration;
-    
-    public ServiceInfo() {
-        this.model = MODEL_PRIMITIVE;
-    }
-    
-    /**
-     * @return Returns the model.
-     */
-    public int getModel() {
-        return model;
-    }
-    
-    /**
-     * @param model The model to set.
-     */
-    public void setModel(int model) {
-        this.model = model;
-    }
-    
-    /**
-     * @return Returns the destroyMethod.
-     */
-    public String getDestroyMethodName() {
-        return destroyMethodName;
-    }
-    
-    /**
-     * @param destroyMethod The destroyMethod to set.
-     */
-    public void setDestroyMethodName(String destroyMethod) {
-        this.destroyMethodName = destroyMethod;
-    }
-    
-    /**
-     * @return Returns the initMethod.
-     */
-    public String getInitMethodName() {
-        return initMethodName;
-    }
-    
-    /**
-     * @param initMethod The initMethod to set.
-     */
-    public void setInitMethodName(String initMethod) {
-        this.initMethodName = initMethod;
-    }
-    
-    /**
-     * @return Returns the poolInMethodName
-     */
-    public String getPoolInMethodName() {
-        return this.poolInMethodName;
-    }
-    
-    /**
-     * @param poolMethod The poolInMethod name to set.
-     */
-    public void setPoolInMethodName(String poolMethod) {
-        this.poolInMethodName = poolMethod;
-    }
-    
-    /**
-     * @return Returns the poolOutMethodName
-     */
-    public String getPoolOutMethodName() {
-        return this.poolOutMethodName;
-    }
-    
-    /**
-     * @param poolMethod The poolOutMethod name to set.
-     */
-    public void setPoolOutMethodName(String poolMethod) {
-        this.poolOutMethodName = poolMethod;
-    }
-
-    /**
-     * @return Returns the destroyMethod.
-     */
-    public Method getDestroyMethod() throws Exception {
-        if ( this.destroyMethod == null && this.destroyMethodName != null ) {
-            this.destroyMethod = this.serviceClass.getMethod(this.destroyMethodName, null);
-        }
-        return destroyMethod;
-    }
-
-    /**
-     * @return Returns the initMethod.
-     */
-    public Method getInitMethod() throws Exception {
-        if ( this.initMethod == null && this.initMethodName != null ) {
-            this.initMethod = this.serviceClass.getMethod(this.initMethodName, null);
-        }
-        return initMethod;
-    }
-
-    /**
-     * @return Returns the poolInMethod.
-     */
-    public Method getPoolInMethod() throws Exception {
-        if ( this.poolInMethod == null && this.poolInMethodName != null ) {
-            this.poolInMethod = this.serviceClass.getMethod(this.poolInMethodName, null);
-        }
-        return poolInMethod;
-    }
-
-    /**
-     * @return Returns the poolInMethod.
-     */
-    public Method getPoolOutMethod() throws Exception {
-        if ( this.poolOutMethod == null && this.poolOutMethodName != null ) {
-            this.poolOutMethod = this.serviceClass.getMethod(this.poolOutMethodName, null);
-        }
-        return poolOutMethod;
-    }
-
-    /**
-     * @return Returns the serviceClass.
-     */
-    public Class getServiceClass() {
-        return serviceClass;
-    }
-    
-    /**
-     * @return Returns the serviceClassName.
-     */
-    public String getServiceClassName() {
-        return serviceClassName;
-    }
-    
-    /**
-     * @param serviceClassName The serviceClassName to set.
-     */
-    public void setServiceClassName(String serviceClassName) {
-        this.serviceClassName = serviceClassName;
-    }
-    
-    /**
-     * @param serviceClass The serviceClass to set.
-     */
-    public void setServiceClass(Class serviceClass) {
-        this.serviceClass = serviceClass;
-    }
-        
-    /**
-     * @return Returns the configuration.
-     */
-    public Configuration getConfiguration() {
-        return configuration;
-    }
-    /**
-     * @param configuration The configuration to set.
-     */
-    public void setConfiguration(Configuration configuration) {
-        this.configuration = configuration;
-    }
-    
-    public String getLocation() {
-        return this.configuration.getLocation();
-    }
-    
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-        return "ServiceInfo: {class=" + this.getServiceClassName()+"}";
-    }
-    
-    public void fill(Configuration attr) {
-        // test model
-        final String model = attr.getAttribute("model", null);
-        if ( "pooled".equals(model) ) {
-            this.setModel(ServiceInfo.MODEL_POOLED);
-            this.setPoolInMethodName(attr.getAttribute("pool-in", null));
-            this.setPoolOutMethodName(attr.getAttribute("pool-out", null));
-        } else if ( "singleton".equals(model) ) {
-            this.setModel(ServiceInfo.MODEL_SINGLETON);
-        }
-        this.setInitMethodName(attr.getAttribute("init", null));
-        this.setDestroyMethodName(attr.getAttribute("destroy", null));
-    }
-}
+/*
+ * Copyright 1999-2004 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.components;
+
+import java.lang.reflect.Method;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+/**
+ * Meta-information about a service
+ *  
+ * @version CVS $Id$
+ */
+public class ServiceInfo {
+
+    public static final int MODEL_PRIMITIVE = 0;
+    public static final int MODEL_SINGLETON = 1;
+    public static final int MODEL_POOLED    = 2;
+    
+    private int model;
+    private String initMethodName;
+    private String destroyMethodName;
+    private String poolInMethodName;
+    private String poolOutMethodName;
+    private Class serviceClass;
+    private String serviceClassName;
+    private Method initMethod;
+    private Method destroyMethod;
+    private Method poolInMethod;
+    private Method poolOutMethod;
+    private Configuration configuration;
+    
+    public ServiceInfo() {
+        this.model = MODEL_PRIMITIVE;
+    }
+    
+    /**
+     * @return Returns the model.
+     */
+    public int getModel() {
+        return model;
+    }
+    
+    /**
+     * @param model The model to set.
+     */
+    public void setModel(int model) {
+        this.model = model;
+    }
+    
+    /**
+     * @return Returns the destroyMethod.
+     */
+    public String getDestroyMethodName() {
+        return destroyMethodName;
+    }
+    
+    /**
+     * @param destroyMethod The destroyMethod to set.
+     */
+    public void setDestroyMethodName(String destroyMethod) {
+        this.destroyMethodName = destroyMethod;
+    }
+    
+    /**
+     * @return Returns the initMethod.
+     */
+    public String getInitMethodName() {
+        return initMethodName;
+    }
+    
+    /**
+     * @param initMethod The initMethod to set.
+     */
+    public void setInitMethodName(String initMethod) {
+        this.initMethodName = initMethod;
+    }
+    
+    /**
+     * @return Returns the poolInMethodName
+     */
+    public String getPoolInMethodName() {
+        return this.poolInMethodName;
+    }
+    
+    /**
+     * @param poolMethod The poolInMethod name to set.
+     */
+    public void setPoolInMethodName(String poolMethod) {
+        this.poolInMethodName = poolMethod;
+    }
+    
+    /**
+     * @return Returns the poolOutMethodName
+     */
+    public String getPoolOutMethodName() {
+        return this.poolOutMethodName;
+    }
+    
+    /**
+     * @param poolMethod The poolOutMethod name to set.
+     */
+    public void setPoolOutMethodName(String poolMethod) {
+        this.poolOutMethodName = poolMethod;
+    }
+
+    /**
+     * @return Returns the destroyMethod.
+     */
+    public Method getDestroyMethod() throws Exception {
+        if ( this.destroyMethod == null && this.destroyMethodName != null ) {
+            this.destroyMethod = this.serviceClass.getMethod(this.destroyMethodName, null);
+        }
+        return destroyMethod;
+    }
+
+    /**
+     * @return Returns the initMethod.
+     */
+    public Method getInitMethod() throws Exception {
+        if ( this.initMethod == null && this.initMethodName != null ) {
+            this.initMethod = this.serviceClass.getMethod(this.initMethodName, null);
+        }
+        return initMethod;
+    }
+
+    /**
+     * @return Returns the poolInMethod.
+     */
+    public Method getPoolInMethod() throws Exception {
+        if ( this.poolInMethod == null && this.poolInMethodName != null ) {
+            this.poolInMethod = this.serviceClass.getMethod(this.poolInMethodName, null);
+        }
+        return poolInMethod;
+    }
+
+    /**
+     * @return Returns the poolInMethod.
+     */
+    public Method getPoolOutMethod() throws Exception {
+        if ( this.poolOutMethod == null && this.poolOutMethodName != null ) {
+            this.poolOutMethod = this.serviceClass.getMethod(this.poolOutMethodName, null);
+        }
+        return poolOutMethod;
+    }
+
+    /**
+     * @return Returns the serviceClass.
+     */
+    public Class getServiceClass() {
+        return serviceClass;
+    }
+    
+    /**
+     * @return Returns the serviceClassName.
+     */
+    public String getServiceClassName() {
+        return serviceClassName;
+    }
+    
+    /**
+     * @param serviceClassName The serviceClassName to set.
+     */
+    public void setServiceClassName(String serviceClassName) {
+        this.serviceClassName = serviceClassName;
+    }
+    
+    /**
+     * @param serviceClass The serviceClass to set.
+     */
+    public void setServiceClass(Class serviceClass) {
+        this.serviceClass = serviceClass;
+    }
+        
+    /**
+     * @return Returns the configuration.
+     */
+    public Configuration getConfiguration() {
+        return configuration;
+    }
+    /**
+     * @param configuration The configuration to set.
+     */
+    public void setConfiguration(Configuration configuration) {
+        this.configuration = configuration;
+    }
+    
+    public String getLocation() {
+        return this.configuration.getLocation();
+    }
+    
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return "ServiceInfo: {class=" + this.getServiceClassName()+"}";
+    }
+    
+    public void fill(Configuration attr) {
+        // test model
+        final String model = attr.getAttribute("model", null);
+        if ( "pooled".equals(model) ) {
+            this.setModel(ServiceInfo.MODEL_POOLED);
+            this.setPoolInMethodName(attr.getAttribute("pool-in", null));
+            this.setPoolOutMethodName(attr.getAttribute("pool-out", null));
+        } else if ( "singleton".equals(model) ) {
+            this.setModel(ServiceInfo.MODEL_SINGLETON);
+        }
+        this.setInitMethodName(attr.getAttribute("init", null));
+        this.setDestroyMethodName(attr.getAttribute("destroy", null));
+    }
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java	Thu Dec 30 06:16:00 2004
@@ -1,294 +1,294 @@
-/* 
- * Copyright 2002-2004 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.excalibur.logger.LoggerManager;
-import org.apache.avalon.excalibur.pool.Poolable;
-import org.apache.avalon.framework.component.Composable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.context.Context;
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.thread.SingleThreaded;
-import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.components.ServiceInfo;
-
-/**
- * This class acts like a Factory to instantiate the correct version
- * of the component handler that you need.
- *
- * @version CVS $Id: AbstractComponentHandler.java 55144 2004-10-20 12:26:09Z ugo $
- */
-public abstract class AbstractComponentHandler 
-implements ComponentHandler {
-    
-    private final Object referenceSemaphore = new Object();
-    private int references = 0;
-
-    protected final Logger logger;
-    
-    /** This factory is used to created new objects */
-    protected final ComponentFactory factory;
-    
-    /** State management boolean stating whether the Handler is disposed or not */
-    protected boolean disposed = false;
-
-    /** State management boolean stating whether the Handler is initialized or not */
-    protected boolean initialized = false;
-    
-    private ServiceInfo info;
-
-    /**
-     * Looks up and returns a component handler for a given component class.
-     *
-     * @param role the component's role. Can be <code>null</code> if the role isn't known.
-     * @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 service.
-     * @param context The current context object.
-     * @param logger  The current logger
-     * @param loggerManager The current LoggerManager.
-     *
-     * @throws Exception If there were any problems obtaining a ComponentHandler
-     */
-    public static ComponentHandler getComponentHandler( final String role,
-                                                        final Class componentClass,
-                                                        final Configuration configuration,
-                                                        final ServiceManager serviceManager,
-                                                        final Context context,
-                                                        final Logger logger,
-                                                        final LoggerManager loggerManager,
-                                                        final RoleManager roleManager)
-    throws Exception {
-        int numInterfaces = 0;
-
-        final ServiceInfo info = new ServiceInfo();
-        info.setServiceClass(componentClass);
-        info.setServiceClassName(componentClass.getName());
-        info.setConfiguration(configuration);
-        
-        // Early check for Composable
-        if ( Composable.class.isAssignableFrom( componentClass ) ) {
-            throw new Exception("Interface Composable is not supported anymore. Please change class "
-                                + componentClass.getName() + " to use Serviceable instead.");
-        }
-
-        if( SingleThreaded.class.isAssignableFrom( componentClass ) ) {
-            numInterfaces++;
-            info.setModel(ServiceInfo.MODEL_PRIMITIVE);
-        }
-
-        if( ThreadSafe.class.isAssignableFrom( componentClass ) ) {
-            numInterfaces++;
-            info.setModel(ServiceInfo.MODEL_SINGLETON);
-        }
-
-        if( Poolable.class.isAssignableFrom( componentClass ) ) {
-            numInterfaces++;
-            info.setModel(ServiceInfo.MODEL_POOLED);
-        }
-
-        if( numInterfaces > 1 ) {
-            throw new Exception( "[CONFLICT] More than one lifecycle interface in "
-                                 + componentClass.getName() + "  May implement no more than one of "
-                                 + "SingleThreaded, ThreadSafe, or Poolable" );
-        }
-
-        if ( numInterfaces == 0 ) {
-            // this component does not use avalon interfaces, so get the info from the configuration
-            info.fill(configuration);
-        }
-        
-        // Create the factory to use to create the instances of the Component.
-        ComponentFactory factory;
-        
-        if (DefaultServiceSelector.class.isAssignableFrom(componentClass)) {
-            // Special factory for DefaultServiceSelector
-            factory = new DefaultServiceSelector.Factory(serviceManager, context, logger, loggerManager,
-                    roleManager, info, role);
-            
-        } else if (StandaloneServiceSelector.class.isAssignableFrom(componentClass)) {
-                // Special factory for StandaloneServiceSelector
-                factory = new StandaloneServiceSelector.Factory(serviceManager, context, logger, loggerManager,
-                        roleManager, info);
-                
-        } else {
-            factory = new ComponentFactory(serviceManager, context, logger, loggerManager,
-                    roleManager, info);
-        }
-
-        AbstractComponentHandler handler;
-        
-        if( info.getModel() == ServiceInfo.MODEL_POOLED )  {
-            handler = new PoolableComponentHandler( info, logger, factory, configuration );
-        } else if( info.getModel() == ServiceInfo.MODEL_SINGLETON ) {
-            handler = new ThreadSafeComponentHandler( info, logger, factory );
-        } else {
-            // This is a SingleThreaded component
-            handler = new SingleThreadedComponentHandler( info, logger, factory );
-        }
-
-        return handler;
-    }
-
-    /**
-     * Creates a new ComponentHandler.
-     */
-    public AbstractComponentHandler(ServiceInfo info, Logger logger, ComponentFactory factory) {
-        this.info = info;
-        this.logger = logger;
-        this.factory = factory;
-    }
-    
-    public ServiceInfo getInfo() {
-        return this.info;
-    }
-
-    /**
-     * Get an instance of the type of component handled by this handler.
-     * <p>
-     * Subclasses should not extend this method but rather the doGet method below otherwise
-     *  reference counts will not be supported.
-     * <p>
-     *
-     * @return an instance
-     * @exception Exception if an error occurs
-     */
-    public final Object get() throws Exception {
-        if( !this.initialized ) {
-            throw new IllegalStateException(
-                "You cannot get a component from an uninitialized handler." );
-        }
-        if( this.disposed ) {
-            throw new IllegalStateException( "You cannot get a component from a disposed handler." );
-        }
-
-        final Object component = this.doGet();
-
-        synchronized( this.referenceSemaphore ) {
-            this.references++;
-        }
-
-        return component;
-    }
-
-    /**
-     * Put back an instance of the type of component handled by this handler.
-     * <p>
-     * Subclasses should not extend this method but rather the doPut method below otherwise
-     *  reference counts will not be supported.
-     * <p>
-     *
-     * @param component a service
-     * @exception Exception if an error occurs
-     */
-    public final void put( Object component ) 
-    throws Exception {
-        if( !this.initialized ) {
-            throw new IllegalStateException(
-                "You cannot put a component to an uninitialized handler." );
-        }
-        //  The reference count must be decremented before any calls to doPut.
-        //  If there is another thread blocking, then this thread could stay deep inside
-        //  doPut for an undetermined amount of time until the thread scheduler gives it
-        //  some cycles again.  (It happened).  All ComponentHandler state must therefor
-        //  reflect the thread having left this method before the call to doPut to avoid
-        //  warning messages from the dispose() cycle if that takes place before this
-        //  thread has a chance to continue.
-        synchronized( this.referenceSemaphore ) {
-            this.references--;
-        }
-
-        try {
-            this.doPut( component );
-        } catch( Throwable t ) {
-            this.logger.error("Exception during putting back a component.", t);
-        }
-    }
-
-    /**
-     * Concrete implementation of getting a component.
-     *
-     * @return a service
-     * @exception Exception if an error occurs
-     */
-    protected abstract Object doGet() throws Exception;
-
-    /**
-     * Concrete implementation of putting back a component.
-     *
-     * @param component a <code>Component</code> value
-     * @exception Exception if an error occurs
-     */
-    protected abstract void doPut( Object component ) throws Exception;
-
-    /**
-     * Default here is to return <code>false</code>
-     */
-    public boolean isSingleton() {
-        return false;
-    }
-    
-    /**
-     * Returns <code>true</code> if this component handler can safely be
-     * disposed (i.e. none of the components it is handling are still
-     * being used).
-     *
-     * @return <code>true</code> if this component handler can safely be
-     *         disposed; <code>false</code> otherwise
-     */
-    public final boolean canBeDisposed() {
-        return ( this.references == 0 );
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.cocoon.core.container.ComponentHandler#dispose()
-     */
-    public void dispose() {
-        this.disposed = true;
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.cocoon.core.container.ComponentHandler#initialize()
-     */
-    public void initialize() throws Exception {
-        if( this.initialized ) {
-            return;
-        }
-        this.initialized = true;
-        if( this.logger.isDebugEnabled() ) {
-            this.logger.debug( "ThreadSafeComponentHandler initialized for: " + this.factory.getCreatedClass().getName() );
-        }
-    }
-    
-    /**
-     * Decommission a component
-     * @param component Object to be decommissioned
-     */
-    protected void decommission( final Object component ) {
-        try {
-            this.factory.decommission( component );
-        } catch( final Exception e ) {
-            if( this.logger.isWarnEnabled() ) {
-                this.logger.warn( "Error decommissioning component: "
-                    + this.factory.getCreatedClass().getName(), e );
-            }
-        }
-    }
-    
-}
+/* 
+ * Copyright 2002-2004 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.excalibur.logger.LoggerManager;
+import org.apache.avalon.excalibur.pool.Poolable;
+import org.apache.avalon.framework.component.Composable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.SingleThreaded;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ServiceInfo;
+
+/**
+ * This class acts like a Factory to instantiate the correct version
+ * of the component handler that you need.
+ *
+ * @version CVS $Id$
+ */
+public abstract class AbstractComponentHandler 
+implements ComponentHandler {
+    
+    private final Object referenceSemaphore = new Object();
+    private int references = 0;
+
+    protected final Logger logger;
+    
+    /** This factory is used to created new objects */
+    protected final ComponentFactory factory;
+    
+    /** State management boolean stating whether the Handler is disposed or not */
+    protected boolean disposed = false;
+
+    /** State management boolean stating whether the Handler is initialized or not */
+    protected boolean initialized = false;
+    
+    private ServiceInfo info;
+
+    /**
+     * Looks up and returns a component handler for a given component class.
+     *
+     * @param role the component's role. Can be <code>null</code> if the role isn't known.
+     * @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 service.
+     * @param context The current context object.
+     * @param logger  The current logger
+     * @param loggerManager The current LoggerManager.
+     *
+     * @throws Exception If there were any problems obtaining a ComponentHandler
+     */
+    public static ComponentHandler getComponentHandler( final String role,
+                                                        final Class componentClass,
+                                                        final Configuration configuration,
+                                                        final ServiceManager serviceManager,
+                                                        final Context context,
+                                                        final Logger logger,
+                                                        final LoggerManager loggerManager,
+                                                        final RoleManager roleManager)
+    throws Exception {
+        int numInterfaces = 0;
+
+        final ServiceInfo info = new ServiceInfo();
+        info.setServiceClass(componentClass);
+        info.setServiceClassName(componentClass.getName());
+        info.setConfiguration(configuration);
+        
+        // Early check for Composable
+        if ( Composable.class.isAssignableFrom( componentClass ) ) {
+            throw new Exception("Interface Composable is not supported anymore. Please change class "
+                                + componentClass.getName() + " to use Serviceable instead.");
+        }
+
+        if( SingleThreaded.class.isAssignableFrom( componentClass ) ) {
+            numInterfaces++;
+            info.setModel(ServiceInfo.MODEL_PRIMITIVE);
+        }
+
+        if( ThreadSafe.class.isAssignableFrom( componentClass ) ) {
+            numInterfaces++;
+            info.setModel(ServiceInfo.MODEL_SINGLETON);
+        }
+
+        if( Poolable.class.isAssignableFrom( componentClass ) ) {
+            numInterfaces++;
+            info.setModel(ServiceInfo.MODEL_POOLED);
+        }
+
+        if( numInterfaces > 1 ) {
+            throw new Exception( "[CONFLICT] More than one lifecycle interface in "
+                                 + componentClass.getName() + "  May implement no more than one of "
+                                 + "SingleThreaded, ThreadSafe, or Poolable" );
+        }
+
+        if ( numInterfaces == 0 ) {
+            // this component does not use avalon interfaces, so get the info from the configuration
+            info.fill(configuration);
+        }
+        
+        // Create the factory to use to create the instances of the Component.
+        ComponentFactory factory;
+        
+        if (DefaultServiceSelector.class.isAssignableFrom(componentClass)) {
+            // Special factory for DefaultServiceSelector
+            factory = new DefaultServiceSelector.Factory(serviceManager, context, logger, loggerManager,
+                    roleManager, info, role);
+            
+        } else if (StandaloneServiceSelector.class.isAssignableFrom(componentClass)) {
+                // Special factory for StandaloneServiceSelector
+                factory = new StandaloneServiceSelector.Factory(serviceManager, context, logger, loggerManager,
+                        roleManager, info);
+                
+        } else {
+            factory = new ComponentFactory(serviceManager, context, logger, loggerManager,
+                    roleManager, info);
+        }
+
+        AbstractComponentHandler handler;
+        
+        if( info.getModel() == ServiceInfo.MODEL_POOLED )  {
+            handler = new PoolableComponentHandler( info, logger, factory, configuration );
+        } else if( info.getModel() == ServiceInfo.MODEL_SINGLETON ) {
+            handler = new ThreadSafeComponentHandler( info, logger, factory );
+        } else {
+            // This is a SingleThreaded component
+            handler = new SingleThreadedComponentHandler( info, logger, factory );
+        }
+
+        return handler;
+    }
+
+    /**
+     * Creates a new ComponentHandler.
+     */
+    public AbstractComponentHandler(ServiceInfo info, Logger logger, ComponentFactory factory) {
+        this.info = info;
+        this.logger = logger;
+        this.factory = factory;
+    }
+    
+    public ServiceInfo getInfo() {
+        return this.info;
+    }
+
+    /**
+     * Get an instance of the type of component handled by this handler.
+     * <p>
+     * Subclasses should not extend this method but rather the doGet method below otherwise
+     *  reference counts will not be supported.
+     * <p>
+     *
+     * @return an instance
+     * @exception Exception if an error occurs
+     */
+    public final Object get() throws Exception {
+        if( !this.initialized ) {
+            throw new IllegalStateException(
+                "You cannot get a component from an uninitialized handler." );
+        }
+        if( this.disposed ) {
+            throw new IllegalStateException( "You cannot get a component from a disposed handler." );
+        }
+
+        final Object component = this.doGet();
+
+        synchronized( this.referenceSemaphore ) {
+            this.references++;
+        }
+
+        return component;
+    }
+
+    /**
+     * Put back an instance of the type of component handled by this handler.
+     * <p>
+     * Subclasses should not extend this method but rather the doPut method below otherwise
+     *  reference counts will not be supported.
+     * <p>
+     *
+     * @param component a service
+     * @exception Exception if an error occurs
+     */
+    public final void put( Object component ) 
+    throws Exception {
+        if( !this.initialized ) {
+            throw new IllegalStateException(
+                "You cannot put a component to an uninitialized handler." );
+        }
+        //  The reference count must be decremented before any calls to doPut.
+        //  If there is another thread blocking, then this thread could stay deep inside
+        //  doPut for an undetermined amount of time until the thread scheduler gives it
+        //  some cycles again.  (It happened).  All ComponentHandler state must therefor
+        //  reflect the thread having left this method before the call to doPut to avoid
+        //  warning messages from the dispose() cycle if that takes place before this
+        //  thread has a chance to continue.
+        synchronized( this.referenceSemaphore ) {
+            this.references--;
+        }
+
+        try {
+            this.doPut( component );
+        } catch( Throwable t ) {
+            this.logger.error("Exception during putting back a component.", t);
+        }
+    }
+
+    /**
+     * Concrete implementation of getting a component.
+     *
+     * @return a service
+     * @exception Exception if an error occurs
+     */
+    protected abstract Object doGet() throws Exception;
+
+    /**
+     * Concrete implementation of putting back a component.
+     *
+     * @param component a <code>Component</code> value
+     * @exception Exception if an error occurs
+     */
+    protected abstract void doPut( Object component ) throws Exception;
+
+    /**
+     * Default here is to return <code>false</code>
+     */
+    public boolean isSingleton() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>true</code> if this component handler can safely be
+     * disposed (i.e. none of the components it is handling are still
+     * being used).
+     *
+     * @return <code>true</code> if this component handler can safely be
+     *         disposed; <code>false</code> otherwise
+     */
+    public final boolean canBeDisposed() {
+        return ( this.references == 0 );
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#dispose()
+     */
+    public void dispose() {
+        this.disposed = true;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#initialize()
+     */
+    public void initialize() throws Exception {
+        if( this.initialized ) {
+            return;
+        }
+        this.initialized = true;
+        if( this.logger.isDebugEnabled() ) {
+            this.logger.debug( "ThreadSafeComponentHandler initialized for: " + this.factory.getCreatedClass().getName() );
+        }
+    }
+    
+    /**
+     * Decommission a component
+     * @param component Object to be decommissioned
+     */
+    protected void decommission( final Object component ) {
+        try {
+            this.factory.decommission( component );
+        } catch( final Exception e ) {
+            if( this.logger.isWarnEnabled() ) {
+                this.logger.warn( "Error decommissioning component: "
+                    + this.factory.getCreatedClass().getName(), e );
+            }
+        }
+    }
+    
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java	Thu Dec 30 06:16:00 2004
@@ -1,171 +1,171 @@
-/* 
- * Copyright 2002-2004 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;
-
-/**
- * Base class for all service managers: ServiceManager and ServiceSelector
- *
- * @version CVS $Id: AbstractServiceManager.java 55144 2004-10-20 12:26:09Z ugo $
- */
-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;
-
-    
-    /* (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)
-    throws Exception {
-        return AbstractComponentHandler.getComponentHandler(role,
-                                                     componentClass,
-                                                     configuration,
-                                                     serviceManager,
-                                                     this.context,
-                                                     this.getLogger(),
-                                                     this.loggerManager,
-                                                     this.roleManager);
-    }
-
-    protected void addComponent(String className,
-                                String role,
-                                Configuration configuration) 
-    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 + ")" );
-            }
-
-            final Class clazz = this.getClass().getClassLoader().loadClass( className );
-            this.addComponent( role, clazz, configuration );
-        } 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)
-    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;
-    }
-}
+/* 
+ * Copyright 2002-2004 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;
+
+/**
+ * Base class for all service managers: ServiceManager and ServiceSelector
+ *
+ * @version CVS $Id$
+ */
+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;
+
+    
+    /* (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)
+    throws Exception {
+        return AbstractComponentHandler.getComponentHandler(role,
+                                                     componentClass,
+                                                     configuration,
+                                                     serviceManager,
+                                                     this.context,
+                                                     this.getLogger(),
+                                                     this.loggerManager,
+                                                     this.roleManager);
+    }
+
+    protected void addComponent(String className,
+                                String role,
+                                Configuration configuration) 
+    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 + ")" );
+            }
+
+            final Class clazz = this.getClass().getClassLoader().loadClass( className );
+            this.addComponent( role, clazz, configuration );
+        } 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)
+    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;
+    }
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java	Thu Dec 30 06:16:00 2004
@@ -1,639 +1,639 @@
-/* 
- * Copyright 2002-2004 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.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.avalon.framework.CascadingRuntimeException;
-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.configuration.DefaultConfigurationBuilder;
-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.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.cocoon.components.ServiceInfo;
-import org.apache.cocoon.core.source.SimpleSourceResolver;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.source.SourceResolver;
-
-/**
- * Default service manager for Cocoon's components.
- *
- * @version SVN $Revision: 1.6 $Id: CocoonServiceManager.java 55165 2004-10-20 16:51:50Z cziegeler $
- */
-public class CocoonServiceManager
-extends AbstractServiceManager
-implements ServiceManager, Configurable {
-    
-    /** The location where this manager is defined */
-    protected String location;
-    
-    /** The parent ServiceManager */
-    protected ServiceManager parentManager;
-    
-    /** added component handlers before initialization to maintain
-     *  the order of initialization
-     */
-    private final List newComponentHandlers = new ArrayList();
-
-    /** Temporary list of parent-aware components.  Will be null for most of
-     * our lifecycle. */
-    private ArrayList parentAwareComponents = new ArrayList();
-
-    /** The resolver used to resolve includes. It is lazily loaded in {@link #getSourceResolver()}. */
-    private SourceResolver cachedSourceResolver;
-
-    /** Create the ServiceManager with a parent ServiceManager */
-    public CocoonServiceManager( final ServiceManager parent ) {
-        this.parentManager = parent;
-        
-        RoleManager parentRoleManager = null;
-        // get role manager and logger manager
-        if ( parent instanceof CocoonServiceManager ) {
-            parentRoleManager = ((CocoonServiceManager)parent).roleManager;
-            this.loggerManager = ((CocoonServiceManager)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);
-    }
-    
-    /* (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.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 CocoonServiceManager [" + role + "]" );
-            }
-        }
-
-        if( this.disposed ) {
-            throw new IllegalStateException(
-                "You cannot lookup components on a disposed CocoonServiceManager" );
-        }
-
-        if( role == null ) {
-            final String message =
-                "CocoonServiceManager 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 ServiceInfo 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 Class componentClass = this.getClass().getClassLoader().loadClass( info.getServiceClassName() );
-
-                        final Configuration configuration = new DefaultConfiguration( "", "-" );
-
-                        handler = this.getComponentHandler(role,
-                                                       componentClass,
-                                                       configuration,
-                                                       this);
-
-                        handler.initialize();
-                    } 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 );
-                    }
-
-                    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( final IllegalStateException ise ) {
-            try {
-                handler.initialize();
-                component = handler.get();
-                
-            } catch( final ServiceException ce ) {
-                // Rethrow instead of wrapping a ServiceException with another one
-                throw ce;
-            } 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 );
-            }
-        } 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;
-    }
-
-    /**
-     * Initialize the component
-     * @throws ServiceException
-     */
-    protected void initialize(String role, Object component) 
-    throws ServiceException {
-        // we do nothing here, can be used in subclasses
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
-     */
-    public boolean hasService( final String role ) {
-        if( !this.initialized ) return false;
-        if( 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#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." );
-        }
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
-     */
-    public void configure(Configuration configuration) throws ConfigurationException {
-        // Setup location
-        if (this.location == null) {
-            // First call to configure()
-            this.location = configuration.getLocation();
-        }
-        
-        try {
-            // and load configuration with a empty list of loaded configurations
-            doConfigure(configuration, new HashSet());
-        } finally {
-            // Release any source resolver that may have been created to load includes
-            releaseCachedSourceResolver();
-        }
-    }
-
-    private void doConfigure(final Configuration configuration, Set loadedURIs) throws ConfigurationException {
-        
-        // Read roles
-        String rolesURI = configuration.getAttribute("roles", null);
-        if (rolesURI != null) {
-            Configuration roles = loadConfiguration(rolesURI, configuration.getLocation());
-            this.roleManager.configure(roles);
-        }
-
-        // Set components
-        final Configuration[] configurations = configuration.getChildren();
-
-        for( int i = 0; i < configurations.length; i++ ) {
-            Configuration componentConfig = configurations[i];
-            
-            String componentName = componentConfig.getName();
-            
-            if ("include".equals(componentName)) {
-                String includeURI = componentConfig.getAttribute("src");
-                if (loadedURIs.contains(includeURI)) {
-                    // Already loaded: skip to next configuration element
-                    continue;
-                }
-                // load it and store it in the read set
-                Configuration includeConfig = loadConfiguration(includeURI, componentConfig.getLocation());
-                loadedURIs.add(includeURI);
-                
-                // what is it?
-                String includeKind = includeConfig.getName();
-                if (includeKind.equals("components")) {
-                    // more components
-                    doConfigure(includeConfig, loadedURIs);
-                } else if (includeKind.equals("role-list")) {
-                    // more roles
-                    this.roleManager.configure(includeConfig);
-                } else {
-                    throw new ConfigurationException("Unknow document '" + includeKind + "' included at " +
-                            componentConfig.getLocation());
-                }
-
-            } 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 ServiceInfo 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(className, role, componentConfig);
-            }
-        }
-    }
-
-    /* (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;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.avalon.framework.activity.Initializable#initialize()
-     */
-    public void initialize()
-    throws Exception {
-        super.initialize();
-
-        for( int i = 0; i < this.newComponentHandlers.size(); i++ ) {
-            final ComponentHandler handler =
-                (ComponentHandler)this.newComponentHandlers.get( i );
-            try {
-                handler.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;
-            }
-        }
-
-        List keys = new ArrayList( this.componentHandlers.keySet() );
-
-        for( int i = 0; i < keys.size(); i++ ) {
-            final Object key = keys.get( i );
-            final ComponentHandler handler =
-                (ComponentHandler)this.componentHandlers.get( key );
-
-            if( !this.newComponentHandlers.contains( handler ) ) {
-                try {
-                    handler.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;
-                }
-            }
-        }
-        this.newComponentHandlers.clear();
-        
-        // Initialize parent aware components
-        if (this.parentAwareComponents == null) {
-            throw new ServiceException(null, "CocoonServiceManager already initialized");
-        }
-
-        // Set parents for parentAware components
-        Iterator iter = this.parentAwareComponents.iterator();
-        while (iter.hasNext()) {
-            String role = (String)iter.next();
-            if ( this.parentManager != null && this.parentManager.hasService( role ) ) {
-                // lookup new component
-                Object component = null;
-                try {
-                    component = this.lookup( role );
-                    ((CocoonServiceSelector)component).setParentLocator( this.parentManager, role );
-                } catch (ServiceException ignore) {
-                    // we don't set the parent then
-                } finally {
-                    this.release( component );
-                }
-            }
-        }
-        this.parentAwareComponents = null;  // null to save memory, and catch logic bugs.
-        
-//        Object[] keyArray = this.componentHandlers.keySet().toArray();
-//        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;
-            }
-        }
-        super.dispose();
-    }
-
-    /**
-     * Add a new component to the manager.
-     *
-     * @param role the role name for the new component.
-     * @param component the class of this component.
-     * @param configuration the configuration for this component.
-     */
-    public void addComponent( final String role,
-                              final Class component,
-                              final Configuration configuration )
-    throws ServiceException {
-        if( this.initialized ) {
-            throw new ServiceException( role,
-                "Cannot add components to an initialized CocoonServiceManager." );
-        }
-
-        if( this.getLogger().isDebugEnabled() ) {
-            this.getLogger().debug( "Attempting to get handler for role [" + role + "]" );
-        }
-
-        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role);
-        if (handler != null) {
-            // Overloaded component: we only allow selectors to be overloaded
-            ServiceInfo info = handler.getInfo();
-            if (!DefaultServiceSelector.class.isAssignableFrom(component) ||
-                !DefaultServiceSelector.class.isAssignableFrom(info.getServiceClass())) {
-                throw new ServiceException(role, "Component declared at " + info.getLocation() + " is redefined at " +
-                        configuration.getLocation());
-            }
-        }
-        try {
-            handler = this.getComponentHandler(role, component, configuration, this);
-
-            if( this.getLogger().isDebugEnabled() ) {
-                this.getLogger().debug( "Handler type = " + handler.getClass().getName() );
-            }
-
-            this.componentHandlers.put( role, handler );
-            this.newComponentHandlers.add( handler );
-        } catch ( final ServiceException se ) {
-            throw se;
-        } catch( final Exception e ) {
-            throw new ServiceException( role, "Could not set up component handler.", e );
-        }
-        
-        if ( CocoonServiceSelector.class.isAssignableFrom( component ) ) {
-            this.parentAwareComponents.add(role);
-        }
-        // 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);
-            }
-        }
-    }
-    
-    /**
-     * Load a Configuration from a given URI. If the parent manager does not exist or does not
-     * provide a source resolver, a simple one is created here to load the file.
-     * 
-     * @param uri the configuration's URI
-     * @param location the location where the load occurs (used to raise meaningful errors)
-     * @return the configuration
-     * @throws ConfigurationException
-     */
-    private Configuration loadConfiguration(String uri, String location) throws ConfigurationException {
-        
-        // First get a source resolver
-        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 CascadingRuntimeException("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 CascadingRuntimeException("Cannot setup source resolver, at " + location, ce);
-                }
-                this.cachedSourceResolver = simpleSR;
-            }
-        }
-
-        Configuration result;
-        
-        try {
-            Source src = this.cachedSourceResolver.resolveURI(uri);
-            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
-            result = builder.build(src.getInputStream(), src.getURI());
-        } catch (ConfigurationException ce) {
-            throw ce;
-        } catch (Exception e) {
-            throw new ConfigurationException("Cannot load '" + uri + "' at " + location, e);
-        }
-        
-        return result;
-    }
-    
-    /**
-     * 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;
-    }
-}
+/* 
+ * Copyright 2002-2004 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.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+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.configuration.DefaultConfigurationBuilder;
+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.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ServiceInfo;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * Default service manager for Cocoon's components.
+ *
+ * @version SVN $Revision: 1.6 $Id$
+ */
+public class CocoonServiceManager
+extends AbstractServiceManager
+implements ServiceManager, Configurable {
+    
+    /** The location where this manager is defined */
+    protected String location;
+    
+    /** The parent ServiceManager */
+    protected ServiceManager parentManager;
+    
+    /** added component handlers before initialization to maintain
+     *  the order of initialization
+     */
+    private final List newComponentHandlers = new ArrayList();
+
+    /** Temporary list of parent-aware components.  Will be null for most of
+     * our lifecycle. */
+    private ArrayList parentAwareComponents = new ArrayList();
+
+    /** The resolver used to resolve includes. It is lazily loaded in {@link #getSourceResolver()}. */
+    private SourceResolver cachedSourceResolver;
+
+    /** Create the ServiceManager with a parent ServiceManager */
+    public CocoonServiceManager( final ServiceManager parent ) {
+        this.parentManager = parent;
+        
+        RoleManager parentRoleManager = null;
+        // get role manager and logger manager
+        if ( parent instanceof CocoonServiceManager ) {
+            parentRoleManager = ((CocoonServiceManager)parent).roleManager;
+            this.loggerManager = ((CocoonServiceManager)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);
+    }
+    
+    /* (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.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 CocoonServiceManager [" + role + "]" );
+            }
+        }
+
+        if( this.disposed ) {
+            throw new IllegalStateException(
+                "You cannot lookup components on a disposed CocoonServiceManager" );
+        }
+
+        if( role == null ) {
+            final String message =
+                "CocoonServiceManager 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 ServiceInfo 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 Class componentClass = this.getClass().getClassLoader().loadClass( info.getServiceClassName() );
+
+                        final Configuration configuration = new DefaultConfiguration( "", "-" );
+
+                        handler = this.getComponentHandler(role,
+                                                       componentClass,
+                                                       configuration,
+                                                       this);
+
+                        handler.initialize();
+                    } 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 );
+                    }
+
+                    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( final IllegalStateException ise ) {
+            try {
+                handler.initialize();
+                component = handler.get();
+                
+            } catch( final ServiceException ce ) {
+                // Rethrow instead of wrapping a ServiceException with another one
+                throw ce;
+            } 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 );
+            }
+        } 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;
+    }
+
+    /**
+     * Initialize the component
+     * @throws ServiceException
+     */
+    protected void initialize(String role, Object component) 
+    throws ServiceException {
+        // we do nothing here, can be used in subclasses
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService( final String role ) {
+        if( !this.initialized ) return false;
+        if( 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#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." );
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        // Setup location
+        if (this.location == null) {
+            // First call to configure()
+            this.location = configuration.getLocation();
+        }
+        
+        try {
+            // and load configuration with a empty list of loaded configurations
+            doConfigure(configuration, new HashSet());
+        } finally {
+            // Release any source resolver that may have been created to load includes
+            releaseCachedSourceResolver();
+        }
+    }
+
+    private void doConfigure(final Configuration configuration, Set loadedURIs) throws ConfigurationException {
+        
+        // Read roles
+        String rolesURI = configuration.getAttribute("roles", null);
+        if (rolesURI != null) {
+            Configuration roles = loadConfiguration(rolesURI, configuration.getLocation());
+            this.roleManager.configure(roles);
+        }
+
+        // Set components
+        final Configuration[] configurations = configuration.getChildren();
+
+        for( int i = 0; i < configurations.length; i++ ) {
+            Configuration componentConfig = configurations[i];
+            
+            String componentName = componentConfig.getName();
+            
+            if ("include".equals(componentName)) {
+                String includeURI = componentConfig.getAttribute("src");
+                if (loadedURIs.contains(includeURI)) {
+                    // Already loaded: skip to next configuration element
+                    continue;
+                }
+                // load it and store it in the read set
+                Configuration includeConfig = loadConfiguration(includeURI, componentConfig.getLocation());
+                loadedURIs.add(includeURI);
+                
+                // what is it?
+                String includeKind = includeConfig.getName();
+                if (includeKind.equals("components")) {
+                    // more components
+                    doConfigure(includeConfig, loadedURIs);
+                } else if (includeKind.equals("role-list")) {
+                    // more roles
+                    this.roleManager.configure(includeConfig);
+                } else {
+                    throw new ConfigurationException("Unknow document '" + includeKind + "' included at " +
+                            componentConfig.getLocation());
+                }
+
+            } 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 ServiceInfo 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(className, role, componentConfig);
+            }
+        }
+    }
+
+    /* (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;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize()
+    throws Exception {
+        super.initialize();
+
+        for( int i = 0; i < this.newComponentHandlers.size(); i++ ) {
+            final ComponentHandler handler =
+                (ComponentHandler)this.newComponentHandlers.get( i );
+            try {
+                handler.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;
+            }
+        }
+
+        List keys = new ArrayList( this.componentHandlers.keySet() );
+
+        for( int i = 0; i < keys.size(); i++ ) {
+            final Object key = keys.get( i );
+            final ComponentHandler handler =
+                (ComponentHandler)this.componentHandlers.get( key );
+
+            if( !this.newComponentHandlers.contains( handler ) ) {
+                try {
+                    handler.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;
+                }
+            }
+        }
+        this.newComponentHandlers.clear();
+        
+        // Initialize parent aware components
+        if (this.parentAwareComponents == null) {
+            throw new ServiceException(null, "CocoonServiceManager already initialized");
+        }
+
+        // Set parents for parentAware components
+        Iterator iter = this.parentAwareComponents.iterator();
+        while (iter.hasNext()) {
+            String role = (String)iter.next();
+            if ( this.parentManager != null && this.parentManager.hasService( role ) ) {
+                // lookup new component
+                Object component = null;
+                try {
+                    component = this.lookup( role );
+                    ((CocoonServiceSelector)component).setParentLocator( this.parentManager, role );
+                } catch (ServiceException ignore) {
+                    // we don't set the parent then
+                } finally {
+                    this.release( component );
+                }
+            }
+        }
+        this.parentAwareComponents = null;  // null to save memory, and catch logic bugs.
+        
+//        Object[] keyArray = this.componentHandlers.keySet().toArray();
+//        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;
+            }
+        }
+        super.dispose();
+    }
+
+    /**
+     * Add a new component to the manager.
+     *
+     * @param role the role name for the new component.
+     * @param component the class of this component.
+     * @param configuration the configuration for this component.
+     */
+    public void addComponent( final String role,
+                              final Class component,
+                              final Configuration configuration )
+    throws ServiceException {
+        if( this.initialized ) {
+            throw new ServiceException( role,
+                "Cannot add components to an initialized CocoonServiceManager." );
+        }
+
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "Attempting to get handler for role [" + role + "]" );
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role);
+        if (handler != null) {
+            // Overloaded component: we only allow selectors to be overloaded
+            ServiceInfo info = handler.getInfo();
+            if (!DefaultServiceSelector.class.isAssignableFrom(component) ||
+                !DefaultServiceSelector.class.isAssignableFrom(info.getServiceClass())) {
+                throw new ServiceException(role, "Component declared at " + info.getLocation() + " is redefined at " +
+                        configuration.getLocation());
+            }
+        }
+        try {
+            handler = this.getComponentHandler(role, component, configuration, this);
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "Handler type = " + handler.getClass().getName() );
+            }
+
+            this.componentHandlers.put( role, handler );
+            this.newComponentHandlers.add( handler );
+        } catch ( final ServiceException se ) {
+            throw se;
+        } catch( final Exception e ) {
+            throw new ServiceException( role, "Could not set up component handler.", e );
+        }
+        
+        if ( CocoonServiceSelector.class.isAssignableFrom( component ) ) {
+            this.parentAwareComponents.add(role);
+        }
+        // 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);
+            }
+        }
+    }
+    
+    /**
+     * Load a Configuration from a given URI. If the parent manager does not exist or does not
+     * provide a source resolver, a simple one is created here to load the file.
+     * 
+     * @param uri the configuration's URI
+     * @param location the location where the load occurs (used to raise meaningful errors)
+     * @return the configuration
+     * @throws ConfigurationException
+     */
+    private Configuration loadConfiguration(String uri, String location) throws ConfigurationException {
+        
+        // First get a source resolver
+        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 CascadingRuntimeException("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 CascadingRuntimeException("Cannot setup source resolver, at " + location, ce);
+                }
+                this.cachedSourceResolver = simpleSR;
+            }
+        }
+
+        Configuration result;
+        
+        try {
+            Source src = this.cachedSourceResolver.resolveURI(uri);
+            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+            result = builder.build(src.getInputStream(), src.getURI());
+        } catch (ConfigurationException ce) {
+            throw ce;
+        } catch (Exception e) {
+            throw new ConfigurationException("Cannot load '" + uri + "' at " + location, e);
+        }
+        
+        return result;
+    }
+    
+    /**
+     * 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;
+    }
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java	Thu Dec 30 06:16:00 2004
@@ -1,28 +1,28 @@
-/* 
- * Copyright 2002-2004 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;
-
-/**
- * Default component selector for Cocoon's components.
- *
- * @version CVS $Id: CocoonServiceSelector.java 55144 2004-10-20 12:26:09Z ugo $
- */
-public class CocoonServiceSelector extends StandaloneServiceSelector {
-    
-    // TODO: Can we remove this?
-
-}
+/* 
+ * Copyright 2002-2004 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;
+
+/**
+ * Default component selector for Cocoon's components.
+ *
+ * @version CVS $Id$
+ */
+public class CocoonServiceSelector extends StandaloneServiceSelector {
+    
+    // TODO: Can we remove this?
+
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java	Thu Dec 30 06:16:00 2004
@@ -1,174 +1,174 @@
-/* 
- * Copyright 2002-2004 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.logger.LoggerManager;
-import org.apache.avalon.excalibur.pool.Recyclable;
-import org.apache.avalon.framework.container.ContainerUtil;
-import org.apache.avalon.framework.context.Context;
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.parameters.Parameterizable;
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.cocoon.components.ServiceInfo;
-
-/**
- * Factory for Avalon based components.
- *
- * @version CVS $Id: ComponentFactory.java 55172 2004-10-20 17:52:18Z cziegeler $
- */
-public class ComponentFactory {
-    
-    protected final ServiceInfo serviceInfo;
-    
-    /** The Context for the component
-     */
-    protected final Context context;
-
-    /** The service manager for this component
-     */
-    protected final ServiceManager serviceManager;
-    
-    /** The parameters for this component
-     */
-    protected Parameters parameters;
-    
-    protected final Logger logger;
-    
-    protected final LoggerManager loggerManager;
-
-    protected final RoleManager roleManager;
-    
-    /**
-     * Construct a new component factory for the specified component.
-     *
-     * @param componentClass the class to instantiate (must have a default constructor).
-     * @param configuration the <code>Configuration</code> object to pass to new instances.
-     * @param seerviceManager the service manager to pass to <code>Serviceable</code>s.
-     * @param context the <code>Context</code> to pass to <code>Contexutalizable</code>s.
-     *
-     */
-    public ComponentFactory( final ServiceManager serviceManager,
-                             final Context context,
-                             final Logger logger,
-                             final LoggerManager loggerManager,
-                             final RoleManager roleManager,
-                             final ServiceInfo info) {
-        this.serviceManager = serviceManager;
-        this.context = context;
-        this.loggerManager = loggerManager;
-        this.roleManager = roleManager;
-        this.serviceInfo = info;
-        
-        Logger actualLogger = logger;
-        // If the handler is created "manually" (e.g. XSP engine), loggerManager can be null
-        if(loggerManager != null && this.serviceInfo.getConfiguration() != null) {
-            final String category = this.serviceInfo.getConfiguration().getAttribute("logger", null);
-            if(category != null) {
-                actualLogger = loggerManager.getLoggerForCategory(category);
-            }
-        }
-        this.logger = actualLogger;
-    }
-
-    /**
-     * Create a new instance
-     */
-    public Object newInstance()
-    throws Exception {
-        final Object component = this.serviceInfo.getServiceClass().newInstance();
-
-        if( this.logger.isDebugEnabled() ) {
-            this.logger.debug( "ComponentFactory creating new instance of " +
-                    this.serviceInfo.getServiceClass().getName() + "." );
-        }
-
-        ContainerUtil.enableLogging(component, this.logger);
-        ContainerUtil.contextualize( component, this.context );
-        ContainerUtil.service( component, this.serviceManager );
-        ContainerUtil.configure( component, this.serviceInfo.getConfiguration() );
-
-        if( component instanceof Parameterizable ) {
-            if ( this.parameters == null ) {
-                this.parameters = Parameters.fromConfiguration( this.serviceInfo.getConfiguration() );
-            }
-            ContainerUtil.parameterize( component, this.parameters );
-        }
-
-        ContainerUtil.initialize( component );
-
-        final Method method = this.serviceInfo.getInitMethod();
-        if ( method != null ) {
-            method.invoke(component, null);
-        }
-
-        ContainerUtil.start( component );
-
-        return component;
-    }
-
-    public Class getCreatedClass() {
-        return this.serviceInfo.getServiceClass();
-    }
-
-    /**
-     * Destroy an instance
-     */
-    public void decommission( final Object component )
-    throws Exception {
-        if( this.logger.isDebugEnabled() ) {
-            this.logger.debug( "ComponentFactory decommissioning instance of " +
-                    this.serviceInfo.getServiceClass().getName() + "." );
-        }
-
-        ContainerUtil.stop( component );
-        ContainerUtil.dispose( component );
-
-        final Method method = this.serviceInfo.getDestroyMethod();
-        if ( method != null ) {
-            method.invoke(component, null);
-        }
-    }
-
-    /**
-     * Handle service specific methods for getting it out of the pool
-     */
-    public void exitingPool( final Object component )
-    throws Exception {
-        final Method method = this.serviceInfo.getPoolOutMethod();
-        if ( method != null ) {
-            method.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();
-        }
-        final Method method = this.serviceInfo.getPoolInMethod();
-        if ( method != null ) {
-            method.invoke(component, null);
-        }         
-    }
-}
+/* 
+ * Copyright 2002-2004 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.logger.LoggerManager;
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ServiceInfo;
+
+/**
+ * Factory for Avalon based components.
+ *
+ * @version CVS $Id$
+ */
+public class ComponentFactory {
+    
+    protected final ServiceInfo serviceInfo;
+    
+    /** The Context for the component
+     */
+    protected final Context context;
+
+    /** The service manager for this component
+     */
+    protected final ServiceManager serviceManager;
+    
+    /** The parameters for this component
+     */
+    protected Parameters parameters;
+    
+    protected final Logger logger;
+    
+    protected final LoggerManager loggerManager;
+
+    protected final RoleManager roleManager;
+    
+    /**
+     * Construct a new component factory for the specified component.
+     *
+     * @param componentClass the class to instantiate (must have a default constructor).
+     * @param configuration the <code>Configuration</code> object to pass to new instances.
+     * @param seerviceManager the service manager to pass to <code>Serviceable</code>s.
+     * @param context the <code>Context</code> to pass to <code>Contexutalizable</code>s.
+     *
+     */
+    public ComponentFactory( final ServiceManager serviceManager,
+                             final Context context,
+                             final Logger logger,
+                             final LoggerManager loggerManager,
+                             final RoleManager roleManager,
+                             final ServiceInfo info) {
+        this.serviceManager = serviceManager;
+        this.context = context;
+        this.loggerManager = loggerManager;
+        this.roleManager = roleManager;
+        this.serviceInfo = info;
+        
+        Logger actualLogger = logger;
+        // If the handler is created "manually" (e.g. XSP engine), loggerManager can be null
+        if(loggerManager != null && this.serviceInfo.getConfiguration() != null) {
+            final String category = this.serviceInfo.getConfiguration().getAttribute("logger", null);
+            if(category != null) {
+                actualLogger = loggerManager.getLoggerForCategory(category);
+            }
+        }
+        this.logger = actualLogger;
+    }
+
+    /**
+     * Create a new instance
+     */
+    public Object newInstance()
+    throws Exception {
+        final Object component = this.serviceInfo.getServiceClass().newInstance();
+
+        if( this.logger.isDebugEnabled() ) {
+            this.logger.debug( "ComponentFactory creating new instance of " +
+                    this.serviceInfo.getServiceClass().getName() + "." );
+        }
+
+        ContainerUtil.enableLogging(component, this.logger);
+        ContainerUtil.contextualize( component, this.context );
+        ContainerUtil.service( component, this.serviceManager );
+        ContainerUtil.configure( component, this.serviceInfo.getConfiguration() );
+
+        if( component instanceof Parameterizable ) {
+            if ( this.parameters == null ) {
+                this.parameters = Parameters.fromConfiguration( this.serviceInfo.getConfiguration() );
+            }
+            ContainerUtil.parameterize( component, this.parameters );
+        }
+
+        ContainerUtil.initialize( component );
+
+        final Method method = this.serviceInfo.getInitMethod();
+        if ( method != null ) {
+            method.invoke(component, null);
+        }
+
+        ContainerUtil.start( component );
+
+        return component;
+    }
+
+    public Class getCreatedClass() {
+        return this.serviceInfo.getServiceClass();
+    }
+
+    /**
+     * Destroy an instance
+     */
+    public void decommission( final Object component )
+    throws Exception {
+        if( this.logger.isDebugEnabled() ) {
+            this.logger.debug( "ComponentFactory decommissioning instance of " +
+                    this.serviceInfo.getServiceClass().getName() + "." );
+        }
+
+        ContainerUtil.stop( component );
+        ContainerUtil.dispose( component );
+
+        final Method method = this.serviceInfo.getDestroyMethod();
+        if ( method != null ) {
+            method.invoke(component, null);
+        }
+    }
+
+    /**
+     * Handle service specific methods for getting it out of the pool
+     */
+    public void exitingPool( final Object component )
+    throws Exception {
+        final Method method = this.serviceInfo.getPoolOutMethod();
+        if ( method != null ) {
+            method.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();
+        }
+        final Method method = this.serviceInfo.getPoolInMethod();
+        if ( method != null ) {
+            method.invoke(component, null);
+        }         
+    }
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentHandler.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentHandler.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentHandler.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentHandler.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentHandler.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentHandler.java	Thu Dec 30 06:16:00 2004
@@ -1,79 +1,79 @@
-/* 
- * Copyright 2002-2004 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.cocoon.components.ServiceInfo;
-
-/**
- * This class acts like a Factory to instantiate the correct version
- * of the component handler that you need.
- *
- * @version CVS $Id: AbstractComponentHandler.java 55144 2004-10-20 12:26:09Z ugo $
- */
-public interface ComponentHandler {
-
-    /**
-     * Get an instance of the type of component handled by this handler.
-     * 
-     * @return an instance
-     * @exception Exception if an error occurs
-     */
-    Object get() throws Exception;
-
-    /**
-     * Put back an instance of the type of component handled by this handler.
-     *
-     * @param component a service
-     * @exception Exception if an error occurs
-     */
-    void put( Object component ) 
-    throws Exception;
-    
-    /**
-     * Indicates if this handler manages a single object, i.e. all calls to {@link #get()}
-     * will return the same object.
-     * 
-     * @return <code>true</code> if managed object is a singleton
-     */
-    boolean isSingleton();
-
-    /**
-     * Returns <code>true</code> if this component handler can safely be
-     * disposed (i.e. none of the components it is handling are still
-     * being used).
-     *
-     * @return <code>true</code> if this component handler can safely be
-     *         disposed; <code>false</code> otherwise
-     */
-    boolean canBeDisposed();
-
-    /**
-     * Dispose of the component handler and any associated Pools and Factories.
-     */
-    public void dispose();
-    
-    /**
-     * Initialize this handler
-     */
-    void initialize() throws Exception;
-    
-    /**
-     * Get the service metadata for this handler
-     */
-    ServiceInfo getInfo();
-
-}
+/* 
+ * Copyright 2002-2004 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.cocoon.components.ServiceInfo;
+
+/**
+ * This class acts like a Factory to instantiate the correct version
+ * of the component handler that you need.
+ *
+ * @version CVS $Id$
+ */
+public interface ComponentHandler {
+
+    /**
+     * Get an instance of the type of component handled by this handler.
+     * 
+     * @return an instance
+     * @exception Exception if an error occurs
+     */
+    Object get() throws Exception;
+
+    /**
+     * Put back an instance of the type of component handled by this handler.
+     *
+     * @param component a service
+     * @exception Exception if an error occurs
+     */
+    void put( Object component ) 
+    throws Exception;
+    
+    /**
+     * Indicates if this handler manages a single object, i.e. all calls to {@link #get()}
+     * will return the same object.
+     * 
+     * @return <code>true</code> if managed object is a singleton
+     */
+    boolean isSingleton();
+
+    /**
+     * Returns <code>true</code> if this component handler can safely be
+     * disposed (i.e. none of the components it is handling are still
+     * being used).
+     *
+     * @return <code>true</code> if this component handler can safely be
+     *         disposed; <code>false</code> otherwise
+     */
+    boolean canBeDisposed();
+
+    /**
+     * Dispose of the component handler and any associated Pools and Factories.
+     */
+    public void dispose();
+    
+    /**
+     * Initialize this handler
+     */
+    void initialize() throws Exception;
+    
+    /**
+     * Get the service metadata for this handler
+     */
+    ServiceInfo getInfo();
+
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java	Thu Dec 30 06:16:00 2004
@@ -1,228 +1,228 @@
-/* 
- * Copyright 2002-2004 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.Iterator;
-import java.util.LinkedList;
-
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.cocoon.components.ServiceInfo;
-
-/**
- * The PoolableComponentHandler to make sure that poolable components are initialized
- * destroyed and pooled correctly.
- * <p>
- * Components which implement Poolable may be configured to be pooled using the following
- *  example configuration.  This example assumes that the user component class MyComp
- *  implements Poolable.
- * <p>
- * Configuration Example:
- * <pre>
- *   &lt;my-comp pool-max="8"/&gt;
- * </pre>
- * <p>
- * Roles Example:
- * <pre>
- *   &lt;role name="com.mypkg.MyComponent"
- *         shorthand="my-comp"
- *         default-class="com.mypkg.DefaultMyComponent"/&gt;
- * </pre>
- * <p>
- * Configuration Attributes:
- * <ul>
- * <li>The <code>pool-max</code> attribute is used to set the maximum number of components which
- *  will be pooled. (Defaults to "8") If additional instances are required, they're created,
- *  but not pooled.</li>
- * </ul>
- *
- * @version CVS $Id: PoolableComponentHandler.java 55144 2004-10-20 12:26:09Z ugo $
- */
-public class PoolableComponentHandler
-extends AbstractComponentHandler {
-    
-    /** The default max size of the pool */
-    public static final int DEFAULT_MAX_POOL_SIZE = 8;
-
-    /**
-     * Object used to synchronize access to the get and put methods
-     */
-    protected final Object semaphore = new Object();
-
-    /**
-     * The maximum size of the pool.
-     */
-    private final int max;
-
-    /**
-     * List of the Poolable instances which are available for use.
-     */
-    private LinkedList ready;
-
-    /**
-     * Store the size of the ready list to optimize operations which require this value.
-     */
-    private int readySize;
-
-    /**
-     * Total number of Poolable instances in the pool
-     */
-    private int size;
-    
-    /**
-     * Create a PoolableComponentHandler which manages a pool of Components
-     *  created by the specified factory object.
-     *
-     * @param factory The factory object which is responsible for creating the components
-     *                managed by the ComponentHandler.
-     * @param config The configuration to use to configure the pool.
-     */
-    public PoolableComponentHandler( final ServiceInfo info,
-                                     final Logger logger,
-                                     final ComponentFactory factory,
-                                     final Configuration config )
-    throws Exception {
-        super(info, logger, factory);
-
-        final int poolMax = config.getAttributeAsInteger( "pool-max", DEFAULT_MAX_POOL_SIZE );
-        this.max = ( poolMax <= 0 ? Integer.MAX_VALUE : poolMax );
-
-        // Create the pool lists.
-        this.ready = new LinkedList();
-    }
-
-    /**
-     * Dispose of the ComponentHandler and any associated Pools and Factories.
-     */
-    public void dispose() {
-        super.dispose();
-
-        // Any Poolables in the m_ready list need to be disposed of
-        synchronized( this.semaphore ) {
-            // Remove objects in the ready list.
-            for( Iterator iter = this.ready.iterator(); iter.hasNext(); ) {
-                Object poolable = iter.next();
-                iter.remove();
-                this.readySize--;
-                this.permanentlyRemovePoolable( poolable );
-            }
-
-            if( ( this.size > 0 ) && this.logger.isDebugEnabled() ) {
-                this.logger.debug( "There were " + this.size
-                                   + " outstanding objects when the pool was disposed." );
-            }
-        }
-    }
-    
-    /**
-     * Permanently removes a poolable from the pool's active list and
-     *  destroys it so that it will not ever be reused.
-     * <p>
-     * This method is only called by threads that have m_semaphore locked.
-     */
-    protected void permanentlyRemovePoolable( Object poolable ) {
-        this.size--;
-        this.decommission( poolable );
-    }
-
-    /**
-     * Gets a Poolable from the pool.  If there is room in the pool, a new Poolable will be
-     *  created.  Depending on the parameters to the constructor, the method may block or throw
-     *  an exception if a Poolable is not available on the pool.
-     *
-     * @return Always returns a Poolable.  Contract requires that put must always be called with
-     *  the Poolable returned.
-     * @throws Exception An exception may be thrown as described above or if there is an exception
-     *  thrown by the ObjectFactory's newInstance() method.
-     */
-    protected Object doGet() throws Exception {
-        Object poolable;
-        synchronized( this.semaphore ) {
-            // Look for a Poolable at the end of the m_ready list
-            if( this.readySize > 0 ){
-                // A poolable is ready and waiting in the pool
-                poolable = this.ready.removeLast();
-                this.readySize--;
-            } else {
-                // Create a new poolable.  May throw an exception if the poolable can not be
-                //  instantiated.
-                poolable = this.factory.newInstance();
-                this.size++;
-
-                if( this.logger.isDebugEnabled() ) {
-                    this.logger.debug( "Created a new " + poolable.getClass().getName()
-                                       + " from the object factory." );
-                }
-            }
-        }
-
-        this.factory.exitingPool(poolable);
-        
-        if( this.logger.isDebugEnabled() ) {
-            this.logger.debug( "Got a " + poolable.getClass().getName() + " from the pool." );
-        }
-
-        return poolable;
-    }
-
-    /**
-     * Returns a poolable to the pool 
-     *
-     * @param poolable Poolable to return to the pool.
-     */
-    protected void doPut( final Object poolable ) {
-        try {
-            this.factory.enteringPool(poolable);
-        } catch (Exception ignore) {
-            this.logger.warn("Exception during putting component back into the pool.", ignore);
-        }
-
-        synchronized( this.semaphore ) {
-            if( this.size <= this.max ) {
-                if( this.disposed ) {
-                    // The pool has already been disposed.
-                    if( this.logger.isDebugEnabled() ) {
-                        this.logger.debug( "Put called for a " + poolable.getClass().getName()
-                                           + " after the pool was disposed." );
-                    }
-
-                    this.permanentlyRemovePoolable( poolable );
-                } else {
-                    // There is room in the pool to keep this poolable.
-                    if( this.logger.isDebugEnabled() ) {
-                        this.logger.debug( "Put a " + poolable.getClass().getName()
-                                           + " back into the pool." );
-                    }
-
-                    this.ready.addLast( poolable );
-                    this.readySize++;
-
-                }
-            } else {
-                // More Poolables were created than can be held in the pool, so remove.
-                if( this.logger.isDebugEnabled() ) {
-                    this.logger.debug( "No room to put a " + poolable.getClass().getName()
-                                       + " back into the pool, so remove it." );
-                }
-
-                this.permanentlyRemovePoolable( poolable );
-            }
-        }
-    }
-
-    
-}
+/* 
+ * Copyright 2002-2004 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.Iterator;
+import java.util.LinkedList;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ServiceInfo;
+
+/**
+ * The PoolableComponentHandler to make sure that poolable components are initialized
+ * destroyed and pooled correctly.
+ * <p>
+ * Components which implement Poolable may be configured to be pooled using the following
+ *  example configuration.  This example assumes that the user component class MyComp
+ *  implements Poolable.
+ * <p>
+ * Configuration Example:
+ * <pre>
+ *   &lt;my-comp pool-max="8"/&gt;
+ * </pre>
+ * <p>
+ * Roles Example:
+ * <pre>
+ *   &lt;role name="com.mypkg.MyComponent"
+ *         shorthand="my-comp"
+ *         default-class="com.mypkg.DefaultMyComponent"/&gt;
+ * </pre>
+ * <p>
+ * Configuration Attributes:
+ * <ul>
+ * <li>The <code>pool-max</code> attribute is used to set the maximum number of components which
+ *  will be pooled. (Defaults to "8") If additional instances are required, they're created,
+ *  but not pooled.</li>
+ * </ul>
+ *
+ * @version CVS $Id$
+ */
+public class PoolableComponentHandler
+extends AbstractComponentHandler {
+    
+    /** The default max size of the pool */
+    public static final int DEFAULT_MAX_POOL_SIZE = 8;
+
+    /**
+     * Object used to synchronize access to the get and put methods
+     */
+    protected final Object semaphore = new Object();
+
+    /**
+     * The maximum size of the pool.
+     */
+    private final int max;
+
+    /**
+     * List of the Poolable instances which are available for use.
+     */
+    private LinkedList ready;
+
+    /**
+     * Store the size of the ready list to optimize operations which require this value.
+     */
+    private int readySize;
+
+    /**
+     * Total number of Poolable instances in the pool
+     */
+    private int size;
+    
+    /**
+     * Create a PoolableComponentHandler which manages a pool of Components
+     *  created by the specified factory object.
+     *
+     * @param factory The factory object which is responsible for creating the components
+     *                managed by the ComponentHandler.
+     * @param config The configuration to use to configure the pool.
+     */
+    public PoolableComponentHandler( final ServiceInfo info,
+                                     final Logger logger,
+                                     final ComponentFactory factory,
+                                     final Configuration config )
+    throws Exception {
+        super(info, logger, factory);
+
+        final int poolMax = config.getAttributeAsInteger( "pool-max", DEFAULT_MAX_POOL_SIZE );
+        this.max = ( poolMax <= 0 ? Integer.MAX_VALUE : poolMax );
+
+        // Create the pool lists.
+        this.ready = new LinkedList();
+    }
+
+    /**
+     * Dispose of the ComponentHandler and any associated Pools and Factories.
+     */
+    public void dispose() {
+        super.dispose();
+
+        // Any Poolables in the m_ready list need to be disposed of
+        synchronized( this.semaphore ) {
+            // Remove objects in the ready list.
+            for( Iterator iter = this.ready.iterator(); iter.hasNext(); ) {
+                Object poolable = iter.next();
+                iter.remove();
+                this.readySize--;
+                this.permanentlyRemovePoolable( poolable );
+            }
+
+            if( ( this.size > 0 ) && this.logger.isDebugEnabled() ) {
+                this.logger.debug( "There were " + this.size
+                                   + " outstanding objects when the pool was disposed." );
+            }
+        }
+    }
+    
+    /**
+     * Permanently removes a poolable from the pool's active list and
+     *  destroys it so that it will not ever be reused.
+     * <p>
+     * This method is only called by threads that have m_semaphore locked.
+     */
+    protected void permanentlyRemovePoolable( Object poolable ) {
+        this.size--;
+        this.decommission( poolable );
+    }
+
+    /**
+     * Gets a Poolable from the pool.  If there is room in the pool, a new Poolable will be
+     *  created.  Depending on the parameters to the constructor, the method may block or throw
+     *  an exception if a Poolable is not available on the pool.
+     *
+     * @return Always returns a Poolable.  Contract requires that put must always be called with
+     *  the Poolable returned.
+     * @throws Exception An exception may be thrown as described above or if there is an exception
+     *  thrown by the ObjectFactory's newInstance() method.
+     */
+    protected Object doGet() throws Exception {
+        Object poolable;
+        synchronized( this.semaphore ) {
+            // Look for a Poolable at the end of the m_ready list
+            if( this.readySize > 0 ){
+                // A poolable is ready and waiting in the pool
+                poolable = this.ready.removeLast();
+                this.readySize--;
+            } else {
+                // Create a new poolable.  May throw an exception if the poolable can not be
+                //  instantiated.
+                poolable = this.factory.newInstance();
+                this.size++;
+
+                if( this.logger.isDebugEnabled() ) {
+                    this.logger.debug( "Created a new " + poolable.getClass().getName()
+                                       + " from the object factory." );
+                }
+            }
+        }
+
+        this.factory.exitingPool(poolable);
+        
+        if( this.logger.isDebugEnabled() ) {
+            this.logger.debug( "Got a " + poolable.getClass().getName() + " from the pool." );
+        }
+
+        return poolable;
+    }
+
+    /**
+     * Returns a poolable to the pool 
+     *
+     * @param poolable Poolable to return to the pool.
+     */
+    protected void doPut( final Object poolable ) {
+        try {
+            this.factory.enteringPool(poolable);
+        } catch (Exception ignore) {
+            this.logger.warn("Exception during putting component back into the pool.", ignore);
+        }
+
+        synchronized( this.semaphore ) {
+            if( this.size <= this.max ) {
+                if( this.disposed ) {
+                    // The pool has already been disposed.
+                    if( this.logger.isDebugEnabled() ) {
+                        this.logger.debug( "Put called for a " + poolable.getClass().getName()
+                                           + " after the pool was disposed." );
+                    }
+
+                    this.permanentlyRemovePoolable( poolable );
+                } else {
+                    // There is room in the pool to keep this poolable.
+                    if( this.logger.isDebugEnabled() ) {
+                        this.logger.debug( "Put a " + poolable.getClass().getName()
+                                           + " back into the pool." );
+                    }
+
+                    this.ready.addLast( poolable );
+                    this.readySize++;
+
+                }
+            } else {
+                // More Poolables were created than can be held in the pool, so remove.
+                if( this.logger.isDebugEnabled() ) {
+                    this.logger.debug( "No room to put a " + poolable.getClass().getName()
+                                       + " back into the pool, so remove it." );
+                }
+
+                this.permanentlyRemovePoolable( poolable );
+            }
+        }
+    }
+
+    
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java	Thu Dec 30 06:16:00 2004
@@ -1,283 +1,283 @@
-/* 
- * Copyright 2002-2004 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.net.URL;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-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.DefaultConfigurationBuilder;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.cocoon.components.ServiceInfo;
-
-/**
- * Default RoleManager implementation.  It populates the RoleManager
- * from a configuration file.
- *
- * @version CVS $Id: RoleManager.java 55144 2004-10-20 12:26:09Z ugo $
- */
-public class RoleManager
-extends AbstractLogEnabled
-implements Configurable {
-    
-    /** Map for shorthand to role mapping */
-    private Map shorthands = new HashMap();
-
-    /** Map for role to default classname mapping */
-    private Map classNames = new HashMap();
-
-    /** Map for role->key to classname mapping */
-    private 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 ServiceInfo getDefaultServiceInfoForRole( final String role ) {
-        final ServiceInfo info = (ServiceInfo)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
-     * CocoonServiceSelector, 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 ServiceInfo 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 ServiceInfo s = ( ServiceInfo ) 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 ) {
-                ServiceInfo info = (ServiceInfo)this.classNames.get(roleName);
-                if (info == null) {
-                    // Create a new info and store it
-                    info = new ServiceInfo();
-                    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, but they're currently not used
-                }
-            }
-
-            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();
-
-                    ServiceInfo info = (ServiceInfo)keyMap.get(shortHand);
-                    if (info == null) {       
-                        info = new ServiceInfo();
-                        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, but they're currently not used
-                    }
-                }
-            }
-
-            if( this.getLogger().isDebugEnabled() ) {
-                this.getLogger().debug( "added Role " + roleName + " with shorthand " +
-                                   shorthand + " for " + defaultClassName );
-            }
-        }
-    }
-    
-    
-    
-    private Set loadedURLs = new HashSet();
-    
-    public void loadFromClassPath() throws Exception {
-        ClassLoader cl = Thread.currentThread().getContextClassLoader();
-        Enumeration resources = cl.getResources("/org/apache/cocoon/cocoon.roles");
-        
-        while(resources.hasMoreElements()) {
-            URL url = (URL)resources.nextElement();
-            loadURL(url.toExternalForm());
-        }
-    }
-    
-    public void loadURL(String resource) throws Exception {
-        if (!hasLoaded(resource)) {
-            loadedURLs.add(resource);
-
-            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
-            Configuration config = builder.build(resource);
-            configure(config);
-        }
-    }
-    
-    public boolean hasLoaded(String resource) {
-        return loadedURLs.contains(resource) || (parent != null && parent.hasLoaded(resource));
-    }
-}
+/* 
+ * Copyright 2002-2004 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.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+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.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.components.ServiceInfo;
+
+/**
+ * Default RoleManager implementation.  It populates the RoleManager
+ * from a configuration file.
+ *
+ * @version CVS $Id$
+ */
+public class RoleManager
+extends AbstractLogEnabled
+implements Configurable {
+    
+    /** Map for shorthand to role mapping */
+    private Map shorthands = new HashMap();
+
+    /** Map for role to default classname mapping */
+    private Map classNames = new HashMap();
+
+    /** Map for role->key to classname mapping */
+    private 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 ServiceInfo getDefaultServiceInfoForRole( final String role ) {
+        final ServiceInfo info = (ServiceInfo)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
+     * CocoonServiceSelector, 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 ServiceInfo 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 ServiceInfo s = ( ServiceInfo ) 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 ) {
+                ServiceInfo info = (ServiceInfo)this.classNames.get(roleName);
+                if (info == null) {
+                    // Create a new info and store it
+                    info = new ServiceInfo();
+                    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, but they're currently not used
+                }
+            }
+
+            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();
+
+                    ServiceInfo info = (ServiceInfo)keyMap.get(shortHand);
+                    if (info == null) {       
+                        info = new ServiceInfo();
+                        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, but they're currently not used
+                    }
+                }
+            }
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "added Role " + roleName + " with shorthand " +
+                                   shorthand + " for " + defaultClassName );
+            }
+        }
+    }
+    
+    
+    
+    private Set loadedURLs = new HashSet();
+    
+    public void loadFromClassPath() throws Exception {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        Enumeration resources = cl.getResources("/org/apache/cocoon/cocoon.roles");
+        
+        while(resources.hasMoreElements()) {
+            URL url = (URL)resources.nextElement();
+            loadURL(url.toExternalForm());
+        }
+    }
+    
+    public void loadURL(String resource) throws Exception {
+        if (!hasLoaded(resource)) {
+            loadedURLs.add(resource);
+
+            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+            Configuration config = builder.build(resource);
+            configure(config);
+        }
+    }
+    
+    public boolean hasLoaded(String resource) {
+        return loadedURLs.contains(resource) || (parent != null && parent.hasLoaded(resource));
+    }
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java	Thu Dec 30 06:16:00 2004
@@ -1,67 +1,67 @@
-/* 
- * Copyright 2002-2004 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.logger.Logger;
-import org.apache.cocoon.components.ServiceInfo;
-
-/**
- * The DefaultComponentHandler to make sure components are initialized
- * and destroyed correctly.
- *
- * @version CVS $Id: SingleThreadedComponentHandler.java 55144 2004-10-20 12:26:09Z ugo $
- */
-public class SingleThreadedComponentHandler
-extends AbstractComponentHandler {
-
-    /**
-     * Create a SingleThreadedComponentHandler which manages a pool of Components
-     *  created by the specified factory object.
-     *
-     * @param logger The logger to use
-     * @param factory The factory object which is responsible for creating the components
-     *                managed by the handler.
-     */
-    public SingleThreadedComponentHandler( final ServiceInfo info,
-                                    final Logger logger,
-                                    final ComponentFactory factory ) {
-        super(info, logger, factory);
-    }
-
-    /**
-     * Get a reference of the desired Component
-     *
-     * @return A component instance.
-     *
-     * @throws Exception If there are any problems encountered acquiring a
-     *                   component instance.
-     */
-    protected Object doGet()
-    throws Exception {
-        return this.factory.newInstance();
-    }
-
-    /**
-     * Return a reference of the desired Component
-     *
-     * @param component Component to be be put/released back to the handler.
-     */
-    protected void doPut( final Object component ) {
-        this.decommission( component );
-    }
-
-}
+/* 
+ * Copyright 2002-2004 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.logger.Logger;
+import org.apache.cocoon.components.ServiceInfo;
+
+/**
+ * The DefaultComponentHandler to make sure components are initialized
+ * and destroyed correctly.
+ *
+ * @version CVS $Id$
+ */
+public class SingleThreadedComponentHandler
+extends AbstractComponentHandler {
+
+    /**
+     * Create a SingleThreadedComponentHandler which manages a pool of Components
+     *  created by the specified factory object.
+     *
+     * @param logger The logger to use
+     * @param factory The factory object which is responsible for creating the components
+     *                managed by the handler.
+     */
+    public SingleThreadedComponentHandler( final ServiceInfo info,
+                                    final Logger logger,
+                                    final ComponentFactory factory ) {
+        super(info, logger, factory);
+    }
+
+    /**
+     * Get a reference of the desired Component
+     *
+     * @return A component instance.
+     *
+     * @throws Exception If there are any problems encountered acquiring a
+     *                   component instance.
+     */
+    protected Object doGet()
+    throws Exception {
+        return this.factory.newInstance();
+    }
+
+    /**
+     * Return a reference of the desired Component
+     *
+     * @param component Component to be be put/released back to the handler.
+     */
+    protected void doPut( final Object component ) {
+        this.decommission( component );
+    }
+
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java&r1=123715&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java	Thu Dec 30 06:16:00 2004
@@ -1,85 +1,85 @@
-/* 
- * Copyright 2002-2004 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.logger.Logger;
-import org.apache.cocoon.components.ServiceInfo;
-
-/**
- * The ThreadSafeComponentHandler to make sure components are initialized
- * and destroyed correctly.
- *
- * @version CVS $Id: ThreadSafeComponentHandler.java 55144 2004-10-20 12:26:09Z ugo $
- */
-public class ThreadSafeComponentHandler
-extends AbstractComponentHandler {
-    
-    private Object instance;
-
-    /**
-     * Create a ThreadSafeComponentHandler which manages a single instance
-     * of an object return by the component factory.
-     * @param logger The logger to use
-     * @param factory The factory object which is responsible for creating the components
-     *                managed by the handler.
-     */
-    public ThreadSafeComponentHandler( final ServiceInfo info,
-                                       final Logger logger,
-                                       final ComponentFactory factory ) {
-        super(info, logger, factory);
-    }
-    
-    public boolean isSingleton() {
-        return true;
-    }
-
-    public void initialize() 
-    throws Exception {
-        if( this.initialized ) {
-            return;
-        }
-        if( this.instance == null ) {
-            this.instance = this.factory.newInstance();
-        }
-        super.initialize();
-    }
-
-    /**
-     * Get a reference of the desired Component
-     */
-    protected Object doGet()
-    throws Exception {
-        return this.instance;
-    }
-
-    /**
-     * Return a reference of the desired Component
-     */
-    protected void doPut( final Object component ) {
-        // nothing to do
-    }
-
-    /**
-     * Dispose of the ComponentHandler and any associated Pools and Factories.
-     */
-    public void dispose() {
-        this.decommission( this.instance );
-        this.instance = null;
-
-        super.dispose();
-    }
-}
+/* 
+ * Copyright 2002-2004 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.logger.Logger;
+import org.apache.cocoon.components.ServiceInfo;
+
+/**
+ * The ThreadSafeComponentHandler to make sure components are initialized
+ * and destroyed correctly.
+ *
+ * @version CVS $Id$
+ */
+public class ThreadSafeComponentHandler
+extends AbstractComponentHandler {
+    
+    private Object instance;
+
+    /**
+     * Create a ThreadSafeComponentHandler which manages a single instance
+     * of an object return by the component factory.
+     * @param logger The logger to use
+     * @param factory The factory object which is responsible for creating the components
+     *                managed by the handler.
+     */
+    public ThreadSafeComponentHandler( final ServiceInfo info,
+                                       final Logger logger,
+                                       final ComponentFactory factory ) {
+        super(info, logger, factory);
+    }
+    
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public void initialize() 
+    throws Exception {
+        if( this.initialized ) {
+            return;
+        }
+        if( this.instance == null ) {
+            this.instance = this.factory.newInstance();
+        }
+        super.initialize();
+    }
+
+    /**
+     * Get a reference of the desired Component
+     */
+    protected Object doGet()
+    throws Exception {
+        return this.instance;
+    }
+
+    /**
+     * Return a reference of the desired Component
+     */
+    protected void doPut( final Object component ) {
+        // nothing to do
+    }
+
+    /**
+     * Dispose of the ComponentHandler and any associated Pools and Factories.
+     */
+    public void dispose() {
+        this.decommission( this.instance );
+        this.instance = null;
+
+        super.dispose();
+    }
+}

Modified: cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java&r1=123715&p2=cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java	(original)
+++ cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java	Thu Dec 30 06:16:00 2004
@@ -1,361 +1,361 @@
-/* 
- * Copyright 2002-2004 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 java.net.URL;
-
-import junit.framework.TestCase;
-
-import org.apache.avalon.excalibur.logger.LoggerManager;
-import org.apache.avalon.framework.configuration.Configurable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.DefaultConfiguration;
-import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
-import org.apache.avalon.framework.container.ContainerUtil;
-import org.apache.avalon.framework.context.Context;
-import org.apache.avalon.framework.context.DefaultContext;
-import org.apache.avalon.framework.logger.ConsoleLogger;
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.parameters.Parameterizable;
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.avalon.framework.service.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-
-/**
- * JUnit TestCase for Cocoon Components.
- * <p>
- *   This class extends the JUnit TestCase class to setup an environment which
- *   makes it possible to easily test Cocoon Components. The following methods
- *   and instance variables are exposed for convenience testing:
- * </p>
- * <dl>
- *   <dt>getManager()</dt>
- *   <dd>
- *     This instance variable contains an initialized service manager which
- *     can be used to lookup components configured in the test configuration
- *     file. (see below)
- *   </dd>
- *   <dt>getLogger()</dt>
- *   <dd>
- *     This method returns a logger for this test case. By default this
- *     logger logs with log level DEBUG.
- *   </dd>
- * </dl>
- * <p>
- *   The following test case configuration can be used as a basis for new tests.
- *   Detailed explanations of the configuration elements can be found after
- *   the example. 
- * </p>
- * <pre>
- *   &lt;testcase&gt;
- *     &lt;context&gt;
- *       &lt;entry name="foo" value="bar"/&gt;
- *       &lt;entry name="baz" class="my.context.Class"/&gt;
- *     &lt;/context&gt;
- *
- *     &lt;roles&gt;
- *       &lt;role name="org.apache.avalon.excalibur.datasource.DataSourceComponentSelector"
- *             shorthand="datasources"
- *             default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"&gt;
- *          &lt;hint shorthand="jdbc" class="org.apache.avalon.excalibur.datasource.JdbcDataSource"/&gt;
- *       &lt;/role&gt;
- *     &lt;/roles&gt;
- *
- *     &lt;components&gt;
- *       &lt;datasources&gt;
- *         &lt;jdbc name="personell"&gt;
- *           &lt;pool-controller min="5" max="10"/&gt;
- *           &lt;jdbc name="personnel"/&gt;
- *           &lt;dburl&gt;jdbc:odbc:test&lt;/dburl&gt;
- *           &lt;user&gt;test&lt;/user&gt;
- *           &lt;password&gt;test&lt;/password&gt;
- *           &lt;driver&gt;sun.jdbc.odbc.JdbcOdbcDriver&lt;/driver&gt;
- *         &lt;/jdbc&gt;
- *       &lt;/datasources&gt;
- *     &lt;/components&gt;
- *   &lt;/testcase&gt;
- * </pre>
- * <p>
- * Element Explanation:
- * <dl>
- * <dt>testcase</dt>
- * <dd>Defines a test case configuration.  Must contain one each of the
- *  following elements: 
- *  <code>context</code>, <code>roles</code>, and <code>components</code>
- *  </dd>.
- *
- * <dt>context</dt>
- * <dd>Allows context properties to be set in the context passed to any
- *  Contextualizable components.</dd>
- *
- * <dt>roles</dt>
- * <dd>Roles configuration for the components configured in the
- *  <code>components</code> element.  
- * </dd>
- *
- * <dt>components</dt>
- * <dd>Used to configure any Components used by the test cases.  
- * </dd>
- *
- * </dl>
- *
- * @version $Id: $
- */
-public class ContainerTestCase extends TestCase {
-    
-    /** The default logger */
-    private Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG);
-    
-    /** The service manager to use */
-    private ServiceManager manager;
-
-    /** The context */
-    private Context context;
-    
-    /** Return the logger */
-    protected Logger getLogger() {
-        return logger;
-    }
-
-    /** Return the service manager */
-    protected ServiceManager getManager() {
-        return this.manager;
-    }
-    
-    /* (non-Javadoc)
-     * @see junit.framework.TestCase#setUp()
-     */
-    protected void setUp() throws Exception {
-        super.setUp();
-        this.prepare();
-    }
-    
-    /**
-     * Initializes the ComponentLocator
-     *
-     * The configuration file is determined by the class name plus .xtest appended,
-     * all '.' replaced by '/' and loaded as a resource via classpath
-     */
-    protected void prepare()
-    throws Exception {
-        final String resourceName = getClass().getName().replace( '.', '/' ) + ".xtest";
-        URL resource = getClass().getClassLoader().getResource( resourceName );
-
-        if( resource != null ) {
-            getLogger().debug( "Loading resource " + resourceName );
-            this.prepare( resource.openStream() );
-        } else {
-            getLogger().debug( "Resource not found " + resourceName );
-            this.prepare( null );
-        }
-    }
-
-    /**
-     * Initializes the ComponentLocator
-     *
-     * @param testconf The configuration file is passed as a <code>InputStream</code>
-     *
-     * A common way to supply a InputStream is to overwrite the initialize() method
-     * in the sub class, do there whatever is needed to get the right InputStream object
-     * supplying a conformant xtest configuartion and pass it to this initialize method.
-     * the mentioned initialize method is also the place to set a different logging priority
-     * to the member variable m_logPriority.
-     */
-    protected final void prepare( final InputStream testconf )
-    throws Exception {
-        if ( getLogger().isDebugEnabled() ) {
-            getLogger().debug( "Initializing " + this.getName() );
-        }
-
-        final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
-        final Configuration conf;
-        if ( testconf != null ) {
-            conf = builder.build( testconf );
-        } else {
-            conf = new DefaultConfiguration("", "-");
-        }
-
-        this.context = this.setupContext( conf.getChild( "context" ) );
-
-        this.setupManagers( conf.getChild( "components" ),
-                            conf.getChild( "roles" ));
-    }
-
-    /* (non-Javadoc)
-     * @see junit.framework.TestCase#tearDown()
-     */
-    protected void tearDown() throws Exception {
-        this.done();
-        super.tearDown();
-    }
-
-    /**
-     * Disposes the <code>ComponentLocator</code>
-     */
-    final private void done() {
-        if( manager != null ) {
-            ContainerUtil.dispose(manager);
-            manager = null;
-        }
-    }
-
-    /**
-     * set up a context according to the xtest configuration specifications context
-     * element.
-     *
-     * A method addContext(DefaultContext context) is called here to enable subclasses
-     * to put additional objects into the context programmatically.
-     */
-    final private Context setupContext( final Configuration conf )
-    throws Exception {
-        final DefaultContext context = new DefaultContext();
-        final Configuration[] confs = conf.getChildren( "entry" );
-        for( int i = 0; i < confs.length; i++ ) {
-            final String key = confs[ i ].getAttribute( "name" );
-            final String value = confs[ i ].getAttribute( "value", null );
-            if( value == null ) {
-                String clazz = confs[ i ].getAttribute( "class" );
-                Object obj = getClass().getClassLoader().loadClass( clazz ).newInstance();
-                context.put( key, obj );
-                if( getLogger().isInfoEnabled() ) {
-                    getLogger().info( "ContainerTestCase: added an instance of class " + clazz + " to context entry " + key );
-                }
-            } else {
-                context.put( key, value );
-                if( getLogger().isInfoEnabled() ) {
-                    getLogger().info( "ContainerTestCase: added value \"" + value + "\" to context entry " + key );
-                }
-            }
-        }
-        this.addContext( context );
-        return context ;
-    }
-
-    /**
-     * This method may be overwritten by subclasses to put additional objects
-     * into the context programmatically.
-     */
-    protected void addContext( DefaultContext context ) {
-        // nothing to add here
-    }
-
-    /**
-     * This method may be overwritten by subclasses to add aditional
-     * components.
-     */
-    protected void addComponents( CocoonServiceManager manager) 
-    throws ServiceException {
-        // subclasses can add components here
-    }
-    
-    final private void setupManagers( final Configuration confCM,
-                                      final Configuration confRM)
-    throws Exception {
-        // Setup the RoleManager
-        RoleManager roleManager = new RoleManager();
-        roleManager.enableLogging( this.getLogger() );
-        roleManager.configure( confRM );
-
-        // Set up the ComponentLocator
-        CocoonServiceManager ecManager = new CocoonServiceManager(null);
-        ecManager.enableLogging( this.getLogger() );
-        ecManager.contextualize( this.context );
-        ecManager.setRoleManager( roleManager );
-        ecManager.setLoggerManager( new DefaultLoggerManager(this.logger));
-        ecManager.configure( confCM );
-        this.addComponents( ecManager );
-        ecManager.initialize();
-        this.manager = ecManager;
-    }
-
-    protected final Object lookup( final String key )
-    throws ServiceException {
-        return manager.lookup( key );
-    }
-
-    protected final void release( final Object object ) {
-        manager.release( object );
-    }
-    
-    private Object getComponent(String classname,
-                                Configuration conf,
-                                Parameters p) 
-    throws Exception {
-        final Object instance = Class.forName(classname).newInstance();
-        ContainerUtil.enableLogging(instance, getLogger());
-        ContainerUtil.contextualize(instance, this.context);
-        ContainerUtil.service(instance, getManager());
-        if ( instance instanceof Configurable ) {
-            // default configuration to invoke method!
-            if ( conf == null ) {
-                conf = new DefaultConfiguration("", "-");
-            }
-            ContainerUtil.configure(instance, conf);
-        }
-        if ( instance instanceof Parameterizable ) {
-            // default configuration to invoke method!
-            if ( p == null ) {
-                p = new Parameters();
-            }
-            ContainerUtil.parameterize(instance, p);                       
-        }
-        ContainerUtil.initialize(instance);
-        return instance;
-    }
-    
-    protected Object getComponent(String classname,
-                                  Configuration conf) 
-    throws Exception {
-        return this.getComponent(classname, conf, null);
-    }
-
-    protected Object getComponent(String classname,
-                                  Parameters p) 
-    throws Exception {
-        return this.getComponent(classname, null, p);
-    }
-    
-    protected Object getComponent(String classname) 
-    throws Exception {
-        return this.getComponent(classname, null, null);
-    }
-
-    /**
-     * We use this simple logger manager that sends all output to the console (logger)
-     */
-    protected static class DefaultLoggerManager implements LoggerManager {
-        
-        private Logger logger;
-        
-        public DefaultLoggerManager(Logger logger) {
-            this.logger = logger;
-        }
-        /* (non-Javadoc)
-         * @see org.apache.avalon.excalibur.logger.LoggerManager#getDefaultLogger()
-         */
-        public Logger getDefaultLogger() {
-            return this.logger;
-        }
-        /* (non-Javadoc)
-         * @see org.apache.avalon.excalibur.logger.LoggerManager#getLoggerForCategory(java.lang.String)
-         */
-        public Logger getLoggerForCategory(String arg0) {
-            return this.logger;
-        }
-    }
-}
+/* 
+ * Copyright 2002-2004 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 java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ * JUnit TestCase for Cocoon Components.
+ * <p>
+ *   This class extends the JUnit TestCase class to setup an environment which
+ *   makes it possible to easily test Cocoon Components. The following methods
+ *   and instance variables are exposed for convenience testing:
+ * </p>
+ * <dl>
+ *   <dt>getManager()</dt>
+ *   <dd>
+ *     This instance variable contains an initialized service manager which
+ *     can be used to lookup components configured in the test configuration
+ *     file. (see below)
+ *   </dd>
+ *   <dt>getLogger()</dt>
+ *   <dd>
+ *     This method returns a logger for this test case. By default this
+ *     logger logs with log level DEBUG.
+ *   </dd>
+ * </dl>
+ * <p>
+ *   The following test case configuration can be used as a basis for new tests.
+ *   Detailed explanations of the configuration elements can be found after
+ *   the example. 
+ * </p>
+ * <pre>
+ *   &lt;testcase&gt;
+ *     &lt;context&gt;
+ *       &lt;entry name="foo" value="bar"/&gt;
+ *       &lt;entry name="baz" class="my.context.Class"/&gt;
+ *     &lt;/context&gt;
+ *
+ *     &lt;roles&gt;
+ *       &lt;role name="org.apache.avalon.excalibur.datasource.DataSourceComponentSelector"
+ *             shorthand="datasources"
+ *             default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"&gt;
+ *          &lt;hint shorthand="jdbc" class="org.apache.avalon.excalibur.datasource.JdbcDataSource"/&gt;
+ *       &lt;/role&gt;
+ *     &lt;/roles&gt;
+ *
+ *     &lt;components&gt;
+ *       &lt;datasources&gt;
+ *         &lt;jdbc name="personell"&gt;
+ *           &lt;pool-controller min="5" max="10"/&gt;
+ *           &lt;jdbc name="personnel"/&gt;
+ *           &lt;dburl&gt;jdbc:odbc:test&lt;/dburl&gt;
+ *           &lt;user&gt;test&lt;/user&gt;
+ *           &lt;password&gt;test&lt;/password&gt;
+ *           &lt;driver&gt;sun.jdbc.odbc.JdbcOdbcDriver&lt;/driver&gt;
+ *         &lt;/jdbc&gt;
+ *       &lt;/datasources&gt;
+ *     &lt;/components&gt;
+ *   &lt;/testcase&gt;
+ * </pre>
+ * <p>
+ * Element Explanation:
+ * <dl>
+ * <dt>testcase</dt>
+ * <dd>Defines a test case configuration.  Must contain one each of the
+ *  following elements: 
+ *  <code>context</code>, <code>roles</code>, and <code>components</code>
+ *  </dd>.
+ *
+ * <dt>context</dt>
+ * <dd>Allows context properties to be set in the context passed to any
+ *  Contextualizable components.</dd>
+ *
+ * <dt>roles</dt>
+ * <dd>Roles configuration for the components configured in the
+ *  <code>components</code> element.  
+ * </dd>
+ *
+ * <dt>components</dt>
+ * <dd>Used to configure any Components used by the test cases.  
+ * </dd>
+ *
+ * </dl>
+ *
+ * @version $Id$
+ */
+public class ContainerTestCase extends TestCase {
+    
+    /** The default logger */
+    private Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG);
+    
+    /** The service manager to use */
+    private ServiceManager manager;
+
+    /** The context */
+    private Context context;
+    
+    /** Return the logger */
+    protected Logger getLogger() {
+        return logger;
+    }
+
+    /** Return the service manager */
+    protected ServiceManager getManager() {
+        return this.manager;
+    }
+    
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+        this.prepare();
+    }
+    
+    /**
+     * Initializes the ComponentLocator
+     *
+     * The configuration file is determined by the class name plus .xtest appended,
+     * all '.' replaced by '/' and loaded as a resource via classpath
+     */
+    protected void prepare()
+    throws Exception {
+        final String resourceName = getClass().getName().replace( '.', '/' ) + ".xtest";
+        URL resource = getClass().getClassLoader().getResource( resourceName );
+
+        if( resource != null ) {
+            getLogger().debug( "Loading resource " + resourceName );
+            this.prepare( resource.openStream() );
+        } else {
+            getLogger().debug( "Resource not found " + resourceName );
+            this.prepare( null );
+        }
+    }
+
+    /**
+     * Initializes the ComponentLocator
+     *
+     * @param testconf The configuration file is passed as a <code>InputStream</code>
+     *
+     * A common way to supply a InputStream is to overwrite the initialize() method
+     * in the sub class, do there whatever is needed to get the right InputStream object
+     * supplying a conformant xtest configuartion and pass it to this initialize method.
+     * the mentioned initialize method is also the place to set a different logging priority
+     * to the member variable m_logPriority.
+     */
+    protected final void prepare( final InputStream testconf )
+    throws Exception {
+        if ( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Initializing " + this.getName() );
+        }
+
+        final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+        final Configuration conf;
+        if ( testconf != null ) {
+            conf = builder.build( testconf );
+        } else {
+            conf = new DefaultConfiguration("", "-");
+        }
+
+        this.context = this.setupContext( conf.getChild( "context" ) );
+
+        this.setupManagers( conf.getChild( "components" ),
+                            conf.getChild( "roles" ));
+    }
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        this.done();
+        super.tearDown();
+    }
+
+    /**
+     * Disposes the <code>ComponentLocator</code>
+     */
+    final private void done() {
+        if( manager != null ) {
+            ContainerUtil.dispose(manager);
+            manager = null;
+        }
+    }
+
+    /**
+     * set up a context according to the xtest configuration specifications context
+     * element.
+     *
+     * A method addContext(DefaultContext context) is called here to enable subclasses
+     * to put additional objects into the context programmatically.
+     */
+    final private Context setupContext( final Configuration conf )
+    throws Exception {
+        final DefaultContext context = new DefaultContext();
+        final Configuration[] confs = conf.getChildren( "entry" );
+        for( int i = 0; i < confs.length; i++ ) {
+            final String key = confs[ i ].getAttribute( "name" );
+            final String value = confs[ i ].getAttribute( "value", null );
+            if( value == null ) {
+                String clazz = confs[ i ].getAttribute( "class" );
+                Object obj = getClass().getClassLoader().loadClass( clazz ).newInstance();
+                context.put( key, obj );
+                if( getLogger().isInfoEnabled() ) {
+                    getLogger().info( "ContainerTestCase: added an instance of class " + clazz + " to context entry " + key );
+                }
+            } else {
+                context.put( key, value );
+                if( getLogger().isInfoEnabled() ) {
+                    getLogger().info( "ContainerTestCase: added value \"" + value + "\" to context entry " + key );
+                }
+            }
+        }
+        this.addContext( context );
+        return context ;
+    }
+
+    /**
+     * This method may be overwritten by subclasses to put additional objects
+     * into the context programmatically.
+     */
+    protected void addContext( DefaultContext context ) {
+        // nothing to add here
+    }
+
+    /**
+     * This method may be overwritten by subclasses to add aditional
+     * components.
+     */
+    protected void addComponents( CocoonServiceManager manager) 
+    throws ServiceException {
+        // subclasses can add components here
+    }
+    
+    final private void setupManagers( final Configuration confCM,
+                                      final Configuration confRM)
+    throws Exception {
+        // Setup the RoleManager
+        RoleManager roleManager = new RoleManager();
+        roleManager.enableLogging( this.getLogger() );
+        roleManager.configure( confRM );
+
+        // Set up the ComponentLocator
+        CocoonServiceManager ecManager = new CocoonServiceManager(null);
+        ecManager.enableLogging( this.getLogger() );
+        ecManager.contextualize( this.context );
+        ecManager.setRoleManager( roleManager );
+        ecManager.setLoggerManager( new DefaultLoggerManager(this.logger));
+        ecManager.configure( confCM );
+        this.addComponents( ecManager );
+        ecManager.initialize();
+        this.manager = ecManager;
+    }
+
+    protected final Object lookup( final String key )
+    throws ServiceException {
+        return manager.lookup( key );
+    }
+
+    protected final void release( final Object object ) {
+        manager.release( object );
+    }
+    
+    private Object getComponent(String classname,
+                                Configuration conf,
+                                Parameters p) 
+    throws Exception {
+        final Object instance = Class.forName(classname).newInstance();
+        ContainerUtil.enableLogging(instance, getLogger());
+        ContainerUtil.contextualize(instance, this.context);
+        ContainerUtil.service(instance, getManager());
+        if ( instance instanceof Configurable ) {
+            // default configuration to invoke method!
+            if ( conf == null ) {
+                conf = new DefaultConfiguration("", "-");
+            }
+            ContainerUtil.configure(instance, conf);
+        }
+        if ( instance instanceof Parameterizable ) {
+            // default configuration to invoke method!
+            if ( p == null ) {
+                p = new Parameters();
+            }
+            ContainerUtil.parameterize(instance, p);                       
+        }
+        ContainerUtil.initialize(instance);
+        return instance;
+    }
+    
+    protected Object getComponent(String classname,
+                                  Configuration conf) 
+    throws Exception {
+        return this.getComponent(classname, conf, null);
+    }
+
+    protected Object getComponent(String classname,
+                                  Parameters p) 
+    throws Exception {
+        return this.getComponent(classname, null, p);
+    }
+    
+    protected Object getComponent(String classname) 
+    throws Exception {
+        return this.getComponent(classname, null, null);
+    }
+
+    /**
+     * We use this simple logger manager that sends all output to the console (logger)
+     */
+    protected static class DefaultLoggerManager implements LoggerManager {
+        
+        private Logger logger;
+        
+        public DefaultLoggerManager(Logger logger) {
+            this.logger = logger;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.avalon.excalibur.logger.LoggerManager#getDefaultLogger()
+         */
+        public Logger getDefaultLogger() {
+            return this.logger;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.avalon.excalibur.logger.LoggerManager#getLoggerForCategory(java.lang.String)
+         */
+        public Logger getLoggerForCategory(String arg0) {
+            return this.logger;
+        }
+    }
+}

Modified: cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java?view=diff&rev=123716&p1=cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java&r1=123715&p2=cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java&r2=123716
==============================================================================
--- cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java	(original)
+++ cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java	Thu Dec 30 06:16:00 2004
@@ -26,7 +26,7 @@
 /**
  * Test cases for {@link RoleManager}.
  * 
- * @version CVS $Id: RoleManagerTestCase.java 55163 2004-10-20 16:41:11Z ugo $
+ * @version CVS $Id$
  */
 public class RoleManagerTestCase extends MockObjectTestCase {
     

Mime
View raw message