Java tutorial
package com.soebes.maven.plugins.iterator; import java.util.ArrayList; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.BuildPluginManager; import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.PluginConfigurationException; import org.apache.maven.plugin.PluginDescriptorParsingException; import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.reporting.exec.MavenPluginManagerHelper; import org.codehaus.plexus.configuration.PlexusConfiguration; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3DomUtils; /** * Executor will execute a given plugin by iterating through the given items. * * @author Karl-Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a> */ @Mojo(name = "iterator", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.TEST, requiresProject = true, threadSafe = true) public class IteratorMojo extends AbstractIteratorMojo { /** * By using the pluginExecutors you can define a list of plugins which will be executed during executor. * * <pre> * {@code * <pluginExecutors> * <pluginExecutor> * ..Plugin * </pluginExecutor> * </pluginExecutors> * } * </pre> * * A plugin must be defined by using the plugin tag. You can omit the version tag if you have defined the plugin's * version in the pluginManagement section. * * <pre> * {@code * <plugin> * <groupId>..</groupId> * <artifactId>..</artifactId> * <version>..</version> * </plugin> * } * </pre> * * Furthermore you need to define the goal of the given plugin by using the tag: * * <pre> * {@code * <goal>...</goal> * } * </pre> * * And finally you need to define the configuration for the plugin by using the following: * * <pre> * {@code * <configuration> * Plugin Configuration * </configuration> * } * </pre> */ @Parameter(required = true) private List<PluginExecutor> pluginExecutors; /** * This is the helper class to support Maven 3.1 and before. */ @Component protected MavenPluginManagerHelper mavenPluginManagerHelper; /** * The Maven BuildPluginManager component. */ @Component private BuildPluginManager pluginManager; @Parameter(defaultValue = "${plugin}", required = true, readonly = true) private PluginDescriptor pluginDescriptor; /** * This will copy the configuration from <b>src</b> to the result whereas the placeholder will be replaced with the * current value. */ private PlexusConfiguration copyConfiguration(Xpp3Dom src, String iteratorName, String value) { XmlPlexusConfiguration dom = new XmlPlexusConfiguration(src.getName()); if (src.getValue() == null) { dom.setValue(src.getValue()); } else { if (src.getValue().contains(iteratorName)) { dom.setValue(src.getValue().replaceAll(iteratorName, value)); } else { dom.setValue(src.getValue()); } } for (String attributeName : src.getAttributeNames()) { dom.setAttribute(attributeName, src.getAttribute(attributeName)); } for (Xpp3Dom child : src.getChildren()) { dom.addChild(copyConfiguration(child, iteratorName, value)); } return dom; } /** * This method will give back the plugin information which has been given as parameter in case of an not existing * pluginManagement section or if the version of the plugin is already defined. Otherwise the version will be got * from the pluginManagement area if the plugin can be found in it. * * @param plugin The plugin which should be checked against the pluginManagement area. * @return The plugin version. If the plugin version is not defined it means that neither the version has been * defined by the pluginManagement section nor by the user itself. */ private Plugin getPluginVersionFromPluginManagement(Plugin plugin) { if (!isPluginManagementDefined()) { return plugin; } if (isPluginVersionDefined(plugin)) { return plugin; } Map<String, Plugin> plugins = getMavenProject().getPluginManagement().getPluginsAsMap(); Plugin result = plugins.get(plugin.getKey()); if (result == null) { return plugin; } else { return result; } } private boolean isPluginVersionDefined(Plugin plugin) { return plugin.getVersion() != null; } private boolean isPluginManagementDefined() { return getMavenProject().getPluginManagement() != null; } public void execute() throws MojoExecutionException, MojoFailureException { if (isSkip()) { getLog().info("Skip by user request."); return; } if (isNoneSet()) { throw new MojoExecutionException("You have to use at least one. " + "Either items element, " + "itemsWithProperties, content or folder element!"); } if (atLeastOneItemFound()) { if (isMoreThanOneSet()) { throw new MojoExecutionException("You can use only one element. " + "Either items, itemsWithProperties, content or folder element but not more than one of them."); } } else { getLog().info("The list of items to iterate on is empty. Nothing will be done..."); } List<Exception> exceptions = new ArrayList<>(); for (ItemWithProperties item : getItemsConverted()) { for (PluginExecutor pluginExecutor : pluginExecutors) { try { handlePluginExecution(item, pluginExecutor); } catch (MojoExecutionException e) { if (isFailAtEnd()) { exceptions.add(e); } else { throw e; } } catch (MojoFailureException e) { // An Failure will stop the iteration under any circumstances. throw e; } } } if (!exceptions.isEmpty()) { for (Exception exception : exceptions) { getLog().error(exception); } throw new MojoExecutionException("Failures during iteration"); } } /** * This will inject the iteration into the current properties and furthermore the properties if they have given and * execute the plugin with the appropriate context. * * @param item The items which are using for the current iteration. * @param pluginExecutor The {@link PluginExecutor} * @throws MojoExecutionException in case of an error. * @throws MojoFailureException failure during the run of a plugin. */ private void handlePluginExecution(ItemWithProperties item, PluginExecutor pluginExecutor) throws MojoExecutionException, MojoFailureException { Plugin executePlugin = getPluginVersionFromPluginManagement(pluginExecutor.getPlugin()); if (executePlugin.getVersion() == null) { throw new MojoExecutionException( "Unknown plugin version. You have to define the version either directly or via pluginManagement."); } Xpp3Dom resultConfiguration = handlePluginConfigurationFromPluginManagement(pluginExecutor, executePlugin); PlexusConfiguration plexusConfiguration = copyConfiguration(resultConfiguration, getPlaceHolder(), item.getName()); createLogOutput(pluginExecutor, executePlugin, item.getName()); // Put the value of the current iteration into the current context. getMavenProject().getProperties().put(getIteratorName(), item.getName()); if (item.hasProperties()) { // Add all properties to the context. for (Entry<Object, Object> entry : item.getProperties().entrySet()) { getMavenProject().getProperties().put(entry.getKey(), entry.getValue()); } } try { executeMojo(executePlugin, pluginExecutor.getGoal(), toXpp3Dom(plexusConfiguration)); } catch (MojoExecutionException e) { throw e; } catch (MojoFailureException e) { throw e; } catch (PluginResolutionException e) { getLog().error("PluginresourceException:", e); throw new MojoExecutionException("PluginRescourceException", e); } catch (PluginDescriptorParsingException e) { getLog().error("PluginDescriptorParsingException:", e); throw new MojoExecutionException("PluginDescriptorParsingException", e); } catch (InvalidPluginDescriptorException e) { getLog().error("InvalidPluginDescriptorException:", e); throw new MojoExecutionException("InvalidPluginDescriptorException", e); } catch (PluginConfigurationException e) { getLog().error("PluginConfigurationException:", e); throw new MojoExecutionException("PluginConfigurationException", e); } catch (PluginManagerException e) { getLog().error("PluginManagerException:", e); throw new MojoExecutionException("PluginManagerException", e); } finally { // Remove the old key from context. getMavenProject().getProperties().remove(getIteratorName()); if (item.hasProperties()) { // Remove all old properties from context. for (Object entry : item.getProperties().keySet()) { getMavenProject().getProperties().remove(entry); } } } } private Xpp3Dom handlePluginConfigurationFromPluginManagement(PluginExecutor pluginExecutor, Plugin executePlugin) { Xpp3Dom resultConfiguration = toXpp3Dom(pluginExecutor.getConfiguration()); getLog().debug("Configuration: " + resultConfiguration.toString()); if (executePlugin.getConfiguration() != null) { Xpp3Dom x = (Xpp3Dom) executePlugin.getConfiguration(); resultConfiguration = Xpp3DomUtils.mergeXpp3Dom(x, toXpp3Dom(pluginExecutor.getConfiguration())); getLog().debug("ConfigurationExecutePlugin: " + executePlugin.getConfiguration().toString()); } return resultConfiguration; } /** * Taken from MojoExecutor of Don Brown. Make it working with Maven 3.1. * * @param plugin * @param goal * @param configuration * @param env * @throws MojoExecutionException * @throws PluginResolutionException * @throws PluginDescriptorParsingException * @throws InvalidPluginDescriptorException * @throws PluginManagerException * @throws PluginConfigurationException * @throws MojoFailureException */ private void executeMojo(Plugin plugin, String goal, Xpp3Dom configuration) throws MojoExecutionException, PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException, MojoFailureException, PluginConfigurationException, PluginManagerException { if (configuration == null) { throw new NullPointerException("configuration may not be null"); } PluginDescriptor pluginDescriptor = getPluginDescriptor(plugin); MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo(goal); if (mojoDescriptor == null) { throw new MojoExecutionException("Could not find goal '" + goal + "' in plugin " + plugin.getGroupId() + ":" + plugin.getArtifactId() + ":" + plugin.getVersion()); } MojoExecution exec = mojoExecution(mojoDescriptor, configuration); pluginManager.executeMojo(getMavenSession(), exec); } private PluginDescriptor getPluginDescriptor(Plugin plugin) throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { return mavenPluginManagerHelper.getPluginDescriptor(plugin, getMavenProject().getRemotePluginRepositories(), getMavenSession()); } private MojoExecution mojoExecution(MojoDescriptor mojoDescriptor, Xpp3Dom configuration) { Xpp3Dom resultConfiguration = Xpp3DomUtils.mergeXpp3Dom(configuration, toXpp3Dom(mojoDescriptor.getMojoConfiguration())); return new MojoExecution(mojoDescriptor, resultConfiguration); } /** * Taken from MojoExecutor of Don Brown. Converts PlexusConfiguration to a Xpp3Dom. * * @param config the PlexusConfiguration. Must not be {@code null}. * @return the Xpp3Dom representation of the PlexusConfiguration */ public Xpp3Dom toXpp3Dom(PlexusConfiguration config) { Xpp3Dom result = new Xpp3Dom(config.getName()); result.setValue(config.getValue(null)); for (String name : config.getAttributeNames()) { result.setAttribute(name, config.getAttribute(name)); } for (PlexusConfiguration child : config.getChildren()) { result.addChild(toXpp3Dom(child)); } return result; } /** * Will create the output during the executions for the plugins like <code>groupId:artifactId:version:goal</code>. * * @param pluginExecutor * @param executePlugin */ private void createLogOutput(PluginExecutor pluginExecutor, Plugin executePlugin, String item) { StringBuilder sb = new StringBuilder("------ "); sb.append("("); sb.append(item); sb.append(") "); sb.append(executePlugin.getKey()); sb.append(":"); sb.append(executePlugin.getVersion()); sb.append(":"); sb.append(pluginExecutor.getGoal()); getLog().info(sb.toString()); } }