updated to reflect and use new powerful Relation class.
This commit is contained in:
parent
25c76b621e
commit
e0f030a63f
1 changed files with 78 additions and 88 deletions
|
@ -48,6 +48,10 @@ public final class Node implements INode, Serializable {
|
||||||
// the serialization version this object was read from (see readObject())
|
// the serialization version this object was read from (see readObject())
|
||||||
protected short version = 0;
|
protected short version = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read this object instance from a stream. This does some smart conversion to
|
||||||
|
* update from previous serialization formats.
|
||||||
|
*/
|
||||||
private void readObject (ObjectInputStream in) throws IOException {
|
private void readObject (ObjectInputStream in) throws IOException {
|
||||||
try {
|
try {
|
||||||
// as a general rule of thumb, if a string can be null use read/writeObject,
|
// as a general rule of thumb, if a string can be null use read/writeObject,
|
||||||
|
@ -105,6 +109,9 @@ public final class Node implements INode, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write out this instance to a stream
|
||||||
|
*/
|
||||||
private void writeObject (ObjectOutputStream out) throws IOException {
|
private void writeObject (ObjectOutputStream out) throws IOException {
|
||||||
out.writeShort (5); // serialization version
|
out.writeShort (5); // serialization version
|
||||||
out.writeUTF (id);
|
out.writeUTF (id);
|
||||||
|
@ -253,7 +260,7 @@ public final class Node implements INode, Serializable {
|
||||||
Relation rel = (Relation) e.nextElement ();
|
Relation rel = (Relation) e.nextElement ();
|
||||||
// NOTE: this should never be the case, since we're just looping through
|
// NOTE: this should never be the case, since we're just looping through
|
||||||
// mappnigs with a local db column
|
// mappnigs with a local db column
|
||||||
if (rel.direction != Relation.PRIMITIVE && rel.direction != Relation.FORWARD)
|
if (rel.reftype != Relation.PRIMITIVE && rel.reftype != Relation.REFERENCE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Value val = rec.getValue (rel.getDbField ());
|
Value val = rec.getValue (rel.getDbField ());
|
||||||
|
@ -261,7 +268,7 @@ public final class Node implements INode, Serializable {
|
||||||
if (val.isNull ())
|
if (val.isNull ())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Property newprop = new Property (rel.propname, this);
|
Property newprop = new Property (rel.propName, this);
|
||||||
|
|
||||||
switch (val.type ()) {
|
switch (val.type ()) {
|
||||||
|
|
||||||
|
@ -320,17 +327,14 @@ public final class Node implements INode, Serializable {
|
||||||
|
|
||||||
if(propMap == null)
|
if(propMap == null)
|
||||||
propMap = new Hashtable ();
|
propMap = new Hashtable ();
|
||||||
propMap.put (rel.propname.toLowerCase(), newprop);
|
propMap.put (rel.propName.toLowerCase(), newprop);
|
||||||
// mark property as clean, since it's fresh from the db
|
// mark property as clean, since it's fresh from the db
|
||||||
newprop.dirty = false;
|
newprop.dirty = false;
|
||||||
|
|
||||||
// if the property is a pointer to another node, change the property type to NODE
|
// if the property is a pointer to another node, change the property type to NODE
|
||||||
if (rel.direction == Relation.FORWARD) {
|
if (rel.reftype == Relation.REFERENCE && rel.usesPrimaryKey ()) {
|
||||||
// FIXME: References to anything other than the primary key are not supported
|
// FIXME: References to anything other than the primary key are not supported
|
||||||
if (rel.usesPrimaryKey ())
|
newprop.nhandle = new NodeHandle (new DbKey (rel.otherType, newprop.getStringValue ()));
|
||||||
newprop.nhandle = new NodeHandle (new DbKey (rel.other, newprop.getStringValue ()));
|
|
||||||
else
|
|
||||||
newprop.nhandle = new NodeHandle (new DbKey (rel.other, newprop.getStringValue (), rel.getRemoteField ()));
|
|
||||||
newprop.type = IProperty.NODE;
|
newprop.type = IProperty.NODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,13 +449,13 @@ public final class Node implements INode, Serializable {
|
||||||
Node p = parentHandle.getNode (nmgr);
|
Node p = parentHandle.getNode (nmgr);
|
||||||
DbMapping parentmap = p.getDbMapping ();
|
DbMapping parentmap = p.getDbMapping ();
|
||||||
Relation prel = parentmap.getPropertyRelation();
|
Relation prel = parentmap.getPropertyRelation();
|
||||||
if (prel != null && prel.subnodesAreProperties && !prel.usesPrimaryKey ()) {
|
if (prel != null && prel.subnodesAreProperties && prel.accessor != null) {
|
||||||
String propname = dbmap.columnNameToProperty (prel.getRemoteField ());
|
String propname = dbmap.columnNameToProperty (prel.accessor);
|
||||||
String propvalue = getString (propname, false);
|
String propvalue = getString (propname, false);
|
||||||
if (propvalue != null && propvalue.length() > 0) {
|
if (propvalue != null && propvalue.length() > 0) {
|
||||||
setName (propvalue);
|
setName (propvalue);
|
||||||
anonymous = false;
|
anonymous = false;
|
||||||
// nameProp = localrel.propname;
|
// nameProp = localrel.propName;
|
||||||
} else {
|
} else {
|
||||||
anonymous = true;
|
anonymous = true;
|
||||||
}
|
}
|
||||||
|
@ -575,7 +579,8 @@ public final class Node implements INode, Serializable {
|
||||||
public void setName (String name) {
|
public void setName (String name) {
|
||||||
// "/" is used as delimiter, so it's not a legal char
|
// "/" is used as delimiter, so it's not a legal char
|
||||||
if (name.indexOf('/') > -1)
|
if (name.indexOf('/') > -1)
|
||||||
throw new RuntimeException ("The name of the node must not contain \"/\".");
|
return;
|
||||||
|
// throw new RuntimeException ("The name of the node must not contain \"/\".");
|
||||||
if (name == null || name.trim().length() == 0)
|
if (name == null || name.trim().length() == 0)
|
||||||
this.name = id; // use id as name
|
this.name = id; // use id as name
|
||||||
else
|
else
|
||||||
|
@ -615,14 +620,11 @@ public final class Node implements INode, Serializable {
|
||||||
if (parentmap != null) {
|
if (parentmap != null) {
|
||||||
// first try to retrieve name via generic property relation of parent
|
// first try to retrieve name via generic property relation of parent
|
||||||
Relation prel = parentmap.getPropertyRelation ();
|
Relation prel = parentmap.getPropertyRelation ();
|
||||||
if (prel != null && prel.other == dbmap && prel.direction == Relation.DIRECT) {
|
if (prel != null && prel.otherType == dbmap && prel.accessor != null) {
|
||||||
// reverse look up property used to access this via parent
|
// reverse look up property used to access this via parent
|
||||||
String dbfield = prel.getRemoteField ();
|
Relation proprel = (Relation) dbmap.getDB2Prop ().get (prel.accessor);
|
||||||
if (dbfield != null) {
|
if (proprel != null && proprel.propName != null)
|
||||||
Relation proprel = (Relation) dbmap.getDB2Prop ().get (dbfield);
|
newname = getString (proprel.propName, false);
|
||||||
if (proprel != null && proprel.propname != null)
|
|
||||||
newname = getString (proprel.propname, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,7 +668,7 @@ public final class Node implements INode, Serializable {
|
||||||
if (dbm != null && dbm.getSubnodeGroupby () != null) {
|
if (dbm != null && dbm.getSubnodeGroupby () != null) {
|
||||||
// check for groupby
|
// check for groupby
|
||||||
Relation rel = (Relation) dbmap.getDB2Prop ().get (dbm.getSubnodeGroupby());
|
Relation rel = (Relation) dbmap.getDB2Prop ().get (dbm.getSubnodeGroupby());
|
||||||
pn = pn.getSubnode (getString (rel.propname, false));
|
pn = pn.getSubnode (getString (rel.propName, false));
|
||||||
}
|
}
|
||||||
if (pn != null) {
|
if (pn != null) {
|
||||||
setParent ((Node) pn);
|
setParent ((Node) pn);
|
||||||
|
@ -716,8 +718,8 @@ public final class Node implements INode, Serializable {
|
||||||
node.makePersistentCapable ();
|
node.makePersistentCapable ();
|
||||||
|
|
||||||
String n = node.getName();
|
String n = node.getName();
|
||||||
if (n.indexOf('/') > -1)
|
// if (n.indexOf('/') > -1)
|
||||||
throw new RuntimeException ("\"/\" found in Node name.");
|
// throw new RuntimeException ("\"/\" found in Node name.");
|
||||||
|
|
||||||
// only lock node if it has to be modified for a change in subnodes
|
// only lock node if it has to be modified for a change in subnodes
|
||||||
if (!ignoreSubnodeChange ())
|
if (!ignoreSubnodeChange ())
|
||||||
|
@ -737,16 +739,18 @@ public final class Node implements INode, Serializable {
|
||||||
if (dbmap != null) {
|
if (dbmap != null) {
|
||||||
Relation srel = dbmap.getSubnodeRelation ();
|
Relation srel = dbmap.getSubnodeRelation ();
|
||||||
if (srel != null && srel.groupby != null) try {
|
if (srel != null && srel.groupby != null) try {
|
||||||
Relation groupbyRel = (Relation) srel.other.getDB2Prop ().get (srel.groupby);
|
Relation groupbyRel = (Relation) srel.otherType.getDB2Prop ().get (srel.groupby);
|
||||||
String groupbyProp = (groupbyRel != null) ?
|
String groupbyProp = (groupbyRel != null) ?
|
||||||
groupbyRel.propname : srel.groupby;
|
groupbyRel.propName : srel.groupby;
|
||||||
String groupbyValue = node.getString (groupbyProp, false);
|
String groupbyValue = node.getString (groupbyProp, false);
|
||||||
INode groupbyNode = getNode (groupbyValue, false);
|
INode groupbyNode = getNode (groupbyValue, false);
|
||||||
// if group-by node doesn't exist, we'll create it
|
// if group-by node doesn't exist, we'll create it
|
||||||
if (groupbyNode == null)
|
if (groupbyNode == null)
|
||||||
groupbyNode = getGroupbySubnode (groupbyValue, true);
|
groupbyNode = getGroupbySubnode (groupbyValue, true);
|
||||||
groupbyNode.addNode (node);
|
groupbyNode.addNode (node);
|
||||||
checkBackLink (node);
|
|
||||||
|
srel.setConstraints (this, node);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
System.err.println ("Error adding groupby: "+x);
|
System.err.println ("Error adding groupby: "+x);
|
||||||
|
@ -773,10 +777,10 @@ public final class Node implements INode, Serializable {
|
||||||
// check if properties are subnodes (_properties.aresubnodes=true)
|
// check if properties are subnodes (_properties.aresubnodes=true)
|
||||||
if (dbmap != null && node.dbmap != null) {
|
if (dbmap != null && node.dbmap != null) {
|
||||||
Relation prel = dbmap.getPropertyRelation();
|
Relation prel = dbmap.getPropertyRelation();
|
||||||
if (prel != null && prel.subnodesAreProperties && !prel.usesPrimaryKey ()) {
|
if (prel != null && prel.accessor != null) {
|
||||||
Relation localrel = node.dbmap.columnNameToRelation (prel.getRemoteField ());
|
Relation localrel = node.dbmap.columnNameToRelation (prel.accessor);
|
||||||
// if no relation from db column to prop name is found, assume that both are equal
|
// if no relation from db column to prop name is found, assume that both are equal
|
||||||
String propname = localrel == null ? prel.getRemoteField() : localrel.propname;
|
String propname = localrel == null ? prel.accessor : localrel.propName;
|
||||||
String prop = node.getString (propname, false);
|
String prop = node.getString (propname, false);
|
||||||
if (prop != null && prop.length() > 0) {
|
if (prop != null && prop.length() > 0) {
|
||||||
INode old = getNode (prop, false);
|
INode old = getNode (prop, false);
|
||||||
|
@ -806,7 +810,8 @@ public final class Node implements INode, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkBackLink (node);
|
if (dbmap != null && dbmap.getSubnodeRelation () != null)
|
||||||
|
dbmap.getSubnodeRelation ().setConstraints (this, node);
|
||||||
|
|
||||||
lastmodified = System.currentTimeMillis ();
|
lastmodified = System.currentTimeMillis ();
|
||||||
lastSubnodeChange = lastmodified;
|
lastSubnodeChange = lastmodified;
|
||||||
|
@ -814,24 +819,6 @@ public final class Node implements INode, Serializable {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBackLink (Node node) {
|
|
||||||
// check if the subnode is in relational db and needs to link back to this
|
|
||||||
// in order to make it a subnode
|
|
||||||
if (dbmap != null) {
|
|
||||||
Relation srel = dbmap.getSubnodeRelation ();
|
|
||||||
if (srel != null && srel.direction == Relation.BACKWARD) {
|
|
||||||
Relation backlink = srel.other.columnNameToRelation (srel.getRemoteField());
|
|
||||||
if (backlink != null && backlink.propname != null) {
|
|
||||||
if (node.get (backlink.propname, false) == null) {
|
|
||||||
if (this.state == VIRTUAL)
|
|
||||||
node.setString (backlink.propname, getNonVirtualHomeID());
|
|
||||||
else
|
|
||||||
node.setString (backlink.propname, getID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public INode createNode () {
|
public INode createNode () {
|
||||||
return createNode (null, numberOfNodes ()); // create new node at end of subnode array
|
return createNode (null, numberOfNodes ()); // create new node at end of subnode array
|
||||||
|
@ -899,11 +886,11 @@ public final class Node implements INode, Serializable {
|
||||||
if ("".equals (subid)) {
|
if ("".equals (subid)) {
|
||||||
return this;
|
return this;
|
||||||
} else if (subid != null) {
|
} else if (subid != null) {
|
||||||
|
|
||||||
loadNodes ();
|
loadNodes ();
|
||||||
if (subnodes == null || subnodes.size() == 0)
|
if (subnodes == null || subnodes.size() == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// check if there is a group-by relation
|
|
||||||
NodeHandle nhandle = null;
|
NodeHandle nhandle = null;
|
||||||
int l = subnodes.size ();
|
int l = subnodes.size ();
|
||||||
for (int i=0; i<l; i++) try {
|
for (int i=0; i<l; i++) try {
|
||||||
|
@ -916,24 +903,20 @@ public final class Node implements INode, Serializable {
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if (srel != null && srel.groupby != null)
|
|
||||||
nhandle = new NodeHandle (new SyntheticKey (runner.getKey (), next));
|
|
||||||
else
|
|
||||||
nhandle = new NodeHandle (new DbKey (smap, next));
|
|
||||||
boolean found = runner.subnodes == null ? false : runner.subnodes.contains (nhandle); */
|
|
||||||
|
|
||||||
if (nhandle != null) {
|
if (nhandle != null) {
|
||||||
retval = nhandle.getNode (nmgr);
|
retval = nhandle.getNode (nmgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This would be an alternative way to do it, without loading the subnodes:
|
||||||
|
// if (dbmap != null && dbmap.getSubnodeRelation () != null)
|
||||||
|
// retval = nmgr.getNode (this, subid, dbmap.getSubnodeRelation ());
|
||||||
|
|
||||||
if (retval != null && retval.parentHandle == null && !"root".equalsIgnoreCase (retval.getPrototype ())) {
|
if (retval != null && retval.parentHandle == null && !"root".equalsIgnoreCase (retval.getPrototype ())) {
|
||||||
retval.setParent (this);
|
retval.setParent (this);
|
||||||
retval.anonymous = true;
|
retval.anonymous = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (retval == null) {
|
|
||||||
retval = (Node) getNode (subid, false);
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -989,6 +972,7 @@ public final class Node implements INode, Serializable {
|
||||||
}
|
}
|
||||||
} catch (Exception noluck) {
|
} catch (Exception noluck) {
|
||||||
nmgr.logEvent ("Error creating group-by node for "+sid+": "+noluck);
|
nmgr.logEvent ("Error creating group-by node for "+sid+": "+noluck);
|
||||||
|
noluck.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1040,20 +1024,20 @@ public final class Node implements INode, Serializable {
|
||||||
// which needs to be unset
|
// which needs to be unset
|
||||||
if (dbmap != null) {
|
if (dbmap != null) {
|
||||||
Relation srel = dbmap.getSubnodeRelation ();
|
Relation srel = dbmap.getSubnodeRelation ();
|
||||||
if (srel != null && srel.direction == Relation.BACKWARD) {
|
/*if (srel != null && srel.reftype == Relation.BACKWARD) {
|
||||||
Relation backlink = srel.other.columnNameToRelation (srel.getRemoteField ());
|
Relation backlink = srel.otherType.columnNameToRelation (srel.getRemoteField ());
|
||||||
if (backlink != null && id.equals (node.getString (backlink.propname, false)))
|
if (backlink != null && id.equals (node.getString (backlink.propName, false)))
|
||||||
node.unset (backlink.propname);
|
node.unset (backlink.propName);
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if subnodes are also accessed as properties. If so, also unset the property
|
// check if subnodes are also accessed as properties. If so, also unset the property
|
||||||
if (dbmap != null && node.dbmap != null) {
|
if (dbmap != null && node.dbmap != null) {
|
||||||
Relation prel = dbmap.getPropertyRelation();
|
Relation prel = dbmap.getPropertyRelation();
|
||||||
if (prel != null && prel.subnodesAreProperties && !prel.usesPrimaryKey ()) {
|
if (prel != null && prel.accessor != null) {
|
||||||
Relation localrel = node.dbmap.columnNameToRelation (prel.getRemoteField());
|
Relation localrel = node.dbmap.columnNameToRelation (prel.accessor);
|
||||||
// if no relation from db column to prop name is found, assume that both are equal
|
// if no relation from db column to prop name is found, assume that both are equal
|
||||||
String propname = localrel == null ? prel.getRemoteField () : localrel.propname;
|
String propname = localrel == null ? prel.accessor : localrel.propName;
|
||||||
String prop = node.getString (propname, false);
|
String prop = node.getString (propname, false);
|
||||||
if (prop != null && getNode (prop, false) == node)
|
if (prop != null && getNode (prop, false) == node)
|
||||||
unset (prop);
|
unset (prop);
|
||||||
|
@ -1190,9 +1174,6 @@ public final class Node implements INode, Serializable {
|
||||||
if (smap != null && smap.isRelational ()) {
|
if (smap != null && smap.isRelational ()) {
|
||||||
// check if subnodes need to be reloaded
|
// check if subnodes need to be reloaded
|
||||||
Relation subRel = dbmap.getSubnodeRelation ();
|
Relation subRel = dbmap.getSubnodeRelation ();
|
||||||
// can't do backward relation on transient subnodes
|
|
||||||
if (state == TRANSIENT && subRel.direction == Relation.BACKWARD)
|
|
||||||
return;
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
long lastChange = subRel.aggressiveCaching ? lastSubnodeChange : smap.getLastDataChange ();
|
long lastChange = subRel.aggressiveCaching ? lastSubnodeChange : smap.getLastDataChange ();
|
||||||
// also reload if the type mapping has changed.
|
// also reload if the type mapping has changed.
|
||||||
|
@ -1226,7 +1207,7 @@ public final class Node implements INode, Serializable {
|
||||||
// return true if a change in subnodes can be ignored because it is
|
// return true if a change in subnodes can be ignored because it is
|
||||||
// stored in the subnodes themselves.
|
// stored in the subnodes themselves.
|
||||||
Relation rel = dbmap == null ? null : dbmap.getSubnodeRelation();
|
Relation rel = dbmap == null ? null : dbmap.getSubnodeRelation();
|
||||||
return (rel != null && rel.other != null && rel.other.isRelational() && rel.direction == Relation.BACKWARD);
|
return (rel != null && rel.otherType != null && rel.otherType.isRelational());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1239,8 +1220,8 @@ public final class Node implements INode, Serializable {
|
||||||
return dbmap.getProp2DB ().keys();
|
return dbmap.getProp2DB ().keys();
|
||||||
|
|
||||||
Relation prel = dbmap == null ? null : dbmap.getPropertyRelation ();
|
Relation prel = dbmap == null ? null : dbmap.getPropertyRelation ();
|
||||||
if (prel != null && prel.direction == Relation.DIRECT && !prel.subnodesAreProperties
|
if (prel != null && prel.accessor != null && !prel.subnodesAreProperties
|
||||||
&& prel.other != null && prel.other.isRelational ())
|
&& prel.otherType != null && prel.otherType.isRelational ())
|
||||||
// return names of objects from a relational db table
|
// return names of objects from a relational db table
|
||||||
return nmgr.getPropertyNames (this, prel).elements ();
|
return nmgr.getPropertyNames (this, prel).elements ();
|
||||||
else if (propMap != null)
|
else if (propMap != null)
|
||||||
|
@ -1281,10 +1262,10 @@ public final class Node implements INode, Serializable {
|
||||||
|
|
||||||
// the property does not exist in our propmap - see if we can create it on the fly,
|
// the property does not exist in our propmap - see if we can create it on the fly,
|
||||||
// either because it is mapped from a relational database or defined as virtual node
|
// either because it is mapped from a relational database or defined as virtual node
|
||||||
if (prop == null && dbmap != null) {
|
if (prop == null && dbmap != null && state != TRANSIENT && state != NEW) {
|
||||||
Relation prel = dbmap.getPropertyRelation (propname);
|
Relation prel = dbmap.getPropertyRelation (propname);
|
||||||
Relation srel = dbmap.getSubnodeRelation ();
|
Relation srel = dbmap.getSubnodeRelation ();
|
||||||
/* if (prel != null && prel.virtual && prel.other != null && !prel.other.isRelational ()) {
|
/* if (prel != null && prel.virtual && prel.otherType != null && !prel.otherType.isRelational ()) {
|
||||||
Node pn = (Node) createNode (propname);
|
Node pn = (Node) createNode (propname);
|
||||||
if (prel.prototype != null) {
|
if (prel.prototype != null) {
|
||||||
pn.setPrototype (prel.prototype);
|
pn.setPrototype (prel.prototype);
|
||||||
|
@ -1296,7 +1277,7 @@ public final class Node implements INode, Serializable {
|
||||||
prel = srel;
|
prel = srel;
|
||||||
if (prel == null)
|
if (prel == null)
|
||||||
prel = dbmap.getPropertyRelation ();
|
prel = dbmap.getPropertyRelation ();
|
||||||
if (prel != null && (prel.direction == Relation.DIRECT || prel.virtual || prel.groupby != null)) {
|
if (prel != null && (prel.accessor != null || prel.virtual || prel.groupby != null)) {
|
||||||
// this may be a relational node stored by property name
|
// this may be a relational node stored by property name
|
||||||
try {
|
try {
|
||||||
Node pn = nmgr.getNode (this, propname, prel);
|
Node pn = nmgr.getNode (this, propname, prel);
|
||||||
|
@ -1418,13 +1399,14 @@ public final class Node implements INode, Serializable {
|
||||||
// but only do this if we already have a parent set, i.e. if we are already stored in the db
|
// but only do this if we already have a parent set, i.e. if we are already stored in the db
|
||||||
Node parent = parentHandle == null ? null : (Node) getParent ();
|
Node parent = parentHandle == null ? null : (Node) getParent ();
|
||||||
|
|
||||||
if (parent != null && parent.getDbMapping() != null) {
|
if (dbmap != null && parent != null && parent.getDbMapping() != null) {
|
||||||
// check if this node is already registered with the old name; if so, remove it.
|
// check if this node is already registered with the old name; if so, remove it.
|
||||||
// then set parent's property to this node for the new name value
|
// then set parent's property to this node for the new name value
|
||||||
DbMapping parentmap = parent.getDbMapping ();
|
DbMapping parentmap = parent.getDbMapping ();
|
||||||
Relation prel = parentmap.getPropertyRelation ();
|
Relation prel = parentmap.getPropertyRelation ();
|
||||||
|
String dbcolumn = dbmap.propertyToColumnName (propname);
|
||||||
|
|
||||||
if (prel != null && prel.subnodesAreProperties && propname.equals (prel.getRemoteField())) {
|
if (prel != null && prel.accessor != null && prel.accessor.equals (dbcolumn)) {
|
||||||
INode n = parent.getNode (value, false);
|
INode n = parent.getNode (value, false);
|
||||||
if (n != null && n != this) {
|
if (n != null && n != this) {
|
||||||
parent.unset (value);
|
parent.unset (value);
|
||||||
|
@ -1639,8 +1621,8 @@ public final class Node implements INode, Serializable {
|
||||||
prop.setNodeValue (n);
|
prop.setNodeValue (n);
|
||||||
Relation rel = dbmap == null ? null : dbmap.getPropertyRelation (propname);
|
Relation rel = dbmap == null ? null : dbmap.getPropertyRelation (propname);
|
||||||
|
|
||||||
if (rel == null || rel.direction == Relation.FORWARD || rel.virtual ||
|
if (rel == null || rel.reftype == Relation.REFERENCE || rel.virtual ||
|
||||||
rel.other == null || !rel.other.isRelational()) {
|
rel.otherType == null || !rel.otherType.isRelational()) {
|
||||||
// the node must be stored as explicit property
|
// the node must be stored as explicit property
|
||||||
if (propMap == null)
|
if (propMap == null)
|
||||||
propMap = new Hashtable ();
|
propMap = new Hashtable ();
|
||||||
|
@ -1648,25 +1630,26 @@ public final class Node implements INode, Serializable {
|
||||||
if (state == CLEAN) markAs (MODIFIED);
|
if (state == CLEAN) markAs (MODIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rel != null && rel.direction == Relation.FORWARD && !rel.usesPrimaryKey ()) {
|
/* if (rel != null && rel.reftype == Relation.REFERENCE && !rel.usesPrimaryKey ()) {
|
||||||
// if the relation for this property doesn't use the primary key of the value object, make a
|
// if the relation for this property doesn't use the primary key of the value object, make a
|
||||||
// secondary key object with the proper db column
|
// secondary key object with the proper db column
|
||||||
String kval = n.getString (rel.other.columnNameToProperty (rel.getRemoteField ()), false);
|
String kval = n.getString (rel.otherType.columnNameToProperty (rel.getRemoteField ()), false);
|
||||||
prop.nhandle = new NodeHandle (new DbKey (n.getDbMapping (), kval, rel.getRemoteField ()));
|
prop.nhandle = new NodeHandle (new DbKey (n.getDbMapping (), kval, rel.getRemoteField ()));
|
||||||
}
|
} */
|
||||||
|
|
||||||
if (n.state != TRANSIENT) {
|
// don't check node in transactor cache -- this is done anyway when the node becomes persistent.
|
||||||
|
/* if (n.state != TRANSIENT) {
|
||||||
// check node in with transactor cache
|
// check node in with transactor cache
|
||||||
String nID = n.getID();
|
String nID = n.getID();
|
||||||
Transactor tx = (Transactor) Thread.currentThread ();
|
Transactor tx = (Transactor) Thread.currentThread ();
|
||||||
tx.visitCleanNode (new DbKey (nmap, nID), n);
|
tx.visitCleanNode (new DbKey (nmap, nID), n);
|
||||||
// if the field is not the primary key of the property, also register it
|
// if the field is not the primary key of the property, also register it
|
||||||
if (rel != null && rel.direction == Relation.DIRECT) {
|
if (rel != null && rel.reftype == Relation.DIRECT && state != TRANSIENT) {
|
||||||
Key secKey = new SyntheticKey (getKey (), propname);
|
Key secKey = new SyntheticKey (getKey (), propname);
|
||||||
nmgr.evictKey (secKey);
|
nmgr.evictKey (secKey);
|
||||||
tx.visitCleanNode (secKey, n);
|
tx.visitCleanNode (secKey, n);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
lastmodified = System.currentTimeMillis ();
|
lastmodified = System.currentTimeMillis ();
|
||||||
if (n.state == DELETED) n.markAs (MODIFIED);
|
if (n.state == DELETED) n.markAs (MODIFIED);
|
||||||
|
@ -1812,23 +1795,30 @@ public final class Node implements INode, Serializable {
|
||||||
*/
|
*/
|
||||||
public synchronized INode getCacheNode () {
|
public synchronized INode getCacheNode () {
|
||||||
if (cacheNode == null)
|
if (cacheNode == null)
|
||||||
cacheNode = new helma.objectmodel.Node();
|
cacheNode = new TransientNode();
|
||||||
return cacheNode;
|
return cacheNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
* This method walks down node path to the first non-virtual node and return it.
|
||||||
public String getNonVirtualHomeID () {
|
* limit max depth to 3, since there shouldn't be more then 2 layers of virtual nodes.
|
||||||
|
*/
|
||||||
|
public INode getNonVirtualParent () {
|
||||||
INode node = this;
|
INode node = this;
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
if (node == null) break;
|
if (node == null) break;
|
||||||
if (node.getState() != Node.VIRTUAL)
|
if (node.getState() != Node.VIRTUAL)
|
||||||
return node.getID ();
|
return node;
|
||||||
node = node.getParent ();
|
node = node.getParent ();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instances of this class may be used to mark an entry in the object cache as null.
|
||||||
|
* This method tells the caller whether this is the case.
|
||||||
|
*/
|
||||||
public boolean isNullNode () {
|
public boolean isNullNode () {
|
||||||
return nmgr == null;
|
return nmgr == null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue