Child Tracking
Each tree node has two convenient methods which return a list of all the attributes the node object currently holds. The runtime hook automatically implements those methods for each node at runtime.
Activation
The child tracking can be activated for a certain class by implementing the interface com.quartercode.jtimber.api.node.Node
. The interface declares two methods:
public List<Object> getChildren()
public int getChildCount()
The implementation of both methods is not important and will be overriden at runtime. However, some kind of implementation (like return null
) is necessary in order for the compiler to accept the code. If you are able to, it is recommended to extend the class com.quartercode.jtimber.api.node.DefaultNode
instead of implementing the node interface directly. That class already implements the two empty method stubs.
Retrieval
You can call the two new methods on the nodes like any other method. However, you must ensure that the runtime hook is active at runtime. It will fill the two node methods with actual functionality.
- The
getChildren()
method returns a list containing the values of all non-null attributes the node currently has. The list literally contains all attributes, and not just the parent-aware ones. Even primitives are contained in the list. Moreover, if the node references an object multiple times, the returned list contains that child object multiple times as well. - The
getChildCount()
method returns the size of the list returned by thegetChildren()
method. However, it is considerably faster and doesn't need to create an internal list object.
Wrappers
For each child, the generated algorithm checks whether it is a wrapper. If it is, the objects returned by the Wrapper.getActualChildren()
method are used as children instead of the wrapper itself. For example, a list wrapper is not seen as a proper child. Instead, the elements of the list it contains are the actual children.
Note that this process is applied recursively. If the list would contain other wrappers, those would be resolved as well.
Example
class Parent extends DefaultNode<Node<?>> {
private String object1 = "abc";
private Child object2 = new Child();
// Getters and setters
}
class Child extends DefaultParentAware<Parent> {
}
public static void main(String[] args) {
Parent parent = new Parent();
String object1 = parent.getObject1();
Child object2 = parent.getObject2();
assert parent.getChildren().get(0) == object1;
assert parent.getChildren().get(1) == object2;
}