package jetbrains.mps.core.tool.environment.classloading;
/*Generated by MPS */
import org.jetbrains.annotations.NonNls;
import java.io.PrintStream;
import java.util.Stack;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.io.IOException;
import java.util.Enumeration;
import java.net.URISyntaxException;
import java.io.File;
import java.util.NoSuchElementException;
public class ClassPath {
@NonNls
private static final String FILE_PROTOCOL = "file";
private static final boolean myDebugTime = false;
private static final long NS_THRESHOLD = 10000000L;
private static PrintStream ourOrder;
private final Stack<URL> myUrls = new Stack<URL>();
private final ArrayList<Loader> myLoaders = new ArrayList<Loader>();
private final HashMap<URL, Loader> myLoadersMap = new HashMap<URL, Loader>();
private final ClasspathCache myCache = new ClasspathCache();
private final boolean myCanLockJars;
private final boolean myCanUseCache;
private final boolean myAcceptUnescapedUrls;
public ClassPath(URL[] urls, boolean canLockJars, boolean canUseCache) {
this(urls, canLockJars, canUseCache, false);
}
public ClassPath(URL[] urls, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls) {
this.myCanLockJars = canLockJars;
this.myCanUseCache = canUseCache;
this.myAcceptUnescapedUrls = acceptUnescapedUrls;
push(urls);
}
public void addURL(URL url) {
synchronized (myUrls) {
myUrls.push(url);
}
}
private void push(URL[] urls) {
synchronized (myUrls) {
for (int i = urls.length - 1; i >= 0; i--) {
myUrls.push(urls[i]);
}
}
}
@Nullable
public Resource getResource(String s, boolean flag) {
final long started = (ClassPath.myDebugTime ? System.nanoTime() : 0);
try {
int i;
if (myCanUseCache) {
final List<Loader> loaders = myCache.getLoaders(s);
for (Loader loader : loaders) {
final Resource resource = loader.getResource(s, flag);
if (resource != null) {
// printOrder(loader, s);
return resource;
}
}
synchronized (myUrls) {
if (myUrls.isEmpty()) {
return null;
}
}
i = myLoaders.size();
} else {
i = 0;
}
for (Loader loader; (loader = getLoader(i)) != null; i++) {
Resource resource = loader.getResource(s, flag);
if (resource != null) {
return resource;
}
}
return null;
} finally {
long doneFor = (ClassPath.myDebugTime ? System.nanoTime() - started : 0);
if (doneFor > ClassPath.NS_THRESHOLD) {
System.out.println((doneFor / 1000000) + " ms for getResource:" + s + ", flag:" + flag);
}
}
}
@Nullable
private Loader getLoader(int i) {
while (myLoaders.size() < i + 1) {
URL url;
synchronized (myUrls) {
if (myUrls.empty()) {
return null;
}
url = myUrls.pop();
}
if (myLoadersMap.containsKey(url)) {
continue;
}
Loader loader;
try {
loader = getLoader(url);
if (loader == null) {
continue;
}
} catch (IOException ioexception) {
continue;
}
myLoaders.add(loader);
myLoadersMap.put(url, loader);
}
return myLoaders.get(i);
}
public Enumeration<URL> getResources(final String name, final boolean check) {
return new ClassPath.MyEnumeration(name, check);
}
@Nullable
private Loader getLoader(final URL url) throws IOException {
String s;
if (myAcceptUnescapedUrls) {
s = url.getFile();
} else {
try {
s = url.toURI().getSchemeSpecificPart();
} catch (URISyntaxException thisShouldNotHappen) {
thisShouldNotHappen.printStackTrace();
s = url.getFile();
}
}
Loader loader = null;
if (s != null && new File(s).isDirectory()) {
if (ClassPath.FILE_PROTOCOL.equals(url.getProtocol())) {
loader = new FileLoader(url);
}
} else {
loader = new JarLoader(url, myCanLockJars);
}
if (loader != null && myCanUseCache) {
try {
loader.buildCache(myCache);
} catch (Throwable e) {
// TODO: log can't create loader
}
}
return loader;
}
private class MyEnumeration implements Enumeration<URL> {
private int myIndex = 0;
private Resource myRes = null;
private final String myName;
private final boolean myCheck;
public MyEnumeration(String name, boolean check) {
myName = name;
myCheck = check;
}
private boolean next() {
if (myRes != null) {
return true;
}
Loader loader;
while ((loader = getLoader(myIndex++)) != null) {
myRes = loader.getResource(myName, myCheck);
if (myRes != null) {
return true;
}
}
return false;
}
@Override
public boolean hasMoreElements() {
return next();
}
@Override
public URL nextElement() {
if (!(next())) {
throw new NoSuchElementException();
} else {
Resource resource = myRes;
myRes = null;
return resource.getURL();
}
}
}
}