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 requireNonNull( session, "session cannot be null" );
135 requireNonNull( dominantRepositories, "dominantRepositories cannot be null" );
136 requireNonNull( recessiveRepositories, "recessiveRepositories cannot be null" );
137 if ( recessiveRepositories.isEmpty() )
138 {
139 return dominantRepositories;
140 }
141
142 MirrorSelector mirrorSelector = session.getMirrorSelector();
143 AuthenticationSelector authSelector = session.getAuthenticationSelector();
144 ProxySelector proxySelector = session.getProxySelector();
145
146 List<RemoteRepository> result = new ArrayList<>( dominantRepositories );
147
148 next: for ( RemoteRepository recessiveRepository : recessiveRepositories )
149 {
150 RemoteRepository repository = recessiveRepository;
151
152 if ( recessiveIsRaw )
153 {
154 RemoteRepository mirrorRepository = mirrorSelector.getMirror( recessiveRepository );
155
156 if ( mirrorRepository != null )
157 {
158 logMirror( session, recessiveRepository, mirrorRepository );
159 repository = mirrorRepository;
160 }
161 }
162
163 String key = getKey( repository );
164
165 for ( ListIterator<RemoteRepository> it = result.listIterator(); it.hasNext(); )
166 {
167 RemoteRepository dominantRepository = it.next();
168
169 if ( key.equals( getKey( dominantRepository ) ) )
170 {
171 if ( !dominantRepository.getMirroredRepositories().isEmpty()
172 && !repository.getMirroredRepositories().isEmpty() )
173 {
174 RemoteRepository mergedRepository = mergeMirrors( session, dominantRepository, repository );
175 if ( mergedRepository != dominantRepository )
176 {
177 it.set( mergedRepository );
178 }
179 }
180
181 continue next;
182 }
183 }
184
185 if ( recessiveIsRaw )
186 {
187 RemoteRepository.Builder builder = null;
188 Authentication auth = authSelector.getAuthentication( repository );
189 if ( auth != null )
190 {
191 builder = new RemoteRepository.Builder( repository );
192 builder.setAuthentication( auth );
193 }
194 Proxy proxy = proxySelector.getProxy( repository );
195 if ( proxy != null )
196 {
197 if ( builder == null )
198 {
199 builder = new RemoteRepository.Builder( repository );
200 }
201 builder.setProxy( proxy );
202 }
203 if ( builder != null )
204 {
205 repository = builder.build();
206 }
207 }
208
209 result.add( repository );
210 }
211
212 return result;
213 }
214
215 private void logMirror( RepositorySystemSession session, RemoteRepository original, RemoteRepository mirror )
216 {
217 if ( !LOGGER.isDebugEnabled() )
218 {
219 return;
220 }
221 RepositoryCache cache = session.getCache();
222 if ( cache != null )
223 {
224 Object key = new LoggedMirror( original, mirror );
225 if ( cache.get( session, key ) != null )
226 {
227 return;
228 }
229 cache.put( session, key, Boolean.TRUE );
230 }
231 LOGGER.debug( "Using mirror {} ({}) for {} ({}).",
232 mirror.getId(), mirror.getUrl(), original.getId(), original.getUrl() );
233 }
234
235 private String getKey( RemoteRepository repository )
236 {
237 return repository.getId();
238 }
239
240 private RemoteRepository mergeMirrors( RepositorySystemSession session, RemoteRepository dominant,
241 RemoteRepository recessive )
242 {
243 RemoteRepository.Builder merged = null;
244 RepositoryPolicy releases = null, snapshots = null;
245
246 next: for ( RemoteRepository rec : recessive.getMirroredRepositories() )
247 {
248 String recKey = getKey( rec );
249
250 for ( RemoteRepository dom : dominant.getMirroredRepositories() )
251 {
252 if ( recKey.equals( getKey( dom ) ) )
253 {
254 continue next;
255 }
256 }
257
258 if ( merged == null )
259 {
260 merged = new RemoteRepository.Builder( dominant );
261 releases = dominant.getPolicy( false );
262 snapshots = dominant.getPolicy( true );
263 }
264
265 releases = merge( session, releases, rec.getPolicy( false ), false );
266 snapshots = merge( session, snapshots, rec.getPolicy( true ), false );
267
268 merged.addMirroredRepository( rec );
269 }
270
271 if ( merged == null )
272 {
273 return dominant;
274 }
275 return merged.setReleasePolicy( releases ).setSnapshotPolicy( snapshots ).build();
276 }
277
278 public RepositoryPolicy getPolicy( RepositorySystemSession session, RemoteRepository repository, boolean releases,
279 boolean snapshots )
280 {
281 requireNonNull( session, "session cannot be null" );
282 requireNonNull( repository, "repository cannot be null" );
283 RepositoryPolicy policy1 = releases ? repository.getPolicy( false ) : null;
284 RepositoryPolicy policy2 = snapshots ? repository.getPolicy( true ) : null;
285 return merge( session, policy1, policy2, true );
286 }
287
288 private RepositoryPolicy merge( RepositorySystemSession session, RepositoryPolicy policy1,
289 RepositoryPolicy policy2, boolean globalPolicy )
290 {
291 RepositoryPolicy policy;
292
293 if ( policy2 == null )
294 {
295 if ( globalPolicy )
296 {
297 policy = merge( policy1, session.getUpdatePolicy(), session.getChecksumPolicy() );
298 }
299 else
300 {
301 policy = policy1;
302 }
303 }
304 else if ( policy1 == null )
305 {
306 if ( globalPolicy )
307 {
308 policy = merge( policy2, session.getUpdatePolicy(), session.getChecksumPolicy() );
309 }
310 else
311 {
312 policy = policy2;
313 }
314 }
315 else if ( !policy2.isEnabled() )
316 {
317 if ( globalPolicy )
318 {
319 policy = merge( policy1, session.getUpdatePolicy(), session.getChecksumPolicy() );
320 }
321 else
322 {
323 policy = policy1;
324 }
325 }
326 else if ( !policy1.isEnabled() )
327 {
328 if ( globalPolicy )
329 {
330 policy = merge( policy2, session.getUpdatePolicy(), session.getChecksumPolicy() );
331 }
332 else
333 {
334 policy = policy2;
335 }
336 }
337 else
338 {
339 String checksums = session.getChecksumPolicy();
340
341 if ( globalPolicy && !StringUtils.isEmpty( checksums ) )
342 {
343
344 }
345 else
346 {
347 checksums =
348 checksumPolicyProvider.getEffectiveChecksumPolicy( session, policy1.getChecksumPolicy(),
349 policy2.getChecksumPolicy() );
350 }
351
352 String updates = session.getUpdatePolicy();
353
354 if ( globalPolicy && !StringUtils.isEmpty( updates ) )
355 {
356
357 }
358 else
359 {
360 updates =
361 updatePolicyAnalyzer.getEffectiveUpdatePolicy( session, policy1.getUpdatePolicy(),
362 policy2.getUpdatePolicy() );
363 }
364
365 policy = new RepositoryPolicy( true, updates, checksums );
366 }
367
368 return policy;
369 }
370
371 private RepositoryPolicy merge( RepositoryPolicy policy, String updates, String checksums )
372 {
373 if ( policy != null )
374 {
375 if ( StringUtils.isEmpty( updates ) )
376 {
377 updates = policy.getUpdatePolicy();
378 }
379 if ( StringUtils.isEmpty( checksums ) )
380 {
381 checksums = policy.getChecksumPolicy();
382 }
383 if ( !policy.getUpdatePolicy().equals( updates ) || !policy.getChecksumPolicy().equals( checksums ) )
384 {
385 policy = new RepositoryPolicy( policy.isEnabled(), updates, checksums );
386 }
387 }
388 return policy;
389 }
390
391 }