create changelog entry
[debian/openrocket] / android-libraries / TreeViewList / src / pl / polidea / treeview / TreeBuilder.java
1 package pl.polidea.treeview;
2
3 import android.util.Log;
4
5 /**
6  * Allows to build tree easily in sequential mode (you have to know levels of
7  * all the tree elements upfront). You should rather use this class rather than
8  * manager if you build initial tree from some external data source.
9  * 
10  * @param <T>
11  */
12 public class TreeBuilder<T> {
13     private static final String TAG = TreeBuilder.class.getSimpleName();
14
15     private final TreeStateManager<T> manager;
16
17     private T lastAddedId = null;
18     private int lastLevel = -1;
19
20     public TreeBuilder(final TreeStateManager<T> manager) {
21         this.manager = manager;
22     }
23
24     public void clear() {
25         manager.clear();
26     }
27
28     /**
29      * Adds new relation to existing tree. Child is set as the last child of the
30      * parent node. Parent has to already exist in the tree, child cannot yet
31      * exist. This method is mostly useful in case you add entries layer by
32      * layer - i.e. first top level entries, then children for all parents, then
33      * grand-children and so on.
34      * 
35      * @param parent
36      *            parent id
37      * @param child
38      *            child id
39      */
40     public synchronized void addRelation(final T parent, final T child) {
41         Log.d(TAG, "Adding relation parent:" + parent + " -> child: " + child);
42         manager.addAfterChild(parent, child, null);
43         lastAddedId = child;
44         lastLevel = manager.getLevel(child);
45     }
46
47     /**
48      * Adds sequentially new node. Using this method is the simplest way of
49      * building tree - if you have all the elements in the sequence as they
50      * should be displayed in fully-expanded tree. You can combine it with add
51      * relation - for example you can add information about few levels using
52      * {@link addRelation} and then after the right level is added as parent,
53      * you can continue adding them using sequential operation.
54      * 
55      * @param id
56      *            id of the node
57      * @param level
58      *            its level
59      */
60     public synchronized void sequentiallyAddNextNode(final T id, final int level) {
61         Log.d(TAG, "Adding sequentiall node " + id + " at level " + level);
62         if (lastAddedId == null) {
63             addNodeToParentOneLevelDown(null, id, level);
64         } else {
65             if (level <= lastLevel) {
66                 final T parent = findParentAtLevel(lastAddedId, level - 1);
67                 addNodeToParentOneLevelDown(parent, id, level);
68             } else {
69                 addNodeToParentOneLevelDown(lastAddedId, id, level);
70             }
71         }
72     }
73
74     /**
75      * Find parent of the node at the level specified.
76      * 
77      * @param node
78      *            node from which we start
79      * @param levelToFind
80      *            level which we are looking for
81      * @return the node found (null if it is topmost node).
82      */
83     private T findParentAtLevel(final T node, final int levelToFind) {
84         T parent = manager.getParent(node);
85         while (parent != null) {
86             if (manager.getLevel(parent) == levelToFind) {
87                 break;
88             }
89             parent = manager.getParent(parent);
90         }
91         return parent;
92     }
93
94     /**
95      * Adds note to parent at the level specified. But it verifies that the
96      * level is one level down than the parent!
97      * 
98      * @param parent
99      *            parent parent
100      * @param id
101      *            new node id
102      * @param level
103      *            should always be parent's level + 1
104      */
105     private void addNodeToParentOneLevelDown(final T parent, final T id,
106             final int level) {
107         if (parent == null && level != 0) {
108             throw new TreeConfigurationException("Trying to add new id " + id
109                     + " to top level with level != 0 (" + level + ")");
110         }
111         if (parent != null && manager.getLevel(parent) != level - 1) {
112             throw new TreeConfigurationException("Trying to add new id " + id
113                     + " <" + level + "> to " + parent + " <"
114                     + manager.getLevel(parent)
115                     + ">. The difference in levels up is bigger than 1.");
116         }
117         manager.addAfterChild(parent, id, null);
118         setLastAdded(id, level);
119     }
120
121     private void setLastAdded(final T id, final int level) {
122         lastAddedId = id;
123         lastLevel = level;
124     }
125
126 }