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