Please note this class is only meant for developers of this control, not users.
This class implements a session based javascript handler. It manages the client side javascript behavior by tracking the client's selected tree paths.
The problem: when javascript is enabled, the entire tree must be sent to the browser to be navigatable without round trips to the server. However the tree should not be displayed in an expanded state so css is used to apply the 'display: none' idiom to 'collapse' the nodes even though they are really expanded.
On the browser as the user expands and collapses nodes he/she will make selections and deselections of certain nodes. Since the node's value is rendered as a hyperlink, selecting or deselecting the node will create a request to the server. After the round trip to the server the tree will again be rendered in a collapsed state because the server will apply the css 'display :none' idiom before returning to the browser. It would be nice if instead of collapsing the entire tree again, to keep those tree paths that lead to selected nodes in a expanded state.
The solution: SessionHandler keeps track of the
selected paths and is queried at rendering time which nodes should be hidden and which nodes should be displayed. The
selected path are all the node's from the selected node up to the root node.
SessionHandler also keeps track of the
overlaid paths.
Overlaid paths comes from two or more selected paths that share certain common nodes. Overlaid paths are used in determining when a selected path can be removed from the tracker. To understand this better here is an example tree (top to bottom):
root node1 node2 node1.1 node1.2 node2.1 node2.2
IF node1 is selected, the
selected path would include the nodes "root and node1". If node1.1 is then selected, the
selected path would also include the nodes "root, node1 and node1.1". The same ff node1.2 is selected. The
overlaid path would include the shared nodes of the three selected paths. Thus the overlaid path would consist of "root" because that node is shared by all three paths. Overlaid path will also contain "node1" because it is shared by node1.1 and node1.2.
The implementation: To keep memory storage to a minimum, only the hashcode of a node is stored, and it is stored only once for any node on any selected path. Thus if n nodes in a tree are selected there will only be n hashcodes stored.
The overlaid paths are stored in a object consisting of a counter which increments and decrements each time a path is selected or deselected. The overlaid path also stores a boolean indicating if a a node is the last node on the path or not. The last node in the selected path should not be expanded because we do not want the children of the last node to be displayed. Lets look at our previous example again. The overlaid paths would contain the following information:
- root: int = 3, lastNodeInPath = false
- node1: int = 3, lastNodeInPath = false
- node1.1: int = 1, lastNodeInPath = true
- node1.2: int = 1, lastNodeInPath = true
The overlaid paths indicates that the root node was found on three selected paths, and it is not the last node in the path. It cannot be the last node in the path because its child, node1 is also found on the selected path. node1 is also found on three selected paths (remember that node1 was itself selected) and is also not the last node in the path because both its children are found on selected paths as well. node1.1 is only found once on a selected path and because it does not have any children, it is the last node in the path. node1.2 is the same as node1.1.
When a user deselects a node, each node on the selected path are decremented from the overlaid path counter. If a overlaid counter is reduced to 0, the selected path is also removed from storage. Also as nodes are removed, each node's lastNodeInPath indicator is updated to reflect if that node is the new last node on the path. For example if a user deselects node1.1 the overlaid path will look as follows:
- root: int = 1, lastNodeInPath = false
- node1: int = 1, lastNodeInPath = false
- node1.1: int = 1, lastNodeInPath = true
Only 1 instance of root and node1 are left on the paths, but both are still not the last node in the path. Because node1.2 counter was reduced to 0, it was removed from the
selected path storage as well.
If the user deselects node1.1 overlaid path will look like this:
- root: int = 1, lastNodeInPath = false
- node1: int = 1, lastNodeInPath = true
node1 is now the lastNodeInPath. node1.1 is also removed from the
selected path storage.
Note: this class stores information between requests in the javax.servlet.http.HttpSession as a attribute. The attributes prefix is
js_path_handler_ followed by the name of the tree {@link Tree#name}. If two tree's in the same session have the same name they will
overwrite each others session attribute!