001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS <http://nuxeo.com> and others 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Jean-Marc Orliaguet, Chalmers 011 * 012 * $Id$ 013 */ 014 015package org.nuxeo.theme.nodes; 016 017import java.util.ArrayList; 018import java.util.List; 019 020public abstract class AbstractNode implements Node { 021 022 private Node parentNode; 023 024 private List<Node> childrenNodes = new ArrayList<Node>(); 025 026 public void clearParent() { 027 parentNode = null; 028 } 029 030 public void setParent(Node parent) throws NodeException { 031 if (equals(parent)) { 032 throw new NodeException(String.format("A node cannot be made a parent of itself: %s.", this)); 033 } 034 if (parent != null && parent.isChildOf(this)) { 035 throw new NodeException(String.format("Cycle detected while trying to make %s a parent of %s.", parent, 036 this)); 037 } 038 if (parentNode != null) { 039 List<Node> siblings = parentNode.getChildren(); 040 siblings.remove(this); 041 parentNode.setChildren(siblings); 042 } 043 parentNode = parent; 044 } 045 046 public Node getParent() { 047 return parentNode; 048 } 049 050 public Node addChild(Node node) throws NodeException { 051 if (equals(node)) { 052 throw new NodeException(String.format("A node cannot be made a child of itself: %s.", this)); 053 } 054 if (isChildOf(node)) { 055 throw new NodeException(String.format("Cycle detected while trying to add child %s to %s.", node, this)); 056 } 057 childrenNodes.add(node); 058 node.setParent(this); 059 return node; 060 } 061 062 public void removeChild(Node node) throws NodeException { 063 if (!childrenNodes.contains(node)) { 064 throw new NodeException(String.format("Trying to remove unexisting child %s of %s", node, this)); 065 } 066 childrenNodes.remove(node); 067 node.setParent(null); 068 } 069 070 public List<Node> getChildren() { 071 return childrenNodes; 072 } 073 074 public void setChildren(List<Node> children) throws NodeException { 075 for (Node child : children) { 076 if (equals(child)) { 077 throw new NodeException(String.format("Node %s cannot be made a child of itself", child)); 078 } 079 if (isChildOf(child)) { 080 throw new NodeException(String.format("Cycle detected while trying to set children of %s.", this)); 081 } 082 } 083 childrenNodes = children; 084 } 085 086 public abstract NodeTypeFamily getNodeTypeFamily(); 087 088 public boolean isLeaf() { 089 return getNodeTypeFamily() == NodeTypeFamily.LEAF; 090 } 091 092 public Integer getOrder() { 093 Integer order = null; 094 if (parentNode != null) { 095 order = parentNode.getChildren().indexOf(this); 096 } 097 return order; 098 } 099 100 public void setOrder(Integer order) throws NodeException { 101 if (order == null) { 102 throw new NodeException(String.format("Cannot set node order to null on %s", this)); 103 } 104 if (parentNode == null) { 105 throw new NodeException(String.format("Cannot set order on node %s unless it has a parent", this)); 106 } 107 List<Node> siblings = parentNode.getChildren(); 108 siblings.remove(this); 109 if (order < 0 || (order > 0 && order > siblings.size())) { 110 throw new NodeException(String.format("Incorrect node order value (%s) for %s", order, this)); 111 } 112 siblings.add(order, this); 113 parentNode.setChildren(siblings); 114 } 115 116 public void moveTo(Node container, Integer order) throws NodeException { 117 setParent(container); 118 setOrder(order); 119 } 120 121 public void insertAfter(Node node) throws NodeException { 122 node.getParent().addChild(this); 123 moveTo(node.getParent(), node.getOrder() + 1); 124 } 125 126 public boolean hasSiblings() { 127 if (parentNode == null) { 128 return false; 129 } 130 return parentNode.getChildren().size() > 1; 131 } 132 133 public Node getNextNode() { 134 int order = getOrder(); 135 List<Node> siblings = parentNode.getChildren(); 136 if (order + 1 >= siblings.size()) { 137 return null; 138 } 139 return siblings.get(order + 1); 140 } 141 142 public Node getPreviousNode() { 143 int order = getOrder(); 144 if (order == 0) { 145 return null; 146 } 147 List<Node> siblings = parentNode.getChildren(); 148 return siblings.get(order - 1); 149 } 150 151 public boolean hasChildren() { 152 return !childrenNodes.isEmpty(); 153 } 154 155 public boolean isChildOf(Node node) { 156 boolean res = false; 157 Node parent = parentNode; 158 while (parent != null) { 159 if (parent == node) { 160 res = true; 161 break; 162 } 163 parent = parent.getParent(); 164 } 165 return res; 166 } 167 168 public void removeDescendants() throws NodeException { 169 for (Node child : childrenNodes) { 170 child.removeDescendants(); 171 child.clearParent(); 172 } 173 childrenNodes.clear(); 174 } 175 176 public List<Node> getDescendants() { 177 List<Node> descendants = new ArrayList<Node>(); 178 collectDescendants(descendants); 179 return descendants; 180 } 181 182 public void collectDescendants(List<Node> nodes) { 183 for (Node child : childrenNodes) { 184 nodes.add(child); 185 child.collectDescendants(nodes); 186 } 187 } 188 189}