View Javadoc
1   package org.apache.maven.plugin.javadoc;
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.artifact.DependencyResolutionRequiredException;
25  import org.apache.maven.artifact.handler.ArtifactHandler;
26  import org.apache.maven.model.Resource;
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugins.annotations.Component;
29  import org.apache.maven.plugins.annotations.LifecyclePhase;
30  import org.apache.maven.plugins.annotations.Mojo;
31  import org.apache.maven.plugins.annotations.Parameter;
32  import org.apache.maven.plugins.annotations.ResolutionScope;
33  import org.apache.maven.project.MavenProjectHelper;
34  import org.apache.maven.reporting.MavenReportException;
35  import org.codehaus.plexus.archiver.Archiver;
36  import org.codehaus.plexus.archiver.ArchiverException;
37  import org.codehaus.plexus.archiver.jar.JarArchiver;
38  import org.codehaus.plexus.archiver.jar.ManifestException;
39  
40  import java.io.File;
41  import java.io.IOException;
42  import java.util.List;
43  import java.util.Locale;
44  
45  /**
46   * Bundles the Javadoc documentation for <code>main Java code</code> in an <b>NON aggregator</b> project into
47   * a jar using the standard <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/">Javadoc Tool</a>.
48   *
49   * @version $Id: JavadocJar.html 922314 2014-09-15 20:18:14Z dennisl $
50   * @since 2.0
51   */
52  @Mojo( name = "jar", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true )
53  public class JavadocJar
54      extends AbstractJavadocMojo
55  {
56      /**
57       * Includes all generated Javadoc files
58       */
59      private static final String[] DEFAULT_INCLUDES = new String[]{ "**/**" };
60  
61      /**
62       * Excludes all processing files.
63       *
64       * @see AbstractJavadocMojo#DEBUG_JAVADOC_SCRIPT_NAME
65       * @see AbstractJavadocMojo#OPTIONS_FILE_NAME
66       * @see AbstractJavadocMojo#PACKAGES_FILE_NAME
67       * @see AbstractJavadocMojo#ARGFILE_FILE_NAME
68       * @see AbstractJavadocMojo#FILES_FILE_NAME
69       */
70      private static final String[] DEFAULT_EXCLUDES =
71          new String[]{ DEBUG_JAVADOC_SCRIPT_NAME, OPTIONS_FILE_NAME, PACKAGES_FILE_NAME, ARGFILE_FILE_NAME,
72              FILES_FILE_NAME };
73  
74      // ----------------------------------------------------------------------
75      // Mojo components
76      // ----------------------------------------------------------------------
77  
78      /**
79       * Used for attaching the artifact in the project.
80       */
81      @Component
82      private MavenProjectHelper projectHelper;
83  
84      /**
85       * The Jar archiver.
86       *
87       * @since 2.5
88       */
89      @Component( role = Archiver.class, hint = "jar" )
90      private JarArchiver jarArchiver;
91  
92      // ----------------------------------------------------------------------
93      // Mojo Parameters
94      // ----------------------------------------------------------------------
95  
96      /**
97       * Specifies the destination directory where javadoc saves the generated HTML files.
98       * See <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#d">d</a>.
99       *
100      * @deprecated
101      */
102     @Parameter( property = "destDir" )
103     private File destDir;
104 
105     /**
106      * Specifies the directory where the generated jar file will be put.
107      */
108     @Parameter( property = "project.build.directory" )
109     private String jarOutputDirectory;
110 
111     /**
112      * Specifies the filename that will be used for the generated jar file. Please note that <code>-javadoc</code>
113      * or <code>-test-javadoc</code> will be appended to the file name.
114      */
115     @Parameter( property = "project.build.finalName" )
116     private String finalName;
117 
118     /**
119      * Specifies whether to attach the generated artifact to the project helper.
120      * <br/>
121      */
122     @Parameter( property = "attach", defaultValue = "true" )
123     private boolean attach;
124 
125     /**
126      * The archive configuration to use.
127      * See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
128      *
129      * @since 2.5
130      */
131     @Parameter
132     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
133 
134     /**
135      * Path to the default MANIFEST file to use. It will be used if
136      * <code>useDefaultManifestFile</code> is set to <code>true</code>.
137      *
138      * @since 2.5
139      */
140     @Parameter( defaultValue = "${project.build.outputDirectory}/META-INF/MANIFEST.MF", required = true,
141                 readonly = true )
142     private File defaultManifestFile;
143 
144     /**
145      * Set this to <code>true</code> to enable the use of the <code>defaultManifestFile</code>.
146      * <br/>
147      *
148      * @since 2.5
149      */
150     @Parameter( defaultValue = "false" )
151     private boolean useDefaultManifestFile;
152 
153     /**
154      * @since 2.10
155      */
156     @Parameter( property = "maven.javadoc.classifier", defaultValue = "javadoc", required = true )
157     private String classifier;
158 
159     /** {@inheritDoc} */
160     public void execute()
161         throws MojoExecutionException
162     {
163         if ( skip )
164         {
165             getLog().info( "Skipping javadoc generation" );
166             return;
167         }
168 
169         File innerDestDir = this.destDir;
170         if ( innerDestDir == null )
171         {
172             innerDestDir = new File( getOutputDirectory() );
173         }
174 
175         if ( !( "pom".equalsIgnoreCase( project.getPackaging() ) && isAggregator() ) )
176         {
177             ArtifactHandler artifactHandler = project.getArtifact().getArtifactHandler();
178             if ( !"java".equals( artifactHandler.getLanguage() ) )
179             {
180                 getLog().info( "Not executing Javadoc as the project is not a Java classpath-capable package" );
181                 return;
182             }
183         }
184 
185         try
186         {
187             executeReport( Locale.getDefault() );
188 
189             if ( innerDestDir.exists() )
190             {
191                 File outputFile = generateArchive( innerDestDir, finalName + "-" + getClassifier() + ".jar" );
192 
193                 if ( !attach )
194                 {
195                     getLog().info( "NOT adding javadoc to attached artifacts list." );
196                 }
197                 else
198                 {
199                     // TODO: these introduced dependencies on the project are going to become problematic - can we export it
200                     //  through metadata instead?
201                     projectHelper.attachArtifact( project, "javadoc", getClassifier(), outputFile );
202                 }
203             }
204         }
205         catch ( ArchiverException e )
206         {
207             failOnError( "ArchiverException: Error while creating archive", e );
208         }
209         catch ( IOException e )
210         {
211             failOnError( "IOException: Error while creating archive", e );
212         }
213         catch ( MavenReportException e )
214         {
215             failOnError( "MavenReportException: Error while creating archive", e );
216         }
217         catch ( RuntimeException e )
218         {
219             failOnError( "RuntimeException: Error while creating archive", e );
220         }
221     }
222 
223     // ----------------------------------------------------------------------
224     // Protected methods
225     // ----------------------------------------------------------------------
226 
227     /**
228      * @return the wanted classifier, i.e. <code>javadoc</code> or <code>test-javadoc</code>
229      */
230     protected String getClassifier()
231     {
232         return classifier;
233     }
234 
235     // ----------------------------------------------------------------------
236     // private methods
237     // ----------------------------------------------------------------------
238 
239     /**
240      * Method that creates the jar file
241      *
242      * @param javadocFiles the directory where the generated jar file will be put
243      * @param jarFileName the filename of the generated jar file
244      * @return a File object that contains the generated jar file
245      * @throws ArchiverException if any
246      * @throws IOException if any
247      */
248     private File generateArchive( File javadocFiles, String jarFileName )
249         throws ArchiverException, IOException
250     {
251         File javadocJar = new File( jarOutputDirectory, jarFileName );
252 
253         if ( javadocJar.exists() )
254         {
255             javadocJar.delete();
256         }
257 
258         MavenArchiver archiver = new MavenArchiver();
259         archiver.setArchiver( jarArchiver );
260         archiver.setOutputFile( javadocJar );
261 
262         File contentDirectory = javadocFiles;
263         if ( !contentDirectory.exists() )
264         {
265             getLog().warn( "JAR will be empty - no content was marked for inclusion!" );
266         }
267         else
268         {
269             archiver.getArchiver().addDirectory( contentDirectory, DEFAULT_INCLUDES, DEFAULT_EXCLUDES );
270         }
271 
272         List<Resource> resources = project.getBuild().getResources();
273 
274         for ( Resource r : resources )
275         {
276             if ( r.getDirectory().endsWith( "maven-shared-archive-resources" ) )
277             {
278                 archiver.getArchiver().addDirectory( new File( r.getDirectory() ) );
279             }
280         }
281 
282         if ( useDefaultManifestFile && defaultManifestFile.exists() && archive.getManifestFile() == null )
283         {
284             getLog().info( "Adding existing MANIFEST to archive. Found under: " + defaultManifestFile.getPath() );
285             archive.setManifestFile( defaultManifestFile );
286         }
287 
288         try
289         {
290             // we don't want Maven stuff
291             archive.setAddMavenDescriptor( false );
292             archiver.createArchive( session, project, archive );
293         }
294         catch ( ManifestException e )
295         {
296             throw new ArchiverException( "ManifestException: " + e.getMessage(), e );
297         }
298         catch ( DependencyResolutionRequiredException e )
299         {
300             throw new ArchiverException( "DependencyResolutionRequiredException: " + e.getMessage(), e );
301         }
302 
303         return javadocJar;
304     }
305 }