Pretty much reworked all the Helma type management code.
This commit is contained in:
parent
ea5edf51c9
commit
7463553a95
11 changed files with 360 additions and 360 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 ("<b>Error in application '"+app.getName()+"':</b> <br><br><pre>"+error+"</pre>");
|
||||
|
|
|
@ -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) };
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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<list.length; i++) {
|
||||
String fn = list[i];
|
||||
if (!proto.updatables.containsKey (fn)) {
|
||||
if (fn.endsWith (templateExtension) || fn.endsWith (scriptExtension) ||
|
||||
fn.endsWith (actionExtension) || fn.endsWith (skinExtension) ||
|
||||
"type.properties".equalsIgnoreCase (fn)) {
|
||||
needsUpdate = true;
|
||||
// updatables.add ("[new:"+proto.getName()+"/"+fn+"]");
|
||||
// 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<list.length; i++) {
|
||||
String fn = list[i];
|
||||
if (!proto.updatables.containsKey (fn)) {
|
||||
if (fn.endsWith (templateExtension) ||
|
||||
fn.endsWith (scriptExtension) ||
|
||||
fn.endsWith (actionExtension) ||
|
||||
fn.endsWith (skinExtension) ||
|
||||
"type.properties".equalsIgnoreCase (fn))
|
||||
{
|
||||
if (createSet == null)
|
||||
createSet = new HashSet ();
|
||||
createSet.add (list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if nothing needs to be updated, mark prototype as checked and return
|
||||
if (!needsUpdate) {
|
||||
// if nothing needs to be updated, mark prototype as checked and return
|
||||
if (updateSet == null && createSet == null) {
|
||||
proto.markChecked ();
|
||||
return;
|
||||
}
|
||||
|
||||
// first go through new files and create new items
|
||||
if (createSet != null) {
|
||||
Object[] newFiles = createSet.toArray ();
|
||||
for (int i=0; i<newFiles.length; i++) {
|
||||
String filename = (String) newFiles[i];
|
||||
int dot = filename.lastIndexOf (".");
|
||||
String tmpname = filename.substring(0, dot);
|
||||
File tmpfile = new File (dir, filename);
|
||||
|
||||
if (filename.endsWith (templateExtension)) {
|
||||
try {
|
||||
Template t = new Template (tmpfile, tmpname, proto);
|
||||
proto.addTemplate (t);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
} else if (filename.endsWith (scriptExtension)) {
|
||||
try {
|
||||
FunctionFile ff = new FunctionFile (tmpfile, proto);
|
||||
proto.addFunctionFile (ff);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
} else if (filename.endsWith (actionExtension)) {
|
||||
try {
|
||||
ActionFile af = new ActionFile (tmpfile, tmpname, proto);
|
||||
proto.addActionFile (af);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
} else if (filename.endsWith (skinExtension)) {
|
||||
SkinFile sf = new SkinFile (tmpfile, tmpname, proto);
|
||||
proto.addSkinFile (sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// next go through existing updatables
|
||||
if (updateSet != null) {
|
||||
for (Iterator i = updateSet.iterator(); i.hasNext(); ) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
try {
|
||||
upd.update ();
|
||||
} catch (Exception x) {
|
||||
if (upd instanceof DbMapping)
|
||||
app.logEvent ("Error updating db mapping for type "+proto.getName()+": "+x);
|
||||
else
|
||||
app.logEvent ("Error updating "+upd+" of prototye type "+proto.getName()+": "+x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mark prototype as checked and updated.
|
||||
proto.markChecked ();
|
||||
return;
|
||||
}
|
||||
|
||||
// app.logEvent ("TypeManager: Updating prototypes for "+app.getName()+": "+updatables);
|
||||
|
||||
// first go through new files and create new items
|
||||
String[] list = dir.list ();
|
||||
for (int i=0; i<list.length; i++) {
|
||||
String fn = list[i];
|
||||
int dot = fn.lastIndexOf (".");
|
||||
|
||||
if (dot < 0)
|
||||
continue;
|
||||
|
||||
if (proto.updatables.containsKey (fn) || !(fn.endsWith (templateExtension) || fn.endsWith (scriptExtension) ||
|
||||
fn.endsWith (actionExtension) || fn.endsWith (skinExtension) || "type.properties".equalsIgnoreCase (fn))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String tmpname = list[i].substring(0, dot);
|
||||
File tmpfile = new File (dir, list[i]);
|
||||
|
||||
if (list[i].endsWith (templateExtension)) {
|
||||
try {
|
||||
Template t = new Template (tmpfile, tmpname, proto);
|
||||
proto.updatables.put (list[i], t);
|
||||
proto.templates.put (tmpname, t);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
|
||||
} else if (list[i].endsWith (scriptExtension)) {
|
||||
try {
|
||||
FunctionFile ff = new FunctionFile (tmpfile, tmpname, proto);
|
||||
proto.updatables.put (list[i], ff);
|
||||
proto.functions.put (tmpname, ff);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
|
||||
} else if (list[i].endsWith (actionExtension)) {
|
||||
try {
|
||||
ActionFile af = new ActionFile (tmpfile, tmpname, proto);
|
||||
proto.updatables.put (list[i], af);
|
||||
proto.actions.put (tmpname, af);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
|
||||
} else if (list[i].endsWith (skinExtension)) {
|
||||
SkinFile sf = new SkinFile (tmpfile, tmpname, proto);
|
||||
proto.updatables.put (list[i], sf);
|
||||
proto.skins.put (tmpname, sf);
|
||||
}
|
||||
}
|
||||
|
||||
// next go through existing updatables
|
||||
if (updatables != null) {
|
||||
for (Iterator i = updatables.iterator(); i.hasNext(); ) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
|
||||
try {
|
||||
upd.update ();
|
||||
} catch (Exception x) {
|
||||
if (upd instanceof DbMapping)
|
||||
app.logEvent ("Error updating db mapping for type "+proto.getName()+": "+x);
|
||||
else
|
||||
app.logEvent ("Error updating "+upd+" of prototye type "+proto.getName()+": "+x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mark prototype as checked and updated.
|
||||
proto.markChecked ();
|
||||
proto.markUpdated();
|
||||
proto.markUpdated();
|
||||
|
||||
} // end of synchronized (proto)
|
||||
|
||||
|
|
|
@ -72,20 +72,22 @@ public class ZippedAppFile implements Updatable {
|
|||
}
|
||||
if (fname.endsWith (".hac")) {
|
||||
String name = fname.substring (0, fname.lastIndexOf ("."));
|
||||
String sourceName = file.getName()+"/"+ename;
|
||||
String content = getZipEntryContent (zip, entry);
|
||||
// System.err.println ("["+content+"]");
|
||||
ActionFile act = new ActionFile (content, name, proto);
|
||||
proto.actions.put (name, act);
|
||||
ActionFile act = new ActionFile (content, name, sourceName, proto);
|
||||
proto.addActionFile (act);
|
||||
updatables.add (act);
|
||||
// mark prototype as updated
|
||||
proto.markUpdated ();
|
||||
}
|
||||
else if (fname.endsWith (".hsp")) {
|
||||
String name = fname.substring (0, fname.lastIndexOf ("."));
|
||||
String sourceName = file.getName()+"/"+ename;
|
||||
String content = getZipEntryContent (zip, entry);
|
||||
// System.err.println ("["+content+"]");
|
||||
Template tmp = new Template (content, name, proto);
|
||||
proto.templates.put (name, tmp);
|
||||
Template tmp = new Template (content, name, sourceName, proto);
|
||||
proto.addTemplate (tmp);
|
||||
updatables.add (tmp);
|
||||
// mark prototype as updated
|
||||
proto.markUpdated ();
|
||||
|
@ -95,21 +97,20 @@ public class ZippedAppFile implements Updatable {
|
|||
String content = getZipEntryContent (zip, entry);
|
||||
// System.err.println ("["+content+"]");
|
||||
SkinFile skin = new SkinFile (content, name, proto);
|
||||
proto.skins.put (name, skin);
|
||||
proto.addSkinFile (skin);
|
||||
updatables.add (skin);
|
||||
}
|
||||
else if (fname.endsWith (".js")) {
|
||||
String name = fname.substring (0, fname.lastIndexOf ("."));
|
||||
String sourceName = file.getName()+"/"+ename;
|
||||
String content = getZipEntryContent (zip, entry);
|
||||
// System.err.println ("["+content+"]");
|
||||
FunctionFile ff = new FunctionFile (content, name, proto);
|
||||
proto.functions.put (name, ff);
|
||||
FunctionFile ff = new FunctionFile (content, sourceName, proto);
|
||||
proto.addFunctionFile (ff);
|
||||
updatables.add (ff);
|
||||
// mark prototype as updated
|
||||
proto.markUpdated ();
|
||||
}
|
||||
else if ("type.properties".equalsIgnoreCase (fname)) {
|
||||
String name = fname.substring (0, fname.lastIndexOf ("."));
|
||||
DbMapping dbmap = proto.getDbMapping ();
|
||||
SystemProperties props = dbmap.getProperties ();
|
||||
props.addProps (file.getName(), zip.getInputStream (entry));
|
||||
|
|
|
@ -21,8 +21,7 @@ import helma.util.Updatable;
|
|||
|
||||
public class ActionFile implements Updatable {
|
||||
|
||||
String name;
|
||||
String functionName;
|
||||
String name, sourceName;
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
File file;
|
||||
|
@ -34,36 +33,21 @@ public class ActionFile implements Updatable {
|
|||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.name = name;
|
||||
functionName = getName()+"_action";
|
||||
this.sourceName = file.getParentFile().getName()+"/"+file.getName();
|
||||
this.file = file;
|
||||
this.content = null;
|
||||
if (file != null)
|
||||
update ();
|
||||
}
|
||||
|
||||
public ActionFile (String content, String name, Prototype proto) {
|
||||
public ActionFile (String content, String name, String sourceName, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.name = name;
|
||||
functionName = getName()+"_action";
|
||||
this.sourceName = sourceName;
|
||||
this.file = null;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Abstract method that must be implemented by subclasses to update evaluators with
|
||||
* new content of action file.
|
||||
*/
|
||||
// protected abstract void update (String content) throws Exception;
|
||||
|
||||
/**
|
||||
* Abstract method that must be implemented by subclasses to remove
|
||||
* action from evaluators.
|
||||
*/
|
||||
// protected abstract void remove ();
|
||||
|
||||
|
||||
/**
|
||||
* Tell the type manager whether we need an update. this is the case when
|
||||
* the file has been modified or deleted.
|
||||
|
@ -74,41 +58,58 @@ public class ActionFile implements Updatable {
|
|||
|
||||
|
||||
public void update () {
|
||||
|
||||
if (!file.exists ()) {
|
||||
// remove functions declared by this from all object prototypes
|
||||
remove ();
|
||||
} else {
|
||||
try {
|
||||
FileReader reader = new FileReader (file);
|
||||
char cbuf[] = new char[(int) file.length ()];
|
||||
reader.read (cbuf);
|
||||
reader.close ();
|
||||
content = new String (cbuf);
|
||||
// update (content);
|
||||
} catch (Exception filex) {
|
||||
app.logEvent ("*** Error reading action file "+file+": "+filex);
|
||||
}
|
||||
lastmod = file.lastModified ();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove () {
|
||||
prototype.removeAction (name);
|
||||
if (file != null)
|
||||
prototype.removeUpdatable (file.getName());
|
||||
prototype.removeActionFile (this);
|
||||
}
|
||||
|
||||
public File getFile () {
|
||||
return file;
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSourceName () {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
public Reader getReader () throws FileNotFoundException {
|
||||
if (content != null)
|
||||
return new StringReader (content);
|
||||
else if (file.length() == 0)
|
||||
return new StringReader(";");
|
||||
else
|
||||
return new FileReader (file);
|
||||
}
|
||||
|
||||
public String getContent () {
|
||||
return content;
|
||||
if (content != null)
|
||||
return content;
|
||||
else {
|
||||
try {
|
||||
FileReader reader = new FileReader (file);
|
||||
char cbuf[] = new char[(int) file.length ()];
|
||||
reader.read (cbuf);
|
||||
reader.close ();
|
||||
return new String (cbuf);
|
||||
} catch (Exception filex) {
|
||||
app.logEvent ("Error reading "+this+": "+filex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getFunctionName () {
|
||||
return functionName;
|
||||
return name + "_action";
|
||||
}
|
||||
|
||||
public Prototype getPrototype () {
|
||||
|
@ -120,7 +121,7 @@ public class ActionFile implements Updatable {
|
|||
}
|
||||
|
||||
public String toString () {
|
||||
return "ActionFile["+prototype.getName()+"/"+functionName+"]";
|
||||
return "ActionFile["+sourceName+"]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,22 +20,18 @@ import helma.util.Updatable;
|
|||
|
||||
public class FunctionFile implements Updatable {
|
||||
|
||||
String name;
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
File file;
|
||||
String sourceName;
|
||||
String content;
|
||||
long lastmod;
|
||||
|
||||
// a set of funcion names defined by this file. We keep this to be able to
|
||||
// remove them once the file should get removed
|
||||
HashSet declaredProps;
|
||||
long declaredPropsTimestamp;
|
||||
|
||||
public FunctionFile (File file, String name, Prototype proto) {
|
||||
public FunctionFile (File file, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.name = name;
|
||||
this.sourceName = file.getParentFile().getName()+"/"+file.getName();
|
||||
this.file = file;
|
||||
update ();
|
||||
}
|
||||
|
@ -45,13 +41,12 @@ public class FunctionFile implements Updatable {
|
|||
* files contained in zipped applications. The whole update mechanism is bypassed
|
||||
* by immediately parsing the code.
|
||||
*/
|
||||
public FunctionFile (String body, String name, Prototype proto) {
|
||||
public FunctionFile (String body, String sourceName, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.name = name;
|
||||
this.sourceName = sourceName;
|
||||
this.file = null;
|
||||
this.content = body;
|
||||
update ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,30 +59,15 @@ public class FunctionFile implements Updatable {
|
|||
|
||||
|
||||
public void update () {
|
||||
|
||||
if (file != null) {
|
||||
if (!file.exists ()) {
|
||||
remove ();
|
||||
} else {
|
||||
lastmod = file.lastModified ();
|
||||
// app.typemgr.readFunctionFile (file, prototype.getName ());
|
||||
// app.getScriptingEnvironment().evaluateFile (prototype, file);
|
||||
}
|
||||
} else {
|
||||
// app.getScriptingEnvironment().evaluateString (prototype, content);
|
||||
}
|
||||
}
|
||||
|
||||
/* public void evaluate (ScriptingEnvironment env) {
|
||||
if (file != null)
|
||||
env.evaluateFile (prototype, file);
|
||||
else
|
||||
env.evaluateString (prototype, content);
|
||||
}*/
|
||||
public boolean hasFile () {
|
||||
return file != null;
|
||||
}
|
||||
|
||||
public File getFile () {
|
||||
return file;
|
||||
}
|
||||
|
@ -96,19 +76,17 @@ public class FunctionFile implements Updatable {
|
|||
return content;
|
||||
}
|
||||
|
||||
public String getSourceName () {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
public void remove () {
|
||||
prototype.removeFunctionFile (name);
|
||||
if (file != null)
|
||||
prototype.removeUpdatable (file.getName());
|
||||
prototype.removeFunctionFile (this);
|
||||
}
|
||||
|
||||
|
||||
public String toString () {
|
||||
if (file == null)
|
||||
return "[Zipped script file]";
|
||||
else
|
||||
return prototype.getName()+"/"+file.getName();
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ import java.util.Iterator;
|
|||
import java.util.StringTokenizer;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
// import FESI.Data.*;
|
||||
// import FESI.Exceptions.*;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -26,26 +24,36 @@ import helma.framework.core.*;
|
|||
|
||||
public class Template extends ActionFile {
|
||||
|
||||
String processedContent = null;
|
||||
|
||||
public Template (File file, String name, Prototype proto) {
|
||||
super (file, name, proto);
|
||||
functionName = name;
|
||||
}
|
||||
|
||||
public Template (String content, String name, Prototype proto) {
|
||||
super (content, name, proto);
|
||||
functionName = name;
|
||||
public Template (String content, String name, String sourceName, Prototype proto) {
|
||||
super (content, name, sourceName, proto);
|
||||
}
|
||||
|
||||
|
||||
public String getFunctionName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Reader getReader () {
|
||||
return new StringReader(getContent());
|
||||
}
|
||||
|
||||
public String getContent () {
|
||||
|
||||
if (processedContent != null)
|
||||
return processedContent;
|
||||
|
||||
Vector partBuffer = new Vector ();
|
||||
int l = content.length ();
|
||||
String cstring = super.getContent();
|
||||
char[] cnt = cstring.toCharArray ();
|
||||
int l = cnt.length;
|
||||
if (l == 0)
|
||||
return "";
|
||||
char cnt[] = new char[l];
|
||||
content.getChars (0, l, cnt, 0);
|
||||
|
||||
// if last charackter is whitespace, swallow it. this is necessary for some inner templates to look ok.
|
||||
if (Character.isWhitespace (cnt[l-1]))
|
||||
|
@ -141,14 +149,12 @@ public class Template extends ActionFile {
|
|||
}
|
||||
// templateBody.append ("\r\nreturn null;\r\n");
|
||||
|
||||
return templateBody.toString ();
|
||||
|
||||
processedContent = templateBody.toString ();
|
||||
return processedContent;
|
||||
}
|
||||
|
||||
public void remove () {
|
||||
prototype.removeTemplate (name);
|
||||
if (file != null)
|
||||
prototype.removeUpdatable (file.getName());
|
||||
prototype.removeTemplate (this);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,30 +29,41 @@ public class FesiActionAdapter {
|
|||
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
String functionName;
|
||||
String sourceName;
|
||||
// this is the parsed function which can be easily applied to RequestEvaluator objects
|
||||
// this is the parsed function which can be easily applied to FesiEvaluator objects
|
||||
TypeUpdater pfunc, pfuncAsString;
|
||||
|
||||
public FesiActionAdapter (ActionFile action) {
|
||||
prototype = action.getPrototype ();
|
||||
app = action.getApplication ();
|
||||
String content = action.getContent ();
|
||||
String functionName = action.getFunctionName ();
|
||||
sourceName = action.toString ();
|
||||
Reader reader = null;
|
||||
functionName = action.getFunctionName ();
|
||||
sourceName = action.getSourceName ();
|
||||
try {
|
||||
reader = action.getReader ();
|
||||
pfunc = parseFunction (functionName,
|
||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||
content);
|
||||
reader,
|
||||
sourceName);
|
||||
} catch (Throwable x) {
|
||||
String message = x.getMessage ();
|
||||
pfunc = new ErrorFeedback (functionName, message);
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
// check if this is a template and we need to generate an "_as_string" variant
|
||||
if (action instanceof Template) {
|
||||
String content = "res.pushStringBuffer(); " +
|
||||
action.getContent () +
|
||||
"\r\nreturn res.popStringBuffer();\r\n";
|
||||
try {
|
||||
pfuncAsString = parseFunction (functionName+"_as_string",
|
||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||
"res.pushStringBuffer(); "+content+"\r\nreturn res.popStringBuffer();\r\n");
|
||||
new StringReader(content),
|
||||
sourceName);
|
||||
} catch (Throwable x) {
|
||||
String message = x.getMessage ();
|
||||
pfunc = new ErrorFeedback (functionName+"_as_string", message);
|
||||
|
@ -70,7 +81,7 @@ public class FesiActionAdapter {
|
|||
pfuncAsString.updateEvaluator (fesi);
|
||||
}
|
||||
|
||||
protected TypeUpdater parseFunction (String funcname, String params, String body) throws EcmaScriptException {
|
||||
protected TypeUpdater parseFunction (String funcName, String params, Reader body, String sourceName) throws EcmaScriptException {
|
||||
|
||||
// ESObject fp = app.eval.evaluator.getFunctionPrototype();
|
||||
// ConstructedFunctionObject function = null;
|
||||
|
@ -78,15 +89,13 @@ public class FesiActionAdapter {
|
|||
ASTStatementList sl = null;
|
||||
FunctionEvaluationSource fes = null;
|
||||
|
||||
if (body == null || "".equals (body.trim()))
|
||||
/* if (body == null || "".equals (body.trim()))
|
||||
body = ";\r\n";
|
||||
else
|
||||
body = body + "\r\n";
|
||||
body = body + "\r\n"; */
|
||||
if (params == null) params = "";
|
||||
else params = params.trim ();
|
||||
|
||||
String fulltext = "function "+funcname+" (" + params + ") {\n" + body + "\n}";
|
||||
|
||||
EcmaScript parser;
|
||||
StringReader is;
|
||||
|
||||
|
@ -100,26 +109,26 @@ public class FesiActionAdapter {
|
|||
fpl = (ASTFormalParameterList) parser.FormalParameterList();
|
||||
is.close();
|
||||
} catch (ParseException x) {
|
||||
throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
|
||||
throw new EcmaScriptParseException (x, new FileEvaluationSource(sourceName, null));
|
||||
}
|
||||
}
|
||||
// this is very very very strange: without the toString, lots of obscure exceptions
|
||||
// deep inside the parser...
|
||||
is = new java.io.StringReader(body.toString ());
|
||||
// is = new java.io.StringReader(body.toString ());
|
||||
try {
|
||||
parser = new EcmaScript (is);
|
||||
parser = new EcmaScript (body);
|
||||
sl = (ASTStatementList) parser.StatementList();
|
||||
is.close();
|
||||
body.close();
|
||||
} catch (ParseException x) {
|
||||
app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x);
|
||||
throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
|
||||
throw new EcmaScriptParseException (x, new FileEvaluationSource(sourceName, null));
|
||||
} catch (Exception x) {
|
||||
app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x);
|
||||
throw new RuntimeException (x.getMessage ());
|
||||
}
|
||||
|
||||
fes = new FunctionEvaluationSource (new StringEvaluationSource(fulltext, null), funcname);
|
||||
return new ParsedFunction (fpl, sl, fes, fulltext, funcname);
|
||||
fes = new FunctionEvaluationSource (new FileEvaluationSource(sourceName, null), funcName);
|
||||
return new ParsedFunction (fpl, sl, fes, null, funcName);
|
||||
}
|
||||
|
||||
class ParsedFunction implements TypeUpdater {
|
||||
|
|
|
@ -112,7 +112,7 @@ public final class FesiEvaluator implements ScriptingEngine {
|
|||
}
|
||||
|
||||
/**
|
||||
* Initialize the evaluator, making sure the minimum type information
|
||||
* Initialize the evaluator, making sure the minimum type information
|
||||
* necessary to bootstrap the rest is parsed.
|
||||
*/
|
||||
private void initialize () {
|
||||
|
@ -127,7 +127,7 @@ public final class FesiEvaluator implements ScriptingEngine {
|
|||
getPrototype ("global");
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Initialize a prototype without fully parsing its script files.
|
||||
*/
|
||||
void initPrototype (Prototype prototype) {
|
||||
|
@ -146,7 +146,10 @@ public final class FesiEvaluator implements ScriptingEngine {
|
|||
}
|
||||
}
|
||||
String name = prototype.getName ();
|
||||
if (!"global".equalsIgnoreCase (name) && !"hopobject".equalsIgnoreCase (name) && opp == null) {
|
||||
if (!"global".equalsIgnoreCase (name) &&
|
||||
!"hopobject".equalsIgnoreCase (name) &&
|
||||
opp == null)
|
||||
{
|
||||
if (app.isJavaPrototype (name))
|
||||
opp = getRawPrototype ("__javaobject__");
|
||||
else
|
||||
|
@ -228,26 +231,13 @@ public final class FesiEvaluator implements ScriptingEngine {
|
|||
global.putHiddenProperty (name, new NodeConstructor (name, fp, this));
|
||||
} catch (EcmaScriptException ignore) {}
|
||||
}
|
||||
for (Iterator it = prototype.getFunctions().values().iterator(); it.hasNext(); ) {
|
||||
FunctionFile ff = (FunctionFile) it.next ();
|
||||
if (ff.hasFile ())
|
||||
evaluateFile (prototype, ff.getFile ());
|
||||
else
|
||||
evaluateString (prototype, ff.getContent ());
|
||||
for (Iterator it = prototype.getZippedCode().values().iterator(); it.hasNext(); ) {
|
||||
Object code = it.next();
|
||||
evaluate (prototype, code);
|
||||
}
|
||||
for (Iterator it = prototype.getTemplates().values().iterator(); it.hasNext(); ) {
|
||||
Template tmp = (Template) it.next ();
|
||||
try {
|
||||
FesiActionAdapter adp = new FesiActionAdapter (tmp);
|
||||
adp.updateEvaluator (this);
|
||||
} catch (EcmaScriptException ignore) {}
|
||||
}
|
||||
for (Iterator it = prototype.getActions().values().iterator(); it.hasNext(); ) {
|
||||
ActionFile act = (ActionFile) it.next ();
|
||||
try {
|
||||
FesiActionAdapter adp = new FesiActionAdapter (act);
|
||||
adp.updateEvaluator (this);
|
||||
} catch (EcmaScriptException ignore) {}
|
||||
for (Iterator it = prototype.getCode().values().iterator(); it.hasNext(); ) {
|
||||
Object code = it.next();
|
||||
evaluate (prototype, code);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -665,6 +655,8 @@ public final class FesiEvaluator implements ScriptingEngine {
|
|||
public ESValue getObjectWrapper (Object e) {
|
||||
if (app.getPrototypeName (e) != null)
|
||||
return getElementWrapper (e);
|
||||
/* else if (e instanceof Map)
|
||||
return new ESMapWrapper (this, (Map) e); */
|
||||
/* else if (e instanceof INode)
|
||||
return new ESNode ((INode) e, this); */
|
||||
else
|
||||
|
@ -762,21 +754,34 @@ public final class FesiEvaluator implements ScriptingEngine {
|
|||
return reval.req;
|
||||
}
|
||||
|
||||
public synchronized void evaluateFile (Prototype prototype, File file) {
|
||||
try {
|
||||
FileReader fr = new FileReader (file);
|
||||
EvaluationSource es = new FileEvaluationSource (file.getPath (), null);
|
||||
updateEvaluator (prototype, fr, es);
|
||||
} catch (IOException iox) {
|
||||
app.logEvent ("Error updating function file: "+iox);
|
||||
private synchronized void evaluate (Prototype prototype, Object code) {
|
||||
if (code instanceof FunctionFile) {
|
||||
FunctionFile funcfile = (FunctionFile) code;
|
||||
File file = funcfile.getFile ();
|
||||
if (file != null) {
|
||||
try {
|
||||
FileReader fr = new FileReader (file);
|
||||
EvaluationSource es = new FileEvaluationSource (funcfile.getSourceName(), null);
|
||||
updateEvaluator (prototype, fr, es);
|
||||
} catch (IOException iox) {
|
||||
app.logEvent ("Error updating function file: "+iox);
|
||||
}
|
||||
} else {
|
||||
StringReader reader = new StringReader (funcfile.getContent());
|
||||
EvaluationSource es = new FileEvaluationSource (funcfile.getSourceName(), null);
|
||||
updateEvaluator (prototype, reader, es);
|
||||
}
|
||||
} else if (code instanceof ActionFile) {
|
||||
ActionFile action = (ActionFile) code;
|
||||
FesiActionAdapter fa = new FesiActionAdapter (action);
|
||||
try {
|
||||
fa.updateEvaluator (this);
|
||||
} catch (EcmaScriptException esx) {
|
||||
app.logEvent ("Error parsing "+action+": "+esx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void evaluateString (Prototype prototype, String code) {
|
||||
StringReader reader = new StringReader (code);
|
||||
StringEvaluationSource es = new StringEvaluationSource (code, null);
|
||||
updateEvaluator (prototype, reader, es);
|
||||
}
|
||||
|
||||
private synchronized void updateEvaluator (Prototype prototype, Reader reader, EvaluationSource source) {
|
||||
try {
|
||||
|
|
Loading…
Add table
Reference in a new issue