001package org.eclipse.aether.internal.impl.synccontext;
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.HashMap;
023import java.util.Map;
024import java.util.concurrent.TimeUnit;
025
026import javax.inject.Inject;
027import javax.inject.Named;
028import javax.inject.Singleton;
029
030import org.eclipse.aether.internal.impl.synccontext.named.DiscriminatingNameMapper;
031import org.eclipse.aether.internal.impl.synccontext.named.GAVNameMapper;
032import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
033import org.eclipse.aether.internal.impl.synccontext.named.StaticNameMapper;
034import org.eclipse.aether.named.NamedLockFactory;
035import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory;
036import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory;
037import org.eclipse.aether.named.providers.NoopNamedLockFactory;
038
039/**
040 * Selector for {@link NamedLockFactory} and {@link NameMapper} that selects and exposes selected ones. Essentially
041 * all the named locks configuration is here.
042 */
043@Singleton
044@Named
045public final class NamedLockFactorySelector
046{
047    public static final long TIME = Long.getLong(
048        "aether.syncContext.named.time", 30L
049    );
050
051    public static final TimeUnit TIME_UNIT = TimeUnit.valueOf( System.getProperty(
052        "aether.syncContext.named.time.unit", TimeUnit.SECONDS.name()
053    ) );
054
055    private static final String FACTORY_NAME = System.getProperty(
056        "aether.syncContext.named.factory", LocalReadWriteLockNamedLockFactory.NAME
057    );
058
059    private static final String NAME_MAPPER_NAME = System.getProperty(
060        "aether.syncContext.named.nameMapper", GAVNameMapper.NAME
061    );
062
063    private final NamedLockFactory namedLockFactory;
064
065    private final NameMapper nameMapper;
066
067    /**
068     * Constructor used with DI, where factories are injected and selected based on key.
069     */
070    @Inject
071    public NamedLockFactorySelector( final Map<String, NamedLockFactory> factories,
072                                     final Map<String, NameMapper> nameMappers )
073    {
074        this.namedLockFactory = selectNamedLockFactory( factories );
075        this.nameMapper = selectNameMapper( nameMappers );
076    }
077
078    /**
079     * Default constructor for ServiceLocator.
080     */
081    public NamedLockFactorySelector()
082    {
083        Map<String, NamedLockFactory> factories = new HashMap<>();
084        factories.put( NoopNamedLockFactory.NAME, new NoopNamedLockFactory() );
085        factories.put( LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory() );
086        factories.put( LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory() );
087        this.namedLockFactory = selectNamedLockFactory( factories );
088
089        Map<String, NameMapper> nameMappers = new HashMap<>();
090        nameMappers.put( StaticNameMapper.NAME, new StaticNameMapper() );
091        nameMappers.put( GAVNameMapper.NAME, new GAVNameMapper() );
092        nameMappers.put( DiscriminatingNameMapper.NAME, new DiscriminatingNameMapper( new GAVNameMapper() ) );
093        this.nameMapper = selectNameMapper( nameMappers );
094    }
095
096    /**
097     * Returns the selected {@link NamedLockFactory}, never null.
098     */
099    public NamedLockFactory getSelectedNamedLockFactory()
100    {
101        return namedLockFactory;
102    }
103
104    /**
105     * Returns the selected {@link NameMapper}, never null.
106     */
107    public NameMapper getSelectedNameMapper()
108    {
109        return nameMapper;
110    }
111
112    private static NamedLockFactory selectNamedLockFactory( final Map<String, NamedLockFactory> factories )
113    {
114        NamedLockFactory factory = factories.get( FACTORY_NAME );
115        if ( factory == null )
116        {
117            throw new IllegalArgumentException( "Unknown NamedLockFactory name: " + FACTORY_NAME
118                + ", known ones: " + factories.keySet() );
119        }
120        return factory;
121    }
122
123    private static NameMapper selectNameMapper( final Map<String, NameMapper> nameMappers )
124    {
125        NameMapper nameMapper = nameMappers.get( NAME_MAPPER_NAME );
126        if ( nameMapper == null )
127        {
128            throw new IllegalArgumentException( "Unknown NameMapper name: " + NAME_MAPPER_NAME
129                + ", known ones: " + nameMappers.keySet() );
130        }
131        return nameMapper;
132    }
133}