package org.exoplatform.navigation.webui;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.exoplatform.commons.utils.HTMLEntityEncoder;
import org.exoplatform.portal.mop.Described.State;
import org.exoplatform.portal.mop.Visibility;
import org.exoplatform.portal.mop.navigation.NodeChangeListener;
import org.exoplatform.portal.mop.navigation.NodeState;
import org.exoplatform.portal.mop.page.PageKey;
import org.exoplatform.portal.mop.user.UserNavigation;
import org.exoplatform.portal.mop.user.UserNode;
import org.exoplatform.portal.webui.util.Util;
/**
* A wrapper class of {@link UserNode} for manipulation in WebUI part
*
* @author <a href="mailto:trong.tran@exoplatform.com">Trong Tran</a>
* @version $Revision$
*/
public class TreeNode implements NodeChangeListener<UserNode> {
private Map<String, TreeNode> caches;
private UserNavigation nav;
private UserNode node;
private TreeNode rootNode;
private boolean deleteNode = false;
private boolean cloneNode = false;
private String id;
private List<TreeNode> children;
private Map<Locale, State> i18nizedLabels;
public TreeNode(UserNavigation nav, UserNode node) {
this(nav, node, null);
this.rootNode = this;
this.caches = new HashMap<String, TreeNode>();
addToCached(this);
}
private TreeNode(UserNavigation nav, UserNode node, TreeNode rootNode) {
this.rootNode = rootNode;
this.nav = nav;
this.node = node;
}
public List<TreeNode> getChildren() {
if (children == null) {
children = new LinkedList<TreeNode>();
for (UserNode child : node.getChildren()) {
String key = child.getId() == null ? String.valueOf(child.hashCode()) : child.getId();
TreeNode node = findNode(key);
if (node == null) {
throw new IllegalStateException("Can' find node " + child.getURI() + " in the cache");
}
children.add(node);
}
}
return children;
}
public TreeNode getChild(String name) {
UserNode child = node.getChild(name);
if (child == null) {
return null;
}
return findNode(child.getId() == null ? String.valueOf(child.hashCode()) : child.getId());
}
public boolean removeChild(TreeNode child) {
children = null;
if (child == null) {
return false;
}
removeFromCached(child);
return node.removeChild(child.getName());
}
public TreeNode getParent() {
UserNode parent = node.getParent();
if (parent == null)
return null;
return findNode(parent.getId() == null ? String.valueOf(parent.hashCode()) : parent.getId());
}
public TreeNode getChild(int childIndex) throws IndexOutOfBoundsException {
UserNode child = node.getChild(childIndex);
if (child == null) {
return null;
}
return findNode(child.getId() == null ? String.valueOf(child.hashCode()) : child.getId());
}
public TreeNode addChild(String childName) {
children = null;
UserNode child = node.addChild(childName);
return addToCached(new TreeNode(nav, child, this.rootNode));
}
public void addChild(TreeNode child) {
TreeNode oldParent = child.getParent();
if (oldParent != null) {
oldParent.children = null;
}
children = null;
this.node.addChild(child.getNode());
}
public void addChild(int index, TreeNode child) {
TreeNode oldParent = child.getParent();
if (oldParent != null) {
oldParent.children = null;
}
children = null;
node.addChild(index, child.getNode());
}
public TreeNode findNode(String nodeID) {
return this.rootNode.caches.get(nodeID);
}
public UserNode getNode() {
return node;
}
public UserNavigation getPageNavigation() {
return nav;
}
public boolean isDeleteNode() {
return deleteNode;
}
public void setDeleteNode(boolean deleteNode) {
this.deleteNode = deleteNode;
}
public boolean isCloneNode() {
return cloneNode;
}
public void setCloneNode(boolean b) {
cloneNode = b;
}
public String getPageRef() {
return node.getPageRef() != null ? node.getPageRef().format() : null;
}
public String getId() {
if (this.id == null) {
this.id = node.getId() == null ? String.valueOf(node.hashCode()) : node.getId();
}
return this.id;
}
public String getURI() {
return node.getURI();
}
public String getIcon() {
return node.getIcon();
}
public void setIcon(String icon) {
node.setIcon(icon);
}
public String getEncodedResolvedLabel() {
if (getLabel() == null) {
if (i18nizedLabels != null) {
Locale locale = Util.getPortalRequestContext().getLocale();
for (Locale key : i18nizedLabels.keySet()) {
if (key.equals(locale)) {
String label = i18nizedLabels.get(key).getName();
if (label == null || label.trim().length() == 0) {
return node.getName();
}
return HTMLEntityEncoder.getInstance().encode(label);
}
}
}
}
String encodedLabel = node.getEncodedResolvedLabel();
return encodedLabel == null ? "" : encodedLabel;
}
public String getName() {
return node.getName();
}
public void setName(String name) {
node.setName(name);
}
public String getLabel() {
return node.getLabel();
}
public void setLabel(String label) {
node.setLabel(label);
}
public Visibility getVisibility() {
return node.getVisibility();
}
public void setVisibility(Visibility visibility) {
node.setVisibility(visibility);
}
public long getStartPublicationTime() {
return node.getStartPublicationTime();
}
public void setStartPublicationTime(long startPublicationTime) {
node.setStartPublicationTime(startPublicationTime);
}
public long getEndPublicationTime() {
return node.getEndPublicationTime();
}
public void setEndPublicationTime(long endPublicationTime) {
node.setEndPublicationTime(endPublicationTime);
}
public boolean isRestrictOutsidePublicationWindow() {
return node.isRestrictOutsidePublicationWindow();
}
public void setRestrictOutsidePublicationWindow(boolean restrictOutsidePublicationWindow) {
node.setRestrictOutsidePublicationWindow(restrictOutsidePublicationWindow);
}
public void setPageRef(String pageRef) {
node.setPageRef(pageRef != null ? PageKey.parse(pageRef) : null);
}
public String getResolvedLabel() {
String resolvedLabel = node.getResolvedLabel();
return resolvedLabel == null ? "" : resolvedLabel;
}
public boolean hasChildrenRelationship() {
return node.hasChildrenRelationship();
}
public int getChildrenCount() {
return node.getChildrenCount();
}
private TreeNode addToCached(TreeNode node) {
if (node == null) {
return null;
}
if (findNode(node.getId()) != null) {
return node;
}
this.rootNode.caches.put(node.getId(), node);
for (UserNode child : node.getNode().getChildren()) {
addToCached(new TreeNode(nav, child, this.rootNode));
}
return node;
}
private TreeNode removeFromCached(TreeNode node) {
if (node == null) {
return null;
}
this.rootNode.caches.remove(node.getId());
if (node.hasChildrenRelationship()) {
for (TreeNode child : node.getChildren()) {
removeFromCached(child);
}
}
return node;
}
@Override
public void onAdd(UserNode target, UserNode parent, UserNode previous) {
addToCached(new TreeNode(this.nav, target, this.rootNode));
findNode(parent.getId()).children = null;
}
@Override
public void onCreate(UserNode target, UserNode parent, UserNode previous, String name) {
}
@Override
public void onRemove(UserNode target, UserNode parent) {
removeFromCached(findNode(target.getId()));
findNode(parent.getId()).children = null;
}
@Override
public void onDestroy(UserNode target, UserNode parent) {
}
@Override
public void onRename(UserNode target, UserNode parent, String name) {
}
@Override
public void onUpdate(UserNode target, NodeState state) {
}
@Override
public void onMove(UserNode target, UserNode from, UserNode to, UserNode previous) {
TreeNode fromTreeNode = findNode(from.getId());
TreeNode toTreeNode = findNode(to.getId());
fromTreeNode.children = null;
toTreeNode.children = null;
}
public void setI18nizedLabels(Map<Locale, State> labels) {
this.i18nizedLabels = labels;
}
public Map<Locale, State> getI18nizedLabels() {
return i18nizedLabels;
}
}