001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.supplier;
020
021import java.util.HashMap;
022import java.util.LinkedHashMap;
023import java.util.Map;
024import java.util.concurrent.atomic.AtomicBoolean;
025import java.util.function.Supplier;
026
027import org.apache.maven.model.building.DefaultModelBuilderFactory;
028import org.apache.maven.model.building.ModelBuilder;
029import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader;
030import org.apache.maven.repository.internal.DefaultModelCacheFactory;
031import org.apache.maven.repository.internal.DefaultVersionRangeResolver;
032import org.apache.maven.repository.internal.DefaultVersionResolver;
033import org.apache.maven.repository.internal.MavenArtifactRelocationSource;
034import org.apache.maven.repository.internal.ModelCacheFactory;
035import org.apache.maven.repository.internal.PluginsMetadataGeneratorFactory;
036import org.apache.maven.repository.internal.SnapshotMetadataGeneratorFactory;
037import org.apache.maven.repository.internal.VersionsMetadataGeneratorFactory;
038import org.apache.maven.repository.internal.relocation.DistributionManagementArtifactRelocationSource;
039import org.apache.maven.repository.internal.relocation.UserPropertiesArtifactRelocationSource;
040import org.eclipse.aether.RepositoryListener;
041import org.eclipse.aether.RepositorySystem;
042import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
043import org.eclipse.aether.impl.ArtifactDescriptorReader;
044import org.eclipse.aether.impl.ArtifactResolver;
045import org.eclipse.aether.impl.DependencyCollector;
046import org.eclipse.aether.impl.Deployer;
047import org.eclipse.aether.impl.Installer;
048import org.eclipse.aether.impl.LocalRepositoryProvider;
049import org.eclipse.aether.impl.MetadataGeneratorFactory;
050import org.eclipse.aether.impl.MetadataResolver;
051import org.eclipse.aether.impl.OfflineController;
052import org.eclipse.aether.impl.RemoteRepositoryFilterManager;
053import org.eclipse.aether.impl.RemoteRepositoryManager;
054import org.eclipse.aether.impl.RepositoryConnectorProvider;
055import org.eclipse.aether.impl.RepositoryEventDispatcher;
056import org.eclipse.aether.impl.RepositorySystemLifecycle;
057import org.eclipse.aether.impl.UpdateCheckManager;
058import org.eclipse.aether.impl.UpdatePolicyAnalyzer;
059import org.eclipse.aether.impl.VersionRangeResolver;
060import org.eclipse.aether.impl.VersionResolver;
061import org.eclipse.aether.internal.impl.DefaultArtifactPredicateFactory;
062import org.eclipse.aether.internal.impl.DefaultArtifactResolver;
063import org.eclipse.aether.internal.impl.DefaultChecksumPolicyProvider;
064import org.eclipse.aether.internal.impl.DefaultChecksumProcessor;
065import org.eclipse.aether.internal.impl.DefaultDeployer;
066import org.eclipse.aether.internal.impl.DefaultInstaller;
067import org.eclipse.aether.internal.impl.DefaultLocalPathComposer;
068import org.eclipse.aether.internal.impl.DefaultLocalPathPrefixComposerFactory;
069import org.eclipse.aether.internal.impl.DefaultLocalRepositoryProvider;
070import org.eclipse.aether.internal.impl.DefaultMetadataResolver;
071import org.eclipse.aether.internal.impl.DefaultOfflineController;
072import org.eclipse.aether.internal.impl.DefaultPathProcessor;
073import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager;
074import org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider;
075import org.eclipse.aether.internal.impl.DefaultRepositoryEventDispatcher;
076import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider;
077import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
078import org.eclipse.aether.internal.impl.DefaultRepositorySystemLifecycle;
079import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
080import org.eclipse.aether.internal.impl.DefaultTransporterProvider;
081import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager;
082import org.eclipse.aether.internal.impl.DefaultUpdatePolicyAnalyzer;
083import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory;
084import org.eclipse.aether.internal.impl.LocalPathComposer;
085import org.eclipse.aether.internal.impl.LocalPathPrefixComposerFactory;
086import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
087import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
088import org.eclipse.aether.internal.impl.TrackingFileManager;
089import org.eclipse.aether.internal.impl.checksum.DefaultChecksumAlgorithmFactorySelector;
090import org.eclipse.aether.internal.impl.checksum.Md5ChecksumAlgorithmFactory;
091import org.eclipse.aether.internal.impl.checksum.Sha1ChecksumAlgorithmFactory;
092import org.eclipse.aether.internal.impl.checksum.Sha256ChecksumAlgorithmFactory;
093import org.eclipse.aether.internal.impl.checksum.Sha512ChecksumAlgorithmFactory;
094import org.eclipse.aether.internal.impl.checksum.SparseDirectoryTrustedChecksumsSource;
095import org.eclipse.aether.internal.impl.checksum.SummaryFileTrustedChecksumsSource;
096import org.eclipse.aether.internal.impl.checksum.TrustedToProvidedChecksumsSourceAdapter;
097import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector;
098import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate;
099import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector;
100import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector;
101import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager;
102import org.eclipse.aether.internal.impl.filter.GroupIdRemoteRepositoryFilterSource;
103import org.eclipse.aether.internal.impl.filter.PrefixesRemoteRepositoryFilterSource;
104import org.eclipse.aether.internal.impl.resolution.TrustedChecksumsArtifactResolverPostProcessor;
105import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
106import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
107import org.eclipse.aether.internal.impl.synccontext.named.NameMappers;
108import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory;
109import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
110import org.eclipse.aether.internal.impl.transport.http.DefaultChecksumExtractor;
111import org.eclipse.aether.internal.impl.transport.http.Nx2ChecksumExtractor;
112import org.eclipse.aether.internal.impl.transport.http.XChecksumExtractor;
113import org.eclipse.aether.named.NamedLockFactory;
114import org.eclipse.aether.named.providers.FileLockNamedLockFactory;
115import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory;
116import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory;
117import org.eclipse.aether.named.providers.NoopNamedLockFactory;
118import org.eclipse.aether.spi.artifact.ArtifactPredicateFactory;
119import org.eclipse.aether.spi.artifact.decorator.ArtifactDecoratorFactory;
120import org.eclipse.aether.spi.artifact.generator.ArtifactGeneratorFactory;
121import org.eclipse.aether.spi.checksums.ProvidedChecksumsSource;
122import org.eclipse.aether.spi.checksums.TrustedChecksumsSource;
123import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
124import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
125import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
126import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
127import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
128import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
129import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
130import org.eclipse.aether.spi.connector.transport.TransporterFactory;
131import org.eclipse.aether.spi.connector.transport.TransporterProvider;
132import org.eclipse.aether.spi.connector.transport.http.ChecksumExtractor;
133import org.eclipse.aether.spi.connector.transport.http.ChecksumExtractorStrategy;
134import org.eclipse.aether.spi.io.ChecksumProcessor;
135import org.eclipse.aether.spi.io.PathProcessor;
136import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
137import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor;
138import org.eclipse.aether.spi.synccontext.SyncContextFactory;
139import org.eclipse.aether.transport.apache.ApacheTransporterFactory;
140import org.eclipse.aether.transport.file.FileTransporterFactory;
141import org.eclipse.aether.util.version.GenericVersionScheme;
142import org.eclipse.aether.version.VersionScheme;
143
144/**
145 * A simple memorizing {@link Supplier} of {@link RepositorySystem} instance, that on first call
146 * supplies lazily constructed instance, and on each subsequent call same instance. Hence, this instance should be
147 * thrown away immediately once repository system was created and there is no need for more instances. If new
148 * repository system instance needed, new instance of this class must be created. For proper shut down of returned
149 * repository system instance(s) use {@link RepositorySystem#shutdown()} method on supplied instance(s).
150 * <p>
151 * Since Resolver 2.0 this class offers access to various components via public getters, and allows even partial object
152 * graph construction.
153 * <p>
154 * Extend this class {@code createXXX()} methods and override to customize, if needed. The contract of this class makes
155 * sure that these (potentially overridden) methods are invoked only once, and instance created by those methods are
156 * memorized and kept as long as supplier instance is kept open.
157 * <p>
158 * This class is not thread safe and must be used from one thread only, while the constructed {@link RepositorySystem}
159 * is thread safe.
160 * <p>
161 * Important: Given the instance of supplier memorizes the supplier {@link RepositorySystem} instance it supplies,
162 * their lifecycle is shared as well: once supplied repository system is shut-down, this instance becomes closed as
163 * well. Any subsequent {@code getXXX} method invocation attempt will fail with {@link IllegalStateException}.
164 *
165 * @since 2.0.0
166 */
167public class RepositorySystemSupplier implements Supplier<RepositorySystem> {
168    private final AtomicBoolean closed = new AtomicBoolean(false);
169
170    public RepositorySystemSupplier() {}
171
172    private void checkClosed() {
173        if (closed.get()) {
174            throw new IllegalStateException("Supplier is closed");
175        }
176    }
177
178    private PathProcessor pathProcessor;
179
180    public final PathProcessor getPathProcessor() {
181        checkClosed();
182        if (pathProcessor == null) {
183            pathProcessor = createPathProcessor();
184        }
185        return pathProcessor;
186    }
187
188    protected PathProcessor createPathProcessor() {
189        return new DefaultPathProcessor();
190    }
191
192    private ChecksumProcessor checksumProcessor;
193
194    public final ChecksumProcessor getChecksumProcessor() {
195        checkClosed();
196        if (checksumProcessor == null) {
197            checksumProcessor = createChecksumProcessor();
198        }
199        return checksumProcessor;
200    }
201
202    protected ChecksumProcessor createChecksumProcessor() {
203        return new DefaultChecksumProcessor(getPathProcessor());
204    }
205
206    private TrackingFileManager trackingFileManager;
207
208    public final TrackingFileManager getTrackingFileManager() {
209        checkClosed();
210        if (trackingFileManager == null) {
211            trackingFileManager = createTrackingFileManager();
212        }
213        return trackingFileManager;
214    }
215
216    protected TrackingFileManager createTrackingFileManager() {
217        return new DefaultTrackingFileManager();
218    }
219
220    private LocalPathComposer localPathComposer;
221
222    public final LocalPathComposer getLocalPathComposer() {
223        checkClosed();
224        if (localPathComposer == null) {
225            localPathComposer = createLocalPathComposer();
226        }
227        return localPathComposer;
228    }
229
230    protected LocalPathComposer createLocalPathComposer() {
231        return new DefaultLocalPathComposer();
232    }
233
234    private LocalPathPrefixComposerFactory localPathPrefixComposerFactory;
235
236    public final LocalPathPrefixComposerFactory getLocalPathPrefixComposerFactory() {
237        checkClosed();
238        if (localPathPrefixComposerFactory == null) {
239            localPathPrefixComposerFactory = createLocalPathPrefixComposerFactory();
240        }
241        return localPathPrefixComposerFactory;
242    }
243
244    protected LocalPathPrefixComposerFactory createLocalPathPrefixComposerFactory() {
245        return new DefaultLocalPathPrefixComposerFactory();
246    }
247
248    private RepositorySystemLifecycle repositorySystemLifecycle;
249
250    public final RepositorySystemLifecycle getRepositorySystemLifecycle() {
251        checkClosed();
252        if (repositorySystemLifecycle == null) {
253            repositorySystemLifecycle = createRepositorySystemLifecycle();
254            repositorySystemLifecycle.addOnSystemEndedHandler(() -> closed.set(true));
255        }
256        return repositorySystemLifecycle;
257    }
258
259    protected RepositorySystemLifecycle createRepositorySystemLifecycle() {
260        return new DefaultRepositorySystemLifecycle();
261    }
262
263    private OfflineController offlineController;
264
265    public final OfflineController getOfflineController() {
266        checkClosed();
267        if (offlineController == null) {
268            offlineController = createOfflineController();
269        }
270        return offlineController;
271    }
272
273    protected OfflineController createOfflineController() {
274        return new DefaultOfflineController();
275    }
276
277    private UpdatePolicyAnalyzer updatePolicyAnalyzer;
278
279    public final UpdatePolicyAnalyzer getUpdatePolicyAnalyzer() {
280        checkClosed();
281        if (updatePolicyAnalyzer == null) {
282            updatePolicyAnalyzer = createUpdatePolicyAnalyzer();
283        }
284        return updatePolicyAnalyzer;
285    }
286
287    protected UpdatePolicyAnalyzer createUpdatePolicyAnalyzer() {
288        return new DefaultUpdatePolicyAnalyzer();
289    }
290
291    private ChecksumPolicyProvider checksumPolicyProvider;
292
293    public final ChecksumPolicyProvider getChecksumPolicyProvider() {
294        checkClosed();
295        if (checksumPolicyProvider == null) {
296            checksumPolicyProvider = createChecksumPolicyProvider();
297        }
298        return checksumPolicyProvider;
299    }
300
301    protected ChecksumPolicyProvider createChecksumPolicyProvider() {
302        return new DefaultChecksumPolicyProvider();
303    }
304
305    private UpdateCheckManager updateCheckManager;
306
307    public final UpdateCheckManager getUpdateCheckManager() {
308        checkClosed();
309        if (updateCheckManager == null) {
310            updateCheckManager = createUpdateCheckManager();
311        }
312        return updateCheckManager;
313    }
314
315    protected UpdateCheckManager createUpdateCheckManager() {
316        return new DefaultUpdateCheckManager(getTrackingFileManager(), getUpdatePolicyAnalyzer(), getPathProcessor());
317    }
318
319    private Map<String, NamedLockFactory> namedLockFactories;
320
321    public final Map<String, NamedLockFactory> getNamedLockFactories() {
322        checkClosed();
323        if (namedLockFactories == null) {
324            namedLockFactories = createNamedLockFactories();
325        }
326        return namedLockFactories;
327    }
328
329    protected Map<String, NamedLockFactory> createNamedLockFactories() {
330        HashMap<String, NamedLockFactory> result = new HashMap<>();
331        result.put(NoopNamedLockFactory.NAME, new NoopNamedLockFactory());
332        result.put(LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory());
333        result.put(LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory());
334        result.put(FileLockNamedLockFactory.NAME, new FileLockNamedLockFactory());
335        return result;
336    }
337
338    private Map<String, NameMapper> nameMappers;
339
340    public final Map<String, NameMapper> getNameMappers() {
341        checkClosed();
342        if (nameMappers == null) {
343            nameMappers = createNameMappers();
344        }
345        return nameMappers;
346    }
347
348    protected Map<String, NameMapper> createNameMappers() {
349        HashMap<String, NameMapper> result = new HashMap<>();
350        result.put(NameMappers.STATIC_NAME, NameMappers.staticNameMapper());
351        result.put(NameMappers.GAV_NAME, NameMappers.gavNameMapper());
352        result.put(NameMappers.DISCRIMINATING_NAME, NameMappers.discriminatingNameMapper());
353        result.put(NameMappers.FILE_GAV_NAME, NameMappers.fileGavNameMapper());
354        result.put(NameMappers.FILE_HGAV_NAME, NameMappers.fileHashingGavNameMapper());
355        return result;
356    }
357
358    private NamedLockFactoryAdapterFactory namedLockFactoryAdapterFactory;
359
360    public final NamedLockFactoryAdapterFactory getNamedLockFactoryAdapterFactory() {
361        checkClosed();
362        if (namedLockFactoryAdapterFactory == null) {
363            namedLockFactoryAdapterFactory = createNamedLockFactoryAdapterFactory();
364        }
365        return namedLockFactoryAdapterFactory;
366    }
367
368    protected NamedLockFactoryAdapterFactory createNamedLockFactoryAdapterFactory() {
369        return new NamedLockFactoryAdapterFactoryImpl(
370                getNamedLockFactories(), getNameMappers(), getRepositorySystemLifecycle());
371    }
372
373    private SyncContextFactory syncContextFactory;
374
375    public final SyncContextFactory getSyncContextFactory() {
376        checkClosed();
377        if (syncContextFactory == null) {
378            syncContextFactory = createSyncContextFactory();
379        }
380        return syncContextFactory;
381    }
382
383    protected SyncContextFactory createSyncContextFactory() {
384        return new DefaultSyncContextFactory(getNamedLockFactoryAdapterFactory());
385    }
386
387    private Map<String, ChecksumAlgorithmFactory> checksumAlgorithmFactories;
388
389    public final Map<String, ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
390        checkClosed();
391        if (checksumAlgorithmFactories == null) {
392            checksumAlgorithmFactories = createChecksumAlgorithmFactories();
393        }
394        return checksumAlgorithmFactories;
395    }
396
397    protected Map<String, ChecksumAlgorithmFactory> createChecksumAlgorithmFactories() {
398        HashMap<String, ChecksumAlgorithmFactory> result = new HashMap<>();
399        result.put(Sha512ChecksumAlgorithmFactory.NAME, new Sha512ChecksumAlgorithmFactory());
400        result.put(Sha256ChecksumAlgorithmFactory.NAME, new Sha256ChecksumAlgorithmFactory());
401        result.put(Sha1ChecksumAlgorithmFactory.NAME, new Sha1ChecksumAlgorithmFactory());
402        result.put(Md5ChecksumAlgorithmFactory.NAME, new Md5ChecksumAlgorithmFactory());
403        return result;
404    }
405
406    private ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector;
407
408    public final ChecksumAlgorithmFactorySelector getChecksumAlgorithmFactorySelector() {
409        checkClosed();
410        if (checksumAlgorithmFactorySelector == null) {
411            checksumAlgorithmFactorySelector = createChecksumAlgorithmFactorySelector();
412        }
413        return checksumAlgorithmFactorySelector;
414    }
415
416    protected ChecksumAlgorithmFactorySelector createChecksumAlgorithmFactorySelector() {
417        return new DefaultChecksumAlgorithmFactorySelector(getChecksumAlgorithmFactories());
418    }
419
420    private ArtifactPredicateFactory artifactPredicateFactory;
421
422    public final ArtifactPredicateFactory getArtifactPredicateFactory() {
423        checkClosed();
424        if (artifactPredicateFactory == null) {
425            artifactPredicateFactory = createArtifactPredicateFactory();
426        }
427        return artifactPredicateFactory;
428    }
429
430    protected ArtifactPredicateFactory createArtifactPredicateFactory() {
431        return new DefaultArtifactPredicateFactory(getChecksumAlgorithmFactorySelector());
432    }
433
434    private Map<String, RepositoryLayoutFactory> repositoryLayoutFactories;
435
436    public final Map<String, RepositoryLayoutFactory> getRepositoryLayoutFactories() {
437        checkClosed();
438        if (repositoryLayoutFactories == null) {
439            repositoryLayoutFactories = createRepositoryLayoutFactories();
440        }
441        return repositoryLayoutFactories;
442    }
443
444    protected Map<String, RepositoryLayoutFactory> createRepositoryLayoutFactories() {
445        HashMap<String, RepositoryLayoutFactory> result = new HashMap<>();
446        result.put(
447                Maven2RepositoryLayoutFactory.NAME,
448                new Maven2RepositoryLayoutFactory(
449                        getChecksumAlgorithmFactorySelector(), getArtifactPredicateFactory()));
450        return result;
451    }
452
453    private RepositoryLayoutProvider repositoryLayoutProvider;
454
455    public final RepositoryLayoutProvider getRepositoryLayoutProvider() {
456        checkClosed();
457        if (repositoryLayoutProvider == null) {
458            repositoryLayoutProvider = createRepositoryLayoutProvider();
459        }
460        return repositoryLayoutProvider;
461    }
462
463    protected RepositoryLayoutProvider createRepositoryLayoutProvider() {
464        return new DefaultRepositoryLayoutProvider(getRepositoryLayoutFactories());
465    }
466
467    private LocalRepositoryProvider localRepositoryProvider;
468
469    public final LocalRepositoryProvider getLocalRepositoryProvider() {
470        checkClosed();
471        if (localRepositoryProvider == null) {
472            localRepositoryProvider = createLocalRepositoryProvider();
473        }
474        return localRepositoryProvider;
475    }
476
477    protected LocalRepositoryProvider createLocalRepositoryProvider() {
478        LocalPathComposer localPathComposer = getLocalPathComposer();
479        HashMap<String, LocalRepositoryManagerFactory> localRepositoryProviders = new HashMap<>(2);
480        localRepositoryProviders.put(
481                SimpleLocalRepositoryManagerFactory.NAME, new SimpleLocalRepositoryManagerFactory(localPathComposer));
482        localRepositoryProviders.put(
483                EnhancedLocalRepositoryManagerFactory.NAME,
484                new EnhancedLocalRepositoryManagerFactory(
485                        localPathComposer, getTrackingFileManager(), getLocalPathPrefixComposerFactory()));
486        return new DefaultLocalRepositoryProvider(localRepositoryProviders);
487    }
488
489    private RemoteRepositoryManager remoteRepositoryManager;
490
491    public final RemoteRepositoryManager getRemoteRepositoryManager() {
492        checkClosed();
493        if (remoteRepositoryManager == null) {
494            remoteRepositoryManager = createRemoteRepositoryManager();
495        }
496        return remoteRepositoryManager;
497    }
498
499    protected RemoteRepositoryManager createRemoteRepositoryManager() {
500        return new DefaultRemoteRepositoryManager(getUpdatePolicyAnalyzer(), getChecksumPolicyProvider());
501    }
502
503    private Map<String, RemoteRepositoryFilterSource> remoteRepositoryFilterSources;
504
505    public final Map<String, RemoteRepositoryFilterSource> getRemoteRepositoryFilterSources() {
506        checkClosed();
507        if (remoteRepositoryFilterSources == null) {
508            remoteRepositoryFilterSources = createRemoteRepositoryFilterSources();
509        }
510        return remoteRepositoryFilterSources;
511    }
512
513    protected Map<String, RemoteRepositoryFilterSource> createRemoteRepositoryFilterSources() {
514        HashMap<String, RemoteRepositoryFilterSource> result = new HashMap<>();
515        result.put(
516                GroupIdRemoteRepositoryFilterSource.NAME,
517                new GroupIdRemoteRepositoryFilterSource(getRepositorySystemLifecycle()));
518        result.put(
519                PrefixesRemoteRepositoryFilterSource.NAME,
520                new PrefixesRemoteRepositoryFilterSource(getRepositoryLayoutProvider()));
521        return result;
522    }
523
524    private RemoteRepositoryFilterManager remoteRepositoryFilterManager;
525
526    public final RemoteRepositoryFilterManager getRemoteRepositoryFilterManager() {
527        checkClosed();
528        if (remoteRepositoryFilterManager == null) {
529            remoteRepositoryFilterManager = createRemoteRepositoryFilterManager();
530        }
531        return remoteRepositoryFilterManager;
532    }
533
534    protected RemoteRepositoryFilterManager createRemoteRepositoryFilterManager() {
535        return new DefaultRemoteRepositoryFilterManager(getRemoteRepositoryFilterSources());
536    }
537
538    private Map<String, RepositoryListener> repositoryListeners;
539
540    public final Map<String, RepositoryListener> getRepositoryListeners() {
541        checkClosed();
542        if (repositoryListeners == null) {
543            repositoryListeners = createRepositoryListeners();
544        }
545        return repositoryListeners;
546    }
547
548    protected Map<String, RepositoryListener> createRepositoryListeners() {
549        return new HashMap<>();
550    }
551
552    private RepositoryEventDispatcher repositoryEventDispatcher;
553
554    public final RepositoryEventDispatcher getRepositoryEventDispatcher() {
555        checkClosed();
556        if (repositoryEventDispatcher == null) {
557            repositoryEventDispatcher = createRepositoryEventDispatcher();
558        }
559        return repositoryEventDispatcher;
560    }
561
562    protected RepositoryEventDispatcher createRepositoryEventDispatcher() {
563        return new DefaultRepositoryEventDispatcher(getRepositoryListeners());
564    }
565
566    private Map<String, TrustedChecksumsSource> trustedChecksumsSources;
567
568    public final Map<String, TrustedChecksumsSource> getTrustedChecksumsSources() {
569        checkClosed();
570        if (trustedChecksumsSources == null) {
571            trustedChecksumsSources = createTrustedChecksumsSources();
572        }
573        return trustedChecksumsSources;
574    }
575
576    protected Map<String, TrustedChecksumsSource> createTrustedChecksumsSources() {
577        HashMap<String, TrustedChecksumsSource> result = new HashMap<>();
578        result.put(
579                SparseDirectoryTrustedChecksumsSource.NAME,
580                new SparseDirectoryTrustedChecksumsSource(getChecksumProcessor(), getLocalPathComposer()));
581        result.put(
582                SummaryFileTrustedChecksumsSource.NAME,
583                new SummaryFileTrustedChecksumsSource(getLocalPathComposer(), getRepositorySystemLifecycle()));
584        return result;
585    }
586
587    private Map<String, ProvidedChecksumsSource> providedChecksumsSources;
588
589    public final Map<String, ProvidedChecksumsSource> getProvidedChecksumsSources() {
590        checkClosed();
591        if (providedChecksumsSources == null) {
592            providedChecksumsSources = createProvidedChecksumsSources();
593        }
594        return providedChecksumsSources;
595    }
596
597    protected Map<String, ProvidedChecksumsSource> createProvidedChecksumsSources() {
598        HashMap<String, ProvidedChecksumsSource> result = new HashMap<>();
599        result.put(
600                TrustedToProvidedChecksumsSourceAdapter.NAME,
601                new TrustedToProvidedChecksumsSourceAdapter(getTrustedChecksumsSources()));
602        return result;
603    }
604
605    private Map<String, ChecksumExtractorStrategy> checksumExtractorStrategies;
606
607    public final Map<String, ChecksumExtractorStrategy> getChecksumExtractorStrategies() {
608        checkClosed();
609        if (checksumExtractorStrategies == null) {
610            checksumExtractorStrategies = createChecksumExtractorStrategies();
611        }
612        return checksumExtractorStrategies;
613    }
614
615    protected Map<String, ChecksumExtractorStrategy> createChecksumExtractorStrategies() {
616        HashMap<String, ChecksumExtractorStrategy> result = new HashMap<>();
617        result.put(XChecksumExtractor.NAME, new XChecksumExtractor());
618        result.put(Nx2ChecksumExtractor.NAME, new Nx2ChecksumExtractor());
619        return result;
620    }
621
622    private ChecksumExtractor checksumExtractor;
623
624    public final ChecksumExtractor getChecksumExtractor() {
625        checkClosed();
626        if (checksumExtractor == null) {
627            checksumExtractor = createChecksumExtractor();
628        }
629        return checksumExtractor;
630    }
631
632    protected ChecksumExtractor createChecksumExtractor() {
633        return new DefaultChecksumExtractor(getChecksumExtractorStrategies());
634    }
635
636    private Map<String, TransporterFactory> transporterFactories;
637
638    public final Map<String, TransporterFactory> getTransporterFactories() {
639        checkClosed();
640        if (transporterFactories == null) {
641            transporterFactories = createTransporterFactories();
642        }
643        return transporterFactories;
644    }
645
646    protected Map<String, TransporterFactory> createTransporterFactories() {
647        HashMap<String, TransporterFactory> result = new HashMap<>();
648        result.put(FileTransporterFactory.NAME, new FileTransporterFactory());
649        result.put(
650                ApacheTransporterFactory.NAME,
651                new ApacheTransporterFactory(getChecksumExtractor(), getPathProcessor()));
652        return result;
653    }
654
655    private TransporterProvider transporterProvider;
656
657    public final TransporterProvider getTransporterProvider() {
658        checkClosed();
659        if (transporterProvider == null) {
660            transporterProvider = createTransporterProvider();
661        }
662        return transporterProvider;
663    }
664
665    protected TransporterProvider createTransporterProvider() {
666        return new DefaultTransporterProvider(getTransporterFactories());
667    }
668
669    private BasicRepositoryConnectorFactory basicRepositoryConnectorFactory;
670
671    public final BasicRepositoryConnectorFactory getBasicRepositoryConnectorFactory() {
672        checkClosed();
673        if (basicRepositoryConnectorFactory == null) {
674            basicRepositoryConnectorFactory = createBasicRepositoryConnectorFactory();
675        }
676        return basicRepositoryConnectorFactory;
677    }
678
679    protected BasicRepositoryConnectorFactory createBasicRepositoryConnectorFactory() {
680        return new BasicRepositoryConnectorFactory(
681                getTransporterProvider(),
682                getRepositoryLayoutProvider(),
683                getChecksumPolicyProvider(),
684                getChecksumProcessor(),
685                getProvidedChecksumsSources());
686    }
687
688    private Map<String, RepositoryConnectorFactory> repositoryConnectorFactories;
689
690    public final Map<String, RepositoryConnectorFactory> getRepositoryConnectorFactories() {
691        checkClosed();
692        if (repositoryConnectorFactories == null) {
693            repositoryConnectorFactories = createRepositoryConnectorFactories();
694        }
695        return repositoryConnectorFactories;
696    }
697
698    protected Map<String, RepositoryConnectorFactory> createRepositoryConnectorFactories() {
699        HashMap<String, RepositoryConnectorFactory> result = new HashMap<>();
700        result.put(BasicRepositoryConnectorFactory.NAME, getBasicRepositoryConnectorFactory());
701        return result;
702    }
703
704    private RepositoryConnectorProvider repositoryConnectorProvider;
705
706    public final RepositoryConnectorProvider getRepositoryConnectorProvider() {
707        checkClosed();
708        if (repositoryConnectorProvider == null) {
709            repositoryConnectorProvider = createRepositoryConnectorProvider();
710        }
711        return repositoryConnectorProvider;
712    }
713
714    protected RepositoryConnectorProvider createRepositoryConnectorProvider() {
715        return new DefaultRepositoryConnectorProvider(
716                getRepositoryConnectorFactories(), getRemoteRepositoryFilterManager());
717    }
718
719    private Installer installer;
720
721    public final Installer getInstaller() {
722        checkClosed();
723        if (installer == null) {
724            installer = createInstaller();
725        }
726        return installer;
727    }
728
729    protected Installer createInstaller() {
730        return new DefaultInstaller(
731                getPathProcessor(),
732                getRepositoryEventDispatcher(),
733                getArtifactGeneratorFactories(),
734                getMetadataGeneratorFactories(),
735                getSyncContextFactory());
736    }
737
738    private Deployer deployer;
739
740    public final Deployer getDeployer() {
741        checkClosed();
742        if (deployer == null) {
743            deployer = createDeployer();
744        }
745        return deployer;
746    }
747
748    protected Deployer createDeployer() {
749        return new DefaultDeployer(
750                getPathProcessor(),
751                getRepositoryEventDispatcher(),
752                getRepositoryConnectorProvider(),
753                getRemoteRepositoryManager(),
754                getUpdateCheckManager(),
755                getArtifactGeneratorFactories(),
756                getMetadataGeneratorFactories(),
757                getSyncContextFactory(),
758                getOfflineController());
759    }
760
761    private Map<String, DependencyCollectorDelegate> dependencyCollectorDelegates;
762
763    public final Map<String, DependencyCollectorDelegate> getDependencyCollectorDelegates() {
764        checkClosed();
765        if (dependencyCollectorDelegates == null) {
766            dependencyCollectorDelegates = createDependencyCollectorDelegates();
767        }
768        return dependencyCollectorDelegates;
769    }
770
771    protected Map<String, DependencyCollectorDelegate> createDependencyCollectorDelegates() {
772        RemoteRepositoryManager remoteRepositoryManager = getRemoteRepositoryManager();
773        ArtifactDescriptorReader artifactDescriptorReader = getArtifactDescriptorReader();
774        VersionRangeResolver versionRangeResolver = getVersionRangeResolver();
775        HashMap<String, DependencyCollectorDelegate> result = new HashMap<>();
776        result.put(
777                DfDependencyCollector.NAME,
778                new DfDependencyCollector(
779                        remoteRepositoryManager,
780                        artifactDescriptorReader,
781                        versionRangeResolver,
782                        getArtifactDecoratorFactories()));
783        result.put(
784                BfDependencyCollector.NAME,
785                new BfDependencyCollector(
786                        remoteRepositoryManager,
787                        artifactDescriptorReader,
788                        versionRangeResolver,
789                        getArtifactDecoratorFactories()));
790        return result;
791    }
792
793    private DependencyCollector dependencyCollector;
794
795    public final DependencyCollector getDependencyCollector() {
796        checkClosed();
797        if (dependencyCollector == null) {
798            dependencyCollector = createDependencyCollector();
799        }
800        return dependencyCollector;
801    }
802
803    protected DependencyCollector createDependencyCollector() {
804        return new DefaultDependencyCollector(getDependencyCollectorDelegates());
805    }
806
807    private Map<String, ArtifactResolverPostProcessor> artifactResolverPostProcessors;
808
809    public final Map<String, ArtifactResolverPostProcessor> getArtifactResolverPostProcessors() {
810        checkClosed();
811        if (artifactResolverPostProcessors == null) {
812            artifactResolverPostProcessors = createArtifactResolverPostProcessors();
813        }
814        return artifactResolverPostProcessors;
815    }
816
817    protected Map<String, ArtifactResolverPostProcessor> createArtifactResolverPostProcessors() {
818        HashMap<String, ArtifactResolverPostProcessor> result = new HashMap<>();
819        result.put(
820                TrustedChecksumsArtifactResolverPostProcessor.NAME,
821                new TrustedChecksumsArtifactResolverPostProcessor(
822                        getChecksumAlgorithmFactorySelector(), getTrustedChecksumsSources()));
823        return result;
824    }
825
826    private ArtifactResolver artifactResolver;
827
828    public final ArtifactResolver getArtifactResolver() {
829        checkClosed();
830        if (artifactResolver == null) {
831            artifactResolver = createArtifactResolver();
832        }
833        return artifactResolver;
834    }
835
836    protected ArtifactResolver createArtifactResolver() {
837        return new DefaultArtifactResolver(
838                getPathProcessor(),
839                getRepositoryEventDispatcher(),
840                getVersionResolver(),
841                getUpdateCheckManager(),
842                getRepositoryConnectorProvider(),
843                getRemoteRepositoryManager(),
844                getSyncContextFactory(),
845                getOfflineController(),
846                getArtifactResolverPostProcessors(),
847                getRemoteRepositoryFilterManager());
848    }
849
850    private MetadataResolver metadataResolver;
851
852    public final MetadataResolver getMetadataResolver() {
853        checkClosed();
854        if (metadataResolver == null) {
855            metadataResolver = createMetadataResolver();
856        }
857        return metadataResolver;
858    }
859
860    protected MetadataResolver createMetadataResolver() {
861        return new DefaultMetadataResolver(
862                getRepositoryEventDispatcher(),
863                getUpdateCheckManager(),
864                getRepositoryConnectorProvider(),
865                getRemoteRepositoryManager(),
866                getSyncContextFactory(),
867                getOfflineController(),
868                getRemoteRepositoryFilterManager(),
869                getPathProcessor());
870    }
871
872    private VersionScheme versionScheme;
873
874    public final VersionScheme getVersionScheme() {
875        checkClosed();
876        if (versionScheme == null) {
877            versionScheme = createVersionScheme();
878        }
879        return versionScheme;
880    }
881
882    protected VersionScheme createVersionScheme() {
883        return new GenericVersionScheme();
884    }
885
886    private Map<String, ArtifactGeneratorFactory> artifactGeneratorFactories;
887
888    public final Map<String, ArtifactGeneratorFactory> getArtifactGeneratorFactories() {
889        checkClosed();
890        if (artifactGeneratorFactories == null) {
891            artifactGeneratorFactories = createArtifactGeneratorFactories();
892        }
893        return artifactGeneratorFactories;
894    }
895
896    protected Map<String, ArtifactGeneratorFactory> createArtifactGeneratorFactories() {
897        // by default none, this is extension point
898        return new HashMap<>();
899    }
900
901    private Map<String, ArtifactDecoratorFactory> artifactDecoratorFactories;
902
903    public final Map<String, ArtifactDecoratorFactory> getArtifactDecoratorFactories() {
904        checkClosed();
905        if (artifactDecoratorFactories == null) {
906            artifactDecoratorFactories = createArtifactDecoratorFactories();
907        }
908        return artifactDecoratorFactories;
909    }
910
911    protected Map<String, ArtifactDecoratorFactory> createArtifactDecoratorFactories() {
912        // by default none, this is extension point
913        return new HashMap<>();
914    }
915
916    // Maven provided
917
918    private Map<String, MetadataGeneratorFactory> metadataGeneratorFactories;
919
920    public final Map<String, MetadataGeneratorFactory> getMetadataGeneratorFactories() {
921        checkClosed();
922        if (metadataGeneratorFactories == null) {
923            metadataGeneratorFactories = createMetadataGeneratorFactories();
924        }
925        return metadataGeneratorFactories;
926    }
927
928    protected Map<String, MetadataGeneratorFactory> createMetadataGeneratorFactories() {
929        // from maven-resolver-provider
930        HashMap<String, MetadataGeneratorFactory> result = new HashMap<>();
931        result.put(PluginsMetadataGeneratorFactory.NAME, new PluginsMetadataGeneratorFactory());
932        result.put(VersionsMetadataGeneratorFactory.NAME, new VersionsMetadataGeneratorFactory());
933        result.put(SnapshotMetadataGeneratorFactory.NAME, new SnapshotMetadataGeneratorFactory());
934        return result;
935    }
936
937    private LinkedHashMap<String, MavenArtifactRelocationSource> artifactRelocationSources;
938
939    public final LinkedHashMap<String, MavenArtifactRelocationSource> getMavenArtifactRelocationSources() {
940        checkClosed();
941        if (artifactRelocationSources == null) {
942            artifactRelocationSources = createMavenArtifactRelocationSources();
943        }
944        return artifactRelocationSources;
945    }
946
947    protected LinkedHashMap<String, MavenArtifactRelocationSource> createMavenArtifactRelocationSources() {
948        // from maven-resolver-provider
949        LinkedHashMap<String, MavenArtifactRelocationSource> result = new LinkedHashMap<>();
950        result.put(UserPropertiesArtifactRelocationSource.NAME, new UserPropertiesArtifactRelocationSource());
951        result.put(
952                DistributionManagementArtifactRelocationSource.NAME,
953                new DistributionManagementArtifactRelocationSource());
954        return result;
955    }
956
957    private ArtifactDescriptorReader artifactDescriptorReader;
958
959    public final ArtifactDescriptorReader getArtifactDescriptorReader() {
960        checkClosed();
961        if (artifactDescriptorReader == null) {
962            artifactDescriptorReader = createArtifactDescriptorReader();
963        }
964        return artifactDescriptorReader;
965    }
966
967    protected ArtifactDescriptorReader createArtifactDescriptorReader() {
968        // from maven-resolver-provider
969        return new DefaultArtifactDescriptorReader(
970                getRemoteRepositoryManager(),
971                getVersionResolver(),
972                getVersionRangeResolver(),
973                getArtifactResolver(),
974                getModelBuilder(),
975                getRepositoryEventDispatcher(),
976                getModelCacheFactory(),
977                getMavenArtifactRelocationSources());
978    }
979
980    private VersionResolver versionResolver;
981
982    public final VersionResolver getVersionResolver() {
983        checkClosed();
984        if (versionResolver == null) {
985            versionResolver = createVersionResolver();
986        }
987        return versionResolver;
988    }
989
990    protected VersionResolver createVersionResolver() {
991        // from maven-resolver-provider
992        return new DefaultVersionResolver(
993                getMetadataResolver(), getSyncContextFactory(), getRepositoryEventDispatcher());
994    }
995
996    private VersionRangeResolver versionRangeResolver;
997
998    public final VersionRangeResolver getVersionRangeResolver() {
999        checkClosed();
1000        if (versionRangeResolver == null) {
1001            versionRangeResolver = createVersionRangeResolver();
1002        }
1003        return versionRangeResolver;
1004    }
1005
1006    protected VersionRangeResolver createVersionRangeResolver() {
1007        // from maven-resolver-provider
1008        return new DefaultVersionRangeResolver(
1009                getMetadataResolver(), getSyncContextFactory(), getRepositoryEventDispatcher(), getVersionScheme());
1010    }
1011
1012    private ModelBuilder modelBuilder;
1013
1014    public final ModelBuilder getModelBuilder() {
1015        checkClosed();
1016        if (modelBuilder == null) {
1017            modelBuilder = createModelBuilder();
1018        }
1019        return modelBuilder;
1020    }
1021
1022    protected ModelBuilder createModelBuilder() {
1023        // from maven-model-builder
1024        return new DefaultModelBuilderFactory().newInstance();
1025    }
1026
1027    private ModelCacheFactory modelCacheFactory;
1028
1029    public final ModelCacheFactory getModelCacheFactory() {
1030        checkClosed();
1031        if (modelCacheFactory == null) {
1032            modelCacheFactory = createModelCacheFactory();
1033        }
1034        return modelCacheFactory;
1035    }
1036
1037    protected ModelCacheFactory createModelCacheFactory() {
1038        // from maven-resolver-provider
1039        return new DefaultModelCacheFactory();
1040    }
1041
1042    private RepositorySystem repositorySystem;
1043
1044    public final RepositorySystem getRepositorySystem() {
1045        checkClosed();
1046        if (repositorySystem == null) {
1047            repositorySystem = createRepositorySystem();
1048        }
1049        return repositorySystem;
1050    }
1051
1052    protected RepositorySystem createRepositorySystem() {
1053        return new DefaultRepositorySystem(
1054                getVersionResolver(),
1055                getVersionRangeResolver(),
1056                getArtifactResolver(),
1057                getMetadataResolver(),
1058                getArtifactDescriptorReader(),
1059                getDependencyCollector(),
1060                getInstaller(),
1061                getDeployer(),
1062                getLocalRepositoryProvider(),
1063                getSyncContextFactory(),
1064                getRemoteRepositoryManager(),
1065                getRepositorySystemLifecycle(),
1066                getArtifactDecoratorFactories());
1067    }
1068
1069    @Override
1070    public RepositorySystem get() {
1071        return getRepositorySystem();
1072    }
1073}