* Allow _parent to consist of three elements, such as page.comments.blocked.
Fixes bug 563 - http://helma.org/bugs/show_bug.cgi?id=563 * Throw an exception when adding to a collection with accessname defined and the collection already contains an object with the given name. Previously, the old object was deleted from the database. Fixes bug 561 - http://helma.org/bugs/show_bug.cgi?id=561
This commit is contained in:
parent
3c059e8778
commit
ae0536eb26
2 changed files with 32 additions and 26 deletions
|
@ -789,13 +789,18 @@ public final class Node implements INode, Serializable {
|
|||
if (pn2 == null) {
|
||||
getApp().logError("Error: Can't retrieve parent node " +
|
||||
pinfo + " for " + this);
|
||||
} else if (pinfo.collectionname != null) {
|
||||
pn2 = (Node) pn2.getNode(pinfo.collectionname);
|
||||
} else if (pn2.equals(this)) {
|
||||
// a special case we want to support: virtualname is actually
|
||||
// a reference to this node, not a collection containint this node.
|
||||
setParent(pn);
|
||||
name = pinfo.virtualname;
|
||||
anonymous = false;
|
||||
return pn;
|
||||
}
|
||||
pn = pn2;
|
||||
|
||||
pn = pn2;
|
||||
}
|
||||
|
||||
DbMapping dbm = (pn == null) ? null : pn.getDbMapping();
|
||||
|
@ -952,11 +957,11 @@ public final class Node implements INode, Serializable {
|
|||
}
|
||||
|
||||
// check if subnode accessname is set. If so, check if another node
|
||||
// uses the same access name and remove it
|
||||
if ((dbmap != null) && (node.dbmap != null)) {
|
||||
// uses the same access name, throwing an exception if so.
|
||||
if (dbmap != null && node.dbmap != null) {
|
||||
Relation prel = dbmap.getSubnodeRelation();
|
||||
|
||||
if ((prel != null) && (prel.accessName != null)) {
|
||||
if (prel != null && prel.accessName != null) {
|
||||
Relation localrel = node.dbmap.columnNameToRelation(prel.accessName);
|
||||
|
||||
// if no relation from db column to prop name is found,
|
||||
|
@ -965,15 +970,14 @@ public final class Node implements INode, Serializable {
|
|||
: localrel.propName;
|
||||
String prop = node.getString(propname);
|
||||
|
||||
if ((prop != null) && (prop.length() > 0)) {
|
||||
if (prop != null && prop.length() > 0) {
|
||||
INode old = (INode) getChildElement(prop);
|
||||
|
||||
if ((old != null) && (old != node)) {
|
||||
// FIXME: we delete the existing node here,
|
||||
// but actually the app developer should prevent this from
|
||||
// happening, so it might be better to throw an exception.
|
||||
old.remove();
|
||||
this.removeNode(old);
|
||||
if (old != null && old != node) {
|
||||
// A node with this name already exists. This is a
|
||||
// programming error, throw an exception.
|
||||
throw new RuntimeException("An object named \"" + prop +
|
||||
"\" is already contained in the collection.");
|
||||
}
|
||||
|
||||
if (state != TRANSIENT) {
|
||||
|
@ -2714,7 +2718,7 @@ public final class Node implements INode, Serializable {
|
|||
* @return the number of loaded nodes within this collection update
|
||||
*/
|
||||
public int updateSubnodes () {
|
||||
// FIXME: what do we do if dbmap is null
|
||||
// TODO: what do we do if dbmap is null
|
||||
if (dbmap == null) {
|
||||
throw new RuntimeException (this + " doesn't have a DbMapping");
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package helma.objectmodel.db;
|
||||
|
||||
import helma.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* This class describes a parent relation between releational nodes.
|
||||
|
@ -23,38 +25,38 @@ package helma.objectmodel.db;
|
|||
public class ParentInfo {
|
||||
public final String propname;
|
||||
public final String virtualname;
|
||||
public final String collectionname;
|
||||
public final boolean isroot;
|
||||
|
||||
/**
|
||||
* Creates a new ParentInfo object.
|
||||
*
|
||||
* @param desc ...
|
||||
* @param desc a single parent info descriptor
|
||||
*/
|
||||
public ParentInfo(String desc) {
|
||||
|
||||
// [named] isn't used anymore, we just want to keep the parsing compatible.
|
||||
int n = desc.indexOf("[named]");
|
||||
String d = n>-1 ? desc.substring(0, n) : desc;
|
||||
desc = n > -1 ? desc.substring(0, n) : desc;
|
||||
|
||||
int dot = d.indexOf(".");
|
||||
String[] parts = StringUtils.split(desc, ".");
|
||||
|
||||
if (dot > -1) {
|
||||
propname = d.substring(0, dot).trim();
|
||||
virtualname = d.substring(dot + 1).trim();
|
||||
} else {
|
||||
propname = d.trim();
|
||||
virtualname = null;
|
||||
}
|
||||
propname = parts.length > 0 ? parts[0].trim() : null;
|
||||
virtualname = parts.length > 1 ? parts[1].trim() : null;
|
||||
collectionname = parts.length > 2 ? parts[2].trim() : null;
|
||||
|
||||
isroot = "root".equalsIgnoreCase(propname);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
* @return a string representation of the parent info
|
||||
*/
|
||||
public String toString() {
|
||||
return "ParentInfo[" + propname + "," + virtualname + "]";
|
||||
StringBuffer b = new StringBuffer("ParentInfo[").append(propname);
|
||||
if (virtualname != null)
|
||||
b.append(".").append(virtualname);
|
||||
if (collectionname != null)
|
||||
b.append(".").append(collectionname);
|
||||
return b.append("]").toString();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue