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