package org.xpect.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Set;
import java.util.jar.Manifest;
import org.apache.log4j.Logger;
import org.xpect.runner.XpectRunner;
import com.google.common.base.Joiner;
import com.google.common.collect.Sets;
import com.google.common.io.Closeables;
public class ClasspathUtil {
private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
private final static Logger LOG = Logger.getLogger(ClasspathUtil.class);
@SuppressWarnings("resource")
public static Collection<URL> findResources(String... fileNames) {
Set<URL> result = Sets.newLinkedHashSet();
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try {
for (String fileName : fileNames) {
Enumeration<URL> resources = classLoader.getResources(fileName);
while (resources.hasMoreElements())
result.add(resources.nextElement());
}
} catch (IOException e) {
LOG.error(e.getMessage(), e);
}
if (classLoader instanceof URLClassLoader) {
URLClassLoader ucl = (URLClassLoader) classLoader;
for (URL u : ucl.getURLs())
if (!u.getFile().endsWith(".jar")) {
try {
java.io.File f = new java.io.File(u.toURI());
if (f.isDirectory()) {
int levels = 5;
W: while (levels >= 0 && f != null) {
for (String fileName : fileNames) {
java.io.File pl = new java.io.File(f + "/" + fileName);
if (pl.isFile()) {
result.add(pl.toURI().toURL());
break W;
}
}
levels--;
f = f.getParentFile();
}
}
} catch (URISyntaxException e) {
LOG.error(e.getMessage(), e);
} catch (MalformedURLException e) {
LOG.error(e.getMessage(), e);
}
}
}
// for some reason, ucl.getURLs() doesn't catch the current project in standalone maven surefire
if (XpectRunner.INSTANCE != null) {
Class<?> clazz = XpectRunner.INSTANCE.getTestClass().getJavaClass();
String[] segments = clazz.getName().split("\\.");
String fileName = Joiner.on('/').join(segments) + ".class";
URL resource = clazz.getClassLoader().getResource(fileName);
if ("jar".equals(resource.getProtocol())) {
// URI location = URI.createURI(resource.toString()).trimSegments(segments.length).appendSegment("");
// return location;
} else {
File classFile;
try {
classFile = new File(resource.toURI());
File packageRootFolder = classFile;
for (int i = 0; i < segments.length; i++) {
packageRootFolder = packageRootFolder.getParentFile();
if (packageRootFolder == null)
LOG.error("Could not determine package root for " + clazz);
}
File current = packageRootFolder;
W: while (current != null) {
for (String name : fileNames) {
java.io.File pl = new java.io.File(current, name);
if (pl.isFile()) {
result.add(pl.toURI().toURL());
break W;
}
}
current = current.getParentFile();
}
} catch (URISyntaxException e) {
LOG.error(e.getMessage(), e);
} catch (MalformedURLException e) {
LOG.error(e.getMessage(), e);
}
}
}
return result;
}
public static String getSymbolicName(InputStream manifestInputStream) {
try {
Manifest manifest = new Manifest(manifestInputStream);
return getSymbolicName(manifest);
} catch (IOException e) {
LOG.error("error parsing manifest", e);
} finally {
Closeables.closeQuietly(manifestInputStream);
}
return null;
}
public static String getSymbolicName(Manifest manifest) {
String name = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLIC_NAME);
if (name != null) {
int i = name.indexOf(';');
if (i >= 0)
name = name.substring(0, i);
}
return name;
}
}