View Javadoc
1   package org.apache.maven.archetype.mojos;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.archetype.ArchetypeManager;
23  import org.apache.maven.archetype.common.ArchetypeArtifactManager;
24  import org.apache.maven.archetype.exception.UnknownArchetype;
25  import org.apache.maven.archetype.metadata.ArchetypeDescriptor;
26  import org.apache.maven.archetype.metadata.RequiredProperty;
27  import org.apache.maven.archiver.MavenArchiveConfiguration;
28  import org.apache.maven.archiver.MavenArchiver;
29  import org.apache.maven.execution.MavenSession;
30  import org.apache.maven.plugin.AbstractMojo;
31  import org.apache.maven.plugin.MojoExecutionException;
32  import org.apache.maven.plugin.MojoFailureException;
33  import org.apache.maven.plugins.annotations.Component;
34  import org.apache.maven.plugins.annotations.LifecyclePhase;
35  import org.apache.maven.plugins.annotations.Mojo;
36  import org.apache.maven.plugins.annotations.Parameter;
37  import org.apache.maven.project.MavenProject;
38  import org.codehaus.plexus.archiver.Archiver;
39  import org.codehaus.plexus.archiver.jar.JarArchiver;
40  import org.codehaus.plexus.archiver.util.DefaultFileSet;
41  
42  import java.io.File;
43  import java.util.Map;
44  
45  /**
46   * Build a JAR from the current Archetype project.
47   *
48   * @author rafale
49   */
50  @Mojo( name = "jar", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true )
51  public class JarMojo
52      extends AbstractMojo
53  {
54  
55      /**
56       * Directory containing the classes.
57       */
58      @Parameter( defaultValue = "${project.build.outputDirectory}", required = true )
59      private File archetypeDirectory;
60  
61      /**
62       * Name of the generated JAR.
63       */
64      @Parameter( defaultValue = "${project.build.finalName}", alias = "jarName", required = true )
65      private String finalName;
66  
67      /**
68       * Directory containing the generated JAR.
69       */
70      @Parameter( defaultValue = "${project.build.directory}", required = true )
71      private File outputDirectory;
72  
73      /**
74       * Exclude some files from the archetype like .gitignore.
75       */
76      @Parameter( defaultValue = "true" )
77      private boolean useDefaultExcludes;
78  
79      /**
80       * The Maven project.
81       */
82      @Parameter( defaultValue = "${project}", readonly = true, required = true )
83      private MavenProject project;
84  
85      /**
86       * The {@link MavenSession}.
87       */
88      @Parameter( defaultValue = "${session}", readonly = true, required = true )
89      private MavenSession session;
90  
91      /**
92       * The Jar archiver.
93       */
94      @Component
95      private Map<String, Archiver> archivers;
96  
97      /**
98       * The archive configuration to use. See <a href="https://maven.apache.org/shared/maven-archiver/index.html">Maven
99       * Archiver Reference</a>.
100      *
101      * @since 3.2.0
102      */
103     @Parameter
104     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
105 
106     /**
107      * Timestamp for reproducible output archive entries, either formatted as ISO 8601
108      * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
109      * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
110      *
111      * @since 3.2.0
112      */
113     @Parameter( defaultValue = "${project.build.outputTimestamp}" )
114     private String outputTimestamp;
115 
116     /**
117      * The archetype manager component.
118      */
119     @Component
120     private ArchetypeManager manager;
121 
122     /**
123      * The archetype artifact manager component.
124      */
125     @Component
126     private ArchetypeArtifactManager archetypeArtifactManager;
127 
128     @Override
129     public void execute()
130         throws MojoExecutionException, MojoFailureException
131     {
132         File jarFile = new File( outputDirectory, finalName + ".jar" );
133         getLog().info( "Building archetype jar: " + jarFile );
134 
135         MavenArchiver archiver = new MavenArchiver();
136         archiver.setCreatedBy( "Maven Archetype Plugin", "org.apache.maven.plugins", "maven-archetype-plugin" );
137 
138         archiver.setOutputFile( jarFile );
139 
140         archiver.setArchiver( (JarArchiver) archivers.get( "jar" ) );
141 
142         // configure for Reproducible Builds based on outputTimestamp value
143         archiver.configureReproducible( outputTimestamp );
144 
145         try
146         {
147             DefaultFileSet fs = DefaultFileSet.fileSet( archetypeDirectory ).prefixed( "" )
148                 .includeExclude( null,  null ).includeEmptyDirs( true );
149             fs.setUsingDefaultExcludes( useDefaultExcludes );
150             archiver.getArchiver().addFileSet( fs );
151 
152             archiver.createArchive( session, project, archive );
153         }
154         catch ( Exception e )
155         {
156             throw new MojoExecutionException( "Error assembling archetype jar " + jarFile, e );
157         }
158 
159         checkArchetypeFile( jarFile );
160 
161         project.getArtifact().setFile( jarFile );
162     }
163 
164     private void checkArchetypeFile( File jarFile )
165         throws MojoExecutionException
166     {
167         try
168         {
169             if ( archetypeArtifactManager.isFileSetArchetype( jarFile ) )
170             {
171                 checkFileSetArchetypeFile( jarFile );
172             }
173             else if ( archetypeArtifactManager.isOldArchetype( jarFile ) )
174             {
175                 getLog().warn( "Building an Old (1.x) Archetype: consider migrating it to current 2.x Archetype." );
176             }
177             else
178             {
179                 throw new MojoExecutionException( "The current project does not build an archetype" );
180             }
181         }
182         catch ( UnknownArchetype ua )
183         {
184             throw new MojoExecutionException( ua.getMessage(), ua );
185         }
186     }
187 
188     private void checkFileSetArchetypeFile( File jarFile )
189         throws UnknownArchetype
190     {
191         ArchetypeDescriptor archetypeDescriptor = archetypeArtifactManager.getFileSetArchetypeDescriptor( jarFile );
192 
193         for ( RequiredProperty rp : archetypeDescriptor.getRequiredProperties() )
194         {
195             if ( rp.getKey().contains( "." ) )
196             {
197                 getLog().warn( "Invalid required property name '" + rp.getKey()
198                                    + "': dot character makes is unusable in Velocity template" );
199             }
200         }
201     }
202 }