Greatly improved type checking performance for large application directories.

Fixed bug 117 (skins not inherited from hopobject proto).
Generally cleaned up things a lot.
This commit is contained in:
hns 2002-09-25 17:38:05 +00:00
parent 131ae0c6a9
commit d09006f985

View file

@ -23,14 +23,20 @@ public final class TypeManager {
HashMap prototypes; HashMap prototypes;
HashMap zipfiles; HashMap zipfiles;
long lastCheck = 0; long lastCheck = 0;
// boolean rewire; long appDirMod = 0;
// the hopobject prototype
Prototype hopobjectProto;
// the global prototype
Prototype globalProto;
final static String[] standardTypes = {"user", "global", "root", "hopobject"}; final static String[] standardTypes = {"user", "global", "root", "hopobject"};
final static String templateExtension = ".hsp"; final static String templateExtension = ".hsp";
final static String scriptExtension = ".js"; final static String scriptExtension = ".js";
final static String actionExtension = ".hac"; final static String actionExtension = ".hac";
final static String skinExtension = ".skin"; final static String skinExtension = ".skin";
public TypeManager (Application app) { public TypeManager (Application app) {
this.app = app; this.app = app;
appDir = app.appDir; appDir = app.appDir;
@ -38,7 +44,7 @@ public final class TypeManager {
if (appDir.list().length == 0) { if (appDir.list().length == 0) {
for (int i=0; i<standardTypes.length; i++) { for (int i=0; i<standardTypes.length; i++) {
File f = new File (appDir, standardTypes[i]); File f = new File (appDir, standardTypes[i]);
if (!f.exists() && !f.mkdir ()) if (!f.exists() && !f.mkdir ())
app.logEvent ("Warning: directory "+f.getAbsolutePath ()+" could not be created."); app.logEvent ("Warning: directory "+f.getAbsolutePath ()+" could not be created.");
else if (!f.isDirectory ()) else if (!f.isDirectory ())
app.logEvent ("Warning: "+f.getAbsolutePath ()+" is not a directory."); app.logEvent ("Warning: "+f.getAbsolutePath ()+" is not a directory.");
@ -54,17 +60,20 @@ public final class TypeManager {
* compile or evaluate any scripts. * compile or evaluate any scripts.
*/ */
public void createPrototypes () { public void createPrototypes () {
// create standard prototypes.
registerPrototype ("root", new File (appDir, "root"),
new Prototype ("root", app));
registerPrototype ("user", new File (appDir, "user"),
new Prototype ("user", app));
// hopobject prototype is special in that we keep a reference
// to it, since we need it regularly when setting parent prototypes.
hopobjectProto = new Prototype ("hopobject", app);
registerPrototype ("hopobject", new File (appDir, "hopobject"), hopobjectProto);
// same with global prototype
globalProto = new Prototype ("global", app);
registerPrototype ("global", new File (appDir, "global"), globalProto);
// loop through directories and create prototypes // loop through directories and create prototypes
checkFiles (); checkFiles ();
// check if standard prototypes have been created
// if not, create them.
for (int i=0; i<standardTypes.length; i++) {
String pname = standardTypes[i];
if (prototypes.get (pname) == null) {
Prototype proto = new Prototype (pname, app);
registerPrototype (pname, new File (appDir, pname), proto);
}
}
} }
@ -86,51 +95,40 @@ public final class TypeManager {
* there are any prototypes to be created. * there are any prototypes to be created.
*/ */
public void checkFiles () { public void checkFiles () {
// long now = System.currentTimeMillis (); // check if any files have been created/removed since last time we
// System.out.print ("checking prototypes for "+app); // checked...
File[] list = appDir.listFiles (); if (appDir.lastModified() > appDirMod) {
if (list == null) appDirMod = appDir.lastModified ();
throw new RuntimeException ("Can't read app directory "+appDir+" - check permissions"); String[] list = appDir.list ();
for (int i=0; i<list.length; i++) { if (list == null)
String filename = list[i].getName (); throw new RuntimeException ("Can't read app directory "+appDir+" - check permissions");
Prototype proto = getPrototype (filename); for (int i=0; i<list.length; i++) {
// if prototype doesn't exist, create it if (list[i].endsWith (".zip")) {
if (proto == null) { ZippedAppFile zipped = (ZippedAppFile) zipfiles.get (list[i]);
// leave out ".." and other directories that contain "."
if (filename.indexOf ('.') < 0 && list[i].isDirectory () && isValidTypeName (filename)) {
// create new prototype
proto = new Prototype (filename, app);
registerPrototype (filename, list[i], proto);
// give logger thread a chance to tell what's going on
// Thread.yield();
} else if (filename.toLowerCase().endsWith (".zip") && !list[i].isDirectory ()) {
ZippedAppFile zipped = (ZippedAppFile) zipfiles.get (filename);
if (zipped == null) { if (zipped == null) {
zipped = new ZippedAppFile (list[i], app); File f = new File (appDir, list[i]);
zipfiles.put (filename, zipped); if (!f.isDirectory ()) {
zipped = new ZippedAppFile (f, app);
zipfiles.put (list[i], zipped);
}
}
continue;
}
if (list[i].indexOf ('.') > -1)
continue;
Prototype proto = getPrototype (list[i]);
// if prototype doesn't exist, create it
if (proto == null && isValidTypeName (list[i])) {
File f = new File (appDir, list[i]);
if (f.isDirectory ()) {
// create new prototype
proto = new Prototype (list[i], app);
registerPrototype (list[i], f, proto);
} }
} }
} }
} }
// loop through prototypes and check if type.properties needs updates
// it's important that we do this _after_ potentially new prototypes
// have been created in the previous loop.
for (Iterator i=prototypes.values().iterator(); i.hasNext(); ) {
Prototype proto = (Prototype) i.next ();
// update prototype's type mapping
DbMapping dbmap = proto.getDbMapping ();
if (dbmap != null && dbmap.needsUpdate ()) {
dbmap.update ();
// set parent prototype, in case it has changed.
String parentName = dbmap.getExtends ();
if (parentName != null)
proto.setParentPrototype (getPrototype (parentName));
else
proto.setParentPrototype (null);
}
}
// loop through zip files to check for updates // loop through zip files to check for updates
for (Iterator it=zipfiles.values ().iterator (); it.hasNext (); ) { for (Iterator it=zipfiles.values ().iterator (); it.hasNext (); ) {
ZippedAppFile zipped = (ZippedAppFile) it.next (); ZippedAppFile zipped = (ZippedAppFile) it.next ();
@ -139,6 +137,26 @@ public final class TypeManager {
} }
} }
// loop through prototypes and check if type.properties needs updates
// it's important that we do this _after_ potentially new prototypes
// have been created in the previous loop.
for (Iterator i=prototypes.values().iterator(); i.hasNext(); ) {
Prototype proto = (Prototype) i.next ();
// update prototype's type mapping
DbMapping dbmap = proto.getDbMapping ();
if (dbmap != null && dbmap.needsUpdate ()) {
dbmap.update ();
if (proto != hopobjectProto && proto != globalProto) {
// set parent prototype, in case it has changed.
String parentName = dbmap.getExtends ();
if (parentName != null)
proto.setParentPrototype (getPrototype (parentName));
else if (!app.isJavaPrototype (proto.getName()))
proto.setParentPrototype (hopobjectProto);
}
}
}
} }
@ -237,7 +255,7 @@ public final class TypeManager {
} }
} }
// next we check if files have been created since last update // next we check if files have been created or removed since last update
if (proto.getLastCheck() < dir.lastModified ()) { if (proto.getLastCheck() < dir.lastModified ()) {
String[] list = dir.list(); String[] list = dir.list();
for (int i=0; i<list.length; i++) { for (int i=0; i<list.length; i++) {