diff --git a/source/java/org/alfresco/repo/jscript/Node.java b/source/java/org/alfresco/repo/jscript/Node.java index cc5f23d28c..c29cb17c08 100644 --- a/source/java/org/alfresco/repo/jscript/Node.java +++ b/source/java/org/alfresco/repo/jscript/Node.java @@ -114,9 +114,12 @@ public class Node implements Serializable, Scopeable /** The aspects applied to this node */ private Set aspects = null; - /** The associations from this node */ + /** The target associations for this node */ private ScriptableQNameMap assocs = null; + /** The child associations for this node */ + private ScriptableQNameMap childAssocs = null; + /** The children of this node */ private Node[] children = null; @@ -410,7 +413,7 @@ public class Node implements Serializable, Scopeable * associative array access. This means associations of this node can be access thus: * node.assocs["translations"][0] * - * @return associations as a Map of assoc name to an Array of Nodes. + * @return target associations as a Map of assoc name to an Array of Nodes. */ @SuppressWarnings("unchecked") public Map getAssocs() @@ -450,6 +453,52 @@ public class Node implements Serializable, Scopeable return getAssocs(); } + /** + * Return the child associations from this Node. As a Map of assoc name to an Array of Nodes. + * The Map returned implements the Scriptable interface to allow access to the assoc arrays via JavaScript + * associative array access. This means associations of this node can be access thus: + * node.childAssocs["contains"][0] + * + * @return child associations as a Map of assoc name to an Array of Nodes. + */ + @SuppressWarnings("unchecked") + public Map getChildAssocs() + { + if (this.childAssocs == null) + { + // this Map implements the Scriptable interface for native JS syntax property access + this.childAssocs = new ScriptableQNameMap(this.services.getNamespaceService()); + + List refs = this.nodeService.getChildAssocs(nodeRef); + for (ChildAssociationRef ref : refs) + { + String qname = ref.getTypeQName().toString(); + Node[] nodes = (Node[]) this.childAssocs.get(qname); + if (nodes == null) + { + // first access for the list for this qname + nodes = new Node[1]; + } + else + { + Node[] newNodes = new Node[nodes.length + 1]; + System.arraycopy(nodes, 0, newNodes, 0, nodes.length); + nodes = newNodes; + } + nodes[nodes.length - 1] = newInstance(ref.getChildRef(), this.services, this.scope); + + this.childAssocs.put(ref.getTypeQName().toString(), nodes); + } + } + + return this.childAssocs; + } + + public Map jsGet_childAssocs() + { + return getChildAssocs(); + } + /** * Return all the properties known about this node. The Map returned implements the Scriptable interface to * allow access to the properties via JavaScript associative array access. This means properties of a node can @@ -1796,6 +1845,7 @@ public class Node implements Serializable, Scopeable this.properties = null; this.aspects = null; this.assocs = null; + this.childAssocs = null; this.children = null; this.displayPath = null; this.isDocument = null; diff --git a/source/java/org/alfresco/repo/template/TemplateNode.java b/source/java/org/alfresco/repo/template/TemplateNode.java index 383633b14c..0f5d103972 100644 --- a/source/java/org/alfresco/repo/template/TemplateNode.java +++ b/source/java/org/alfresco/repo/template/TemplateNode.java @@ -72,9 +72,12 @@ public class TemplateNode extends BasePermissionsNode private static Log logger = LogFactory.getLog(TemplateNode.class); - /** All associations from this node */ + /** Target associations from this node */ private Map> assocs = null; + /** The child associations from this node */ + private Map> childAssocs = null; + /** Cached values */ protected NodeRef nodeRef; private String name; @@ -246,6 +249,32 @@ public class TemplateNode extends BasePermissionsNode return this.assocs; } + /** + * @return The child associations for this Node. As a Map of assoc name to a List of TemplateNodes. + */ + public Map> getChildAssocs() + { + if (this.childAssocs == null) + { + List refs = this.services.getNodeService().getChildAssocs(this.nodeRef); + this.childAssocs = new QNameMap>(this.services.getNamespaceService()); + for (ChildAssociationRef ref : refs) + { + String qname = ref.getTypeQName().toString(); + List nodes = this.childAssocs.get(qname); + if (nodes == null) + { + // first access for the list for this qname + nodes = new ArrayList(4); + this.childAssocs.put(ref.getTypeQName().toString(), nodes); + } + nodes.add( new TemplateNode(ref.getChildRef(), this.services, this.imageResolver) ); + } + } + + return this.childAssocs; + } + /** * @return true if the node is currently locked */