View Javadoc

1   /*
2    * Created on Oct 20, 2004
3    */
4   package org.extremecomponents.tree.model;
5   
6   import java.util.ArrayList;
7   import java.util.Iterator;
8   import java.util.List;
9   
10  import org.apache.commons.beanutils.BeanUtils;
11  import org.apache.commons.beanutils.PropertyUtils;
12  
13  import org.apache.commons.logging.Log;
14  import org.apache.commons.logging.LogFactory;
15  
16  import org.extremecomponents.table.model.ParameterRegistry;
17  
18  import org.extremecomponents.tree.bean.TreeNode;
19  
20  
21  /***
22   * org.extremecomponents.tree.model.TreeModelUtils.java -
23   *
24   * @author phorn
25   */
26  public class TreeModelUtils
27  {
28  	private static Log logger = LogFactory.getLog(TreeModelUtils.class);
29  
30  	/***
31  	 * Recursively loads the tree structure into the treeList attribute and sets the
32  	 * treeList as the collection to use.
33  	 * @param model
34  	 * @param inputList
35  	 * @throws Exception
36  	 */
37  	public static List loadTreeStructure(TreeModel model, List inputList) throws Exception
38  	{
39  		List result = new ArrayList();
40  
41  		List searchList = new ArrayList();
42  		searchList.addAll(inputList);
43  
44  		for (Iterator iter = searchList.iterator(); iter.hasNext();)
45  		{
46  			Object bean = iter.next();
47  
48  			if (BeanUtils.getProperty(bean, model.getParentAttribute()) == null)
49  			{
50  				//Load up the top level parents
51  				TreeNode node = new TreeNode(bean, getBeanId(model, bean), 0);
52  				result.add(node);
53  				iter.remove();
54  				loadChildren(model, result, searchList, node, 0);
55  			}
56  		}
57  
58  		return result;
59  	}
60  
61  	/***
62  	 * @param model
63  	 * @param displayList
64  	 * @param searchList
65  	 * @param node
66  	 * @param currentDepth
67  	 * @throws Exception
68  	 */
69  	public static void loadChildren(TreeModel model, List displayList, List searchList, TreeNode node, int currentDepth) throws Exception
70  	{
71  		currentDepth++;
72  
73  		List subList = new ArrayList();
74  		subList.addAll(searchList);
75  
76  		Object id = node.getIdentifier();
77  		String key = getNodeKey(model, id);
78  
79  		if (model.getOpenNodes().get(key) != null)
80  		{
81  			node.setOpen(true);
82  		}
83  		else
84  		{
85  			node.setOpen(false);
86  		}
87  
88  		for (Iterator iter = subList.iterator(); iter.hasNext();)
89  		{
90  			Object bean = iter.next();
91  
92  			if (nodeIsBeanParent(model, node, bean))
93  			{
94  				TreeNode childNode = new TreeNode(bean, getBeanId(model, bean), currentDepth);
95  				node.addChild(childNode);
96  				childNode.setParent(node);
97  				iter.remove();
98  
99  				if (isOpen(model, node, true))
100 				{
101 					displayList.add(childNode);
102 				}
103 
104 				loadChildren(model, displayList, subList, childNode, currentDepth); //Recurse
105 			}
106 		}
107 	}
108 
109 	/***
110 	 * Used by the filter function to add back the filtered out parents.
111 	 * @param model
112 	 * @param searchList
113 	 * @return
114 	 * @throws Exception
115 	 */
116 	public static List findParents(TreeModel model, List searchList) throws Exception
117 	{
118 		logger.debug("TreeModel.findParents()");
119 
120 		List result = new ArrayList();
121 
122 		for (Iterator iter = searchList.iterator(); iter.hasNext();)
123 		{
124 			Object bean = iter.next();
125 
126 			if (!result.contains(bean))
127 			{
128 				result.add(bean);
129 			}
130 
131 			findBeanParents(model, result, bean);
132 		}
133 
134 		return result;
135 	}
136 
137 	/***
138 	 * Recursive call used by the filter function to add back the filtered out parents.
139 	 * @param model
140 	 * @param parents
141 	 * @param bean
142 	 * @throws Exception
143 	 */
144 	public static void findBeanParents(TreeModel model, List parents, Object bean) throws Exception
145 	{
146 		Object parent = PropertyUtils.getProperty(bean, model.getParentAttribute());
147 
148 		if (parent == null)
149 		{
150 			return;
151 		}
152 		else
153 		{
154 			if (!parents.contains(parent))
155 			{
156 				parents.add(parent);
157 				findBeanParents(model, parents, parent);
158 			}
159 		}
160 	}
161 
162 	/***
163 	 * Used by the filter function to add back the filtered out children.
164 	 * @param model
165 	 * @param displayList
166 	 * @throws Exception
167 	 */
168 	public static void addClosedChildren(TreeModel model, List displayList) throws Exception
169 	{
170 		logger.debug("TreeModel.addClosedChildren()");
171 
172 		List parents = new ArrayList();
173 		parents.addAll(displayList);
174 
175 		for (Iterator iter = parents.iterator(); iter.hasNext();)
176 		{
177 			TreeNode node = (TreeNode) iter.next();
178 
179 			if ((node.getChildren() == null) || (node.getChildren().size() == 0))
180 			{
181 				addChildren(model, displayList, node);
182 			}
183 		}
184 	}
185 
186 	/***
187 	 * Recursive call used by the filter function to add back the filtered out children
188 	 * but keeps them collapsed unless they have been openned manually be the open parameter.
189 	 * @param model
190 	 * @param displayList
191 	 * @param node
192 	 * @throws Exception
193 	 */
194 	public static void addChildren(TreeModel model, List displayList, TreeNode node) throws Exception
195 	{
196 		for (Iterator iter = model.getTableCollection().iterator(); iter.hasNext();)
197 		{
198 			Object bean = iter.next();
199 
200 			if (nodeIsBeanParent(model, node, bean))
201 			{
202 				TreeNode childNode = new TreeNode(bean, getBeanId(model, bean), node.getDepth() + 1);
203 				node.addChild(childNode);
204 
205 				Object id = node.getIdentifier();
206 				String openParam = (String) model.getOpenNodes().get(getNodeKey(model, id));
207 
208 				if (isOpen(model, node, false) || "true".equals(openParam))
209 				{
210 					node.setOpen(true);
211 
212 					int parentPosition = displayList.indexOf(node);
213 					displayList.add(parentPosition + 1, childNode);
214 				}
215 
216 				addChildren(model, displayList, childNode);
217 			}
218 		}
219 	}
220 
221 	/***
222 	 * @param model
223 	 * @param node
224 	 * @param bean
225 	 * @return
226 	 * @throws Exception
227 	 */
228 	public static boolean nodeIsBeanParent(TreeModel model, TreeNode node, Object bean) throws Exception
229 	{
230 		Object parent = PropertyUtils.getProperty(bean, model.getParentAttribute());
231 
232 		if (parent == null)
233 		{
234 			return false;
235 		}
236 
237 		Object nodeId = node.getIdentifier();
238 		Object parentId = getBeanId(model, parent);
239 
240 		return (node.getBean().equals(parent) || nodeId.equals(parentId));
241 	}
242 
243 	/***
244 	 * @param model
245 	 * @param bean
246 	 * @return
247 	 * @throws Exception
248 	 */
249 	public static Object getBeanId(TreeModel model, Object bean) throws Exception
250 	{
251 		return PropertyUtils.getProperty(bean, model.getIdentifier());
252 	}
253 
254 	/***
255 	 * Find out if the node and all parents are open.
256 	 * @param model
257 	 * @param node
258 	 * @param filterControlled
259 	 * @return
260 	 */
261 	public static boolean isOpen(TreeModel model, TreeNode node, boolean filterControlled)
262 	{
263 		if (filterControlled && model.getFilterHandler().doFilter() && !model.getFilterHandler().doClear())
264 		{
265 			node.setOpen(true);
266 
267 			return true;
268 		}
269 
270 		if (!node.isOpen())
271 		{
272 			return false;
273 		}
274 
275 		if (node.getParent() == null)
276 		{
277 			return true;
278 		}
279 
280 		return isOpen(model, node.getParent(), filterControlled);
281 	}
282 
283 	/***
284 	 * @param model
285 	 * @param id value of the node.
286 	 * @return Returns the parameter key used to indicate this node is open.
287 	 */
288 	public static String getNodeKey(TreeModel model, Object id)
289 	{
290 		return model.getTableKey() + ParameterRegistry.OPEN + id;
291 	}
292 }