/* vim: set ts=2 et sw=2 cindent fo=qroca: */ package com.globant.katari.menu.dropdown.application; import org.apache.commons.lang.Validate; import java.util.List; import java.util.LinkedList; import com.globant.katari.core.web.MenuNode; import com.globant.katari.core.security.MenuAccessFilterer; /** A menu tree accesible by the logged in user. */ public class UserMenuNode { /** The node to display. * * It is never null. */ private MenuNode menuNode; /** The childre of this node. * * This is never null. */ private List<UserMenuNode> children = new LinkedList<UserMenuNode>(); /** Create a UserMenuNode for a menu node. * * The UserMenuNode contains the tree of all menu items accesible by the * user, as determined by the filterer. * * @param theMenuNode The menu node. It cannot be null. * * @param filterer Decides if a leaf node is accessible or not. This cannot * be null. */ public UserMenuNode(final MenuNode theMenuNode, final MenuAccessFilterer filterer) { Validate.notNull(theMenuNode, "A menu node must be provided to create a" + " display node"); Validate.notNull(filterer, "The menu filterer cannot be null"); menuNode = theMenuNode; children = getChildren(menuNode, filterer); } /** Create a UserMenuNode for a leaf menu node. * * @param leafNode The menu node. It must be a non null leaf node. */ private UserMenuNode(final MenuNode leafNode) { Validate.notNull(leafNode, "The menu node cannot be null."); Validate.isTrue(leafNode.isLeaf(), "The menu node must be a leaf."); menuNode = leafNode; } /** Create a UserMenuNode for a non-leaf menu node, with some children. * * @param node The menu node. It cannot be a leaf node and it cannot be null. * * @param theChildren The wrapped children of the node. It cannot be null. */ private UserMenuNode(final MenuNode node, final List<UserMenuNode> theChildren) { Validate.notNull(node, "The menu node cannot be null."); Validate.isTrue(!node.isLeaf(), "The menu node cannot be a leaf."); Validate.notNull(theChildren, "The children nodes cannot be null."); menuNode = node; children = theChildren; } /** Wraps the user accessible children of the provided parent node in a * UserMenuNode. * * This class returns a list of UserMenuNode that wraps the children of the * parent node, keeping its order. The resulting list only contains nodes * that has, as descendent, at least one accessible leaf node, as decided by * the filterer. * * @param parentNode The node that contains the children to wrap. It must be * a non null, non leaf node. * * @param filterer Decides if a leaf node is accessible or not. This cannot * be null. * * @return a list of UserMenuNode that wraps the accessible children of * parentNode. It never returns null. */ private List<UserMenuNode> getChildren(final MenuNode parentNode, final MenuAccessFilterer filterer) { Validate.notNull(parentNode, "The menu node cannot be null."); Validate.isTrue(!parentNode.isLeaf(), "The menu node cannot be a leaf."); List<UserMenuNode> result = new LinkedList<UserMenuNode>(); List<UserMenuNode> currentChildren; for (MenuNode node : parentNode.getChildNodes()) { if (node.isLeaf()) { if (filterer.isAccessible(node)) { result.add(new UserMenuNode(node)); } } else { currentChildren = getChildren(node, filterer); if (currentChildren.size() > 0) { result.add(new UserMenuNode(node, currentChildren)); } } } return result; } /** Obtains the wrapped menu node. * * @return the menu node. It never returns null. */ public MenuNode getMenuNode() { return menuNode; } /** Obtains the wrapped children of this user menu node. * * @return the list of children, never null. */ public List<UserMenuNode> getChildren() { return children; } }