001package org.dcm4che3.net.proxy;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.HashMap;
006import java.util.Iterator;
007import java.util.List;
008import java.util.Map;
009import java.util.ServiceLoader;
010import java.util.TreeMap;
011
012/**
013 * Service that retrieves the Service Provider Implementations of Proxy Manager.
014 * 
015 * @author Amaury Pernette
016 *
017 */
018public class ProxyService {
019
020    public static final String DEFAULT_PROVIDER_NAME = BasicProxyManager.PROVIDER_NAME;
021    public static final String DEFAULT_VERSION = BasicProxyManager.VERSION;
022
023    // Initialize-on-Demand Holder Class Idiom
024    private static class SingletonHolder {
025        private static ProxyService service = new ProxyService();
026    }
027
028    private Map<String, Map<String, ProxyManager>> managersModel;
029
030    private ProxyService() {
031        this.managersModel = new HashMap<String, Map<String, ProxyManager>>();
032        final ServiceLoader<ProxyManager> loader = ServiceLoader.load(ProxyManager.class);
033        // Load managers in internal model
034        final Iterator<ProxyManager> managers = loader.iterator();
035        while (managers.hasNext()) {
036            final ProxyManager proxyManager = managers.next();
037            // Manager provider map
038            final String providerName = proxyManager.getProviderName();
039            if (!this.managersModel.containsKey(providerName)) {
040                this.managersModel.put(providerName, new TreeMap<String, ProxyManager>());
041            }
042            final Map<String, ProxyManager> providerManagers = this.managersModel.get(providerName);
043            // Manager version
044            final String version = proxyManager.getVersion();
045            providerManagers.put(version, proxyManager);
046        }
047    }
048
049    public static synchronized ProxyService getInstance() {
050        return SingletonHolder.service;
051    }
052
053    public ProxyManager getProxyManager(final String managerProviderName, final String managerVersion) {
054        if (managerProviderName != null && !managerProviderName.isEmpty()) {
055            // Get managers for this provider
056            final Map<String, ProxyManager> providerManagers = this.managersModel.get(managerProviderName);
057            if (providerManagers != null && !providerManagers.isEmpty()) {
058                ProxyManager manager = null;
059                if (managerVersion != null && !managerVersion.isEmpty()) {
060                    // Get specific version
061                    manager = providerManagers.get(managerVersion);
062                } else {
063                    // If no specified version : get the last available
064                    final List<String> versions = new ArrayList<String>(providerManagers.keySet());
065                    Collections.reverse(versions);
066                    manager = providerManagers.get(versions.get(0));
067                }
068                return manager;
069            }
070        }
071        return getDefaultProxyManager();
072    }
073
074    public ProxyManager getDefaultProxyManager() {
075        return getProxyManager(DEFAULT_PROVIDER_NAME, DEFAULT_VERSION);
076    }
077
078    public List<String> getAvailableProviders() {
079        return new ArrayList<String>(this.managersModel.keySet());
080    }
081
082    public List<String> getAvailableVersionsFor(final String provider) {
083        final List<String> versions = new ArrayList<String>();
084        if (this.managersModel.containsKey(provider)) {
085            versions.addAll(this.managersModel.get(provider).keySet());
086        }
087        return versions;
088    }
089}