1 package com.atlassian.plugin.osgi.util;
2
3 import aQute.bnd.osgi.AbstractResource;
4 import aQute.bnd.osgi.ClassDataCollector;
5 import aQute.bnd.osgi.Clazz;
6 import aQute.bnd.osgi.Descriptors;
7 import com.google.common.collect.Collections2;
8 import com.google.common.collect.ImmutableSet;
9 import com.google.common.collect.Sets;
10 import org.apache.commons.io.IOUtils;
11
12 import java.io.Closeable;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.util.Set;
16
17
18
19
20
21
22 public class ClassBinaryScanner {
23
24
25
26
27
28
29
30
31 public static ScanResult scanClassBinary(Clazz clazz) throws IOException {
32 final ImmutableSet.Builder<String> allReferredClasses = new ImmutableSet.Builder<>();
33 final String[] superClassName = new String[]{null};
34 try {
35
36 clazz.parseClassFileWithCollector(new ClassDataCollector() {
37
38 @Override
39 public void extendsClass(Descriptors.TypeRef ref) {
40 superClassName[0] = ref.getBinary();
41 allReferredClasses.add(ref.getBinary());
42 }
43
44 @Override
45 public void implementsInterfaces(Descriptors.TypeRef[] refs) {
46 for (Descriptors.TypeRef ref : refs) {
47 allReferredClasses.add(ref.getBinary());
48 }
49 }
50
51 @Override
52 public void addReference(Descriptors.TypeRef ref) {
53 allReferredClasses.add(ref.getBinary());
54 }
55 });
56 } catch (Exception e) {
57 throw new IOException("Error parsing class file", e);
58 }
59
60 Set<String> referredPackages = Sets.newHashSet(Collections2.transform(clazz.getReferred(),
61 packageRef -> {
62 if (packageRef != null) {
63 return packageRef.getFQN();
64 } else {
65 return null;
66 }
67 }));
68 return new ScanResult(allReferredClasses.build(), referredPackages, superClassName[0]);
69 }
70
71
72
73
74
75
76 public static class ScanResult {
77
78 private Set<String> referredClasses;
79 private Set<String> referredPackages;
80 private String superClass;
81
82 public ScanResult(Set<String> referredClasses, Set<String> referredPackages, String superClass) {
83 this.referredClasses = referredClasses;
84 this.referredPackages = referredPackages;
85 this.superClass = superClass;
86 }
87
88 public Set<String> getReferredClasses() {
89 return referredClasses;
90 }
91
92 public Set<String> getReferredPackages() {
93 return referredPackages;
94 }
95
96 public String getSuperClass() {
97 return superClass;
98 }
99 }
100
101
102
103
104
105
106 public static class InputStreamResource extends AbstractResource implements Closeable {
107 private InputStream inputStream;
108
109 public InputStreamResource(InputStream inputStream) {
110 super(-1);
111 this.inputStream = inputStream;
112 }
113
114 @Override
115 protected byte[] getBytes() throws Exception {
116 return IOUtils.toByteArray(inputStream);
117 }
118
119 @Override
120 public void close() throws IOException {
121 inputStream.close();
122 }
123
124 }
125 }