1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.lifecycle.internal.concurrent;
20
21 import java.util.List;
22 import java.util.concurrent.CopyOnWriteArrayList;
23
24 import org.apache.maven.project.MavenProject;
25 import org.apache.maven.slf4j.MavenSimpleLogger;
26
27
28
29
30 public class ConcurrentLogOutput implements AutoCloseable {
31
32 private static final ThreadLocal<ProjectExecutionContext> CONTEXT = new InheritableThreadLocal<>();
33
34 public ConcurrentLogOutput() {
35 MavenSimpleLogger.setLogSink(this::accept);
36 }
37
38 protected void accept(String message) {
39 ProjectExecutionContext context = CONTEXT.get();
40 if (context != null) {
41 context.accept(message);
42 } else {
43 System.out.println(message);
44 }
45 }
46
47 @Override
48 public void close() {
49 MavenSimpleLogger.setLogSink(null);
50 }
51
52 public AutoCloseable build(MavenProject project) {
53 return new ProjectExecutionContext(project);
54 }
55
56 private static class ProjectExecutionContext implements AutoCloseable {
57 final MavenProject project;
58 final List<String> messages = new CopyOnWriteArrayList<>();
59 boolean closed;
60
61 ProjectExecutionContext(MavenProject project) {
62 this.project = project;
63 CONTEXT.set(this);
64 }
65
66 void accept(String message) {
67 if (!closed) {
68 this.messages.add(message);
69 } else {
70 System.out.println(message);
71 }
72 }
73
74 @Override
75 public void close() {
76 closed = true;
77 CONTEXT.set(null);
78 this.messages.forEach(System.out::println);
79 }
80 }
81 }