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