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(list);
oos.close();
}
@Override
public String toString(){
return "[" + ClassDiscoveryURLCache.class.getSimpleName() + ": " + 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);
}
}