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