views:

783

answers:

3

I am writing a custom maven2 MOJO. I need to access the runtime configuration of another plugin, from this MOJO.

What is the best way to do this?

A: 

I'm not sure how you would do that exactly, but it seems to me that this might not be the best design decision. If at all possible you should aim to decouple your Mojo from any other plugins out there.

Instead I would recommend using custom properties to factor out any duplication in the configuration of separate plugins.

You can set a custom property "foo" in your pom by using the properties section:

<project>
  ...
  <properties>
    <foo>value</foo>
  </properties>
  ...
</project>

The property foo is now accessible anywhere in the pom by using the dollar sign + curly brace notation:

<somePluginProperty>${foo}</somePluginProperty>
Mike Deck
+2  A: 

Using properties is certainly one way to go, however not ideal. It still requires a user to define the ${propertyName} in multiple places throughout the pom. I want to allow my plugin to work with no modifications to the user's pom, other than the plugin definition itself.

I don't see accessing the runtime properties of another MOJO as too tight coupling. If the other MOJO is defined anywhere in the build hierarchy, I want my MOJO to respect the same configuration.

My current solution is:

private Plugin lookupPlugin(String key) {

    List plugins = getProject().getBuildPlugins();

    for (Iterator iterator = plugins.iterator(); iterator.hasNext();) {
        Plugin plugin = (Plugin) iterator.next();
        if(key.equalsIgnoreCase(plugin.getKey())) {
            return plugin;
        }
    }
    return null;
}


/**
 * Extracts nested values from the given config object into a List.
 * 
 * @param childname the name of the first subelement that contains the list
 * @param config the actual config object
 */
private List extractNestedStrings(String childname, Xpp3Dom config) {

    final Xpp3Dom subelement = config.getChild(childname);
    if (subelement != null) {
        List result = new LinkedList();
        final Xpp3Dom[] children = subelement.getChildren();
        for (int i = 0; i < children.length; i++) {
            final Xpp3Dom child = children[i];
            result.add(child.getValue());
        }
        getLog().info("Extracted strings: " + result);
        return result;
    }

    return null;
}

This has worked for the few small builds I've tested with. Including a multi-module build.

npellow
+1  A: 

You can get a list of plugins currently been used in the build using the following steps:

First you need to get Maven to inject the current project into your mojo, you use the class variable defined below to get this.

/**
 * The maven project.
 * 
 * @parameter expression="${project}"
 * @readonly
 */
 private MavenProject project;

Then you can use the following to get a list of plugins used in this build.

mavenProject.getBuildPlugins()

You can iterate though this list until you find the plugin from which you want to extract configuration.

Finally, you can get the configuration as a Xpp3Dom.

plugin.getConfiguration()

Note: If your altering the other plugins configuration (rather than just extracting information), it will only remain altered for the current phase and not subsequent phases.

Kingamajick
How is this different from my solution above?Also, does getBuildPlugins return only plugins defined in the <build> section of the pom.xml, or all plugins, even those defined in profiles etc?
npellow
Using getBuildPlugins() will only return plugins which are in the <build> section of the pom.xml and plugins which are defined in the <build> section of active profiles.
Kingamajick