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