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 }