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.apache.maven.shared.dependency.analyzer.DependencyUsage;
30 import org.objectweb.asm.AnnotationVisitor;
31 import org.objectweb.asm.ClassReader;
32 import org.objectweb.asm.ClassVisitor;
33 import org.objectweb.asm.FieldVisitor;
34 import org.objectweb.asm.MethodVisitor;
35 import org.objectweb.asm.signature.SignatureVisitor;
36
37
38
39
40
41
42
43
44 public class DependencyClassFileVisitor implements ClassFileVisitor {
45 private static final int BUF_SIZE = 8192;
46
47 private final ResultCollector resultCollector = new ResultCollector();
48
49 private final ClassesPatterns excludedClasses;
50
51
52
53
54 public DependencyClassFileVisitor(ClassesPatterns excludedClasses) {
55 this.excludedClasses = excludedClasses;
56 }
57
58
59
60
61 public DependencyClassFileVisitor() {
62 this(new ClassesPatterns());
63 }
64
65
66
67
68
69
70
71
72
73 @Override
74 public void visitClass(String className, InputStream in) {
75 try {
76 byte[] byteCode = toByteArray(in);
77
78 if (excludedClasses.isMatch(className)) {
79 return;
80 }
81
82 ClassReader reader = new ClassReader(byteCode);
83
84 final Set<String> constantPoolClassRefs = ConstantPoolParser.getConstantPoolClassReferences(byteCode);
85 for (String string : constantPoolClassRefs) {
86 resultCollector.addName(className, string);
87 }
88
89 AnnotationVisitor annotationVisitor = new DefaultAnnotationVisitor(resultCollector, className);
90 SignatureVisitor signatureVisitor = new DefaultSignatureVisitor(resultCollector, className);
91 FieldVisitor fieldVisitor = new DefaultFieldVisitor(annotationVisitor, resultCollector, className);
92 MethodVisitor methodVisitor =
93 new DefaultMethodVisitor(annotationVisitor, signatureVisitor, resultCollector, className);
94 ClassVisitor classVisitor = new DefaultClassVisitor(
95 signatureVisitor, annotationVisitor, fieldVisitor, methodVisitor, resultCollector, className);
96
97 reader.accept(classVisitor, 0);
98 } catch (IOException exception) {
99 throw new UncheckedIOException(exception);
100 } catch (IndexOutOfBoundsException e) {
101
102
103 throw new VisitClassException("Unable to process: " + className, e);
104 } catch (UnknownConstantPoolTypeException | IllegalArgumentException e) {
105 throw new VisitClassException("Byte code of '" + className + "' is corrupt", e);
106 }
107 }
108
109 private byte[] toByteArray(InputStream in) throws IOException {
110 ByteArrayOutputStream out = new ByteArrayOutputStream();
111 byte[] buffer = new byte[BUF_SIZE];
112 int i;
113 while ((i = in.read(buffer)) > 0) {
114 out.write(buffer, 0, i);
115 }
116 return out.toByteArray();
117 }
118
119
120
121
122
123
124 public Set<String> getDependencies() {
125 return resultCollector.getDependencies();
126 }
127
128
129
130
131
132
133
134 public Set<DependencyUsage> getDependencyUsages() {
135 return resultCollector.getDependencyUsages();
136 }
137 }