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 public final class LineConsumerThread extends CloseableDaemonThread {
33 private final Charset encoding;
34 private final ReadableByteChannel channel;
35 private final EventHandler<String> eventHandler;
36 private final CountdownCloseable countdownCloseable;
37 private volatile boolean disabled;
38
39 public LineConsumerThread(
40 @Nonnull String threadName,
41 @Nonnull ReadableByteChannel channel,
42 @Nonnull EventHandler<String> eventHandler,
43 @Nonnull CountdownCloseable countdownCloseable) {
44 this(threadName, channel, eventHandler, countdownCloseable, Charset.defaultCharset());
45 }
46
47 public LineConsumerThread(
48 @Nonnull String threadName,
49 @Nonnull ReadableByteChannel channel,
50 @Nonnull EventHandler<String> eventHandler,
51 @Nonnull CountdownCloseable countdownCloseable,
52 @Nonnull Charset encoding) {
53 super(threadName);
54 this.channel = channel;
55 this.eventHandler = eventHandler;
56 this.countdownCloseable = countdownCloseable;
57 this.encoding = encoding;
58 }
59
60 @Override
61 public void run() {
62 try (Scanner stream = new Scanner(channel, encoding.name());
63 CountdownCloseable c = countdownCloseable; ) {
64 boolean isError = false;
65 while (stream.hasNextLine()) {
66 try {
67 String line = stream.nextLine();
68 isError |= stream.ioException() != null;
69 if (!isError && !disabled) {
70 eventHandler.handleEvent(line);
71 }
72 } catch (IllegalStateException e) {
73 isError = true;
74 }
75 }
76 } catch (IOException e) {
77 if (e instanceof InterruptedIOException || e.getCause() instanceof InterruptedException) {
78 Thread.currentThread().interrupt();
79 }
80 } catch (IllegalStateException e) {
81
82 }
83 }
84
85 public void disable() {
86 disabled = true;
87 }
88
89 @Override
90 public void close() throws IOException {
91 channel.close();
92 }
93 }