14
14
15
15
package com .google .googlejavaformat .java ;
16
16
17
- import static java .nio .charset .StandardCharsets .UTF_8 ;
18
-
19
17
import com .google .common .base .Strings ;
20
18
import com .google .common .collect .ImmutableList ;
21
19
import com .google .common .collect .Iterables ;
33
31
import com .google .googlejavaformat .Newlines ;
34
32
import com .google .googlejavaformat .Op ;
35
33
import com .google .googlejavaformat .OpsBuilder ;
34
+ import org .openjdk .javax .tools .Diagnostic ;
35
+ import org .openjdk .javax .tools .DiagnosticCollector ;
36
+ import org .openjdk .javax .tools .DiagnosticListener ;
37
+ import org .openjdk .javax .tools .JavaFileObject ;
38
+ import org .openjdk .javax .tools .SimpleJavaFileObject ;
39
+ import org .openjdk .javax .tools .StandardLocation ;
40
+ import org .openjdk .tools .javac .file .JavacFileManager ;
41
+ import org .openjdk .tools .javac .main .Option ;
42
+ import org .openjdk .tools .javac .parser .JavacParser ;
43
+ import org .openjdk .tools .javac .parser .ParserFactory ;
44
+ import org .openjdk .tools .javac .tree .JCTree .JCCompilationUnit ;
45
+ import org .openjdk .tools .javac .util .Context ;
46
+ import org .openjdk .tools .javac .util .Log ;
47
+ import org .openjdk .tools .javac .util .Options ;
36
48
37
49
import java .io .File ;
50
+ import java .io .FileNotFoundException ;
38
51
import java .io .IOError ;
39
52
import java .io .IOException ;
53
+ import java .io .PrintWriter ;
40
54
import java .net .URI ;
41
55
import java .nio .file .Files ;
42
56
import java .nio .file .Path ;
48
62
import java .util .concurrent .CompletableFuture ;
49
63
import java .util .concurrent .ExecutionException ;
50
64
import java .util .concurrent .ExecutorService ;
51
- import java .util .concurrent .Future ;
52
65
import java .util .concurrent .LinkedBlockingQueue ;
53
66
import java .util .concurrent .ThreadPoolExecutor ;
54
67
import java .util .concurrent .TimeUnit ;
55
68
import java .util .concurrent .TimeoutException ;
56
69
import java .util .stream .Collectors ;
57
70
58
- import org .openjdk .javax .tools .Diagnostic ;
59
- import org .openjdk .javax .tools .DiagnosticCollector ;
60
- import org .openjdk .javax .tools .DiagnosticListener ;
61
- import org .openjdk .javax .tools .JavaFileObject ;
62
- import org .openjdk .javax .tools .SimpleJavaFileObject ;
63
- import org .openjdk .javax .tools .StandardLocation ;
64
- import org .openjdk .tools .javac .file .JavacFileManager ;
65
- import org .openjdk .tools .javac .main .Option ;
66
- import org .openjdk .tools .javac .parser .JavacParser ;
67
- import org .openjdk .tools .javac .parser .ParserFactory ;
68
- import org .openjdk .tools .javac .tree .JCTree .JCCompilationUnit ;
69
- import org .openjdk .tools .javac .util .Context ;
70
- import org .openjdk .tools .javac .util .Log ;
71
- import org .openjdk .tools .javac .util .Options ;
71
+ import static java .nio .charset .StandardCharsets .UTF_8 ;
72
72
73
73
/**
74
74
* This is google-java-format, a new Java formatter that follows the Google Java Style Guide quite
104
104
*/
105
105
@ Immutable
106
106
public final class Formatter {
107
- static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor (
107
+ /**
108
+ * This ExecutorService will be used at method {@link Formatter#formatSourceFile(String, boolean, boolean, long, TimeUnit, boolean)}
109
+ * if the method's param {@code useExecutor} is true, then the formatter will submit the task to this Executor.
110
+ * and the default timeout is 1 sec for each file.
111
+ * */
112
+ private static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor (
108
113
Runtime .getRuntime ().availableProcessors (),
109
114
Math .min (Runtime .getRuntime ().availableProcessors () * 2 , 50 ),
110
115
60 ,
@@ -221,32 +226,45 @@ public void formatSource(CharSource input, CharSink output)
221
226
* The ExecuteService {@link Formatter#EXECUTOR_SERVICE} to submit a {@link FormatFileCallable}.
222
227
* You should check the result list's element. if the element is empty, you should do not overwrite
223
228
* it to source file path.
229
+ * if you want to replace the old source by the formatted source, let the param {@code reWrite} as true
224
230
*
231
+ * @param reWrite whether to reWrite the source file.
225
232
* @param file the input
226
233
* @param useExecutor whether multi-thread mode
234
+ * @param timeout the timeout value, for each java file.
235
+ * @param unit the time unit
236
+ * @param timeoutForAll if true, total timeout is {@code timeout}, else timeout is {@code timeout * fileCount}
227
237
* @return the formatted java source
228
238
*/
229
- public List <String > formatSourceFile (String file , boolean useExecutor )
239
+ public List <String > formatSourceFile (String file , boolean useExecutor , boolean reWrite ,
240
+ long timeout , TimeUnit unit , boolean timeoutForAll )
230
241
throws IOException , FormatterException {
231
242
if (Strings .isNullOrEmpty (file )) {
232
243
return Collections .emptyList ();
233
244
}
245
+ // re-set the timeout value.
246
+ if (timeout <= 0 ) {
247
+ timeout = 1 ;
248
+ unit = TimeUnit .SECONDS ;
249
+ timeoutForAll = false ;
250
+ }
234
251
File sourceFile = new File (file );
235
252
if (sourceFile .isFile ()) {
236
253
// this is a file
237
254
if (useExecutor ) {
238
- CompletableFuture <List <String >> formattedFuture = CompletableFuture .supplyAsync (()-> {
255
+ CompletableFuture <List <String >> formattedFuture = CompletableFuture .supplyAsync (() -> {
239
256
Path path = Paths .get (file );
240
257
String formatted ;
241
258
try {
242
259
formatted = formatSource (new String (Files .readAllBytes (path ), UTF_8 ));
260
+ writeFile (file , formatted , reWrite );
243
261
} catch (FormatterException | IOException e ) {
244
262
formatted = "" ;
245
263
}
246
264
return ImmutableList .of (formatted ); // do not update the file source.
247
265
}, EXECUTOR_SERVICE );
248
266
try {
249
- if (formattedFuture .get (1 , TimeUnit . SECONDS ) == null ) {
267
+ if (formattedFuture .get (timeout , unit ) == null ) {
250
268
return Collections .emptyList ();
251
269
} else {
252
270
return formattedFuture .getNow (Collections .emptyList ());
@@ -257,12 +275,13 @@ public List<String> formatSourceFile(String file, boolean useExecutor)
257
275
} else {
258
276
Path path = Paths .get (file );
259
277
String formatted = formatSource (new String (Files .readAllBytes (path ), UTF_8 ));
278
+ writeFile (file , formatted , reWrite );
260
279
return ImmutableList .of (formatted ); // do not update the file source.
261
280
}
262
281
} else if (sourceFile .isDirectory ()) {
263
282
// this is a directory
264
283
List <String > filePathLit = Lists .newArrayList ();
265
- scanDirectory (file , filePathLit );
284
+ scanJavaFileInDirectory (file , filePathLit );
266
285
if (filePathLit .isEmpty ()) {
267
286
return Collections .emptyList ();
268
287
}
@@ -274,6 +293,7 @@ public List<String> formatSourceFile(String file, boolean useExecutor)
274
293
String formatted ;
275
294
try {
276
295
formatted = formatSource (new String (Files .readAllBytes (path ), UTF_8 ));
296
+ writeFile (p , formatted , reWrite );
277
297
} catch (FormatterException | IOException e ) {
278
298
formatted = "" ;
279
299
}
@@ -284,12 +304,14 @@ public List<String> formatSourceFile(String file, boolean useExecutor)
284
304
CompletableFuture <List <String >> formattedResultFuture =
285
305
CompletableFuture
286
306
.allOf (formattedFutureList .toArray (new CompletableFuture [formattedFutureList .size ()]))
287
- .thenApply (formattedFuture -> formattedFutureList
288
- .stream ()
289
- .map (CompletableFuture ::join )
290
- .collect (Collectors .toList ()));
307
+ .thenApply (formattedFuture ->
308
+ formattedFutureList .stream ().map (CompletableFuture ::join ).collect (Collectors .toList ()));
291
309
try {
292
- if (formattedResultFuture .get (formattedFutureList .size (), TimeUnit .SECONDS ) == null ) {
310
+ long timeOutValue = timeout ;
311
+ if (!timeoutForAll ) {
312
+ timeOutValue = formattedFutureList .size () * timeout ;
313
+ }
314
+ if (formattedResultFuture .get (timeOutValue , unit ) == null ) {
293
315
return Collections .emptyList ();
294
316
} else {
295
317
return formattedResultFuture .getNow (Collections .emptyList ());
@@ -303,6 +325,7 @@ public List<String> formatSourceFile(String file, boolean useExecutor)
303
325
Path path = Paths .get (p );
304
326
String formatted = formatSource (new String (Files .readAllBytes (path ), UTF_8 ));
305
327
formattedList .add (formatted );
328
+ writeFile (p , formatted , reWrite );
306
329
}
307
330
return formattedList ;
308
331
}
@@ -312,13 +335,32 @@ public List<String> formatSourceFile(String file, boolean useExecutor)
312
335
}
313
336
}
314
337
338
+ /**
339
+ * Re-write file with the new content.
340
+ *
341
+ * @param filePath the file path
342
+ * @param content the new content
343
+ * @param reWrite whether to re-write
344
+ * @throws FileNotFoundException Not Find
345
+ */
346
+ private void writeFile (String filePath , String content , boolean reWrite )
347
+ throws FileNotFoundException {
348
+ if (!Strings .isNullOrEmpty (content ) && reWrite ) {
349
+ // re-write the formatted source.
350
+ PrintWriter printWriter = new PrintWriter (new File (filePath ));
351
+ printWriter .print (content );
352
+ printWriter .flush ();
353
+ printWriter .close ();
354
+ }
355
+ }
356
+
315
357
/**
316
358
* Scan the directory {@code directory} to find all of the java files.
317
359
*
318
360
* @param directory the scan directory
319
361
* @param filePathList the result.
320
362
*/
321
- private void scanDirectory (String directory , List <String > filePathList ) {
363
+ private void scanJavaFileInDirectory (String directory , List <String > filePathList ) {
322
364
if (Strings .isNullOrEmpty (directory )) {
323
365
return ;
324
366
}
@@ -334,10 +376,10 @@ private void scanDirectory(String directory, List<String> filePathList) {
334
376
return ; // no file
335
377
}
336
378
for (File file : fileList ) {
337
- if (file .isFile ()) {
379
+ if (file .isFile () && file . getAbsolutePath (). endsWith ( ".java" ) ) {
338
380
filePathList .add (file .getAbsolutePath ());
339
381
} else if (file .isDirectory ()) {
340
- scanDirectory ( directory , filePathList );
382
+ scanJavaFileInDirectory ( file . getAbsolutePath () , filePathList );
341
383
}
342
384
}
343
385
}
0 commit comments