in adapter/runtime/src/main/java/org/apache/rocketmq/eventbridge/adapter/runtime/common/plugin/PluginUtils.java [146:223]
public static List<Path> pluginUrls(Path topPath) throws IOException {
boolean containsClassFiles = false;
Set<Path> archives = new TreeSet<>();
LinkedList<DirectoryEntry> dfs = new LinkedList<>();
Set<Path> visited = new HashSet<>();
if (isArchive(topPath)) {
return Collections.singletonList(topPath);
}
DirectoryStream<Path> topListing = Files.newDirectoryStream(
topPath,
PLUGIN_PATH_FILTER
);
dfs.push(new DirectoryEntry(topListing));
visited.add(topPath);
try {
while (!dfs.isEmpty()) {
Iterator<Path> neighbors = dfs.peek().iterator;
if (!neighbors.hasNext()) {
dfs.pop().stream.close();
continue;
}
Path adjacent = neighbors.next();
if (Files.isSymbolicLink(adjacent)) {
try {
Path symlink = Files.readSymbolicLink(adjacent);
Path parent = adjacent.getParent();
if (parent == null) {
continue;
}
Path absolute = parent.resolve(symlink).toRealPath();
if (Files.exists(absolute)) {
adjacent = absolute;
} else {
continue;
}
} catch (IOException e) {
log.warn(
"Resolving symbolic link '{}' failed. Ignoring this path.",
adjacent,
e
);
continue;
}
}
if (!visited.contains(adjacent)) {
visited.add(adjacent);
if (isArchive(adjacent)) {
archives.add(adjacent);
} else if (isClassFile(adjacent)) {
containsClassFiles = true;
} else {
DirectoryStream<Path> listing = Files.newDirectoryStream(
adjacent,
PLUGIN_PATH_FILTER
);
dfs.push(new DirectoryEntry(listing));
}
}
}
} finally {
while (!dfs.isEmpty()) {
dfs.pop().stream.close();
}
}
if (containsClassFiles) {
if (archives.isEmpty()) {
return Collections.singletonList(topPath);
}
log.warn("Plugin path contains both java archives and class files. Returning only the"
+ " archives");
}
return Arrays.asList(archives.toArray(new Path[0]));
}