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
56 this.excludedClasses = excludedClasses;
57 }
58
59
60
61
62 public DependencyClassFileVisitor() {
63 this(new ClassesPatterns());
64 }
65
66
67 @Override
68 public void visitClass(String className, InputStream in) {
69 try {
70 byte[] byteCode = toByteArray(in);
71
72 if (excludedClasses.isMatch(className)) {
73 return;
74 }
75
76 ClassReader reader = new ClassReader(byteCode);
77
78 final Set<String> constantPoolClassRefs = ConstantPoolParser.getConstantPoolClassReferences(byteCode);
79 for (String string : constantPoolClassRefs) {
80 resultCollector.addName(className, string);
81 }
82
83 AnnotationVisitor annotationVisitor = new DefaultAnnotationVisitor(resultCollector, className);
84 SignatureVisitor signatureVisitor = new DefaultSignatureVisitor(resultCollector, className);
85 FieldVisitor fieldVisitor = new DefaultFieldVisitor(annotationVisitor, resultCollector, className);
86 MethodVisitor mv =
87 new DefaultMethodVisitor(annotationVisitor, signatureVisitor, resultCollector, className);
88 ClassVisitor classVisitor = new DefaultClassVisitor(
89 signatureVisitor, annotationVisitor, fieldVisitor, mv, resultCollector, className);
90
91 reader.accept(classVisitor, 0);
92 } catch (IOException exception) {
93 throw new UncheckedIOException(exception);
94 } catch (IndexOutOfBoundsException e) {
95
96
97 throw new VisitClassException("Unable to process: " + className, e);
98 } catch (IllegalArgumentException e) {
99 throw new VisitClassException("Byte code of '" + className + "' is corrupt", e);
100 }
101 }
102
103 private byte[] toByteArray(InputStream in) throws IOException {
104 ByteArrayOutputStream out = new ByteArrayOutputStream();
105 byte[] buffer = new byte[BUF_SIZE];
106 int i;
107 while ((i = in.read(buffer)) > 0) {
108 out.write(buffer, 0, i);
109 }
110 return out.toByteArray();
111 }
112
113
114
115
116
117
118 public Set<String> getDependencies() {
119 return resultCollector.getDependencies();
120 }
121
122
123
124
125
126
127
128 public Set<DependencyUsage> getDependencyUsages() {
129 return resultCollector.getDependencyUsages();
130 }
131 }