Nodes now know about their prototypes. Until now they were stored as generic properties, which lead to some problems (name clashes etc.)
This commit is contained in:
		
							parent
							
								
									554ec4a3a5
								
							
						
					
					
						commit
						d412a6c5f0
					
				
					 10 changed files with 63 additions and 30 deletions
				
			
		| 
						 | 
				
			
			@ -249,10 +249,10 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    public Prototype getPrototype (INode n) {
 | 
			
		||||
    	IProperty proto = n.get ("prototype", false);
 | 
			
		||||
	if (proto == null)
 | 
			
		||||
    	String protoname = n.getPrototype ();
 | 
			
		||||
	if (protoname == null)
 | 
			
		||||
	    return null;
 | 
			
		||||
	return getPrototype (proto.toString ());
 | 
			
		||||
	return getPrototype (protoname);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -290,7 +290,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
 | 
			
		|||
	    unode = new Node (uname);
 | 
			
		||||
	    unode.setString ("name", uname);
 | 
			
		||||
	    unode.setString ("password", password);
 | 
			
		||||
	    unode.setString ("prototype", "user");
 | 
			
		||||
	    unode.setPrototype ("user");
 | 
			
		||||
	    unode.setDbMapping (userMapping);
 | 
			
		||||
	    users.setNode (uname, unode);
 | 
			
		||||
	    return users.getNode (uname, false);	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,11 +90,11 @@ public class ESNode extends ObjectPrototype {
 | 
			
		|||
    public void setPrototype (String protoName) {
 | 
			
		||||
        checkNode ();
 | 
			
		||||
        this.protoName = protoName;
 | 
			
		||||
        node.setString ("prototype", protoName);
 | 
			
		||||
        node.setPrototype (protoName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getESClassName () {
 | 
			
		||||
        return protoName == null ? "Node" : protoName;
 | 
			
		||||
        return protoName == null ? "HopObject" : protoName;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public String toString () {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,6 +80,7 @@ public class HopExtension {
 | 
			
		|||
 | 
			
		||||
        // methods that give access to properties and global user lists
 | 
			
		||||
        go.putHiddenProperty("Node", node); // register the constructor for a plain Node object.
 | 
			
		||||
        go.putHiddenProperty("HopObject", node); // HopObject is the new name for node.
 | 
			
		||||
        go.putHiddenProperty("getProperty", new GlobalGetProperty ("getProperty", evaluator, fp));
 | 
			
		||||
        go.putHiddenProperty("token", new GlobalGetProperty ("token", evaluator, fp));
 | 
			
		||||
        go.putHiddenProperty("getUser", new GlobalGetUser ("getUser", evaluator, fp, reval));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ public class NodeConstructor extends BuiltinFunctionObject {
 | 
			
		|||
 | 
			
		||||
        public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
			
		||||
           ESNode node = null;
 | 
			
		||||
           if ("Node".equals (typename)) {
 | 
			
		||||
           if ("Node".equals (typename) || "hopobject".equalsIgnoreCase (typename)) {
 | 
			
		||||
               if (arguments.length == 0) {
 | 
			
		||||
                   node = new ESNode (reval.esNodePrototype, this.evaluator, null, reval);
 | 
			
		||||
                   reval.objectcache.put (node.getNode (), node);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -246,8 +246,8 @@ public class RequestEvaluator implements Runnable {
 | 
			
		|||
	                    isProperty = false;
 | 
			
		||||
	                    if (currentNode != null && currentNode.getState() != INode.VIRTUAL) // add to reqPath array
 | 
			
		||||
	                        reqPath.putProperty (reqPath.size(), getNodeWrapper (currentNode));
 | 
			
		||||
	                    // limit path to < 20 tokens
 | 
			
		||||
	                    if (i > 20) throw new RuntimeException ("Path too deep");
 | 
			
		||||
	                    // limit path to < 50 tokens
 | 
			
		||||
	                    if (i > 50) throw new RuntimeException ("Path too deep");
 | 
			
		||||
	                }
 | 
			
		||||
 | 
			
		||||
	                if (currentNode == null)
 | 
			
		||||
| 
						 | 
				
			
			@ -384,8 +384,7 @@ public class RequestEvaluator implements Runnable {
 | 
			
		|||
	        }
 | 
			
		||||
 | 
			
		||||
	        // check XML-RPC access permissions
 | 
			
		||||
	        String proto = current.getProperty ("prototype", "prototype".hashCode ()).toString ();
 | 
			
		||||
	        if (proto != null)
 | 
			
		||||
	        String proto = ((ESNode) current).getNode().getPrototype ();
 | 
			
		||||
	        app.checkXmlRpcAccess (proto, method);
 | 
			
		||||
 | 
			
		||||
	        ESValue esa[] = new ESValue[l];
 | 
			
		||||
| 
						 | 
				
			
			@ -624,7 +623,7 @@ public class RequestEvaluator implements Runnable {
 | 
			
		|||
 | 
			
		||||
        if (esn == null || esn.getNode() != n) {
 | 
			
		||||
            ObjectPrototype op = null;
 | 
			
		||||
            String protoname = n.getString ("prototype", false);
 | 
			
		||||
            String protoname = n.getPrototype ();
 | 
			
		||||
 | 
			
		||||
            // set the DbMapping of the node according to its prototype.
 | 
			
		||||
            // this *should* be done on the objectmodel level, but isn't currently
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ public class User implements Serializable {
 | 
			
		|||
    	this.app = app;
 | 
			
		||||
    	setNode (null);
 | 
			
		||||
	cache = new Node (sid);
 | 
			
		||||
             cache.setString ("prototype", "user");
 | 
			
		||||
             cache.setPrototype ("user");
 | 
			
		||||
	sessionID = sid;
 | 
			
		||||
	onSince = System.currentTimeMillis ();
 | 
			
		||||
	lastTouched = onSince;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,9 +44,10 @@ public interface INode {
 | 
			
		|||
    public long lastModified ();
 | 
			
		||||
    public long created ();
 | 
			
		||||
    public boolean isAnonymous (); // is this a named node, or an anonymous node in a collection?
 | 
			
		||||
    // public void setPrototype (String prototype);
 | 
			
		||||
    // public String getPrototype ();
 | 
			
		||||
    public String getPrototype ();
 | 
			
		||||
    public void setPrototype (String prototype);
 | 
			
		||||
    public INode getCacheNode ();
 | 
			
		||||
    public void setCacheNode (INode cache);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *  node-related methods
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,8 @@ public class Node implements INode, Serializable {
 | 
			
		|||
    protected Vector links;   // links to this node
 | 
			
		||||
    protected Vector proplinks;  // nodes using this node as property
 | 
			
		||||
 | 
			
		||||
    protected String prototype;
 | 
			
		||||
 | 
			
		||||
    protected String contentType;
 | 
			
		||||
    protected byte content[];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -184,6 +186,14 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	    this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPrototype () {
 | 
			
		||||
	return prototype;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setPrototype (String proto) {
 | 
			
		||||
	this.prototype = proto;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public INode getParent () {
 | 
			
		||||
	return parent; 
 | 
			
		||||
| 
						 | 
				
			
			@ -748,7 +758,7 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	return converted;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Node cacheNode;
 | 
			
		||||
    INode cacheNode;
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the cache node for this node. This can be used to store transient cache data per node from Javascript.
 | 
			
		||||
     */
 | 
			
		||||
| 
						 | 
				
			
			@ -758,6 +768,10 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	return cacheNode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public synchronized void setCacheNode (INode cache) {
 | 
			
		||||
	this.cacheNode = cache;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,6 +84,7 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	out.writeBoolean (anonymous);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    transient String prototype;
 | 
			
		||||
    transient INode cacheNode;
 | 
			
		||||
    transient WrappedNodeManager nmgr;
 | 
			
		||||
    transient DbMapping dbmap;
 | 
			
		||||
| 
						 | 
				
			
			@ -117,9 +118,9 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	this.name = propname;
 | 
			
		||||
	this.anonymous = false;
 | 
			
		||||
	if (prototype == null)
 | 
			
		||||
	    setString ("prototype", ""); // set prototype to avoid db lookup if unset
 | 
			
		||||
	    setPrototype ("");
 | 
			
		||||
	else
 | 
			
		||||
	    setString ("prototype", prototype);
 | 
			
		||||
	    setPrototype (prototype);
 | 
			
		||||
	this.state = VIRTUAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +134,7 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	checkWriteLock ();
 | 
			
		||||
	String nameField =  dbmap.getNameField ();
 | 
			
		||||
	name = nameField == null ? id : rec.getValue (nameField).asString ();
 | 
			
		||||
	setString ("prototype", dbmap.getTypeName ());
 | 
			
		||||
	setPrototype (dbmap.getTypeName ());
 | 
			
		||||
	for (Enumeration e=dbmap.db2prop.elements (); e.hasMoreElements();  ) {
 | 
			
		||||
 | 
			
		||||
	    Relation rel = (Relation) e.nextElement ();
 | 
			
		||||
| 
						 | 
				
			
			@ -242,12 +243,8 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	this.nmgr = nmgr;
 | 
			
		||||
 	this.id = id;
 | 
			
		||||
	this.name = name == null || "".equals (name) ? id : name;
 | 
			
		||||
	if (prototype != null) {
 | 
			
		||||
	    propMap = new Hashtable ();
 | 
			
		||||
	    Property prop = new Property ("prototype", this);
 | 
			
		||||
	    prop.setStringValue (prototype);
 | 
			
		||||
	    propMap.put ("prototype", prop);
 | 
			
		||||
	}
 | 
			
		||||
	if (prototype != null)
 | 
			
		||||
	    setPrototype (prototype);
 | 
			
		||||
	created = lastmodified = System.currentTimeMillis ();
 | 
			
		||||
	markAs (CLEAN);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -463,6 +460,21 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	return path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPrototype () {
 | 
			
		||||
	if (prototype == null && propMap != null) {
 | 
			
		||||
	    // retrieve prototype name from properties
 | 
			
		||||
	    Property pp = (Property) propMap.get ("prototype");
 | 
			
		||||
	    if (pp != null)
 | 
			
		||||
	        prototype = pp.getStringValue ();
 | 
			
		||||
	}
 | 
			
		||||
	return prototype;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setPrototype (String proto) {
 | 
			
		||||
	this.prototype = proto;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void setDbMapping (DbMapping dbmap) {
 | 
			
		||||
	if (this.dbmap != dbmap) {
 | 
			
		||||
	    this.dbmap = dbmap;
 | 
			
		||||
| 
						 | 
				
			
			@ -767,6 +779,8 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	loadNodes ();
 | 
			
		||||
	if (subnodes.contains (sid)) try {
 | 
			
		||||
	    Node node = new Node (this, sid, nmgr, null);
 | 
			
		||||
	    // set "groupname" property to value of groupby field
 | 
			
		||||
	    node.setString ("groupname", sid);
 | 
			
		||||
	    Relation srel = dbmap.getSubnodeRelation ();
 | 
			
		||||
	    Relation prel = dbmap.getPropertyRelation ();
 | 
			
		||||
	    DbMapping dbm = new DbMapping ();
 | 
			
		||||
| 
						 | 
				
			
			@ -1377,7 +1391,7 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	DbMapping nmap = dbmap == null ? null : dbmap.getPropertyMapping (propname);
 | 
			
		||||
	if (nmap != null && nmap != n.getDbMapping()) {
 | 
			
		||||
	    n.setDbMapping (nmap);
 | 
			
		||||
	    n.setString ("prototype", nmap.getTypeName ());
 | 
			
		||||
	    n.setPrototype (nmap.getTypeName ());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Property prop = (Property) propMap.get (p2);
 | 
			
		||||
| 
						 | 
				
			
			@ -1677,6 +1691,10 @@ public class Node implements INode, Serializable {
 | 
			
		|||
	return cacheNode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public synchronized void setCacheNode (INode cache) {
 | 
			
		||||
	this.cacheNode = cache;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // walk down node path to the first non-virtual node and return its id.
 | 
			
		||||
    // limit max depth to 3, since there shouldn't be more then 2 layers of virtual nodes.
 | 
			
		||||
    public String getNonVirtualHomeID () {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -686,8 +686,8 @@ public final class NodeManager {
 | 
			
		|||
	    Key k = home.getKey ().getVirtualKey (kstr);
 | 
			
		||||
	    node = (Node) cache.get (k);
 | 
			
		||||
	    if (node != null && node.getState() != INode.INVALID) {
 | 
			
		||||
	        if (rel.prototype != null && !rel.prototype.equals (node.getString ("prototype", false)))
 | 
			
		||||
	            node.setString ("prototype", rel.prototype);
 | 
			
		||||
	        if (rel.prototype != null && !rel.prototype.equals (node.getPrototype ()))
 | 
			
		||||
	            node.setPrototype (rel.prototype);
 | 
			
		||||
	        return node;
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -696,7 +696,7 @@ public final class NodeManager {
 | 
			
		|||
	    if (rel.other == null || (!rel.other.isRelational() && !home.getDbMapping().isRelational())) {
 | 
			
		||||
	        node = (Node) home.createNode (rel.propname);
 | 
			
		||||
	        if (rel.prototype != null)
 | 
			
		||||
	            node.setString ("prototype", rel.prototype);
 | 
			
		||||
	            node.setPrototype (rel.prototype);
 | 
			
		||||
	    } else {
 | 
			
		||||
	        node = new Node (home, kstr, safe, rel.prototype);
 | 
			
		||||
	    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue