View Javadoc

1   package org.apache.maven.plugin.jar;
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 java.io.File;
23  import org.apache.maven.archiver.MavenArchiveConfiguration;
24  import org.apache.maven.archiver.MavenArchiver;
25  import org.apache.maven.execution.MavenSession;
26  import org.apache.maven.plugin.AbstractMojo;
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.project.MavenProject;
29  import org.apache.maven.project.MavenProjectHelper;
30  import org.codehaus.plexus.archiver.jar.JarArchiver;
31  
32  /**
33   * Base class for creating a jar from project classes.
34   *
35   * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
36   * @version $Id: AbstractJarMojo.java 1235468 2012-01-24 20:22:30Z krosenvold $
37   */
38  public abstract class AbstractJarMojo
39      extends AbstractMojo
40  {
41  
42      private static final String[] DEFAULT_EXCLUDES = new String[] { "**/package.html" };
43  
44      private static final String[] DEFAULT_INCLUDES = new String[] { "**/**" };
45  
46      /**
47       * List of files to include. Specified as fileset patterns which are relative to the input directory whose contents
48       * is being packaged into the JAR.
49       *
50       * @parameter
51       */
52      private String[] includes;
53  
54      /**
55       * List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents
56       * is being packaged into the JAR.
57       *
58       * @parameter
59       */
60      private String[] excludes;
61  
62      /**
63       * Directory containing the generated JAR.
64       *
65       * @parameter default-value="${project.build.directory}"
66       * @required
67       */
68      private File outputDirectory;
69  
70      /**
71       * Name of the generated JAR.
72       *
73       * @parameter alias="jarName" expression="${jar.finalName}" default-value="${project.build.finalName}"
74       * @required
75       */
76      private String finalName;
77  
78      /**
79       * The Jar archiver.
80       *
81       * @component role="org.codehaus.plexus.archiver.Archiver" roleHint="jar"
82       */
83      private JarArchiver jarArchiver;
84  
85      /**
86       * The Maven project.
87       *
88       * @parameter default-value="${project}"
89       * @required
90       * @readonly
91       */
92      private MavenProject project;
93  
94      /**
95       * @parameter default-value="${session}"
96       * @readonly
97       * @required
98       */
99      private MavenSession session;
100 
101     /**
102      * The archive configuration to use.
103      * See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
104      *
105      * @parameter
106      */
107     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
108 
109     /**
110      * Path to the default MANIFEST file to use. It will be used if
111      * <code>useDefaultManifestFile</code> is set to <code>true</code>.
112      *
113      * @parameter default-value="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
114      * @required
115      * @readonly
116      * @since 2.2
117      */
118     private File defaultManifestFile;
119 
120     /**
121      * Set this to <code>true</code> to enable the use of the <code>defaultManifestFile</code>.
122      *
123      * @parameter expression="${jar.useDefaultManifestFile}" default-value="false"
124      *
125      * @since 2.2
126      */
127     private boolean useDefaultManifestFile;
128 
129     /**
130      * @component
131      */
132     private MavenProjectHelper projectHelper;
133 
134     /**
135      * Whether creating the archive should be forced.
136      *
137      * @parameter expression="${jar.forceCreation}" default-value="false"
138      */
139     private boolean forceCreation;
140 	
141     /**
142      * Skip creating empty archives
143      * 
144      * @parameter expression="${jar.skipIfEmpty}" default-value="false"
145      */
146     private boolean skipIfEmpty;
147 
148     /**
149      * Return the specific output directory to serve as the root for the archive.
150      */
151     protected abstract File getClassesDirectory();
152 
153     protected final MavenProject getProject()
154     {
155         return project;
156     }
157 
158     /**
159      * Overload this to produce a jar with another classifier, for example a test-jar.
160      */
161     protected abstract String getClassifier();
162 
163     /**
164      * Overload this to produce a test-jar, for example.
165      */
166     protected abstract String getType();
167 
168     protected static File getJarFile( File basedir, String finalName, String classifier )
169     {
170         if ( classifier == null )
171         {
172             classifier = "";
173         }
174         else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
175         {
176             classifier = "-" + classifier;
177         }
178 
179         return new File( basedir, finalName + classifier + ".jar" );
180     }
181 
182     /**
183      * Default Manifest location. Can point to a non existing file.
184      * Cannot return null.
185      */
186     protected File getDefaultManifestFile()
187     {
188         return defaultManifestFile;
189     }
190 
191 
192     /**
193      * Generates the JAR.
194      *
195      * @todo Add license files in META-INF directory.
196      */
197     public File createArchive()
198         throws MojoExecutionException
199     {
200         File jarFile = getJarFile( outputDirectory, finalName, getClassifier() );
201 
202         MavenArchiver archiver = new MavenArchiver();
203 
204         archiver.setArchiver( jarArchiver );
205 
206         archiver.setOutputFile( jarFile );
207 
208         archive.setForced( forceCreation );
209 
210         try
211         {
212             File contentDirectory = getClassesDirectory();
213             if ( !contentDirectory.exists() )
214             {
215                 getLog().warn( "JAR will be empty - no content was marked for inclusion!" );
216             }
217             else
218             {
219                 archiver.getArchiver().addDirectory( contentDirectory, getIncludes(), getExcludes() );
220             }
221 
222             File existingManifest = getDefaultManifestFile();
223 
224             if ( useDefaultManifestFile && existingManifest.exists() && archive.getManifestFile() == null )
225             {
226                 getLog().info( "Adding existing MANIFEST to archive. Found under: " + existingManifest.getPath() );
227                 archive.setManifestFile( existingManifest );
228             }
229 
230             archiver.createArchive( session, project, archive );
231 
232             return jarFile;
233         }
234         catch ( Exception e )
235         {
236             // TODO: improve error handling
237             throw new MojoExecutionException( "Error assembling JAR", e );
238         }
239     }
240 
241     /**
242      * Generates the JAR.
243      *
244      * @todo Add license files in META-INF directory.
245      */
246     public void execute()
247         throws MojoExecutionException
248     {
249         if ( skipIfEmpty && !getClassesDirectory().exists() )
250         {
251             getLog().info( "Skipping packaging of the test-jar" );
252         }
253         else
254         {
255             File jarFile = createArchive();
256 
257             String classifier = getClassifier();
258             if ( classifier != null )
259             {
260                 projectHelper.attachArtifact( getProject(), getType(), classifier, jarFile );
261             }
262             else
263             {
264                 getProject().getArtifact().setFile( jarFile );
265             }
266         }
267     }
268 
269     private String[] getIncludes()
270     {
271         if ( includes != null && includes.length > 0 )
272         {
273             return includes;
274         }
275         return DEFAULT_INCLUDES;
276     }
277 
278     private String[] getExcludes()
279     {
280         if ( excludes != null && excludes.length > 0 )
281         {
282             return excludes;
283         }
284         return DEFAULT_EXCLUDES;
285     }
286 }