1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl.checksum;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.IOException;
26 import java.io.UncheckedIOException;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32
33 import org.eclipse.aether.RepositorySystemSession;
34 import org.eclipse.aether.artifact.Artifact;
35 import org.eclipse.aether.internal.impl.LocalPathComposer;
36 import org.eclipse.aether.repository.ArtifactRepository;
37 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
38 import org.eclipse.aether.spi.io.ChecksumProcessor;
39 import org.eclipse.aether.util.ConfigUtils;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 import static java.util.Objects.requireNonNull;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 @Singleton
63 @Named(SparseDirectoryTrustedChecksumsSource.NAME)
64 public final class SparseDirectoryTrustedChecksumsSource extends FileTrustedChecksumsSourceSupport {
65 public static final String NAME = "sparseDirectory";
66
67 private static final String CONFIG_PROPS_PREFIX =
68 FileTrustedChecksumsSourceSupport.CONFIG_PROPS_PREFIX + NAME + ".";
69
70
71
72
73
74
75
76
77 public static final String CONFIG_PROP_ENABLED = FileTrustedChecksumsSourceSupport.CONFIG_PROPS_PREFIX + NAME;
78
79
80
81
82
83
84
85
86 public static final String CONFIG_PROP_BASEDIR = CONFIG_PROPS_PREFIX + "basedir";
87
88 public static final String LOCAL_REPO_PREFIX_DIR = ".checksums";
89
90
91
92
93
94
95
96
97 public static final String CONFIG_PROP_ORIGIN_AWARE = CONFIG_PROPS_PREFIX + "originAware";
98
99 private static final Logger LOGGER = LoggerFactory.getLogger(SparseDirectoryTrustedChecksumsSource.class);
100
101 private final ChecksumProcessor checksumProcessor;
102
103 private final LocalPathComposer localPathComposer;
104
105 @Inject
106 public SparseDirectoryTrustedChecksumsSource(
107 ChecksumProcessor checksumProcessor, LocalPathComposer localPathComposer) {
108 this.checksumProcessor = requireNonNull(checksumProcessor);
109 this.localPathComposer = requireNonNull(localPathComposer);
110 }
111
112 @Override
113 protected boolean isEnabled(RepositorySystemSession session) {
114 return ConfigUtils.getBoolean(session, false, CONFIG_PROP_ENABLED);
115 }
116
117 private boolean isOriginAware(RepositorySystemSession session) {
118 return ConfigUtils.getBoolean(session, true, CONFIG_PROP_ORIGIN_AWARE);
119 }
120
121 @Override
122 protected Map<String, String> doGetTrustedArtifactChecksums(
123 RepositorySystemSession session,
124 Artifact artifact,
125 ArtifactRepository artifactRepository,
126 List<ChecksumAlgorithmFactory> checksumAlgorithmFactories) {
127 final boolean originAware = isOriginAware(session);
128 final HashMap<String, String> checksums = new HashMap<>();
129 Path basedir = getBasedir(session, LOCAL_REPO_PREFIX_DIR, CONFIG_PROP_BASEDIR, false);
130 if (Files.isDirectory(basedir)) {
131 for (ChecksumAlgorithmFactory checksumAlgorithmFactory : checksumAlgorithmFactories) {
132 Path checksumPath = basedir.resolve(
133 calculateArtifactPath(originAware, artifact, artifactRepository, checksumAlgorithmFactory));
134
135 if (!Files.isRegularFile(checksumPath)) {
136 LOGGER.debug(
137 "Artifact '{}' trusted checksum '{}' not found on path '{}'",
138 artifact,
139 checksumAlgorithmFactory.getName(),
140 checksumPath);
141 continue;
142 }
143
144 try {
145 String checksum = checksumProcessor.readChecksum(checksumPath);
146 if (checksum != null) {
147 checksums.put(checksumAlgorithmFactory.getName(), checksum);
148 }
149 } catch (IOException e) {
150
151 LOGGER.warn(
152 "Could not read artifact '{}' trusted checksum on path '{}'", artifact, checksumPath, e);
153 throw new UncheckedIOException(e);
154 }
155 }
156 }
157 return checksums;
158 }
159
160 @Override
161 protected Writer doGetTrustedArtifactChecksumsWriter(RepositorySystemSession session) {
162 return new SparseDirectoryWriter(
163 getBasedir(session, LOCAL_REPO_PREFIX_DIR, CONFIG_PROP_BASEDIR, true), isOriginAware(session));
164 }
165
166 private String calculateArtifactPath(
167 boolean originAware,
168 Artifact artifact,
169 ArtifactRepository artifactRepository,
170 ChecksumAlgorithmFactory checksumAlgorithmFactory) {
171 String path = localPathComposer.getPathForArtifact(artifact, false) + "."
172 + checksumAlgorithmFactory.getFileExtension();
173 if (originAware) {
174 path = artifactRepository.getId() + "/" + path;
175 }
176 return path;
177 }
178
179 private class SparseDirectoryWriter implements Writer {
180 private final Path basedir;
181
182 private final boolean originAware;
183
184 private SparseDirectoryWriter(Path basedir, boolean originAware) {
185 this.basedir = basedir;
186 this.originAware = originAware;
187 }
188
189 @Override
190 public void addTrustedArtifactChecksums(
191 Artifact artifact,
192 ArtifactRepository artifactRepository,
193 List<ChecksumAlgorithmFactory> checksumAlgorithmFactories,
194 Map<String, String> trustedArtifactChecksums)
195 throws IOException {
196 for (ChecksumAlgorithmFactory checksumAlgorithmFactory : checksumAlgorithmFactories) {
197 Path checksumPath = basedir.resolve(
198 calculateArtifactPath(originAware, artifact, artifactRepository, checksumAlgorithmFactory));
199 String checksum = requireNonNull(trustedArtifactChecksums.get(checksumAlgorithmFactory.getName()));
200 checksumProcessor.writeChecksum(checksumPath, checksum);
201 }
202 }
203 }
204 }