001 package org.shiftone.jrat.provider.tree;
002
003
004 import org.shiftone.jrat.core.Accumulator;
005 import org.shiftone.jrat.core.MethodKey;
006 import org.shiftone.jrat.util.log.Logger;
007
008 import java.io.Externalizable;
009 import java.io.IOException;
010 import java.io.ObjectInput;
011 import java.io.ObjectOutput;
012 import java.util.ArrayList;
013 import java.util.HashMap;
014 import java.util.List;
015
016
017 /**
018 * Class TreeNode
019 *
020 * @author jeff@shiftone.org (Jeff Drost)
021 */
022 public class TreeNode implements Externalizable {
023
024 private static final Logger LOG = Logger.getLogger(TreeNode.class);
025 private static final long serialVersionUID = 1;
026 protected MethodKey methodKey;
027 protected TreeNode parent;
028 private Accumulator accumulator;
029 protected HashMap children = new HashMap(5);
030
031
032 public void writeExternal(ObjectOutput out) throws IOException {
033
034 out.writeObject(accumulator);
035 out.writeObject(methodKey);
036
037 // column a copy of the children
038 List list = getChildren();
039
040 // write a child count
041 int childCount = list.size();
042 out.writeInt(childCount);
043
044 // write the children
045 for (int i = 0; i < childCount; i++) {
046 TreeNode child = (TreeNode) list.get(i);
047 child.writeExternal(out);
048 }
049 }
050
051 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
052
053 this.accumulator = (Accumulator) in.readObject();
054 this.methodKey = (MethodKey) in.readObject();
055
056 int childCount = in.readInt();
057 for (int i = 0; i < childCount; i++) {
058
059 TreeNode child = new TreeNode();
060
061 child.readExternal(in);
062
063 children.put(child.getMethodKey(), child);
064 child.parent = this;
065 }
066
067 }
068
069 public TreeNode() {
070
071 // root node
072 this.methodKey = null;
073 this.parent = null;
074 this.accumulator = new Accumulator();
075 }
076
077
078 public TreeNode(MethodKey methodKey, TreeNode treeNode) {
079 this.methodKey = methodKey;
080 this.parent = treeNode;
081 this.accumulator = new Accumulator();
082 }
083
084 public List getChildren() {
085
086 List list = new ArrayList();
087
088 synchronized (children) {
089 list.addAll(children.values());
090 }
091
092 return list;
093 }
094
095
096 /**
097 * Method gets <b>AND CREATES IF NEEDED</b> the requested tree node
098 */
099 public TreeNode getChild(MethodKey methodKey) {
100
101 TreeNode treeNode = null;
102
103 synchronized (children) {
104 treeNode = (TreeNode) children.get(methodKey);
105
106 if (treeNode == null) {
107 treeNode = new TreeNode(methodKey, this);
108
109 children.put(methodKey, treeNode);
110 }
111 }
112
113 return treeNode;
114 }
115
116
117 public final TreeNode getParentNode() {
118 return parent;
119 }
120
121
122 public final boolean isRootNode() {
123 return (methodKey == null);
124 }
125
126
127 public Accumulator getAccumulator() {
128 return accumulator;
129 }
130
131 public MethodKey getMethodKey() {
132 return methodKey;
133 }
134
135 // ---------------------------------------------------------------
136
137 public synchronized void reset() {
138
139 // need to clone map - concurrency issues
140 List list = new ArrayList();
141
142 synchronized (children) {
143 list.addAll(children.values());
144 }
145
146 for (int i = 0; i < list.size(); i++) {
147 TreeNode treeNode = (TreeNode) list.get(i);
148
149 treeNode.reset();
150 }
151
152 accumulator.reset(); // this is the actual call to reset
153 }
154
155
156 }