All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.reactiverse.vertx.maven.plugin.mojos.SetupMojo Maven / Gradle / Ivy

Go to download

A plugin to allow package, start, stop, run of Eclipse Vert.x applications

There is a newer version: 2.0.1
Show newest version
/*
 *
 *   Copyright (c) 2016-2018 Red Hat, Inc.
 *
 *   Red Hat 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.
 */

package io.reactiverse.vertx.maven.plugin.mojos;

import io.reactiverse.vertx.maven.plugin.components.Prompter;
import io.reactiverse.vertx.maven.plugin.utils.MojoUtils;
import io.reactiverse.vertx.maven.plugin.utils.SetupTemplateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.*;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toCollection;
import static org.twdata.maven.mojoexecutor.MojoExecutor.dependency;
import static org.twdata.maven.mojoexecutor.MojoExecutor.plugin;

/**
 * This Goal helps in setting up Vert.x maven project with vertx-maven-plugin, with sane defaults
 */
@Mojo(name = "setup", requiresProject = false)
public class SetupMojo extends AbstractMojo {

    public static final String JAVA_EXTENSION = ".java";
    public static final String VERTX_CORE_VERSION = "vertx-core-version";
    public static final String VERTX_GROUP_ID = "io.vertx";
    public static final String VERTX_BOM_ARTIFACT_ID = "vertx-stack-depchain";
    public static final String VERTX_CORE_ARTIFACT_ID = "vertx-core";
    public static final String VERTX_LAUNCHER_APPLICATION_ARTIFACT_ID = "vertx-launcher-application";

    private static final String PLUGIN_GROUP_ID = "io.reactiverse";
    private static final String PLUGIN_ARTIFACT_ID = "vertx-maven-plugin";
    private static final String VERTX_MAVEN_PLUGIN_VERSION_PROPERTY = "vertx-maven-plugin-version";

    /**
     * The Maven Session.
     */
    @Parameter(defaultValue = "${session}", readonly = true)
    protected MavenSession mavenSession;

    /**
     * The Maven project which will define and configure the vertx-maven-plugin
     */
    @Parameter(defaultValue = "${project}")
    protected MavenProject project;

    @Parameter(property = "projectGroupId")
    protected String projectGroupId;

    @Parameter(property = "projectArtifactId")
    protected String projectArtifactId;

    @Parameter(property = "projectVersion", defaultValue = "1.0-SNAPSHOT")
    protected String projectVersion;

    @Parameter(property = "vertxBom", defaultValue = VERTX_BOM_ARTIFACT_ID)
    protected String vertxBom;

    @Parameter(property = "vertxVersion")
    protected String vertxVersion;

    @Parameter(property = "verticle")
    protected String verticle;

    @Parameter(property = "javaVersion")
    protected String javaVersion;

    @Component
    protected Prompter prompter;

    @Override
    public void execute() throws MojoExecutionException {
        File pomFile = project.getFile();

        Model model;

        //Create pom.xml if not
        if (pomFile == null || !pomFile.isFile()) {
            pomFile = createPomFileFromUserInputs();
        }

        //We should get cloned of the OriginalModel, as project.getModel will return effective model
        model = project.getOriginalModel().clone();

        createDirectories();
        SetupTemplateUtils.createVerticle(project, verticle, getLog());

        Optional vmPlugin = MojoUtils.hasPlugin(project, PLUGIN_GROUP_ID + ":" + PLUGIN_ARTIFACT_ID);
        if (vmPlugin.isPresent()) {
            return;
        }

        //Set  a property at maven project level for vert.x  and vert.x maven plugin versions
        model.getProperties().putIfAbsent("vertx-maven-plugin.version", MojoUtils.getVersion(VERTX_MAVEN_PLUGIN_VERSION_PROPERTY));

        vertxVersion = vertxVersion == null ? MojoUtils.getVersion(VERTX_CORE_VERSION) : vertxVersion;

        model.getProperties().putIfAbsent("vertx.version", vertxVersion);
        if (!StringUtils.isBlank(verticle)) {
            if (verticle.endsWith(JAVA_EXTENSION)) {
                verticle = verticle.substring(0, verticle.length() - JAVA_EXTENSION.length());
            }
            model.getProperties().putIfAbsent("vertx.verticle", verticle);
        }

        //Add Vert.x BOM
        addVertxBom(model);

        //Add Vert.x Dependencies
        Stream.Builder deps = Stream.builder().add(VERTX_CORE_ARTIFACT_ID);
        if (vertxVersion.startsWith("5.")) {
            deps.add(VERTX_LAUNCHER_APPLICATION_ARTIFACT_ID);
        }
        addVertxDependencies(model, deps.build().collect(toCollection(LinkedHashSet::new)));

        Plugin vertxMavenPlugin = plugin(PLUGIN_GROUP_ID, PLUGIN_ARTIFACT_ID, "${vertx-maven-plugin.version}");

        if (isParentPom(model)) {
            addPluginManagementSection(model, vertxMavenPlugin);
            //strip the vertxVersion off
            vertxMavenPlugin = plugin(PLUGIN_GROUP_ID, PLUGIN_ARTIFACT_ID);
        } else {
            vertxMavenPlugin = plugin(PLUGIN_GROUP_ID, PLUGIN_ARTIFACT_ID, "${vertx-maven-plugin.version}");
        }

        PluginExecution pluginExec = new PluginExecution();
        pluginExec.addGoal("initialize");
        pluginExec.addGoal("package");
        pluginExec.setId("vmp");
        vertxMavenPlugin.addExecution(pluginExec);

        Build build = createBuildSectionIfRequired(model);
        build.getPlugins().add(vertxMavenPlugin);

        save(pomFile, model);
    }

    private Build createBuildSectionIfRequired(Model model) {
        Build build = model.getBuild();
        if (build == null) {
            build = new Build();
            model.setBuild(build);
        }
        if (build.getPlugins() == null) {
            build.setPlugins(new ArrayList<>());
        }
        return build;
    }

    private void addPluginManagementSection(Model model, Plugin vertxMavenPlugin) {
        if (model.getBuild().getPluginManagement() != null) {
            if (model.getBuild().getPluginManagement().getPlugins() == null) {
                model.getBuild().getPluginManagement().setPlugins(new ArrayList<>());
            }
            model.getBuild().getPluginManagement().getPlugins().add(vertxMavenPlugin);
        }
    }

    private File createPomFileFromUserInputs() throws MojoExecutionException {
        File pomFile;
        Model model;
        String currentDirectory = System.getProperty("user.dir");
        getLog().info("Creating a new pom.xml file in: " + currentDirectory);
        pomFile = new File(currentDirectory, "pom.xml");

        try {
            projectGroupId = promptOrUseDefault(projectGroupId, "Set the project groupId", "io.vertx.example");
            projectArtifactId = promptOrUseDefault(projectArtifactId, "Set the project artifactId", "my-vertx-project");
            projectVersion = promptOrUseDefault(projectVersion, "Set the project version", "1.0-SNAPSHOT");
            vertxVersion = promptOrUseDefault(vertxVersion, "Set the Vert.x version", MojoUtils.getVersion(VERTX_CORE_VERSION));
            verticle = promptOrUseDefault(verticle, "Set the verticle class name", projectGroupId.replace("-", ".").replace("_", ".") + ".MainVerticle");
        } catch (IOException e) {
            throw new MojoExecutionException("Error while prompting setup config", e);
        }

        if (verticle != null && verticle.endsWith(JAVA_EXTENSION)) {
            verticle = verticle.substring(0, verticle.length() - JAVA_EXTENSION.length());
        }

        Map context = new HashMap<>();
        context.put("mProjectGroupId", projectGroupId);
        context.put("mProjectArtifactId", projectArtifactId);
        context.put("mProjectVersion", projectVersion);
        context.put("vertxBom", vertxBom != null ? vertxBom : VERTX_BOM_ARTIFACT_ID);
        context.put("vertxVersion", vertxVersion != null ? vertxVersion : MojoUtils.getVersion(VERTX_CORE_VERSION));

        context.put("vertxVerticle", verticle);
        context.put("vmpVersion", MojoUtils.getVersion(VERTX_MAVEN_PLUGIN_VERSION_PROPERTY));

        context.put("javaVersion", javaVersion != null ? javaVersion : SystemUtils.JAVA_SPECIFICATION_VERSION);

        SetupTemplateUtils.createPom(context, pomFile);

        //The project should be recreated and set with right model
        MavenXpp3Reader xpp3Reader = new MavenXpp3Reader();
        try (InputStream is = Files.newInputStream(pomFile.toPath())) {
            model = xpp3Reader.read(is);
        } catch (IOException | XmlPullParserException e) {
            throw new MojoExecutionException("Error while reading POM file model", e);
        }

        project = new MavenProject(model);
        project.setPomFile(pomFile);
        project.setOriginalModel(model); // the current model is the original model as well

        return pomFile;
    }

    private String promptOrUseDefault(String value, String msg, String defaultValue) throws IOException {
        if (value != null) {
            return value;
        }
        if (mavenSession.getRequest().isInteractiveMode()) {
            return prompter.promptWithDefaultValue(msg, defaultValue);
        }
        return defaultValue;
    }

    private void save(File pomFile, Model model) throws MojoExecutionException {
        MavenXpp3Writer xpp3Writer = new MavenXpp3Writer();
        try (FileWriter pomFileWriter = new FileWriter(pomFile)) {
            xpp3Writer.write(pomFileWriter, model);
            pomFileWriter.flush();
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to write the pom.xml file", e);
        }
    }

    private void createDirectories() {
        File root = project.getBasedir();
        File source = new File(root, "src/main/java");
        File resources = new File(root, "src/main/resources");
        File test = new File(root, "src/test/java");

        String prefix = "Creation of ";
        if (!source.isDirectory()) {
            boolean res = source.mkdirs();
            getLog().debug(prefix + source.getAbsolutePath() + " : " + res);
        }
        if (!resources.isDirectory()) {
            boolean res = resources.mkdirs();
            getLog().debug(prefix + resources.getAbsolutePath() + " : " + res);
        }
        if (!test.isDirectory()) {
            boolean res = test.mkdirs();
            getLog().debug(prefix + test.getAbsolutePath() + " : " + res);
        }
    }


    private boolean isParentPom(Model model) {
        return "pom".equals(model.getPackaging());
    }

    /**
     * Method used to add the vert.x dependencies typically the vert.x core
     *
     * @param model - the {@code {@link Model}}
     */
    private void addVertxDependencies(Model model, LinkedHashSet toAdd) {
        for (Dependency dependency : model.getDependencies()) {
            if (VERTX_GROUP_ID.equals(dependency.getGroupId())) {
                toAdd.remove(dependency.getArtifactId());
            }
        }
        for (String artifactId : toAdd) {
            model.getDependencies().add(dependency(VERTX_GROUP_ID, artifactId, null));
        }
    }


    /**
     * Method used to add the vert.x BOM
     *
     * @param model - the {@code {@link Model}}
     */
    private void addVertxBom(Model model) {
        DependencyManagement dependencyManagement = model.getDependencyManagement();
        if (dependencyManagement != null) {
            for (Dependency dependency : dependencyManagement.getDependencies()) {
                if (VERTX_GROUP_ID.equals(dependency.getGroupId()) && vertxBom.equals(dependency.getArtifactId())) {
                    return;
                }
            }
        } else {
            dependencyManagement = new DependencyManagement();
            model.setDependencyManagement(dependencyManagement);
        }
        Dependency dependency = dependency(VERTX_GROUP_ID, vertxBom, "${vertx.version}");
        dependency.setType("pom");
        dependency.setScope("import");
        dependencyManagement.addDependency(dependency);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy