1 package com.sri.common.taglib;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.List;
7
8 /***
9 * Default implementation of the tree node.
10 *
11 * @author Michael Rimov
12 */
13 public class DefaultTreeNode implements TreeNode, Serializable {
14
15 /***
16 *
17 */
18 private static final long serialVersionUID = 1L;
19
20
21 /***
22 * Sets the maximum label length and truncates if the label is to long
23 */
24 public static final int MAXIMUM_LABEL_LENGTH = 60;
25
26
27 /***
28 * Field for node label.
29 */
30 private String label;
31
32 /***
33 * Field for node link.
34 */
35 private String link;
36
37
38 /***
39 * Field for node children.
40 */
41 private List children;
42
43 /***
44 * True if the node is selected.
45 */
46 private boolean selected;
47
48 /***
49 * Parent tree node.
50 */
51 private final TreeNode parent;
52
53 /***
54 * The selected style.
55 */
56 private String selectedStyle;
57
58 /***
59 * The unselected style.
60 */
61 private String unselectedStyle;
62
63 /***
64 * Default constructor.
65 */
66 public DefaultTreeNode() {
67 parent = null;
68 }
69
70
71 /***
72 * Constructor that takes a parent node. Sets this node's parent as well
73 * as adds the node to the parent.
74 *
75 * @param parentNode TreeNode
76 */
77 public DefaultTreeNode(final DefaultTreeNode parentNode) {
78 assert parentNode != null;
79 this.parent = parentNode;
80 parentNode.addNested(this);
81 }
82
83 /***
84 * Retrieve the Label of the tree node.
85 *
86 * @return String the label
87 */
88 public String getLabel() {
89 return label;
90 }
91
92 /***
93 * Retrieve the link if the node is clicked.
94 *
95 * @return String url for the link of the node.
96 */
97 public String getLink() {
98 return link;
99 }
100
101
102 /***
103 * Retrieve the CSS style for the node when it is selected. (Or for folders,
104 * when its children are selected or it is open)
105 *
106 * @return String
107 */
108 public String getSelectedStyle() {
109 return selectedStyle;
110 }
111
112 /***
113 * Retrieve the CSS style for the node when it is unselected. (Or for
114 * folders, when it is closed)
115 *
116 * @return String
117 */
118 public String getUnselectedStyle() {
119 return unselectedStyle;
120 }
121
122
123 /***
124 * Retrieve the parent to allow bi-direction navigation through the tree.
125 *
126 * @return TreeNode
127 */
128 public TreeNode getParent() {
129 return parent;
130 }
131
132
133 /***
134 * Retrieve all children (may be an empty array) if no children.
135 *
136 * @return TreeNode[]
137 */
138 public TreeNode[] getNested() {
139 if (!isParent()) {
140 return TreeNode.NO_CHILDREN;
141 }
142
143 return (TreeNode[]) children.toArray(new TreeNode[children.size()]);
144 }
145
146 /***
147 * Retrieves whether or not this is a parent node. In other words,
148 * are there children.
149 *
150 * @return boolean true if there are child nodes.
151 */
152 public boolean isParent() {
153 if (children == null || children.size() == 0) {
154 return false;
155 }
156
157 return true;
158 }
159
160 /***
161 * Url of the icon associated with the node. (Optional)
162 */
163 private String iconUrl;
164
165
166 /***
167 * {@inheritDoc}
168 *
169 * @return String
170 */
171 public String getIconUrl() {
172 return iconUrl;
173 }
174
175 /***
176 * Sets the icon url.
177 *
178 * @param newValue String
179 */
180 public void setIconUrl(final String newValue) {
181 iconUrl = newValue;
182 }
183
184 /***
185 * Adds a nested tree node to this node.
186 *
187 * @param node TreeNode
188 */
189 public void addNested(final TreeNode node) {
190 if (children == null) {
191 children = new ArrayList();
192 }
193
194 children.add(node);
195 }
196
197 /***
198 * Sets the label for the node.
199 *
200 * @param nodeLabel String the label of the node.
201 */
202 public void setLabel(final String nodeLabel) {
203 if (nodeLabel != null) {
204 String labelToSet = nodeLabel.trim();
205
206
207 if (labelToSet.indexOf("<br />") > 0) {
208 labelToSet = labelToSet.substring(0, labelToSet.indexOf("<br />")) + "... (more)";
209 }
210
211 if (labelToSet.indexOf('\n') > 0) {
212 labelToSet = labelToSet.substring(0, labelToSet.indexOf('\n')) + "... (more)";
213 }
214
215 if (labelToSet.length() > MAXIMUM_LABEL_LENGTH) {
216 labelToSet = labelToSet.substring(0, MAXIMUM_LABEL_LENGTH) + "... (more)";
217
218 }
219
220 this.label = labelToSet;
221 } else {
222 this.label = nodeLabel;
223 }
224 }
225
226 /***
227 * Sets the link for the node. May be optional if there are subnodes.
228 *
229 * @param nodeLink String
230 */
231 public void setLink(final String nodeLink) {
232 this.link = nodeLink;
233 }
234
235
236 /***
237 * {@inheritDoc}
238 *
239 * @return boolean
240 */
241 public boolean isSelected() {
242 return selected;
243 }
244
245 /***
246 * Sets whether the node is selected or not.
247 *
248 * @param selectionValue boolean
249 */
250 public void setSelected(final boolean selectionValue) {
251 selected = selectionValue;
252 if (parent != null) {
253 parent.setSelected(selectionValue);
254 }
255 }
256
257 /***
258 * Sets the node selected style.
259 *
260 * @param nodeSelectedStyle String
261 */
262 public void setSelectedStyle(final String nodeSelectedStyle) {
263 this.selectedStyle = nodeSelectedStyle;
264 }
265
266 /***
267 * Sets the nodes unselected style.
268 *
269 * @param nodeUnselectedStyle String
270 */
271 public void setUnselectedStyle(final String nodeUnselectedStyle) {
272 this.unselectedStyle = nodeUnselectedStyle;
273 }
274
275 /***
276 * {@inheritDoc}
277 */
278 public void expandAllFolders() {
279 if (this.isParent()) {
280 this.setSelected(true);
281 for (Iterator i = this.children.iterator(); i.hasNext();) {
282 TreeNode oneNode = (TreeNode) i.next();
283 if (oneNode.getNested() != TreeNode.NO_CHILDREN) {
284 oneNode.expandAllFolders();
285 }
286 }
287 }
288
289 }
290
291 /***
292 * {@inheritDoc}
293 */
294 public void collapseAllFolders() {
295 this.setSelected(false);
296 }
297
298 }