Issue #1499 ClasspathPattern module support

Added simple but inefficient implementation for jrt matching
This commit is contained in:
Greg Wilkins 2017-08-22 17:02:17 +10:00
parent 2a3deb0a10
commit 1d1ba56c88
2 changed files with 147 additions and 24 deletions

View File

@ -79,7 +79,8 @@ public class ClasspathPattern extends AbstractSet<String>
_pattern=pattern;
_inclusive = !pattern.startsWith("-");
_name = _inclusive ? pattern : pattern.substring(1).trim();
_type = _name.startsWith("file:")?Type.LOCATION:(_name.endsWith(".")?Type.PACKAGE:Type.CLASSNAME);
boolean is_location = _name.startsWith("file:") || _name.startsWith("jrt:");
_type = is_location?Type.LOCATION:(_name.endsWith(".")?Type.PACKAGE:Type.CLASSNAME);
}
Entry(String name, boolean include)
@ -87,7 +88,8 @@ public class ClasspathPattern extends AbstractSet<String>
_pattern=include?name:("-"+name);
_inclusive = include;
_name = name;
_type = _name.startsWith("file:")?Type.LOCATION:(_name.endsWith(".")?Type.PACKAGE:Type.CLASSNAME);
boolean is_location = _name.startsWith("file:") || _name.startsWith("jrt:");
_type = is_location?Type.LOCATION:(_name.endsWith(".")?Type.PACKAGE:Type.CLASSNAME);
}
@ -308,36 +310,65 @@ public class ClasspathPattern extends AbstractSet<String>
}
@SuppressWarnings("serial")
public static class ByLocation extends HashSet<File> implements Predicate<Path>
public static class ByLocation extends HashSet<URI> implements Predicate<URI>
{
@Override
public boolean test(Path path)
public boolean test(URI uri)
{
for (File file: this)
// TODO this is very inefficient with object creation
switch(uri.getScheme())
{
if (file.isDirectory())
case "file":
{
if (path.startsWith(file.toPath()))
Path path = Paths.get(uri);
for (URI u: this)
{
return true;
}
}
else
{
if (path.equals(file.toPath()))
{
return true;
if (u.getScheme().equals("file"))
{
File file = new File(u);
if (file.isDirectory())
{
if (path.startsWith(file.toPath()))
{
return true;
}
} else
{
if (path.equals(file.toPath()))
{
return true;
}
}
}
}
return false;
}
case "jrt":
{
String module = uri.getPath().split("/")[1];
for (URI u: this)
{
if (u.getScheme().equals("jrt"))
{
String m = u.toString().split("/")[1];
if (module.equals(m))
return true;
}
}
return false;
}
default:
throw new IllegalStateException("unknown URI scheme: "+uri);
}
return false;
}
}
Map<String,Entry> _entries = new HashMap<>();
IncludeExcludeSet<Entry,String> _patterns = new IncludeExcludeSet<>(ByPackageOrName.class);
IncludeExcludeSet<File,Path> _locations = new IncludeExcludeSet<>(ByLocation.class);
IncludeExcludeSet<URI,URI> _locations = new IncludeExcludeSet<>(ByLocation.class);
public ClasspathPattern()
{
@ -412,11 +443,11 @@ public class ClasspathPattern extends AbstractSet<String>
{
try
{
File file = Resource.newResource(entry.getName()).getFile().getAbsoluteFile().getCanonicalFile();
URI uri = Resource.newResource(entry.getName()).getURI();
if (entry.isInclusive())
_locations.include(file);
_locations.include(uri);
else
_locations.exclude(file);
_locations.exclude(uri);
}
catch (Exception e)
{
@ -526,7 +557,7 @@ public class ClasspathPattern extends AbstractSet<String>
return byName; // Already excluded so no need to check location.
URI location = TypeUtil.getLocationOfClass(clazz);
Boolean byLocation = location == null ? null
: _locations.isIncludedAndNotExcluded(Paths.get(location));
: _locations.isIncludedAndNotExcluded(location);
if (LOG.isDebugEnabled())
LOG.debug("match {} from {} byName={} byLocation={} in {}",clazz,location,byName,byLocation,this);
@ -564,8 +595,7 @@ public class ClasspathPattern extends AbstractSet<String>
URI jarUri = URIUtil.getJarSource(url.toURI());
if ("file".equalsIgnoreCase(jarUri.getScheme()))
{
File file = new File(jarUri);
byLocation = _locations.isIncludedAndNotExcluded(file.toPath());
byLocation = _locations.isIncludedAndNotExcluded(jarUri);
}
}
catch(Exception e)

View File

@ -154,6 +154,49 @@ public class ClasspathPatternTest
Assert.assertThat(pattern.match(ClasspathPatternTest.class), Matchers.is(true));
}
@SuppressWarnings("restriction")
@Test
public void testIncludedLocationsOrModule() throws Exception
{
Assume.assumeTrue(JDK.IS_9);
// jar from JVM classloader
URI mod_string = TypeUtil.getLocationOfClass(String.class);
// System.err.println(mod_string);
// a jar from maven repo jar
URI loc_junit = TypeUtil.getLocationOfClass(Test.class);
// System.err.println(loc_junit);
// class file
URI loc_test = TypeUtil.getLocationOfClass(ClasspathPatternTest.class);
// System.err.println(loc_test);
ClasspathPattern pattern = new ClasspathPattern();
pattern.include("something");
Assert.assertThat(pattern.match(String.class), Matchers.is(false));
Assert.assertThat(pattern.match(Test.class), Matchers.is(false));
Assert.assertThat(pattern.match(JDK.class), Matchers.is(false));
Assert.assertThat(pattern.match(ClasspathPatternTest.class), Matchers.is(false));
// Add module for all JVM base classes
pattern.include("jrt:/java.base");
// Add jar for individual class and classes directory
pattern.include(loc_junit.toString(), loc_test.toString());
Assert.assertThat(pattern.match(String.class), Matchers.is(true));
Assert.assertThat(pattern.match(Test.class), Matchers.is(true));
Assert.assertThat(pattern.match(JDK.class), Matchers.is(false));
Assert.assertThat(pattern.match(ClasspathPatternTest.class), Matchers.is(true));
pattern.add("-java.lang.String");
Assert.assertThat(pattern.match(String.class), Matchers.is(false));
Assert.assertThat(pattern.match(Test.class), Matchers.is(true));
Assert.assertThat(pattern.match(JDK.class), Matchers.is(false));
Assert.assertThat(pattern.match(ClasspathPatternTest.class), Matchers.is(true));
}
@SuppressWarnings("restriction")
@Test
public void testExcludeLocations() throws Exception
@ -194,6 +237,46 @@ public class ClasspathPatternTest
Assert.assertThat(pattern.match(ClasspathPatternTest.class), Matchers.is(false));
}
@SuppressWarnings("restriction")
@Test
public void testExcludeLocationsOrModule() throws Exception
{
Assume.assumeTrue(JDK.IS_9);
// jar from JVM classloader
URI mod_string = TypeUtil.getLocationOfClass(String.class);
// System.err.println(mod_string);
// a jar from maven repo jar
URI loc_junit = TypeUtil.getLocationOfClass(Test.class);
// System.err.println(loc_junit);
// class file
URI loc_test = TypeUtil.getLocationOfClass(ClasspathPatternTest.class);
// System.err.println(loc_test);
ClasspathPattern pattern = new ClasspathPattern();
// include everything
pattern.include(".");
Assert.assertThat(pattern.match(String.class), Matchers.is(true));
Assert.assertThat(pattern.match(Test.class), Matchers.is(true));
Assert.assertThat(pattern.match(JDK.class), Matchers.is(true));
Assert.assertThat(pattern.match(ClasspathPatternTest.class), Matchers.is(true));
// Add directory for both JVM classes
pattern.exclude("jrt:/java.base/");
// Add jar for individual class and classes directory
pattern.exclude(loc_junit.toString(), loc_test.toString());
Assert.assertThat(pattern.match(String.class), Matchers.is(false));
Assert.assertThat(pattern.match(Test.class), Matchers.is(false));
Assert.assertThat(pattern.match(JDK.class), Matchers.is(true));
Assert.assertThat(pattern.match(ClasspathPatternTest.class), Matchers.is(false));
}
@Test
public void testLarge()
{
@ -208,4 +291,14 @@ public class ClasspathPatternTest
Assert.assertTrue(pattern.match("n" + i + "." + Integer.toHexString(100 + i) + ".Name"));
}
}
@Test
public void testJvmModule()
{
URI uri = TypeUtil.getLocationOfClass(String.class);
System.err.println(uri);
System.err.println(uri.toString().split("/")[0]);
System.err.println(uri.toString().split("/")[1]);
}
}