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 java.io.File;
22  import java.io.IOException;
23  import java.net.HttpURLConnection;
24  import java.net.URL;
25  import java.nio.charset.Charset;
26  import java.nio.charset.StandardCharsets;
27  import java.nio.file.Files;
28  import java.nio.file.Path;
29  import java.nio.file.Paths;
30  import java.util.Collections;
31  import java.util.HashMap;
32  import java.util.List;
33  import java.util.Locale;
34  import java.util.Map;
35  import java.util.Objects;
36  
37  import org.apache.commons.lang3.StringUtils;
38  import org.apache.maven.execution.MavenSession;
39  import org.apache.maven.model.Plugin;
40  import org.apache.maven.plugin.LegacySupport;
41  import org.apache.maven.plugin.MojoExecution;
42  import org.apache.maven.plugin.MojoExecutionException;
43  import org.apache.maven.plugin.MojoFailureException;
44  import org.apache.maven.plugin.testing.AbstractMojoTestCase;
45  import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
46  import org.apache.maven.plugins.javadoc.ProxyServer.AuthAsyncProxyServlet;
47  import org.apache.maven.project.MavenProject;
48  import org.apache.maven.project.ProjectBuildingRequest;
49  import org.apache.maven.project.ProjectBuildingRequest.RepositoryMerging;
50  import org.apache.maven.settings.Proxy;
51  import org.apache.maven.settings.Settings;
52  import org.apache.maven.shared.utils.io.FileUtils;
53  import org.codehaus.plexus.languages.java.version.JavaVersion;
54  import org.eclipse.aether.DefaultRepositorySystemSession;
55  import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
56  import org.eclipse.aether.repository.LocalRepository;
57  import org.hamcrest.MatcherAssert;
58  import org.junit.AssumptionViolatedException;
59  import org.slf4j.Logger;
60  import org.slf4j.LoggerFactory;
61  
62  import static org.apache.commons.io.FileUtils.copyDirectory;
63  import static org.apache.commons.io.FileUtils.deleteDirectory;
64  import static org.assertj.core.api.Assertions.assertThat;
65  import static org.hamcrest.CoreMatchers.anyOf;
66  import static org.hamcrest.CoreMatchers.containsString;
67  import static org.hamcrest.CoreMatchers.is;
68  import static org.junit.Assume.assumeThat;
69  import static org.mockito.Mockito.mock;
70  import static org.mockito.Mockito.spy;
71  import static org.mockito.Mockito.when;
72  
73  /**
74   * Test {@link org.apache.maven.plugins.javadoc.JavadocReport} class.
75   *
76   * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
77   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
78   */
79  public class JavadocReportTest extends AbstractMojoTestCase {
80  
81      private static final char LINE_SEPARATOR = ' ';
82  
83      public static final String OPTIONS_UMLAUT_ENCODING = "Options Umlaut Encoding ö ä ü ß";
84  
85      private Path unit;
86  
87      private Path tempDirectory;
88  
89      private File localRepo;
90  
91      private static final Logger LOGGER = LoggerFactory.getLogger(JavadocReportTest.class);
92  
93      @Override
94      protected void setUp() throws Exception {
95          super.setUp();
96  
97          tempDirectory = Files.createTempDirectory("JavadocReportTest");
98          localRepo = tempDirectory.resolve(Paths.get("target/local-repo/")).toFile();
99          unit = new File(getBasedir(), "src/test/resources/unit").toPath();
100 
101         createTestRepo();
102     }
103 
104     @Override
105     protected void tearDown() throws Exception {
106         try {
107             deleteDirectory(tempDirectory.toFile());
108         } catch (IOException ex) {
109             // CI servers can have problems deleting files.
110             // It will get cleared out eventually, and since
111             // temporary directories have unique names,
112             // it shouldn't affect subsequent tests.
113         }
114 
115         super.tearDown();
116     }
117 
118     private JavadocReport lookupMojo(Path testPom) throws Exception {
119         JavadocReport mojo = (JavadocReport) lookupMojo("javadoc", testPom.toFile());
120 
121         Plugin p = new Plugin();
122         p.setGroupId("org.apache.maven.plugins");
123         p.setArtifactId("maven-javadoc-plugin");
124         MojoExecution mojoExecution = new MojoExecution(p, "javadoc", null);
125 
126         setVariableValueToObject(mojo, "mojoExecution", mojoExecution);
127 
128         MavenProject currentProject = new MavenProjectStub();
129         currentProject.setGroupId("GROUPID");
130         currentProject.setArtifactId("ARTIFACTID");
131 
132         List<MavenProject> reactorProjects =
133                 mojo.getReactorProjects() != null ? mojo.getReactorProjects() : Collections.emptyList();
134         MavenSession session = newMavenSession(currentProject);
135         setVariableValueToObject(mojo, "session", session);
136         setVariableValueToObject(mojo, "repoSession", session.getRepositorySession());
137         setVariableValueToObject(mojo, "reactorProjects", reactorProjects);
138         return mojo;
139     }
140 
141     /**
142      * Create test repository in target directory.
143      *
144      * @throws IOException if any
145      */
146     private void createTestRepo() throws IOException {
147         assertTrue(localRepo.mkdirs());
148 
149         // ----------------------------------------------------------------------
150         // UMLGraph
151         // ----------------------------------------------------------------------
152 
153         Path sourceDir = unit.resolve("doclet-test/artifact-doclet");
154         assertThat(sourceDir).exists();
155         copyDirectory(sourceDir.toFile(), localRepo);
156 
157         // ----------------------------------------------------------------------
158         // UMLGraph-bis
159         // ----------------------------------------------------------------------
160 
161         sourceDir = unit.resolve("doclet-path-test/artifact-doclet");
162         assertThat(sourceDir).exists();
163         copyDirectory(sourceDir.toFile(), localRepo);
164 
165         // ----------------------------------------------------------------------
166         // commons-attributes-compiler
167         // https://www.tullmann.org/pat/taglets/
168         // ----------------------------------------------------------------------
169 
170         sourceDir = unit.resolve("taglet-test/artifact-taglet");
171         assertThat(sourceDir).exists();
172         copyDirectory(sourceDir.toFile(), localRepo);
173 
174         // ----------------------------------------------------------------------
175         // stylesheetfile-test
176         // ----------------------------------------------------------------------
177 
178         sourceDir = unit.resolve("stylesheetfile-test/artifact-stylesheetfile");
179         assertThat(sourceDir).exists();
180         copyDirectory(sourceDir.toFile(), localRepo);
181 
182         // ----------------------------------------------------------------------
183         // helpfile-test
184         // ----------------------------------------------------------------------
185 
186         sourceDir = unit.resolve("helpfile-test/artifact-helpfile");
187         assertThat(sourceDir).exists();
188         copyDirectory(sourceDir.toFile(), localRepo);
189 
190         // Remove SCM files
191         List<String> files = FileUtils.getFileAndDirectoryNames(
192                 localRepo, FileUtils.getDefaultExcludesAsString(), null, true, true, true, true);
193         for (String filename : files) {
194             File file = new File(filename);
195 
196             if (file.isDirectory()) {
197                 deleteDirectory(file);
198             } else {
199                 file.delete();
200             }
201         }
202     }
203 
204     /**
205      * Convenience method that reads the contents of the specified file object into a string with a
206      * <code>space</code> as line separator.
207      *
208      * @see #LINE_SEPARATOR
209      * @param file the file to be read
210      * @return a String object that contains the contents of the file
211      * @throws IOException if any
212      */
213     private static String readFile(Path file) throws IOException {
214         return readFile(file, StandardCharsets.UTF_8);
215     }
216 
217     /**
218      * Convenience method that reads the contents of the specified file object into a string with a
219      * <code>space</code> as line separator.
220      *
221      * @see #LINE_SEPARATOR
222      * @param file the file to be read
223      * @param cs charset to use
224      * @return a String object that contains the contents of the file
225      * @throws IOException if any
226      */
227     private static String readFile(Path file, Charset cs) throws IOException {
228         StringBuilder str = new StringBuilder((int) Files.size(file));
229 
230         for (String strTmp : Files.readAllLines(file, cs)) {
231             str.append(LINE_SEPARATOR);
232             str.append(strTmp);
233         }
234 
235         return str.toString();
236     }
237 
238     /**
239      * Test when default configuration is provided for the plugin
240      *
241      * @throws Exception if any
242      */
243     public void testDefaultConfiguration() throws Exception {
244         Path testPom = unit.resolve("default-configuration/default-configuration-plugin-config.xml");
245         JavadocReport mojo = lookupMojo(testPom);
246         mojo.execute();
247 
248         // package level generated javadoc files
249         Path apidocs = new File(getBasedir(), "target/test/unit/default-configuration/target/site/apidocs").toPath();
250 
251         String appHtml = "def/configuration/App.html";
252         Path generatedFile = apidocs.resolve(appHtml);
253         assertThat(generatedFile).exists();
254 
255         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore("16")) {
256             String url = Objects.requireNonNull(mojo.getDefaultJavadocApiLink()).getUrl();
257             HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
258             connection.setRequestMethod("HEAD");
259             try {
260                 // only test when URL can be reached
261                 if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
262                     try {
263                         assumeThat(connection.getURL().toString(), is(url));
264 
265                         // https://bugs.openjdk.java.net/browse/JDK-8216497
266                         MatcherAssert.assertThat(
267                                 url + " available, but " + appHtml + " is missing link to java.lang.Object",
268                                 new String(Files.readAllBytes(generatedFile), StandardCharsets.UTF_8),
269                                 anyOf(
270                                         containsString("/docs/api/java/lang/Object.html"),
271                                         containsString("/docs/api/java.base/java/lang/Object.html")));
272                     } catch (AssumptionViolatedException e) {
273                         LOGGER.warn("ignoring defaultAPI check: {}", e.getMessage());
274                     }
275                 }
276             } catch (Exception e) {
277                 LOGGER.error("error connecting to javadoc URL: {}", url);
278                 throw e;
279             }
280         } else {
281             MatcherAssert.assertThat(
282                     new String(Files.readAllBytes(generatedFile), StandardCharsets.UTF_8),
283                     containsString("/docs/api/java.base/java/lang/Object.html"));
284         }
285 
286         assertThat(apidocs.resolve("def/configuration/AppSample.html")).exists();
287         assertThat(apidocs.resolve("def/configuration/package-summary.html")).exists();
288         assertThat(apidocs.resolve("def/configuration/package-tree.html")).exists();
289         assertThat(apidocs.resolve("def/configuration/package-use.html")).exists();
290 
291         // package-frame and allclasses-(no)frame not generated anymore since Java 11
292         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore("11")) {
293             assertThat(apidocs.resolve("def/configuration/package-frame.html")).exists();
294             assertThat(apidocs.resolve("allclasses-frame.html"))
295                     .exists()
296                     .content()
297                     .containsOnlyOnce("def/configuration/App.html")
298                     .containsOnlyOnce("def/configuration/AppSample.html");
299             assertThat(apidocs.resolve("allclasses-noframe.html"))
300                     .exists()
301                     .content()
302                     .containsOnlyOnce("def/configuration/App.html")
303                     .containsOnlyOnce("def/configuration/AppSample.html");
304         }
305 
306         // class level generated javadoc files
307         assertThat(apidocs.resolve("def/configuration/class-use/App.html")).exists();
308         assertThat(apidocs.resolve("def/configuration/class-use/AppSample.html"))
309                 .exists();
310 
311         // project level generated javadoc files
312         assertThat(apidocs.resolve("constant-values.html")).exists();
313         assertThat(apidocs.resolve("deprecated-list.html")).exists();
314         assertThat(apidocs.resolve("help-doc.html")).exists();
315         assertThat(apidocs.resolve("index-all.html")).exists();
316         assertThat(apidocs.resolve("index.html")).exists();
317         assertThat(apidocs.resolve("overview-tree.html")).exists();
318         if (JavaVersion.JAVA_VERSION.isAtLeast("23")) {
319             assertThat(apidocs.resolve("resource-files/stylesheet.css")).exists();
320         } else {
321 
322             assertThat(apidocs.resolve("stylesheet.css")).exists();
323         }
324 
325         if (JavaVersion.JAVA_VERSION.isAtLeast("10")) {
326             assertThat(apidocs.resolve("element-list")).exists();
327         } else {
328             assertThat(apidocs.resolve("package-list")).exists();
329         }
330     }
331 
332     /**
333      * Method for testing the subpackages and excludePackageNames parameter
334      *
335      * @throws Exception if any
336      */
337     public void testSubpackages() throws Exception {
338         Path testPom = unit.resolve("subpackages-test/subpackages-test-plugin-config.xml");
339         JavadocReport mojo = lookupMojo(testPom);
340         mojo.execute();
341 
342         Path apidocs = new File(getBasedir(), "target/test/unit/subpackages-test/target/site/apidocs").toPath();
343 
344         // check the excluded packages
345         assertThat(apidocs.resolve("subpackages/test/excluded")).doesNotExist();
346         assertThat(apidocs.resolve("subpackages/test/included/exclude")).doesNotExist();
347 
348         // check if the classes in the specified subpackages were included
349         assertThat(apidocs.resolve("subpackages/test/App.html")).exists();
350         assertThat(apidocs.resolve("subpackages/test/AppSample.html")).exists();
351         assertThat(apidocs.resolve("subpackages/test/included/IncludedApp.html"))
352                 .exists();
353         assertThat(apidocs.resolve("subpackages/test/included/IncludedAppSample.html"))
354                 .exists();
355     }
356 
357     public void testIncludesExcludes() throws Exception {
358         Path testPom = unit.resolve("file-include-exclude-test/file-include-exclude-plugin-config.xml");
359         JavadocReport mojo = lookupMojo(testPom);
360         mojo.execute();
361 
362         Path apidocs =
363                 new File(getBasedir(), "target/test/unit/file-include-exclude-test/target/site/apidocs").toPath();
364 
365         // check if the classes in the specified subpackages were included
366         assertThat(apidocs.resolve("subpackages/test/App.html")).exists();
367         assertThat(apidocs.resolve("subpackages/test/AppSample.html")).exists();
368         assertThat(apidocs.resolve("subpackages/test/included/IncludedApp.html"))
369                 .exists();
370         assertThat(apidocs.resolve("subpackages/test/included/IncludedAppSample.html"))
371                 .exists();
372         assertThat(apidocs.resolve("subpackages/test/PariahApp.html")).doesNotExist();
373     }
374 
375     /**
376      * Test the recursion and exclusion of the doc-files subdirectories.
377      *
378      * @throws Exception if any
379      */
380     public void testDocfiles() throws Exception {
381         // Should be an assumption, but not supported by TestCase
382         // Seems like a bug in Javadoc 9 and above
383         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast("9")) {
384             return;
385         }
386 
387         Path testPom = unit.resolve("docfiles-test/docfiles-test-plugin-config.xml");
388         JavadocReport mojo = lookupMojo(testPom);
389         mojo.execute();
390 
391         Path apidocs = new File(getBasedir(), "target/test/unit/docfiles-test/target/site/apidocs/").toPath();
392 
393         // check if the doc-files subdirectories were copied
394         assertThat(apidocs.resolve("docfiles/test/doc-files")).exists();
395         assertThat(apidocs.resolve("docfiles/test/doc-files/included-dir1/sample-included1.gif"))
396                 .exists();
397         assertThat(apidocs.resolve("docfiles/test/doc-files/included-dir2/sample-included2.gif"))
398                 .exists();
399         assertThat(apidocs.resolve("docfiles/test/doc-files/excluded-dir1")).doesNotExist();
400         assertThat(apidocs.resolve("docfiles/test/doc-files/excluded-dir2")).doesNotExist();
401 
402         testPom = unit.resolve("docfiles-with-java-test/docfiles-with-java-test-plugin-config.xml");
403         mojo = lookupMojo(testPom);
404         mojo.execute();
405     }
406 
407     /**
408      * Test javadoc plugin using custom configuration. noindex, notree and nodeprecated parameters
409      * were set to true.
410      *
411      * @throws Exception if any
412      */
413     public void testCustomConfiguration() throws Exception {
414         Path testPom = unit.resolve("custom-configuration/custom-configuration-plugin-config.xml");
415         JavadocReport mojo = lookupMojo(testPom);
416         mojo.execute();
417 
418         Path apidocs = new File(getBasedir(), "target/test/unit/custom-configuration/target/site/apidocs").toPath();
419 
420         // check if there is a tree page generated (notree == true)
421         assertThat(apidocs.resolve("overview-tree.html")).doesNotExist();
422         assertThat(apidocs.resolve("custom/configuration/package-tree.html")).doesNotExist();
423 
424         // check if the main index page was generated (noindex == true)
425         assertThat(apidocs.resolve("index-all.html")).doesNotExist();
426 
427         // check if the deprecated list and the deprecated api were generated (nodeprecated == true)
428         // @todo Fix: the class-use of the deprecated api is still created eventhough the deprecated api of that class
429         // is no longer generated
430         assertThat(apidocs.resolve("deprecated-list.html")).doesNotExist();
431         assertThat(apidocs.resolve("custom/configuration/App.html")).doesNotExist();
432 
433         // read the contents of the html files based on some of the parameter values
434         // author == false
435         String str = readFile(apidocs.resolve("custom/configuration/AppSample.html"));
436         assertFalse(str.toLowerCase(Locale.ENGLISH).contains("author"));
437 
438         // bottom
439         assertTrue(str.toUpperCase(Locale.ENGLISH).contains("SAMPLE BOTTOM CONTENT"));
440 
441         // offlineLinks
442         if (JavaVersion.JAVA_VERSION.isBefore("11.0.2")) {
443             assertThat(str)
444                     .containsIgnoringCase("href=\"http://java.sun.com/j2se/1.4.2/docs/api/java/lang/string.html");
445         } else {
446             assertTrue(str.toLowerCase(Locale.ENGLISH)
447                     .contains("href=\"http://java.sun.com/j2se/1.4.2/docs/api/java.base/java/lang/string.html"));
448         }
449 
450         // header
451         assertTrue(str.toUpperCase(Locale.ENGLISH).contains("MAVEN JAVADOC PLUGIN TEST"));
452 
453         // footer
454         if (JavaVersion.JAVA_VERSION.isBefore("16-ea")
455                 && !System.getProperty("java.vm.name").contains("OpenJ9")) {
456             assertTrue(str.toUpperCase(Locale.ENGLISH).contains("MAVEN JAVADOC PLUGIN TEST FOOTER"));
457         }
458 
459         // nohelp == true
460         assertFalse(str.toUpperCase(Locale.ENGLISH).contains("/HELP-DOC.HTML"));
461 
462         // check the wildcard (*) package exclusions -- excludePackageNames parameter
463         assertThat(apidocs.resolve("custom/configuration/exclude1/Exclude1App.html"))
464                 .exists();
465         assertThat(apidocs.resolve("custom/configuration/exclude1/subexclude/SubexcludeApp.html"))
466                 .doesNotExist();
467         assertThat(apidocs.resolve("custom/configuration/exclude2/Exclude2App.html"))
468                 .doesNotExist();
469 
470         assertThat(apidocs.resolve("options")).isRegularFile();
471 
472         String contentOptions = new String(Files.readAllBytes(apidocs.resolve("options")), StandardCharsets.UTF_8);
473 
474         assertNotNull(contentOptions);
475         assertThat(contentOptions).contains("-link").contains("http://java.sun.com/j2se/");
476     }
477 
478     /**
479      * Method to test the doclet artifact configuration
480      *
481      * @throws Exception if any
482      */
483     public void testDoclets() throws Exception {
484         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast("13")) {
485             // As of JDK 13, the com.sun.javadoc API is no longer supported.
486             return;
487         }
488 
489         // ----------------------------------------------------------------------
490         // doclet-test: check if the file generated by UmlGraph exists and if
491         // doclet path contains the UmlGraph artifact
492         // ----------------------------------------------------------------------
493 
494         Path testPom = unit.resolve("doclet-test/doclet-test-plugin-config.xml");
495         JavadocReport mojo = lookupMojo(testPom);
496 
497         MavenSession session = spy(newMavenSession(mojo.project));
498         ProjectBuildingRequest buildingRequest = mock(ProjectBuildingRequest.class);
499         when(buildingRequest.getRemoteRepositories()).thenReturn(mojo.project.getRemoteArtifactRepositories());
500         when(session.getProjectBuildingRequest()).thenReturn(buildingRequest);
501         DefaultRepositorySystemSession repositorySession = new DefaultRepositorySystemSession();
502         repositorySession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory()
503                 .newInstance(repositorySession, new LocalRepository(localRepo)));
504         when(buildingRequest.getRepositorySession()).thenReturn(repositorySession);
505         when(session.getRepositorySession()).thenReturn(repositorySession);
506         LegacySupport legacySupport = lookup(LegacySupport.class);
507         legacySupport.setSession(session);
508 
509         setVariableValueToObject(mojo, "session", session);
510         setVariableValueToObject(mojo, "repoSession", repositorySession);
511         mojo.execute();
512 
513         Path generatedFile =
514                 new File(getBasedir(), "target/test/unit/doclet-test/target/site/apidocs/graph.dot").toPath();
515         assertThat(generatedFile).exists();
516 
517         Path optionsFile = new File(mojo.getPluginReportOutputDirectory(), "options").toPath();
518         assertThat(optionsFile).exists();
519         String options = readFile(optionsFile);
520         assertThat(options).contains("/target/local-repo/umlgraph/UMLGraph/2.1/UMLGraph-2.1.jar");
521 
522         // ----------------------------------------------------------------------
523         // doclet-path: check if the file generated by UmlGraph exists and if
524         // doclet path contains the twice UmlGraph artifacts
525         // ----------------------------------------------------------------------
526 
527         testPom = unit.resolve("doclet-path-test/doclet-path-test-plugin-config.xml");
528         mojo = lookupMojo(testPom);
529         setVariableValueToObject(mojo, "session", session);
530         setVariableValueToObject(mojo, "repoSession", repositorySession);
531         mojo.execute();
532 
533         generatedFile = new File(getBasedir(), "target/test/unit/doclet-test/target/site/apidocs/graph.dot").toPath();
534         assertThat(generatedFile).exists();
535 
536         optionsFile = new File(mojo.getPluginReportOutputDirectory(), "options").toPath();
537         assertThat(optionsFile).exists();
538         options = readFile(optionsFile);
539         assertThat(options)
540                 .contains("/target/local-repo/umlgraph/UMLGraph/2.1/UMLGraph-2.1.jar")
541                 .contains("/target/local-repo/umlgraph/UMLGraph-bis/2.1/UMLGraph-bis-2.1.jar");
542     }
543 
544     /**
545      * Method to test when the path to the project sources has an apostrophe (')
546      *
547      * @throws Exception if any
548      */
549     public void testQuotedPath() throws Exception {
550         Path testPom = unit.resolve("quotedpath'test/quotedpath-test-plugin-config.xml");
551         JavadocReport mojo = lookupMojo(testPom);
552         mojo.execute();
553 
554         Path apidocs = new File(getBasedir(), "target/test/unit/quotedpath'test/target/site/apidocs").toPath();
555 
556         // package level generated javadoc files
557         assertThat(apidocs.resolve("quotedpath/test/App.html")).exists();
558         assertThat(apidocs.resolve("quotedpath/test/AppSample.html")).exists();
559 
560         // project level generated javadoc files
561         assertThat(apidocs.resolve("index-all.html")).exists();
562         assertThat(apidocs.resolve("index.html")).exists();
563         assertThat(apidocs.resolve("overview-tree.html")).exists();
564         if (JavaVersion.JAVA_VERSION.isAtLeast("23")) {
565             assertThat(apidocs.resolve("resource-files/stylesheet.css")).exists();
566         } else {
567             assertThat(apidocs.resolve("stylesheet.css")).exists();
568         }
569 
570         if (JavaVersion.JAVA_VERSION.isBefore("10")) {
571             assertThat(apidocs.resolve("package-list")).exists();
572         } else {
573             assertThat(apidocs.resolve("element-list")).exists();
574         }
575     }
576 
577     /**
578      * Method to test when the options file has umlauts.
579      *
580      * @throws Exception if any
581      */
582     public void testOptionsUmlautEncoding() throws Exception {
583         Path testPom = unit.resolve("optionsumlautencoding-test/optionsumlautencoding-test-plugin-config.xml");
584         JavadocReport mojo = lookupMojo(testPom);
585         mojo.execute();
586 
587         Path optionsFile = new File(mojo.getPluginReportOutputDirectory(), "options").toPath();
588         assertThat(optionsFile).exists();
589 
590         // check for a part of the window title
591         String content;
592         String expected;
593         if (JavaVersion.JAVA_VERSION.isAtLeast("9") && JavaVersion.JAVA_VERSION.isBefore("12")) {
594             content = readFile(optionsFile, StandardCharsets.UTF_8);
595             expected = OPTIONS_UMLAUT_ENCODING;
596         } else {
597             content = readFile(optionsFile, Charset.defaultCharset());
598             expected = new String(OPTIONS_UMLAUT_ENCODING.getBytes(Charset.defaultCharset()));
599         }
600 
601         assertThat(content).contains(expected);
602 
603         Path apidocs =
604                 new File(getBasedir(), "target/test/unit/optionsumlautencoding-test/target/site/apidocs").toPath();
605 
606         // package level generated javadoc files
607         assertThat(apidocs.resolve("optionsumlautencoding/test/App.html")).exists();
608         assertThat(apidocs.resolve("optionsumlautencoding/test/AppSample.html")).exists();
609 
610         // project level generated javadoc files
611         assertThat(apidocs.resolve("index-all.html")).exists();
612         assertThat(apidocs.resolve("index.html")).exists();
613         assertThat(apidocs.resolve("overview-tree.html")).exists();
614         if (JavaVersion.JAVA_VERSION.isAtLeast("23")) {
615             assertThat(apidocs.resolve("resource-files/stylesheet.css")).exists();
616         } else {
617             assertThat(apidocs.resolve("stylesheet.css")).exists();
618         }
619 
620         if (JavaVersion.JAVA_VERSION.isBefore("10")) {
621             assertThat(apidocs.resolve("package-list")).exists();
622         } else {
623             assertThat(apidocs.resolve("element-list")).exists();
624         }
625     }
626 
627     /**
628      * Method to test the taglet artifact configuration
629      *
630      * @throws Exception if any
631      */
632     public void testTaglets() throws Exception {
633         // ----------------------------------------------------------------------
634         // taglet-test: check if a taglet is used
635         // ----------------------------------------------------------------------
636 
637         // Should be an assumption, but not supported by TestCase
638         // com.sun.tools.doclets.Taglet not supported by Java9 anymore
639         // Should be refactored with jdk.javadoc.doclet.Taglet
640         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast("10")) {
641             return;
642         }
643 
644         Path testPom = unit.resolve("taglet-test/taglet-test-plugin-config.xml");
645         JavadocReport mojo = lookupMojo(testPom);
646 
647         MavenSession session = spy(newMavenSession(mojo.project));
648         ProjectBuildingRequest buildingRequest = mock(ProjectBuildingRequest.class);
649         when(buildingRequest.getRemoteRepositories()).thenReturn(mojo.project.getRemoteArtifactRepositories());
650         when(session.getProjectBuildingRequest()).thenReturn(buildingRequest);
651         DefaultRepositorySystemSession repositorySession = new DefaultRepositorySystemSession();
652         repositorySession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory()
653                 .newInstance(repositorySession, new LocalRepository(localRepo)));
654         when(buildingRequest.getRepositorySession()).thenReturn(repositorySession);
655         when(session.getRepositorySession()).thenReturn(repositorySession);
656         LegacySupport legacySupport = lookup(LegacySupport.class);
657         legacySupport.setSession(session);
658 
659         setVariableValueToObject(mojo, "session", session);
660         setVariableValueToObject(mojo, "repoSession", repositorySession);
661 
662         mojo.execute();
663 
664         Path apidocs = new File(getBasedir(), "target/test/unit/taglet-test/target/site/apidocs").toPath();
665 
666         assertThat(apidocs.resolve("index.html")).exists();
667 
668         Path appFile = apidocs.resolve("taglet/test/App.html");
669         assertThat(appFile).exists();
670         String appString = readFile(appFile);
671         assertThat(appString).contains("<b>To Do:</b>");
672     }
673 
674     /**
675      * Method to test the jdk5 javadoc
676      *
677      * @throws Exception if any
678      */
679     public void testJdk5() throws Exception {
680         // Should be an assumption, but not supported by TestCase
681         // Java 5 not supported by Java9 anymore
682         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast("9")) {
683             return;
684         }
685 
686         Path testPom = unit.resolve("jdk5-test/jdk5-test-plugin-config.xml");
687         JavadocReport mojo = lookupMojo(testPom);
688         mojo.execute();
689 
690         Path apidocs = new File(getBasedir(), "target/test/unit/jdk5-test/target/site/apidocs").toPath();
691 
692         assertThat(apidocs.resolve("index.html")).exists();
693 
694         Path overviewSummary = apidocs.resolve("overview-summary.html");
695         assertThat(overviewSummary).exists();
696         String content = readFile(overviewSummary);
697         assertThat(content).contains("<b>Test the package-info</b>");
698 
699         Path packageSummary = apidocs.resolve("jdk5/test/package-summary.html");
700         assertThat(packageSummary).exists();
701         content = readFile(packageSummary);
702         assertThat(content).contains("<b>Test the package-info</b>");
703     }
704 
705     /**
706      * Test to find the javadoc executable when <code>java.home</code> is not in the JDK_HOME. In this case, try to
707      * use the <code>JAVA_HOME</code> environment variable.
708      *
709      * @throws Exception if any
710      */
711     public void testToFindJavadoc() throws Exception {
712         String oldJreHome = System.getProperty("java.home");
713         System.setProperty("java.home", "foo/bar");
714 
715         Path testPom = unit.resolve("javaHome-test/javaHome-test-plugin-config.xml");
716         JavadocReport mojo = lookupMojo(testPom);
717         mojo.execute();
718 
719         System.setProperty("java.home", oldJreHome);
720     }
721 
722     /**
723      * Test the javadoc resources.
724      *
725      * @throws Exception if any
726      */
727     public void testJavadocResources() throws Exception {
728         Path testPom = unit.resolve("resources-test/resources-test-plugin-config.xml");
729         JavadocReport mojo = lookupMojo(testPom);
730         mojo.execute();
731 
732         Path apidocs = new File(getBasedir(), "target/test/unit/resources-test/target/site/apidocs/").toPath();
733 
734         Path app = apidocs.resolve("resources/test/App.html");
735         assertThat(app).exists();
736         String content = readFile(app);
737         assertThat(content).contains("<img src=\"doc-files/maven-feather.png\" alt=\"Maven\">");
738         assertThat(apidocs.resolve("resources/test/doc-files/maven-feather.png"))
739                 .exists();
740 
741         Path app2 = apidocs.resolve("resources/test2/App2.html");
742         assertThat(app2).exists();
743         content = readFile(app2);
744         assertThat(content).contains("<img src=\"doc-files/maven-feather.png\" alt=\"Maven\">");
745         assertThat(apidocs.resolve("resources/test2/doc-files/maven-feather.png"))
746                 .doesNotExist();
747 
748         // with excludes
749         testPom = unit.resolve("resources-with-excludes-test/resources-with-excludes-test-plugin-config.xml");
750         mojo = lookupMojo(testPom);
751         mojo.execute();
752 
753         apidocs = new File(getBasedir(), "target/test/unit/resources-with-excludes-test/target/site/apidocs").toPath();
754 
755         app = apidocs.resolve("resources/test/App.html");
756         assertThat(app).exists();
757         content = readFile(app);
758         assertThat(content).contains("<img src=\"doc-files/maven-feather.png\" alt=\"Maven\">");
759 
760         JavaVersion javadocVersion = (JavaVersion) getVariableValueFromObject(mojo, "javadocRuntimeVersion");
761         if (javadocVersion.isAtLeast("1.8") /* && javadocVersion.isBefore( "14" ) */) {
762             // https://bugs.openjdk.java.net/browse/JDK-8032205
763             assertThat(apidocs.resolve("resources/test/doc-files/maven-feather.png"))
764                     .as("Javadoc runtime version: " + javadocVersion
765                             + "\nThis bug appeared in JDK8 and was planned to be fixed in JDK9, see JDK-8032205")
766                     .exists();
767         } else {
768             assertThat(apidocs.resolve("resources/test/doc-files/maven-feather.png"))
769                     .doesNotExist();
770         }
771         assertThat(apidocs.resolve("resources/test2/doc-files/maven-feather.png"))
772                 .exists();
773 
774         app2 = apidocs.resolve("resources/test2/App2.html");
775         assertThat(app2).exists();
776         content = readFile(app2);
777         assertThat(content).contains("<img src=\"doc-files/maven-feather.png\" alt=\"Maven\">");
778         assertThat(apidocs.resolve("resources/test2/doc-files/maven-feather.png"))
779                 .exists();
780     }
781 
782     /**
783      * Test the javadoc for a POM project.
784      *
785      * @throws Exception if any
786      */
787     public void testPom() throws Exception {
788         Path testPom = unit.resolve("pom-test/pom-test-plugin-config.xml");
789         JavadocReport mojo = lookupMojo(testPom);
790         mojo.execute();
791 
792         assertThat(new File(getBasedir(), "target/test/unit/pom-test/target/site"))
793                 .doesNotExist();
794     }
795 
796     /**
797      * Test the javadoc with tag.
798      *
799      * @throws Exception if any
800      */
801     public void testTag() throws Exception {
802         Path testPom = unit.resolve("tag-test/tag-test-plugin-config.xml");
803         JavadocReport mojo = lookupMojo(testPom);
804         mojo.execute();
805 
806         Path app = new File(getBasedir(), "target/test/unit/tag-test/target/site/apidocs/tag/test/App.html").toPath();
807         assertThat(app).exists();
808         String readed = readFile(app);
809         assertThat(readed).contains(">To do something:</").contains(">Generator Class:</");
810 
811         // In javadoc-options-javadoc-resources.xml tag 'version' has only a name,
812         // which is not enough for Java 11 anymore
813         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore("11")) {
814             assertThat(readed).contains(">Version:</");
815             assertTrue(readed.toLowerCase(Locale.ENGLISH).contains("</dt>" + LINE_SEPARATOR + "  <dd>1.0</dd>")
816                     || readed.toLowerCase(Locale.ENGLISH)
817                             .contains("</dt>" + LINE_SEPARATOR + "<dd>1.0</dd>" /* JDK 8 */));
818         }
819     }
820 
821     /**
822      * Test newline in the header/footer parameter
823      *
824      * @throws Exception if any
825      */
826     public void testHeaderFooter() throws Exception {
827         Path testPom = unit.resolve("header-footer-test/header-footer-test-plugin-config.xml");
828         JavadocReport mojo = lookupMojo(testPom);
829         try {
830             mojo.execute();
831         } catch (MojoExecutionException e) {
832             fail("Doesnt handle correctly newline for header or footer parameter");
833         }
834     }
835 
836     /**
837      * Test newline in various string parameters
838      *
839      * @throws Exception if any
840      */
841     public void testNewline() throws Exception {
842         Path testPom = unit.resolve("newline-test/newline-test-plugin-config.xml");
843         JavadocReport mojo = lookupMojo(testPom);
844         try {
845             mojo.execute();
846         } catch (MojoExecutionException e) {
847             fail("Doesn't handle correctly newline for string parameters. See options and packages files.");
848         }
849     }
850 
851     /**
852      * Method to test the jdk6 javadoc
853      *
854      * @throws Exception if any
855      */
856     public void testJdk6() throws Exception {
857         // Should be an assumption, but not supported by TestCase
858         // Java 6 not supported by Java 12 anymore
859         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast("12")) {
860             return;
861         }
862 
863         Path testPom = unit.resolve("jdk6-test/jdk6-test-plugin-config.xml");
864         JavadocReport mojo = lookupMojo(testPom);
865         mojo.execute();
866 
867         Path apidocs = new File(getBasedir(), "target/test/unit/jdk6-test/target/site/apidocs").toPath();
868         assertThat(apidocs.resolve("index.html")).exists();
869 
870         Path overview;
871         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore("11")) {
872             overview = apidocs.resolve("overview-summary.html");
873         } else {
874             overview = apidocs.resolve("index.html");
875         }
876 
877         assertThat(overview).exists();
878         String content = readFile(overview);
879         assertThat(content)
880                 .contains("Top - Copyright &#169; All rights reserved.")
881                 .contains("Header - Copyright &#169; All rights reserved.");
882         // IBM dist of adopt-openj9 does not support the footer param
883         if (!System.getProperty("java.vm.name").contains("OpenJ9")) {
884             assertThat(content).contains("Footer - Copyright &#169; All rights reserved.");
885         }
886 
887         Path packageSummary = apidocs.resolve("jdk6/test/package-summary.html");
888         assertThat(packageSummary).exists();
889         content = readFile(packageSummary);
890         assertThat(content)
891                 .contains("Top - Copyright &#169; All rights reserved.")
892                 .contains("Header - Copyright &#169; All rights reserved.");
893 
894         // IBM dist of adopt-openj9 does not support the footer param
895         if (!System.getProperty("java.vm.name").contains("OpenJ9")) {
896             assertThat(content).contains("Footer - Copyright &#169; All rights reserved.");
897         }
898     }
899 
900     /**
901      * Method to test proxy support in the javadoc
902      *
903      * @throws Exception if any
904      */
905     public void testProxy() throws Exception {
906         Settings settings = new Settings();
907         Proxy proxy = new Proxy();
908 
909         // dummy proxy
910         proxy.setActive(true);
911         proxy.setHost("127.0.0.1");
912         proxy.setPort(80);
913         proxy.setProtocol("http");
914         proxy.setUsername("toto");
915         proxy.setPassword("toto");
916         proxy.setNonProxyHosts("www.google.com|*.somewhere.com");
917         settings.addProxy(proxy);
918 
919         Path testPom =
920                 new File(getBasedir(), "src/test/resources/unit/proxy-test/proxy-test-plugin-config.xml").toPath();
921         JavadocReport mojo = lookupMojo(testPom);
922 
923         MavenSession session = spy(newMavenSession(mojo.project));
924         ProjectBuildingRequest buildingRequest = mock(ProjectBuildingRequest.class);
925         when(buildingRequest.getRemoteRepositories()).thenReturn(mojo.project.getRemoteArtifactRepositories());
926         when(buildingRequest.getRepositoryMerging()).thenReturn(RepositoryMerging.POM_DOMINANT);
927         when(session.getProjectBuildingRequest()).thenReturn(buildingRequest);
928         DefaultRepositorySystemSession repositorySession = new DefaultRepositorySystemSession();
929         repositorySession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory()
930                 .newInstance(repositorySession, new LocalRepository(localRepo)));
931         when(buildingRequest.getRepositorySession()).thenReturn(repositorySession);
932         when(session.getRepositorySession()).thenReturn(repositorySession);
933         LegacySupport legacySupport = lookup(LegacySupport.class);
934         legacySupport.setSession(session);
935 
936         setVariableValueToObject(mojo, "settings", settings);
937         setVariableValueToObject(mojo, "session", session);
938         setVariableValueToObject(mojo, "repoSession", repositorySession);
939         mojo.execute();
940 
941         Path commandLine = new File(
942                         getBasedir(),
943                         "target/test/unit/proxy-test/target/site/apidocs/javadoc."
944                                 + (SystemUtils.IS_OS_WINDOWS ? "bat" : "sh"))
945                 .toPath();
946         assertThat(commandLine).exists();
947         String readed = readFile(commandLine);
948         assertThat(readed).contains("-J-Dhttp.proxyHost=127.0.0.1").contains("-J-Dhttp.proxyPort=80");
949         if (SystemUtils.IS_OS_WINDOWS) {
950             assertThat(readed).contains(" -J-Dhttp.nonProxyHosts=\"www.google.com^|*.somewhere.com\" ");
951         } else {
952             assertThat(readed).contains(" \"-J-Dhttp.nonProxyHosts=\\\"www.google.com^|*.somewhere.com\\\"\" ");
953         }
954 
955         Path options = new File(getBasedir(), "target/test/unit/proxy-test/target/site/apidocs/options").toPath();
956         assertThat(options).exists();
957         String optionsContent = readFile(options);
958         // NO -link expected
959         assertThat(optionsContent).doesNotContain("-link");
960 
961         // real proxy
962         ProxyServer proxyServer = null;
963         AuthAsyncProxyServlet proxyServlet;
964         try {
965             proxyServlet = new AuthAsyncProxyServlet();
966             proxyServer = new ProxyServer(proxyServlet);
967             proxyServer.start();
968 
969             settings = new Settings();
970             proxy = new Proxy();
971             proxy.setActive(true);
972             proxy.setHost(proxyServer.getHostName());
973             proxy.setPort(proxyServer.getPort());
974             proxy.setProtocol("http");
975             settings.addProxy(proxy);
976 
977             mojo = lookupMojo(testPom);
978             setVariableValueToObject(mojo, "settings", settings);
979             setVariableValueToObject(mojo, "session", session);
980             setVariableValueToObject(mojo, "repoSession", repositorySession);
981             mojo.execute();
982             readed = readFile(commandLine);
983             assertTrue(readed.contains("-J-Dhttp.proxyHost=" + proxyServer.getHostName()));
984             assertTrue(readed.contains("-J-Dhttp.proxyPort=" + proxyServer.getPort()));
985 
986             optionsContent = readFile(options);
987             // -link expected
988             // TODO: This got disabled for now!
989             // This test fails since the last commit but I actually think it only ever worked by accident.
990             // It did rely on a commons-logging-1.0.4.pom which got resolved by a test which did run previously.
991             // But after updating to commons-logging.1.1.1 there is no pre-resolved artifact available in
992             // target/local-repo anymore, thus the javadoc link info cannot get built and the test fails
993             // I'll for now just disable this line of code, because the test as far as I can see _never_
994             // did go upstream. The remoteRepository list used is always empty!.
995             //
996             //            assertTrue( optionsContent.contains( "-link 'http://commons.apache.org/logging/apidocs'" ) );
997         } finally {
998             if (proxyServer != null) {
999                 proxyServer.stop();
1000             }
1001         }
1002 
1003         // auth proxy
1004         Map<String, String> authentications = new HashMap<>();
1005         authentications.put("foo", "bar");
1006         try {
1007             proxyServlet = new AuthAsyncProxyServlet(authentications);
1008             proxyServer = new ProxyServer(proxyServlet);
1009             proxyServer.start();
1010 
1011             settings = new Settings();
1012             proxy = new Proxy();
1013             proxy.setActive(true);
1014             proxy.setHost(proxyServer.getHostName());
1015             proxy.setPort(proxyServer.getPort());
1016             proxy.setProtocol("http");
1017             proxy.setUsername("foo");
1018             proxy.setPassword("bar");
1019             settings.addProxy(proxy);
1020 
1021             mojo = lookupMojo(testPom);
1022             setVariableValueToObject(mojo, "settings", settings);
1023             setVariableValueToObject(mojo, "session", session);
1024             setVariableValueToObject(mojo, "repoSession", repositorySession);
1025             mojo.execute();
1026             readed = readFile(commandLine);
1027             assertThat(readed)
1028                     .contains("-J-Dhttp.proxyHost=" + proxyServer.getHostName())
1029                     .contains("-J-Dhttp.proxyPort=" + proxyServer.getPort());
1030 
1031             optionsContent = readFile(options);
1032             // -link expected
1033             // see comment above (line 829)
1034             //             assertTrue( optionsContent.contains( "-link 'http://commons.apache.org/logging/apidocs'" ) );
1035         } finally {
1036             if (proxyServer != null) {
1037                 proxyServer.stop();
1038             }
1039         }
1040     }
1041 
1042     /**
1043      * Method to test error or conflict in Javadoc options and in standard doclet options.
1044      *
1045      * @throws Exception if any
1046      */
1047     public void testValidateOptions() throws Exception {
1048         // encoding
1049         Path testPom = unit.resolve("validate-options-test/wrong-encoding-test-plugin-config.xml");
1050         JavadocReport mojo = lookupMojo(testPom);
1051         try {
1052             mojo.execute();
1053             fail("No wrong encoding catch");
1054         } catch (MojoExecutionException e) {
1055             assertTrue("No wrong encoding catch", e.getMessage().contains("Unsupported option <encoding/>"));
1056         }
1057         testPom = unit.resolve("validate-options-test/wrong-docencoding-test-plugin-config.xml");
1058         mojo = lookupMojo(testPom);
1059         try {
1060             mojo.execute();
1061             fail("No wrong docencoding catch");
1062         } catch (MojoExecutionException e) {
1063             assertTrue("No wrong docencoding catch", e.getMessage().contains("Unsupported option <docencoding/>"));
1064         }
1065         testPom = unit.resolve("validate-options-test/wrong-charset-test-plugin-config.xml");
1066         mojo = lookupMojo(testPom);
1067         try {
1068             mojo.execute();
1069             fail("No wrong charset catch");
1070         } catch (MojoExecutionException e) {
1071             assertTrue("No wrong charset catch", e.getMessage().contains("Unsupported option <charset/>"));
1072         }
1073 
1074         testPom = unit.resolve("validate-options-test/wrong-locale-with-variant-test-plugin-config.xml");
1075         mojo = lookupMojo(testPom);
1076         mojo.execute();
1077         assertTrue("No wrong locale catch", true);
1078 
1079         // conflict options
1080         testPom = unit.resolve("validate-options-test/conflict-options-test-plugin-config.xml");
1081         mojo = lookupMojo(testPom);
1082         try {
1083             mojo.execute();
1084             fail("No conflict catch");
1085         } catch (MojoExecutionException e) {
1086             assertTrue("No conflict catch", e.getMessage().contains("Option <nohelp/> conflicts with <helpfile/>"));
1087         }
1088     }
1089 
1090     /**
1091      * Method to test the <code>&lt;tagletArtifacts/&gt;</code> parameter.
1092      *
1093      * @throws Exception if any
1094      */
1095     public void testTagletArtifacts() throws Exception {
1096         // Should be an assumption, but not supported by TestCase
1097         // com.sun.tools.doclets.Taglet not supported by Java 10 anymore
1098         if (JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast("10")) {
1099             return;
1100         }
1101 
1102         Path testPom = unit.resolve("tagletArtifacts-test/tagletArtifacts-test-plugin-config.xml");
1103         JavadocReport mojo = lookupMojo(testPom);
1104 
1105         MavenSession session = newMavenSession(mojo.project);
1106         DefaultRepositorySystemSession repoSysSession = (DefaultRepositorySystemSession) session.getRepositorySession();
1107         repoSysSession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory()
1108                 .newInstance(session.getRepositorySession(), new LocalRepository(new File("target/local-repo"))));
1109         // Ensure remote repo connection uses SSL
1110         LegacySupport legacySupport = lookup(LegacySupport.class);
1111         legacySupport.setSession(session);
1112         setVariableValueToObject(mojo, "session", session);
1113         setVariableValueToObject(mojo, "repoSession", repoSysSession);
1114         mojo.execute();
1115 
1116         Path optionsFile = new File(mojo.getPluginReportOutputDirectory(), "options").toPath();
1117         assertThat(optionsFile).exists();
1118         String options = readFile(optionsFile);
1119         // count -taglet
1120         assertThat(StringUtils.countMatches(options, LINE_SEPARATOR + "-taglet" + LINE_SEPARATOR))
1121                 .isEqualTo(3);
1122         assertThat(options)
1123                 .contains("org.codehaus.plexus.javadoc.PlexusConfigurationTaglet")
1124                 .contains("org.codehaus.plexus.javadoc.PlexusRequirementTaglet")
1125                 .contains("org.codehaus.plexus.javadoc.PlexusComponentTaglet");
1126     }
1127 
1128     /**
1129      * Method to test the <code>&lt;stylesheetfile/&gt;</code> parameter.
1130      *
1131      * @throws Exception if any
1132      */
1133     public void testStylesheetfile() throws Exception {
1134         Path testPom = unit.resolve("stylesheetfile-test/pom.xml");
1135 
1136         JavadocReport mojo = lookupMojo(testPom);
1137         assertNotNull(mojo);
1138 
1139         MavenSession session = spy(newMavenSession(mojo.project));
1140         ProjectBuildingRequest buildingRequest = mock(ProjectBuildingRequest.class);
1141         when(buildingRequest.getRemoteRepositories()).thenReturn(mojo.project.getRemoteArtifactRepositories());
1142         when(session.getProjectBuildingRequest()).thenReturn(buildingRequest);
1143         DefaultRepositorySystemSession repositorySession = new DefaultRepositorySystemSession();
1144         repositorySession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory()
1145                 .newInstance(repositorySession, new LocalRepository(localRepo)));
1146         when(buildingRequest.getRepositorySession()).thenReturn(repositorySession);
1147         when(session.getRepositorySession()).thenReturn(repositorySession);
1148         LegacySupport legacySupport = lookup(LegacySupport.class);
1149         legacySupport.setSession(session);
1150         setVariableValueToObject(mojo, "session", session);
1151         setVariableValueToObject(mojo, "repoSession", repositorySession);
1152 
1153         Path apidocs = new File(getBasedir(), "target/test/unit/stylesheetfile-test/target/site/apidocs").toPath();
1154 
1155         Path stylesheetfile = apidocs.resolve("stylesheet.css");
1156         if (JavaVersion.JAVA_VERSION.isAtLeast("23")) {
1157             stylesheetfile = apidocs.resolve("resource-files/stylesheet.css");
1158         }
1159         Path options = apidocs.resolve("options");
1160 
1161         // stylesheet == maven OR java
1162         setVariableValueToObject(mojo, "stylesheet", "javamaven");
1163 
1164         try {
1165             mojo.execute();
1166             fail();
1167         } catch (MojoExecutionException | MojoFailureException e) {
1168         }
1169 
1170         // stylesheet == java
1171         setVariableValueToObject(mojo, "stylesheet", "java");
1172         mojo.execute();
1173 
1174         String content = readFile(stylesheetfile);
1175         if (JavaVersion.JAVA_VERSION.isAtLeast("13-ea")) {
1176             assertTrue(content.contains("/*" + LINE_SEPARATOR + " * Javadoc style sheet" + LINE_SEPARATOR + " */"));
1177         } else if (JavaVersion.JAVA_VERSION.isAtLeast("10")) {
1178             assertTrue(content.contains("/* " + LINE_SEPARATOR + " * Javadoc style sheet" + LINE_SEPARATOR + " */"));
1179         } else {
1180             assertTrue(content.contains("/* Javadoc style sheet */"));
1181         }
1182 
1183         String optionsContent = readFile(options);
1184         assertFalse(optionsContent.contains("-stylesheetfile"));
1185 
1186         // stylesheetfile defined as a project resource
1187         setVariableValueToObject(mojo, "stylesheet", null);
1188         setVariableValueToObject(mojo, "stylesheetfile", "com/mycompany/app/javadoc/css/stylesheet.css");
1189         mojo.execute();
1190 
1191         content = readFile(stylesheetfile);
1192         assertTrue(content.contains("/* Custom Javadoc style sheet in project */"));
1193 
1194         optionsContent = readFile(options);
1195         assertTrue(optionsContent.contains("-stylesheetfile"));
1196         Path stylesheetResource =
1197                 unit.resolve("stylesheetfile-test/src/main/resources/com/mycompany/app/javadoc/css/stylesheet.css");
1198         assertTrue(optionsContent.contains(
1199                 "'" + stylesheetResource.toFile().getAbsolutePath().replaceAll("\\\\", "/") + "'"));
1200 
1201         // stylesheetfile defined in a javadoc plugin dependency
1202         setVariableValueToObject(mojo, "stylesheetfile", "com/mycompany/app/javadoc/css2/stylesheet.css");
1203         mojo.execute();
1204 
1205         content = readFile(stylesheetfile);
1206         assertTrue(content.contains("/* Custom Javadoc style sheet in artefact */"));
1207 
1208         optionsContent = readFile(options);
1209         assertTrue(optionsContent.contains("-stylesheetfile"));
1210 
1211         assertThat(optionsContent)
1212                 .contains("'" + stylesheetfile.toFile().getAbsolutePath().replaceAll("\\\\", "/") + "'");
1213 
1214         // stylesheetfile defined as file
1215         Path css = unit.resolve("stylesheetfile-test/src/main/resources/com/mycompany/app/javadoc/css3/stylesheet.css");
1216         setVariableValueToObject(mojo, "stylesheetfile", css.toFile().getAbsolutePath());
1217         mojo.execute();
1218 
1219         content = readFile(stylesheetfile);
1220         assertTrue(content.contains("/* Custom Javadoc style sheet as file */"));
1221 
1222         optionsContent = readFile(options);
1223         assertTrue(optionsContent.contains("-stylesheetfile"));
1224         stylesheetResource =
1225                 unit.resolve("stylesheetfile-test/src/main/resources/com/mycompany/app/javadoc/css3/stylesheet.css");
1226         assertTrue(optionsContent.contains(
1227                 "'" + stylesheetResource.toFile().getAbsolutePath().replaceAll("\\\\", "/") + "'"));
1228     }
1229 
1230     /**
1231      * Method to test the <code>&lt;helpfile/&gt;</code> parameter.
1232      *
1233      * @throws Exception if any
1234      */
1235     public void testHelpfile() throws Exception {
1236         Path testPom = unit.resolve("helpfile-test/pom.xml");
1237 
1238         JavadocReport mojo = lookupMojo(testPom);
1239         assertNotNull(mojo);
1240 
1241         MavenSession session = spy(newMavenSession(mojo.project));
1242         ProjectBuildingRequest buildingRequest = mock(ProjectBuildingRequest.class);
1243         when(buildingRequest.getRemoteRepositories()).thenReturn(mojo.project.getRemoteArtifactRepositories());
1244         when(session.getProjectBuildingRequest()).thenReturn(buildingRequest);
1245         DefaultRepositorySystemSession repositorySession = new DefaultRepositorySystemSession();
1246         repositorySession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory()
1247                 .newInstance(repositorySession, new LocalRepository(localRepo)));
1248         when(buildingRequest.getRepositorySession()).thenReturn(repositorySession);
1249         when(session.getRepositorySession()).thenReturn(repositorySession);
1250         LegacySupport legacySupport = lookup(LegacySupport.class);
1251         legacySupport.setSession(session);
1252         setVariableValueToObject(mojo, "session", session);
1253         setVariableValueToObject(mojo, "repoSession", repositorySession);
1254 
1255         Path apidocs = new File(getBasedir(), "target/test/unit/helpfile-test/target/site/apidocs").toPath();
1256 
1257         Path helpfile = apidocs.resolve("help-doc.html");
1258         Path options = apidocs.resolve("options");
1259 
1260         // helpfile by default
1261         mojo.execute();
1262 
1263         String content = readFile(helpfile);
1264         assertTrue(content.contains("<!-- Generated by javadoc"));
1265 
1266         String optionsContent = readFile(options);
1267         assertFalse(optionsContent.contains("-helpfile"));
1268 
1269         // helpfile defined in a javadoc plugin dependency
1270         setVariableValueToObject(mojo, "helpfile", "com/mycompany/app/javadoc/helpfile/help-doc.html");
1271 
1272         setVariableValueToObject(mojo, "session", session);
1273         setVariableValueToObject(mojo, "repoSession", repositorySession);
1274 
1275         mojo.execute();
1276 
1277         content = readFile(helpfile);
1278         assertTrue(content.contains("<!--  Help file from artefact -->"));
1279 
1280         optionsContent = readFile(options);
1281         assertTrue(optionsContent.contains("-helpfile"));
1282         Path help = apidocs.resolve("help-doc.html");
1283         assertTrue(optionsContent.contains("'" + help.toFile().getAbsolutePath().replaceAll("\\\\", "/") + "'"));
1284 
1285         // helpfile defined as a project resource
1286         setVariableValueToObject(mojo, "helpfile", "com/mycompany/app/javadoc/helpfile2/help-doc.html");
1287         mojo.execute();
1288 
1289         content = readFile(helpfile);
1290         assertTrue(content.contains("<!--  Help file from file -->"));
1291 
1292         optionsContent = readFile(options);
1293         assertTrue(optionsContent.contains("-helpfile"));
1294         help = unit.resolve("helpfile-test/src/main/resources/com/mycompany/app/javadoc/helpfile2/help-doc.html");
1295         assertTrue(optionsContent.contains("'" + help.toFile().getAbsolutePath().replaceAll("\\\\", "/") + "'"));
1296 
1297         // helpfile defined as file
1298         help = unit.resolve("helpfile-test/src/main/resources/com/mycompany/app/javadoc/helpfile2/help-doc.html");
1299         setVariableValueToObject(mojo, "helpfile", help.toFile().getAbsolutePath());
1300         mojo.execute();
1301 
1302         content = readFile(helpfile);
1303         assertTrue(content.contains("<!--  Help file from file -->"));
1304 
1305         optionsContent = readFile(options);
1306         assertTrue(optionsContent.contains("-helpfile"));
1307         assertTrue(optionsContent.contains("'" + help.toFile().getAbsolutePath().replaceAll("\\\\", "/") + "'"));
1308     }
1309 }