Skip to content

Commit

Permalink
possible fix for #520, jar scanning should work
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrthomas committed Oct 2, 2018
1 parent e751728 commit 26a13b1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 72 deletions.
117 changes: 48 additions & 69 deletions karate-core/src/main/java/com/intuit/karate/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
import java.nio.charset.StandardCharsets;
import com.intuit.karate.core.Feature;
import com.intuit.karate.core.FeatureParser;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
Expand Down Expand Up @@ -59,10 +62,10 @@ public static final boolean isClassPath(String text) {
public static final boolean isFilePath(String text) {
return text.startsWith(FILE_COLON);
}

public static final boolean isThisPath(String text) {
return text.startsWith(THIS_COLON);
}
}

public static final boolean isJsonFile(String text) {
return text.endsWith(".json");
Expand Down Expand Up @@ -345,7 +348,8 @@ public static String toRelativeClassPath(Path path, ClassLoader cl) {
if (!isFile(path)) {
return CLASSPATH_COLON + toStandardPath(path.toString());
}
for (Path rootPath : getAllClassPaths(cl)) {
for (URL url : getAllClassPathUrls(cl)) {
Path rootPath = getPathFor(url);
if (path.startsWith(rootPath)) {
Path relativePath = rootPath.relativize(path);
return CLASSPATH_COLON + toStandardPath(relativePath.toString());
Expand All @@ -360,19 +364,10 @@ public static File getDirContaining(Class clazz) {
}

public static Path getPathContaining(Class clazz) {
String relativePath = clazz.getPackage().getName().replace('.', '/');
ClassLoader cl = clazz.getClassLoader();
Path path = getPathIfJar(relativePath, cl);
if (path != null) {
return path;
}
// get file path
try {
URL url = cl.getResource(relativePath);
return Paths.get(url.toURI());
} catch (Exception e) {
throw new RuntimeException(e);
}
Package p = clazz.getPackage();
String relative = p.getName().replace('.', '/');
URL url = clazz.getClassLoader().getResource(relative);
return getPathFor(url);
}

public static File getFileRelativeTo(Class clazz, String path) {
Expand Down Expand Up @@ -416,15 +411,34 @@ public static List<Resource> scanForFeatureFiles(List<String> paths, ClassLoader
}
return list;
}

private static Path getPathFor(URL url) {
try {
if (url.toString().contains("!/")) {
FileSystem fs = getFileSystem(url.toURI());
return fs.getRootDirectories().iterator().next();
} else {
return Paths.get(url.toURI());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static List<Path> getAllClassPaths(ClassLoader classLoader) {
public static List<URL> getAllClassPathUrls(ClassLoader classLoader) {
try {
List<Path> list = new ArrayList();
List<URL> list = new ArrayList();
Enumeration<URL> iterator = classLoader.getResources("");
while (iterator.hasMoreElements()) {
URL url = iterator.nextElement();
list.add(Paths.get(url.toURI()));
list.add(url);
}
if (classLoader instanceof URLClassLoader) {
for (URL u : ((URLClassLoader) classLoader).getURLs()) {
URL url = new URL("jar:" + u + "!/");
list.add(url);
}
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
Expand All @@ -444,31 +458,12 @@ private static FileSystem getFileSystem(URI uri) {
}
}

private static Path getPathIfJar(String relativePath, ClassLoader cl) {
try {
URL url = cl.getResource(relativePath);
if (url != null && url.toURI().getScheme().equals("jar")) {
FileSystem fileSystem = getFileSystem(url.toURI());
return fileSystem.getPath(relativePath);
} else {
return null;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static List<Resource> scanForFeatureFiles(boolean classpath, String searchPath, ClassLoader cl) {
List<Resource> files = new ArrayList();
if (classpath) {
searchPath = removePrefix(searchPath);
Path search = getPathIfJar(searchPath, cl);
if (search != null) {
collectFeatureFilesFromJar(search, files);
} else {
for (Path rootPath : getAllClassPaths(cl)) {
collectFeatureFiles(rootPath, searchPath, files);
}
for (URL url : getAllClassPathUrls(cl)) {
collectFeatureFiles(url, searchPath, files);
}
return files;
} else {
Expand All @@ -477,27 +472,27 @@ public static List<Resource> scanForFeatureFiles(boolean classpath, String searc
}
}

private static void collectFeatureFiles(Path rootPath, String searchPath, List<Resource> files) {
boolean classpath = rootPath != null;
private static void collectFeatureFiles(URL url, String searchPath, List<Resource> files) {
boolean classpath = url != null;
Path rootPath;
Path search;
if (classpath) {
rootPath = getPathFor(url);
search = rootPath.resolve(searchPath);
if (!search.toFile().exists()) {
return;
}
} else {
rootPath = new File(".").getAbsoluteFile().toPath();
search = Paths.get(searchPath);
}
Stream<Path> stream;
try {
stream = Files.walk(search);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (IOException e) { // NoSuchFileException
return;
}
for (Iterator<Path> paths = stream.iterator(); paths.hasNext();) {
Path path = paths.next();
if (path.getFileName().toString().endsWith(".feature")) {
Path fileName = path.getFileName();
if (fileName != null && fileName.toString().endsWith(".feature")) {
String relativePath = rootPath.relativize(path.toAbsolutePath()).toString();
relativePath = relativePath.replaceAll("[.]{2,}", "");
if (relativePath.charAt(0) == '/') {
Expand All @@ -508,45 +503,29 @@ private static void collectFeatureFiles(Path rootPath, String searchPath, List<R
}
}
}

private static void collectFeatureFilesFromJar(Path searchPath, List<Resource> files) {
Stream<Path> stream;
try {
stream = Files.walk(searchPath);
} catch (IOException e) {
throw new RuntimeException(e);
}
for (Iterator<Path> paths = stream.iterator(); paths.hasNext();) {
Path path = paths.next();
if (path.getFileName().toString().endsWith(".feature")) {
Resource resource = new Resource(path, CLASSPATH_COLON + toStandardPath(path.toString()));
files.add(resource);
}
}
}

public static enum Platform {
WINDOWS,
MAC,
UNIX,
UNKNOWN
}

public static boolean isWindows() {
return getPlatform() == Platform.WINDOWS;
}

public static Platform getPlatform() {
String os = System.getProperty("os.name", "").toLowerCase();
if (os.contains("win")) {
String os = System.getProperty("os.name", "").toLowerCase();
if (os.contains("win")) {
return Platform.WINDOWS;
} else if (os.contains("mac")) {
return Platform.MAC;
} else if (os.contains("nix") || os.contains("nux")) {
return Platform.UNIX;
} else {
return Platform.UNKNOWN;
}
}
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.intuit.karate;

import java.io.File;
import java.net.URL;
import java.util.List;

import static org.junit.Assert.*;
Expand Down Expand Up @@ -65,7 +66,10 @@ public void testRelativePathForClass() {

@Test
public void testGetAllClasspaths() {
FileUtils.getAllClassPaths(getClass().getClassLoader());
List<URL> urls = FileUtils.getAllClassPathUrls(getClass().getClassLoader());
for (URL url : urls) {
logger.debug("url: {}", url);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ public void testFileUtilsForJarFile() throws Exception {
Path path = FileUtils.getPathContaining(main);
assertFalse(FileUtils.isFile(path));
String relativePath = FileUtils.toRelativeClassPath(path, cl);
assertEquals("classpath:demo/jar1", relativePath);
path = FileUtils.fromRelativeClassPath(relativePath, cl);
assertEquals("classpath:/", relativePath);
path = FileUtils.fromRelativeClassPath("classpath:demo/jar1", cl);
assertEquals(path.toString(), "/demo/jar1");
}

Expand Down

0 comments on commit 26a13b1

Please sign in to comment.