/
ClassDiscoveryURLCache.java
116 lines (102 loc) · 3.36 KB
/
ClassDiscoveryURLCache.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.laytonsmith.PureUtilities.ClassLoading;
import com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror;
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
import com.laytonsmith.PureUtilities.ProgressIterator;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* This file represents a jar, and can tell you what annotations are available on each class, method, and field. This
* class has methods to serialize and deserialize from json, a descriptor, which can be used to rebuild this class with.
*/
public class ClassDiscoveryURLCache {
private final List<ClassMirror<?>> list;
/**
* Creates a new ClassDiscoveryURLCache. This operation may take a long time, depending on the size of the url that
* needs scanning.
*
* @param url
*/
public ClassDiscoveryURLCache(URL url) {
this(url, (ProgressIterator) null);
}
/**
* Creates a new ClassDiscoveryURLCache. This operation may take a long time, depending on the size of the url that
* needs scanning. The ProgressIterator can be null, but if provided is passed into the internal ClassDiscovery
* object that is used.
*
* @param url
* @param progress
*/
public ClassDiscoveryURLCache(URL url, ProgressIterator progress) {
list = new ArrayList<ClassMirror<?>>();
ClassDiscovery discovery = new ClassDiscovery();
discovery.setProgressIterator(progress);
//Double check to ensure that this is null, otherwise
//we would get stuck in an infinite loop.
discovery.setClassDiscoveryCache(null);
discovery.addDiscoveryLocation(url);
for(ClassMirror m : discovery.getKnownClasses(url)) {
ReflectionUtils.set(ClassMirror.class, m, "originalURL", url);
list.add(m);
}
}
/**
* Creates a new ClassDiscoveryURLCache object from a descriptor that was created earlier with writeDescriptor. The
* url may be null, but if provided, will be used as a fallback in case an error occurs with the descriptor.
*
* @param url
* @param descriptor
* @throws IOException
* @throws java.lang.ClassNotFoundException
*/
public ClassDiscoveryURLCache(URL url, InputStream descriptor) throws IOException, ClassNotFoundException {
List<ClassMirror<?>> list;
ObjectInputStream ois = new ObjectInputStream(descriptor);
try {
list = (List<ClassMirror<?>>) ois.readObject();
} catch (ClassNotFoundException ex) {
if(url != null) {
//We can recover from this one, but it won't be instant.
list = new ClassDiscoveryURLCache(url).list;
} else {
throw ex;
}
}
ois.close();
for(ClassMirror m : list) {
ReflectionUtils.set(ClassMirror.class, m, "originalURL", url);
}
this.list = list;
}
public void writeDescriptor(OutputStream out) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(this.list);
oos.close();
}
@Override
public String toString() {
return "[" + ClassDiscoveryURLCache.class.getSimpleName() + ": " + this.list.size() + "]";
}
/**
* Package private, no copy is made.
*
* @return
*/
/* package */ List<ClassMirror<?>> getClasses() {
return list;
}
/**
* Returns the classes in this cache.
*
* @return
*/
public List<ClassMirror> getClassList() {
return new ArrayList<ClassMirror>(list);
}
}