Avoid recreating `Resource` during container/jar pattern filtering in `MetaInfConfiguration`
* Delete PatternMatcher.java
This commit is contained in:
parent
3b690fdefd
commit
842af3ed22
|
@ -45,6 +45,46 @@ public class FileID
|
|||
return basename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the extension of a URI path.
|
||||
* This is the name of the last segment of the URI path with a substring
|
||||
* for the extension (if any), including the dot, lower-cased.
|
||||
*
|
||||
* @param uri The URI to search
|
||||
* @return The last segment extension. Null if input uri is null, or scheme is null, or URI is not a `jar:file:` or `file:` based URI
|
||||
*/
|
||||
public static String getExtension(URI uri)
|
||||
{
|
||||
if (uri == null)
|
||||
return null;
|
||||
if (uri.getScheme() == null)
|
||||
return null;
|
||||
|
||||
String path = null;
|
||||
if (uri.getScheme().equalsIgnoreCase("jar"))
|
||||
{
|
||||
URI sspUri = URI.create(uri.getRawSchemeSpecificPart());
|
||||
if (!sspUri.getScheme().equalsIgnoreCase("file"))
|
||||
{
|
||||
return null; // not a `jar:file:` based URI
|
||||
}
|
||||
|
||||
path = sspUri.getPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
path = uri.getPath();
|
||||
}
|
||||
|
||||
// look for `!/` split
|
||||
int jarEnd = path.indexOf("!/");
|
||||
if (jarEnd >= 0)
|
||||
{
|
||||
return getExtension(path.substring(0, jarEnd));
|
||||
}
|
||||
return getExtension(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the extension of a file path (not a directory).
|
||||
* This is the name of the last segment of the file path with a substring
|
||||
|
@ -149,35 +189,10 @@ public class FileID
|
|||
*/
|
||||
public static boolean isArchive(URI uri)
|
||||
{
|
||||
if (uri == null)
|
||||
String ext = getExtension(uri);
|
||||
if (ext == null)
|
||||
return false;
|
||||
if (uri.getScheme() == null)
|
||||
return false;
|
||||
if (uri.getScheme().equalsIgnoreCase("jar"))
|
||||
{
|
||||
URI sspUri = URI.create(uri.getRawSchemeSpecificPart());
|
||||
if (!sspUri.getScheme().equalsIgnoreCase("file"))
|
||||
{
|
||||
return false; // not a `jar:file:` based URI
|
||||
}
|
||||
|
||||
String path = sspUri.getPath();
|
||||
|
||||
int jarEnd = path.indexOf("!/");
|
||||
if (jarEnd >= 0)
|
||||
{
|
||||
return isArchive(path.substring(0, jarEnd));
|
||||
}
|
||||
return isArchive(path);
|
||||
}
|
||||
String path = uri.getPath();
|
||||
// look for `!/` split
|
||||
int jarEnd = path.indexOf("!/");
|
||||
if (jarEnd >= 0)
|
||||
{
|
||||
return isArchive(path.substring(0, jarEnd));
|
||||
}
|
||||
return isArchive(path);
|
||||
return (ext.equals(".jar") || ext.equals(".war") || ext.equals(".zip"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -255,6 +270,17 @@ public class FileID
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the URI pointing to a Java Archive (JAR) File (not directory)
|
||||
*
|
||||
* @param uri the uri to test.
|
||||
* @return True if a .jar file.
|
||||
*/
|
||||
public static boolean isJavaArchive(URI uri)
|
||||
{
|
||||
return ".jar".equals(getExtension(uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the path a Java Archive (JAR) File (not directory)
|
||||
*
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class PatternMatcher
|
||||
{
|
||||
public abstract void matched(URI uri) throws Exception;
|
||||
|
||||
public void match(String pattern, URI[] uris, boolean isNullInclusive)
|
||||
throws Exception
|
||||
{
|
||||
Pattern p = (pattern == null ? null : Pattern.compile(pattern));
|
||||
match(p, uris, isNullInclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find jar names from the provided list matching a pattern.
|
||||
*
|
||||
* If the pattern is null and isNullInclusive is true, then
|
||||
* all jar names will match.
|
||||
*
|
||||
* A pattern is a set of acceptable jar names. Each acceptable
|
||||
* jar name is a regex. Each regex can be separated by either a
|
||||
* "," or a "|". If you use a "|" this or's together the jar
|
||||
* name patterns. This means that ordering of the matches is
|
||||
* unimportant to you. If instead, you want to match particular
|
||||
* jar names, and you want to match them in order, you should
|
||||
* separate the regexs with "," instead.
|
||||
*
|
||||
* Eg "aaa-.*\\.jar|bbb-.*\\.jar"
|
||||
* Will iterate over the jar names and match
|
||||
* in any order.
|
||||
*
|
||||
* Eg "aaa-*\\.jar,bbb-.*\\.jar"
|
||||
* Will iterate over the jar names, matching
|
||||
* all those starting with "aaa-" first, then "bbb-".
|
||||
*
|
||||
* @param pattern the pattern
|
||||
* @param uris the uris to test the pattern against
|
||||
* @param isNullInclusive if true, an empty pattern means all names match, if false, none match
|
||||
* @throws Exception if fundamental error in pattern matching
|
||||
*/
|
||||
public void match(Pattern pattern, URI[] uris, boolean isNullInclusive)
|
||||
throws Exception
|
||||
{
|
||||
if (uris != null)
|
||||
{
|
||||
String[] patterns = (pattern == null ? null : pattern.pattern().split(","));
|
||||
|
||||
List<Pattern> subPatterns = new ArrayList<Pattern>();
|
||||
for (int i = 0; patterns != null && i < patterns.length; i++)
|
||||
{
|
||||
subPatterns.add(Pattern.compile(patterns[i]));
|
||||
}
|
||||
if (subPatterns.isEmpty())
|
||||
subPatterns.add(pattern);
|
||||
|
||||
if (subPatterns.isEmpty())
|
||||
{
|
||||
matchPatterns(null, uris, isNullInclusive);
|
||||
}
|
||||
else
|
||||
{
|
||||
//for each subpattern, iterate over all the urls, processing those that match
|
||||
for (Pattern p : subPatterns)
|
||||
{
|
||||
matchPatterns(p, uris, isNullInclusive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void matchPatterns(Pattern pattern, URI[] uris, boolean isNullInclusive)
|
||||
throws Exception
|
||||
{
|
||||
for (int i = 0; i < uris.length; i++)
|
||||
{
|
||||
URI uri = uris[i];
|
||||
String s = uri.toString();
|
||||
if ((pattern == null && isNullInclusive) ||
|
||||
(pattern != null && pattern.matcher(s).matches()))
|
||||
{
|
||||
matched(uris[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1759,15 +1759,8 @@ public final class URIUtil
|
|||
{
|
||||
// Simple reference
|
||||
URI refUri = toURI(reference);
|
||||
// Is this a Java Archive that can be mounted?
|
||||
URI jarFileUri = toJarFileUri(refUri);
|
||||
if (jarFileUri != null)
|
||||
// add as mountable URI
|
||||
uris.add(jarFileUri);
|
||||
else
|
||||
// add as normal URI
|
||||
uris.add(refUri);
|
||||
|
||||
// Ensure that a Java Archive that can be mounted
|
||||
uris.add(toJarFileUri(refUri));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -1785,7 +1778,7 @@ public final class URIUtil
|
|||
* The resulting URI will point to the {@code jar:file://foo.jar!/} said Java Archive (jar, war, or zip)
|
||||
*
|
||||
* @param uri the URI to mutate to a {@code jar:file:...} URI.
|
||||
* @return the <code>jar:${uri_to_java_archive}!/${internal-reference}</code> URI or null if not a Java Archive.
|
||||
* @return the <code>jar:${uri_to_java_archive}!/${internal-reference}</code> URI or the unchanged URI if not a Java Archive.
|
||||
* @see FileID#isArchive(URI)
|
||||
*/
|
||||
public static URI toJarFileUri(URI uri)
|
||||
|
@ -1794,7 +1787,7 @@ public final class URIUtil
|
|||
String scheme = Objects.requireNonNull(uri.getScheme(), "URI scheme");
|
||||
|
||||
if (!FileID.isArchive(uri))
|
||||
return null;
|
||||
return uri;
|
||||
|
||||
boolean hasInternalReference = uri.getRawSchemeSpecificPart().indexOf("!/") > 0;
|
||||
|
||||
|
@ -1835,11 +1828,9 @@ public final class URIUtil
|
|||
Objects.requireNonNull(resource);
|
||||
|
||||
// Only try URI for string for known schemes, otherwise assume it is a Path
|
||||
URI uri = (KNOWN_SCHEMES.getBest(resource) != null)
|
||||
? URI.create(resource)
|
||||
return (KNOWN_SCHEMES.getBest(resource) != null)
|
||||
? correctFileURI(URI.create(resource))
|
||||
: Paths.get(resource).toUri();
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Predicate for matching {@link URI} against a provided Regex {@link Pattern}
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If the pattern is null and isNullInclusive is true, then
|
||||
* all URIs will match.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* A pattern is a set of acceptable URI names. Each acceptable
|
||||
* name is a regex. Each regex can be separated by either a
|
||||
* "," or a "|". If you use a "|" this or's together the URI
|
||||
* name patterns. This means that ordering of the matches is
|
||||
* unimportant to you. If instead, you want to match particular
|
||||
* names, and you want to match them in order, you should
|
||||
* separate the regexs with "," instead.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Eg "aaa-.*\\.jar|bbb-.*\\.jar"
|
||||
* Will iterate over the jar names and match in any order.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Eg "aaa-*\\.jar,bbb-.*\\.jar"
|
||||
* Will iterate over the jar names, matching
|
||||
* all those starting with "aaa-" first, then "bbb-".
|
||||
* </p>
|
||||
*/
|
||||
public class UriPatternPredicate implements Predicate<URI>
|
||||
{
|
||||
private final List<Pattern> subPatterns;
|
||||
private final boolean isNullInclusive;
|
||||
|
||||
public UriPatternPredicate(String regex, boolean isNullInclusive)
|
||||
{
|
||||
this(regex == null ? null : Pattern.compile(regex), isNullInclusive);
|
||||
}
|
||||
|
||||
public UriPatternPredicate(Pattern pattern, boolean isNullInclusive)
|
||||
{
|
||||
this.isNullInclusive = isNullInclusive;
|
||||
String[] patterns = (pattern == null ? null : pattern.pattern().split(","));
|
||||
|
||||
subPatterns = new ArrayList<>();
|
||||
for (int i = 0; patterns != null && i < patterns.length; i++)
|
||||
{
|
||||
subPatterns.add(Pattern.compile(patterns[i]));
|
||||
}
|
||||
if (subPatterns.isEmpty())
|
||||
subPatterns.add(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(URI uri)
|
||||
{
|
||||
if (subPatterns.isEmpty())
|
||||
{
|
||||
return match(null, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
// for each sub-pattern, test if a match
|
||||
for (Pattern p : subPatterns)
|
||||
{
|
||||
if (match(p, uri))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean match(Pattern pattern, URI uri)
|
||||
{
|
||||
String s = uri.toString();
|
||||
return ((pattern == null && isNullInclusive) ||
|
||||
(pattern != null && pattern.matcher(s).matches()));
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ public class MountedPathResource extends PathResource
|
|||
@Override
|
||||
public boolean isContainedIn(Resource r)
|
||||
{
|
||||
return r.getURI().equals(containerUri);
|
||||
return URIUtil.unwrapContainer(r.getURI()).equals(containerUri);
|
||||
}
|
||||
|
||||
public Path getContainerPath()
|
||||
|
|
|
@ -81,10 +81,6 @@ public class ResourceCollection extends Resource
|
|||
throw new IllegalArgumentException("Does not exist: " + r);
|
||||
}
|
||||
|
||||
if (!r.isDirectory())
|
||||
{
|
||||
throw new IllegalArgumentException("Not a directory: " + r);
|
||||
}
|
||||
unique.add(r);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util.resource;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.eclipse.jetty.util.UriPatternPredicate;
|
||||
|
||||
/**
|
||||
* Specialized {@link UriPatternPredicate} to allow filtering {@link Resource} entries by their URI.
|
||||
*/
|
||||
public class ResourceUriPatternPredicate implements Predicate<Resource>
|
||||
{
|
||||
private final Predicate<URI> uriPredicate;
|
||||
|
||||
public ResourceUriPatternPredicate(String regex, boolean isNullInclusive)
|
||||
{
|
||||
this(new UriPatternPredicate(regex, isNullInclusive));
|
||||
}
|
||||
|
||||
public ResourceUriPatternPredicate(UriPatternPredicate uriPredicate)
|
||||
{
|
||||
this.uriPredicate = Objects.requireNonNull(uriPredicate, "UriPatternPredicate cannot be null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Resource resource)
|
||||
{
|
||||
if (resource == null)
|
||||
return false;
|
||||
URI uri = resource.getURI();
|
||||
return uriPredicate.test(uri);
|
||||
}
|
||||
}
|
|
@ -903,7 +903,8 @@ public class URIUtilTest
|
|||
// Bad java file.uri syntax
|
||||
String input = "file:/home/user/lib/acme.jar";
|
||||
List<URI> uris = URIUtil.split(input);
|
||||
String expected = String.format("jar:%s!/", input);
|
||||
// As zipfs with corrected file.uri syntax as well
|
||||
String expected = "jar:file:///home/user/lib/acme.jar!/";
|
||||
assertThat(uris.get(0).toString(), is(expected));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.net.URL;
|
|||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -33,16 +34,18 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.FileID;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.UriPatternPredicate;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.ResourceUriPatternPredicate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -79,73 +82,6 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern";
|
||||
public static final List<String> __allScanTypes = Arrays.asList(METAINF_TLDS, METAINF_RESOURCES, METAINF_FRAGMENTS);
|
||||
|
||||
/**
|
||||
* ContainerPathNameMatcher
|
||||
*
|
||||
* Matches names of jars on the container classpath
|
||||
* against a pattern. If no pattern is specified, no
|
||||
* jars match.
|
||||
*/
|
||||
public class ContainerPathNameMatcher extends PatternMatcher
|
||||
{
|
||||
protected final WebAppContext _context;
|
||||
protected final String _pattern;
|
||||
|
||||
public ContainerPathNameMatcher(WebAppContext context, String pattern)
|
||||
{
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException("Context null");
|
||||
_context = context;
|
||||
_pattern = pattern;
|
||||
}
|
||||
|
||||
public void match(List<URI> uris) throws Exception
|
||||
{
|
||||
if (uris == null)
|
||||
return;
|
||||
match(_pattern, uris.toArray(new URI[uris.size()]), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matched(URI uri)
|
||||
{
|
||||
_context.getMetaData().addContainerResource(_resourceFactory.newResource(uri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WebAppPathNameMatcher
|
||||
*
|
||||
* Matches names of jars or dirs on the webapp classpath
|
||||
* against a pattern. If there is no pattern, all jars or dirs
|
||||
* will match.
|
||||
*/
|
||||
public class WebAppPathNameMatcher extends PatternMatcher
|
||||
{
|
||||
protected final WebAppContext _context;
|
||||
protected final String _pattern;
|
||||
|
||||
public WebAppPathNameMatcher(WebAppContext context, String pattern)
|
||||
{
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException("Context null");
|
||||
_context = context;
|
||||
_pattern = pattern;
|
||||
}
|
||||
|
||||
public void match(List<URI> uris)
|
||||
throws Exception
|
||||
{
|
||||
match(_pattern, uris.toArray(new URI[uris.size()]), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matched(URI uri)
|
||||
{
|
||||
_context.getMetaData().addWebInfResource(_resourceFactory.newResource(uri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, to a list of URLs, these resources are added to the context
|
||||
* resource base as a resource collection.
|
||||
|
@ -209,28 +145,29 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
|
||||
// Apply an initial name filter to the jars to select which will be eventually
|
||||
// scanned for META-INF info and annotations. The filter is based on inclusion patterns.
|
||||
ContainerPathNameMatcher containerPathNameMatcher = new ContainerPathNameMatcher(context, pattern);
|
||||
List<URI> containerUris = getAllContainerJars(context);
|
||||
UriPatternPredicate uriPatternPredicate = new UriPatternPredicate(pattern, false);
|
||||
Consumer<URI> addContainerResource = (uri) ->
|
||||
{
|
||||
Resource resource = _resourceFactory.newResource(uri);
|
||||
context.getMetaData().addContainerResource(resource);
|
||||
};
|
||||
|
||||
List<URI> containerUris = getAllContainerJars(context);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("All container urls {}", containerUris);
|
||||
containerPathNameMatcher.match(containerUris);
|
||||
containerUris.stream()
|
||||
.filter(uriPatternPredicate)
|
||||
.forEach(addContainerResource);
|
||||
|
||||
// When running on jvm 9 or above, we we won't be able to look at the application
|
||||
// When running on jvm 9 or above, we won't be able to look at the application
|
||||
// classloader to extract urls, so we need to examine the classpath instead.
|
||||
String classPath = System.getProperty("java.class.path");
|
||||
if (classPath != null)
|
||||
{
|
||||
List<URI> cpUris = new ArrayList<>();
|
||||
String[] entries = classPath.split(File.pathSeparator);
|
||||
for (String entry : entries)
|
||||
{
|
||||
File f = new File(entry);
|
||||
cpUris.add(f.toURI());
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Matching java.class.path {}", cpUris);
|
||||
containerPathNameMatcher.match(cpUris);
|
||||
Stream.of(classPath.split(File.pathSeparator))
|
||||
.map(URIUtil::toURI)
|
||||
.filter(uriPatternPredicate)
|
||||
.forEach(addContainerResource);
|
||||
}
|
||||
|
||||
// We also need to examine the module path.
|
||||
|
@ -240,30 +177,31 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
String modulePath = System.getProperty("jdk.module.path");
|
||||
if (modulePath != null)
|
||||
{
|
||||
List<URI> moduleUris = new ArrayList<>();
|
||||
String[] entries = modulePath.split(File.pathSeparator);
|
||||
for (String entry : entries)
|
||||
List<Path> matchingBasePaths =
|
||||
Stream.of(modulePath.split(File.pathSeparator))
|
||||
.map(URIUtil::toURI)
|
||||
.filter(uriPatternPredicate)
|
||||
.map(Paths::get)
|
||||
.toList();
|
||||
for (Path path: matchingBasePaths)
|
||||
{
|
||||
File file = new File(entry);
|
||||
if (file.isDirectory())
|
||||
if (Files.isDirectory(path))
|
||||
{
|
||||
File[] files = file.listFiles();
|
||||
if (files != null)
|
||||
try (Stream<Path> listing = Files.list(path))
|
||||
{
|
||||
for (File f : files)
|
||||
for (Path listEntry: listing.toList())
|
||||
{
|
||||
moduleUris.add(f.toURI());
|
||||
Resource resource = _resourceFactory.newResource(listEntry);
|
||||
context.getMetaData().addContainerResource(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
moduleUris.add(file.toURI());
|
||||
Resource resource = _resourceFactory.newResource(path);
|
||||
context.getMetaData().addContainerResource(resource);
|
||||
}
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Matching jdk.module.path {}", moduleUris);
|
||||
containerPathNameMatcher.match(moduleUris);
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -286,22 +224,18 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
//Apply filter to WEB-INF/lib jars
|
||||
String pattern = (String)context.getAttribute(WEBINF_JAR_PATTERN);
|
||||
WebAppPathNameMatcher matcher = new WebAppPathNameMatcher(context, pattern);
|
||||
ResourceUriPatternPredicate webinfPredicate = new ResourceUriPatternPredicate(pattern, true);
|
||||
|
||||
List<Resource> jars = findJars(context);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("webapp {}={} jars {}", WEBINF_JAR_PATTERN, pattern, jars);
|
||||
|
||||
//Convert to uris for matching
|
||||
// Only add matching Resources to metadata.webInfResources
|
||||
if (jars != null)
|
||||
{
|
||||
List<URI> uris = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (Resource r : jars)
|
||||
{
|
||||
uris.add(r.getURI());
|
||||
}
|
||||
matcher.match(uris);
|
||||
jars.stream()
|
||||
.filter(webinfPredicate)
|
||||
.forEach(resource -> context.getMetaData().addWebInfResource(resource));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.net.URL;
|
|||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -33,16 +34,18 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.FileID;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.UriPatternPredicate;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.ResourceUriPatternPredicate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -79,73 +82,6 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern";
|
||||
public static final List<String> __allScanTypes = Arrays.asList(METAINF_TLDS, METAINF_RESOURCES, METAINF_FRAGMENTS);
|
||||
|
||||
/**
|
||||
* ContainerPathNameMatcher
|
||||
*
|
||||
* Matches names of jars on the container classpath
|
||||
* against a pattern. If no pattern is specified, no
|
||||
* jars match.
|
||||
*/
|
||||
public class ContainerPathNameMatcher extends PatternMatcher
|
||||
{
|
||||
protected final WebAppContext _context;
|
||||
protected final String _pattern;
|
||||
|
||||
public ContainerPathNameMatcher(WebAppContext context, String pattern)
|
||||
{
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException("Context null");
|
||||
_context = context;
|
||||
_pattern = pattern;
|
||||
}
|
||||
|
||||
public void match(List<URI> uris) throws Exception
|
||||
{
|
||||
if (uris == null)
|
||||
return;
|
||||
match(_pattern, uris.toArray(new URI[uris.size()]), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matched(URI uri)
|
||||
{
|
||||
_context.getMetaData().addContainerResource(_resourceFactory.newResource(uri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WebAppPathNameMatcher
|
||||
*
|
||||
* Matches names of jars or dirs on the webapp classpath
|
||||
* against a pattern. If there is no pattern, all jars or dirs
|
||||
* will match.
|
||||
*/
|
||||
public class WebAppPathNameMatcher extends PatternMatcher
|
||||
{
|
||||
protected final WebAppContext _context;
|
||||
protected final String _pattern;
|
||||
|
||||
public WebAppPathNameMatcher(WebAppContext context, String pattern)
|
||||
{
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException("Context null");
|
||||
_context = context;
|
||||
_pattern = pattern;
|
||||
}
|
||||
|
||||
public void match(List<URI> uris)
|
||||
throws Exception
|
||||
{
|
||||
match(_pattern, uris.toArray(new URI[uris.size()]), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matched(URI uri)
|
||||
{
|
||||
_context.getMetaData().addWebInfResource(_resourceFactory.newResource(uri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, to a list of URLs, these resources are added to the context
|
||||
* resource base as a resource collection.
|
||||
|
@ -202,33 +138,36 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
public void findAndFilterContainerPaths(final WebAppContext context) throws Exception
|
||||
{
|
||||
String pattern = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{}={}", CONTAINER_JAR_PATTERN, pattern);
|
||||
if (StringUtil.isBlank(pattern))
|
||||
return; // TODO review if this short cut will allow later code simplifications
|
||||
|
||||
// Apply an initial name filter to the jars to select which will be eventually
|
||||
// scanned for META-INF info and annotations. The filter is based on inclusion patterns.
|
||||
ContainerPathNameMatcher containerPathNameMatcher = new ContainerPathNameMatcher(context, pattern);
|
||||
UriPatternPredicate uriPatternPredicate = new UriPatternPredicate(pattern, false);
|
||||
Consumer<URI> addContainerResource = (uri) ->
|
||||
{
|
||||
Resource resource = _resourceFactory.newResource(uri);
|
||||
context.getMetaData().addContainerResource(resource);
|
||||
};
|
||||
|
||||
List<URI> containerUris = getAllContainerJars(context);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Matching container urls {}", containerUris);
|
||||
containerPathNameMatcher.match(containerUris);
|
||||
LOG.debug("All container urls {}", containerUris);
|
||||
containerUris.stream()
|
||||
.filter(uriPatternPredicate)
|
||||
.forEach(addContainerResource);
|
||||
|
||||
// When running on jvm 9 or above, we we won't be able to look at the application
|
||||
// When running on jvm 9 or above, we won't be able to look at the application
|
||||
// classloader to extract urls, so we need to examine the classpath instead.
|
||||
String classPath = System.getProperty("java.class.path");
|
||||
if (classPath != null)
|
||||
{
|
||||
List<URI> cpUris = new ArrayList<>();
|
||||
String[] entries = classPath.split(File.pathSeparator);
|
||||
for (String entry : entries)
|
||||
{
|
||||
File f = new File(entry);
|
||||
cpUris.add(f.toURI());
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Matching java.class.path {}", cpUris);
|
||||
containerPathNameMatcher.match(cpUris);
|
||||
Stream.of(classPath.split(File.pathSeparator))
|
||||
.map(URIUtil::toURI)
|
||||
.filter(uriPatternPredicate)
|
||||
.forEach(addContainerResource);
|
||||
}
|
||||
|
||||
// We also need to examine the module path.
|
||||
|
@ -238,30 +177,31 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
String modulePath = System.getProperty("jdk.module.path");
|
||||
if (modulePath != null)
|
||||
{
|
||||
List<URI> moduleUris = new ArrayList<>();
|
||||
String[] entries = modulePath.split(File.pathSeparator);
|
||||
for (String entry : entries)
|
||||
List<Path> matchingBasePaths =
|
||||
Stream.of(modulePath.split(File.pathSeparator))
|
||||
.map(URIUtil::toURI)
|
||||
.filter(uriPatternPredicate)
|
||||
.map(Paths::get)
|
||||
.toList();
|
||||
for (Path path: matchingBasePaths)
|
||||
{
|
||||
File file = new File(entry);
|
||||
if (file.isDirectory())
|
||||
if (Files.isDirectory(path))
|
||||
{
|
||||
File[] files = file.listFiles();
|
||||
if (files != null)
|
||||
try (Stream<Path> listing = Files.list(path))
|
||||
{
|
||||
for (File f : files)
|
||||
for (Path listEntry: listing.toList())
|
||||
{
|
||||
moduleUris.add(f.toURI());
|
||||
Resource resource = _resourceFactory.newResource(listEntry);
|
||||
context.getMetaData().addContainerResource(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
moduleUris.add(file.toURI());
|
||||
Resource resource = _resourceFactory.newResource(path);
|
||||
context.getMetaData().addContainerResource(resource);
|
||||
}
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Matching jdk.module.path {}", moduleUris);
|
||||
containerPathNameMatcher.match(moduleUris);
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -283,19 +223,19 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
throws Exception
|
||||
{
|
||||
//Apply filter to WEB-INF/lib jars
|
||||
WebAppPathNameMatcher matcher = new WebAppPathNameMatcher(context, (String)context.getAttribute(WEBINF_JAR_PATTERN));
|
||||
String pattern = (String)context.getAttribute(WEBINF_JAR_PATTERN);
|
||||
ResourceUriPatternPredicate webinfPredicate = new ResourceUriPatternPredicate(pattern, true);
|
||||
|
||||
List<Resource> jars = findJars(context);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("webapp {}={} jars {}", WEBINF_JAR_PATTERN, pattern, jars);
|
||||
|
||||
//Convert to uris for matching
|
||||
// Only add matching Resources to metadata.webInfResources
|
||||
if (jars != null)
|
||||
{
|
||||
List<URI> uris = new ArrayList<>();
|
||||
for (Resource r : jars)
|
||||
{
|
||||
uris.add(r.getURI());
|
||||
}
|
||||
matcher.match(uris);
|
||||
jars.stream()
|
||||
.filter(webinfPredicate)
|
||||
.forEach(resource -> context.getMetaData().addWebInfResource(resource));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue