-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathInstrumentation.java
110 lines (92 loc) · 3.35 KB
/
Instrumentation.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package me.earth.headlessmc.launcher.instrumentation;
import lombok.Cleanup;
import lombok.CustomLog;
import lombok.RequiredArgsConstructor;
import lombok.val;
import me.earth.headlessmc.launcher.util.IOUtil;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.stream.Collectors;
@CustomLog
@RequiredArgsConstructor
public class Instrumentation {
private final List<Transformer> transformers;
private final File base;
public List<String> instrument(List<Target> targetsIn) throws IOException {
List<Target> targets = targetsIn;
if (transformers.isEmpty()) {
return targets.stream()
.map(Target::getPath)
.collect(Collectors.toList());
}
for (val transformer : transformers) {
targets = transformer.transform(targets);
}
val result = new ArrayList<String>(targets.size());
for (val target : targets) {
val targetTransformers = transformers
.stream()
.filter(transformer -> transformer.matches(target))
.collect(Collectors.toList());
val url = runTransformers(target, targets, targetTransformers);
result.add(url);
}
val inactive = getInactiveTransformers(transformers);
if (!inactive.isEmpty()) {
log.info("Transformers did not run: " + inactive);
}
return result;
}
// TODO: this is too long and kinda ugly
private String runTransformers(Target target,
List<Target> targets,
List<Transformer> transformers)
throws IOException {
if (transformers.isEmpty()) {
return target.getPath();
}
@Cleanup
val jar = target.toJar();
// TODO: cache????
val file = base.getAbsolutePath()
+ File.separator
+ new File(jar.getName()).getName();
File targetJar = new File(file);
if (targetJar.exists()) {
log.warning(targetJar + " already exists!");
return file;
}
@Cleanup
val jos = IOUtil.jarOutput(targetJar);
for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ) {
val next = e.nextElement();
@Cleanup
val is = jar.getInputStream(next);
EntryStream stream = new EntryStream(is, targets, next);
for (Transformer transformer : transformers) {
val stream2 = transformer.transform(stream);
if (stream2 != stream) {
stream.close();
}
stream = stream2;
}
if (!stream.isSkipped()) {
jos.putNextEntry(new JarEntry(next.getName()));
IOUtil.copy(stream, jos);
jos.flush();
jos.closeEntry();
}
}
return file;
}
private String getInactiveTransformers(List<Transformer> transformers) {
return transformers.stream()
.filter(t -> !t.hasRun())
.map(t -> t.getClass().getName())
.collect(Collectors.joining(","));
}
}