View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.typeresolution;
    5
    6   import net.sourceforge.pmd.typeresolution.visitors.PMDASMVisitor;
    7
    8   import org.objectweb.asm.ClassReader;
    9
    10  import java.io.IOException;
    11  import java.util.LinkedList;
    12  import java.util.HashSet;
    13  import java.util.List;
    14  import java.util.Map;
    15  import java.util.Set;
    16
    17  /*
    18   * I've refactored this class to not cache the results any more. This is a
    19   * tradeoff in testing I've found the CPU tradeoff is negligeable. With the
    20   * cache, large codebases consumed a lot of memory and slowed down greatly when
    21   * approaching 3,000 classes. I'm adding this comment in case someone is looking
    22   * at this code and thinks a cache may help.
    23   */
    24  public class PMDASMClassLoader extends ClassLoader {
    25
    26      public PMDASMClassLoader(ClassLoader parent) {
    27      	super(parent);
    28      }
    29
    30      private Set<String> dontBother = new HashSet<String>();
    31
    32      public synchronized Map<String, String> getImportedClasses(String name) throws ClassNotFoundException {
    33
    34          if (dontBother.contains(name)) {
    35              throw new ClassNotFoundException(name);
    36          }
    37          try {
    38              ClassReader reader = new ClassReader(getResourceAsStream(name.replace('.', '/') + ".class"));
    39              PMDASMVisitor asmVisitor = new PMDASMVisitor();
    40              reader.accept(asmVisitor, 0);
    41
    42              List<String> inner = asmVisitor.getInnerClasses();
    43              if (inner != null && !inner.isEmpty()) {
    44                  inner = new LinkedList<String>(inner); // to avoid ConcurrentModificationException
    45                  for (String str: inner) {
    46                      reader = new ClassReader(getResourceAsStream(str.replace('.', '/') + ".class"));
    47                      reader.accept(asmVisitor, 0);
    48                  }
    49              }
    50              return asmVisitor.getPackages();
    51          } catch (IOException e) {
    52              dontBother.add(name);
    53              throw new ClassNotFoundException(name, e);
    54          }
    55      }
    56  }