我目前正在开发一个插件,可以从枚举创建降价表。 例如,如果我有这个枚举:
enum MyEnum {
/**
* Documentation for 1
*/
MYCONSTANT1(1),
MYCONSTANT2(2);
// rest is omitted
}
插件将生成此表:
代码 | 姓名 | 描述 |
---|---|---|
1 | 我的常量1 | 1 个文档 |
2 | 我的常数2 |
该插件目前需要java文件的路径才能运行,并且工作正常。
我的问题是,如果枚举位于外部工件/库中,则无法使该插件工作,因为它们存储在 jar 中。
我的感觉告诉我,应该有一种可靠的方法来使用 maven 插件 api 或其他一些库来获取 java 文件,但缺乏文档让这对我来说真的很困难。
我应该如何解决这个问题?
有没有办法通过类引用可靠地获取源文件,例如
com.example.MyEnum
?
我尝试阅读文档,但找不到有关该问题的太多信息。 我也尝试使用 chatgpt,但它产生了太多代码的幻觉,而且由于这个问题非常具体,它无法找到我可以使用的答案。
编辑
我意识到仅仅获取编译后的源文件并反编译它并不那么简单,因为它不包含文档。最好的解决方案是下载工件的源代码,然后解析类文件,就像我在源代码位于项目文件中时所做的那样。
我深入研究了 maven 插件开发文档,我发现您可以使用
RepositorySystem
组件来解析工件源。
ArtifactRequest artifactRequest = new ArtifactRequest(artifact, project.getRemoteProjectRepositories(), null);
ArtifactResult artifactResult = repositorySystem.resolveArtifact(session.getRepositorySession(), artifactRequest)
通过这种方式,您可以在插件的依赖项中定义包含类源的工件,并在运行时解析它。从那里您只需加载 jar 文件并读取其源代码。
这是通过引用获取源文件的完整示例:
private Optional<File> getSourceFile() {
return execution.getPlugin()
.getDependencies()
.stream()
.map(dependency -> findSourceFileInDependency(sourceClass, dependency))
.filter(Objects::nonNull)
.findFirst();
}
private File findSourceFileInDependency(String sourceClass, Dependency dependency) {
String sourceFileName = sourceClass.replace(".", "/") + ".java";
DefaultArtifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), "sources", "jar", dependency.getVersion());
ArtifactRequest artifactRequest = new ArtifactRequest(artifact, project.getRemoteProjectRepositories(), null);
try {
File artifactFile = repositorySystem.resolveArtifact(session.getRepositorySession(), artifactRequest)
.getArtifact()
.getFile();
try (JarFile jarFile = new JarFile(artifactFile);
InputStream sourceFileIs = jarFile.getInputStream(jarFile.getEntry(sourceFileName))) {
File sourceFile = File.createTempFile(String.format("%s_%s", UUID.randomUUID(), sourceFileName), ".java");
sourceFile.deleteOnExit();
Files.copy(sourceFileIs, sourceFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
return sourceFile;
} catch (IOException | NullPointerException e) {
}
} catch (ArtifactResolutionException e) {
}
return null;
}