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