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;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.net.URI;
26 import java.net.URISyntaxException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.stream.Collectors;
33
34 import org.eclipse.aether.RepositorySystemSession;
35 import org.eclipse.aether.artifact.Artifact;
36 import org.eclipse.aether.internal.impl.checksum.DefaultChecksumAlgorithmFactorySelector;
37 import org.eclipse.aether.metadata.Metadata;
38 import org.eclipse.aether.repository.RemoteRepository;
39 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
40 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
41 import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
42 import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
43 import org.eclipse.aether.transfer.NoRepositoryLayoutException;
44 import org.eclipse.aether.util.ConfigUtils;
45
46 import static java.util.Objects.requireNonNull;
47
48
49
50
51 @Singleton
52 @Named("maven2")
53 public final class Maven2RepositoryLayoutFactory implements RepositoryLayoutFactory {
54
55 public static final String CONFIG_PROP_CHECKSUMS_ALGORITHMS = "aether.checksums.algorithms";
56
57 private static final String DEFAULT_CHECKSUMS_ALGORITHMS = "SHA-1,MD5";
58
59 public static final String CONFIG_PROP_OMIT_CHECKSUMS_FOR_EXTENSIONS =
60 "aether.checksums.omitChecksumsForExtensions";
61
62 private static final String DEFAULT_OMIT_CHECKSUMS_FOR_EXTENSIONS = ".asc,.sigstore";
63
64 private float priority;
65
66 private final ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector;
67
68 public float getPriority() {
69 return priority;
70 }
71
72
73
74
75 @Deprecated
76 public Maven2RepositoryLayoutFactory() {
77 this(new DefaultChecksumAlgorithmFactorySelector());
78 }
79
80 @Inject
81 public Maven2RepositoryLayoutFactory(ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector) {
82 this.checksumAlgorithmFactorySelector = requireNonNull(checksumAlgorithmFactorySelector);
83 }
84
85
86
87
88
89
90
91 public Maven2RepositoryLayoutFactory setPriority(float priority) {
92 this.priority = priority;
93 return this;
94 }
95
96 public RepositoryLayout newInstance(RepositorySystemSession session, RemoteRepository repository)
97 throws NoRepositoryLayoutException {
98 requireNonNull(session, "session cannot be null");
99 requireNonNull(repository, "repository cannot be null");
100 if (!"default".equals(repository.getContentType())) {
101 throw new NoRepositoryLayoutException(repository);
102 }
103
104 List<ChecksumAlgorithmFactory> checksumsAlgorithms = checksumAlgorithmFactorySelector.selectList(
105 ConfigUtils.parseCommaSeparatedUniqueNames(ConfigUtils.getString(
106 session,
107 DEFAULT_CHECKSUMS_ALGORITHMS,
108 CONFIG_PROP_CHECKSUMS_ALGORITHMS + "." + repository.getId(),
109 CONFIG_PROP_CHECKSUMS_ALGORITHMS)));
110
111
112 Set<String> omitChecksumsForExtensions = Arrays.stream(ConfigUtils.getString(
113 session,
114 DEFAULT_OMIT_CHECKSUMS_FOR_EXTENSIONS,
115 CONFIG_PROP_OMIT_CHECKSUMS_FOR_EXTENSIONS)
116 .split(","))
117 .filter(s -> s != null && !s.trim().isEmpty())
118 .collect(Collectors.toSet());
119
120
121 if (omitChecksumsForExtensions.stream().anyMatch(s -> !s.startsWith("."))) {
122 throw new IllegalArgumentException(String.format(
123 "The configuration %s contains illegal values: %s (all entries must start with '.' (dot))",
124 CONFIG_PROP_OMIT_CHECKSUMS_FOR_EXTENSIONS, omitChecksumsForExtensions));
125 }
126
127 return new Maven2RepositoryLayout(
128 checksumAlgorithmFactorySelector, checksumsAlgorithms, omitChecksumsForExtensions);
129 }
130
131 private static class Maven2RepositoryLayout implements RepositoryLayout {
132 private final ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector;
133
134 private final List<ChecksumAlgorithmFactory> configuredChecksumAlgorithms;
135
136 private final Set<String> extensionsWithoutChecksums;
137
138 private Maven2RepositoryLayout(
139 ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector,
140 List<ChecksumAlgorithmFactory> configuredChecksumAlgorithms,
141 Set<String> extensionsWithoutChecksums) {
142 this.checksumAlgorithmFactorySelector = requireNonNull(checksumAlgorithmFactorySelector);
143 this.configuredChecksumAlgorithms = Collections.unmodifiableList(configuredChecksumAlgorithms);
144 this.extensionsWithoutChecksums = requireNonNull(extensionsWithoutChecksums);
145 }
146
147 private URI toUri(String path) {
148 try {
149 return new URI(null, null, path, null);
150 } catch (URISyntaxException e) {
151 throw new IllegalStateException(e);
152 }
153 }
154
155 @Override
156 public List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
157 return configuredChecksumAlgorithms;
158 }
159
160 @Override
161 public boolean hasChecksums(Artifact artifact) {
162 String artifactExtension = artifact.getExtension();
163 for (String extensionWithoutChecksums : extensionsWithoutChecksums) {
164 if (artifactExtension.endsWith(extensionWithoutChecksums)) {
165 return false;
166 }
167 }
168 return true;
169 }
170
171 @Override
172 public URI getLocation(Artifact artifact, boolean upload) {
173 StringBuilder path = new StringBuilder(128);
174
175 path.append(artifact.getGroupId().replace('.', '/')).append('/');
176
177 path.append(artifact.getArtifactId()).append('/');
178
179 path.append(artifact.getBaseVersion()).append('/');
180
181 path.append(artifact.getArtifactId()).append('-').append(artifact.getVersion());
182
183 if (artifact.getClassifier().length() > 0) {
184 path.append('-').append(artifact.getClassifier());
185 }
186
187 if (artifact.getExtension().length() > 0) {
188 path.append('.').append(artifact.getExtension());
189 }
190
191 return toUri(path.toString());
192 }
193
194 @Override
195 public URI getLocation(Metadata metadata, boolean upload) {
196 StringBuilder path = new StringBuilder(128);
197
198 if (metadata.getGroupId().length() > 0) {
199 path.append(metadata.getGroupId().replace('.', '/')).append('/');
200
201 if (metadata.getArtifactId().length() > 0) {
202 path.append(metadata.getArtifactId()).append('/');
203
204 if (metadata.getVersion().length() > 0) {
205 path.append(metadata.getVersion()).append('/');
206 }
207 }
208 }
209
210 path.append(metadata.getType());
211
212 return toUri(path.toString());
213 }
214
215 @Override
216 public List<ChecksumLocation> getChecksumLocations(Artifact artifact, boolean upload, URI location) {
217 if (!hasChecksums(artifact) || isChecksum(artifact.getExtension())) {
218 return Collections.emptyList();
219 }
220 return getChecksumLocations(location);
221 }
222
223 @Override
224 public List<ChecksumLocation> getChecksumLocations(Metadata metadata, boolean upload, URI location) {
225 return getChecksumLocations(location);
226 }
227
228 private List<ChecksumLocation> getChecksumLocations(URI location) {
229 List<ChecksumLocation> checksumLocations = new ArrayList<>(configuredChecksumAlgorithms.size());
230 for (ChecksumAlgorithmFactory checksumAlgorithmFactory : configuredChecksumAlgorithms) {
231 checksumLocations.add(ChecksumLocation.forLocation(location, checksumAlgorithmFactory));
232 }
233 return checksumLocations;
234 }
235
236 private boolean isChecksum(String extension) {
237 return checksumAlgorithmFactorySelector.isChecksumExtension(extension);
238 }
239 }
240 }