* 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:
parent
c1ddf495ca
commit
3271f940cd
1 changed files with 88 additions and 8 deletions
|
@ -160,6 +160,20 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
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;
|
||||
}
|
||||
|
||||
checkNode();
|
||||
|
||||
return node.getCacheNode();
|
||||
}
|
||||
|
||||
|
@ -248,6 +264,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
|
||||
String act = null;
|
||||
|
||||
checkNode();
|
||||
|
||||
if (action != null) {
|
||||
if (action instanceof Wrapper) {
|
||||
act = ((Wrapper) action).unwrap().toString();
|
||||
|
@ -269,23 +287,27 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
* @return ...
|
||||
*/
|
||||
public Object jsFunction_get(Object id) {
|
||||
if ((node == null) || (id == null) || id == Undefined.instance) {
|
||||
if ((node == null) || (id == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object n = null;
|
||||
|
||||
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 {
|
||||
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;
|
||||
} else {
|
||||
return Context.toObject(n, core.global);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,6 +322,7 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
return null;
|
||||
}
|
||||
|
||||
checkNode();
|
||||
Object n = node.getSubnode(id.toString());
|
||||
|
||||
if (n == null) {
|
||||
|
@ -324,6 +347,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
return false;
|
||||
}
|
||||
|
||||
checkNode();
|
||||
|
||||
if (id instanceof Number) {
|
||||
|
||||
if (!(value instanceof HopObject)) {
|
||||
|
@ -354,6 +379,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
return 0;
|
||||
}
|
||||
|
||||
checkNode();
|
||||
|
||||
return node.numberOfNodes();
|
||||
}
|
||||
|
||||
|
@ -381,6 +408,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
return;
|
||||
}
|
||||
|
||||
checkNode();
|
||||
|
||||
try {
|
||||
((helma.objectmodel.db.Node) node).prefetchChildren(start, length);
|
||||
} catch (Exception x) {
|
||||
|
@ -391,6 +420,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
* Clear the node's cache node.
|
||||
*/
|
||||
public void jsFunction_clearCache() {
|
||||
checkNode();
|
||||
|
||||
node.clearCacheNode();
|
||||
}
|
||||
|
||||
|
@ -403,6 +434,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
Enumeration e = node.getSubnodes();
|
||||
ArrayList a = new ArrayList();
|
||||
|
||||
checkNode();
|
||||
|
||||
while ((e != null) && e.hasMoreElements()) {
|
||||
a.add(Context.toObject(e.nextElement(), core.global));
|
||||
}
|
||||
|
@ -422,6 +455,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
return false;
|
||||
}
|
||||
|
||||
checkNode();
|
||||
|
||||
if (child instanceof HopObject) {
|
||||
node.addNode(((HopObject) child).node);
|
||||
|
||||
|
@ -448,6 +483,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
return false;
|
||||
}
|
||||
|
||||
checkNode();
|
||||
|
||||
if (child instanceof HopObject) {
|
||||
node.addNode(((HopObject) child).node, index);
|
||||
|
||||
|
@ -467,6 +504,9 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
public boolean jsFunction_remove(Object child) {
|
||||
// semantics: if called without arguments, remove self.
|
||||
// otherwise, remove given subnodes.
|
||||
|
||||
checkNode();
|
||||
|
||||
if (child == Undefined.instance) {
|
||||
return node.remove();
|
||||
} else if (node != null) {
|
||||
|
@ -495,8 +535,16 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
public boolean jsFunction_invalidate(Object childId) {
|
||||
if (childId != null && node instanceof helma.objectmodel.db.Node) {
|
||||
if (childId == Undefined.instance) {
|
||||
|
||||
if (node.getState() == INode.INVALID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
((helma.objectmodel.db.Node) node).invalidate();
|
||||
} else {
|
||||
|
||||
checkNode();
|
||||
|
||||
((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) {
|
||||
if ((node != null) && obj instanceof HopObject) {
|
||||
checkNode();
|
||||
|
||||
return node.contains(((HopObject) obj).node);
|
||||
}
|
||||
|
||||
|
@ -527,6 +577,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
super.put(name, start, value);
|
||||
} else {
|
||||
|
||||
checkNode();
|
||||
|
||||
if ("subnodeRelation".equals(name)) {
|
||||
node.setSubnodeRelation(value == null ? null : value.toString());
|
||||
}
|
||||
|
@ -586,8 +638,13 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
return true;
|
||||
}
|
||||
|
||||
if ((node != null) && (node.get(name) != null)) {
|
||||
return true;
|
||||
if (node != null) {
|
||||
|
||||
checkNode();
|
||||
|
||||
if (node.get(name) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -600,7 +657,11 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
*/
|
||||
public void delete(String name) {
|
||||
super.delete(name);
|
||||
|
||||
if ((node != null)) {
|
||||
|
||||
checkNode();
|
||||
|
||||
node.unset(name);
|
||||
}
|
||||
}
|
||||
|
@ -629,7 +690,19 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
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) {
|
||||
|
||||
checkNode();
|
||||
|
||||
// Everything starting with an underscore is interpreted as internal property
|
||||
if (name.charAt(0) == '_') {
|
||||
return getInternalProperty(name);
|
||||
|
@ -758,6 +831,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
Enumeration enum = node.properties();
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
checkNode();
|
||||
|
||||
while (enum.hasMoreElements())
|
||||
list.add(enum.nextElement());
|
||||
|
||||
|
@ -774,6 +849,8 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
*/
|
||||
public boolean has(int idx, Scriptable start) {
|
||||
if (node != null) {
|
||||
checkNode();
|
||||
|
||||
return (0 <= idx && idx < node.numberOfNodes());
|
||||
}
|
||||
|
||||
|
@ -790,7 +867,10 @@ public class HopObject extends ScriptableObject implements Wrapper {
|
|||
*/
|
||||
public Object get(int idx, Scriptable start) {
|
||||
if (node != null) {
|
||||
checkNode();
|
||||
|
||||
INode n = node.getSubnodeAt(idx);
|
||||
|
||||
if (n != null) {
|
||||
return Context.toObject(n, core.global);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue