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