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