/** * Gets the descendant values.<p> * * @param path the path * @return the descendant values */ public List<V> getDescendantValues(List<P> path) { CmsPathTree<P, V> node = findNode(path); List<V> result = Lists.newArrayList(); if (node != null) { node.collectEntries(result); } return result; }
/** * Sets the value for the sub-path given, starting from this node.<p> * * @param path the path * @param value the value to set */ public void setValue(List<P> path, V value) { ensureNode(path).setValue(value); }
/** * Gets the child values for the given path.<p> * * @param path the path * * @return the child values */ public List<V> getChildValues(List<P> path) { CmsPathTree<P, V> descendant = findNode(path); if (descendant != null) { return descendant.getChildValues(); } else { return Collections.emptyList(); } }
/** * Returns the node for the given path, creating all nodes on the way if they don't already exist.<p> * * @param path the path for which to make sure a node exists * * @return the node for the path */ private CmsPathTree<P, V> ensureNode(List<P> path) { List<P> pathToConsume = Lists.newLinkedList(path); CmsPathTree<P, V> lastExistingNode = findNodeInternal(pathToConsume); CmsPathTree<P, V> currentNode = lastExistingNode; for (P pathPart : pathToConsume) { CmsPathTree<P, V> child = new CmsPathTree<P, V>(); currentNode.m_children.put(pathPart, child); currentNode = child; } return currentNode; }
/** * Gets the value for the sub-path given, starting from this node.<p> * * @param path the path * @return the value for the node */ public V getValue(List<P> path) { CmsPathTree<P, V> node = findNode(path); if (node != null) { return node.m_value; } else { return null; } }
/** * Collect all descendant values in the given collection.<p> * * @param target the collection in which to store the descendant values */ public void collectEntries(Collection<V> target) { if (m_value != null) { target.add(m_value); } for (CmsPathTree<P, V> child : m_children.values()) { child.collectEntries(target); } }
/** * Finds the node for the given path, and returns it or null if node was found.<p> * * @param path the path * @return the node for the path */ public CmsPathTree<P, V> findNode(List<P> path) { List<P> pathToConsume = Lists.newLinkedList(path); CmsPathTree<P, V> descendant = findNodeInternal(pathToConsume); if (!pathToConsume.isEmpty()) { return null; } else { return descendant; } }
/** * Gets the values for the descendants of the path, including the path itself.<p> * * @param path the path * @return the descendant values for the path */ public List<V> getDescendantValues(String path) { return m_tree.getDescendantValues(splitPath(path)); }
/** * Adds an element for the given path, overwriting the previous element for that path if there is one.<p> * * @param path the path * @param value the element to add */ public void add(String path, V value) { m_tree.setValue(splitPath(path), value); }
/** * Gets the values for the direct children of the given path.<p> * * @param path the path * @return the child values */ public List<V> getChildValues(String path) { return m_tree.getChildValues(splitPath(path)); }
/** * Tries to traverse the descendants of this node along the given path, * and returns the last existing node along that path.<p> * * The given path is modified so that only the part of the path for which no nodes can be found * remains.<p> * * @param pathToConsume the path to find (will be modified by this method) * @return the last node found along the descendant chain for the path */ private CmsPathTree<P, V> findNodeInternal(List<P> pathToConsume) { Iterator<P> iter = pathToConsume.iterator(); CmsPathTree<P, V> currentNode = this; while (iter.hasNext()) { CmsPathTree<P, V> child = currentNode.getChild(iter.next()); if (child != null) { iter.remove(); currentNode = child; } else { return currentNode; } } return currentNode; }