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.impl;
20
21 import javax.xml.stream.XMLStreamException;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.util.List;
28 import java.util.Objects;
29 import java.util.concurrent.atomic.AtomicReference;
30 import java.util.function.Supplier;
31
32 import org.apache.maven.api.services.ModelBuilderException;
33 import org.apache.maven.artifact.DefaultArtifact;
34 import org.apache.maven.internal.transformation.PomArtifactTransformer;
35 import org.apache.maven.internal.transformation.TransformationFailedException;
36 import org.apache.maven.project.MavenProject;
37 import org.eclipse.aether.RepositorySystemSession;
38 import org.eclipse.aether.internal.impl.checksum.Sha1ChecksumAlgorithmFactory;
39 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmHelper;
40
41
42
43
44
45
46 class TransformedArtifact extends DefaultArtifact {
47
48 private static final int SHA1_BUFFER_SIZE = 8192;
49 private final PomArtifactTransformer pomArtifactTransformer;
50 private final MavenProject project;
51 private final Supplier<Path> sourcePathProvider;
52 private final Path target;
53 private final RepositorySystemSession session;
54 private final AtomicReference<String> sourceState;
55
56 @SuppressWarnings("checkstyle:ParameterNumber")
57 TransformedArtifact(
58 PomArtifactTransformer pomArtifactTransformer,
59 MavenProject project,
60 Path target,
61 RepositorySystemSession session,
62 org.apache.maven.artifact.Artifact source,
63 Supplier<Path> sourcePathProvider,
64 String classifier,
65 String extension) {
66 super(
67 source.getGroupId(),
68 source.getArtifactId(),
69 source.getVersionRange(),
70 source.getScope(),
71 extension,
72 classifier,
73 new TransformedArtifactHandler(
74 classifier, extension, source.getArtifactHandler().getPackaging()));
75 this.pomArtifactTransformer = pomArtifactTransformer;
76 this.project = project;
77 this.target = target;
78 this.session = session;
79 this.sourcePathProvider = sourcePathProvider;
80 this.sourceState = new AtomicReference<>(null);
81 }
82
83 @Override
84 public boolean isResolved() {
85 return getFile() != null;
86 }
87
88 @Override
89 public void setFile(File file) {
90 throw new UnsupportedOperationException("transformed artifact file cannot be set");
91 }
92
93 @Override
94 public synchronized File getFile() {
95 try {
96 String state = mayUpdate();
97 if (state == null) {
98 return null;
99 }
100 return target.toFile();
101 } catch (IOException | XMLStreamException | ModelBuilderException e) {
102 throw new TransformationFailedException(e);
103 }
104 }
105
106 private String mayUpdate() throws IOException, XMLStreamException, ModelBuilderException {
107 String result;
108 Path src = sourcePathProvider.get();
109 if (src == null) {
110 Files.deleteIfExists(target);
111 result = null;
112 } else if (!Files.exists(src)) {
113 Files.deleteIfExists(target);
114 result = "";
115 } else {
116 String current = ChecksumAlgorithmHelper.calculate(src, List.of(new Sha1ChecksumAlgorithmFactory()))
117 .get(Sha1ChecksumAlgorithmFactory.NAME);
118 String existing = sourceState.get();
119 if (!Files.exists(target) || !Objects.equals(current, existing)) {
120 pomArtifactTransformer.transform(project, session, src, target);
121 Files.setLastModifiedTime(target, Files.getLastModifiedTime(src));
122 }
123 result = current;
124 }
125 sourceState.set(result);
126 return result;
127 }
128 }