| /* |
| * 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. |
| */ |
| package org.apache.maven.archetype.mojos; |
| |
| import java.io.File; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Properties; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.maven.archetype.ArchetypeGenerationRequest; |
| import org.apache.maven.archetype.ArchetypeGenerationResult; |
| import org.apache.maven.archetype.ArchetypeManager; |
| import org.apache.maven.archetype.ui.generation.ArchetypeGenerationConfigurator; |
| import org.apache.maven.archetype.ui.generation.ArchetypeSelector; |
| import org.apache.maven.artifact.repository.ArtifactRepository; |
| import org.apache.maven.execution.MavenSession; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.ContextEnabled; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugin.MojoFailureException; |
| import org.apache.maven.plugins.annotations.Component; |
| import org.apache.maven.plugins.annotations.Execute; |
| 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.shared.invoker.DefaultInvocationRequest; |
| import org.apache.maven.shared.invoker.InvocationRequest; |
| import org.apache.maven.shared.invoker.InvocationResult; |
| import org.apache.maven.shared.invoker.Invoker; |
| import org.apache.maven.shared.invoker.MavenInvocationException; |
| |
| /** |
| * Generates a new project from an archetype, or updates the actual project if using a partial archetype. |
| * If the project is fully generated, it is generated in a directory corresponding to its artifactId. |
| * If the project is updated with a partial archetype, it is done in the current directory. |
| * |
| * @author rafale |
| */ |
| @Mojo(name = "generate", requiresProject = false) |
| @Execute(phase = LifecyclePhase.GENERATE_SOURCES) |
| public class CreateProjectFromArchetypeMojo extends AbstractMojo implements ContextEnabled { |
| @Component |
| private ArchetypeManager manager; |
| |
| @Component |
| private ArchetypeSelector selector; |
| |
| @Component |
| private ArchetypeGenerationConfigurator configurator; |
| |
| @Component |
| private Invoker invoker; |
| |
| /** |
| * The archetype's artifactId. |
| */ |
| @Parameter(property = "archetypeArtifactId") |
| private String archetypeArtifactId; |
| |
| /** |
| * The archetype's groupId. |
| */ |
| @Parameter(property = "archetypeGroupId") |
| private String archetypeGroupId; |
| |
| /** |
| * The archetype's version. |
| */ |
| @Parameter(property = "archetypeVersion") |
| private String archetypeVersion; |
| |
| /** |
| * The archetype catalogs to use to build a list and let the user choose from. |
| * It is a comma separated list of catalogs. |
| * Catalogs use the following schemes: |
| * <ul> |
| * <li>'<code>local</code>' which is the shortcut to the local repository</li> |
| * <li>'<code>remote</code>' which is the shortcut for Maven Central repository or its mirror</li> |
| * <li>'<code>internal</code>' which is an internal catalog</li> |
| * </ul> |
| * <p/> |
| * If you want the catalogs to come from a different repository, please add the following to your |
| * {@code settings.xml} |
| * <pre> |
| * <repository> |
| * <id>archetype</id> |
| * <url>https://repository.domain.com/path/to/repo/</url> |
| * </repository> |
| * |
| * <!-- in case of a repository with authentication --> |
| * <server> |
| * <id>archetype</id> |
| * <username>user.name</username> |
| * <password>s3cr3t</password> |
| * </server> |
| * </pre> |
| * If Maven Central repository catalog file is empty, <code>internal</code> catalog is used instead. |
| */ |
| @Parameter(property = "archetypeCatalog", defaultValue = "remote,local") |
| private String archetypeCatalog; |
| |
| /** |
| * If set to {@code true} will ask for values also for properties having defaults in the first place. |
| * Only has an effect if {@link #interactiveMode} is used. |
| */ |
| @Parameter(property = "askForDefaultPropertyValues", defaultValue = "false", required = true) |
| private Boolean askForDefaultPropertyValues; |
| |
| /** |
| * Local Maven repository. |
| */ |
| @Parameter(defaultValue = "${localRepository}", readonly = true, required = true) |
| private ArtifactRepository localRepository; |
| |
| /** |
| * List of remote repositories used by the resolver. |
| */ |
| @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true) |
| private List<ArtifactRepository> remoteArtifactRepositories; |
| |
| /** |
| * User settings used to check the interactiveMode. |
| */ |
| @Parameter(property = "interactiveMode", defaultValue = "${settings.interactiveMode}", required = true) |
| private Boolean interactiveMode; |
| |
| @Parameter(defaultValue = "${basedir}", property = "outputDirectory") |
| private File outputDirectory; |
| |
| @Parameter(defaultValue = "${session}", readonly = true) |
| private MavenSession session; |
| |
| /** |
| * Goals to immediately run on the project created from the archetype. |
| */ |
| @Parameter(property = "goals") |
| private String goals; |
| |
| /** |
| * Applying some filter on displayed archetypes list: format is <code>artifactId</code> or <code>groupId:artifactId</code>. |
| * <ul> |
| * <li><code>org.apache:</code> -> displays all archetypes which contain org.apache in groupId</li> |
| * <li><code>:jee</code> or <code>jee</code> -> displays all archetypes which contain jee in artifactId</li> |
| * <li><code>org.apache:jee</code> -> displays all archetypes which contain org.apache in groupId AND jee in artifactId</li> |
| * </ul> |
| * |
| * @since 2.1 |
| */ |
| @Parameter(property = "filter") |
| private String filter; |
| |
| @Override |
| public void execute() throws MojoExecutionException, MojoFailureException { |
| Properties executionProperties = session.getUserProperties(); |
| |
| ArchetypeGenerationRequest request = new ArchetypeGenerationRequest() |
| .setArchetypeGroupId(archetypeGroupId) |
| .setArchetypeArtifactId(archetypeArtifactId) |
| .setArchetypeVersion(archetypeVersion) |
| .setOutputDirectory(outputDirectory.getAbsolutePath()) |
| .setLocalRepository(localRepository) |
| .setRemoteArtifactRepositories(remoteArtifactRepositories) |
| .setFilter(filter) |
| .setAskForDefaultPropertyValues(askForDefaultPropertyValues) |
| .setProjectBuildingRequest(session.getProjectBuildingRequest()); |
| |
| try { |
| if (interactiveMode.booleanValue()) { |
| getLog().info("Generating project in Interactive mode"); |
| } else { |
| getLog().info("Generating project in Batch mode"); |
| } |
| |
| selector.selectArchetype(request, interactiveMode, archetypeCatalog); |
| |
| if (StringUtils.isBlank(request.getArchetypeArtifactId())) { |
| // no archetype found: stopping |
| return; |
| } |
| |
| configurator.configureArchetype(request, interactiveMode, executionProperties); |
| |
| ArchetypeGenerationResult generationResult = manager.generateProjectFromArchetype(request); |
| |
| if (generationResult.getCause() != null) { |
| throw new MojoFailureException( |
| generationResult.getCause(), |
| generationResult.getCause().getMessage(), |
| generationResult.getCause().getMessage()); |
| } |
| } catch (MojoFailureException ex) { |
| throw ex; |
| } catch (Exception ex) { |
| throw (MojoFailureException) new MojoFailureException(ex.getMessage()).initCause(ex); |
| } |
| |
| String artifactId = request.getArtifactId(); |
| |
| String postArchetypeGenerationGoals = request.getArchetypeGoals(); |
| |
| if (postArchetypeGenerationGoals == null || postArchetypeGenerationGoals.isEmpty()) { |
| postArchetypeGenerationGoals = goals; |
| } |
| |
| if (postArchetypeGenerationGoals != null && !postArchetypeGenerationGoals.isEmpty()) { |
| invokePostArchetypeGenerationGoals(postArchetypeGenerationGoals, artifactId); |
| } |
| } |
| |
| private void invokePostArchetypeGenerationGoals(String goals, String artifactId) |
| throws MojoExecutionException, MojoFailureException { |
| getLog().info("Invoking post-archetype-generation goals: " + goals); |
| |
| File projectBasedir = new File(outputDirectory, artifactId); |
| |
| if (projectBasedir.exists()) { |
| InvocationRequest request = new DefaultInvocationRequest() |
| .setBaseDirectory(projectBasedir) |
| .setGoals(Arrays.asList(StringUtils.split(goals, ","))); |
| |
| try { |
| InvocationResult result = invoker.execute(request); |
| |
| if (result.getExitCode() != 0) { |
| throw new MojoExecutionException("Failed to invoke goals", result.getExecutionException()); |
| } |
| } catch (MavenInvocationException e) { |
| throw new MojoExecutionException("Cannot run additions goals.", e); |
| } |
| } else { |
| getLog().info("Post-archetype-generation goals aborted: unavailable basedir " + projectBasedir); |
| } |
| } |
| } |