Skip to content

Commit

Permalink
Merge pull request #172 from EntityReborn/master
Browse files Browse the repository at this point in the history
Some backend extension work to facilitate good things to come.
  • Loading branch information
LadyCailin committed Nov 1, 2013
2 parents 1e0b4dd + 985f1f5 commit efde7db
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 12 deletions.
Expand Up @@ -176,6 +176,9 @@ public void setDebugMode(boolean on){
* @param url
*/
public void removePreCache(URL url) {
if (url == null) {
throw new NullPointerException("url cannot be null");
}
preCaches.remove(url);
}

Expand All @@ -186,6 +189,9 @@ public void removePreCache(URL url) {
* @param cache
*/
public void addPreCache(URL url, ClassDiscoveryURLCache cache) {
if (url == null) {
throw new NullPointerException("url cannot be null");
}
if(debug){
System.out.println("Adding precache for " + url);
}
Expand Down Expand Up @@ -377,17 +383,39 @@ public ClassLoader getDefaultClassLoader() {
* @param url
*/
public synchronized void addDiscoveryLocation(URL url) {
if (url == null) {
throw new NullPointerException("url cannot be null");
}
if (urlCache.contains(url)) {
//Already here, so just return.
return;
}
if (url == null) {
throw new NullPointerException("url cannot be null");
}
urlCache.add(url);
dirtyURLs.add(url);
classCache.put(url, new HashSet<ClassMirror<?>>());
}

/**
* Remove a discovery URL. Will invalidate caches.
*
* @param url
*/
public synchronized void removeDiscoveryLocation(URL url) {
if (url == null) {
throw new NullPointerException("url cannot be null");
}

if (!urlCache.contains(url)) {
//Not here, so just return.
return;
}

urlCache.remove(url);
dirtyURLs.remove(url);
preCaches.remove(url);

invalidateCaches();
}

/**
* Clears the internal caches. This is called automatically when a new
Expand Down Expand Up @@ -433,6 +461,9 @@ public Set<ClassMirror<?>> getKnownClasses() {
* @return
*/
public List<ClassMirror<?>> getKnownClasses(URL url) {
if (url == null) {
throw new NullPointerException("url cannot be null");
}
if (!classCache.containsKey(url)) {
addDiscoveryLocation(url);
}
Expand Down
Expand Up @@ -2,13 +2,15 @@
package com.laytonsmith.PureUtilities.ClassLoading;

import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
Expand All @@ -18,15 +20,15 @@
*/
public class DynamicClassLoader extends ClassLoader {

private final Set<URLClassLoader> classLoaders = new LinkedHashSet<URLClassLoader>();
private final Map<URL, URLClassLoader> classLoaders = new LinkedHashMap<URL, URLClassLoader>();
private final Set<URL> urls = new HashSet<URL>();
private boolean destroyed = false;

/**
* Adds a jar to this class loader instance. This can be done at runtime,
* however note that jars cannot be removed, and if a jar already defines
* a class (or the class has already been loaded) it cannot be changed inside this
* instance. Adding the same URL twice has no effect.
* and if a jar already defines a class (or the class has already been loaded)
* it cannot be changed inside this instance. Adding the same URL twice has
* no effect.
* @param url The url to the jar.
*/
public synchronized void addJar(URL url){
Expand All @@ -35,12 +37,35 @@ public synchronized void addJar(URL url){
return;
}
urls.add(url);
classLoaders.add(new URLClassLoader(new URL[]{url}, DynamicClassLoader.class.getClassLoader()));
classLoaders.put(url, new URLClassLoader(new URL[]{url}, DynamicClassLoader.class.getClassLoader()));
}

/**
* Remove a jar from this class loader instance. Adding the same URL twice has
* no effect.
*
* @param url
*/
public synchronized void removeJar(URL url) {
checkDestroy();

if(!urls.contains(url)){
return;
}

urls.remove(url);
URLClassLoader l = classLoaders.remove(url);

try {
l.close();
} catch (IOException ex) {
// Whatever.
}
}

@Override
protected synchronized Package getPackage(String name) {
for(ClassLoader c : classLoaders){
for(ClassLoader c : classLoaders.values()){
Package p = (Package) ReflectionUtils.invokeMethod(c.getClass(), c, "getPackage", new Class[]{String.class}, new Object[]{name});
if(p != null){
return p;
Expand All @@ -52,7 +77,7 @@ protected synchronized Package getPackage(String name) {
@Override
protected synchronized Package[] getPackages() {
List<Package> packages = new ArrayList<Package>();
for(ClassLoader c : classLoaders){
for(ClassLoader c : classLoaders.values()){
packages.addAll(Arrays.asList((Package[])ReflectionUtils.invokeMethod(c.getClass(), c, "getPackages")));
}
return packages.toArray(new Package[packages.size()]);
Expand All @@ -68,7 +93,7 @@ protected synchronized Class<?> loadClass(String name, boolean resolve) throws C
return c;
} catch(ClassNotFoundException ex){
//Otherwise we need to find the class ourselves.
for(URLClassLoader url : classLoaders){
for(URLClassLoader url : classLoaders.values()){
try{
Class c = url.loadClass(name);
if(resolve){
Expand Down

0 comments on commit efde7db

Please sign in to comment.