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 org.apache.maven.archiver.MavenArchiveConfiguration;
23  import org.apache.maven.archiver.MavenArchiver;
24  import org.apache.maven.plugin.AbstractMojo;
25  import org.apache.maven.plugin.MojoExecutionException;
26  import org.apache.maven.project.MavenProject;
27  import org.apache.maven.project.MavenProjectHelper;
28  import org.codehaus.plexus.archiver.jar.JarArchiver;
29  
30  import java.io.File;
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 1158941 2011-08-17 22:22:17Z rfscholte $
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       * The archive configuration to use.
96       * See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
97       *
98       * @parameter
99       */
100     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
101 
102     /**
103      * Path to the default MANIFEST file to use. It will be used if
104      * <code>useDefaultManifestFile</code> is set to <code>true</code>.
105      *
106      * @parameter default-value="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
107      * @required
108      * @readonly
109      * @since 2.2
110      */
111     private File defaultManifestFile;
112 
113     /**
114      * Set this to <code>true</code> to enable the use of the <code>defaultManifestFile</code>.
115      *
116      * @parameter expression="${jar.useDefaultManifestFile}" default-value="false"
117      *
118      * @since 2.2
119      */
120     private boolean useDefaultManifestFile;
121 
122     /**
123      * @component
124      */
125     private MavenProjectHelper projectHelper;
126 
127     /**
128      * Whether creating the archive should be forced.
129      *
130      * @parameter expression="${jar.forceCreation}" default-value="false"
131      */
132     private boolean forceCreation;
133 
134     /**
135      * Return the specific output directory to serve as the root for the archive.
136      */
137     protected abstract File getClassesDirectory();
138 
139     protected final MavenProject getProject()
140     {
141         return project;
142     }
143 
144     /**
145      * Overload this to produce a jar with another classifier, for example a test-jar.
146      */
147     protected abstract String getClassifier();
148 
149     /**
150      * Overload this to produce a test-jar, for example.
151      */
152     protected abstract String getType();
153 
154     protected static File getJarFile( File basedir, String finalName, String classifier )
155     {
156         if ( classifier == null )
157         {
158             classifier = "";
159         }
160         else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
161         {
162             classifier = "-" + classifier;
163         }
164 
165         return new File( basedir, finalName + classifier + ".jar" );
166     }
167 
168     /**
169      * Default Manifest location. Can point to a non existing file.
170      * Cannot return null.
171      */
172     protected File getDefaultManifestFile()
173     {
174         return defaultManifestFile;
175     }
176 
177 
178     /**
179      * Generates the JAR.
180      *
181      * @todo Add license files in META-INF directory.
182      */
183     public File createArchive()
184         throws MojoExecutionException
185     {
186         File jarFile = getJarFile( outputDirectory, finalName, getClassifier() );
187 
188         MavenArchiver archiver = new MavenArchiver();
189 
190         archiver.setArchiver( jarArchiver );
191 
192         archiver.setOutputFile( jarFile );
193 
194         archive.setForced( forceCreation );
195 
196         try
197         {
198             File contentDirectory = getClassesDirectory();
199             if ( !contentDirectory.exists() )
200             {
201                 getLog().warn( "JAR will be empty - no content was marked for inclusion!" );
202             }
203             else
204             {
205                 archiver.getArchiver().addDirectory( contentDirectory, getIncludes(), getExcludes() );
206             }
207 
208             File existingManifest = getDefaultManifestFile();
209 
210             if ( useDefaultManifestFile && existingManifest.exists() && archive.getManifestFile() == null )
211             {
212                 getLog().info( "Adding existing MANIFEST to archive. Found under: " + existingManifest.getPath() );
213                 archive.setManifestFile( existingManifest );
214             }
215 
216             archiver.createArchive( project, archive );
217 
218             return jarFile;
219         }
220         catch ( Exception e )
221         {
222             // TODO: improve error handling
223             throw new MojoExecutionException( "Error assembling JAR", e );
224         }
225     }
226 
227     /**
228      * Generates the JAR.
229      *
230      * @todo Add license files in META-INF directory.
231      */
232     public void execute()
233         throws MojoExecutionException
234     {
235         File jarFile = createArchive();
236 
237         String classifier = getClassifier();
238         if ( classifier != null )
239         {
240             projectHelper.attachArtifact( getProject(), getType(), classifier, jarFile );
241         }
242         else
243         {
244             getProject().getArtifact().setFile( jarFile );
245         }
246     }
247 
248     private String[] getIncludes()
249     {
250         if ( includes != null && includes.length > 0 )
251         {
252             return includes;
253         }
254         return DEFAULT_INCLUDES;
255     }
256 
257     private String[] getExcludes()
258     {
259         if ( excludes != null && excludes.length > 0 )
260         {
261             return excludes;
262         }
263         return DEFAULT_EXCLUDES;
264     }
265 }