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