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