001    /*
002     * BeanTreeContent.java
003     *
004     * Created on February 4, 2007, 12:54 PM
005     */
006    
007    package net.sf.tacos.model.impl;
008    
009    import java.util.Collection;
010    import java.util.Collections;
011    import java.util.HashMap;
012    import java.util.Iterator;
013    import java.util.List;
014    import java.util.Map;
015    import net.sf.tacos.model.ITreeContentProvider;
016    import org.apache.commons.beanutils.PropertyUtils;
017    
018    /**
019     * A useful {@link ITreeContentProvider} that can recreate the tree structure
020     * using a root bean (of any type) and the property name that will return its
021     * children (a {@link Collection} of the same type).
022     * 
023     * This class is meant to be used for quickly prototyping trees. You're advised to
024     * create your own implementation in order to tweek performance issues.
025     * 
026     * @author andyhot
027     */
028    public class BeanWithChildrenTreeContentProvider implements ITreeContentProvider {
029        
030        private Object root;
031        private String childProperty;
032        private Map parents;
033        
034        public BeanWithChildrenTreeContentProvider(Object root, String childProperty) {
035            this.root = root;
036            this.childProperty = childProperty;
037            buildParents();
038        }
039        
040        private void buildParents() {
041            parents = new HashMap();
042            appendChildren(root, parents);
043        }
044        
045        private void appendChildren(Object base, Map map) {
046            for (Iterator iter = getChildren(base).iterator(); iter.hasNext();) {
047                Object object = iter.next();
048                map.put(object, base);
049                appendChildren(object, map);
050            }
051        }    
052        
053        public Collection getChildren(Object parentElement) {
054            try {
055                Collection children = (Collection) PropertyUtils.getProperty(parentElement, childProperty);
056                if (children == null)
057                    children = Collections.emptyList();
058                return children;
059            } catch (Exception e) {
060                throw new RuntimeException("Error getting property", e);
061            }           
062        }
063    
064        public boolean hasChildren(Object parentElement) {
065            return getChildren(parentElement).size() > 0;
066        }
067    
068        public Object getParent(Object childElement) {
069            return parents.get(childElement);        
070        }
071    
072        public List getElements() {        
073            return Collections.singletonList(root);
074        }
075    
076    }