View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.javadoc;
20  
21  import javax.inject.Inject;
22  
23  import java.io.File;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collections;
27  import java.util.LinkedList;
28  import java.util.List;
29  import java.util.Locale;
30  import java.util.ResourceBundle;
31  
32  import org.apache.maven.artifact.Artifact;
33  import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
34  import org.apache.maven.doxia.tools.SiteTool;
35  import org.apache.maven.plugins.annotations.Execute;
36  import org.apache.maven.plugins.annotations.LifecyclePhase;
37  import org.apache.maven.plugins.annotations.Mojo;
38  import org.apache.maven.plugins.annotations.Parameter;
39  import org.apache.maven.plugins.annotations.ResolutionScope;
40  import org.apache.maven.plugins.javadoc.resolver.ResourceResolver;
41  import org.apache.maven.plugins.javadoc.resolver.SourceResolverConfig;
42  import org.apache.maven.project.MavenProject;
43  import org.apache.maven.project.ProjectBuilder;
44  import org.apache.maven.reporting.MavenReportException;
45  import org.apache.maven.toolchain.ToolchainManager;
46  import org.codehaus.plexus.archiver.manager.ArchiverManager;
47  import org.codehaus.plexus.util.StringUtils;
48  import org.eclipse.aether.RepositorySystem;
49  import org.eclipse.aether.util.filter.ScopeDependencyFilter;
50  
51  /**
52   * Generates documentation for the <code>Java Test code</code> in a <b>NON aggregator</b> project using the standard
53   * <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/man/javadoc.html">Javadoc Tool</a>.
54   *
55   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
56   * @since 2.3
57   * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/man/javadoc.html">Javadoc Tool</a>
58   */
59  @Mojo(name = "test-javadoc", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true)
60  @Execute(phase = LifecyclePhase.GENERATE_TEST_SOURCES)
61  public class TestJavadocReport extends JavadocReport {
62      // ----------------------------------------------------------------------
63      // Javadoc Options (should be inline with options defined in TestJavadocJar)
64      // ----------------------------------------------------------------------
65  
66      /**
67       * Specifies the Test title to be placed near the top of the overview summary file.
68       * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/man/javadoc.html#standard-doclet-options">Doclet option doctitle</a>.
69       * @since 2.5
70       */
71      @Parameter(
72              property = "testDoctitle",
73              alias = "doctitle",
74              defaultValue = "${project.name} ${project.version} Test API")
75      private String testDoctitle;
76  
77      /**
78       * Specifies that Javadoc should retrieve the text for the Test overview documentation from the "source" file
79       * specified by path/filename and place it on the Overview page (overview-summary.html).
80       * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/man/javadoc.html#standard-doclet-options">Doclet option overview</a>.
81       * @since 2.5
82       */
83      @Parameter(
84              property = "testOverview",
85              alias = "overview",
86              defaultValue = "${basedir}/src/test/javadoc/overview.html")
87      private File testOverview;
88  
89      /**
90       * Specifies the Test title to be placed in the HTML title tag.
91       * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/man/javadoc.html#standard-doclet-options">Doclet option windowtitle</a>.
92       * @since 2.5
93       */
94      @Parameter(
95              property = "testWindowtitle",
96              alias = "windowtitle",
97              defaultValue = "${project.name} ${project.version} Test API")
98      private String testWindowtitle;
99  
100     // ----------------------------------------------------------------------
101     // Mojo Parameters (should be inline with options defined in TestJavadocJar)
102     // ----------------------------------------------------------------------
103 
104     /**
105      * Specifies the Test Javadoc resources directory to be included in the Javadoc (i.e. package.html, images...).
106      * <br/>
107      * Could be used in addition of <code>docfilessubdirs</code> parameter.
108      * <br/>
109      * See <a href="#docfilessubdirs">docfilessubdirs</a>.
110      *
111      * @since 2.5
112      */
113     @Parameter(alias = "javadocDirectory", defaultValue = "${basedir}/src/test/javadoc")
114     private File testJavadocDirectory;
115 
116     // ----------------------------------------------------------------------
117     // Report Mojo Parameters
118     // ----------------------------------------------------------------------
119 
120     /**
121      * The name of the Test Javadoc report to be displayed in the Maven Generated Reports page
122      * (i.e. <code>project-reports.html</code>).
123      *
124      * @since 2.5
125      */
126     @Parameter(property = "testName", alias = "name")
127     private String testName;
128 
129     /**
130      * The description of the Test Javadoc report to be displayed in the Maven Generated Reports page
131      * (i.e. <code>project-reports.html</code>).
132      *
133      * @since 2.5
134      */
135     @Parameter(property = "testDescription", alias = "description")
136     private String testDescription;
137 
138     // ----------------------------------------------------------------------
139     // Report public methods
140     // ----------------------------------------------------------------------
141 
142     @Inject
143     public TestJavadocReport(
144             SiteTool siteTool,
145             ArchiverManager archiverManager,
146             ResourceResolver resourceResolver,
147             RepositorySystem repoSystem,
148             ArtifactHandlerManager artifactHandlerManager,
149             ProjectBuilder mavenProjectBuilder,
150             ToolchainManager toolchainManager) {
151         super(
152                 siteTool,
153                 archiverManager,
154                 resourceResolver,
155                 repoSystem,
156                 artifactHandlerManager,
157                 mavenProjectBuilder,
158                 toolchainManager);
159     }
160 
161     @Override
162     protected void executeReport(Locale unusedLocale) throws MavenReportException {
163         addMainJavadocLink();
164 
165         super.executeReport(unusedLocale);
166     }
167 
168     @Override
169     public String getName(Locale locale) {
170         if (testName == null || testName.isEmpty()) {
171             return getBundle(locale).getString("report.test-javadoc.name");
172         }
173 
174         return testName;
175     }
176 
177     @Override
178     public String getDescription(Locale locale) {
179         if (testDescription == null || testDescription.isEmpty()) {
180             return getBundle(locale).getString("report.test-javadoc.description");
181         }
182 
183         return testDescription;
184     }
185 
186     // ----------------------------------------------------------------------
187     // Protected methods
188     // Important Note: should be inline with methods defined in TestJavadocJar
189     // ----------------------------------------------------------------------
190 
191     @Override
192     protected List<File> getProjectBuildOutputDirs(MavenProject p) {
193         List<File> dirs = new ArrayList<>();
194         if (StringUtils.isNotEmpty(p.getBuild().getOutputDirectory())) {
195             dirs.add(new File(p.getBuild().getOutputDirectory()));
196         }
197         if (StringUtils.isNotEmpty(p.getBuild().getTestOutputDirectory())) {
198             dirs.add(new File(p.getBuild().getTestOutputDirectory()));
199         }
200 
201         return dirs;
202     }
203 
204     @Override
205     protected List<String> getProjectSourceRoots(MavenProject p) {
206         if ("pom".equals(p.getPackaging().toLowerCase())) {
207             return Collections.emptyList();
208         }
209 
210         return p.getTestCompileSourceRoots() == null
211                 ? Collections.<String>emptyList()
212                 : new LinkedList<>(p.getTestCompileSourceRoots());
213     }
214 
215     @Override
216     protected List<String> getExecutionProjectSourceRoots(MavenProject p) {
217         if ("pom".equals(p.getExecutionProject().getPackaging().toLowerCase())) {
218             return Collections.emptyList();
219         }
220 
221         return p.getExecutionProject().getTestCompileSourceRoots() == null
222                 ? Collections.<String>emptyList()
223                 : new LinkedList<>(p.getExecutionProject().getTestCompileSourceRoots());
224     }
225 
226     @Override
227     protected File getJavadocDirectory() {
228         return testJavadocDirectory;
229     }
230 
231     @Override
232     protected String getDoctitle() {
233         return testDoctitle;
234     }
235 
236     @Override
237     protected File getOverview() {
238         return testOverview;
239     }
240 
241     @Override
242     protected String getWindowtitle() {
243         return testWindowtitle;
244     }
245 
246     @Override
247     protected ScopeDependencyFilter getDependencyScopeFilter() {
248         return new ScopeDependencyFilter(
249                 Arrays.asList(
250                         Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_TEST),
251                 null);
252     }
253 
254     /**
255      * Gets the resource bundle for the specified locale.
256      *
257      * @param locale The locale of the currently generated report.
258      * @return The resource bundle for the requested locale.
259      */
260     private ResourceBundle getBundle(Locale locale) {
261         return ResourceBundle.getBundle(
262                 "test-javadoc-report", locale, getClass().getClassLoader());
263     }
264 
265     /**
266      * Add the <code>../apidocs</code> to the links parameter so Test report could be linked to the Main report.
267      */
268     private void addMainJavadocLink() {
269         if (links == null) {
270             links = new ArrayList<>();
271         }
272 
273         File apidocs = new File(getReportOutputDirectory(), "apidocs");
274         if (apidocs.isDirectory() && !links.contains("../apidocs")) {
275             links.add("../apidocs");
276         }
277     }
278 
279     /**
280      * Overridden to enable the resolution of -test-sources jar files.
281      *
282      * {@inheritDoc}
283      */
284     @Override
285     protected SourceResolverConfig configureDependencySourceResolution(final SourceResolverConfig config) {
286         return super.configureDependencySourceResolution(config)
287                 .withoutCompileSources()
288                 .withTestSources();
289     }
290 
291     @Override
292     protected boolean isTest() {
293         return true;
294     }
295 }