1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.extensions.util;
20
21 import javax.annotation.Nonnull;
22
23 import java.io.IOException;
24 import java.io.InterruptedIOException;
25 import java.nio.channels.ReadableByteChannel;
26 import java.nio.charset.Charset;
27 import java.util.Scanner;
28
29 import org.apache.maven.surefire.extensions.CloseableDaemonThread;
30 import org.apache.maven.surefire.extensions.EventHandler;
31
32
33
34
35 public final class LineConsumerThread extends CloseableDaemonThread {
36 private final Charset encoding;
37 private final ReadableByteChannel channel;
38 private final EventHandler<String> eventHandler;
39 private final CountdownCloseable countdownCloseable;
40 private volatile boolean disabled;
41
42 public LineConsumerThread(
43 @Nonnull String threadName,
44 @Nonnull ReadableByteChannel channel,
45 @Nonnull EventHandler<String> eventHandler,
46 @Nonnull CountdownCloseable countdownCloseable) {
47 this(threadName, channel, eventHandler, countdownCloseable, Charset.defaultCharset());
48 }
49
50 public LineConsumerThread(
51 @Nonnull String threadName,
52 @Nonnull ReadableByteChannel channel,
53 @Nonnull EventHandler<String> eventHandler,
54 @Nonnull CountdownCloseable countdownCloseable,
55 @Nonnull Charset encoding) {
56 super(threadName);
57 this.channel = channel;
58 this.eventHandler = eventHandler;
59 this.countdownCloseable = countdownCloseable;
60 this.encoding = encoding;
61 }
62
63 @Override
64 public void run() {
65 try (Scanner stream = new Scanner(channel, encoding.name());
66 CountdownCloseable c = countdownCloseable; ) {
67 boolean isError = false;
68 while (stream.hasNextLine()) {
69 try {
70 String line = stream.nextLine();
71 isError |= stream.ioException() != null;
72 if (!isError && !disabled) {
73 eventHandler.handleEvent(line);
74 }
75 } catch (IllegalStateException e) {
76 isError = true;
77 }
78 }
79 } catch (IOException e) {
80 if (e instanceof InterruptedIOException || e.getCause() instanceof InterruptedException) {
81 Thread.currentThread().interrupt();
82 }
83 } catch (IllegalStateException e) {
84
85 }
86 }
87
88 public void disable() {
89 disabled = true;
90 }
91
92 @Override
93 public void close() throws IOException {
94 channel.close();
95 }
96 }