Made big changes to typemanager. This should make the regular checks much
faster, and functionfiles should clean up after themselves. Probability of new bugs introduced by this is considerable.
This commit is contained in:
parent
643e7ff12e
commit
81ede81781
8 changed files with 281 additions and 141 deletions
|
@ -6,7 +6,7 @@ package helma.framework.core;
|
|||
import java.util.*;
|
||||
import java.io.*;
|
||||
import helma.framework.*;
|
||||
import helma.objectmodel.IServer;
|
||||
import helma.util.Updatable;
|
||||
import FESI.Data.*;
|
||||
import FESI.Parser.*;
|
||||
import FESI.AST.ASTFormalParameterList;
|
||||
|
@ -24,7 +24,7 @@ import FESI.Exceptions.*;
|
|||
*/
|
||||
|
||||
|
||||
public class Action {
|
||||
public class Action implements Updatable {
|
||||
|
||||
String name;
|
||||
String functionName;
|
||||
|
@ -42,32 +42,40 @@ public class Action {
|
|||
this.app = proto.app;
|
||||
this.name = name;
|
||||
this.file = file;
|
||||
update (file);
|
||||
update ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the type manager whether we need an update. this is the case when
|
||||
* the file has been modified or deleted.
|
||||
*/
|
||||
public boolean needsUpdate () {
|
||||
return lastmod != file.lastModified () || !file.exists ();
|
||||
}
|
||||
|
||||
|
||||
public void update (File f) {
|
||||
public void update () {
|
||||
|
||||
this.file = f;
|
||||
long fmod = file.lastModified ();
|
||||
if (lastmod == fmod)
|
||||
return;
|
||||
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 ();
|
||||
String content = new String (cbuf);
|
||||
update (content);
|
||||
} catch (Exception filex) {
|
||||
app.logEvent ("*** Error reading action file "+file+": "+filex);
|
||||
}
|
||||
|
||||
try {
|
||||
FileReader reader = new FileReader (file);
|
||||
char cbuf[] = new char[(int) file.length ()];
|
||||
reader.read (cbuf);
|
||||
reader.close ();
|
||||
String content = new String (cbuf);
|
||||
update (content);
|
||||
} catch (Exception filex) {
|
||||
app.logEvent ("*** Error reading action file "+file+": "+filex);
|
||||
lastmod = file.lastModified ();
|
||||
}
|
||||
lastmod = fmod;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void update (String content) throws Exception {
|
||||
// app.logEvent ("Reading text template " + name);
|
||||
|
||||
|
@ -87,8 +95,25 @@ public class Action {
|
|||
updateRequestEvaluator (reval);
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remove () {
|
||||
prototype.actions.remove (name);
|
||||
prototype.updatables.remove (file.getName());
|
||||
|
||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||
while (evals.hasNext ()) {
|
||||
try {
|
||||
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||
functionName = name+"_hop_action";
|
||||
ESValue esv = (ESValue) op.getProperty (functionName, functionName.hashCode());
|
||||
if (esv instanceof ConstructedFunctionObject || esv instanceof ThrowException) {
|
||||
op.deleteProperty (functionName, functionName.hashCode());
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return name;
|
||||
|
|
|
@ -465,6 +465,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
|
|||
String logDir = props.getProperty ("logdir");
|
||||
if (logDir == null)
|
||||
logDir = "log";
|
||||
// allow log to be redirected to System.out by setting logdir to "console"
|
||||
if ("console".equalsIgnoreCase (logDir))
|
||||
return new Logger (System.out);
|
||||
try {
|
||||
File helper = new File (logDir);
|
||||
if (home != null && !helper.isAbsolute ())
|
||||
|
|
|
@ -6,8 +6,8 @@ package helma.framework.core;
|
|||
import java.util.*;
|
||||
import java.io.*;
|
||||
import helma.framework.*;
|
||||
import helma.objectmodel.IServer;
|
||||
import FESI.Data.ObjectPrototype;
|
||||
import helma.util.Updatable;
|
||||
import FESI.Data.*;
|
||||
import FESI.Exceptions.EcmaScriptException;
|
||||
import FESI.Interpreter.*;
|
||||
|
||||
|
@ -17,39 +17,52 @@ import FESI.Interpreter.*;
|
|||
*/
|
||||
|
||||
|
||||
public class FunctionFile {
|
||||
public class FunctionFile implements Updatable {
|
||||
|
||||
String name;
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
File file;
|
||||
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 functionNames;
|
||||
|
||||
public FunctionFile (File file, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.app;
|
||||
this.name = name;
|
||||
this.file = file;
|
||||
update (file);
|
||||
update ();
|
||||
}
|
||||
|
||||
|
||||
public void update (File f) {
|
||||
/**
|
||||
* Tell the type manager whether we need an update. this is the case when
|
||||
* the file has been modified or deleted.
|
||||
*/
|
||||
public boolean needsUpdate () {
|
||||
return lastmod != file.lastModified () || !file.exists ();
|
||||
}
|
||||
|
||||
this.file = f;
|
||||
|
||||
long fmod = file.lastModified ();
|
||||
if (lastmod == fmod)
|
||||
return;
|
||||
public void update () {
|
||||
|
||||
lastmod = fmod;
|
||||
// app.typemgr.readFunctionFile (file, prototype.getName ());
|
||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||
while (evals.hasNext ()) {
|
||||
try {
|
||||
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||
updateRequestEvaluator (reval);
|
||||
} catch (Exception ignore) {}
|
||||
if (!file.exists ()) {
|
||||
remove ();
|
||||
|
||||
} else {
|
||||
|
||||
lastmod = file.lastModified ();
|
||||
functionNames = null;
|
||||
// app.typemgr.readFunctionFile (file, prototype.getName ());
|
||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||
while (evals.hasNext ()) {
|
||||
try {
|
||||
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||
updateRequestEvaluator (reval);
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,10 +72,23 @@ public class FunctionFile {
|
|||
EvaluationSource es = new FileEvaluationSource(file.getPath(), null);
|
||||
FileReader fr = null;
|
||||
|
||||
HashMap priorProps = new HashMap ();
|
||||
ObjectPrototype op = null;
|
||||
|
||||
try {
|
||||
op = reval.getPrototype (prototype.getName());
|
||||
|
||||
// remember properties before evaluation, so we can tell what's new afterwards
|
||||
if (functionNames == null) try {
|
||||
for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
|
||||
String prop = (String) en.nextElement ();
|
||||
priorProps.put (prop, op.getProperty (prop, prop.hashCode()));
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
|
||||
fr = new FileReader(file);
|
||||
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||
reval.evaluator.evaluate(fr, op, es, false);
|
||||
|
||||
} catch (IOException e) {
|
||||
app.logEvent ("Error parsing function file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+e);
|
||||
} catch (EcmaScriptException e) {
|
||||
|
@ -73,10 +99,44 @@ public class FunctionFile {
|
|||
fr.close();
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
|
||||
// check
|
||||
if (functionNames == null && op != null) try {
|
||||
functionNames = new HashSet ();
|
||||
for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
|
||||
String prop = (String) en.nextElement ();
|
||||
if (priorProps.get (prop) == null || op.getProperty (prop, prop.hashCode()) != priorProps.get (prop))
|
||||
functionNames.add (prop);
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void remove () {
|
||||
prototype.functions.remove (name);
|
||||
prototype.updatables.remove (file.getName());
|
||||
|
||||
// if we did not add anything to any evaluator, we're done
|
||||
if (functionNames == null)
|
||||
return;
|
||||
|
||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||
while (evals.hasNext ()) {
|
||||
try {
|
||||
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||
for (Iterator it=functionNames.iterator(); it.hasNext(); ) {
|
||||
String fname = (String) it.next ();
|
||||
ESValue esv = op.getProperty (fname, fname.hashCode());
|
||||
if (esv instanceof ConstructedFunctionObject) {
|
||||
op.deleteProperty (fname, fname.hashCode());
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ public class Prototype {
|
|||
String id;
|
||||
String name;
|
||||
Application app;
|
||||
Hashtable templates, functions, actions, skins;
|
||||
HashMap templates, functions, actions, skins, updatables;
|
||||
File codeDir;
|
||||
long lastUpdate;
|
||||
|
||||
|
@ -158,18 +158,18 @@ public class Prototype {
|
|||
} catch (EcmaScriptException ignore) {}
|
||||
}
|
||||
|
||||
for (Enumeration en = functions.elements(); en.hasMoreElements(); ) {
|
||||
FunctionFile ff = (FunctionFile) en.nextElement ();
|
||||
for (Iterator it = functions.values().iterator(); it.hasNext(); ) {
|
||||
FunctionFile ff = (FunctionFile) it.next ();
|
||||
ff.updateRequestEvaluator (reval);
|
||||
}
|
||||
for (Enumeration en = templates.elements(); en.hasMoreElements(); ) {
|
||||
Template tmp = (Template) en.nextElement ();
|
||||
for (Iterator it = templates.values().iterator(); it.hasNext(); ) {
|
||||
Template tmp = (Template) it.next ();
|
||||
try {
|
||||
tmp.updateRequestEvaluator (reval);
|
||||
} catch (EcmaScriptException ignore) {}
|
||||
}
|
||||
for (Enumeration en = actions.elements(); en.hasMoreElements(); ) {
|
||||
Action act = (Action) en.nextElement ();
|
||||
for (Iterator it = actions.values().iterator(); it.hasNext(); ) {
|
||||
Action act = (Action) it.next ();
|
||||
try {
|
||||
act.updateRequestEvaluator (reval);
|
||||
} catch (EcmaScriptException ignore) {}
|
||||
|
|
|
@ -5,7 +5,7 @@ package helma.framework.core;
|
|||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import helma.objectmodel.IServer;
|
||||
import helma.util.Updatable;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@ import helma.objectmodel.IServer;
|
|||
*/
|
||||
|
||||
|
||||
public class SkinFile {
|
||||
public class SkinFile implements Updatable {
|
||||
|
||||
String name;
|
||||
Prototype prototype;
|
||||
|
@ -30,17 +30,26 @@ public class SkinFile {
|
|||
this.skin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the type manager whether we need an update. this is the case when
|
||||
* the file has been modified or deleted.
|
||||
*/
|
||||
public boolean needsUpdate () {
|
||||
return lastmod != file.lastModified () || !file.exists ();
|
||||
}
|
||||
|
||||
public void update (File f) {
|
||||
|
||||
this.file = f;
|
||||
public void update () {
|
||||
|
||||
long fmod = file.lastModified ();
|
||||
// we only update this if we already have read the skin
|
||||
if (skin == null || lastmod == fmod)
|
||||
return;
|
||||
|
||||
read ();
|
||||
if (!file.exists ()) {
|
||||
// remove skin from prototype
|
||||
prototype.skins.remove (name);
|
||||
prototype.updatables.remove (file.getName());
|
||||
} else {
|
||||
// we only need to update if the skin has already been initialized
|
||||
if (skin != null)
|
||||
read ();
|
||||
}
|
||||
}
|
||||
|
||||
private void read () {
|
||||
|
|
|
@ -31,6 +31,7 @@ public class Template extends Action {
|
|||
super (file, name, proto);
|
||||
}
|
||||
|
||||
|
||||
public void update (String content) throws Exception {
|
||||
// IServer.getLogger().log ("Reading text template " + name);
|
||||
|
||||
|
@ -161,7 +162,31 @@ public class Template extends Action {
|
|||
updateRequestEvaluator (reval);
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remove () {
|
||||
prototype.templates.remove (name);
|
||||
prototype.updatables.remove (file.getName());
|
||||
|
||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||
while (evals.hasNext ()) {
|
||||
try {
|
||||
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||
functionName = name;
|
||||
ESValue esv = (ESValue) op.getProperty (functionName, functionName.hashCode());
|
||||
if (esv instanceof ConstructedFunctionObject || esv instanceof ThrowException) {
|
||||
op.deleteProperty (functionName, functionName.hashCode());
|
||||
}
|
||||
String fname = name+"_as_string";
|
||||
esv = (ESValue) op.getProperty (fname, fname.hashCode());
|
||||
if (esv instanceof ConstructedFunctionObject || esv instanceof ThrowException) {
|
||||
op.deleteProperty (fname, fname.hashCode());
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public synchronized void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||
if (pfunc != null)
|
||||
|
|
|
@ -18,7 +18,7 @@ public class TypeManager implements Runnable {
|
|||
|
||||
Application app;
|
||||
File appDir;
|
||||
Hashtable prototypes;
|
||||
HashMap prototypes;
|
||||
Prototype nodeProto;
|
||||
long idleSeconds = 120; // if idle for longer than 5 minutes, slow down
|
||||
boolean rewire;
|
||||
|
@ -53,7 +53,7 @@ public class TypeManager implements Runnable {
|
|||
f = new File (appDir, "hopobject");
|
||||
if (!f.exists())
|
||||
f.mkdir ();
|
||||
prototypes = new Hashtable ();
|
||||
prototypes = new HashMap ();
|
||||
registeredEvaluators = Collections.synchronizedList (new ArrayList (30));
|
||||
nodeProto = null;
|
||||
}
|
||||
|
@ -154,10 +154,11 @@ public class TypeManager implements Runnable {
|
|||
idleSeconds = 0;
|
||||
|
||||
String list[] = dir.list();
|
||||
Hashtable ntemp = new Hashtable ();
|
||||
Hashtable nfunc = new Hashtable ();
|
||||
Hashtable nact = new Hashtable ();
|
||||
Hashtable nskins = new Hashtable ();
|
||||
HashMap ntemp = new HashMap ();
|
||||
HashMap nfunc = new HashMap ();
|
||||
HashMap nact = new HashMap ();
|
||||
HashMap nskins = new HashMap ();
|
||||
HashMap updatables = new HashMap (list.length);
|
||||
|
||||
for (int i=0; i<list.length; i++) {
|
||||
File tmpfile = new File (dir, list[i]);
|
||||
|
@ -171,6 +172,7 @@ public class TypeManager implements Runnable {
|
|||
if (list[i].endsWith (app.templateExtension)) {
|
||||
try {
|
||||
Template t = new Template (tmpfile, tmpname, proto);
|
||||
updatables.put (list[i], t);
|
||||
ntemp.put (tmpname, t);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error creating prototype: "+x);
|
||||
|
@ -179,6 +181,7 @@ public class TypeManager implements Runnable {
|
|||
} else if (list[i].endsWith (app.scriptExtension) && tmpfile.length () > 0) {
|
||||
try {
|
||||
FunctionFile ff = new FunctionFile (tmpfile, tmpname, proto);
|
||||
updatables.put (list[i], ff);
|
||||
nfunc.put (tmpname, ff);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error creating prototype: "+x);
|
||||
|
@ -187,23 +190,29 @@ public class TypeManager implements Runnable {
|
|||
} else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
|
||||
try {
|
||||
Action af = new Action (tmpfile, tmpname, proto);
|
||||
updatables.put (list[i], af);
|
||||
nact.put (tmpname, af);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error creating prototype: "+x);
|
||||
}
|
||||
} else if (list[i].endsWith (app.skinExtension)) {
|
||||
} else if (list[i].endsWith (app.skinExtension)) {
|
||||
try {
|
||||
SkinFile sf = new SkinFile (tmpfile, tmpname, proto);
|
||||
updatables.put (list[i], sf);
|
||||
nskins.put (tmpname, sf);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error creating prototype: "+x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updatables.put ("type.properties", proto.dbmap);
|
||||
|
||||
proto.templates = ntemp;
|
||||
proto.functions = nfunc;
|
||||
proto.actions = nact;
|
||||
proto.skins = nskins;
|
||||
proto.updatables = updatables;
|
||||
|
||||
// init prototype on evaluators that are already initialized.
|
||||
Iterator evals = getRegisteredRequestEvaluators ();
|
||||
|
@ -218,95 +227,100 @@ public class TypeManager implements Runnable {
|
|||
public void updatePrototype (String name, File dir, Prototype proto) {
|
||||
// app.logEvent ("updating prototype "+name);
|
||||
|
||||
String list[] = dir.list();
|
||||
Hashtable ntemp = new Hashtable ();
|
||||
Hashtable nfunc = new Hashtable ();
|
||||
Hashtable nact = new Hashtable ();
|
||||
Hashtable nskins = new Hashtable ();
|
||||
boolean needsUpdate = false;
|
||||
|
||||
// our plan is to do as little as possible, so first check if anything has changed at all...
|
||||
for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
if (upd.needsUpdate ())
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
String list[] = dir.list();
|
||||
for (int i=0; i<list.length; i++) {
|
||||
File tmpfile = new File (dir, list[i]);
|
||||
int dot = list[i].indexOf (".");
|
||||
String fn = list[i];
|
||||
if (!proto.updatables.containsKey (fn)) {
|
||||
if (fn.endsWith (app.templateExtension) || fn.endsWith (app.scriptExtension) ||
|
||||
fn.endsWith (app.actionExtension) || fn.endsWith (app.scriptExtension) || "type.properties".equalsIgnoreCase (fn))
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!needsUpdate)
|
||||
return;
|
||||
|
||||
// let the thread know we had to do something.
|
||||
idleSeconds = 0;
|
||||
|
||||
// first go through new files and create new items
|
||||
for (int i=0; i<list.length; i++) {
|
||||
String fn = list[i];
|
||||
int dot = fn.indexOf (".");
|
||||
|
||||
if (dot < 0)
|
||||
continue;
|
||||
|
||||
if (proto.updatables.containsKey (fn) || !(fn.endsWith (app.templateExtension) || fn.endsWith (app.scriptExtension) ||
|
||||
fn.endsWith (app.actionExtension) || fn.endsWith (app.skinExtension) || "type.properties".equalsIgnoreCase (fn))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String tmpname = list[i].substring(0, dot);
|
||||
File tmpfile = new File (dir, list[i]);
|
||||
|
||||
if (list[i].endsWith (app.templateExtension)) {
|
||||
Template t = proto.getTemplate (tmpname);
|
||||
try {
|
||||
if (t == null) {
|
||||
t = new Template (tmpfile, tmpname, proto);
|
||||
idleSeconds = 0;
|
||||
} else if (t.lastmod != tmpfile.lastModified ()) {
|
||||
t.update (tmpfile);
|
||||
idleSeconds = 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
ntemp.put (tmpname, t);
|
||||
|
||||
} else if (list[i].endsWith (app.scriptExtension) && tmpfile.length () > 0) {
|
||||
FunctionFile ff = proto.getFunctionFile (tmpname);
|
||||
try {
|
||||
if (ff == null) {
|
||||
ff = new FunctionFile (tmpfile, tmpname, proto);
|
||||
idleSeconds = 0;
|
||||
} else if (ff.lastmod != tmpfile.lastModified ()) {
|
||||
ff.update (tmpfile);
|
||||
idleSeconds = 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
nfunc.put (tmpname, ff);
|
||||
|
||||
} else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
|
||||
Action af = proto.getAction (tmpname);
|
||||
} else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
|
||||
try {
|
||||
if (af == null) {
|
||||
af = new Action (tmpfile, tmpname, proto);
|
||||
idleSeconds = 0;
|
||||
} else if (af.lastmod != tmpfile.lastModified ()) {
|
||||
af.update (tmpfile);
|
||||
idleSeconds = 0;
|
||||
}
|
||||
Action af = new Action (tmpfile, tmpname, proto);
|
||||
proto.updatables.put (list[i], af);
|
||||
proto.actions.put (tmpname, af);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
nact.put (tmpname, af);
|
||||
|
||||
} else if (list[i].endsWith (app.skinExtension)) {
|
||||
SkinFile sf = proto.getSkinFile (tmpname);
|
||||
try {
|
||||
if (sf == null) {
|
||||
sf = new SkinFile (tmpfile, tmpname, proto);
|
||||
idleSeconds = 0;
|
||||
} else if (sf.lastmod != tmpfile.lastModified ()) {
|
||||
sf.update (tmpfile);
|
||||
idleSeconds = 0;
|
||||
}
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
}
|
||||
nskins.put (tmpname, sf);
|
||||
|
||||
} else if ("type.properties".equalsIgnoreCase (list[i])) {
|
||||
try {
|
||||
if (proto.dbmap.read ()) {
|
||||
idleSeconds = 0;
|
||||
rewire = true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
app.logEvent ("Error updating db mapping for type "+name+": "+ignore);
|
||||
}
|
||||
}
|
||||
} else if (list[i].endsWith (app.skinExtension)) {
|
||||
SkinFile sf = new SkinFile (tmpfile, tmpname, proto);
|
||||
proto.updatables.put (list[i], sf);
|
||||
proto.skins.put (tmpname, sf);
|
||||
}
|
||||
}
|
||||
proto.templates = ntemp;
|
||||
proto.functions = nfunc;
|
||||
proto.actions = nact;
|
||||
proto.skins = nskins;
|
||||
|
||||
// next go through existing updatables
|
||||
for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
|
||||
if (upd.needsUpdate ()) {
|
||||
if (upd instanceof DbMapping)
|
||||
rewire = true;
|
||||
try {
|
||||
upd.update ();
|
||||
} catch (Exception x) {
|
||||
if (upd instanceof DbMapping)
|
||||
app.logEvent ("Error updating db mapping for type "+name+": "+x);
|
||||
else
|
||||
app.logEvent ("Error updating "+upd+" of prototye type "+name+": "+x);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -314,8 +328,8 @@ public class TypeManager implements Runnable {
|
|||
public void initRequestEvaluator (RequestEvaluator reval) {
|
||||
if (!registeredEvaluators.contains (reval))
|
||||
registeredEvaluators.add (reval);
|
||||
for (Enumeration en = prototypes.elements(); en.hasMoreElements(); ) {
|
||||
Prototype p = (Prototype) en.nextElement ();
|
||||
for (Iterator it = prototypes.values().iterator(); it.hasNext(); ) {
|
||||
Prototype p = (Prototype) it.next ();
|
||||
p.initRequestEvaluator (reval);
|
||||
}
|
||||
reval.initialized = true;
|
||||
|
|
|
@ -5,6 +5,7 @@ package helma.objectmodel;
|
|||
|
||||
import helma.framework.core.Application;
|
||||
import helma.objectmodel.db.WrappedNodeManager;
|
||||
import helma.util.Updatable;
|
||||
import java.util.*;
|
||||
import java.sql.*;
|
||||
import com.workingdogs.village.*;
|
||||
|
@ -15,7 +16,7 @@ import com.workingdogs.village.*;
|
|||
* Database row bindings which are represented by instances of the Relation class.
|
||||
*/
|
||||
|
||||
public class DbMapping {
|
||||
public class DbMapping implements Updatable {
|
||||
|
||||
Application app;
|
||||
String typename;
|
||||
|
@ -77,21 +78,25 @@ public class DbMapping {
|
|||
idField = "id";
|
||||
|
||||
this.props = props;
|
||||
read ();
|
||||
update ();
|
||||
|
||||
app.putDbMapping (typename, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the type manager whether we need update() to be called
|
||||
*/
|
||||
public boolean needsUpdate () {
|
||||
return props.lastModified () != lastTypeChange;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read the mapping from the Properties. Return true if the properties were changed.
|
||||
* The read is split in two, this method and the rewire method. The reason is that in order
|
||||
* for rewire to work, all other db mappings must have been initialized and registered.
|
||||
*/
|
||||
public synchronized boolean read () {
|
||||
|
||||
long lastmod = props.lastModified ();
|
||||
if (lastmod == lastTypeChange)
|
||||
return false;
|
||||
public synchronized void update () {
|
||||
|
||||
this.table = props.getProperty ("_tablename");
|
||||
this.idgen = props.getProperty ("_idgen");
|
||||
|
@ -120,11 +125,10 @@ public class DbMapping {
|
|||
} else
|
||||
parent = null;
|
||||
|
||||
lastTypeChange = lastmod;
|
||||
lastTypeChange = props.lastModified ();
|
||||
// set the cached schema & keydef to null so it's rebuilt the next time around
|
||||
schema = null;
|
||||
keydef = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue