如何获得完全解析的pom文件模型? [英] How do I obtain a fully resolved Model of a pom file?

查看:222
本文介绍了如何获得完全解析的pom文件模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获得完全解析的pom文件模型?

How do I obtain a fully resolved Model of a pom file?

这基本上是我如何编程实现pom文件的有效模型?

我正在构建一个maven插件,它针对一组模块执行一些验证规则。
这些模块的pom文件可用,但在执行插件时它们不是反应器的一部分。

I'm building a maven plugin that performs some validation rules against a set of modules. Those modules' pom files are available but they're not part of the reactor when the plugin is executed.

我可以读取一个pom文件并获取使用此方法的相应Model对象(为简单起见,删除了异常处理):

I can read a pom file and obtain the corresponding Model object using this method (removed exception handling for simplicity):

private Model pomToModel(String pathToPom) throws Exception {
    BufferedReader in = new BufferedReader(new FileReader(pathToPom));
    MavenXpp3Reader reader = new MavenXpp3Reader();
    Model model = reader.read(in);
    return model;
}

它的工作原理但Model对象只有与pom文件相同的信息已经。

And it works but the Model object has only the same information that the pom file has.

如何改进该方法以便获得完全解析的Model对象?
通过完全解决,我的意思是:包含所有传递依赖关系以及来自父poms的所有其他内容。

How can I improve that method so that I can obtain a "fully resolved" Model object? By fully resolved, I mean: with all the transitive dependencies and everything else from the parent poms.

干杯!

推荐答案

我做到了: - )

帮助:有效pom和依赖:树确实帮助。

help:effective-pom and dependency:tree really did not help at all.

我不得不看看maven是如何构建模型的MavenProject,它被注入mojo中。
help:effective-pom已经收到已解析的模型,依赖:tree只构建一个DependencyGraph,但它不会将pom的整个模型加载到内存中。

I had to look at how maven builds the Model for the MavenProject that gets injected in the mojo. help:effective-pom already receives the resolved Model, and dependency:tree only builds a DependencyGraph, but it doesn't load the whole model for a pom into memory.

通过使用下面的代码,我能够获得一个Model对象,其中包含来自父级的所有信息,具有已解析的$ {property}表达式,以及扩展的传递依赖性。

By using the code below I was able to get a Model object with all the information from the parent, with resolved ${property} expressions, and expanded transitive dependencies.

以下是:

1)获取ModelResolver

您将需要一个接口org.apache.maven.model.resolution.ModelResolver 的实例。
不幸的是,maven没有通过依赖注入轻松提供一个(至少我找不到),所以我们必须构建一个。
为了使事情变得更好,该接口的唯一两个实现是包保护的,因此您需要使用一些反射魔法来实例化它。
实现它的具体类是 DefaultModelResolver ProjectModelResolver
我能够像这样建立一个DefaultModelResolver

You will need an instance of interface org.apache.maven.model.resolution.ModelResolver. Unfortunately, maven doesn't provide one easily via dependency injection (at least I couldn't find one), so we'll have to build one. To make things even better, the only two implementations of that interface are package protected, so you need to use some reflection magic to instantiate it. The concrete classes that implement it are DefaultModelResolver and ProjectModelResolver. I was able to build a DefaultModelResolver like this

/**
 * The Maven Project Object
 * 
 * @parameter expression="${project}"
 * @required2.0
 * @readonly
 */
protected MavenProject project;

/**
 * @component
 */
protected ArtifactResolver artifactResolver;

/**
 * @component
 */
protected RemoteRepositoryManager remoteRepositoryManager;

private Object invoke( Object object, String method )
        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    return object.getClass().getMethod( method ).invoke( object );
}

private org.apache.maven.model.resolution.ModelResolver makeModelResolver() throws MojoExecutionException {
    try {
        ProjectBuildingRequest projectBuildingRequest =
        (ProjectBuildingRequest) invoke( project, "getProjectBuildingRequest" );

        Class c = Class.forName("org.apache.maven.repository.internal.DefaultModelResolver");
        Constructor ct = c.getConstructor(new Class[]{RepositorySystemSession.class, 
                RequestTrace.class, String.class,
                ArtifactResolver.class, RemoteRepositoryManager.class,
                List.class});
        ct.setAccessible(true);
        return (org.apache.maven.model.resolution.ModelResolver) ct.newInstance(new Object[]{
                projectBuildingRequest.getRepositorySession(), 
                null, null, artifactResolver, remoteRepositoryManager, 
                project.getRemoteProjectRepositories()});
    } catch (Exception e) {
        throw new MojoExecutionException("Error instantiating DefaultModelResolver", e);
    }
}

2)构建模型

当你有一个modelResolver时,你可以从这样的pom文件构建模型:

When you have a modelResolver, you can build the Model from a pom file like this:

public Model resolveEffectiveModel(File pomfile) {
    try {
        return modelBuilder.build(makeModelBuildRequest(pomfile)).getEffectiveModel();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }   
}

private ModelBuildingRequest makeModelBuildRequest(File artifactFile) {
    DefaultModelBuildingRequest mbr = new DefaultModelBuildingRequest();
    mbr.setPomFile(artifactFile);
    mbr.setModelResolver(modelResolver); // <-- the hard-to-get modelResolver
    return mbr;
}

看起来不漂亮,但它对我有用..:P

Doesn't look pretty, but it worked for me.. :P

这篇关于如何获得完全解析的pom文件模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆