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.nio.charset.Charset;
24  import java.nio.charset.StandardCharsets;
25  import java.nio.file.DirectoryStream;
26  import java.nio.file.Files;
27  import java.nio.file.Path;
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.List;
32  
33  import org.apache.maven.reporting.MavenReportException;
34  import org.codehaus.plexus.languages.java.version.JavaVersion;
35  import org.codehaus.plexus.util.cli.Commandline;
36  
37  /**
38   * Helper class to compute and write data used to detect a
39   * stale javadoc.
40   */
41  public class StaleHelper {
42  
43      /**
44       * Compute the data used to detect a stale javadoc
45       *
46       * @param cmd the command line
47       * @return the stale data
48       * @throws MavenReportException if an error occurs
49       */
50      public static List<String> getStaleData(Commandline cmd) throws MavenReportException {
51          try {
52              List<String> ignored = new ArrayList<>();
53              List<String> options = new ArrayList<>();
54              Path dir = cmd.getWorkingDirectory().toPath().toAbsolutePath().normalize();
55              String[] args = cmd.getArguments();
56              Collections.addAll(options, args);
57  
58              final Charset cs;
59              if (JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast("9")
60                      && JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore("12")) {
61                  cs = StandardCharsets.UTF_8;
62              } else {
63                  cs = Charset.defaultCharset();
64              }
65  
66              for (String arg : args) {
67                  if (arg.startsWith("@")) {
68                      String name = arg.substring(1);
69                      options.addAll(Files.readAllLines(dir.resolve(name), cs));
70                      ignored.add(name);
71                  }
72              }
73              List<String> state = new ArrayList<>(options);
74              boolean cp = false;
75              boolean sp = false;
76              for (String arg : options) {
77                  if (cp) {
78                      String s = unquote(arg);
79                      for (String ps : s.split(File.pathSeparator)) {
80                          Path p = dir.resolve(ps);
81                          state.add(p + " = " + lastmod(p));
82                      }
83                  } else if (sp) {
84                      String s = unquote(arg);
85                      for (String ps : s.split(File.pathSeparator)) {
86                          Path p = dir.resolve(ps);
87                          for (Path c : walk(p)) {
88                              if (Files.isRegularFile(c)) {
89                                  state.add(c + " = " + lastmod(c));
90                              }
91                          }
92                          state.add(p + " = " + lastmod(p));
93                      }
94                  }
95                  cp = "-classpath".equals(arg);
96                  sp = "-sourcepath".equals(arg);
97              }
98              for (Path p : walk(dir)) {
99                  if (Files.isRegularFile(p) && !ignored.contains(p.getFileName().toString())) {
100                     state.add(p + " = " + lastmod(p));
101                 }
102             }
103             return state;
104         } catch (Exception e) {
105             throw new MavenReportException("Unable to compute stale date", e);
106         }
107     }
108 
109     /**
110      * Write the data used to detect a stale javadoc
111      *
112      * @param cmd the command line
113      * @param path the stale data path
114      * @throws MavenReportException if an error occurs
115      */
116     public static void writeStaleData(Commandline cmd, Path path) throws MavenReportException {
117         try {
118             List<String> curdata = getStaleData(cmd);
119             Files.createDirectories(path.getParent());
120             Files.write(path, curdata, StandardCharsets.UTF_8);
121         } catch (IOException e) {
122             throw new MavenReportException("Error checking stale data", e);
123         }
124     }
125 
126     private static Collection<Path> walk(Path dir) {
127         Collection<Path> paths = new ArrayList<>();
128         try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dir)) {
129             for (Path p : directoryStream) {
130                 paths.add(p);
131             }
132             return paths;
133         } catch (IOException e) {
134             throw new RuntimeException(e);
135         }
136     }
137 
138     private static String unquote(String s) {
139         if (s.startsWith("'") && s.endsWith("'")) {
140             return s.substring(1, s.length() - 1).replaceAll("\\\\'", "'");
141         } else {
142             return s;
143         }
144     }
145 
146     private static long lastmod(Path p) {
147         try {
148             return Files.getLastModifiedTime(p).toMillis();
149         } catch (IOException e) {
150             return 0;
151         }
152     }
153 }