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  
41  import java.io.File;
42  import java.util.Map;
43  
44  /**
45   * Build a JAR from the current Archetype project.
46   *
47   * @author rafale
48   */
49  @Mojo( name = "jar", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true )
50  public class JarMojo
51      extends AbstractMojo
52  {
53      /**
54       * Directory containing the classes.
55       */
56      @Parameter( defaultValue = "${project.build.outputDirectory}", required = true )
57      private File archetypeDirectory;
58  
59      /**
60       * Name of the generated JAR.
61       */
62      @Parameter( defaultValue = "${project.build.finalName}", alias = "jarName", required = true )
63      private String finalName;
64  
65      /**
66       * Directory containing the generated JAR.
67       */
68      @Parameter( defaultValue = "${project.build.directory}", required = true )
69      private File outputDirectory;
70  
71      /**
72       * The Maven project.
73       */
74      @Parameter( defaultValue = "${project}", readonly = true, required = true )
75      private MavenProject project;
76  
77      /**
78       * The {@link MavenSession}.
79       */
80      @Parameter( defaultValue = "${session}", readonly = true, required = true )
81      private MavenSession session;
82  
83      /**
84       * The Jar archiver.
85       */
86      @Component
87      private Map<String, Archiver> archivers;
88  
89      /**
90       * The archive configuration to use. See <a href="https://maven.apache.org/shared/maven-archiver/index.html">Maven
91       * Archiver Reference</a>.
92       *
93       * @since 3.2.0
94       */
95      @Parameter
96      private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
97  
98      /**
99       * Timestamp for reproducible output archive entries, either formatted as ISO 8601
100      * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
101      * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
102      *
103      * @since 3.2.0
104      */
105     @Parameter( defaultValue = "${project.build.outputTimestamp}" )
106     private String outputTimestamp;
107 
108     /**
109      * The archetype manager component.
110      */
111     @Component
112     private ArchetypeManager manager;
113 
114     /**
115      * The archetype artifact manager component.
116      */
117     @Component
118     private ArchetypeArtifactManager archetypeArtifactManager;
119 
120     @Override
121     public void execute()
122         throws MojoExecutionException, MojoFailureException
123     {
124         File jarFile = new File( outputDirectory, finalName + ".jar" );
125         getLog().info( "Building archetype jar: " + jarFile );
126 
127         MavenArchiver archiver = new MavenArchiver();
128         archiver.setCreatedBy( "Maven Archetype Plugin", "org.apache.maven.plugins", "maven-archetype-plugin" );
129 
130         archiver.setOutputFile( jarFile );
131 
132         archiver.setArchiver( (JarArchiver) archivers.get( "jar" ) );
133 
134         // configure for Reproducible Builds based on outputTimestamp value
135         archiver.configureReproducible( outputTimestamp );
136 
137         try
138         {
139             archiver.getArchiver().addDirectory( archetypeDirectory );
140 
141             archiver.createArchive( session, project, archive );
142         }
143         catch ( Exception e )
144         {
145             throw new MojoExecutionException( "Error assembling archetype jar " + jarFile, e );
146         }
147 
148         checkArchetypeFile( jarFile );
149 
150         project.getArtifact().setFile( jarFile );
151     }
152 
153     private void checkArchetypeFile( File jarFile )
154         throws MojoExecutionException
155     {
156         try
157         {
158             if ( archetypeArtifactManager.isFileSetArchetype( jarFile ) )
159             {
160                 checkFileSetArchetypeFile( jarFile );
161             }
162             else if ( archetypeArtifactManager.isOldArchetype( jarFile ) )
163             {
164                 getLog().warn( "Building an Old (1.x) Archetype: consider migrating it to current 2.x Archetype." );
165             }
166             else
167             {
168                 throw new MojoExecutionException( "The current project does not build an archetype" );
169             }
170         }
171         catch ( UnknownArchetype ua )
172         {
173             throw new MojoExecutionException( ua.getMessage(), ua );
174         }
175     }
176 
177     private void checkFileSetArchetypeFile( File jarFile )
178         throws UnknownArchetype
179     {
180         ArchetypeDescriptor archetypeDescriptor = archetypeArtifactManager.getFileSetArchetypeDescriptor( jarFile );
181 
182         for ( RequiredProperty rp : archetypeDescriptor.getRequiredProperties() )
183         {
184             if ( rp.getKey().contains( "." ) )
185             {
186                 getLog().warn( "Invalid required property name '" + rp.getKey()
187                                    + "': dot character makes is unusable in Velocity template" );
188             }
189         }
190     }
191 }