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