bloritsch    2003/10/22 07:13:52

  Modified:    src/java/org/apache/cocoon/components
                        ComponentLocatorImpl.java ParentAware.java
                        RequestLifecycleComponent.java CocoonContainer.java
                        ContextHelper.java ChainedConfiguration.java
                        LifecycleHelper.java
                        GlobalRequestLifecycleComponent.java
                        CocoonComponentManager.java ComponentLocator.java
                        DefaultSitemapConfigurationHolder.java
                        ComponentContext.java EnvironmentStack.java
  Added:       src/java/org/apache/cocoon/components
                        RequestLifecycleHelper.java
  Log:
  Refactor the helper methods for the RequestLifecycle handling.
  
  Revision  Changes    Path
  1.3       +2 -2      
cocoon-2.2/src/java/org/apache/cocoon/components/ComponentLocatorImpl.java
  
  Index: ComponentLocatorImpl.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/ComponentLocatorImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ComponentLocatorImpl.java 17 Oct 2003 17:49:24 -0000      1.2
  +++ ComponentLocatorImpl.java 22 Oct 2003 14:13:52 -0000      1.3
  @@ -50,8 +50,8 @@
   */
   package org.apache.cocoon.components;
   
  -import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.avalon.framework.service.ServiceException;
  +import org.apache.avalon.framework.service.ServiceManager;
   
   /**
    * This object is set to a [EMAIL PROTECTED] ParentAware} component and 
allows
  
  
  
  1.2       +1 -1      
cocoon-2.2/src/java/org/apache/cocoon/components/ParentAware.java
  
  Index: ParentAware.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/ParentAware.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  
  
  
  1.6       +10 -9     
cocoon-2.2/src/java/org/apache/cocoon/components/RequestLifecycleComponent.java
  
  Index: RequestLifecycleComponent.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/RequestLifecycleComponent.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- RequestLifecycleComponent.java    2 Sep 2003 10:26:18 -0000       1.5
  +++ RequestLifecycleComponent.java    22 Oct 2003 14:13:52 -0000      1.6
  @@ -50,14 +50,13 @@
   */
   package org.apache.cocoon.components;
   
  -import java.io.IOException;
  -import java.util.Map;
  -
  -import org.apache.avalon.excalibur.pool.Poolable;
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.environment.SourceResolver;
   import org.xml.sax.SAXException;
   
  +import java.io.IOException;
  +import java.util.Map;
  +
   /**
    * Components implementing this marker interface have a lifecycle of one
    * request. This means if during one request a component accepting this
  @@ -67,16 +66,18 @@
    * not available to a subrequest.
    * In addition, the first time this component is looked up during a request,
    * the [EMAIL PROTECTED] #setup(SourceResolver, Map)} method is called.
  - * 
  + *
    * @see org.apache.cocoon.components.GlobalRequestLifecycleComponent
  - * 
  + *
  + * TODO: POOLABLE
  + *
    * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
    * @version CVS $Id$
    */
  -public interface RequestLifecycleComponent extends Poolable {
  +public interface RequestLifecycleComponent {
   
       /**
  -     * Set the [EMAIL PROTECTED] SourceResolver} and the objectModel 
  +     * Set the [EMAIL PROTECTED] SourceResolver} and the objectModel
        * used to process the current request.
        */
       void setup(SourceResolver resolver, Map objectModel)
  
  
  
  1.3       +0 -0      
cocoon-2.2/src/java/org/apache/cocoon/components/CocoonContainer.java
  
  Index: CocoonContainer.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/CocoonContainer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  
  
  
  1.5       +3 -3      
cocoon-2.2/src/java/org/apache/cocoon/components/ContextHelper.java
  
  Index: ContextHelper.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/ContextHelper.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ContextHelper.java        1 Jun 2003 15:55:35 -0000       1.4
  +++ ContextHelper.java        22 Oct 2003 14:13:52 -0000      1.5
  @@ -50,14 +50,14 @@
   */
   package org.apache.cocoon.components;
   
  -import java.util.Map;
  -
   import org.apache.avalon.framework.CascadingRuntimeException;
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.context.ContextException;
   import org.apache.cocoon.environment.ObjectModelHelper;
   import org.apache.cocoon.environment.Request;
   import org.apache.cocoon.environment.Response;
  +
  +import java.util.Map;
   
   /**
    * A set of constants and methods to access the content of the context
  
  
  
  1.3       +1 -1      
cocoon-2.2/src/java/org/apache/cocoon/components/ChainedConfiguration.java
  
  Index: ChainedConfiguration.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/ChainedConfiguration.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  
  
  
  1.7       +3 -150    
cocoon-2.2/src/java/org/apache/cocoon/components/LifecycleHelper.java
  
  Index: LifecycleHelper.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/LifecycleHelper.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- LifecycleHelper.java      10 Sep 2003 17:39:39 -0000      1.6
  +++ LifecycleHelper.java      22 Oct 2003 14:13:52 -0000      1.7
  @@ -53,8 +53,6 @@
   import org.apache.avalon.framework.activity.Disposable;
   import org.apache.avalon.framework.activity.Initializable;
   import org.apache.avalon.framework.activity.Startable;
  -import org.apache.avalon.framework.component.ComponentManager;
  -import org.apache.avalon.framework.component.Composable;
   import org.apache.avalon.framework.configuration.Configurable;
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.context.Context;
  @@ -66,9 +64,6 @@
   import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.avalon.framework.service.Serviceable;
   
  -import org.apache.avalon.excalibur.component.RoleManageable;
  -import org.apache.avalon.excalibur.component.RoleManager;
  -
   /**
    * Utility class for setting up Avalon components. Similar to Excalibur's
    * <code>DefaultComponentFactory</code>, but on existing objects.
  @@ -90,10 +85,6 @@
        */
       final private Context m_context;
   
  -    /** The component manager for this component.
  -     */
  -    final private ComponentManager m_componentManager;
  -
       /** The service manager for this component.
        */
       final private ServiceManager m_serviceManager;
  @@ -102,36 +93,9 @@
        */
       final private Configuration m_configuration;
   
  -    /** The RoleManager for child ComponentSelectors
  -     */
  -    final private RoleManager m_roles;
  -
  -    /**
  -     * Construct a new <code>LifecycleHelper</code> that can be used 
repeatedly to
  -     * setup several components. 
  -     * <p>
  -     * <b>Note</b> : if a parameter is <code>null</code>,
  -     * the corresponding method isn't called (e.g. if 
<code>configuration</code> is
  -     * <code>null</code>, <code>configure()</code> isn't called).
  -     *
  -     * @param logger the <code>Logger</code> to pass to 
<code>LogEnabled</code>s, unless there is
  -     *        a <code>LogKitManager</code> and the configuration specifies a 
logger name.
  -     * @param context the <code>Context</code> to pass to 
<code>Contexutalizable</code>s.
  -     * @param componentManager the component manager to pass to 
<code>Composable</code>s.
  -     * @param roles the <code>RoleManager</code> to pass to 
<code>DefaultComponentSelector</code>s.
  -     * @param configuration the <code>Configuration</code> object to pass to 
new instances.
  -     */
  -    public LifecycleHelper(final Logger logger,
  -                            final Context context,
  -                            final ComponentManager componentManager,
  -                            final RoleManager roles,
  -                           final Configuration configuration) {
  -        this(logger, context, null, componentManager, roles, configuration);
  -    }
  -
       /**
        * Construct a new <code>LifecycleHelper</code> that can be used 
repeatedly to
  -     * setup several components. 
  +     * setup several components.
        * <p>
        * <b>Note</b> : if a parameter is <code>null</code>,
        * the corresponding method isn't called (e.g. if 
<code>configuration</code> is
  @@ -140,49 +104,19 @@
        * @param logger the <code>Logger</code> to pass to 
<code>LogEnabled</code>s, unless there is
        *        a <code>LogKitManager</code> and the configuration specifies a 
logger name.
        * @param context the <code>Context</code> to pass to 
<code>Contexutalizable</code>s.
  -     * @param serviceManager the service manager to pass to 
<code>Serviceable</code>s.
  -     * @param roles the <code>RoleManager</code> to pass to 
<code>DefaultComponentSelector</code>s.
  +     * @param serviceManager the component manager to pass to 
<code>Composable</code>s.
        * @param configuration the <code>Configuration</code> object to pass to 
new instances.
        */
       public LifecycleHelper(final Logger logger,
                               final Context context,
                               final ServiceManager serviceManager,
  -                            final RoleManager roles,
  -                           final Configuration configuration) {
  -        this(logger, context, serviceManager, null, roles, configuration);
  -    }
  -
  -    /**
  -     * Construct a new <code>LifecycleHelper</code> that can be used 
repeatedly to
  -     * setup several components. 
  -     * <p>
  -     * <b>Note</b> : if a parameter is <code>null</code>,
  -     * the corresponding method isn't called (e.g. if 
<code>configuration</code> is
  -     * <code>null</code>, <code>configure()</code> isn't called).
  -     *
  -     * @param logger the <code>Logger</code> to pass to 
<code>LogEnabled</code>s, unless there is
  -     *        a <code>LogKitManager</code> and the configuration specifies a 
logger name.
  -     * @param context the <code>Context</code> to pass to 
<code>Contexutalizable</code>s.
  -     * @param serviceManager the service manager to pass to 
<code>Serviceable</code>s.
  -     * @param componentManager the component manager to pass to 
<code>Composable</code>s.
  -     * @param roles the <code>RoleManager</code> to pass to 
<code>DefaultComponentSelector</code>s.
  -     * @param configuration the <code>Configuration</code> object to pass to 
new instances.
  -     */
  -    public LifecycleHelper(final Logger logger,
  -                            final Context context,
  -                            final ServiceManager serviceManager,
  -                            final ComponentManager componentManager,
  -                            final RoleManager roles,
                              final Configuration configuration) {
           m_logger = logger;
           m_context = context;
           m_serviceManager = serviceManager;
  -        m_componentManager = componentManager;
  -        m_roles = roles;
           m_configuration = configuration;
       }
   
  -
       /**
        * Setup a component, including initialization and start.
        *
  @@ -211,41 +145,17 @@
               m_logger,
               m_context,
               m_serviceManager,
  -            m_componentManager,
  -            m_roles,
               m_configuration,
               initializeAndStart);
       }
   
       /**
  -     * Static equivalent to [EMAIL PROTECTED] #setupComponent(Object)}, to 
be used when there's only one
  -     * component to setup.
  -     */
  -    public static Object setupComponent(final Object component,
  -                                         final Logger logger,
  -                                         final Context context,
  -                                         final ComponentManager 
componentManager,
  -                                         final RoleManager roles,
  -                                        final Configuration configuration)
  -    throws Exception {
  -        return setupComponent(
  -            component,
  -            logger,
  -            context,
  -            componentManager,
  -            roles,
  -            configuration,
  -            true);
  -    }
  -
  -    /**
        * Alternative setupComponent method that takes a ServiceManager instead 
of a ComponentManger.
        */
       public static Object setupComponent(final Object component,
                                            final Logger logger,
                                            final Context context,
                                            final ServiceManager serviceManager,
  -                                         final RoleManager roles,
                                           final Configuration configuration)
       throws Exception {
           return setupComponent(
  @@ -253,69 +163,20 @@
               logger,
               context,
               serviceManager,
  -            roles,
               configuration,
               true);
       }
   
       /**
  -     * Static equivalent to [EMAIL PROTECTED] #setupComponent(Object, 
boolean)}, to be used when there's only one
  -     * component to setup.
  -     */
  -    public static Object setupComponent(final Object component,
  -                                         final Logger logger,
  -                                         final Context context,
  -                                         final ComponentManager 
componentManager,
  -                                         final RoleManager roles,
  -                                        final Configuration configuration,
  -                                         final boolean initializeAndStart)
  -    throws Exception {
  -        return setupComponent(
  -            component,
  -            logger,
  -            context,
  -            null,
  -            componentManager,
  -            roles,
  -            configuration,
  -            initializeAndStart);
  -    }
  -
  -    /**
        * Alternative setupComponent method that takes a ServiceManager instead 
of a ComponentManger.
        */
       public static Object setupComponent(final Object component,
                                            final Logger logger,
                                            final Context context,
                                            final ServiceManager serviceManager,
  -                                         final RoleManager roles,
                                           final Configuration configuration,
                                            final boolean initializeAndStart)
       throws Exception {
  -        return setupComponent(
  -            component,
  -            logger,
  -            context,
  -            serviceManager,
  -            null,
  -            roles,
  -            configuration,
  -            initializeAndStart);
  -    }
  -
  -    /**
  -     * Static equivalent to [EMAIL PROTECTED] #setupComponent(Object, 
boolean)}, to be used when there's only one
  -     * component to setup.
  -     */
  -    public static Object setupComponent(final Object component,
  -                                 final Logger logger,
  -                                 final Context context,
  -                                 final ServiceManager serviceManager,
  -                                 final ComponentManager componentManager,
  -                                 final RoleManager roles,
  -                                 final Configuration configuration,
  -                                 final boolean initializeAndStart)
  -    throws Exception {
           if (component instanceof LogEnabled) {
               ((LogEnabled) component).enableLogging(logger);
           }
  @@ -324,16 +185,8 @@
               ((Contextualizable) component).contextualize(context);
           }
   
  -        if (null != componentManager && component instanceof Composable) {
  -            ((Composable) component).compose(componentManager);
  -        }
  -
           if (null != serviceManager && component instanceof Serviceable) {
               ((Serviceable) component).service(serviceManager);
  -        } 
  -        
  -        if (null != roles && component instanceof RoleManageable) {
  -            ((RoleManageable) component).setRoleManager(roles);
           }
   
           if (null != configuration && component instanceof Configurable) {
  
  
  
  1.5       +8 -8      
cocoon-2.2/src/java/org/apache/cocoon/components/GlobalRequestLifecycleComponent.java
  
  Index: GlobalRequestLifecycleComponent.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/GlobalRequestLifecycleComponent.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- GlobalRequestLifecycleComponent.java      2 Sep 2003 10:26:18 -0000       
1.4
  +++ GlobalRequestLifecycleComponent.java      22 Oct 2003 14:13:52 -0000      
1.5
  @@ -50,32 +50,32 @@
   */
   package org.apache.cocoon.components;
   
  -import java.io.IOException;
  -import java.util.Map;
  -
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.environment.SourceResolver;
   import org.xml.sax.SAXException;
   
  +import java.io.IOException;
  +import java.util.Map;
  +
   /**
    * Components implementing this marker interface have a lifecycle of one
    * request-response cycle. This means if during one cycle a component 
accepting this
    * interface is looked up several times, it's always the same instance.
  - * Each internal subrequest happens in the same cycle, so an instance looked 
up in 
  + * Each internal subrequest happens in the same cycle, so an instance looked 
up in
    * either the "main" request or in any of the subrequests is available to all
  - * other requests in this cycle. 
  + * other requests in this cycle.
    * In addition, the first time this component is looked up during a request,
    * the [EMAIL PROTECTED] #setup(SourceResolver, Map)} method is called.
    *
    * @see org.apache.cocoon.components.RequestLifecycleComponent
  - * 
  + *
    * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
    * @version CVS $Id$
    */
   public interface GlobalRequestLifecycleComponent {
   
       /**
  -     * Set the [EMAIL PROTECTED] SourceResolver} and the objectModel 
  +     * Set the [EMAIL PROTECTED] SourceResolver} and the objectModel
        * used to process the current request.
        */
       void setup(SourceResolver resolver, Map objectModel)
  
  
  
  1.23      +33 -449   
cocoon-2.2/src/java/org/apache/cocoon/components/CocoonComponentManager.java
  
  Index: CocoonComponentManager.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/CocoonComponentManager.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- CocoonComponentManager.java       21 Oct 2003 13:38:36 -0000      1.22
  +++ CocoonComponentManager.java       22 Oct 2003 14:13:52 -0000      1.23
  @@ -50,29 +50,23 @@
   */
   package org.apache.cocoon.components;
   
  -import java.util.ArrayList;
  -import java.util.HashMap;
  -import java.util.Iterator;
  -import java.util.List;
  -import java.util.Map;
  -
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.configuration.ConfigurationException;
  -import org.apache.avalon.framework.logger.Logger;
  -import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.avalon.framework.service.ServiceException;
  -import org.apache.avalon.framework.service.ServiceSelector;
  -import org.apache.cocoon.ProcessingException;
  -import org.apache.cocoon.Processor;
  +import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.cocoon.environment.Environment;
  -import org.apache.cocoon.xml.XMLConsumer;
   import org.apache.excalibur.source.SourceResolver;
   
  +import java.util.ArrayList;
  +import java.util.HashMap;
  +import java.util.Iterator;
  +import java.util.Map;
  +
   /**
    * Cocoon Component Manager.
  - * This manager extends the [EMAIL PROTECTED] ExcaliburComponentManager}
  + * This manager extends the ///////
    * by a special lifecycle handling for a [EMAIL PROTECTED] 
RequestLifecycleComponent}
  - * 
  + *
    * WARNING: This is a "private" Cocoon core class - do NOT use this class
    * directly - and do not assume that a [EMAIL PROTECTED] 
org.apache.avalon.framework.service.ServiceManager} you get
    * via the compose() method is an instance of CocoonComponentManager.
  @@ -82,15 +76,9 @@
    * @version CVS $Id$
    */
   public final class CocoonComponentManager
  -extends ExcaliburComponentManager
  +implements SourceResolver, ServiceManager
   {
   
  -    /** The key used to store the current process environment */
  -    private static final String PROCESS_KEY = 
CocoonComponentManager.class.getName();
  -
  -
  -    /** The environment information */
  -    private static InheritableThreadLocal environmentStack = new 
CloningInheritableThreadLocal();
   
       /** The configured [EMAIL PROTECTED] SourceResolver} */
       private SourceResolver sourceResolver;
  @@ -107,173 +95,16 @@
   
       /** Create the ComponentManager */
       public CocoonComponentManager() {
  -        super( null, Thread.currentThread().getContextClassLoader() );
  -    }
  -
  -    /** Create the ComponentManager with a Classloader */
  -    public CocoonComponentManager(final ClassLoader loader) {
  -        super( null, loader );
  -    }
  -
  -    /** Create the ComponentManager with a Classloader and parent 
ComponentManager */
  -    public CocoonComponentManager(final ServiceManager manager, final 
ClassLoader loader) {
  -        super( manager, loader );
  -        this.parentManager = manager;
       }
   
       /** Create the ComponentManager with a parent ComponentManager */
       public CocoonComponentManager(final ServiceManager manager) {
  -        super( manager);
           this.parentManager = manager;
       }
   
  -    /**
  -     * This hook must be called by the sitemap each time a sitemap is entered
  -     * This method should never raise an exception, except when the
  -     * parameters are not set!
  -     */
  -    public static void enterEnvironment(Environment      env,
  -                                        ServiceManager manager,
  -                                        Processor        processor) {
  -        if ( null == env || null == manager || null == processor) {
  -            throw new 
IllegalArgumentException("CocoonComponentManager.enterEnvironment: all 
parameters must be set: " + env + " - " + manager + " - " + processor);
  -        }
  -
  -        EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
  -             if (stack == null) {
  -            stack = new EnvironmentStack();
  -                     environmentStack.set(stack);
  -             }
  -             stack.push(new Object[] {env, processor, manager, new 
Integer(stack.getOffset())});
  -        stack.setOffset(stack.size()-1);
  -
  -        env.setAttribute("CocoonComponentManager.processor", processor);
  -    }
  -
  -    /**
  -     * This hook must be called by the sitemap each time a sitemap is left.
  -     * It's the counterpart to [EMAIL PROTECTED] 
#enterEnvironment(Environment, ServiceManager, Processor)}.
  -     */
  -    public static void leaveEnvironment() {
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        final Object[] objs = (Object[])stack.pop();
  -        stack.setOffset(((Integer)objs[3]).intValue());
  -        if ( stack.isEmpty() ) {
  -            final Environment env = (Environment)objs[0];
  -            final Map globalComponents = 
(Map)env.getAttribute(GlobalRequestLifecycleComponent.class.getName());
  -            if ( globalComponents != null) {
  -
  -                final Iterator iter = globalComponents.values().iterator();
  -                while ( iter.hasNext() ) {
  -                    final Object[] o = (Object[])iter.next();
  -                    final Object c = o[0];
  -                    ((CocoonComponentManager)o[1]).releaseRLComponent( c );
  -                }
  -            }
  -            
env.removeAttribute(GlobalRequestLifecycleComponent.class.getName());
  -        }
  -    }
  -
  -    public static void checkEnvironment(Logger logger)
  -    throws Exception {
  -        // TODO (CZ): This is only for testing - remove it later on
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        if (stack != null && !stack.isEmpty() ) {
  -            logger.error("ENVIRONMENT STACK HAS NOT BEEN CLEANED PROPERLY");
  -            throw new ProcessingException("Environment stack has not been 
cleaned up properly. "
  -                                          +"Please report this (if possible 
together with a test case) "
  -                                          +"to the Cocoon developers.");
  -        }
  -    }
  -
  -    /**
  -     * Create an environment aware xml consumer for the cocoon
  -     * protocol
  -     */
  -    public static XMLConsumer createEnvironmentAwareConsumer(XMLConsumer 
consumer) {
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        final Object[] objs = (Object[])stack.getCurrent();
  -        return stack.getEnvironmentAwareConsumerWrapper(consumer, 
((Integer)objs[3]).intValue());
  -    }
  -
  -    /**
  -     * This hook has to be called before a request is processed.
  -     * The hook is called by the Cocoon component and by the
  -     * cocoon protocol implementation.
  -     * This method should never raise an exception, except when
  -     * the environment is not set.
  -     *
  -     * @return A unique key within this thread.
  -     */
  -    public static Object startProcessing(Environment env) {
  -             if ( null == env) {
  -                     throw new 
RuntimeException("CocoonComponentManager.startProcessing: environment must be 
set.");
  -             }
  -        final EnvironmentDescription desc = new EnvironmentDescription(env);
  -        env.getObjectModel().put(PROCESS_KEY, desc);
  -             env.startingProcessing();
  -        return desc;
  -    }
  -
  -    /**
  -     * This hook has to be called before a request is processed.
  -     * The hook is called by the Cocoon component and by the
  -     * cocoon protocol implementation.
  -     * @param key A unique key within this thread return by
  -     *         [EMAIL PROTECTED] #startProcessing(Environment)}.
  -     */
  -    public static void endProcessing(Environment env, Object key) {
  -             env.finishingProcessing();
  -        final EnvironmentDescription desc = (EnvironmentDescription)key;
  -        desc.release();
  -        env.getObjectModel().remove(PROCESS_KEY);
  -    }
  -
  -    /**
  -     * Return the current environment (for the cocoon: protocol)
  -     */
  -    public static Environment getCurrentEnvironment() {
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        if (null != stack && !stack.empty()) {
  -            return (Environment) ((Object[])stack.getCurrent())[0];
  -        }
  -        return null;
  -    }
  -
  -    /**
  -     * Return the current processor (for the cocoon: protocol)
  -     */
  -    public static Processor getCurrentProcessor() {
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        if (null != stack && !stack.empty()) {
  -            return (Processor) ((Object[])stack.getCurrent())[1];
  -        }
  -        return null;
  -    }
  -
  -    /**
  -     * Return the processor that is actually processing the request
  -     */
  -    public static Processor getLastProcessor(Environment env) {
  -        return 
(Processor)env.getAttribute("CocoonComponentManager.processor");
  -    }
  -
  -    /**
  -     * Get the current sitemap component manager.
  -     * This method return the current sitemap component manager. This
  -     * is the manager that holds all the components of the currently
  -     * processed (sub)sitemap.
  -     */
  -    static public ServiceManager getSitemapComponentManager() {
  -             final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -
  -             if ( null != stack && !stack.empty()) {
  -                     Object[] o = (Object[])stack.peek();
  -                     return (ServiceManager)o[2];
  -             }
  -
  -        // if we don't have an environment yet, just return null
  -        return null;
  +    public boolean hasService(String role)
  +    {
  +        return parentManager.hasService(role);
       }
   
       /**
  @@ -289,12 +120,18 @@
   
               throw new ServiceException( role, message );
           }
  +        if ( role.equals(SourceResolver.ROLE) ) {
  +            if ( null == this.sourceResolver ) {
  +                this.sourceResolver = (SourceResolver) parentManager.lookup( 
role );
  +            }
  +            return this;
  +        }
   
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  +        final EnvironmentStack stack = 
RequestLifecycleHelper.getTopEnvironmentStack();
           if ( null != stack && !stack.empty()) {
               final Object[] objects = (Object[])stack.getCurrent();
               final Map objectModel = 
((Environment)objects[0]).getObjectModel();
  -            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  +            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(RequestLifecycleHelper.PROCESS_KEY);
               if ( null != desc ) {
                   Object component = desc.getRequestLifecycleComponent(role);
                   if (null != component) {
  @@ -307,22 +144,19 @@
               }
           }
   
  -        final Object component = super.lookup( role );
  +        final Object component = parentManager.lookup( role );
           if (null != component && component instanceof 
RequestLifecycleComponent) {
               if (stack == null || stack.empty()) {
                   throw new ServiceException(role, "ComponentManager has no 
Environment Stack.");
               }
               final Object[] objects = (Object[]) stack.getCurrent();
               final Map objectModel = 
((Environment)objects[0]).getObjectModel();
  -            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  +            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(RequestLifecycleHelper.PROCESS_KEY);
               if ( null != desc ) {
   
                   // first test if the parent CM has already initialized this 
component
                   if ( !desc.containsRequestLifecycleComponent( role ) ) {
                       try {
  -                        if (component instanceof Reserviceable) {
  -                            ((Reserviceable) component).recompose(this);
  -                        }
                           ((RequestLifecycleComponent) 
component).setup((org.apache.cocoon.environment.SourceResolver)objects[0],
                                                                         
objectModel);
                       } catch (Exception local) {
  @@ -339,15 +173,12 @@
               }
               final Object[] objects = (Object[]) stack.getCurrent();
               final Map objectModel = 
((Environment)objects[0]).getObjectModel();
  -            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  +            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(RequestLifecycleHelper.PROCESS_KEY);
               if ( null != desc ) {
   
                   // first test if the parent CM has already initialized this 
component
                   if ( !desc.containsGlobalRequestLifecycleComponent( role ) ) 
{
                       try {
  -                        if (component instanceof Reserviceable ) {
  -                            ((Reserviceable) component).recompose(this);
  -                        }
                           ((GlobalRequestLifecycleComponent) 
component).setup((org.apache.cocoon.environment.SourceResolver)objects[0],
                                                                         
objectModel);
                       } catch (Exception local) {
  @@ -392,71 +223,17 @@
                || component instanceof GlobalRequestLifecycleComponent) {
               return;
           }
  -        super.release( component);
  +        if ( component == this ) {
  +            return;
  +        }
  +        parentManager.release( component);
       }
   
       /**
        * Release a RequestLifecycleComponent
        */
       protected void releaseRLComponent( final Object component ) {
  -        super.release( component );
  -    }
  -
  -    /**
  -     * Add an automatically released component
  -     */
  -    public static void addComponentForAutomaticRelease(final ServiceSelector 
selector,
  -                                                       final Object         
component,
  -                                                       final ServiceManager  
manager)
  -    throws ProcessingException {
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        if ( null != stack && !stack.empty()) {
  -            final Object[] objects = (Object[])stack.get(0);
  -            final Map objectModel = 
((Environment)objects[0]).getObjectModel();
  -            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  -            if ( null != desc ) {
  -                desc.addToAutoRelease(selector, component, manager);
  -            }
  -        } else {
  -            throw new ProcessingException("Unable to add component for 
automatic release: no environment available.");
  -        }
  -    }
  -
  -    /**
  -     * Add an automatically released component
  -     */
  -    public static void addComponentForAutomaticRelease(final ServiceManager 
manager,
  -                                                       final Object        
component)
  -    throws ProcessingException {
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        if ( null != stack && !stack.empty()) {
  -            final Object[] objects = (Object[])stack.get(0);
  -            final Map objectModel = 
((Environment)objects[0]).getObjectModel();
  -            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  -            if ( null != desc ) {
  -                desc.addToAutoRelease(manager, component);
  -            }
  -        } else {
  -            throw new ProcessingException("Unable to add component for 
automatic release: no environment available.");
  -        }
  -    }
  -
  -    /**
  -     * Remove from automatically released components
  -     */
  -    public static void removeFromAutomaticRelease(final Object component)
  -    throws ProcessingException {
  -        final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  -        if ( null != stack && !stack.empty()) {
  -            final Object[] objects = (Object[])stack.get(0);
  -            final Map objectModel = 
((Environment)objects[0]).getObjectModel();
  -            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  -            if ( null != desc ) {
  -                desc.removeFromAutoRelease(component);
  -            }
  -        } else {
  -            throw new ProcessingException("Unable to remove component from 
automatic release: no environment available.");
  -        }
  +        parentManager.release( component );
       }
   
       /**
  @@ -464,10 +241,9 @@
        */
       public void dispose() {
           if ( null != this.sourceResolver ) {
  -            super.release( this.sourceResolver );
  +            parentManager.release( this.sourceResolver );
               this.sourceResolver = null;
           }
  -        super.dispose();
       }
   
       /* (non-Javadoc)
  @@ -475,7 +251,7 @@
        */
       public void addComponent(String role, Class clazz, Configuration conf)
           throws ServiceException {
  -        super.addComponent(role, clazz, conf);
  +//        super.addComponent(role, clazz, conf);
           // Note that at this point, we're not initialized and cannot do
           // lookups, so defer parental introductions to initialize().
           if ( ParentAware.class.isAssignableFrom( clazz ) ) {
  @@ -486,7 +262,7 @@
       public void initialize()
           throws Exception
       {
  -        super.initialize();
  +//        super.initialize();
           if (parentAwareComponents == null) {
               throw new ServiceException(null, "CocoonComponentManager already 
initialized");
           }
  @@ -494,7 +270,7 @@
           Iterator iter = parentAwareComponents.iterator();
           while (iter.hasNext()) {
               String role = (String)iter.next();
  -            getLogger().debug(".. "+role);
  +//            getLogger().debug(".. "+role);
               if ( parentManager != null && parentManager.hasService( role ) ) 
{
                   // lookup new component
                   Object component = null;
  @@ -512,196 +288,4 @@
       }
   }
   
  -final class EnvironmentDescription {
  -
  -    Environment environment;
  -    Map         objectModel;
  -    Map         requestLifecycleComponents;
  -    List        autoreleaseComponents      = new ArrayList(4);
  -
  -    /**
  -     * Constructor
  -     */
  -    EnvironmentDescription(Environment env) {
  -        this.environment = env;
  -        this.objectModel = env.getObjectModel();
  -    }
  -
  -    Map getGlobalRequestLifcecycleComponents() {
  -        Map m = 
(Map)environment.getAttribute(GlobalRequestLifecycleComponent.class.getName());
  -        if ( m == null ) {
  -            m = new HashMap();
  -            
environment.setAttribute(GlobalRequestLifecycleComponent.class.getName(), m);
  -        }
  -        return m;
  -    }
  -
  -    /**
  -     * Release all components of this environment
  -     * All RequestLifecycleComponents and autoreleaseComponents are
  -     * released.
  -     */
  -    void release() {
  -        if ( this.requestLifecycleComponents != null ) {
  -            final Iterator iter = 
this.requestLifecycleComponents.values().iterator();
  -            while (iter.hasNext()) {
  -                final Object[] o = (Object[])iter.next();
  -                final Object component = o[0];
  -                ((CocoonComponentManager)o[1]).releaseRLComponent( component 
);
  -            }
  -            this.requestLifecycleComponents.clear();
  -        }
  -
  -        for(int i = 0; i < autoreleaseComponents.size(); i++) {
  -            final Object[] o = (Object[])autoreleaseComponents.get(i);
  -            final Object component = o[0];
  -            if (o[1] instanceof ServiceManager) {
  -                ((ServiceManager)o[1]).release( component );
  -            } else {
  -                ((ServiceSelector)o[1]).release( component );
  -                if (o[2] != null) {
  -                    ((ServiceManager)o[2]).release( o[1] );
  -                }
  -            }
  -        }
  -        this.autoreleaseComponents.clear();
  -        this.environment = null;
  -        this.objectModel = null;
  -    }
  -
  -
  -    /**
  -     * Add a RequestLifecycleComponent to the environment
  -     */
  -    void addRequestLifecycleComponent(final String role,
  -                                      final Object co,
  -                                      final ServiceManager manager) {
  -        if ( this.requestLifecycleComponents == null ) {
  -            this.requestLifecycleComponents = new HashMap();
  -        }
  -        this.requestLifecycleComponents.put(role, new Object[] {co, 
manager});
  -    }
  -
  -    /**
  -     * Add a GlobalRequestLifecycleComponent to the environment
  -     */
  -    void addGlobalRequestLifecycleComponent(final String role,
  -                                      final Object co,
  -                                      final ServiceManager manager) {
  -        this.getGlobalRequestLifcecycleComponents().put(role, new Object[] 
{co, manager});
  -    }
  -
  -    /**
  -     * Do we already have a request lifecycle component
  -     */
  -    boolean containsRequestLifecycleComponent(final String role) {
  -        if ( this.requestLifecycleComponents == null ) {
  -            return false;
  -        }
  -        return this.requestLifecycleComponents.containsKey( role );
  -    }
  -
  -    /**
  -     * Do we already have a global request lifecycle component
  -     */
  -    boolean containsGlobalRequestLifecycleComponent(final String role) {
  -        return this.getGlobalRequestLifcecycleComponents().containsKey( role 
);
  -    }
  -
  -    /**
  -     * Search a RequestLifecycleComponent
  -     */
  -    Object getRequestLifecycleComponent(final String role) {
  -        if ( this.requestLifecycleComponents == null ) {
  -            return null;
  -        }
  -        final Object[] o = 
(Object[])this.requestLifecycleComponents.get(role);
  -        if ( null != o ) {
  -            return o[0];
  -        }
  -        return null;
  -    }
  -
  -    /**
  -     * Search a GlobalRequestLifecycleComponent
  -     */
  -    Object getGlobalRequestLifecycleComponent(final String role) {
  -        final Object[] o = 
(Object[])this.getGlobalRequestLifcecycleComponents().get(role);
  -        if ( null != o ) {
  -            return o[0];
  -        }
  -        return null;
  -    }
  -
  -    /**
  -     * Add an automatically released component
  -     */
  -    void addToAutoRelease(final ServiceSelector selector,
  -                          final Object         component,
  -                          final ServiceManager  manager) {
  -        this.autoreleaseComponents.add(new Object[] {component, selector, 
manager});
  -    }
  -
  -    /**
  -     * Add an automatically released component
  -     */
  -    void addToAutoRelease(final ServiceManager manager,
  -                          final Object        component) {
  -        this.autoreleaseComponents.add(new Object[] {component, manager});
  -    }
  -
  -    /**
  -     * Remove from automatically released components
  -     */
  -    void removeFromAutoRelease(final Object component)
  -    throws ProcessingException {
  -        int i = 0;
  -        boolean found = false;
  -        while (i < this.autoreleaseComponents.size() && !found) {
  -            final Object[] o = (Object[])this.autoreleaseComponents.get(i);
  -            if (o[0] == component) {
  -                found = true;
  -                if (o[1] instanceof ServiceManager) {
  -                    ((ServiceManager)o[1]).release( component );
  -                } else {
  -                    ((ServiceSelector)o[1]).release( component );
  -                    if (o[2] != null) {
  -                        ((ServiceManager)o[2]).release( o[1] );
  -                    }
  -                }
  -                this.autoreleaseComponents.remove(i);
  -            } else {
  -                i++;
  -            }
  -        }
  -        if (!found) {
  -            throw new ProcessingException("Unable to remove component from 
automatic release: component not found.");
  -        }
  -    }
  -
  -}
  -
  -final class CloningInheritableThreadLocal
  -    extends InheritableThreadLocal {
  -
  -    /**
  -     * Computes the child's initial value for this InheritableThreadLocal
  -     * as a function of the parent's value at the time the child Thread is
  -     * created.  This method is called from within the parent thread before
  -     * the child is started.
  -     * <p>
  -     * This method merely returns its input argument, and should be 
overridden
  -     * if a different behavior is desired.
  -     *
  -     * @param parentValue the parent thread's value
  -     * @return the child thread's initial value
  -     */
  -    protected Object childValue(Object parentValue) {
  -        if ( null != parentValue) {
  -            return ((EnvironmentStack)parentValue).clone();
  -        } else {
  -            return null;
  -        }
  -    }
  -}
   
  
  
  
  1.3       +1 -1      
cocoon-2.2/src/java/org/apache/cocoon/components/ComponentLocator.java
  
  Index: ComponentLocator.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/ComponentLocator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  
  
  
  1.4       +8 -8      
cocoon-2.2/src/java/org/apache/cocoon/components/DefaultSitemapConfigurationHolder.java
  
  Index: DefaultSitemapConfigurationHolder.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/DefaultSitemapConfigurationHolder.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultSitemapConfigurationHolder.java    19 Apr 2003 19:49:33 -0000      
1.3
  +++ DefaultSitemapConfigurationHolder.java    22 Oct 2003 14:13:52 -0000      
1.4
  @@ -58,24 +58,24 @@
    * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
    * @version CVS $Id$
    */
  -public final class DefaultSitemapConfigurationHolder 
  +public final class DefaultSitemapConfigurationHolder
       implements SitemapConfigurationHolder {
   
       /** The role of the sitemap component */
       private String role;
  -    
  +
       /** The prepared configurations indexed by the ChainedConfiguration */
       private Map preparedConfigurations;
  -    
  +
       public DefaultSitemapConfigurationHolder(String role) {
           this.role = role;
       }
  -    
  +
       /**
        * @see SitemapConfigurationHolder#getConfiguration()
        */
       public ChainedConfiguration getConfiguration() {
  -        Map confs = 
CocoonComponentManager.getCurrentProcessor().getComponentConfigurations();
  +        Map confs = 
RequestLifecycleHelper.getCurrentProcessor().getComponentConfigurations();
           return (ChainedConfiguration) (confs == null ? null : 
confs.get(this.role));
       }
   
  @@ -95,10 +95,10 @@
       /**
        * @see 
SitemapConfigurationHolder#setPreparedConfiguration(ChainedConfiguration, 
java.lang.Object)
        */
  -    public void setPreparedConfiguration(ChainedConfiguration configuration, 
  +    public void setPreparedConfiguration(ChainedConfiguration configuration,
                                             Object preparedConfig) {
           if ( null == this.preparedConfigurations ) {
  -            this.preparedConfigurations = new HashMap(5);                    
                          
  +            this.preparedConfigurations = new HashMap(5);
           }
           this.preparedConfigurations.put(configuration, preparedConfig);
       }
  
  
  
  1.3       +8 -8      
cocoon-2.2/src/java/org/apache/cocoon/components/ComponentContext.java
  
  Index: ComponentContext.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/ComponentContext.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ComponentContext.java     23 May 2003 12:14:04 -0000      1.2
  +++ ComponentContext.java     22 Oct 2003 14:13:52 -0000      1.3
  @@ -50,12 +50,12 @@
   */
   package org.apache.cocoon.components;
   
  -import java.util.Map;
  -
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.context.ContextException;
   import org.apache.avalon.framework.context.DefaultContext;
   
  +import java.util.Map;
  +
   /**
    * This is the [EMAIL PROTECTED] Context} implementation for Cocoon 
components.
    * It extends the [EMAIL PROTECTED] DefaultContext} by a special handling for
  @@ -65,11 +65,11 @@
    * @version CVS $Id$
    */
   
  -public class ComponentContext 
  +public class ComponentContext
       extends DefaultContext {
   
       protected static final String OBJECT_MODEL_KEY_PREFIX = 
ContextHelper.CONTEXT_OBJECT_MODEL + '.';
  -    
  +
       /**
        * Create a Context with specified data and parent.
        *
  @@ -116,14 +116,14 @@
       public Object get( final Object key )
       throws ContextException {
           if ( key.equals(ContextHelper.CONTEXT_OBJECT_MODEL)) {
  -            return 
CocoonComponentManager.getCurrentEnvironment().getObjectModel();
  +            return 
RequestLifecycleHelper.getCurrentEnvironment().getObjectModel();
           }
           if ( key instanceof String ) {
               String stringKey = (String)key;
               if ( stringKey.startsWith(OBJECT_MODEL_KEY_PREFIX) ) {
  -                final Map objectModel = 
CocoonComponentManager.getCurrentEnvironment().getObjectModel();
  +                final Map objectModel = 
RequestLifecycleHelper.getCurrentEnvironment().getObjectModel();
                   String objectKey = 
stringKey.substring(OBJECT_MODEL_KEY_PREFIX.length());
  -                
  +
                   Object o = objectModel.get( objectKey );
                   if ( o == null ) {
                       final String message = "Unable to locate " + key;
  
  
  
  1.3       +1 -1      
cocoon-2.2/src/java/org/apache/cocoon/components/EnvironmentStack.java
  
  Index: EnvironmentStack.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.2/src/java/org/apache/cocoon/components/EnvironmentStack.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  
  
  
  1.1                  
cocoon-2.2/src/java/org/apache/cocoon/components/RequestLifecycleHelper.java
  
  Index: RequestLifecycleHelper.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software 
Foundation"
      must not be used to endorse or promote products derived from this  
software
      without  prior written permission. For written permission, please contact
      [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.components;
  
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceSelector;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.Processor;
  import org.apache.cocoon.environment.Environment;
  import org.apache.cocoon.xml.XMLConsumer;
  
  import java.util.*;
  
  /**
   * RequestLifecycleHelper Encapsulates all the static processing that is 
needed
   * for handling RequestLifecycle components.
   *
   * @author <a href="bloritsch.at.apache.org">Berin Loritsch</a>
   * @version CVS $ Revision: 1.1 $
   */
  class RequestLifecycleHelper
  {
      /** The key used to store the current process environment */
      static final String PROCESS_KEY = CocoonComponentManager.class.getName();
      /** The environment information */
      private static InheritableThreadLocal environmentStack = new 
CloningInheritableThreadLocal();
  
      static EnvironmentStack getTopEnvironmentStack()
      {
          return (EnvironmentStack)environmentStack.get();
      }
  
      /**
       * This hook must be called by the sitemap each time a sitemap is entered
       * This method should never raise an exception, except when the
       * parameters are not set!
       */
      static void enterEnvironment(Environment      env,
                                          ServiceManager manager,
                                          Processor        processor) {
          if ( null == env || null == manager || null == processor) {
              throw new 
IllegalArgumentException("CocoonComponentManager.enterEnvironment: all 
parameters must be set: " + env + " - " + manager + " - " + processor);
          }
  
          EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
                if (stack == null) {
              stack = new EnvironmentStack();
                        environmentStack.set(stack);
                }
                stack.push(new Object[] {env, processor, manager, new 
Integer(stack.getOffset())});
          stack.setOffset(stack.size()-1);
  
          env.setAttribute("CocoonComponentManager.processor", processor);
      }
  
      /**
       * This hook must be called by the sitemap each time a sitemap is left.
       * It's the counterpart to [EMAIL PROTECTED] 
#enterEnvironment(Environment, ServiceManager, Processor)}.
       */
      static void leaveEnvironment() {
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          final Object[] objs = (Object[])stack.pop();
          stack.setOffset(((Integer)objs[3]).intValue());
          if ( stack.isEmpty() ) {
              final Environment env = (Environment)objs[0];
              final Map globalComponents = 
(Map)env.getAttribute(GlobalRequestLifecycleComponent.class.getName());
              if ( globalComponents != null) {
  
                  final Iterator iter = globalComponents.values().iterator();
                  while ( iter.hasNext() ) {
                      final Object[] o = (Object[])iter.next();
                      final Object c = o[0];
                      ((CocoonComponentManager)o[1]).releaseRLComponent( c );
                  }
              }
              
env.removeAttribute(GlobalRequestLifecycleComponent.class.getName());
          }
      }
  
      static void checkEnvironment(Logger logger)
      throws Exception {
          // TODO (CZ): This is only for testing - remove it later on
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          if (stack != null && !stack.isEmpty() ) {
              logger.error("ENVIRONMENT STACK HAS NOT BEEN CLEANED PROPERLY");
              throw new ProcessingException("Environment stack has not been 
cleaned up properly. "
                                            +"Please report this (if possible 
together with a test case) "
                                            +"to the Cocoon developers.");
          }
      }
  
      /**
       * Create an environment aware xml consumer for the cocoon
       * protocol
       */
      static XMLConsumer createEnvironmentAwareConsumer(XMLConsumer consumer) {
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          final Object[] objs = (Object[])stack.getCurrent();
          return stack.getEnvironmentAwareConsumerWrapper(consumer, 
((Integer)objs[3]).intValue());
      }
  
      /**
       * This hook has to be called before a request is processed.
       * The hook is called by the Cocoon component and by the
       * cocoon protocol implementation.
       * This method should never raise an exception, except when
       * the environment is not set.
       *
       * @return A unique key within this thread.
       */
      static Object startProcessing(Environment env) {
                if ( null == env) {
                        throw new 
RuntimeException("CocoonComponentManager.startProcessing: environment must be 
set.");
                }
          final EnvironmentDescription desc = new EnvironmentDescription(env);
          env.getObjectModel().put(PROCESS_KEY, desc);
                env.startingProcessing();
          return desc;
      }
  
      /**
       * This hook has to be called before a request is processed.
       * The hook is called by the Cocoon component and by the
       * cocoon protocol implementation.
       * @param key A unique key within this thread return by
       *         [EMAIL PROTECTED] #startProcessing(Environment)}.
       */
      static void endProcessing(Environment env, Object key) {
                env.finishingProcessing();
          final EnvironmentDescription desc = (EnvironmentDescription)key;
          desc.release();
          env.getObjectModel().remove(PROCESS_KEY);
      }
  
      /**
       * Return the current environment (for the cocoon: protocol)
       */
      static Environment getCurrentEnvironment() {
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          if (null != stack && !stack.empty()) {
              return (Environment) ((Object[])stack.getCurrent())[0];
          }
          return null;
      }
  
      /**
       * Return the current processor (for the cocoon: protocol)
       */
      static Processor getCurrentProcessor() {
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          if (null != stack && !stack.empty()) {
              return (Processor) ((Object[])stack.getCurrent())[1];
          }
          return null;
      }
  
      /**
       * Return the processor that is actually processing the request
       */
      static Processor getLastProcessor(Environment env) {
          return 
(Processor)env.getAttribute("CocoonComponentManager.processor");
      }
  
      /**
       * Get the current sitemap component manager.
       * This method return the current sitemap component manager. This
       * is the manager that holds all the components of the currently
       * processed (sub)sitemap.
       */
      static public ServiceManager getSitemapComponentManager() {
                final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
  
                if ( null != stack && !stack.empty()) {
                        Object[] o = (Object[])stack.peek();
                        return (ServiceManager)o[2];
                }
  
          // if we don't have an environment yet, just return null
          return null;
      }
  
      /**
       * Add an automatically released component
       */
      static void addComponentForAutomaticRelease(final ServiceSelector 
selector,
                                                         final Object         
component,
                                                         final ServiceManager  
manager)
      throws ProcessingException {
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          if ( null != stack && !stack.empty()) {
              final Object[] objects = (Object[])stack.get(0);
              final Map objectModel = 
((Environment)objects[0]).getObjectModel();
              EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
              if ( null != desc ) {
                  desc.addToAutoRelease(selector, component, manager);
              }
          } else {
              throw new ProcessingException("Unable to add component for 
automatic release: no environment available.");
          }
      }
  
      /**
       * Add an automatically released component
       */
      static void addComponentForAutomaticRelease(final ServiceManager manager,
                                                         final Object        
component)
      throws ProcessingException {
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          if ( null != stack && !stack.empty()) {
              final Object[] objects = (Object[])stack.get(0);
              final Map objectModel = 
((Environment)objects[0]).getObjectModel();
              EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
              if ( null != desc ) {
                  desc.addToAutoRelease(manager, component);
              }
          } else {
              throw new ProcessingException("Unable to add component for 
automatic release: no environment available.");
          }
      }
  
      /**
       * Remove from automatically released components
       */
      public static void removeFromAutomaticRelease(final Object component)
      throws ProcessingException {
          final EnvironmentStack stack = 
(EnvironmentStack)environmentStack.get();
          if ( null != stack && !stack.empty()) {
              final Object[] objects = (Object[])stack.get(0);
              final Map objectModel = 
((Environment)objects[0]).getObjectModel();
              EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
              if ( null != desc ) {
                  desc.removeFromAutoRelease(component);
              }
          } else {
              throw new ProcessingException("Unable to remove component from 
automatic release: no environment available.");
          }
      }
  }
  
  final class CloningInheritableThreadLocal
          extends InheritableThreadLocal
  {
  
      /**
       * Computes the child's initial value for this InheritableThreadLocal
       * as a function of the parent's value at the time the child Thread is
       * created.  This method is called from within the parent thread before
       * the child is started.
       * <p>
       * This method merely returns its input argument, and should be overridden
       * if a different behavior is desired.
       *
       * @param parentValue the parent thread's value
       * @return the child thread's initial value
       */
      protected Object childValue( Object parentValue )
      {
          if ( null != parentValue )
          {
              return ( (EnvironmentStack) parentValue ).clone();
          }
          else
          {
              return null;
          }
      }
  }
  
  
  final class EnvironmentDescription
  {
  
      Environment environment;
      Map objectModel;
      Map requestLifecycleComponents;
      List autoreleaseComponents = new ArrayList( 4 );
  
      /**
       * Constructor
       */
      EnvironmentDescription( Environment env )
      {
          this.environment = env;
          this.objectModel = env.getObjectModel();
      }
  
      Map getGlobalRequestLifcecycleComponents()
      {
          Map m = (Map) environment.getAttribute( 
GlobalRequestLifecycleComponent.class.getName() );
          if ( m == null )
          {
              m = new HashMap();
              environment.setAttribute( 
GlobalRequestLifecycleComponent.class.getName(), m );
          }
          return m;
      }
  
      /**
       * Release all components of this environment
       * All RequestLifecycleComponents and autoreleaseComponents are
       * released.
       */
      void release()
      {
          if ( this.requestLifecycleComponents != null )
          {
              final Iterator iter = 
this.requestLifecycleComponents.values().iterator();
              while ( iter.hasNext() )
              {
                  final Object[] o = (Object[]) iter.next();
                  final Object component = o[0];
                  ( (CocoonComponentManager) o[1] ).releaseRLComponent( 
component );
              }
              this.requestLifecycleComponents.clear();
          }
  
          for ( int i = 0; i < autoreleaseComponents.size(); i++ )
          {
              final Object[] o = (Object[]) autoreleaseComponents.get( i );
              final Object component = o[0];
              if ( o[1] instanceof ServiceManager )
              {
                  ( (ServiceManager) o[1] ).release( component );
              }
              else
              {
                  ( (ServiceSelector) o[1] ).release( component );
                  if ( o[2] != null )
                  {
                      ( (ServiceManager) o[2] ).release( o[1] );
                  }
              }
          }
          this.autoreleaseComponents.clear();
          this.environment = null;
          this.objectModel = null;
      }
  
  
      /**
       * Add a RequestLifecycleComponent to the environment
       */
      void addRequestLifecycleComponent( final String role,
                                         final Object co,
                                         final ServiceManager manager )
      {
          if ( this.requestLifecycleComponents == null )
          {
              this.requestLifecycleComponents = new HashMap();
          }
          this.requestLifecycleComponents.put( role, new Object[]{co, manager} 
);
      }
  
      /**
       * Add a GlobalRequestLifecycleComponent to the environment
       */
      void addGlobalRequestLifecycleComponent( final String role,
                                               final Object co,
                                               final ServiceManager manager )
      {
          this.getGlobalRequestLifcecycleComponents().put( role, new 
Object[]{co, manager} );
      }
  
      /**
       * Do we already have a request lifecycle component
       */
      boolean containsRequestLifecycleComponent( final String role )
      {
          if ( this.requestLifecycleComponents == null )
          {
              return false;
          }
          return this.requestLifecycleComponents.containsKey( role );
      }
  
      /**
       * Do we already have a global request lifecycle component
       */
      boolean containsGlobalRequestLifecycleComponent( final String role )
      {
          return this.getGlobalRequestLifcecycleComponents().containsKey( role 
);
      }
  
      /**
       * Search a RequestLifecycleComponent
       */
      Object getRequestLifecycleComponent( final String role )
      {
          if ( this.requestLifecycleComponents == null )
          {
              return null;
          }
          final Object[] o = (Object[]) this.requestLifecycleComponents.get( 
role );
          if ( null != o )
          {
              return o[0];
          }
          return null;
      }
  
      /**
       * Search a GlobalRequestLifecycleComponent
       */
      Object getGlobalRequestLifecycleComponent( final String role )
      {
          final Object[] o = (Object[]) 
this.getGlobalRequestLifcecycleComponents().get( role );
          if ( null != o )
          {
              return o[0];
          }
          return null;
      }
  
      /**
       * Add an automatically released component
       */
      void addToAutoRelease( final ServiceSelector selector,
                             final Object component,
                             final ServiceManager manager )
      {
          this.autoreleaseComponents.add( new Object[]{component, selector, 
manager} );
      }
  
      /**
       * Add an automatically released component
       */
      void addToAutoRelease( final ServiceManager manager,
                             final Object component )
      {
          this.autoreleaseComponents.add( new Object[]{component, manager} );
      }
  
      /**
       * Remove from automatically released components
       */
      void removeFromAutoRelease( final Object component )
              throws ProcessingException
      {
          int i = 0;
          boolean found = false;
          while ( i < this.autoreleaseComponents.size() && !found )
          {
              final Object[] o = (Object[]) this.autoreleaseComponents.get( i );
              if ( o[0] == component )
              {
                  found = true;
                  if ( o[1] instanceof ServiceManager )
                  {
                      ( (ServiceManager) o[1] ).release( component );
                  }
                  else
                  {
                      ( (ServiceSelector) o[1] ).release( component );
                      if ( o[2] != null )
                      {
                          ( (ServiceManager) o[2] ).release( o[1] );
                      }
                  }
                  this.autoreleaseComponents.remove( i );
              }
              else
              {
                  i++;
              }
          }
          if ( !found )
          {
              throw new ProcessingException( "Unable to remove component from 
automatic release: component not found." );
          }
      }
  }
  
  
  

Reply via email to