1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.supplier;
20
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.concurrent.atomic.AtomicBoolean;
27 import java.util.function.Supplier;
28
29 import org.apache.maven.model.building.DefaultModelBuilderFactory;
30 import org.apache.maven.model.building.ModelBuilder;
31 import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader;
32 import org.apache.maven.repository.internal.DefaultModelCacheFactory;
33 import org.apache.maven.repository.internal.DefaultVersionRangeResolver;
34 import org.apache.maven.repository.internal.DefaultVersionResolver;
35 import org.apache.maven.repository.internal.MavenArtifactRelocationSource;
36 import org.apache.maven.repository.internal.ModelCacheFactory;
37 import org.apache.maven.repository.internal.PluginsMetadataGeneratorFactory;
38 import org.apache.maven.repository.internal.SnapshotMetadataGeneratorFactory;
39 import org.apache.maven.repository.internal.VersionsMetadataGeneratorFactory;
40 import org.apache.maven.repository.internal.relocation.DistributionManagementArtifactRelocationSource;
41 import org.apache.maven.repository.internal.relocation.UserPropertiesArtifactRelocationSource;
42 import org.eclipse.aether.RepositoryListener;
43 import org.eclipse.aether.RepositorySystem;
44 import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
45 import org.eclipse.aether.impl.ArtifactDescriptorReader;
46 import org.eclipse.aether.impl.ArtifactResolver;
47 import org.eclipse.aether.impl.DependencyCollector;
48 import org.eclipse.aether.impl.Deployer;
49 import org.eclipse.aether.impl.Installer;
50 import org.eclipse.aether.impl.LocalRepositoryProvider;
51 import org.eclipse.aether.impl.MetadataGeneratorFactory;
52 import org.eclipse.aether.impl.MetadataResolver;
53 import org.eclipse.aether.impl.OfflineController;
54 import org.eclipse.aether.impl.RemoteRepositoryFilterManager;
55 import org.eclipse.aether.impl.RemoteRepositoryManager;
56 import org.eclipse.aether.impl.RepositoryConnectorProvider;
57 import org.eclipse.aether.impl.RepositoryEventDispatcher;
58 import org.eclipse.aether.impl.RepositorySystemLifecycle;
59 import org.eclipse.aether.impl.RepositorySystemValidator;
60 import org.eclipse.aether.impl.UpdateCheckManager;
61 import org.eclipse.aether.impl.UpdatePolicyAnalyzer;
62 import org.eclipse.aether.impl.VersionRangeResolver;
63 import org.eclipse.aether.impl.VersionResolver;
64 import org.eclipse.aether.internal.impl.DefaultArtifactPredicateFactory;
65 import org.eclipse.aether.internal.impl.DefaultArtifactResolver;
66 import org.eclipse.aether.internal.impl.DefaultChecksumPolicyProvider;
67 import org.eclipse.aether.internal.impl.DefaultChecksumProcessor;
68 import org.eclipse.aether.internal.impl.DefaultDeployer;
69 import org.eclipse.aether.internal.impl.DefaultInstaller;
70 import org.eclipse.aether.internal.impl.DefaultLocalPathComposer;
71 import org.eclipse.aether.internal.impl.DefaultLocalPathPrefixComposerFactory;
72 import org.eclipse.aether.internal.impl.DefaultLocalRepositoryProvider;
73 import org.eclipse.aether.internal.impl.DefaultMetadataResolver;
74 import org.eclipse.aether.internal.impl.DefaultOfflineController;
75 import org.eclipse.aether.internal.impl.DefaultPathProcessor;
76 import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager;
77 import org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider;
78 import org.eclipse.aether.internal.impl.DefaultRepositoryEventDispatcher;
79 import org.eclipse.aether.internal.impl.DefaultRepositoryKeyFunctionFactory;
80 import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider;
81 import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
82 import org.eclipse.aether.internal.impl.DefaultRepositorySystemLifecycle;
83 import org.eclipse.aether.internal.impl.DefaultRepositorySystemValidator;
84 import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
85 import org.eclipse.aether.internal.impl.DefaultTransporterProvider;
86 import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager;
87 import org.eclipse.aether.internal.impl.DefaultUpdatePolicyAnalyzer;
88 import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory;
89 import org.eclipse.aether.internal.impl.LocalPathComposer;
90 import org.eclipse.aether.internal.impl.LocalPathPrefixComposerFactory;
91 import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
92 import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
93 import org.eclipse.aether.internal.impl.TrackingFileManager;
94 import org.eclipse.aether.internal.impl.checksum.DefaultChecksumAlgorithmFactorySelector;
95 import org.eclipse.aether.internal.impl.checksum.Md5ChecksumAlgorithmFactory;
96 import org.eclipse.aether.internal.impl.checksum.Sha1ChecksumAlgorithmFactory;
97 import org.eclipse.aether.internal.impl.checksum.Sha256ChecksumAlgorithmFactory;
98 import org.eclipse.aether.internal.impl.checksum.Sha512ChecksumAlgorithmFactory;
99 import org.eclipse.aether.internal.impl.checksum.SparseDirectoryTrustedChecksumsSource;
100 import org.eclipse.aether.internal.impl.checksum.SummaryFileTrustedChecksumsSource;
101 import org.eclipse.aether.internal.impl.checksum.TrustedToProvidedChecksumsSourceAdapter;
102 import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector;
103 import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate;
104 import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector;
105 import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector;
106 import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager;
107 import org.eclipse.aether.internal.impl.filter.FilteringPipelineRepositoryConnectorFactory;
108 import org.eclipse.aether.internal.impl.filter.GroupIdRemoteRepositoryFilterSource;
109 import org.eclipse.aether.internal.impl.filter.PrefixesLockingInhibitorFactory;
110 import org.eclipse.aether.internal.impl.filter.PrefixesRemoteRepositoryFilterSource;
111 import org.eclipse.aether.internal.impl.offline.OfflinePipelineRepositoryConnectorFactory;
112 import org.eclipse.aether.internal.impl.resolution.TrustedChecksumsArtifactResolverPostProcessor;
113 import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
114 import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
115 import org.eclipse.aether.internal.impl.synccontext.named.NameMappers;
116 import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory;
117 import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
118 import org.eclipse.aether.internal.impl.transport.http.DefaultChecksumExtractor;
119 import org.eclipse.aether.internal.impl.transport.http.Nx2ChecksumExtractor;
120 import org.eclipse.aether.internal.impl.transport.http.XChecksumExtractor;
121 import org.eclipse.aether.named.NamedLockFactory;
122 import org.eclipse.aether.named.providers.FileLockNamedLockFactory;
123 import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory;
124 import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory;
125 import org.eclipse.aether.named.providers.NoopNamedLockFactory;
126 import org.eclipse.aether.spi.artifact.ArtifactPredicateFactory;
127 import org.eclipse.aether.spi.artifact.decorator.ArtifactDecoratorFactory;
128 import org.eclipse.aether.spi.artifact.generator.ArtifactGeneratorFactory;
129 import org.eclipse.aether.spi.artifact.transformer.ArtifactTransformer;
130 import org.eclipse.aether.spi.checksums.ProvidedChecksumsSource;
131 import org.eclipse.aether.spi.checksums.TrustedChecksumsSource;
132 import org.eclipse.aether.spi.connector.PipelineRepositoryConnectorFactory;
133 import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
134 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
135 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
136 import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
137 import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
138 import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
139 import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
140 import org.eclipse.aether.spi.connector.transport.TransporterFactory;
141 import org.eclipse.aether.spi.connector.transport.TransporterProvider;
142 import org.eclipse.aether.spi.connector.transport.http.ChecksumExtractor;
143 import org.eclipse.aether.spi.connector.transport.http.ChecksumExtractorStrategy;
144 import org.eclipse.aether.spi.io.ChecksumProcessor;
145 import org.eclipse.aether.spi.io.PathProcessor;
146 import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
147 import org.eclipse.aether.spi.locking.LockingInhibitorFactory;
148 import org.eclipse.aether.spi.remoterepo.RepositoryKeyFunctionFactory;
149 import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor;
150 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
151 import org.eclipse.aether.spi.validator.ValidatorFactory;
152 import org.eclipse.aether.transport.apache.ApacheTransporterFactory;
153 import org.eclipse.aether.transport.file.FileTransporterFactory;
154 import org.eclipse.aether.util.version.GenericVersionScheme;
155 import org.eclipse.aether.version.VersionScheme;
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180 public class RepositorySystemSupplier implements Supplier<RepositorySystem> {
181 private final AtomicBoolean closed = new AtomicBoolean(false);
182
183 public RepositorySystemSupplier() {}
184
185 private void checkClosed() {
186 if (closed.get()) {
187 throw new IllegalStateException("Supplier is closed");
188 }
189 }
190
191 private PathProcessor pathProcessor;
192
193 public final PathProcessor getPathProcessor() {
194 checkClosed();
195 if (pathProcessor == null) {
196 pathProcessor = createPathProcessor();
197 }
198 return pathProcessor;
199 }
200
201 protected PathProcessor createPathProcessor() {
202 return new DefaultPathProcessor();
203 }
204
205 private ChecksumProcessor checksumProcessor;
206
207 public final ChecksumProcessor getChecksumProcessor() {
208 checkClosed();
209 if (checksumProcessor == null) {
210 checksumProcessor = createChecksumProcessor();
211 }
212 return checksumProcessor;
213 }
214
215 protected ChecksumProcessor createChecksumProcessor() {
216 return new DefaultChecksumProcessor(getPathProcessor());
217 }
218
219 private TrackingFileManager trackingFileManager;
220
221 public final TrackingFileManager getTrackingFileManager() {
222 checkClosed();
223 if (trackingFileManager == null) {
224 trackingFileManager = createTrackingFileManager();
225 }
226 return trackingFileManager;
227 }
228
229 protected TrackingFileManager createTrackingFileManager() {
230 return new DefaultTrackingFileManager();
231 }
232
233 private LocalPathComposer localPathComposer;
234
235 public final LocalPathComposer getLocalPathComposer() {
236 checkClosed();
237 if (localPathComposer == null) {
238 localPathComposer = createLocalPathComposer();
239 }
240 return localPathComposer;
241 }
242
243 protected LocalPathComposer createLocalPathComposer() {
244 return new DefaultLocalPathComposer();
245 }
246
247 private LocalPathPrefixComposerFactory localPathPrefixComposerFactory;
248
249 public final LocalPathPrefixComposerFactory getLocalPathPrefixComposerFactory() {
250 checkClosed();
251 if (localPathPrefixComposerFactory == null) {
252 localPathPrefixComposerFactory = createLocalPathPrefixComposerFactory();
253 }
254 return localPathPrefixComposerFactory;
255 }
256
257 protected LocalPathPrefixComposerFactory createLocalPathPrefixComposerFactory() {
258 return new DefaultLocalPathPrefixComposerFactory(getRepositoryKeyFunctionFactory());
259 }
260
261 private RepositorySystemLifecycle repositorySystemLifecycle;
262
263 public final RepositorySystemLifecycle getRepositorySystemLifecycle() {
264 checkClosed();
265 if (repositorySystemLifecycle == null) {
266 repositorySystemLifecycle = createRepositorySystemLifecycle();
267 repositorySystemLifecycle.addOnSystemEndedHandler(() -> closed.set(true));
268 }
269 return repositorySystemLifecycle;
270 }
271
272 protected RepositorySystemLifecycle createRepositorySystemLifecycle() {
273 return new DefaultRepositorySystemLifecycle();
274 }
275
276 private OfflineController offlineController;
277
278 public final OfflineController getOfflineController() {
279 checkClosed();
280 if (offlineController == null) {
281 offlineController = createOfflineController();
282 }
283 return offlineController;
284 }
285
286 protected OfflineController createOfflineController() {
287 return new DefaultOfflineController();
288 }
289
290 private UpdatePolicyAnalyzer updatePolicyAnalyzer;
291
292 public final UpdatePolicyAnalyzer getUpdatePolicyAnalyzer() {
293 checkClosed();
294 if (updatePolicyAnalyzer == null) {
295 updatePolicyAnalyzer = createUpdatePolicyAnalyzer();
296 }
297 return updatePolicyAnalyzer;
298 }
299
300 protected UpdatePolicyAnalyzer createUpdatePolicyAnalyzer() {
301 return new DefaultUpdatePolicyAnalyzer();
302 }
303
304 private ChecksumPolicyProvider checksumPolicyProvider;
305
306 public final ChecksumPolicyProvider getChecksumPolicyProvider() {
307 checkClosed();
308 if (checksumPolicyProvider == null) {
309 checksumPolicyProvider = createChecksumPolicyProvider();
310 }
311 return checksumPolicyProvider;
312 }
313
314 protected ChecksumPolicyProvider createChecksumPolicyProvider() {
315 return new DefaultChecksumPolicyProvider();
316 }
317
318 private UpdateCheckManager updateCheckManager;
319
320 public final UpdateCheckManager getUpdateCheckManager() {
321 checkClosed();
322 if (updateCheckManager == null) {
323 updateCheckManager = createUpdateCheckManager();
324 }
325 return updateCheckManager;
326 }
327
328 protected UpdateCheckManager createUpdateCheckManager() {
329 return new DefaultUpdateCheckManager(getTrackingFileManager(), getUpdatePolicyAnalyzer(), getPathProcessor());
330 }
331
332 private RepositoryKeyFunctionFactory repositoriesKeyFunctionFactory;
333
334 public final RepositoryKeyFunctionFactory getRepositoryKeyFunctionFactory() {
335 checkClosed();
336 if (repositoriesKeyFunctionFactory == null) {
337 repositoriesKeyFunctionFactory = createRepositoryKeyFunctionFactory();
338 }
339 return repositoriesKeyFunctionFactory;
340 }
341
342 protected RepositoryKeyFunctionFactory createRepositoryKeyFunctionFactory() {
343 return new DefaultRepositoryKeyFunctionFactory();
344 }
345
346 private Map<String, NamedLockFactory> namedLockFactories;
347
348 public final Map<String, NamedLockFactory> getNamedLockFactories() {
349 checkClosed();
350 if (namedLockFactories == null) {
351 namedLockFactories = createNamedLockFactories();
352 }
353 return namedLockFactories;
354 }
355
356 protected Map<String, NamedLockFactory> createNamedLockFactories() {
357 HashMap<String, NamedLockFactory> result = new HashMap<>();
358 result.put(NoopNamedLockFactory.NAME, new NoopNamedLockFactory());
359 result.put(LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory());
360 result.put(LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory());
361 result.put(FileLockNamedLockFactory.NAME, new FileLockNamedLockFactory());
362 return result;
363 }
364
365 private Map<String, NameMapper> nameMappers;
366
367 public final Map<String, NameMapper> getNameMappers() {
368 checkClosed();
369 if (nameMappers == null) {
370 nameMappers = createNameMappers();
371 }
372 return nameMappers;
373 }
374
375 protected Map<String, NameMapper> createNameMappers() {
376 HashMap<String, NameMapper> result = new HashMap<>();
377 result.put(NameMappers.STATIC_NAME, NameMappers.staticNameMapper());
378 result.put(NameMappers.GAV_NAME, NameMappers.gavNameMapper());
379 result.put(NameMappers.GAECV_NAME, NameMappers.gaecvNameMapper());
380 result.put(NameMappers.DISCRIMINATING_NAME, NameMappers.discriminatingNameMapper());
381 result.put(NameMappers.FILE_GAV_NAME, NameMappers.fileGavNameMapper());
382 result.put(NameMappers.FILE_GAECV_NAME, NameMappers.fileGaecvNameMapper());
383 result.put(NameMappers.FILE_HGAV_NAME, NameMappers.fileHashingGavNameMapper());
384 result.put(NameMappers.FILE_HGAECV_NAME, NameMappers.fileHashingGaecvNameMapper());
385 return result;
386 }
387
388 private Map<String, LockingInhibitorFactory> lockingInhibitorFactories;
389
390 public final Map<String, LockingInhibitorFactory> getLockingInhibitorFactories() {
391 checkClosed();
392 if (lockingInhibitorFactories == null) {
393 lockingInhibitorFactories = createLockingInhibitorFactories();
394 }
395 return lockingInhibitorFactories;
396 }
397
398 protected Map<String, LockingInhibitorFactory> createLockingInhibitorFactories() {
399 HashMap<String, LockingInhibitorFactory> result = new HashMap<>();
400 result.put(PrefixesLockingInhibitorFactory.NAME, new PrefixesLockingInhibitorFactory());
401 return result;
402 }
403
404 private NamedLockFactoryAdapterFactory namedLockFactoryAdapterFactory;
405
406 public final NamedLockFactoryAdapterFactory getNamedLockFactoryAdapterFactory() {
407 checkClosed();
408 if (namedLockFactoryAdapterFactory == null) {
409 namedLockFactoryAdapterFactory = createNamedLockFactoryAdapterFactory();
410 }
411 return namedLockFactoryAdapterFactory;
412 }
413
414 protected NamedLockFactoryAdapterFactory createNamedLockFactoryAdapterFactory() {
415 return new NamedLockFactoryAdapterFactoryImpl(
416 getNamedLockFactories(),
417 getNameMappers(),
418 getLockingInhibitorFactories(),
419 getRepositorySystemLifecycle());
420 }
421
422 private SyncContextFactory syncContextFactory;
423
424 public final SyncContextFactory getSyncContextFactory() {
425 checkClosed();
426 if (syncContextFactory == null) {
427 syncContextFactory = createSyncContextFactory();
428 }
429 return syncContextFactory;
430 }
431
432 protected SyncContextFactory createSyncContextFactory() {
433 return new DefaultSyncContextFactory(getNamedLockFactoryAdapterFactory());
434 }
435
436 private Map<String, ChecksumAlgorithmFactory> checksumAlgorithmFactories;
437
438 public final Map<String, ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
439 checkClosed();
440 if (checksumAlgorithmFactories == null) {
441 checksumAlgorithmFactories = createChecksumAlgorithmFactories();
442 }
443 return checksumAlgorithmFactories;
444 }
445
446 protected Map<String, ChecksumAlgorithmFactory> createChecksumAlgorithmFactories() {
447 HashMap<String, ChecksumAlgorithmFactory> result = new HashMap<>();
448 result.put(Sha512ChecksumAlgorithmFactory.NAME, new Sha512ChecksumAlgorithmFactory());
449 result.put(Sha256ChecksumAlgorithmFactory.NAME, new Sha256ChecksumAlgorithmFactory());
450 result.put(Sha1ChecksumAlgorithmFactory.NAME, new Sha1ChecksumAlgorithmFactory());
451 result.put(Md5ChecksumAlgorithmFactory.NAME, new Md5ChecksumAlgorithmFactory());
452 return result;
453 }
454
455 private ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector;
456
457 public final ChecksumAlgorithmFactorySelector getChecksumAlgorithmFactorySelector() {
458 checkClosed();
459 if (checksumAlgorithmFactorySelector == null) {
460 checksumAlgorithmFactorySelector = createChecksumAlgorithmFactorySelector();
461 }
462 return checksumAlgorithmFactorySelector;
463 }
464
465 protected ChecksumAlgorithmFactorySelector createChecksumAlgorithmFactorySelector() {
466 return new DefaultChecksumAlgorithmFactorySelector(getChecksumAlgorithmFactories());
467 }
468
469 private ArtifactPredicateFactory artifactPredicateFactory;
470
471 public final ArtifactPredicateFactory getArtifactPredicateFactory() {
472 checkClosed();
473 if (artifactPredicateFactory == null) {
474 artifactPredicateFactory = createArtifactPredicateFactory();
475 }
476 return artifactPredicateFactory;
477 }
478
479 protected ArtifactPredicateFactory createArtifactPredicateFactory() {
480 return new DefaultArtifactPredicateFactory(getChecksumAlgorithmFactorySelector());
481 }
482
483 private Map<String, RepositoryLayoutFactory> repositoryLayoutFactories;
484
485 public final Map<String, RepositoryLayoutFactory> getRepositoryLayoutFactories() {
486 checkClosed();
487 if (repositoryLayoutFactories == null) {
488 repositoryLayoutFactories = createRepositoryLayoutFactories();
489 }
490 return repositoryLayoutFactories;
491 }
492
493 protected Map<String, RepositoryLayoutFactory> createRepositoryLayoutFactories() {
494 HashMap<String, RepositoryLayoutFactory> result = new HashMap<>();
495 result.put(
496 Maven2RepositoryLayoutFactory.NAME,
497 new Maven2RepositoryLayoutFactory(
498 getChecksumAlgorithmFactorySelector(), getArtifactPredicateFactory()));
499 return result;
500 }
501
502 private RepositoryLayoutProvider repositoryLayoutProvider;
503
504 public final RepositoryLayoutProvider getRepositoryLayoutProvider() {
505 checkClosed();
506 if (repositoryLayoutProvider == null) {
507 repositoryLayoutProvider = createRepositoryLayoutProvider();
508 }
509 return repositoryLayoutProvider;
510 }
511
512 protected RepositoryLayoutProvider createRepositoryLayoutProvider() {
513 return new DefaultRepositoryLayoutProvider(getRepositoryLayoutFactories());
514 }
515
516 private LocalRepositoryProvider localRepositoryProvider;
517
518 public final LocalRepositoryProvider getLocalRepositoryProvider() {
519 checkClosed();
520 if (localRepositoryProvider == null) {
521 localRepositoryProvider = createLocalRepositoryProvider();
522 }
523 return localRepositoryProvider;
524 }
525
526 protected LocalRepositoryProvider createLocalRepositoryProvider() {
527 LocalPathComposer localPathComposer = getLocalPathComposer();
528 RepositoryKeyFunctionFactory repositoryKeyFunctionFactory = getRepositoryKeyFunctionFactory();
529 HashMap<String, LocalRepositoryManagerFactory> localRepositoryProviders = new HashMap<>(2);
530 localRepositoryProviders.put(
531 SimpleLocalRepositoryManagerFactory.NAME,
532 new SimpleLocalRepositoryManagerFactory(localPathComposer, repositoryKeyFunctionFactory));
533 localRepositoryProviders.put(
534 EnhancedLocalRepositoryManagerFactory.NAME,
535 new EnhancedLocalRepositoryManagerFactory(
536 localPathComposer,
537 getTrackingFileManager(),
538 getLocalPathPrefixComposerFactory(),
539 repositoryKeyFunctionFactory));
540 return new DefaultLocalRepositoryProvider(localRepositoryProviders);
541 }
542
543 private RemoteRepositoryManager remoteRepositoryManager;
544
545 public final RemoteRepositoryManager getRemoteRepositoryManager() {
546 checkClosed();
547 if (remoteRepositoryManager == null) {
548 remoteRepositoryManager = createRemoteRepositoryManager();
549 }
550 return remoteRepositoryManager;
551 }
552
553 protected RemoteRepositoryManager createRemoteRepositoryManager() {
554 return new DefaultRemoteRepositoryManager(
555 getUpdatePolicyAnalyzer(), getChecksumPolicyProvider(), getRepositoryKeyFunctionFactory());
556 }
557
558 private Map<String, RemoteRepositoryFilterSource> remoteRepositoryFilterSources;
559
560 public final Map<String, RemoteRepositoryFilterSource> getRemoteRepositoryFilterSources() {
561 checkClosed();
562 if (remoteRepositoryFilterSources == null) {
563 remoteRepositoryFilterSources = createRemoteRepositoryFilterSources();
564 }
565 return remoteRepositoryFilterSources;
566 }
567
568 protected Map<String, RemoteRepositoryFilterSource> createRemoteRepositoryFilterSources() {
569 HashMap<String, RemoteRepositoryFilterSource> result = new HashMap<>();
570 result.put(
571 GroupIdRemoteRepositoryFilterSource.NAME,
572 new GroupIdRemoteRepositoryFilterSource(
573 getRepositoryKeyFunctionFactory(), getRepositorySystemLifecycle(), getPathProcessor()));
574 result.put(
575 PrefixesRemoteRepositoryFilterSource.NAME,
576 new PrefixesRemoteRepositoryFilterSource(
577 getRepositoryKeyFunctionFactory(),
578 this::getMetadataResolver,
579 this::getRemoteRepositoryManager,
580 getRepositoryLayoutProvider()));
581 return result;
582 }
583
584 private RemoteRepositoryFilterManager remoteRepositoryFilterManager;
585
586 public final RemoteRepositoryFilterManager getRemoteRepositoryFilterManager() {
587 checkClosed();
588 if (remoteRepositoryFilterManager == null) {
589 remoteRepositoryFilterManager = createRemoteRepositoryFilterManager();
590 }
591 return remoteRepositoryFilterManager;
592 }
593
594 protected RemoteRepositoryFilterManager createRemoteRepositoryFilterManager() {
595 return new DefaultRemoteRepositoryFilterManager(getRemoteRepositoryFilterSources());
596 }
597
598 private Map<String, RepositoryListener> repositoryListeners;
599
600 public final Map<String, RepositoryListener> getRepositoryListeners() {
601 checkClosed();
602 if (repositoryListeners == null) {
603 repositoryListeners = createRepositoryListeners();
604 }
605 return repositoryListeners;
606 }
607
608 protected Map<String, RepositoryListener> createRepositoryListeners() {
609 return new HashMap<>();
610 }
611
612 private RepositoryEventDispatcher repositoryEventDispatcher;
613
614 public final RepositoryEventDispatcher getRepositoryEventDispatcher() {
615 checkClosed();
616 if (repositoryEventDispatcher == null) {
617 repositoryEventDispatcher = createRepositoryEventDispatcher();
618 }
619 return repositoryEventDispatcher;
620 }
621
622 protected RepositoryEventDispatcher createRepositoryEventDispatcher() {
623 return new DefaultRepositoryEventDispatcher(getRepositoryListeners());
624 }
625
626 private Map<String, TrustedChecksumsSource> trustedChecksumsSources;
627
628 public final Map<String, TrustedChecksumsSource> getTrustedChecksumsSources() {
629 checkClosed();
630 if (trustedChecksumsSources == null) {
631 trustedChecksumsSources = createTrustedChecksumsSources();
632 }
633 return trustedChecksumsSources;
634 }
635
636 protected Map<String, TrustedChecksumsSource> createTrustedChecksumsSources() {
637 HashMap<String, TrustedChecksumsSource> result = new HashMap<>();
638 result.put(
639 SparseDirectoryTrustedChecksumsSource.NAME,
640 new SparseDirectoryTrustedChecksumsSource(
641 getRepositoryKeyFunctionFactory(), getChecksumProcessor(), getLocalPathComposer()));
642 result.put(
643 SummaryFileTrustedChecksumsSource.NAME,
644 new SummaryFileTrustedChecksumsSource(
645 getRepositoryKeyFunctionFactory(),
646 getLocalPathComposer(),
647 getRepositorySystemLifecycle(),
648 getPathProcessor()));
649 return result;
650 }
651
652 private Map<String, ProvidedChecksumsSource> providedChecksumsSources;
653
654 public final Map<String, ProvidedChecksumsSource> getProvidedChecksumsSources() {
655 checkClosed();
656 if (providedChecksumsSources == null) {
657 providedChecksumsSources = createProvidedChecksumsSources();
658 }
659 return providedChecksumsSources;
660 }
661
662 protected Map<String, ProvidedChecksumsSource> createProvidedChecksumsSources() {
663 HashMap<String, ProvidedChecksumsSource> result = new HashMap<>();
664 result.put(
665 TrustedToProvidedChecksumsSourceAdapter.NAME,
666 new TrustedToProvidedChecksumsSourceAdapter(getTrustedChecksumsSources()));
667 return result;
668 }
669
670 private Map<String, ChecksumExtractorStrategy> checksumExtractorStrategies;
671
672 public final Map<String, ChecksumExtractorStrategy> getChecksumExtractorStrategies() {
673 checkClosed();
674 if (checksumExtractorStrategies == null) {
675 checksumExtractorStrategies = createChecksumExtractorStrategies();
676 }
677 return checksumExtractorStrategies;
678 }
679
680 protected Map<String, ChecksumExtractorStrategy> createChecksumExtractorStrategies() {
681 HashMap<String, ChecksumExtractorStrategy> result = new HashMap<>();
682 result.put(XChecksumExtractor.NAME, new XChecksumExtractor());
683 result.put(Nx2ChecksumExtractor.NAME, new Nx2ChecksumExtractor());
684 return result;
685 }
686
687 private ChecksumExtractor checksumExtractor;
688
689 public final ChecksumExtractor getChecksumExtractor() {
690 checkClosed();
691 if (checksumExtractor == null) {
692 checksumExtractor = createChecksumExtractor();
693 }
694 return checksumExtractor;
695 }
696
697 protected ChecksumExtractor createChecksumExtractor() {
698 return new DefaultChecksumExtractor(getChecksumExtractorStrategies());
699 }
700
701 private Map<String, TransporterFactory> transporterFactories;
702
703 public final Map<String, TransporterFactory> getTransporterFactories() {
704 checkClosed();
705 if (transporterFactories == null) {
706 transporterFactories = createTransporterFactories();
707 }
708 return transporterFactories;
709 }
710
711 protected Map<String, TransporterFactory> createTransporterFactories() {
712 HashMap<String, TransporterFactory> result = new HashMap<>();
713 result.put(FileTransporterFactory.NAME, new FileTransporterFactory());
714 result.put(
715 ApacheTransporterFactory.NAME,
716 new ApacheTransporterFactory(getChecksumExtractor(), getPathProcessor()));
717 return result;
718 }
719
720 private TransporterProvider transporterProvider;
721
722 public final TransporterProvider getTransporterProvider() {
723 checkClosed();
724 if (transporterProvider == null) {
725 transporterProvider = createTransporterProvider();
726 }
727 return transporterProvider;
728 }
729
730 protected TransporterProvider createTransporterProvider() {
731 return new DefaultTransporterProvider(getTransporterFactories());
732 }
733
734 private BasicRepositoryConnectorFactory basicRepositoryConnectorFactory;
735
736 public final BasicRepositoryConnectorFactory getBasicRepositoryConnectorFactory() {
737 checkClosed();
738 if (basicRepositoryConnectorFactory == null) {
739 basicRepositoryConnectorFactory = createBasicRepositoryConnectorFactory();
740 }
741 return basicRepositoryConnectorFactory;
742 }
743
744 protected BasicRepositoryConnectorFactory createBasicRepositoryConnectorFactory() {
745 return new BasicRepositoryConnectorFactory(
746 getTransporterProvider(),
747 getRepositoryLayoutProvider(),
748 getChecksumPolicyProvider(),
749 getPathProcessor(),
750 getChecksumProcessor(),
751 getProvidedChecksumsSources());
752 }
753
754 private Map<String, RepositoryConnectorFactory> repositoryConnectorFactories;
755
756 public final Map<String, RepositoryConnectorFactory> getRepositoryConnectorFactories() {
757 checkClosed();
758 if (repositoryConnectorFactories == null) {
759 repositoryConnectorFactories = createRepositoryConnectorFactories();
760 }
761 return repositoryConnectorFactories;
762 }
763
764 protected Map<String, RepositoryConnectorFactory> createRepositoryConnectorFactories() {
765 HashMap<String, RepositoryConnectorFactory> result = new HashMap<>();
766 result.put(BasicRepositoryConnectorFactory.NAME, getBasicRepositoryConnectorFactory());
767 return result;
768 }
769
770 private Map<String, PipelineRepositoryConnectorFactory> pipelineRepositoryConnectorFactories;
771
772 public final Map<String, PipelineRepositoryConnectorFactory> getPipelineRepositoryConnectorFactories() {
773 checkClosed();
774 if (pipelineRepositoryConnectorFactories == null) {
775 pipelineRepositoryConnectorFactories = createPipelineRepositoryConnectorFactories();
776 }
777 return pipelineRepositoryConnectorFactories;
778 }
779
780 protected Map<String, PipelineRepositoryConnectorFactory> createPipelineRepositoryConnectorFactories() {
781 HashMap<String, PipelineRepositoryConnectorFactory> result = new HashMap<>();
782 result.put(
783 FilteringPipelineRepositoryConnectorFactory.NAME,
784 new FilteringPipelineRepositoryConnectorFactory(getRemoteRepositoryFilterManager()));
785 result.put(
786 OfflinePipelineRepositoryConnectorFactory.NAME,
787 new OfflinePipelineRepositoryConnectorFactory(getOfflineController()));
788 return result;
789 }
790
791 private RepositoryConnectorProvider repositoryConnectorProvider;
792
793 public final RepositoryConnectorProvider getRepositoryConnectorProvider() {
794 checkClosed();
795 if (repositoryConnectorProvider == null) {
796 repositoryConnectorProvider = createRepositoryConnectorProvider();
797 }
798 return repositoryConnectorProvider;
799 }
800
801 protected RepositoryConnectorProvider createRepositoryConnectorProvider() {
802 return new DefaultRepositoryConnectorProvider(
803 getRepositoryConnectorFactories(), getPipelineRepositoryConnectorFactories());
804 }
805
806 private Installer installer;
807
808 public final Installer getInstaller() {
809 checkClosed();
810 if (installer == null) {
811 installer = createInstaller();
812 }
813 return installer;
814 }
815
816 protected Installer createInstaller() {
817 return new DefaultInstaller(
818 getPathProcessor(),
819 getRepositoryEventDispatcher(),
820 getArtifactGeneratorFactories(),
821 getMetadataGeneratorFactories(),
822 getArtifactTransformers(),
823 getSyncContextFactory());
824 }
825
826 private Deployer deployer;
827
828 public final Deployer getDeployer() {
829 checkClosed();
830 if (deployer == null) {
831 deployer = createDeployer();
832 }
833 return deployer;
834 }
835
836 protected Deployer createDeployer() {
837 return new DefaultDeployer(
838 getPathProcessor(),
839 getRepositoryEventDispatcher(),
840 getRepositoryConnectorProvider(),
841 getRemoteRepositoryManager(),
842 getUpdateCheckManager(),
843 getArtifactGeneratorFactories(),
844 getMetadataGeneratorFactories(),
845 getArtifactTransformers(),
846 getSyncContextFactory(),
847 getOfflineController());
848 }
849
850 private Map<String, DependencyCollectorDelegate> dependencyCollectorDelegates;
851
852 public final Map<String, DependencyCollectorDelegate> getDependencyCollectorDelegates() {
853 checkClosed();
854 if (dependencyCollectorDelegates == null) {
855 dependencyCollectorDelegates = createDependencyCollectorDelegates();
856 }
857 return dependencyCollectorDelegates;
858 }
859
860 protected Map<String, DependencyCollectorDelegate> createDependencyCollectorDelegates() {
861 RemoteRepositoryManager remoteRepositoryManager = getRemoteRepositoryManager();
862 ArtifactDescriptorReader artifactDescriptorReader = getArtifactDescriptorReader();
863 VersionRangeResolver versionRangeResolver = getVersionRangeResolver();
864 HashMap<String, DependencyCollectorDelegate> result = new HashMap<>();
865 result.put(
866 DfDependencyCollector.NAME,
867 new DfDependencyCollector(
868 remoteRepositoryManager,
869 artifactDescriptorReader,
870 versionRangeResolver,
871 getArtifactDecoratorFactories()));
872 result.put(
873 BfDependencyCollector.NAME,
874 new BfDependencyCollector(
875 remoteRepositoryManager,
876 artifactDescriptorReader,
877 versionRangeResolver,
878 getArtifactDecoratorFactories()));
879 return result;
880 }
881
882 private DependencyCollector dependencyCollector;
883
884 public final DependencyCollector getDependencyCollector() {
885 checkClosed();
886 if (dependencyCollector == null) {
887 dependencyCollector = createDependencyCollector();
888 }
889 return dependencyCollector;
890 }
891
892 protected DependencyCollector createDependencyCollector() {
893 return new DefaultDependencyCollector(getDependencyCollectorDelegates());
894 }
895
896 private Map<String, ArtifactResolverPostProcessor> artifactResolverPostProcessors;
897
898 public final Map<String, ArtifactResolverPostProcessor> getArtifactResolverPostProcessors() {
899 checkClosed();
900 if (artifactResolverPostProcessors == null) {
901 artifactResolverPostProcessors = createArtifactResolverPostProcessors();
902 }
903 return artifactResolverPostProcessors;
904 }
905
906 protected Map<String, ArtifactResolverPostProcessor> createArtifactResolverPostProcessors() {
907 HashMap<String, ArtifactResolverPostProcessor> result = new HashMap<>();
908 result.put(
909 TrustedChecksumsArtifactResolverPostProcessor.NAME,
910 new TrustedChecksumsArtifactResolverPostProcessor(
911 getChecksumAlgorithmFactorySelector(), getTrustedChecksumsSources()));
912 return result;
913 }
914
915 private ArtifactResolver artifactResolver;
916
917 public final ArtifactResolver getArtifactResolver() {
918 checkClosed();
919 if (artifactResolver == null) {
920 artifactResolver = createArtifactResolver();
921 }
922 return artifactResolver;
923 }
924
925 protected ArtifactResolver createArtifactResolver() {
926 return new DefaultArtifactResolver(
927 getPathProcessor(),
928 getRepositoryEventDispatcher(),
929 getVersionResolver(),
930 getUpdateCheckManager(),
931 getRepositoryConnectorProvider(),
932 getRemoteRepositoryManager(),
933 getSyncContextFactory(),
934 getOfflineController(),
935 getArtifactResolverPostProcessors(),
936 getRemoteRepositoryFilterManager());
937 }
938
939 private MetadataResolver metadataResolver;
940
941 public final MetadataResolver getMetadataResolver() {
942 checkClosed();
943 if (metadataResolver == null) {
944 metadataResolver = createMetadataResolver();
945 }
946 return metadataResolver;
947 }
948
949 protected MetadataResolver createMetadataResolver() {
950 return new DefaultMetadataResolver(
951 getRepositoryEventDispatcher(),
952 getUpdateCheckManager(),
953 getRepositoryConnectorProvider(),
954 getRemoteRepositoryManager(),
955 getSyncContextFactory(),
956 getOfflineController(),
957 getRemoteRepositoryFilterManager(),
958 getPathProcessor());
959 }
960
961 private VersionScheme versionScheme;
962
963 public final VersionScheme getVersionScheme() {
964 checkClosed();
965 if (versionScheme == null) {
966 versionScheme = createVersionScheme();
967 }
968 return versionScheme;
969 }
970
971 protected VersionScheme createVersionScheme() {
972 return new GenericVersionScheme();
973 }
974
975 private Map<String, ArtifactGeneratorFactory> artifactGeneratorFactories;
976
977 public final Map<String, ArtifactGeneratorFactory> getArtifactGeneratorFactories() {
978 checkClosed();
979 if (artifactGeneratorFactories == null) {
980 artifactGeneratorFactories = createArtifactGeneratorFactories();
981 }
982 return artifactGeneratorFactories;
983 }
984
985 protected Map<String, ArtifactGeneratorFactory> createArtifactGeneratorFactories() {
986
987 return new HashMap<>();
988 }
989
990 private Map<String, ArtifactDecoratorFactory> artifactDecoratorFactories;
991
992 public final Map<String, ArtifactDecoratorFactory> getArtifactDecoratorFactories() {
993 checkClosed();
994 if (artifactDecoratorFactories == null) {
995 artifactDecoratorFactories = createArtifactDecoratorFactories();
996 }
997 return artifactDecoratorFactories;
998 }
999
1000 protected Map<String, ArtifactDecoratorFactory> createArtifactDecoratorFactories() {
1001
1002 return new HashMap<>();
1003 }
1004
1005
1006
1007 private Map<String, ArtifactTransformer> artifactTransformers;
1008
1009 public final Map<String, ArtifactTransformer> getArtifactTransformers() {
1010 checkClosed();
1011 if (artifactTransformers == null) {
1012 artifactTransformers = createArtifactTransformers();
1013 }
1014 return artifactTransformers;
1015 }
1016
1017 protected Map<String, ArtifactTransformer> createArtifactTransformers() {
1018 return new HashMap<>();
1019 }
1020
1021 private Map<String, MetadataGeneratorFactory> metadataGeneratorFactories;
1022
1023 public final Map<String, MetadataGeneratorFactory> getMetadataGeneratorFactories() {
1024 checkClosed();
1025 if (metadataGeneratorFactories == null) {
1026 metadataGeneratorFactories = createMetadataGeneratorFactories();
1027 }
1028 return metadataGeneratorFactories;
1029 }
1030
1031 protected Map<String, MetadataGeneratorFactory> createMetadataGeneratorFactories() {
1032
1033 HashMap<String, MetadataGeneratorFactory> result = new HashMap<>();
1034 result.put(PluginsMetadataGeneratorFactory.NAME, new PluginsMetadataGeneratorFactory());
1035 result.put(VersionsMetadataGeneratorFactory.NAME, new VersionsMetadataGeneratorFactory());
1036 result.put(SnapshotMetadataGeneratorFactory.NAME, new SnapshotMetadataGeneratorFactory());
1037 return result;
1038 }
1039
1040 private LinkedHashMap<String, MavenArtifactRelocationSource> artifactRelocationSources;
1041
1042 public final LinkedHashMap<String, MavenArtifactRelocationSource> getMavenArtifactRelocationSources() {
1043 checkClosed();
1044 if (artifactRelocationSources == null) {
1045 artifactRelocationSources = createMavenArtifactRelocationSources();
1046 }
1047 return artifactRelocationSources;
1048 }
1049
1050 protected LinkedHashMap<String, MavenArtifactRelocationSource> createMavenArtifactRelocationSources() {
1051
1052 LinkedHashMap<String, MavenArtifactRelocationSource> result = new LinkedHashMap<>();
1053 result.put(UserPropertiesArtifactRelocationSource.NAME, new UserPropertiesArtifactRelocationSource());
1054 result.put(
1055 DistributionManagementArtifactRelocationSource.NAME,
1056 new DistributionManagementArtifactRelocationSource());
1057 return result;
1058 }
1059
1060 private ArtifactDescriptorReader artifactDescriptorReader;
1061
1062 public final ArtifactDescriptorReader getArtifactDescriptorReader() {
1063 checkClosed();
1064 if (artifactDescriptorReader == null) {
1065 artifactDescriptorReader = createArtifactDescriptorReader();
1066 }
1067 return artifactDescriptorReader;
1068 }
1069
1070 protected ArtifactDescriptorReader createArtifactDescriptorReader() {
1071
1072 return new DefaultArtifactDescriptorReader(
1073 getRemoteRepositoryManager(),
1074 getVersionResolver(),
1075 getVersionRangeResolver(),
1076 getArtifactResolver(),
1077 getModelBuilder(),
1078 getRepositoryEventDispatcher(),
1079 getModelCacheFactory(),
1080 getMavenArtifactRelocationSources());
1081 }
1082
1083 private VersionResolver versionResolver;
1084
1085 public final VersionResolver getVersionResolver() {
1086 checkClosed();
1087 if (versionResolver == null) {
1088 versionResolver = createVersionResolver();
1089 }
1090 return versionResolver;
1091 }
1092
1093 protected VersionResolver createVersionResolver() {
1094
1095 return new DefaultVersionResolver(
1096 getMetadataResolver(), getSyncContextFactory(), getRepositoryEventDispatcher());
1097 }
1098
1099 private VersionRangeResolver versionRangeResolver;
1100
1101 public final VersionRangeResolver getVersionRangeResolver() {
1102 checkClosed();
1103 if (versionRangeResolver == null) {
1104 versionRangeResolver = createVersionRangeResolver();
1105 }
1106 return versionRangeResolver;
1107 }
1108
1109 protected VersionRangeResolver createVersionRangeResolver() {
1110
1111 return new DefaultVersionRangeResolver(
1112 getMetadataResolver(), getSyncContextFactory(), getRepositoryEventDispatcher(), getVersionScheme());
1113 }
1114
1115 private ModelBuilder modelBuilder;
1116
1117 public final ModelBuilder getModelBuilder() {
1118 checkClosed();
1119 if (modelBuilder == null) {
1120 modelBuilder = createModelBuilder();
1121 }
1122 return modelBuilder;
1123 }
1124
1125 protected ModelBuilder createModelBuilder() {
1126
1127 return new DefaultModelBuilderFactory().newInstance();
1128 }
1129
1130 private ModelCacheFactory modelCacheFactory;
1131
1132 public final ModelCacheFactory getModelCacheFactory() {
1133 checkClosed();
1134 if (modelCacheFactory == null) {
1135 modelCacheFactory = createModelCacheFactory();
1136 }
1137 return modelCacheFactory;
1138 }
1139
1140 protected ModelCacheFactory createModelCacheFactory() {
1141
1142 return new DefaultModelCacheFactory();
1143 }
1144
1145 private List<ValidatorFactory> validatorFactories;
1146
1147 public final List<ValidatorFactory> getValidatorFactories() {
1148 checkClosed();
1149 if (validatorFactories == null) {
1150 validatorFactories = createValidatorFactories();
1151 }
1152 return validatorFactories;
1153 }
1154
1155 protected List<ValidatorFactory> createValidatorFactories() {
1156 return new ArrayList<>();
1157 }
1158
1159 private RepositorySystemValidator repositorySystemValidator;
1160
1161 public final RepositorySystemValidator getRepositorySystemValidator() {
1162 checkClosed();
1163 if (repositorySystemValidator == null) {
1164 repositorySystemValidator = createRepositorySystemValidator();
1165 }
1166 return repositorySystemValidator;
1167 }
1168
1169 protected RepositorySystemValidator createRepositorySystemValidator() {
1170 return new DefaultRepositorySystemValidator(getValidatorFactories());
1171 }
1172
1173 private RepositorySystem repositorySystem;
1174
1175 public final RepositorySystem getRepositorySystem() {
1176 checkClosed();
1177 if (repositorySystem == null) {
1178 repositorySystem = createRepositorySystem();
1179 }
1180 return repositorySystem;
1181 }
1182
1183 protected RepositorySystem createRepositorySystem() {
1184 return new DefaultRepositorySystem(
1185 getVersionResolver(),
1186 getVersionRangeResolver(),
1187 getArtifactResolver(),
1188 getMetadataResolver(),
1189 getArtifactDescriptorReader(),
1190 getDependencyCollector(),
1191 getInstaller(),
1192 getDeployer(),
1193 getLocalRepositoryProvider(),
1194 getSyncContextFactory(),
1195 getRemoteRepositoryManager(),
1196 getRepositorySystemLifecycle(),
1197 getArtifactDecoratorFactories(),
1198 getRepositorySystemValidator());
1199 }
1200
1201 @Override
1202 public RepositorySystem get() {
1203 return getRepositorySystem();
1204 }
1205 }