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