Add experimental definePrototype() function.

This commit is contained in:
hns 2009-03-31 20:20:13 +00:00
parent 3d882de822
commit 196bf97053
4 changed files with 57 additions and 7 deletions

View file

@ -984,6 +984,23 @@ public final class Application implements Runnable {
return typemgr.getPrototypes();
}
/**
* Programmatically define a new prototype. If a prototype with this name already exists return
* the existing prototype.
* @param name the prototype name
* @param typeProps custom type properties map
* @return the new prototype
*/
public Prototype definePrototype(String name, Map typeProps) {
Prototype proto = typemgr.getPrototype(name);
if (proto == null) {
proto = typemgr.createPrototype(name, null, typeProps);
} else {
proto.setTypeProperties(typeProps);
}
return proto;
}
/**
* Return a skin for a given object. The skin is found by determining the prototype
* to use for the object, then looking up the skin for the prototype.

View file

@ -74,8 +74,9 @@ public final class Prototype {
* @param name the prototype's name
* @param repository the first prototype's repository
* @param app the application this prototype is a part of
* @param typeProps custom type mapping properties
*/
public Prototype(String name, Repository repository, Application app) {
public Prototype(String name, Repository repository, Application app, Map typeProps) {
// app.logEvent ("Constructing Prototype "+app.getName()+"/"+name);
this.app = app;
this.name = name;
@ -87,10 +88,13 @@ public final class Prototype {
// Create and register type properties file
props = new ResourceProperties(app);
if (repository != null) {
if (typeProps != null) {
props.putAll(typeProps);
} else if (repository != null) {
props.addResource(repository.getResource("type.properties"));
props.addResource(repository.getResource(name + ".properties"));
}
dbmap = new DbMapping(app, name, props);
// we don't need to put the DbMapping into proto.updatables, because
// dbmappings are checked separately in TypeManager.checkFiles() for
@ -392,6 +396,16 @@ public final class Prototype {
lastCodeUpdate = System.currentTimeMillis();
}
/**
* Set the custom type properties for this prototype and update the database mapping.
* @param map the custom type mapping properties.
*/
public void setTypeProperties(Map map) {
props.clear();
props.putAll(map);
dbmap.update();
}
/**
* Get the prototype's aggregated type.properties
*

View file

@ -104,7 +104,7 @@ public final class TypeManager {
public synchronized void createPrototypes() throws IOException {
// create standard prototypes.
for (int i = 0; i < standardTypes.length; i++) {
createPrototype(standardTypes[i], null);
createPrototype(standardTypes[i], null, null);
}
// loop through directories and create prototypes
@ -154,7 +154,7 @@ public final class TypeManager {
if (proto == null) {
// create new prototype if type name is valid
if (isValidTypeName(name))
createPrototype(name, list[i]);
createPrototype(name, list[i], null);
} else {
proto.addRepository(list[i], update);
}
@ -294,14 +294,15 @@ public final class TypeManager {
*
* @param typename the name of the prototype
* @param repository the first prototype source
* @param typeProps custom type mapping properties
* @return the newly created prototype
*/
public synchronized Prototype createPrototype(String typename, Repository repository) {
public synchronized Prototype createPrototype(String typename, Repository repository, Map typeProps) {
if ("true".equalsIgnoreCase(app.getProperty("helma.debugTypeManager"))) {
System.err.println("CREATE: " + typename + " from " + repository + " in " + Thread.currentThread());
// Thread.dumpStack();
}
Prototype proto = new Prototype(typename, repository, app);
Prototype proto = new Prototype(typename, repository, app, typeProps);
// put the prototype into our map
prototypes.put(proto.getLowerCaseName(), proto);
return proto;

View file

@ -73,7 +73,7 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
"getXmlDocument", "getHtmlDocument", "seal",
"getDBConnection", "getURL", "write", "writeln",
"serialize", "deserialize", "defineLibraryScope",
"wrapJavaMap", "unwrapJavaMap", "toJava"
"wrapJavaMap", "unwrapJavaMap", "toJava", "definePrototype"
};
defineFunctionProperties(globalFuncs, GlobalObject.class, DONTENUM | PERMANENT);
@ -673,6 +673,24 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
return null;
}
public Object definePrototype(String name, Scriptable desc) {
if (name == null) {
throw new IllegalArgumentException("First argument to definePrototype() must be String");
}
if (desc == null) {
throw new IllegalArgumentException("Second argument to definePrototype() must be Object");
}
Prototype proto = core.app.definePrototype(name, core.scriptableToProperties(desc));
RhinoCore.TypeInfo type = (RhinoCore.TypeInfo) core.prototypes.get(proto.getLowerCaseName());
if (type == null) {
type = core.initPrototype(proto);
}
core.setParentPrototype(proto, type);
return type.objProto;
}
private static String toString(Object obj) {
if (obj == null || obj == Undefined.instance) {
// Note: we might return "" here in order