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