sylvain 2004/07/06 22:56:04
Modified: src/java/org/apache/cocoon/components/flow AbstractInterpreter.java src/java/org/apache/cocoon/components/flow/javascript/fom FOM_JavaScriptInterpreter.java Log: Replace getSitemapPath() by getInterpreterID() to distinguish user value scopes as several sitemaps can be mounted on the same path Revision Changes Path 1.22 +30 -1 cocoon-2.1/src/java/org/apache/cocoon/components/flow/AbstractInterpreter.java Index: AbstractInterpreter.java =================================================================== RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/flow/AbstractInterpreter.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- AbstractInterpreter.java 26 May 2004 01:31:06 -0000 1.21 +++ AbstractInterpreter.java 7 Jul 2004 05:56:04 -0000 1.22 @@ -44,6 +44,12 @@ * reload script files if they get modified (useful when doing * development), and passing the control to Cocoon's sitemap for * result page generation. + * <p> + * Flow intrepreters belonging to different sitemaps should be isolated. To achieve this, + * class implements the [EMAIL PROTECTED] org.apache.avalon.framework.thread.SingleThreaded}. Since + * the sitemap engine looks up the flow intepreter once at sitemap build time, this ensures + * that each sitemap will use a different instance of this class. But that instance will + * handle all flow calls for a given sitemap, and must therefore be thread safe. * * @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a> * @since March 15, 2002 @@ -53,6 +59,12 @@ implements Component, Serviceable, Contextualizable, Interpreter, SingleThreaded, Configurable, Disposable { + // The instance counters, used to produce unique IDs + private static int instanceCounter = 0; + + // The instance ID of this interpreter, used to identify user scopes + private String instanceID; + protected org.apache.avalon.framework.context.Context avalonContext; /** @@ -75,6 +87,23 @@ * through the "check-time" XML attribute in <code>flow.xmap</code>. */ protected long checkTime; + + public AbstractInterpreter() { + synchronized(AbstractInterpreter.class) { + instanceCounter++; + this.instanceID = String.valueOf(instanceCounter); + } + } + + /** + * Get the unique ID for this interpreter, which can be used to distinguish user value scopes + * attached to the session. + * + * @return a unique ID for this interpreter + */ + protected String getInterpreterID() { + return this.instanceID; + } public void configure(Configuration config) throws ConfigurationException { reloadScripts = config.getChild("reload-scripts").getValueAsBoolean(false); 1.31 +3 -12 cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java Index: FOM_JavaScriptInterpreter.java =================================================================== RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- FOM_JavaScriptInterpreter.java 17 May 2004 18:39:58 -0000 1.30 +++ FOM_JavaScriptInterpreter.java 7 Jul 2004 05:56:04 -0000 1.31 @@ -351,7 +351,7 @@ (HashMap)session.getAttribute(USER_GLOBAL_SCOPE); if (userScopes != null) { // Get the scope attached to the current context - scope = (ThreadScope)userScopes.get(getSitemapPath()); + scope = (ThreadScope)userScopes.get(getInterpreterID()); } } if (scope == null) { @@ -388,7 +388,7 @@ } // Attach the scope to the current context - userScopes.put(getSitemapPath(), scope); + userScopes.put(getInterpreterID(), scope); } catch (IllegalStateException e) { // Session might be invalidated already. if (getLogger().isDebugEnabled()) { @@ -396,15 +396,6 @@ } } return scope; - } - - private String getSitemapPath() throws Exception { - Source src = this.sourceresolver.resolveURI("."); - try { - return src.getURI(); - } finally { - this.sourceresolver.release(src); - } } public static class ThreadScope extends ScriptableObject {