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]