com.github.fridujo.junit.extension.classpath.Classpath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of classpath-junit-extension Show documentation
Show all versions of classpath-junit-extension Show documentation
JUnit5 extension to run tests with classpath customizations
The newest version!
package com.github.fridujo.junit.extension.classpath;
import static java.util.Arrays.stream;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
public class Classpath {
public final Set pathElements;
private final ClasspathContext context;
private Classpath(Set pathElements, ClasspathContext context) {
this.pathElements = Collections.unmodifiableSet(new TreeSet<>(pathElements));
this.context = context;
}
public static Classpath current() {
return current(new ClasspathContext());
}
static Classpath current(ClasspathContext context) {
String rawClasspath = System.getProperty("java.class.path");
Set pathElements = stream(rawClasspath.split(File.pathSeparator))
.map(PathElement::create)
.collect(Collectors.toSet());
return new Classpath(pathElements, context);
}
public ClassLoader newClassLoader() {
ClassLoader parent = this.getClass().getClassLoader().getParent();
final URLClassLoader urlClassLoader = new URLClassLoader(
pathElements.stream().map(PathElement::toUrl).collect(Collectors.toList()).toArray(new URL[0]),
parent);
return urlClassLoader;
}
public Classpath removeJars(String[] excludeJars) {
Set newPaths = new TreeSet<>(pathElements);
Arrays.stream(excludeJars)
.map(Gav::parse)
.forEach(gav -> newPaths.removeIf(p -> p.matches(gav)));
return new Classpath(newPaths, context);
}
public Classpath removeGavs(String[] gavDescriptions) throws NoMatchingClasspathElementFoundException {
return Streams.reduce(stream(gavDescriptions), this, Classpath::removeGav);
}
public Classpath removeGav(String gavDescription) throws NoMatchingClasspathElementFoundException {
Gav gav = Gav.parse(gavDescription);
if (pathElements.stream().filter(pe -> pe.matches(gav)).count() == 0) {
throw new NoMatchingClasspathElementFoundException(gav);
}
Classpath classpath = this;
for (PathElement matchingPath : pathElements.stream().filter(pe -> pe.matches(gav)).collect(Collectors.toSet())) {
classpath = classpath.removeGavWithMatchingPath(gav, matchingPath);
}
return classpath;
}
private Classpath removeGavWithMatchingPath(Gav gav, PathElement matchingPath) {
Set newPaths = new TreeSet<>(pathElements);
newPaths.removeIf(pe -> pe.matches(gav));
Set gavsToRemove = context.listDependencies(matchingPath);
if (!gavsToRemove.isEmpty()) {
Set gavsToKeep = new HashSet<>();
for (PathElement pe : pathElements) {
if (!pe.matches(gav) && !gavsToRemove.stream().anyMatch(g -> pe.matches(g))) {
gavsToKeep.addAll(context.listDependencies(pe));
}
}
gavsToRemove.removeAll(gavsToKeep);
newPaths.removeIf(pe -> pe.matches(gavsToRemove));
}
return new Classpath(newPaths, context);
}
}