* Make JavaScript HopObject.get() return generic Node properties in addition to child objects.

* Added checkNode method() to refresh node in case it has been invalidated.
This commit is contained in:
hns 2003-10-15 16:10:26 +00:00
parent c1ddf495ca
commit 3271f940cd

View file

@ -160,6 +160,20 @@ public class HopObject extends ScriptableObject implements Wrapper {
return node; return node;
} }
/**
* Check if the node has been invalidated. If so, it has to be re-fetched
* from the db via the app's node manager.
*/
private final void checkNode() {
if (node != null && node.getState() == INode.INVALID) {
if (node instanceof helma.objectmodel.db.Node) {
NodeHandle handle = ((helma.objectmodel.db.Node) node).getHandle();
node = handle.getNode(core.app.getWrappedNodeManager());
}
}
}
/** /**
* *
* *
@ -170,6 +184,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
return null; return null;
} }
checkNode();
return node.getCacheNode(); return node.getCacheNode();
} }
@ -248,6 +264,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
String act = null; String act = null;
checkNode();
if (action != null) { if (action != null) {
if (action instanceof Wrapper) { if (action instanceof Wrapper) {
act = ((Wrapper) action).unwrap().toString(); act = ((Wrapper) action).unwrap().toString();
@ -269,23 +287,27 @@ public class HopObject extends ScriptableObject implements Wrapper {
* @return ... * @return ...
*/ */
public Object jsFunction_get(Object id) { public Object jsFunction_get(Object id) {
if ((node == null) || (id == null) || id == Undefined.instance) { if ((node == null) || (id == null)) {
return null; return null;
} }
Object n = null; Object n = null;
if (id instanceof Number) { if (id instanceof Number) {
n = node.getSubnodeAt(((Number) id).intValue()); n = get(((Number) id).intValue(), this);
} else if (id instanceof String) {
n = getFromNode(id.toString());
} else { } else {
n = node.getChildElement(id.toString()); throw new RuntimeException("Invalid type for id argument in HopObject.get(): "+id);
} }
if (n == null) { // since we're calling Scriptable.get() methods, we'll get NOT_FOUND rather
// than null if a property is not defined.
if (n == null || n == NOT_FOUND) {
return null; return null;
} else {
return Context.toObject(n, core.global);
} }
return n;
} }
/** /**
@ -300,6 +322,7 @@ public class HopObject extends ScriptableObject implements Wrapper {
return null; return null;
} }
checkNode();
Object n = node.getSubnode(id.toString()); Object n = node.getSubnode(id.toString());
if (n == null) { if (n == null) {
@ -324,6 +347,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
return false; return false;
} }
checkNode();
if (id instanceof Number) { if (id instanceof Number) {
if (!(value instanceof HopObject)) { if (!(value instanceof HopObject)) {
@ -354,6 +379,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
return 0; return 0;
} }
checkNode();
return node.numberOfNodes(); return node.numberOfNodes();
} }
@ -381,6 +408,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
return; return;
} }
checkNode();
try { try {
((helma.objectmodel.db.Node) node).prefetchChildren(start, length); ((helma.objectmodel.db.Node) node).prefetchChildren(start, length);
} catch (Exception x) { } catch (Exception x) {
@ -391,6 +420,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
* Clear the node's cache node. * Clear the node's cache node.
*/ */
public void jsFunction_clearCache() { public void jsFunction_clearCache() {
checkNode();
node.clearCacheNode(); node.clearCacheNode();
} }
@ -403,6 +434,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
Enumeration e = node.getSubnodes(); Enumeration e = node.getSubnodes();
ArrayList a = new ArrayList(); ArrayList a = new ArrayList();
checkNode();
while ((e != null) && e.hasMoreElements()) { while ((e != null) && e.hasMoreElements()) {
a.add(Context.toObject(e.nextElement(), core.global)); a.add(Context.toObject(e.nextElement(), core.global));
} }
@ -422,6 +455,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
return false; return false;
} }
checkNode();
if (child instanceof HopObject) { if (child instanceof HopObject) {
node.addNode(((HopObject) child).node); node.addNode(((HopObject) child).node);
@ -448,6 +483,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
return false; return false;
} }
checkNode();
if (child instanceof HopObject) { if (child instanceof HopObject) {
node.addNode(((HopObject) child).node, index); node.addNode(((HopObject) child).node, index);
@ -467,6 +504,9 @@ public class HopObject extends ScriptableObject implements Wrapper {
public boolean jsFunction_remove(Object child) { public boolean jsFunction_remove(Object child) {
// semantics: if called without arguments, remove self. // semantics: if called without arguments, remove self.
// otherwise, remove given subnodes. // otherwise, remove given subnodes.
checkNode();
if (child == Undefined.instance) { if (child == Undefined.instance) {
return node.remove(); return node.remove();
} else if (node != null) { } else if (node != null) {
@ -495,8 +535,16 @@ public class HopObject extends ScriptableObject implements Wrapper {
public boolean jsFunction_invalidate(Object childId) { public boolean jsFunction_invalidate(Object childId) {
if (childId != null && node instanceof helma.objectmodel.db.Node) { if (childId != null && node instanceof helma.objectmodel.db.Node) {
if (childId == Undefined.instance) { if (childId == Undefined.instance) {
if (node.getState() == INode.INVALID) {
return true;
}
((helma.objectmodel.db.Node) node).invalidate(); ((helma.objectmodel.db.Node) node).invalidate();
} else { } else {
checkNode();
((helma.objectmodel.db.Node) node).invalidateNode(childId.toString()); ((helma.objectmodel.db.Node) node).invalidateNode(childId.toString());
} }
} }
@ -509,6 +557,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
*/ */
public int jsFunction_contains(Object obj) { public int jsFunction_contains(Object obj) {
if ((node != null) && obj instanceof HopObject) { if ((node != null) && obj instanceof HopObject) {
checkNode();
return node.contains(((HopObject) obj).node); return node.contains(((HopObject) obj).node);
} }
@ -527,6 +577,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
super.put(name, start, value); super.put(name, start, value);
} else { } else {
checkNode();
if ("subnodeRelation".equals(name)) { if ("subnodeRelation".equals(name)) {
node.setSubnodeRelation(value == null ? null : value.toString()); node.setSubnodeRelation(value == null ? null : value.toString());
} }
@ -586,8 +638,13 @@ public class HopObject extends ScriptableObject implements Wrapper {
return true; return true;
} }
if ((node != null) && (node.get(name) != null)) { if (node != null) {
return true;
checkNode();
if (node.get(name) != null) {
return true;
}
} }
return false; return false;
@ -600,7 +657,11 @@ public class HopObject extends ScriptableObject implements Wrapper {
*/ */
public void delete(String name) { public void delete(String name) {
super.delete(name); super.delete(name);
if ((node != null)) { if ((node != null)) {
checkNode();
node.unset(name); node.unset(name);
} }
} }
@ -629,7 +690,19 @@ public class HopObject extends ScriptableObject implements Wrapper {
return retval; return retval;
} }
return getFromNode(name);
}
/**
* Retrieve a property only from the node itself, not the underlying prototype object.
* This is called directly when we call get(x) on a JS HopObject, since we don't want
* to return the prototype functions in that case.
*/
private Object getFromNode(String name) {
if (node != null) { if (node != null) {
checkNode();
// Everything starting with an underscore is interpreted as internal property // Everything starting with an underscore is interpreted as internal property
if (name.charAt(0) == '_') { if (name.charAt(0) == '_') {
return getInternalProperty(name); return getInternalProperty(name);
@ -758,6 +831,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
Enumeration enum = node.properties(); Enumeration enum = node.properties();
ArrayList list = new ArrayList(); ArrayList list = new ArrayList();
checkNode();
while (enum.hasMoreElements()) while (enum.hasMoreElements())
list.add(enum.nextElement()); list.add(enum.nextElement());
@ -774,6 +849,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
*/ */
public boolean has(int idx, Scriptable start) { public boolean has(int idx, Scriptable start) {
if (node != null) { if (node != null) {
checkNode();
return (0 <= idx && idx < node.numberOfNodes()); return (0 <= idx && idx < node.numberOfNodes());
} }
@ -790,7 +867,10 @@ public class HopObject extends ScriptableObject implements Wrapper {
*/ */
public Object get(int idx, Scriptable start) { public Object get(int idx, Scriptable start) {
if (node != null) { if (node != null) {
checkNode();
INode n = node.getSubnodeAt(idx); INode n = node.getSubnodeAt(idx);
if (n != null) { if (n != null) {
return Context.toObject(n, core.global); return Context.toObject(n, core.global);
} }