From a1080de97862d4defad98247e4f451cb4efcbca8 Mon Sep 17 00:00:00 2001 From: hns Date: Fri, 2 Aug 2002 13:32:56 +0000 Subject: [PATCH] Get prototype resources through synchronized methods instead of directly accessing them. This fixes a bug where prototypes that were in the process of being compiled were accessed by evaluators. Pass through RedirectException if notModified() has been called on the response object. --- src/helma/framework/core/Prototype.java | 67 +++++++++++++++++++-- src/helma/scripting/ActionFile.java | 4 +- src/helma/scripting/FunctionFile.java | 4 +- src/helma/scripting/Template.java | 4 +- src/helma/scripting/fesi/FesiEvaluator.java | 29 ++++++--- 5 files changed, 90 insertions(+), 18 deletions(-) diff --git a/src/helma/framework/core/Prototype.java b/src/helma/framework/core/Prototype.java index 37f2e5d3..ec5f259a 100644 --- a/src/helma/framework/core/Prototype.java +++ b/src/helma/framework/core/Prototype.java @@ -3,6 +3,7 @@ package helma.framework.core; +import java.util.Map; import java.util.HashMap; import java.util.Iterator; import java.io.*; @@ -25,11 +26,11 @@ public final class Prototype { final String name; final Application app; - public final HashMap templates; - public final HashMap functions; - public final HashMap actions; - public final HashMap skins; - public final HashMap updatables; + final HashMap templates; + final HashMap functions; + final HashMap actions; + final HashMap skins; + final HashMap updatables; // lastCheck is the time the prototype's files were last checked private long lastCheck; @@ -180,7 +181,63 @@ public final class Prototype { public void markChecked () { lastCheck = System.currentTimeMillis (); } + + /** + * Return a clone of this prototype's actions container. Synchronized + * to not return a map in a transient state where it is just being + * updated by the type manager. + */ + public synchronized Map getActions () { + return (Map) actions.clone(); + } + /** + * Return a clone of this prototype's functions container. Synchronized + * to not return a map in a transient state where it is just being + * updated by the type manager. + */ + public synchronized Map getFunctions () { + return (Map) functions.clone(); + } + + /** + * Return a clone of this prototype's templates container. Synchronized + * to not return a map in a transient state where it is just being + * updated by the type manager. + */ + public synchronized Map getTemplates () { + return (Map) templates.clone(); + } + + /** + * Return a clone of this prototype's skins container. Synchronized + * to not return a map in a transient state where it is just being + * updated by the type manager. + */ + public synchronized Map getSkins () { + return (Map) skins.clone(); + } + + public synchronized void removeUpdatable (String fileName) { + updatables.remove (fileName); + } + + public synchronized void removeAction (String actionName) { + actions.remove (actionName); + } + + public synchronized void removeFunctionFile (String functionFileName) { + functions.remove (functionFileName); + } + + public synchronized void removeTemplate (String templateName) { + templates.remove (templateName); + } + + + /** + * Return a string representing this prototype. + */ public String toString () { return "[Prototype "+ app.getName()+"/"+name+"]"; } diff --git a/src/helma/scripting/ActionFile.java b/src/helma/scripting/ActionFile.java index 4bceaf60..8c767414 100644 --- a/src/helma/scripting/ActionFile.java +++ b/src/helma/scripting/ActionFile.java @@ -94,9 +94,9 @@ public class ActionFile implements Updatable { } protected void remove () { - prototype.actions.remove (name); + prototype.removeAction (name); if (file != null) - prototype.updatables.remove (file.getName()); + prototype.removeUpdatable (file.getName()); } public String getName () { diff --git a/src/helma/scripting/FunctionFile.java b/src/helma/scripting/FunctionFile.java index 85076c18..79d8c44e 100644 --- a/src/helma/scripting/FunctionFile.java +++ b/src/helma/scripting/FunctionFile.java @@ -98,8 +98,8 @@ public class FunctionFile implements Updatable { void remove () { - prototype.functions.remove (name); - prototype.updatables.remove (file.getName()); + prototype.removeFunctionFile (name); + prototype.removeUpdatable (file.getName()); // if we did not add anything to any evaluator, we're done /* if (declaredProps == null || declaredProps.size() == 0) diff --git a/src/helma/scripting/Template.java b/src/helma/scripting/Template.java index d996f9c9..b4b82443 100644 --- a/src/helma/scripting/Template.java +++ b/src/helma/scripting/Template.java @@ -176,9 +176,9 @@ public class Template extends ActionFile { } protected void remove () { - prototype.templates.remove (name); + prototype.removeTemplate (name); if (file != null) - prototype.updatables.remove (file.getName()); + prototype.removeUpdatable (file.getName()); /* Iterator evals = app.typemgr.getRegisteredRequestEvaluators (); while (evals.hasNext ()) { diff --git a/src/helma/scripting/fesi/FesiEvaluator.java b/src/helma/scripting/fesi/FesiEvaluator.java index 58c0c664..4da1e51d 100644 --- a/src/helma/scripting/fesi/FesiEvaluator.java +++ b/src/helma/scripting/fesi/FesiEvaluator.java @@ -24,7 +24,6 @@ import Acme.LruHashtable; /** * This is the implementation of ScriptingEnvironment for the FESI EcmaScript interpreter. */ - public final class FesiEvaluator implements ScriptingEngine { // the application we're running in @@ -32,7 +31,7 @@ public final class FesiEvaluator implements ScriptingEngine { // The FESI evaluator final Evaluator evaluator; - + // the global object final GlobalObject global; @@ -44,7 +43,7 @@ public final class FesiEvaluator implements ScriptingEngine { // the request evaluator instance owning this fesi evaluator final RequestEvaluator reval; - + // extensions loaded by this evaluator static String[] extensions = new String[] { "FESI.Extensions.BasicIO", @@ -63,6 +62,9 @@ public final class FesiEvaluator implements ScriptingEngine { // the global vars set by extensions HashMap extensionGlobals; + /** + * Create a FESI evaluator for the given application and request evaluator. + */ public FesiEvaluator (Application app, RequestEvaluator reval) { this.app = app; this.reval = reval; @@ -81,7 +83,7 @@ public final class FesiEvaluator implements ScriptingEngine { Database dbx = (Database) evaluator.addExtension ("helma.scripting.fesi.extensions.Database"); dbx.setApplication (app); // load extensions defined in server.properties: - extensionGlobals = new HashMap (); + extensionGlobals = new HashMap (); Vector extVec = Server.getServer ().getExtensions (); for (int i=0; i