diff options
Diffstat (limited to 'src/main/java/org/glavo/javah/SearchPath.java')
-rw-r--r-- | src/main/java/org/glavo/javah/SearchPath.java | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/src/main/java/org/glavo/javah/SearchPath.java b/src/main/java/org/glavo/javah/SearchPath.java index b95b7c0..adbe27d 100644 --- a/src/main/java/org/glavo/javah/SearchPath.java +++ b/src/main/java/org/glavo/javah/SearchPath.java @@ -1,7 +1,92 @@ package org.glavo.javah; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.*; +import java.util.jar.Manifest; +import java.util.stream.Collectors; + +import static org.glavo.javah.Utils.*; public interface SearchPath { - Path searchClass(String className) ; + Path search(ClassName name); + + default Path search(String fullName) { + Objects.requireNonNull(fullName); + return search(ClassName.of(fullName)); + } + + static Path searchFrom(Iterable<SearchPath> searchPaths, ClassName name) { + Objects.requireNonNull(searchPaths); + Objects.requireNonNull(name); + + for (SearchPath searchPath : searchPaths) { + if (searchPath == null) { + continue; + } + Path p = searchPath.search(name); + if (p != null) { + return p; + } + } + return null; + } + + static Path searchFromRoots(Iterable<Path> roots, ClassName name) { + Objects.requireNonNull(roots); + Objects.requireNonNull(name); + for (Path root : roots) { + if (root == null || !Files.isDirectory(root)) { + continue; + } + + Path p = root.resolve(name.relativePath()); + if (Files.isRegularFile(p)) { + return p; + } + if (Files.isSymbolicLink(p)) { + try { + p = Files.readSymbolicLink(p); + if (Files.isRegularFile(p)) { + return p; + } + } catch (IOException ignored) { + } + } + } + + return null; + } + + static List<Path> multiReleaseRoots(Path root) { + Objects.requireNonNull(root); + if (!Files.isDirectory(root)) { + return Collections.emptyList(); + } + boolean isMultiRelease = false; + try (InputStream in = Files.newInputStream(root.resolve("META-INF").resolve("MANIFEST.MF"))) { + isMultiRelease = "true".equals(new Manifest(in).getMainAttributes().getValue("Multi-Release")); + } catch (IOException | NullPointerException ignored) { + } + + if (isMultiRelease) { + Path base = root.resolve("META-INF").resolve("versions"); + if (Files.isDirectory(base)) { + try { + List<Path> list = Files.list(base) + .map(Path::toAbsolutePath) + .filter(Files::isDirectory) + .filter(p -> MULTI_RELEASE_VERSIONS.contains(p.getFileName().toString())) + .sorted(Comparator.comparing((Path p) -> Integer.parseInt(p.getFileName().toString())).reversed()) + .collect(Collectors.toCollection(LinkedList::new)); + list.add(root); + return Collections.unmodifiableList(list); + } catch (IOException ignored) { + } + } + } + return Collections.singletonList(root); + } } |