cziegeler    2002/11/20 03:21:50

  Modified:    src/java/org/apache/cocoon Tag: cocoon_2_0_3_branch
                        Cocoon.java
               src/java/org/apache/cocoon/components Tag:
                        cocoon_2_0_3_branch CocoonComponentManager.java
               src/java/org/apache/cocoon/components/source Tag:
                        cocoon_2_0_3_branch SitemapSource.java
               .        Tag: cocoon_2_0_3_branch changes.xml
  Log:
  Fixing bug 12293: RequestLifecycleComponents are not handled properly when the 
cocoon: protocol is used
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.22.2.5  +4 -2      xml-cocoon2/src/java/org/apache/cocoon/Cocoon.java
  
  Index: Cocoon.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/Cocoon.java,v
  retrieving revision 1.22.2.4
  retrieving revision 1.22.2.5
  diff -u -r1.22.2.4 -r1.22.2.5
  --- Cocoon.java       21 Sep 2002 02:34:08 -0000      1.22.2.4
  +++ Cocoon.java       20 Nov 2002 11:21:49 -0000      1.22.2.5
  @@ -568,6 +568,7 @@
               throw new IllegalStateException("You cannot process a Disposed Cocoon 
engine.");
           }
   
  +        Object key = CocoonComponentManager.startProcessing(environment);
           try {
               if (this.getLogger().isDebugEnabled()) {
                   ++activeRequestCount;
  @@ -586,7 +587,8 @@
                   }
               }
           } finally {
  -            if (this.getLogger().isDebugEnabled()) {
  +           CocoonComponentManager.endProcessing(key);
  +           if (this.getLogger().isDebugEnabled()) {
                   --activeRequestCount;
               }
           }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.13.2.4  +254 -40   
xml-cocoon2/src/java/org/apache/cocoon/components/CocoonComponentManager.java
  
  Index: CocoonComponentManager.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/CocoonComponentManager.java,v
  retrieving revision 1.13.2.3
  retrieving revision 1.13.2.4
  diff -u -r1.13.2.3 -r1.13.2.4
  --- CocoonComponentManager.java       4 Aug 2002 04:11:52 -0000       1.13.2.3
  +++ CocoonComponentManager.java       20 Nov 2002 11:21:49 -0000      1.13.2.4
  @@ -51,15 +51,20 @@
   package org.apache.cocoon.components;
   
   import java.io.IOException;
  +import java.util.ArrayList;
   import java.util.HashMap;
   import java.util.Iterator;
  +import java.util.List;
   import java.util.Map;
   import java.util.Stack;
   import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
   import org.apache.avalon.framework.component.Component;
   import org.apache.avalon.framework.component.ComponentException;
   import org.apache.avalon.framework.component.ComponentManager;
  +import org.apache.avalon.framework.component.ComponentSelector;
   import org.apache.avalon.framework.component.Recomposable;
  +import org.apache.avalon.framework.configuration.Configuration;
  +import org.apache.avalon.framework.configuration.DefaultConfiguration;
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.Processor;
   import org.apache.cocoon.environment.Environment;
  @@ -78,6 +83,12 @@
   public final class CocoonComponentManager
   extends ExcaliburComponentManager
   {
  + 
  +    /** The key used to store the current process environment */
  +    private static final String PROCESS_KEY =
  +               "org.apache.cocoon.components.CocoonComponentManager";
  +         
  +    
       /** The environment information */
       private static InheritableThreadLocal environmentStack = new 
InheritableThreadLocal();
   
  @@ -105,9 +116,6 @@
           super(manager);
       }
   
  -    private static final Integer ONE = new Integer(1);
  -    private static final Integer TWO = new Integer(2);
  -
       /**
        * This hook must be called by the sitemap each time a sitemap is entered
        */
  @@ -118,14 +126,13 @@
               environmentStack.set(new Stack());
           }
           final Stack stack = (Stack)environmentStack.get();
  -        if (!stack.empty() ) {
  -            final Object[] objects = (Object[])stack.peek();
  -            if ( objects[1] == objectModel ) {
  -                stack.push(new Object[] {env, objectModel, objects[2], TWO, 
processor});
  -                return;
  -            }
  +        stack.push(new Object[] {env, processor});
  +        
  +        EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  +        if ( null != desc ) {
  +            // this is only for 2.1
  +            // desc.addSitemapConfiguration(processor.getComponentConfigurations());
           }
  -        stack.push(new Object[] {env, objectModel, new HashMap(5), ONE, processor});
       }
   
       /**
  @@ -135,20 +142,40 @@
           final Stack stack = (Stack)environmentStack.get();
           if (null != stack && !stack.empty()) {
               final Object[] objects = (Object[])stack.pop();
  -            if (objects[3] == ONE) {
  -                final Map components = (Map)objects[2];
  -                final Iterator iter = components.values().iterator();
  -                while (iter.hasNext()) {
  -                    final Object[] o = (Object[])iter.next();
  -                    final Component component = (Component)o[0];
  -                    ((CocoonComponentManager)o[1]).releaseRLComponent( component );
  -                }
  +            EnvironmentDescription desc = 
(EnvironmentDescription)((Environment)objects[0]).getObjectModel().get(PROCESS_KEY);
  +            if ( null != desc ) {
  +                // this is only for 2.1
  +                //desc.removeLastSitemapConfiguration();
               }
           }
       }
   
       /**
  -     * Return the current environment object (for the cocoon: protocol)
  +     * 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.
  +     * @return A unique key within this thread.
  +     */
  +    public static Object startProcessing(Environment env) {
  +        EnvironmentDescription desc = new EnvironmentDescription(env);
  +        env.getObjectModel().put(PROCESS_KEY, desc);
  +        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
  +     *         {@link startProcessing(Environment)}.
  +     */
  +    public static void endProcessing(Object key) {
  +        EnvironmentDescription desc = (EnvironmentDescription)key;
  +        desc.release();
  +    }
  +
  +    /**
  +     * Return the current environment (for the cocoon: protocol)
        */
       public static Environment getCurrentEnvironment() {
           final Stack stack = (Stack)environmentStack.get();
  @@ -159,12 +186,12 @@
       }
   
       /**
  -     * Return the current processor object (for the cocoon: protocol)
  +     * Return the current processor (for the cocoon: protocol)
        */
       public static Processor getCurrentProcessor() {
           final Stack stack = (Stack)environmentStack.get();
           if (null != stack && !stack.empty()) {
  -            return (Processor) ((Object[])stack.peek())[4];
  +            return (Processor) ((Object[])stack.peek())[1];
           }
           return null;
       }
  @@ -179,10 +206,10 @@
           final Stack stack = (Stack)environmentStack.get();
           if ( null != stack && !stack.empty()) {
               final Object[] objects = (Object[])stack.peek();
  -            final Map components = (Map)objects[2];
  -            final Object[] o = (Object[])components.get(role);
  -            if ( null != o  ) {
  -                final Component component = (Component) o[0];
  +            final Map objectModel = ((Environment)objects[0]).getObjectModel();
  +            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  +            if ( null != desc ) {
  +                final Component component = desc.getRequestLifecycleComponent(role);
                   if (null != component) {
                       return component;
                   }
  @@ -195,19 +222,23 @@
                   throw new ComponentException("ComponentManager has no Environment 
Stack.");
               }
               final Object[] objects = (Object[]) stack.peek();
  -            final Map components = (Map)objects[2];
  -            // first test if the parent CM has already initialized this component
  -            if (components.containsKey( role ) == false) {
  -                try {
  -                    if (component instanceof Recomposable) {
  -                       ((Recomposable) component).recompose(this);
  +            final Map objectModel = ((Environment)objects[0]).getObjectModel();
  +            EnvironmentDescription desc = 
(EnvironmentDescription)objectModel.get(PROCESS_KEY);
  +            if ( null != desc ) {
  +
  +                // first test if the parent CM has already initialized this 
component
  +                if ( !desc.containsRequestLifecycleComponent( role ) ) {
  +                    try {
  +                        if (component instanceof Recomposable) {
  +                           ((Recomposable) component).recompose(this);
  +                        }
  +                        ((RequestLifecycleComponent) 
component).setup((org.apache.cocoon.environment.SourceResolver)objects[0],
  +                                                              objectModel);
  +                    } catch (Exception local) {
  +                        throw new ComponentException("Exception during setup of 
RequestLifecycleComponent with role '"+role+"'", local);
                       }
  -                    ((RequestLifecycleComponent) 
component).setup((org.apache.cocoon.environment.SourceResolver)objects[0],
  -                                                              (Map)objects[1]);
  -                } catch (Exception local) {
  -                    throw new ComponentException("Exception during setup of 
RequestLifecycleComponent with role '"+role+"'", local);
  +                    desc.addRequestLifecycleComponent(role, component, this);
                   }
  -                components.put(role, new Object[] {component, this});
               }
           }
           return component;
  @@ -229,9 +260,192 @@
       }
   
       /**
  -     * Release a RequestLifecycleComponent
  +     * Add an automatically released component
  +     */
  +    public static void addComponentForAutomaticRelease(final ComponentSelector 
selector,
  +                                                       final Component         
component,
  +                                                       final ComponentManager  
manager)
  +    throws ProcessingException {
  +        final Stack stack = (Stack)environmentStack.get();
  +        if ( null != stack && !stack.empty()) {
  +            final Object[] objects = (Object[])stack.firstElement();
  +            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 ComponentManager 
manager,
  +                                                       final Component        
component)
  +    throws ProcessingException {
  +        final Stack stack = (Stack)environmentStack.get();
  +        if ( null != stack && !stack.empty()) {
  +            final Object[] objects = (Object[])stack.firstElement();
  +            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 Component component)
  +    throws ProcessingException {
  +        final Stack stack = (Stack)environmentStack.get();
  +        if ( null != stack && !stack.empty()) {
  +            final Object[] objects = (Object[])stack.firstElement();
  +            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 EnvironmentDescription {
  +    
  +    private static final Configuration EMPTY_CONFIGURATION = 
  +            new DefaultConfiguration("config", "");
  +    
  +    Environment environment;
  +    Map         objectModel;
  +    Map         requestLifecycleComponents = new HashMap(5);
  +    List        autoreleaseComponents      = new ArrayList(2);
  +    List        sitemapConfigurations      = new ArrayList(4);    
  +    /**
  +     * Constructor
        */
  -    protected void releaseRLComponent( final Component component ) {
  -        super.release( component );
  +    EnvironmentDescription(Environment env) {
  +        this.environment = env;
  +        this.objectModel = env.getObjectModel();
  +    }
  +    
  +    /**
  +     * Release all components of this environment
  +     * All RequestLifecycleComponents and autoreleaseComponents are
  +     * released.
  +     */
  +    void release() {
  +        final Iterator iter = this.requestLifecycleComponents.values().iterator();
  +        while (iter.hasNext()) {
  +            final Object[] o = (Object[])iter.next();
  +            final Component component = (Component)o[0];
  +            ((ComponentManager)o[1]).release( component );
  +        }
  +        
  +        for(int i = 0; i < autoreleaseComponents.size(); i++) {
  +            final Object[] o = (Object[])autoreleaseComponents.get(i);
  +            final Component component = (Component)o[0];
  +            if (o[1] instanceof ComponentManager) {
  +                ((ComponentManager)o[1]).release( component );
  +            } else {
  +                ((ComponentSelector)o[1]).release( component );
  +                if (o[2] != null) {
  +                    ((ComponentManager)o[2]).release( (Component)o[1] );
  +                }
  +            }
  +        }
  +    }
  +  
  +
  +    /**
  +     * Add a RequestLifecycleComponent to the environment
  +     */
  +    void addRequestLifecycleComponent(final String role, 
  +                                      final Component co, 
  +                                      final ComponentManager manager) {
  +        this.requestLifecycleComponents.put(role, new Object[] {co, manager});
  +    }
  +    
  +    boolean containsRequestLifecycleComponent(final String role) {
  +        return this.requestLifecycleComponents.containsKey( role );
  +    }
  +    
  +    /**
  +     * Search a RequestLifecycleComponent
  +     */
  +    Component getRequestLifecycleComponent(final String role) {
  +        final Object[] o = (Object[])this.requestLifecycleComponents.get(role);
  +        if ( null != o ) {
  +            return (Component)o[0];
  +        }
  +        return null;
  +    }
  +
  +    /**
  +     * Add an automatically released component
  +     */
  +    void addToAutoRelease(final ComponentSelector selector,
  +                          final Component         component,
  +                          final ComponentManager  manager) {
  +        this.autoreleaseComponents.add(new Object[] {component, selector, manager});
  +    }
  +
  +    /**
  +     * Add an automatically released component
  +     */
  +    void addToAutoRelease(final ComponentManager manager,
  +                          final Component        component) {
  +        this.autoreleaseComponents.add(new Object[] {component, manager});
  +    }
  +
  +    /**
  +     * Remove from automatically released components
  +     */
  +    void removeFromAutoRelease(final Component 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 ComponentManager) {
  +                    ((ComponentManager)o[1]).release( component );
  +                } else {
  +                    ((ComponentSelector)o[1]).release( component );
  +                    if (o[2] != null) {
  +                        ((ComponentManager)o[2]).release( (Component)o[1] );
  +                    }
  +                }
  +                this.autoreleaseComponents.remove(i);
  +            } else {
  +                i++;
  +            }
  +        }
  +        if (!found) {
  +            throw new ProcessingException("Unable to remove component from 
automatic release: component not found.");
  +        }
  +    }
  +    
  +          
  +    void addSitemapConfiguration(Configuration conf) {
  +        if (conf != null) {
  +             this.sitemapConfigurations.add(conf);
  +        }
       }
  +      
  +    List getSitemapConfigurations() {
  +        return this.sitemapConfigurations;
  +    }
  + 
  +    void removeLastSitemapConfiguration() {
  +        this.sitemapConfigurations.remove(this.sitemapConfigurations.size()-1);
  +    }               
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.9.2.4   +31 -3     
xml-cocoon2/src/java/org/apache/cocoon/components/source/SitemapSource.java
  
  Index: SitemapSource.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/source/SitemapSource.java,v
  retrieving revision 1.9.2.3
  retrieving revision 1.9.2.4
  diff -u -r1.9.2.3 -r1.9.2.4
  --- SitemapSource.java        4 Aug 2002 04:11:52 -0000       1.9.2.3
  +++ SitemapSource.java        20 Nov 2002 11:21:49 -0000      1.9.2.4
  @@ -59,6 +59,8 @@
   import org.apache.cocoon.components.pipeline.CacheableEventPipeline;
   import org.apache.cocoon.components.pipeline.EventPipeline;
   import org.apache.cocoon.components.pipeline.StreamPipeline;
  +import org.apache.cocoon.components.sax.XMLDeserializer;
  +import org.apache.cocoon.components.sax.XMLSerializer;
   import org.apache.cocoon.environment.Environment;
   import org.apache.cocoon.environment.ModifiableSource;
   import org.apache.cocoon.environment.Source;
  @@ -107,6 +109,7 @@
       /** The processor */
       private Processor processor;
   
  +    /** The pipeline processor */
       private Processor pipelineProcessor;
   
       /** The environment */
  @@ -130,6 +133,9 @@
       /** Do I need a refresh ? */
       private boolean needsRefresh;
   
  +    /** The unique key for this processing */
  +    private Object processKey;
  +
       /**
        * Construct a new object
        */
  @@ -237,6 +243,9 @@
           }
   
           try {
  +            CocoonComponentManager.enterEnvironment(this.environment,
  +                                                    
this.environment.getObjectModel(),
  +                                                    this.pipelineProcessor);
               ByteArrayOutputStream os = new ByteArrayOutputStream();
               this.environment.setOutputStream(os);
               this.pipeline.process(this.environment);
  @@ -246,7 +255,8 @@
           } catch (Exception e) {
               throw new ProcessingException("Exception during processing of " + 
this.systemId, e);
           } finally {
  -            // Unhide wrapped environment output stream
  +            CocoonComponentManager.leaveEnvironment();
  +           // Unhide wrapped environment output stream
               this.environment.setOutputStream(null);
               reset();
           }
  @@ -267,6 +277,7 @@
           reset();
           try {
               // initialize the pipelines
  +            this.processKey = 
CocoonComponentManager.startProcessing(this.environment);
               this.eventPipeline = 
(EventPipeline)this.manager.lookup(EventPipeline.ROLE);
               this.pipeline = 
(StreamPipeline)this.manager.lookup(StreamPipeline.ROLE);
   
  @@ -357,15 +368,28 @@
               if (this.redirectSource != null) {
                   this.redirectSource.toSAX(consumer);
               } else {
  +                // We have to buffer the result in order to get
  +                // clean environment stack handling.
  +                XMLSerializer xmls = (XMLSerializer) 
this.manager.lookup(XMLSerializer.ROLE);
  +                Object fragment;
                   try {
                       CocoonComponentManager.enterEnvironment(this.environment,
                                                               
this.environment.getObjectModel(),
                                                               this.pipelineProcessor);
  -                    ((XMLProducer)eventPipeline).setConsumer(consumer);
  +                    ((XMLProducer)eventPipeline).setConsumer(xmls);
                       eventPipeline.process(this.environment);
  +                    fragment = xmls.getSAXFragment();
                   } finally {
  +                    this.manager.release(xmls);
                       CocoonComponentManager.leaveEnvironment();
                   }
  +                XMLDeserializer xmld = (XMLDeserializer) 
this.manager.lookup(XMLDeserializer.ROLE);
  +                try {
  +                    xmld.setConsumer(consumer);
  +                    xmld.deserialize(fragment);
  +                } finally {
  +                    this.manager.release(xmld);
  +                }
               }
           } catch (ComponentException cme) {
               throw new ProcessingException("Could not lookup pipeline components", 
cme);
  @@ -383,6 +407,10 @@
       private void reset() {
           if (this.eventPipeline != null) this.manager.release(this.eventPipeline);
           if (this.pipeline != null) this.manager.release(this.pipeline);
  +        if (this.processKey != null) {
  +            CocoonComponentManager.endProcessing(this.processKey);
  +            this.processKey = null;
  +        }
           this.eventPipeline = null;
           this.pipeline = null;
           this.lastModificationDate = 0;
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.138.2.69 +4 -1      xml-cocoon2/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/changes.xml,v
  retrieving revision 1.138.2.68
  retrieving revision 1.138.2.69
  diff -u -r1.138.2.68 -r1.138.2.69
  --- changes.xml       17 Nov 2002 19:01:39 -0000      1.138.2.68
  +++ changes.xml       20 Nov 2002 11:21:50 -0000      1.138.2.69
  @@ -39,6 +39,9 @@
    </devs>
   
    <release version="@version@" date="@date@">
  +  <action dev="CZ" type="fix" fixes-bug="12293">
  +   RequestLifecycleComponents were not handled properly when the cocoon: protocol 
is used
  +  </action>
     <action dev="CH" type="update">
      Changed SimpleFormTransformer to use InputModules.
     </action>  
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to