1 32 33 package com.jeantessier.dependency; 34 35 import java.util.*; 36 37 import org.apache.log4j.*; 38 39 import com.jeantessier.classreader.*; 40 41 46 public class CodeDependencyCollector extends CollectorBase { 47 private NodeFactory factory; 48 private Node current; 49 private HashSet dependencyListeners = new HashSet(); 50 51 public CodeDependencyCollector() { 52 this(new NodeFactory()); 53 } 54 55 public CodeDependencyCollector(NodeFactory factory) { 56 this.factory = factory; 57 } 58 59 public NodeFactory getFactory() { 60 return factory; 61 } 62 63 public Collection getCollection() { 64 return getFactory().getPackages().values(); 65 } 66 67 public void visitClassfile(Classfile classfile) { 68 current = getFactory().createClass(classfile.getClassName(), true); 69 70 fireBeginClass(classfile.toString()); 71 72 if (classfile.getSuperclassIndex() != 0) { 73 classfile.getRawSuperclass().accept(this); 74 } 75 76 Iterator i; 77 78 i = classfile.getAllInterfaces().iterator(); 79 while (i.hasNext()) { 80 ((Visitable) i.next()).accept(this); 81 } 82 83 i = classfile.getAllFields().iterator(); 84 while (i.hasNext()) { 85 ((Visitable) i.next()).accept(this); 86 } 87 88 i = classfile.getAllMethods().iterator(); 89 while (i.hasNext()) { 90 ((Visitable) i.next()).accept(this); 91 } 92 93 fireEndClass(classfile.toString()); 94 } 95 96 public void visitClass_info(Class_info entry) { 97 Logger.getLogger(getClass()).debug("VisitClass_info():"); 98 Logger.getLogger(getClass()).debug(" name = \"" + entry.getName() + "\""); 99 if (entry.getName().startsWith("[")) { 100 processDescriptor(entry.getName()); 101 } else { 102 Node other = getFactory().createClass(entry.getName()); 103 current.addDependency(other); 104 Logger.getLogger(getClass()).info("Class_info dependency: " + current + " --> " + other); 105 fireDependency(current, other); 106 } 107 } 108 109 public void visitFieldRef_info(FieldRef_info entry) { 110 Logger.getLogger(getClass()).debug("VisitFieldRef_info():"); 111 Logger.getLogger(getClass()).debug(" class = \"" + entry.getClassName() + "\""); 112 Logger.getLogger(getClass()).debug(" name = \"" + entry.getRawNameAndType().getName() + "\""); 113 Logger.getLogger(getClass()).debug(" type = \"" + entry.getRawNameAndType().getType() + "\""); 114 Node other = getFactory().createFeature(entry.getFullSignature()); 115 current.addDependency(other); 116 Logger.getLogger(getClass()).info("FieldRef_info dependency: " + current + " --> " + other); 117 fireDependency(current, other); 118 119 processDescriptor(entry.getRawNameAndType().getType()); 120 } 121 122 public void visitMethodRef_info(MethodRef_info entry) { 123 Logger.getLogger(getClass()).debug("VisitMethodRef_info():"); 124 Logger.getLogger(getClass()).debug(" class = \"" + entry.getClassName() + "\""); 125 Logger.getLogger(getClass()).debug(" name = \"" + entry.getRawNameAndType().getName() + "\""); 126 Logger.getLogger(getClass()).debug(" type = \"" + entry.getRawNameAndType().getType() + "\""); 127 if (!entry.isStaticInitializer()) { 128 Node other = getFactory().createFeature(entry.getFullSignature()); 129 current.addDependency(other); 130 Logger.getLogger(getClass()).info("MethodRef_info dependency: " + current + " --> " + other); 131 fireDependency(current, other); 132 133 processDescriptor(entry.getRawNameAndType().getType()); 134 } 135 } 136 137 public void visitInterfaceMethodRef_info(InterfaceMethodRef_info entry) { 138 Logger.getLogger(getClass()).debug("VisitInterfaceMethodRef_info():"); 139 Logger.getLogger(getClass()).debug(" class = \"" + entry.getClassName() + "\""); 140 Logger.getLogger(getClass()).debug(" name = \"" + entry.getRawNameAndType().getName() + "\""); 141 Logger.getLogger(getClass()).debug(" type = \"" + entry.getRawNameAndType().getType() + "\""); 142 Node other = getFactory().createFeature(entry.getFullSignature()); 143 current.addDependency(other); 144 Logger.getLogger(getClass()).info("InterfaceMethodRef_info dependency: " + current + " --> " + other); 145 fireDependency(current, other); 146 147 processDescriptor(entry.getRawNameAndType().getType()); 148 } 149 150 public void visitField_info(Field_info entry) { 151 Logger.getLogger(getClass()).debug("VisitField_info():"); 152 Logger.getLogger(getClass()).debug(" name = \"" + entry.getName() + "\""); 153 Logger.getLogger(getClass()).debug(" descriptor = \"" + entry.getDescriptor() + "\""); 154 155 current = getFactory().createFeature(entry.getFullSignature(), true); 156 157 processDescriptor(entry.getDescriptor()); 158 159 super.visitField_info(entry); 160 } 161 162 public void visitMethod_info(Method_info entry) { 163 Logger.getLogger(getClass()).debug("VisitMethod_info():"); 164 Logger.getLogger(getClass()).debug(" name = \"" + entry.getName() + "\""); 165 Logger.getLogger(getClass()).debug(" descriptor = \"" + entry.getDescriptor() + "\""); 166 167 current = getFactory().createFeature(entry.getFullSignature(), true); 168 169 processDescriptor(entry.getDescriptor()); 170 171 super.visitMethod_info(entry); 172 } 173 174 public void visitCode_attribute(Code_attribute attribute) { 175 Logger.getLogger(getClass()).debug("VisitCode_attribute() ..."); 176 177 byte[] code = attribute.getCode(); 178 179 183 184 Iterator ci = attribute.iterator(); 185 while (ci.hasNext()) { 186 Instruction instr = (Instruction) ci.next(); 187 switch (instr.getOpcode()) { 188 case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xbd: case 0xc0: case 0xc1: case 0xc5: int start = instr.getStart(); 202 int index = ((code[start+1] & 0xff) << 8) | (code[start+2] & 0xff); 203 ((Visitable) attribute.getClassfile().getConstantPool().get(index)).accept(this); 204 break; 205 default: 206 break; 208 } 209 } 210 211 super.visitCode_attribute(attribute); 212 } 213 214 public void visitExceptionHandler(ExceptionHandler helper) { 215 Logger.getLogger(getClass()).debug(getClass().getName() + "VisitExceptionHandler(): " + helper); 216 217 if (helper.getCatchTypeIndex() != 0) { 218 helper.getRawCatchType().accept(this); 219 } 220 } 221 222 private void processDescriptor(String str) { 223 int currentPos = 0; 224 int startPos; 225 int endPos; 226 227 while ((startPos = str.indexOf('L', currentPos)) != -1) { 228 if ((endPos = str.indexOf(';', startPos)) != -1) { 229 String classname = SignatureHelper.path2ClassName(str.substring(startPos + 1, endPos)); 230 Logger.getLogger(getClass()).debug(" Adding \"" + classname + "\""); 231 Node other = getFactory().createClass(classname); 232 current.addDependency(other); 233 Logger.getLogger(getClass()).info("descriptor dependency: " + current + " --> " + other); 234 fireDependency(current, other); 235 currentPos = endPos + 1; 236 } else { 237 currentPos = startPos + 1; 238 } 239 } 240 } 241 242 public void addDependencyListener(DependencyListener listener) { 243 synchronized(dependencyListeners) { 244 dependencyListeners.add(listener); 245 } 246 } 247 248 public void removeDependencyListener(DependencyListener listener) { 249 synchronized(dependencyListeners) { 250 dependencyListeners.remove(listener); 251 } 252 } 253 254 protected void fireBeginSession() { 255 DependencyEvent event = new DependencyEvent(this); 256 257 HashSet listeners; 258 synchronized(dependencyListeners) { 259 listeners = (HashSet) dependencyListeners.clone(); 260 } 261 262 Iterator i = listeners.iterator(); 263 while(i.hasNext()) { 264 ((DependencyListener) i.next()).beginSession(event); 265 } 266 } 267 268 protected void fireBeginClass(String classname) { 269 DependencyEvent event = new DependencyEvent(this, classname); 270 271 HashSet listeners; 272 synchronized(dependencyListeners) { 273 listeners = (HashSet) dependencyListeners.clone(); 274 } 275 276 Iterator i = listeners.iterator(); 277 while(i.hasNext()) { 278 ((DependencyListener) i.next()).beginClass(event); 279 } 280 } 281 282 protected void fireDependency(Node dependent, Node dependable) { 283 DependencyEvent event = new DependencyEvent(this, dependent, dependable); 284 285 HashSet listeners; 286 synchronized(dependencyListeners) { 287 listeners = (HashSet) dependencyListeners.clone(); 288 } 289 290 Iterator i = listeners.iterator(); 291 while(i.hasNext()) { 292 ((DependencyListener) i.next()).dependency(event); 293 } 294 } 295 296 protected void fireEndClass(String classname) { 297 DependencyEvent event = new DependencyEvent(this, classname); 298 299 HashSet listeners; 300 synchronized(dependencyListeners) { 301 listeners = (HashSet) dependencyListeners.clone(); 302 } 303 304 Iterator i = listeners.iterator(); 305 while(i.hasNext()) { 306 ((DependencyListener) i.next()).endClass(event); 307 } 308 } 309 310 protected void fireEndSession() { 311 DependencyEvent event = new DependencyEvent(this); 312 313 HashSet listeners; 314 synchronized(dependencyListeners) { 315 listeners = (HashSet) dependencyListeners.clone(); 316 } 317 318 Iterator i = listeners.iterator(); 319 while(i.hasNext()) { 320 ((DependencyListener) i.next()).endSession(event); 321 } 322 } 323 } 324 | Popular Tags |