1 package org.codehaus.mojo.taglist;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.LineNumberReader;
28 import java.io.Reader;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Locale;
34
35 import org.apache.commons.lang.StringUtils;
36 import org.apache.maven.plugin.logging.Log;
37 import org.apache.maven.reporting.MavenReportException;
38 import org.codehaus.mojo.taglist.beans.FileReport;
39 import org.codehaus.mojo.taglist.beans.TagReport;
40 import org.codehaus.mojo.taglist.tags.TagClass;
41 import org.codehaus.plexus.util.FileUtils;
42 import org.codehaus.plexus.util.IOUtil;
43
44
45
46
47
48
49
50
51
52
53
54 public class FileAnalyser
55 {
56
57
58
59 private static final String STAR_COMMENT = "*";
60
61
62
63
64 private static final String SLASH_COMMENT = "//";
65
66
67
68
69 private static final int MAX_COMMENT_CHARACTERS = 99999;
70
71
72
73
74 private String encoding;
75
76
77
78
79 private Locale locale;
80
81
82
83
84 private Collection sourceDirs;
85
86
87
88
89 private String includes;
90
91
92
93
94 private String excludes;
95
96
97
98
99 private Log log;
100
101
102
103
104 private boolean multipleLineCommentsOn;
105
106
107
108
109 private boolean emptyCommentsOn;
110
111
112
113
114 private String noCommentString;
115
116
117
118
119 private List<TagClass> tagClasses = new ArrayList();
120
121
122
123
124
125
126
127 public FileAnalyser( TagListReport report, List<TagClass> tagClasses )
128 {
129 multipleLineCommentsOn = report.isMultipleLineComments();
130 emptyCommentsOn = report.isEmptyComments();
131 log = report.getLog();
132 sourceDirs = report.getSourceDirs();
133 encoding = report.getInputEncoding();
134 locale = report.getLocale();
135 noCommentString = report.getBundle().getString( "report.taglist.nocomment" );
136 this.tagClasses = tagClasses;
137 this.includes = report.getIncludesCommaSeparated();
138 this.excludes = report.getExcludesCommaSeparated();
139 }
140
141
142
143
144
145
146
147 public Collection execute()
148 throws MavenReportException
149 {
150 List fileList = findFilesToScan();
151
152 for ( Iterator iter = fileList.iterator(); iter.hasNext(); )
153 {
154 File file = (File) iter.next();
155 if ( file.exists() )
156 {
157 scanFile( file );
158 }
159 }
160
161
162 Collection tagReports = new ArrayList();
163 Iterator itr = tagClasses.iterator();
164 while ( itr.hasNext() )
165 {
166 TagClass tc = (TagClass) itr.next();
167 tagReports.add( tc.getTagReport() );
168 }
169
170 return tagReports;
171 }
172
173
174
175
176
177
178 private List findFilesToScan()
179 throws MavenReportException
180 {
181 List filesList = new ArrayList();
182 try
183 {
184 for ( Iterator iter = sourceDirs.iterator(); iter.hasNext(); )
185 {
186 filesList.addAll( FileUtils.getFiles( new File( (String) iter.next() ), includes, excludes ) );
187 }
188 }
189 catch ( IOException e )
190 {
191 throw new MavenReportException( "Error while trying to find the files to scan.", e );
192 }
193 return filesList;
194 }
195
196
197
198
199
200
201
202
203 private Reader getReader( File file ) throws IOException
204 {
205 InputStream in = new FileInputStream( file );
206 return ( encoding == null ) ? new InputStreamReader( in ) : new InputStreamReader( in, encoding );
207 }
208
209
210
211
212
213
214 public void scanFile( File file )
215 {
216 LineNumberReader reader = null;
217
218 try
219 {
220 reader = new LineNumberReader( getReader( file ) );
221
222 String currentLine = reader.readLine();
223 while ( currentLine != null )
224 {
225 int index = -1;
226 Iterator iter = tagClasses.iterator();
227
228 while ( iter.hasNext() )
229 {
230 TagClass tagClass = (TagClass) iter.next();
231 index = tagClass.tagMatchContains( currentLine, locale );
232 if ( index != TagClass.NO_MATCH )
233 {
234
235 String commentType = null;
236 commentType = extractCommentType( currentLine, index );
237
238 if ( commentType == null )
239 {
240
241
242 break;
243 }
244
245 int tagLength = tagClass.getLastTagMatchStringLength();
246 int commentStartIndex = reader.getLineNumber();
247 StringBuffer comment = new StringBuffer();
248
249 String firstLine = StringUtils.strip( currentLine.substring( index + tagLength ) );
250 firstLine = StringUtils.removeEnd( firstLine, "*/" );
251 if ( firstLine.length() == 0 || ":".equals( firstLine ) )
252 {
253
254 if ( emptyCommentsOn )
255 {
256 comment.append( "--" );
257 comment.append( noCommentString );
258 comment.append( "--" );
259 }
260 else
261 {
262 continue;
263 }
264 }
265 else
266 {
267
268 if ( firstLine.charAt( 0 ) == ':' )
269 {
270 comment.append( firstLine.substring( 1 ).trim() );
271 }
272 else
273 {
274 comment.append( firstLine );
275 }
276
277 if ( multipleLineCommentsOn )
278 {
279
280
281 reader.mark( MAX_COMMENT_CHARACTERS );
282
283
284 String futureLine = reader.readLine();
285
286
287 while ( futureLine != null && futureLine.trim().startsWith( commentType )
288 && futureLine.indexOf( tagClass.getLastTagMatchString() ) < 0 )
289 {
290 String currentComment = futureLine.substring( futureLine.indexOf( commentType )
291 + commentType.length() ).trim();
292 if ( currentComment.startsWith( "@" ) || "".equals( currentComment )
293 || "/".equals( currentComment ) )
294 {
295
296 break;
297 }
298
299 boolean newTagFound = false;
300 Iterator moreTCiter = tagClasses.iterator();
301 while ( moreTCiter.hasNext() )
302 {
303 TagClass tc = (TagClass) moreTCiter.next();
304 if ( tc.tagMatchStartsWith( currentComment, locale ) )
305 {
306 newTagFound = true;
307 break;
308 }
309 }
310 if ( newTagFound )
311 {
312
313 break;
314 }
315
316 comment.append( " " );
317 comment.append( currentComment );
318 futureLine = reader.readLine();
319 }
320
321
322
323 reader.reset();
324 }
325 }
326 TagReport tagReport = tagClass.getTagReport();
327 FileReport fileReport = tagReport.getFileReport( file, encoding );
328 fileReport.addComment( comment.toString(), commentStartIndex );
329 }
330 }
331 currentLine = reader.readLine();
332 }
333 }
334 catch ( IOException e )
335 {
336 log.error( "Error while scanning the file " + file.getPath(), e );
337 }
338 finally
339 {
340 IOUtil.close( reader );
341 }
342 }
343
344
345
346
347
348
349
350
351 private String extractCommentType( String currentLine, int index )
352 {
353 String commentType = null;
354 String beforeTag = currentLine.substring( 0, index ).trim();
355 if ( beforeTag.endsWith( SLASH_COMMENT ) )
356 {
357 commentType = SLASH_COMMENT;
358 }
359 else if ( beforeTag.endsWith( STAR_COMMENT ) )
360 {
361 commentType = STAR_COMMENT;
362 }
363 return commentType;
364 }
365
366 }