1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.transformation;
20
21 import java.io.IOException;
22 import java.io.UncheckedIOException;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.util.Objects;
26 import java.util.concurrent.atomic.AtomicReference;
27 import java.util.function.BiConsumer;
28 import java.util.function.Function;
29 import java.util.function.Supplier;
30
31 import static java.util.Objects.requireNonNull;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 final class OnChangeTransformer implements Supplier<Path> {
47
48 private final Supplier<Path> source;
49
50 private final Path target;
51
52 private final Function<Path, String> stateFunction;
53
54 private final BiConsumer<Path, Path> transformerConsumer;
55
56 private final AtomicReference<String> sourceState;
57
58 OnChangeTransformer(
59 Supplier<Path> source,
60 Path target,
61 Function<Path, String> stateFunction,
62 BiConsumer<Path, Path> transformerConsumer) {
63 this.source = requireNonNull(source);
64 this.target = requireNonNull(target);
65 this.stateFunction = requireNonNull(stateFunction);
66 this.transformerConsumer = requireNonNull(transformerConsumer);
67 this.sourceState = new AtomicReference<>(null);
68 }
69
70 @Override
71 public synchronized Path get() {
72 String state = mayUpdate();
73 if (state == null) {
74 return null;
75 }
76 return target;
77 }
78
79 private String mayUpdate() {
80 String result;
81 try {
82 Path src = source.get();
83 if (src == null) {
84 Files.deleteIfExists(target);
85 result = null;
86 } else if (!Files.exists(src)) {
87 Files.deleteIfExists(target);
88 result = "";
89 } else {
90 String current = stateFunction.apply(src);
91 String existing = sourceState.get();
92 if (!Objects.equals(current, existing)) {
93 transformerConsumer.accept(src, target);
94 Files.setLastModifiedTime(target, Files.getLastModifiedTime(src));
95 }
96 result = current;
97 }
98 } catch (IOException e) {
99 throw new UncheckedIOException(e);
100 }
101 sourceState.set(result);
102 return result;
103 }
104 }