您可以使用以太从 POM 获取插件配置吗?

Can you get plugin configuration from a POM using aether?

我需要阅读 Java 中的插件配置。我已经使用 aether 库获取 运行 时间依赖性、编译时间依赖性等。但是我可以使用 aether 读取基于 pom 文件的插件配置吗?

像这样

<properties>
  <servicePort>8080</servicePort>
  <adminPort>8081</adminPort>
</properties>

<build>
  <plugins>
    <plugin>
      <groupId>com.company.group</groupId>
      <artifactId>my-plugin</artifactId>
      <version>0.1-SNAPSHOT</version>
      <configuration>
        <myConfig>
          <somePropName>someProp</somePropName>
          <portMappings>
            <someProp>${servicePort}</someProp>
            <someProp-admin>${adminPort}</someProp-admin>
          </portMappings>
        </myConfig>
      </configuration>
    </plugin>
  </plugins>
</build>

我希望能够解决

some-Prop 8080
some-prop-admin 8081 

来自这个机制

目前我像这样获取编译关系依赖项

Dependency dependency = new Dependency(new DefaultArtifact(
                    coordinate), COMPILE);
CollectRequest collectRequest = new CollectRequest();
collectRequest.setRoot(dependency);

collectRequest.addRepository(this.aetherSession
        .getRemoteRepository());
DependencyNode node = this.aetherSession
        .getRepoSystem()
        .collectDependencies(this.aetherSession.getRepoSession(),
                collectRequest).getRoot();
DependencyRequest dependencyRequest = new DependencyRequest();
dependencyRequest.setRoot(node);
result = this.aetherSession
        .getRepoSystem()
        .resolveDependencies(this.aetherSession.getRepoSession(),
                dependencyRequest).getArtifactResults();
FinalResult.addAll(result);

我不知道是否有更简单的方法,但是您可以使用 Aether API 来解析您感兴趣的 POM 工件,然后使用 Model 从中构建 Maven 模型生成器 API.

首先,如果您的工件的坐标不是 POM 工件的坐标,您需要通过创建一个具有相同 GAV 的新 DefaultArtifact 将它们转换为 POM 工件,但类型为 "pom"。要解析工件,您可以调用 resolveArtifact on the repository system, and retrieve the result with getArtifact().

一旦你有了解决的工件,你就可以使用maven-model-builder to build the Maven model from the artifact's file. The ModelBuilder can be created with DefaultModelBuilderFactory.newInstance()工厂方法。

对于具有父 POM 的工件,需要在构建模型的请求中设置 ModelResolver。但是,Aether 的唯一可用实现 DefaultModelResolvermaven-aether-provider 中是包私有的,因此我们需要使用反射 API 来构造它。它需要注入通过 MavenRepositorySystemUtils.newServiceLocator() 返回的 serviceLocator 检索的组件。这需要与构建 Aether 会话时使用的定位器相同。

DefaultArtifact artifact = new DefaultArtifact(coordinate);
Artifact pomArtifact = new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion());

ArtifactRequest request = new ArtifactRequest(pomArtifact, Arrays.asList(aetherSession.getRemoteRepository()), null);
pomArtifact = aetherSession.getRepoSystem().resolveArtifact(session, request).getArtifact();

ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
ModelBuildingRequest buildingRequest = new DefaultModelBuildingRequest();
buildingRequest.setPomFile(pomArtifact.getFile());
buildingRequest.setProcessPlugins(true);
buildingRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);

Constructor<?> constr = Class.forName("org.apache.maven.repository.internal.DefaultModelResolver").getConstructors()[0];
constr.setAccessible(true);
ModelResolver modelResolver = (ModelResolver) constr.newInstance(session, null, null,
        serviceLocator.getService(ArtifactResolver.class),
        serviceLocator.getService(VersionRangeResolver.class),
        serviceLocator.getService(RemoteRepositoryManager.class), request.getRepositories());
buildingRequest.setModelResolver(modelResolver);

Model model = modelBuilder.build(buildingRequest).getEffectiveModel();

Xpp3Dom pluginConfiguration = (Xpp3Dom) model.getBuild().getPluginsAsMap().get("com.company.group:my-plugin").getConfiguration();
Xpp3Dom myConfig = pluginConfiguration.getChild("myConfig");
System.out.println(myConfig.getChild("somePropName").getValue()); // prints "someProp"

默认情况下,模型构建器未配置为处理插件,因此我们需要调用 setProcessPlugin(true)。获得有效模型后,配置将包含在 Xpp3Dom 对象中,您可以在 getChild(name) 的帮助下导航该对象,以获取命名的子 XML 元素,以及 getValue() 获取 XML 元素的值。