1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.invoker;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 import java.util.LinkedHashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.concurrent.Callable;
44 import java.util.concurrent.ExecutorService;
45 import java.util.concurrent.Executors;
46 import java.util.stream.Collectors;
47
48 import org.apache.maven.plugins.invoker.model.BuildJob;
49
50
51
52
53
54
55 class JobExecutor {
56 interface ThrowableJobConsumer {
57 void accept(BuildJob t) throws Throwable;
58 }
59
60 private final List<BuildJob> jobs;
61 private final int threadsCount;
62
63 JobExecutor(List<BuildJob> jobs, int threadsCount) {
64 this.jobs = jobs;
65 this.threadsCount = threadsCount;
66 }
67
68 public void forEach(ThrowableJobConsumer jobConsumer) {
69
70 Map<Integer, List<BuildJob>> groupedJobs = jobs.stream()
71 .sorted((j1, j2) -> Integer.compare(j2.getOrdinal(), j1.getOrdinal()))
72 .collect(Collectors.groupingBy(BuildJob::getOrdinal, LinkedHashMap::new, Collectors.toList()));
73
74 ExecutorService executorService = Executors.newFixedThreadPool(threadsCount);
75
76 groupedJobs.forEach((key, value) -> {
77
78 List<Callable<Void>> callableJobs = value.stream()
79 .map(buildJob -> (Callable<Void>) () -> {
80 try {
81 jobConsumer.accept(buildJob);
82 } catch (Throwable e) {
83 buildJob.setResult(BuildJob.Result.ERROR);
84 buildJob.setFailureMessage(String.valueOf(e));
85 }
86 return null;
87 })
88 .collect(Collectors.toList());
89
90 try {
91 executorService.invokeAll(callableJobs);
92 } catch (InterruptedException e) {
93 Thread.currentThread().interrupt();
94 throw new RuntimeException(e);
95 }
96 });
97
98
99 executorService.shutdownNow();
100 }
101 }