diff --git a/src/helma/framework/core/Prototype.java b/src/helma/framework/core/Prototype.java
index 46eade4c..203927e8 100644
--- a/src/helma/framework/core/Prototype.java
+++ b/src/helma/framework/core/Prototype.java
@@ -25,16 +25,14 @@ public final class Prototype {
String name;
Application app;
- HashMap templates;
- HashMap functions;
- HashMap actions;
- HashMap skins;
+ HashMap code, zippedCode;
+ HashMap skins, zippedSkins;
HashMap updatables;
-
- // a map of this prototype's skins as raw strings
+
+ // a map of this prototype's skins as raw strings
// used for exposing skins to application (script) code (via app.skinfiles).
SkinMap skinMap;
-
+
DbMapping dbmap;
// lastCheck is the time the prototype's files were last checked
@@ -54,12 +52,12 @@ public final class Prototype {
this.app = app;
this.name = name;
- templates = new HashMap ();
- functions = new HashMap ();
- actions = new HashMap ();
+ code = new HashMap ();
+ zippedCode = new HashMap ();
skins = new HashMap ();
+ zippedSkins = new HashMap ();
updatables = new HashMap ();
-
+
skinMap = new SkinMap ();
isJavaPrototype = app.isJavaPrototype (name);
@@ -96,35 +94,11 @@ public final class Prototype {
public void setDbMapping (DbMapping dbmap) {
this.dbmap = dbmap;
}
-
+
public DbMapping getDbMapping () {
return dbmap;
}
- /**
- * Get a template defined for this prototype. Templates
- * are files that mix layout and code and were used
- * before skins came along. Think of them as legacy.
- */
- public Template getTemplate (String tmpname) {
- return (Template) templates.get (tmpname);
- }
-
- /**
- * Get a generic function file defined for this prototype.
- */
- public FunctionFile getFunctionFile (String ffname) {
- return (FunctionFile) functions.get (ffname);
- }
-
- /**
- * Get an action file defined for this prototype. Action
- * files are functions with a .hac extension
- * that are accessible publicly via web interface.
- */
- public ActionFile getActionFile (String afname) {
- return (ActionFile) actions.get (afname);
- }
/**
* Get a Skinfile for this prototype. This only works for skins
@@ -132,7 +106,10 @@ public final class Prototype {
* other locations or database stored skins.
*/
public SkinFile getSkinFile (String sfname) {
- return (SkinFile) skins.get (sfname);
+ SkinFile sf = (SkinFile) skins.get (sfname);
+ if (sf == null)
+ sf = (SkinFile) zippedSkins.get (sfname);
+ return sf;
}
/**
@@ -141,7 +118,7 @@ public final class Prototype {
* other locations or database stored skins.
*/
public Skin getSkin (String sfname) {
- SkinFile sf = (SkinFile) skins.get (sfname);
+ SkinFile sf = getSkinFile (sfname);
if (sf != null)
return sf.getSkin ();
else
@@ -153,7 +130,7 @@ public final class Prototype {
return name;
}
- Updatable[] upd = null;
+ /* Updatable[] upd = null;
public Updatable[] getUpdatables () {
if (upd == null) {
upd = new Updatable[updatables.size()];
@@ -163,7 +140,7 @@ public final class Prototype {
}
}
return upd;
- }
+ } */
/**
* Get the last time any script has been re-read for this prototype.
@@ -190,20 +167,20 @@ public final class Prototype {
}
/**
- * Signal that the prototype's scripts have been checked for
+ * Signal that the prototype's scripts have been checked for
* changes.
*/
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();
+ public synchronized Map getCode () {
+ return (Map) code.clone();
}
/**
@@ -211,46 +188,90 @@ public final class Prototype {
* 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();
+ public synchronized Map getZippedCode () {
+ return (Map) zippedCode.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();
+
+ public synchronized void addActionFile (ActionFile action) {
+ File f = action.getFile ();
+ if (f != null) {
+ code.put (action.getSourceName(), action);
+ updatables.put (f.getName(), action);
+ } else {
+ zippedCode.put (action.getSourceName(), action);
+ }
}
- /**
- * 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 addTemplate (Template template) {
+ File f = template.getFile ();
+ if (f != null) {
+ code.put (template.getSourceName(), template);
+ updatables.put (f.getName(), template);
+ } else {
+ zippedCode.put (template.getSourceName(), template);
+ }
}
- public synchronized void removeUpdatable (String fileName) {
- updatables.remove (fileName);
- markUpdated ();
+ public synchronized void addFunctionFile (FunctionFile funcfile) {
+ File f = funcfile.getFile ();
+ if (f != null) {
+ code.put (funcfile.getSourceName(), funcfile);
+ updatables.put (f.getName(), funcfile);
+ } else {
+ zippedCode.put (funcfile.getSourceName(), funcfile);
+ }
}
- public synchronized void removeAction (String actionName) {
- actions.remove (actionName);
- markUpdated ();
+ public synchronized void addSkinFile (SkinFile skinfile) {
+ File f = skinfile.getFile ();
+ if (f != null) {
+ skins.put (skinfile.getName(), skinfile);
+ updatables.put (f.getName(), skinfile);
+ } else {
+ zippedSkins.put (skinfile.getName(), skinfile);
+ }
}
- public synchronized void removeFunctionFile (String functionFileName) {
- functions.remove (functionFileName);
- markUpdated ();
+
+ public synchronized void removeActionFile (ActionFile action) {
+ File f = action.getFile ();
+ if (f != null) {
+ code.remove (action.getSourceName());
+ updatables.remove (f.getName());
+ } else {
+ zippedCode.remove (action.getSourceName());
+ }
}
- public synchronized void removeTemplate (String templateName) {
- templates.remove (templateName);
- markUpdated ();
+ public synchronized void removeFunctionFile (FunctionFile funcfile) {
+ File f = funcfile.getFile ();
+ if (f != null) {
+ code.remove (funcfile.getSourceName());
+ updatables.remove (f.getName());
+ } else {
+ zippedCode.remove (funcfile.getSourceName());
+ }
+ }
+
+ public synchronized void removeTemplate (Template template) {
+ File f = template.getFile ();
+ if (f != null) {
+ code.remove (template.getSourceName());
+ updatables.remove (f.getName());
+ } else {
+ zippedCode.remove (template.getSourceName());
+ }
+ }
+
+ public synchronized void removeSkinFile (SkinFile skinfile) {
+ File f = skinfile.getFile ();
+ if (f != null) {
+ skins.remove (skinfile.getName());
+ updatables.remove (f.getName());
+ } else {
+ zippedSkins.remove (skinfile.getName());
+ }
}
diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java
index a9e4c988..8908a4d7 100644
--- a/src/helma/framework/core/RequestEvaluator.java
+++ b/src/helma/framework/core/RequestEvaluator.java
@@ -108,9 +108,7 @@ public final class RequestEvaluator implements Runnable {
// used for logging
String txname = app.getName()+"/"+req.path;
- // set Timer to get some profiling data
- localrtx.timer.reset ();
- localrtx.timer.beginEvent (requestPath+" init");
+ // begin transaction
localrtx.begin (txname);
String action = null;
@@ -221,15 +219,12 @@ public final class RequestEvaluator implements Runnable {
throw new FrameworkException (notfound.getMessage ());
}
- localrtx.timer.endEvent (txname+" init");
/////////////////////////////////////////////////////////////////////////////
// end of path resolution section
/////////////////////////////////////////////////////////////////////////////
// beginning of execution section
try {
- localrtx.timer.beginEvent (txname+" execute");
-
// enter execution context
scriptingEngine.enterContext (globals);
@@ -255,7 +250,6 @@ public final class RequestEvaluator implements Runnable {
// do the actual action invocation
scriptingEngine.invoke (currentElement, action, new Object[0], false);
- localrtx.timer.endEvent (txname+" execute");
} catch (RedirectException redirect) {
// res.redirect = redirect.getMessage ();
// if there is a message set, save it on the user object for the next request
@@ -296,28 +290,30 @@ public final class RequestEvaluator implements Runnable {
} catch (Exception x) {
- abortTransaction (false);
-
- app.logEvent ("### Exception in "+Thread.currentThread()+": "+x);
- // Dump the profiling data to System.err
- if (app.debug) {
- ((Transactor) Thread.currentThread ()).timer.dump (System.err);
- x.printStackTrace ();
- }
-
// If the transactor thread has been killed by the invoker thread we don't have to
// bother for the error message, just quit.
- if (localrtx != rtx)
+ if (localrtx != rtx) {
+ abortTransaction (false);
break;
+ }
res.reset ();
+ // check if we tried to process the error already
if (error == null) {
+ abortTransaction (false);
app.errorCount += 1;
+ app.logEvent ("Exception in "+Thread.currentThread()+": "+x);
+ // Dump the profiling data to System.err
+ if (app.debug) {
+ x.printStackTrace ();
+ }
// set done to false so that the error will be processed
done = false;
error = x.getMessage ();
if (error == null || error.length() == 0)
error = x.toString ();
+ if (error == null)
+ error = "Unspecified error";
} else {
// error in error action. use traditional minimal error message
res.write ("Error in application '"+app.getName()+"':
"+error+""); diff --git a/src/helma/framework/core/Skin.java b/src/helma/framework/core/Skin.java index 51119c43..27596416 100644 --- a/src/helma/framework/core/Skin.java +++ b/src/helma/framework/core/Skin.java @@ -173,7 +173,6 @@ public final class Skin { this.start = start; this.end = end; - int state = HANDLER; boolean escape = false; char quotechar = '\u0000'; @@ -383,6 +382,8 @@ public final class Skin { // System.err.println ("Getting macro from function"); // pass a clone of the parameter map so if the script changes it, // Map param = ; + // if (parameters == null) + // parameters = new HashMap (); Object[] arguments = { parameters == null ? new HashMap () : new HashMap (parameters) }; diff --git a/src/helma/framework/core/SkinFile.java b/src/helma/framework/core/SkinFile.java index 10652458..0fcd1362 100644 --- a/src/helma/framework/core/SkinFile.java +++ b/src/helma/framework/core/SkinFile.java @@ -24,10 +24,10 @@ public final class SkinFile implements Updatable { public SkinFile (File file, String name, Prototype proto) { this.prototype = proto; - this.app = proto.app; - this.name = name; this.file = file; - this.skin = null; + this.name = name; + app = proto.app; + skin = null; } /** @@ -37,22 +37,22 @@ public final class SkinFile implements Updatable { */ public SkinFile (String body, String name, Prototype proto) { this.prototype = proto; - this.app = proto.app; - this.name = name; - this.file = null; - this.skin = new Skin (body, app); + app = proto.app; + name = name; + file = null; + skin = new Skin (body, app); } /** - * Create a skinfile without that doesn't belong to a prototype, or at + * Create a skinfile that doesn't belong to a prototype, or at * least it doesn't know about its prototype and isn't managed by the prototype. */ public SkinFile (File file, String name, Application app) { - this.prototype = null; this.app = app; - this.name = name; this.file = file; - this.skin = null; + this.name = name; + prototype = null; + skin = null; } @@ -66,7 +66,6 @@ public final class SkinFile implements Updatable { public void update () { - if (!file.exists ()) { // remove skin from prototype remove (); @@ -87,19 +86,20 @@ public final class SkinFile implements Updatable { } catch (IOException x) { app.logEvent ("Error reading Skin "+file+": "+x); } - lastmod = file.lastModified (); } public void remove () { if (prototype != null) { - prototype.skins.remove (name); - if (file != null) - prototype.updatables.remove (file.getName()); + prototype.removeSkinFile (this); } } + public File getFile () { + return file; + } + public Skin getSkin () { if (skin == null) read (); diff --git a/src/helma/framework/core/TypeManager.java b/src/helma/framework/core/TypeManager.java index 9054c821..97fd1102 100644 --- a/src/helma/framework/core/TypeManager.java +++ b/src/helma/framework/core/TypeManager.java @@ -226,127 +226,109 @@ public final class TypeManager { public void updatePrototype (Prototype proto) { if (proto == null) return; - // System.err.println ("UPDATE PROTO: "+app.getName()+"/"+proto.getName()); - // if prototype has been checked in the last second, return - // if (System.currentTimeMillis() - proto.getLastCheck() < 1000) - // return; synchronized (proto) { - // check again because another thread may have checked the - // prototype while we were waiting for access to the synchronized section - if (System.currentTimeMillis() - proto.getLastCheck() < 1000) - return; + // check again because another thread may have checked the + // prototype while we were waiting for access to the synchronized section + if (System.currentTimeMillis() - proto.getLastCheck() < 1000) + return; - File dir = new File (appDir, proto.getName()); - boolean needsUpdate = false; - HashSet updatables = null; + File dir = new File (appDir, proto.getName()); + HashSet updateSet = null; + HashSet createSet = null; - // our plan is to do as little as possible, so first check if - // anything the prototype knows about has changed on disk - for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) { - Updatable upd = (Updatable) i.next(); - if (upd.needsUpdate ()) { - if (updatables == null) - updatables = new HashSet (); - needsUpdate = true; - updatables.add (upd); + // our plan is to do as little as possible, so first check if + // anything the prototype knows about has changed on disk + for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) { + Updatable upd = (Updatable) i.next(); + if (upd.needsUpdate ()) { + if (updateSet == null) + updateSet = new HashSet (); + updateSet.add (upd); + } } - } - // next we check if files have been created or removed since last update - if (proto.getLastCheck() < dir.lastModified ()) { - String[] list = dir.list(); - for (int i=0; i