package cern.gp.explorer.test.helpers; import cern.gp.nodes.NodeFactory; import cern.gp.nodes.children.ChildrenListManager; import cern.gp.nodes.children.NodeList; import java.beans.IntrospectionException; import java.lang.reflect.Constructor; import java.util.Comparator; /** * an implementation of the ChildrenListManager to be used for testing and quick hacks. * It recursively adds children of the same type to the parent, up to the number of * children specified. * This class is typically used in the following way: * <pre> * GPNode root = NodeFactory.createNode(new SimpleDemoBean("parent"), new RecursiveChildrenListManager(10, 3)); * expl = new TreeExplorer(); * expl.setRootNode(root); * </pre> * This creates a tree, in which you can expand 10 parent nodes * @author Vito Baggiolini * @version $Revision: 1.2 $ $Date: 2006/09/25 08:52:36 $ */ public class RecursiveChildrenListManager implements ChildrenListManager { private int count = 0; private final int children; private final int childrenPerParent; private final Class beanClass; private final Constructor beanConstructor; private final static int DEFAULT_CHILDREN = 10; private final static int DEFAULT_CHILDREN_PER_PARENT = 3; private final static Class DEFAULT_BEAN_CLASS = SimpleDemoBean.class; /** * Constructor to create a tree with a pre-defined number of children. This constructor * uses {@link SimpleDemoBean} as Beans to display in the tree. If you need to change * the default settings use a different constructor. */ public RecursiveChildrenListManager() { this(DEFAULT_CHILDREN, DEFAULT_CHILDREN_PER_PARENT); } /** * constructor that allows to specify how many times children are added to the * parents, when the user opens the branches of the tree. After this number has been * reached, no further children will be added to the parent, trying to open further * branch of the tree will simply result in leaf nodes. * * @param children how many times children shall be added */ public RecursiveChildrenListManager(int children) { this(DEFAULT_BEAN_CLASS, children, DEFAULT_CHILDREN_PER_PARENT); } /** * Constructor that allows to specify (1) how many times children are added to parents * when the user opens the branches of the tree and (2) how many children are added to each * parent. * @param children how many times children shall be added * @param childrenPerParent how many children shall be added to each parent */ public RecursiveChildrenListManager(int children, int childrenPerParent) { this(DEFAULT_BEAN_CLASS, children, childrenPerParent); } /** * constructor that allows to specify how many times children are added to the * parents, and how many sibling children are added each time, and the Bean class to use * * @param beanClass the class to use as bean. This class should either have a constructor that * accepts a String (preferred) or at least a no-argument constructor. * @param children the number of times children shall be added * @param the number of sibling children added to each parent */ public RecursiveChildrenListManager(Class beanClass, int children, int childrenPerParent) { this.beanClass = beanClass; this.children = children; this.childrenPerParent = childrenPerParent; this.beanConstructor = getConstructor(beanClass); } // //--- IMPLEMENTS ChildrenListManager // public Comparator getComparator() { return null; } public void initChildrenList(NodeList nodeList) { count++; try { if (count < children) { for (int ix=0; ix< childrenPerParent; ix++) { nodeList.addNode(NodeFactory.createNode(createBean("child " + count + ix), this)); } } else { for (int ix=0; ix< childrenPerParent; ix++) { nodeList.addNode(NodeFactory.createNode(createBean("child " + count + ix))); } } } catch (IntrospectionException ex) { ex.printStackTrace(); } } // //------------- Private Methods ---------------------------------------------- // /** * helper method, tries to find a suitable constructor from the class specified * Currently, this must either be a constructor that accepts one string or a no-argument * constructor. */ private static Constructor getConstructor(Class clazz) { try { return clazz.getConstructor(new Class[] { String.class}); } catch (NoSuchMethodException ex) { System.err.println("warning: bad paramenter " + clazz + "; should have a Constructor that accepts one string as argument"); } try { return clazz.getConstructor(null); } catch (NoSuchMethodException ex) { System.err.println("warning: bad paramenter " + clazz + "; must at least have a non-argument Constructor!"); } try { return SimpleDemoBean.class.getConstructor(new Class[] { String.class} ); } catch (NoSuchMethodException ex) { System.err.println("internal error: SimpleDemoBean.class does not have a String-constructor"); } return null; } /** * helper method, uses the variable beanConstructor to create a new Bean */ private Object createBean(String args) { try { return beanConstructor.newInstance(new Object[] { args }); } catch (Exception ex) { System.err.println("error instantiating beanClass " + beanClass + " with String constructor"); } try { return beanClass.newInstance(); } catch (Exception ex) { System.err.println("error instantiating beanClass " + beanClass + " with default constructor"); } return null; } }