1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.dependency.analyzer.asm;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.UncheckedIOException;
25 import java.util.Set;
26
27 import org.apache.maven.shared.dependency.analyzer.ClassFileVisitor;
28 import org.apache.maven.shared.dependency.analyzer.ClassesPatterns;
29 import org.objectweb.asm.AnnotationVisitor;
30 import org.objectweb.asm.ClassReader;
31 import org.objectweb.asm.ClassVisitor;
32 import org.objectweb.asm.FieldVisitor;
33 import org.objectweb.asm.MethodVisitor;
34 import org.objectweb.asm.signature.SignatureVisitor;
35
36
37
38
39
40
41
42
43 public class DependencyClassFileVisitor implements ClassFileVisitor {
44 private static final int BUF_SIZE = 8192;
45
46 private final ResultCollector resultCollector = new ResultCollector();
47
48 private final ClassesPatterns excludedClasses;
49
50
51
52
53 public DependencyClassFileVisitor(ClassesPatterns excludedClasses) {
54
55 this.excludedClasses = excludedClasses;
56 }
57
58
59
60
61 public DependencyClassFileVisitor() {
62 this(new ClassesPatterns());
63 }
64
65
66 @Override
67 public void visitClass(String className, InputStream in) {
68 try {
69 byte[] byteCode = toByteArray(in);
70
71 if (excludedClasses.isMatch(className)) {
72 return;
73 }
74
75 ClassReader reader = new ClassReader(byteCode);
76
77 final Set<String> constantPoolClassRefs = ConstantPoolParser.getConstantPoolClassReferences(byteCode);
78 for (String string : constantPoolClassRefs) {
79 resultCollector.addName(string);
80 }
81
82 AnnotationVisitor annotationVisitor = new DefaultAnnotationVisitor(resultCollector);
83 SignatureVisitor signatureVisitor = new DefaultSignatureVisitor(resultCollector);
84 FieldVisitor fieldVisitor = new DefaultFieldVisitor(annotationVisitor, resultCollector);
85 MethodVisitor mv = new DefaultMethodVisitor(annotationVisitor, signatureVisitor, resultCollector);
86 ClassVisitor classVisitor =
87 new DefaultClassVisitor(signatureVisitor, annotationVisitor, fieldVisitor, mv, resultCollector);
88
89 reader.accept(classVisitor, 0);
90 } catch (IOException exception) {
91 throw new UncheckedIOException(exception);
92 } catch (IndexOutOfBoundsException e) {
93
94
95 throw new VisitClassException("Unable to process: " + className, e);
96 } catch (IllegalArgumentException e) {
97 throw new VisitClassException("Byte code of '" + className + "' is corrupt", e);
98 }
99 }
100
101 private byte[] toByteArray(InputStream in) throws IOException {
102 ByteArrayOutputStream out = new ByteArrayOutputStream();
103 byte[] buffer = new byte[BUF_SIZE];
104 int i;
105 while ((i = in.read(buffer)) > 0) {
106 out.write(buffer, 0, i);
107 }
108 return out.toByteArray();
109 }
110
111
112
113
114
115
116 public Set<String> getDependencies() {
117 return resultCollector.getDependencies();
118 }
119 }