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.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.ListIterator;
29 import java.util.stream.Collectors;
30
31 import org.eclipse.aether.RepositoryCache;
32 import org.eclipse.aether.RepositorySystemSession;
33 import org.eclipse.aether.impl.RemoteRepositoryManager;
34 import org.eclipse.aether.impl.UpdatePolicyAnalyzer;
35 import org.eclipse.aether.repository.Authentication;
36 import org.eclipse.aether.repository.AuthenticationSelector;
37 import org.eclipse.aether.repository.MirrorSelector;
38 import org.eclipse.aether.repository.Proxy;
39 import org.eclipse.aether.repository.ProxySelector;
40 import org.eclipse.aether.repository.RemoteRepository;
41 import org.eclipse.aether.repository.RepositoryKeyFunction;
42 import org.eclipse.aether.repository.RepositoryPolicy;
43 import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
44 import org.eclipse.aether.spi.remoterepo.RepositoryKeyFunctionFactory;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import static java.util.Objects.requireNonNull;
49
50
51
52 @Singleton
53 @Named
54 public class DefaultRemoteRepositoryManager implements RemoteRepositoryManager {
55
56 private static final class LoggedMirror {
57
58 private final Object[] keys;
59
60 LoggedMirror(RemoteRepository original, RemoteRepository mirror) {
61 keys = new Object[] {mirror.getId(), mirror.getUrl(), original.getId(), original.getUrl()};
62 }
63
64 @Override
65 public boolean equals(Object obj) {
66 if (this == obj) {
67 return true;
68 } else if (!(obj instanceof LoggedMirror)) {
69 return false;
70 }
71 LoggedMirror that = (LoggedMirror) obj;
72 return Arrays.equals(keys, that.keys);
73 }
74
75 @Override
76 public int hashCode() {
77 return Arrays.hashCode(keys);
78 }
79 }
80
81 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRemoteRepositoryManager.class);
82
83 private final UpdatePolicyAnalyzer updatePolicyAnalyzer;
84
85 private final ChecksumPolicyProvider checksumPolicyProvider;
86
87 private final RepositoryKeyFunctionFactory repositoryKeyFunctionFactory;
88
89 @Inject
90 public DefaultRemoteRepositoryManager(
91 UpdatePolicyAnalyzer updatePolicyAnalyzer,
92 ChecksumPolicyProvider checksumPolicyProvider,
93 RepositoryKeyFunctionFactory repositoryKeyFunctionFactory) {
94 this.updatePolicyAnalyzer = requireNonNull(updatePolicyAnalyzer, "update policy analyzer cannot be null");
95 this.checksumPolicyProvider = requireNonNull(checksumPolicyProvider, "checksum policy provider cannot be null");
96 this.repositoryKeyFunctionFactory =
97 requireNonNull(repositoryKeyFunctionFactory, "repository key function factory cannot be null");
98 }
99
100 @Override
101 public List<RemoteRepository> aggregateRepositories(
102 RepositorySystemSession session,
103 List<RemoteRepository> dominantRepositories,
104 List<RemoteRepository> recessiveRepositories,
105 boolean recessiveIsRaw) {
106 requireNonNull(session, "session cannot be null");
107 requireNonNull(dominantRepositories, "dominantRepositories cannot be null");
108 requireNonNull(recessiveRepositories, "recessiveRepositories cannot be null");
109 if (recessiveRepositories.isEmpty()) {
110 return dominantRepositories;
111 }
112
113 RepositoryKeyFunction repositoryKeyFunction = repositoryKeyFunctionFactory.systemRepositoryKeyFunction(session);
114 MirrorSelector mirrorSelector = session.getMirrorSelector();
115 AuthenticationSelector authSelector = session.getAuthenticationSelector();
116 ProxySelector proxySelector = session.getProxySelector();
117
118 List<RemoteRepository> result = new ArrayList<>(dominantRepositories);
119
120 next:
121 for (RemoteRepository recessiveRepository : recessiveRepositories) {
122 RemoteRepository repository = recessiveRepository;
123
124 if (recessiveIsRaw) {
125 RemoteRepository mirrorRepository = mirrorSelector.getMirror(recessiveRepository);
126
127 if (mirrorRepository != null) {
128 logMirror(session, recessiveRepository, mirrorRepository);
129 repository = mirrorRepository;
130 }
131 }
132
133 String key = repositoryKeyFunction.apply(repository, null);
134
135 for (ListIterator<RemoteRepository> it = result.listIterator(); it.hasNext(); ) {
136 RemoteRepository dominantRepository = it.next();
137
138 if (key.equals(repositoryKeyFunction.apply(dominantRepository, null))) {
139 if (!dominantRepository.getMirroredRepositories().isEmpty()
140 && !repository.getMirroredRepositories().isEmpty()) {
141 RemoteRepository mergedRepository =
142 mergeMirrors(session, repositoryKeyFunction, dominantRepository, repository);
143 if (mergedRepository != dominantRepository) {
144 it.set(mergedRepository);
145 }
146 }
147
148 continue next;
149 }
150 }
151
152 if (recessiveIsRaw) {
153 RemoteRepository.Builder builder = null;
154 Authentication auth = authSelector.getAuthentication(repository);
155 if (auth != null) {
156 builder = new RemoteRepository.Builder(repository);
157 builder.setAuthentication(auth);
158 }
159 Proxy proxy = proxySelector.getProxy(repository);
160 if (proxy != null) {
161 if (builder == null) {
162 builder = new RemoteRepository.Builder(repository);
163 }
164 builder.setProxy(proxy);
165 }
166 if (builder != null) {
167 repository = builder.build();
168 }
169 }
170
171 result.add(repository);
172 }
173
174 return result.stream()
175 .map(r -> new RemoteRepository.Builder(r)
176 .setIntent(RemoteRepository.Intent.RESOLUTION)
177 .build())
178 .collect(Collectors.toList());
179 }
180
181 private void logMirror(RepositorySystemSession session, RemoteRepository original, RemoteRepository mirror) {
182 if (!LOGGER.isDebugEnabled()) {
183 return;
184 }
185 RepositoryCache cache = session.getCache();
186 if (cache != null) {
187 Object key = new LoggedMirror(original, mirror);
188 if (cache.get(session, key) != null) {
189 return;
190 }
191 cache.put(session, key, Boolean.TRUE);
192 }
193 LOGGER.debug(
194 "Using mirror {} ({}) for {} ({}).",
195 mirror.getId(),
196 mirror.getUrl(),
197 original.getId(),
198 original.getUrl());
199 }
200
201 private RemoteRepository mergeMirrors(
202 RepositorySystemSession session,
203 RepositoryKeyFunction repositoryKeyFunction,
204 RemoteRepository dominant,
205 RemoteRepository recessive) {
206 RemoteRepository.Builder merged = null;
207 RepositoryPolicy releases = null, snapshots = null;
208
209 next:
210 for (RemoteRepository rec : recessive.getMirroredRepositories()) {
211 String recKey = repositoryKeyFunction.apply(rec, null);
212
213 for (RemoteRepository dom : dominant.getMirroredRepositories()) {
214 if (recKey.equals(repositoryKeyFunction.apply(dom, null))) {
215 continue next;
216 }
217 }
218
219 if (merged == null) {
220 merged = new RemoteRepository.Builder(dominant);
221 releases = dominant.getPolicy(false);
222 snapshots = dominant.getPolicy(true);
223 }
224
225 releases = merge(session, releases, rec.getPolicy(false), false);
226 snapshots = merge(session, snapshots, rec.getPolicy(true), false);
227
228 merged.addMirroredRepository(rec);
229 }
230
231 if (merged == null) {
232 return dominant;
233 }
234 return merged.setReleasePolicy(releases).setSnapshotPolicy(snapshots).build();
235 }
236
237 @Override
238 public RepositoryPolicy getPolicy(
239 RepositorySystemSession session, RemoteRepository repository, boolean releases, boolean snapshots) {
240 requireNonNull(session, "session cannot be null");
241 requireNonNull(repository, "repository cannot be null");
242 RepositoryPolicy policy1 = releases ? repository.getPolicy(false) : null;
243 RepositoryPolicy policy2 = snapshots ? repository.getPolicy(true) : null;
244 return merge(session, policy1, policy2, true);
245 }
246
247 private RepositoryPolicy merge(
248 RepositorySystemSession session, RepositoryPolicy policy1, RepositoryPolicy policy2, boolean globalPolicy) {
249 RepositoryPolicy policy;
250
251 if (policy2 == null) {
252 if (globalPolicy) {
253 policy = merge(
254 policy1,
255 session.getArtifactUpdatePolicy(),
256 session.getMetadataUpdatePolicy(),
257 session.getChecksumPolicy());
258 } else {
259 policy = policy1;
260 }
261 } else if (policy1 == null) {
262 if (globalPolicy) {
263 policy = merge(
264 policy2,
265 session.getArtifactUpdatePolicy(),
266 session.getMetadataUpdatePolicy(),
267 session.getChecksumPolicy());
268 } else {
269 policy = policy2;
270 }
271 } else if (!policy2.isEnabled()) {
272 if (globalPolicy) {
273 policy = merge(
274 policy1,
275 session.getArtifactUpdatePolicy(),
276 session.getMetadataUpdatePolicy(),
277 session.getChecksumPolicy());
278 } else {
279 policy = policy1;
280 }
281 } else if (!policy1.isEnabled()) {
282 if (globalPolicy) {
283 policy = merge(
284 policy2,
285 session.getArtifactUpdatePolicy(),
286 session.getMetadataUpdatePolicy(),
287 session.getChecksumPolicy());
288 } else {
289 policy = policy2;
290 }
291 } else {
292 String checksums = session.getChecksumPolicy();
293
294 if (globalPolicy && checksums != null && !checksums.isEmpty()) {
295
296 } else {
297 checksums = checksumPolicyProvider.getEffectiveChecksumPolicy(
298 session, policy1.getChecksumPolicy(), policy2.getChecksumPolicy());
299 }
300
301 String artifactUpdates = session.getArtifactUpdatePolicy();
302
303 if (globalPolicy && artifactUpdates != null && !artifactUpdates.isEmpty()) {
304
305 } else {
306 artifactUpdates = updatePolicyAnalyzer.getEffectiveUpdatePolicy(
307 session, policy1.getArtifactUpdatePolicy(), policy2.getArtifactUpdatePolicy());
308 }
309 String metadataUpdates = session.getMetadataUpdatePolicy();
310 if (globalPolicy && metadataUpdates != null && !metadataUpdates.isEmpty()) {
311
312 } else {
313 metadataUpdates = updatePolicyAnalyzer.getEffectiveUpdatePolicy(
314 session, policy1.getMetadataUpdatePolicy(), policy2.getMetadataUpdatePolicy());
315 }
316
317 policy = new RepositoryPolicy(true, artifactUpdates, metadataUpdates, checksums);
318 }
319
320 return policy;
321 }
322
323 private RepositoryPolicy merge(
324 RepositoryPolicy policy, String artifactUpdates, String metadataUpdates, String checksums) {
325 if (policy != null) {
326 if (artifactUpdates == null || artifactUpdates.isEmpty()) {
327 artifactUpdates = policy.getArtifactUpdatePolicy();
328 }
329 if (metadataUpdates == null || metadataUpdates.isEmpty()) {
330 metadataUpdates = policy.getMetadataUpdatePolicy();
331 }
332 if (checksums == null || checksums.isEmpty()) {
333 checksums = policy.getChecksumPolicy();
334 }
335 if (!policy.getArtifactUpdatePolicy().equals(artifactUpdates)
336 || !policy.getMetadataUpdatePolicy().equals(metadataUpdates)
337 || !policy.getChecksumPolicy().equals(checksums)) {
338 policy = new RepositoryPolicy(policy.isEnabled(), artifactUpdates, metadataUpdates, checksums);
339 }
340 }
341 return policy;
342 }
343 }