JarFileScanner.java
- package org.jbehave.core.io;
- import static java.util.Arrays.asList;
- import static org.apache.commons.lang3.StringUtils.isBlank;
- import java.io.File;
- import java.io.IOException;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Enumeration;
- import java.util.List;
- import java.util.jar.JarEntry;
- import java.util.jar.JarFile;
- import java.util.stream.Collectors;
- import org.codehaus.plexus.util.SelectorUtils;
- /**
- * Find all matching file entries in a jar.
- */
- public class JarFileScanner {
- private URL jarURL;
- private List<String> includes;
- private List<String> excludes;
- public JarFileScanner(String jarPath, String includes, String excludes) {
- this(jarPath, asList(includes), asList(excludes));
- }
- public JarFileScanner(String jarPath, List<String> includes, List<String> excludes) {
- this(CodeLocations.codeLocationFromPath(jarPath), includes, excludes);
- }
- public JarFileScanner(URL jarURL, String includes, String excludes) {
- this(jarURL, asList(includes), asList(excludes));
- }
- public JarFileScanner(URL jarURL, List<String> includes, List<String> excludes) {
- this.jarURL = jarURL;
- this.includes = includes != null ? toLocalPath(includes) : Arrays.<String>asList();
- this.excludes = excludes != null ? toLocalPath(excludes) : Arrays.<String>asList();
- }
- /**
- * Scans the jar file and returns the paths that match the includes and excludes.
- *
- * @return A List of paths
- * @throws An IllegalStateException when an I/O error occurs in reading the jar file.
- */
- public List<String> scan() {
- try {
- JarFile jar = new JarFile(jarURL.getFile());
- try {
- List<String> result = new ArrayList<>();
- Enumeration<JarEntry> en = jar.entries();
- while (en.hasMoreElements()) {
- JarEntry entry = en.nextElement();
- String path = entry.getName();
- boolean match = includes.size() == 0;
- if (!match) {
- for (String pattern : includes) {
- if (patternMatches(pattern, path)) {
- match = true;
- break;
- }
- }
- }
- if (match) {
- for (String pattern : excludes) {
- if (patternMatches(pattern, path)) {
- match = false;
- break;
- }
- }
- }
- if (match) {
- result.add(path);
- }
- }
- return result;
- } finally {
- jar.close();
- }
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
- private List<String> toLocalPath(List<String> patternList) {
- return patternList.stream()
- .map(pattern -> pattern != null ? pattern.replace('/', File.separatorChar) : null)
- .collect(Collectors.toList());
- }
- private boolean patternMatches(String pattern, String path) {
- if (isBlank(pattern)) {
- return false;
- }
- // SelectorUtils assumes local path separator for path and pattern
- String localPath = path.replace('/', File.separatorChar);
- return SelectorUtils.matchPath(pattern, localPath);
- }
- }