package jetbrains.mps.core.tool.environment.classloading; /*Generated by MPS */ import org.jetbrains.annotations.NonNls; import java.util.List; import java.net.URL; import java.util.Arrays; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collections; import java.io.IOException; import org.jetbrains.annotations.Nullable; import java.io.InputStream; import java.util.Enumeration; public class UrlClassLoader extends ClassLoader { @NonNls /*package*/ static final String CLASS_EXTENSION = ".class"; protected static final boolean myDebugTime = false; protected static final long NS_THRESHOLD = 10000000; private final ClassPath myClassPath; private final List<URL> myURLs; public UrlClassLoader(ClassLoader parent) { this(Arrays.asList(((URLClassLoader) parent).getURLs()), parent.getParent(), true, true); } public UrlClassLoader(List<URL> urls, ClassLoader parent) { this(urls, parent, false, false); } public UrlClassLoader(URL[] urls, ClassLoader parent) { this(Arrays.asList(urls), parent, false, false); } public UrlClassLoader(List<URL> urls, ClassLoader parent, boolean canLockJars, boolean canUseCache) { this(urls, parent, canLockJars, canUseCache, false); } public UrlClassLoader(List<URL> urls, ClassLoader parent, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls) { super(parent); myClassPath = new ClassPath(urls.toArray(new URL[urls.size()]), canLockJars, canUseCache, acceptUnescapedUrls); myURLs = new ArrayList<URL>(urls); } public void addURL(URL url) { myClassPath.addURL(url); myURLs.add(url); } public List<URL> getUrls() { return Collections.unmodifiableList(myURLs); } @Override protected Class findClass(final String name) throws ClassNotFoundException { Resource res = myClassPath.getResource(name.replace('.', '/').concat(UrlClassLoader.CLASS_EXTENSION), false); if (res == null) { throw new ClassNotFoundException(name); } try { return defineClass(name, res); } catch (IOException e) { throw new ClassNotFoundException(name, e); } } @Override protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { return super.loadClass(name, resolve); } @Nullable protected Class _findClass(final String name) { Resource res = myClassPath.getResource(name.replace('.', '/').concat(UrlClassLoader.CLASS_EXTENSION), false); if (res == null) { return null; } try { return defineClass(name, res); } catch (IOException e) { return null; } } private Class defineClass(String name, Resource res) throws IOException { int i = name.lastIndexOf('.'); if (i != -1) { String pkgname = name.substring(0, i); // Check if package already loaded. Package pkg = getPackage(pkgname); if (pkg == null) { try { definePackage(pkgname, null, null, null, null, null, null, null); } catch (IllegalArgumentException e) { // do nothing, package already defined by some other thread } } } byte[] b = res.getBytes(); return _defineClass(name, b); } protected Class _defineClass(final String name, final byte[] b) { return defineClass(name, b, 0, b.length); } @Nullable @Override public URL findResource(final String name) { final long started = (UrlClassLoader.myDebugTime ? System.nanoTime() : 0); try { return findResourceImpl(name); } finally { long doneFor = (UrlClassLoader.myDebugTime ? (System.nanoTime() - started) : 0); if (doneFor > UrlClassLoader.NS_THRESHOLD) { System.out.println((doneFor / 1000000) + " ms for UrlClassLoader.getResource, resource:" + name); } } } protected URL findResourceImpl(final String name) { Resource res = _getResource(name); if (res == null) { return null; } return res.getURL(); } @Nullable private Resource _getResource(final String name) { String n = name; if (n.startsWith("/")) { n = n.substring(1); } return myClassPath.getResource(n, true); } @Nullable @Override public InputStream getResourceAsStream(final String name) { try { Resource res = _getResource(name); if (res == null) { return null; } return res.getInputStream(); } catch (IOException e) { return null; } } @Override protected Enumeration<URL> findResources(String name) throws IOException { return myClassPath.getResources(name, true); } }