View Javadoc
1   package org.apache.maven.plugins.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 java.io.File;
23  import java.io.IOException;
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.util.FileUtils;
35  import org.codehaus.plexus.util.StringUtils;
36  import org.codehaus.plexus.util.cli.Commandline;
37  
38  /**
39   * Helper class to compute and write data used to detect a
40   * stale javadoc.
41   */
42  public class StaleHelper
43  {
44  
45      /**
46       * Compute the data used to detect a stale javadoc
47       *
48       * @param cmd the command line
49       * @return the stale data
50       * @throws MavenReportException if an error occurs
51       */
52      public static String getStaleData( Commandline cmd )
53              throws MavenReportException
54      {
55          try
56          {
57              List<String> ignored = new ArrayList<>();
58              List<String> options = new ArrayList<>();
59              Path dir = cmd.getWorkingDirectory().toPath().toAbsolutePath().normalize();
60              String[] args = cmd.getArguments();
61              Collections.addAll( options, args );
62              for ( String arg : args )
63              {
64                  if ( arg.startsWith( "@" ) )
65                  {
66                      String name = arg.substring( 1 );
67                      options.addAll( Files.readAllLines( dir.resolve( name ), StandardCharsets.UTF_8 ) );
68                      ignored.add( name );
69                  }
70              }
71              List<String> state = new ArrayList<>( options );
72              boolean cp = false;
73              boolean sp = false;
74              for ( String arg : options )
75              {
76                  if ( cp )
77                  {
78                      String s = unquote( arg );
79                      for ( String ps : s.split( File.pathSeparator ) )
80                      {
81                          Path p = dir.resolve( ps );
82                          state.add( p + " = " + lastmod( p ) );
83                      }
84                  }
85                  else if ( sp )
86                  {
87                      String s = unquote( arg );
88                      for ( String ps : s.split( File.pathSeparator ) )
89                      {
90                          Path p = dir.resolve( ps );
91                          for ( Path c : walk( p ) )
92                          {
93                              if ( Files.isRegularFile( c ) )
94                              {
95                                  state.add( c + " = " + lastmod( c ) );
96                              }
97                          }
98                          state.add( p + " = " + lastmod( p ) );
99                      }
100                 }
101                 cp = "-classpath".equals( arg );
102                 sp = "-sourcepath".equals( arg );
103             }
104             for ( Path p : walk( dir ) )
105             {
106                 if ( Files.isRegularFile( p ) && !ignored.contains( p.getFileName().toString() ) )
107                 {
108                     state.add( p + " = " + lastmod( p ) );
109                 }
110             }
111             return StringUtils.join( state.iterator(), SystemUtils.LINE_SEPARATOR );
112         }
113         catch ( Exception e )
114         {
115             throw new MavenReportException( "Unable to compute stale date", e );
116         }
117     }
118 
119     /**
120      * Write the data used to detect a stale javadoc
121      *
122      * @param cmd the command line
123      * @param path the stale data path
124      * @throws MavenReportException if an error occurs
125      */
126     public static void writeStaleData( Commandline cmd, Path path )
127             throws MavenReportException
128     {
129         try
130         {
131             String curdata = getStaleData( cmd );
132             Files.createDirectories( path.getParent() );
133             FileUtils.fileWrite( path.toFile(), null /* platform encoding */, curdata );
134         }
135         catch ( IOException e )
136         {
137             throw new MavenReportException( "Error checking stale data", e );
138         }
139     }
140 
141     private static Collection<Path> walk( Path dir )
142     {
143         Collection<Path> paths = new ArrayList<>();
144         try ( DirectoryStream<Path> directoryStream = Files.newDirectoryStream( dir ) )
145         {
146             for ( Path p : directoryStream )
147             {
148                 paths.add( p );
149             }
150             return paths;
151         }
152         catch ( IOException e )
153         {
154             throw new RuntimeException( e );
155         }
156     }
157 
158     private static String unquote( String s )
159     {
160         if ( s.startsWith( "'" ) && s.endsWith( "'" ) )
161         {
162             return s.substring( 1, s.length() - 1 ).replaceAll( "\\\\'", "'" );
163         }
164         else
165         {
166             return s;
167         }
168     }
169 
170     private static long lastmod( Path p )
171     {
172         try
173         {
174             return Files.getLastModifiedTime( p ).toMillis();
175         }
176         catch ( IOException e )
177         {
178             return 0;
179         }
180     }
181 
182 }