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