001package org.eclipse.aether.impl.guice;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.Collections;
023import java.util.HashMap;
024import java.util.HashSet;
025import java.util.Map;
026import java.util.Set;
027
028import javax.inject.Named;
029import javax.inject.Singleton;
030
031import org.eclipse.aether.RepositoryListener;
032import org.eclipse.aether.RepositorySystem;
033import org.eclipse.aether.impl.ArtifactResolver;
034import org.eclipse.aether.impl.DependencyCollector;
035import org.eclipse.aether.impl.Deployer;
036import org.eclipse.aether.impl.Installer;
037import org.eclipse.aether.impl.LocalRepositoryProvider;
038import org.eclipse.aether.impl.MetadataResolver;
039import org.eclipse.aether.impl.OfflineController;
040import org.eclipse.aether.impl.RemoteRepositoryFilterManager;
041import org.eclipse.aether.impl.RemoteRepositoryManager;
042import org.eclipse.aether.impl.RepositoryConnectorProvider;
043import org.eclipse.aether.impl.RepositoryEventDispatcher;
044import org.eclipse.aether.impl.RepositorySystemLifecycle;
045import org.eclipse.aether.internal.impl.DefaultLocalPathPrefixComposerFactory;
046import org.eclipse.aether.internal.impl.DefaultRepositorySystemLifecycle;
047import org.eclipse.aether.internal.impl.LocalPathComposer;
048import org.eclipse.aether.internal.impl.DefaultLocalPathComposer;
049import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
050import org.eclipse.aether.internal.impl.LocalPathPrefixComposerFactory;
051import org.eclipse.aether.internal.impl.TrackingFileManager;
052import org.eclipse.aether.internal.impl.checksum.SummaryFileTrustedChecksumsSource;
053import org.eclipse.aether.internal.impl.checksum.Md5ChecksumAlgorithmFactory;
054import org.eclipse.aether.internal.impl.checksum.Sha1ChecksumAlgorithmFactory;
055import org.eclipse.aether.internal.impl.checksum.Sha256ChecksumAlgorithmFactory;
056import org.eclipse.aether.internal.impl.checksum.Sha512ChecksumAlgorithmFactory;
057import org.eclipse.aether.internal.impl.checksum.DefaultChecksumAlgorithmFactorySelector;
058import org.eclipse.aether.internal.impl.checksum.SparseDirectoryTrustedChecksumsSource;
059import org.eclipse.aether.internal.impl.checksum.TrustedToProvidedChecksumsSourceAdapter;
060import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate;
061import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector;
062import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector;
063import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager;
064import org.eclipse.aether.internal.impl.filter.GroupIdRemoteRepositoryFilterSource;
065import org.eclipse.aether.internal.impl.filter.PrefixesRemoteRepositoryFilterSource;
066import org.eclipse.aether.internal.impl.resolution.TrustedChecksumsArtifactResolverPostProcessor;
067import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
068import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
069import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
070import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory;
071import org.eclipse.aether.internal.impl.synccontext.named.providers.DiscriminatingNameMapperProvider;
072import org.eclipse.aether.internal.impl.synccontext.named.providers.FileGAVNameMapperProvider;
073import org.eclipse.aether.internal.impl.synccontext.named.providers.FileHashingGAVNameMapperProvider;
074import org.eclipse.aether.internal.impl.synccontext.named.providers.GAVNameMapperProvider;
075import org.eclipse.aether.internal.impl.synccontext.named.providers.StaticNameMapperProvider;
076import org.eclipse.aether.named.NamedLockFactory;
077import org.eclipse.aether.named.providers.FileLockNamedLockFactory;
078import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory;
079import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory;
080import org.eclipse.aether.impl.UpdateCheckManager;
081import org.eclipse.aether.impl.UpdatePolicyAnalyzer;
082import org.eclipse.aether.internal.impl.DefaultArtifactResolver;
083import org.eclipse.aether.internal.impl.DefaultChecksumPolicyProvider;
084import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector;
085import org.eclipse.aether.internal.impl.DefaultDeployer;
086import org.eclipse.aether.internal.impl.DefaultFileProcessor;
087import org.eclipse.aether.internal.impl.DefaultInstaller;
088import org.eclipse.aether.internal.impl.DefaultLocalRepositoryProvider;
089import org.eclipse.aether.internal.impl.DefaultMetadataResolver;
090import org.eclipse.aether.internal.impl.DefaultOfflineController;
091import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager;
092import org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider;
093import org.eclipse.aether.internal.impl.DefaultRepositoryEventDispatcher;
094import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider;
095import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
096import org.eclipse.aether.internal.impl.DefaultTransporterProvider;
097import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager;
098import org.eclipse.aether.internal.impl.DefaultUpdatePolicyAnalyzer;
099import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory;
100import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
101import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
102import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory;
103import org.eclipse.aether.named.providers.NoopNamedLockFactory;
104import org.eclipse.aether.spi.checksums.TrustedChecksumsSource;
105import org.eclipse.aether.spi.connector.checksum.ProvidedChecksumsSource;
106import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
107import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
108import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
109import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
110import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
111import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
112import org.eclipse.aether.spi.connector.transport.TransporterProvider;
113import org.eclipse.aether.spi.io.FileProcessor;
114import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
115import org.eclipse.aether.spi.log.LoggerFactory;
116import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor;
117import org.eclipse.aether.spi.synccontext.SyncContextFactory;
118import org.slf4j.ILoggerFactory;
119
120import com.google.inject.AbstractModule;
121import com.google.inject.Provides;
122import com.google.inject.name.Names;
123
124/**
125 * A ready-made <a href="https://github.com/google/guice" target="_blank">Guice</a> module that sets up bindings
126 * for all components from this library. To acquire a complete repository system, clients need to bind an artifact
127 * descriptor reader, a version resolver, a version range resolver, zero or more metadata generator factories, some
128 * repository connector and transporter factories to access remote repositories.
129 *
130 * @noextend This class must not be extended by clients and will eventually be marked {@code final} without prior
131 * notice.
132 */
133public class AetherModule
134        extends AbstractModule
135{
136
137    /**
138     * Creates a new instance of this Guice module, typically for invoking
139     * {@link com.google.inject.Binder#install(com.google.inject.Module)}.
140     */
141    public AetherModule()
142    {
143    }
144
145    /**
146     * Configures Guice with bindings for Aether components provided by this library.
147     */
148    @Override
149    protected void configure()
150    {
151        bind( RepositorySystem.class ) //
152                .to( DefaultRepositorySystem.class ).in( Singleton.class );
153        bind( ArtifactResolver.class ) //
154                .to( DefaultArtifactResolver.class ).in( Singleton.class );
155
156        bind( DependencyCollector.class ) //
157                .to( DefaultDependencyCollector.class ).in( Singleton.class );
158        bind( DependencyCollectorDelegate.class ).annotatedWith( Names.named( BfDependencyCollector.NAME ) )
159                .to( BfDependencyCollector.class ).in( Singleton.class );
160        bind( DependencyCollectorDelegate.class ).annotatedWith( Names.named( DfDependencyCollector.NAME ) )
161                .to( DfDependencyCollector.class ).in( Singleton.class );
162
163        bind( Deployer.class ) //
164                .to( DefaultDeployer.class ).in( Singleton.class );
165        bind( Installer.class ) //
166                .to( DefaultInstaller.class ).in( Singleton.class );
167        bind( MetadataResolver.class ) //
168                .to( DefaultMetadataResolver.class ).in( Singleton.class );
169        bind( RepositoryLayoutProvider.class ) //
170                .to( DefaultRepositoryLayoutProvider.class ).in( Singleton.class );
171        bind( RepositoryLayoutFactory.class ).annotatedWith( Names.named( "maven2" ) ) //
172                .to( Maven2RepositoryLayoutFactory.class ).in( Singleton.class );
173        bind( TransporterProvider.class ) //
174                .to( DefaultTransporterProvider.class ).in( Singleton.class );
175        bind( ChecksumPolicyProvider.class ) //
176                .to( DefaultChecksumPolicyProvider.class ).in( Singleton.class );
177        bind( RepositoryConnectorProvider.class ) //
178                .to( DefaultRepositoryConnectorProvider.class ).in( Singleton.class );
179        bind( RemoteRepositoryManager.class ) //
180                .to( DefaultRemoteRepositoryManager.class ).in( Singleton.class );
181        bind( UpdateCheckManager.class ) //
182                .to( DefaultUpdateCheckManager.class ).in( Singleton.class );
183        bind( UpdatePolicyAnalyzer.class ) //
184                .to( DefaultUpdatePolicyAnalyzer.class ).in( Singleton.class );
185        bind( FileProcessor.class ) //
186                .to( DefaultFileProcessor.class ).in( Singleton.class );
187        bind( RepositoryEventDispatcher.class ) //
188                .to( DefaultRepositoryEventDispatcher.class ).in( Singleton.class );
189        bind( OfflineController.class ) //
190                .to( DefaultOfflineController.class ).in( Singleton.class );
191
192        bind( LocalPathComposer.class )
193                .to( DefaultLocalPathComposer.class ).in( Singleton.class );
194        bind( LocalPathPrefixComposerFactory.class )
195                .to( DefaultLocalPathPrefixComposerFactory.class ).in( Singleton.class );
196
197        bind( LocalRepositoryProvider.class ) //
198                .to( DefaultLocalRepositoryProvider.class ).in( Singleton.class );
199        bind( LocalRepositoryManagerFactory.class ).annotatedWith( Names.named( "simple" ) ) //
200                .to( SimpleLocalRepositoryManagerFactory.class ).in( Singleton.class );
201        bind( LocalRepositoryManagerFactory.class ).annotatedWith( Names.named( "enhanced" ) ) //
202                .to( EnhancedLocalRepositoryManagerFactory.class ).in( Singleton.class );
203        bind( TrackingFileManager.class ).to( DefaultTrackingFileManager.class ).in( Singleton.class );
204
205        bind( ProvidedChecksumsSource.class )
206                .annotatedWith( Names.named( TrustedToProvidedChecksumsSourceAdapter.NAME ) )
207                .to( TrustedToProvidedChecksumsSourceAdapter.class ).in( Singleton.class );
208
209        bind( TrustedChecksumsSource.class ).annotatedWith( Names.named( SparseDirectoryTrustedChecksumsSource.NAME ) )
210                .to( SparseDirectoryTrustedChecksumsSource.class ).in( Singleton.class );
211        bind( TrustedChecksumsSource.class ).annotatedWith( Names.named( SummaryFileTrustedChecksumsSource.NAME ) )
212                .to( SummaryFileTrustedChecksumsSource.class ).in( Singleton.class );
213
214        bind( ArtifactResolverPostProcessor.class )
215                .annotatedWith( Names.named( TrustedChecksumsArtifactResolverPostProcessor.NAME ) )
216                .to( TrustedChecksumsArtifactResolverPostProcessor.class ).in( Singleton.class );
217
218        bind( ChecksumAlgorithmFactory.class ).annotatedWith( Names.named( Md5ChecksumAlgorithmFactory.NAME ) )
219                .to( Md5ChecksumAlgorithmFactory.class );
220        bind( ChecksumAlgorithmFactory.class ).annotatedWith( Names.named( Sha1ChecksumAlgorithmFactory.NAME ) )
221                .to( Sha1ChecksumAlgorithmFactory.class );
222        bind( ChecksumAlgorithmFactory.class ).annotatedWith( Names.named( Sha256ChecksumAlgorithmFactory.NAME ) )
223                .to( Sha256ChecksumAlgorithmFactory.class );
224        bind( ChecksumAlgorithmFactory.class ).annotatedWith( Names.named( Sha512ChecksumAlgorithmFactory.NAME ) )
225                .to( Sha512ChecksumAlgorithmFactory.class );
226        bind( ChecksumAlgorithmFactorySelector.class )
227                .to( DefaultChecksumAlgorithmFactorySelector.class ).in ( Singleton.class );
228
229        bind( RepositorySystemLifecycle.class )
230                .to( DefaultRepositorySystemLifecycle.class ).in( Singleton.class );
231
232        bind( NamedLockFactoryAdapterFactory.class )
233                .to( NamedLockFactoryAdapterFactoryImpl.class ).in( Singleton.class );
234        bind( SyncContextFactory.class ).to( DefaultSyncContextFactory.class ).in( Singleton.class );
235        bind( org.eclipse.aether.impl.SyncContextFactory.class )
236                .to( org.eclipse.aether.internal.impl.synccontext.legacy.DefaultSyncContextFactory.class )
237                .in( Singleton.class );
238
239        bind( NameMapper.class ).annotatedWith( Names.named( StaticNameMapperProvider.NAME ) )
240                .toProvider( StaticNameMapperProvider.class ).in( Singleton.class );
241        bind( NameMapper.class ).annotatedWith( Names.named( GAVNameMapperProvider.NAME ) )
242                .toProvider( GAVNameMapperProvider.class ).in( Singleton.class );
243        bind( NameMapper.class ).annotatedWith( Names.named( DiscriminatingNameMapperProvider.NAME ) )
244                .toProvider( DiscriminatingNameMapperProvider.class ).in( Singleton.class );
245        bind( NameMapper.class ).annotatedWith( Names.named( FileGAVNameMapperProvider.NAME ) )
246                .toProvider( FileGAVNameMapperProvider.class ).in( Singleton.class );
247        bind( NameMapper.class ).annotatedWith( Names.named( FileHashingGAVNameMapperProvider.NAME ) )
248                .toProvider( FileHashingGAVNameMapperProvider.class ).in( Singleton.class );
249
250        bind( NamedLockFactory.class ).annotatedWith( Names.named( NoopNamedLockFactory.NAME ) )
251                .to( NoopNamedLockFactory.class ).in( Singleton.class );
252        bind( NamedLockFactory.class ).annotatedWith( Names.named( LocalReadWriteLockNamedLockFactory.NAME ) )
253                .to( LocalReadWriteLockNamedLockFactory.class ).in( Singleton.class );
254        bind( NamedLockFactory.class ).annotatedWith( Names.named( LocalSemaphoreNamedLockFactory.NAME ) )
255                .to( LocalSemaphoreNamedLockFactory.class ).in( Singleton.class );
256        bind( NamedLockFactory.class ).annotatedWith( Names.named( FileLockNamedLockFactory.NAME ) )
257                .to( FileLockNamedLockFactory.class ).in( Singleton.class );
258
259        bind( RemoteRepositoryFilterManager.class )
260                .to( DefaultRemoteRepositoryFilterManager.class ).in( Singleton.class );
261        bind( RemoteRepositoryFilterSource.class ).annotatedWith(
262                Names.named( GroupIdRemoteRepositoryFilterSource.NAME ) )
263                .to( GroupIdRemoteRepositoryFilterSource.class ).in( Singleton.class );
264        bind( RemoteRepositoryFilterSource.class ).annotatedWith(
265                Names.named( PrefixesRemoteRepositoryFilterSource.NAME ) )
266                .to( PrefixesRemoteRepositoryFilterSource.class ).in( Singleton.class );
267
268        install( new Slf4jModule() );
269
270    }
271
272    @Provides
273    @Singleton
274    Map<String, RemoteRepositoryFilterSource> remoteRepositoryFilterSources(
275            @Named( GroupIdRemoteRepositoryFilterSource.NAME ) RemoteRepositoryFilterSource groupId,
276            @Named( PrefixesRemoteRepositoryFilterSource.NAME ) RemoteRepositoryFilterSource prefixes
277    )
278    {
279        Map<String, RemoteRepositoryFilterSource> result = new HashMap<>();
280        result.put( GroupIdRemoteRepositoryFilterSource.NAME, groupId );
281        result.put( PrefixesRemoteRepositoryFilterSource.NAME, prefixes );
282        return Collections.unmodifiableMap( result );
283    }
284
285    @Provides
286    @Singleton
287    Map<String, ArtifactResolverPostProcessor> artifactResolverProcessors(
288            @Named( TrustedChecksumsArtifactResolverPostProcessor.NAME ) ArtifactResolverPostProcessor trustedChecksums
289    )
290    {
291        Map<String, ArtifactResolverPostProcessor> result = new HashMap<>();
292        result.put( TrustedChecksumsArtifactResolverPostProcessor.NAME, trustedChecksums );
293        return Collections.unmodifiableMap( result );
294    }
295
296    @Provides
297    @Singleton
298    Map<String, DependencyCollectorDelegate> dependencyCollectorDelegates(
299            @Named( BfDependencyCollector.NAME ) DependencyCollectorDelegate bf,
300            @Named( DfDependencyCollector.NAME ) DependencyCollectorDelegate df
301    )
302    {
303        Map<String, DependencyCollectorDelegate> result = new HashMap<>();
304        result.put( BfDependencyCollector.NAME, bf );
305        result.put( DfDependencyCollector.NAME, df );
306        return Collections.unmodifiableMap( result );
307    }
308
309    @Provides
310    @Singleton
311    Map<String, ProvidedChecksumsSource> providedChecksumSources(
312            @Named( TrustedToProvidedChecksumsSourceAdapter.NAME ) ProvidedChecksumsSource adapter
313    )
314    {
315        Map<String, ProvidedChecksumsSource> result = new HashMap<>();
316        result.put( TrustedToProvidedChecksumsSourceAdapter.NAME, adapter );
317        return Collections.unmodifiableMap( result );
318    }
319
320    @Provides
321    @Singleton
322    Map<String, TrustedChecksumsSource> trustedChecksumSources(
323        @Named( SparseDirectoryTrustedChecksumsSource.NAME ) TrustedChecksumsSource sparse,
324        @Named( SummaryFileTrustedChecksumsSource.NAME ) TrustedChecksumsSource compact
325    )
326    {
327        Map<String, TrustedChecksumsSource> result = new HashMap<>();
328        result.put( SparseDirectoryTrustedChecksumsSource.NAME, sparse );
329        result.put( SummaryFileTrustedChecksumsSource.NAME, compact );
330        return Collections.unmodifiableMap( result );
331    }
332
333    @Provides
334    @Singleton
335    Map<String, ChecksumAlgorithmFactory> provideChecksumTypes(
336            @Named( Sha512ChecksumAlgorithmFactory.NAME ) ChecksumAlgorithmFactory sha512,
337            @Named( Sha256ChecksumAlgorithmFactory.NAME ) ChecksumAlgorithmFactory sha256,
338            @Named( Sha1ChecksumAlgorithmFactory.NAME ) ChecksumAlgorithmFactory sha1,
339            @Named( Md5ChecksumAlgorithmFactory.NAME ) ChecksumAlgorithmFactory md5 )
340    {
341        Map<String, ChecksumAlgorithmFactory> result = new HashMap<>();
342        result.put( Sha512ChecksumAlgorithmFactory.NAME, sha512 );
343        result.put( Sha256ChecksumAlgorithmFactory.NAME, sha256 );
344        result.put( Sha1ChecksumAlgorithmFactory.NAME, sha1 );
345        result.put( Md5ChecksumAlgorithmFactory.NAME, md5 );
346        return Collections.unmodifiableMap( result );
347    }
348
349    @Provides
350    @Singleton
351    Map<String, NameMapper> provideNameMappers(
352            @Named( StaticNameMapperProvider.NAME ) NameMapper staticNameMapper,
353            @Named( GAVNameMapperProvider.NAME ) NameMapper gavNameMapper,
354            @Named( DiscriminatingNameMapperProvider.NAME ) NameMapper discriminatingNameMapper,
355            @Named( FileGAVNameMapperProvider.NAME ) NameMapper fileGavNameMapper,
356            @Named( FileHashingGAVNameMapperProvider.NAME ) NameMapper fileHashingGavNameMapper )
357    {
358        Map<String, NameMapper> result = new HashMap<>();
359        result.put( StaticNameMapperProvider.NAME, staticNameMapper );
360        result.put( GAVNameMapperProvider.NAME, gavNameMapper );
361        result.put( DiscriminatingNameMapperProvider.NAME, discriminatingNameMapper );
362        result.put( FileGAVNameMapperProvider.NAME, fileGavNameMapper );
363        result.put( FileHashingGAVNameMapperProvider.NAME, fileHashingGavNameMapper );
364        return Collections.unmodifiableMap( result );
365    }
366
367    @Provides
368    @Singleton
369    Map<String, NamedLockFactory> provideNamedLockFactories(
370            @Named( LocalReadWriteLockNamedLockFactory.NAME ) NamedLockFactory localRwLock,
371            @Named( LocalSemaphoreNamedLockFactory.NAME ) NamedLockFactory localSemaphore,
372            @Named( FileLockNamedLockFactory.NAME ) NamedLockFactory fileLockFactory )
373    {
374        Map<String, NamedLockFactory> result = new HashMap<>();
375        result.put( LocalReadWriteLockNamedLockFactory.NAME, localRwLock );
376        result.put( LocalSemaphoreNamedLockFactory.NAME, localSemaphore );
377        result.put( FileLockNamedLockFactory.NAME, fileLockFactory );
378        return Collections.unmodifiableMap( result );
379    }
380
381    @Provides
382    @Singleton
383    Set<LocalRepositoryManagerFactory> provideLocalRepositoryManagerFactories(
384            @Named( "simple" ) LocalRepositoryManagerFactory simple,
385            @Named( "enhanced" ) LocalRepositoryManagerFactory enhanced )
386    {
387        Set<LocalRepositoryManagerFactory> result = new HashSet<>();
388        result.add( simple );
389        result.add( enhanced );
390        return Collections.unmodifiableSet( result );
391    }
392
393    @Provides
394    @Singleton
395    Set<RepositoryLayoutFactory> provideRepositoryLayoutFactories( @Named( "maven2" ) RepositoryLayoutFactory maven2 )
396    {
397        Set<RepositoryLayoutFactory> result = new HashSet<>();
398        result.add( maven2 );
399        return Collections.unmodifiableSet( result );
400    }
401
402    @Provides
403    @Singleton
404    Set<RepositoryListener> providesRepositoryListeners()
405    {
406        return Collections.emptySet();
407    }
408
409    private static class Slf4jModule
410            extends AbstractModule
411    {
412
413        @Override
414        protected void configure()
415        {
416            bind( LoggerFactory.class ) //
417                    .to( Slf4jLoggerFactory.class );
418        }
419
420        @Provides
421        @Singleton
422        ILoggerFactory getLoggerFactory()
423        {
424            return org.slf4j.LoggerFactory.getILoggerFactory();
425        }
426
427    }
428
429}