001/*
002 * Copyright (c) 2012, 2013, Credit Suisse (Anatole Tresch), Werner Keil.
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 * 
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 * 
016 * Contributors: Anatole Tresch - initial implementation.
017 */
018package org.javamoney.moneta.convert.internal;
019
020import java.util.ArrayList;
021import java.util.List;
022import java.util.Map;
023import java.util.ServiceLoader;
024import java.util.Set;
025import java.util.concurrent.ConcurrentHashMap;
026
027import javax.money.CurrencyUnit;
028import javax.money.convert.ConversionContext;
029import javax.money.convert.CurrencyConversion;
030import javax.money.convert.ExchangeRateProvider;
031import javax.money.convert.ProviderContext;
032import javax.money.spi.Bootstrap;
033import javax.money.spi.MonetaryConversionsSpi;
034
035import org.javamoney.moneta.spi.CompoundRateProvider;
036
037/**
038 * This is the default implementation of the {@link javax.money.spi.MonetaryConversionsSpi} interface, backing
039 * up the {@link javax.money.convert.MonetaryConversions} singleton.
040 */
041public class DefaultMonetaryConversionsSpi implements MonetaryConversionsSpi {
042    /** The providers loaded. */
043        private Map<String, ExchangeRateProvider> conversionProviders = new ConcurrentHashMap<>();
044
045    /**
046     * Constructors, loads the providers from the {@link javax.money.spi.Bootstrap} component.
047     */
048        public DefaultMonetaryConversionsSpi() {
049                reload();
050        }
051
052    /**
053     * Reloads/reinitializes the providers found.
054     */
055        public void reload() {
056                Map<String, ExchangeRateProvider> newProviders = new ConcurrentHashMap<>();
057                for (ExchangeRateProvider prov : Bootstrap
058                                .getServices(ExchangeRateProvider.class)) {
059                        newProviders.put(prov.getProviderContext().getProviderName(), prov);
060                }
061                this.conversionProviders = newProviders;
062        }
063
064        @Override
065        public ExchangeRateProvider getExchangeRateProvider(String... providers) {
066                List<ExchangeRateProvider> provInstances = new ArrayList<>();
067                for (String provName : providers) {
068                        ExchangeRateProvider prov = this.conversionProviders.get(provName);
069                        if (prov == null) {
070                                throw new IllegalArgumentException(
071                                                "Unsupported conversion/rate provider: " + provName);
072                        }
073                        provInstances.add(prov);
074                }
075                return new CompoundRateProvider(provInstances);
076        }
077
078        @Override
079        public Set<String> getProviderNames() {
080                return this.conversionProviders.keySet();
081        }
082
083        @Override
084        public boolean isProviderAvailable(String provider) {
085                return conversionProviders.containsKey(provider);
086        }
087
088        @Override
089        public CurrencyConversion getConversion(CurrencyUnit termCurrency,
090                        ConversionContext conversionContext, String... providers) {
091                return getExchangeRateProvider(providers).getCurrencyConversion(
092                                termCurrency);
093        }
094
095        @Override
096        public List<String> getDefaultProviderChain() {
097                List<String> stringList = new ArrayList<>();
098                stringList.add("test");
099                return stringList;
100        }
101
102        @Override
103        public ProviderContext getProviderContext(String provider) {
104                ExchangeRateProvider prov = getExchangeRateProvider(provider);
105                return prov.getProviderContext();
106        }
107
108}