001/* 002 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE 003 * CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT. 004 * PLEASE READ THE TERMS AND CONDITIONS OF THIS AGREEMENT CAREFULLY. BY 005 * DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF THE 006 * AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE" 007 * BUTTON AT THE BOTTOM OF THIS PAGE. 008 * 009 * Specification: JSR-354 Money and Currency API ("Specification") 010 * 011 * Copyright (c) 2012-2013, Credit Suisse All rights reserved. 012 */ 013package org.javamoney.moneta.spi; 014 015import org.javamoney.moneta.spi.base.BaseMonetaryCurrenciesSingletonSpi; 016 017import javax.money.CurrencyQuery; 018import javax.money.CurrencyUnit; 019import javax.money.spi.Bootstrap; 020import javax.money.spi.CurrencyProviderSpi; 021import java.util.ArrayList; 022import java.util.HashSet; 023import java.util.List; 024import java.util.Set; 025import java.util.logging.Level; 026import java.util.logging.Logger; 027 028/** 029 * Factory singleton for {@link javax.money.CurrencyUnit} instances as provided by the 030 * different registered {@link javax.money.spi.CurrencyProviderSpi} instances. 031 * 032 * This class is thread safe. 033 * 034 * @author Anatole Tresch 035 */ 036public class DefaultMonetaryCurrenciesSingletonSpi extends BaseMonetaryCurrenciesSingletonSpi { 037 038 @Override 039 public Set<CurrencyUnit> getCurrencies(CurrencyQuery query) { 040 Set<CurrencyUnit> result = new HashSet<>(); 041 List<CurrencyProviderSpi> providers = collectProviders(query); 042 for (CurrencyProviderSpi spi : providers) { 043 try { 044 result.addAll(spi.getCurrencies(query)); 045 } catch (Exception e) { 046 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()) 047 .log(Level.SEVERE, "Error loading currency provider names for " + spi.getClass().getName(), 048 e); 049 } 050 } 051 return result; 052 } 053 054 private List<CurrencyProviderSpi> collectProviders(CurrencyQuery query) { 055 List<CurrencyProviderSpi> result = new ArrayList<>(); 056 if (!query.getProviderNames().isEmpty()) { 057 for (String providerName : query.getProviderNames()) { 058 CurrencyProviderSpi provider = getProvider(providerName); 059 if (provider == null) { 060 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()).warning("No such currency " + 061 "provider found, ignoring: " + providerName); 062 } else { 063 result.add(provider); 064 } 065 } 066 } 067 else{ 068 for(String providerName:getDefaultProviderChain()){ 069 CurrencyProviderSpi provider = getProvider(providerName); 070 if (provider == null) { 071 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()).warning("No such currency " + 072 "provider found, ignoring: " + providerName); 073 } else { 074 result.add(provider); 075 } 076 } 077 } 078 return result; 079 } 080 081 private CurrencyProviderSpi getProvider(String providerName) { 082 for(CurrencyProviderSpi provider: Bootstrap.getServices(CurrencyProviderSpi.class)){ 083 if(provider.getProviderName().equals(providerName)){ 084 return provider; 085 } 086 } 087 return null; 088 } 089 090 /** 091 * This default implementation simply returns all providers defined in arbitrary order. 092 * 093 * @return the default provider chain, never null. 094 */ 095 @Override 096 public List<String> getDefaultProviderChain() { 097 List<String> provList = new ArrayList<>(); 098 String defaultChain = MonetaryConfig.getConfig().get("currencies.default-chain"); 099 if(defaultChain!=null) { 100 String[] items = defaultChain.split(","); 101 for (String item : items) { 102 if (getProviderNames().contains(item.trim())) { 103 provList.add(item); 104 } else { 105 Logger.getLogger(getClass().getName()) 106 .warning("Ignoring non existing default provider: " + item); 107 } 108 } 109 } 110 else{ 111 for(CurrencyProviderSpi currencyProviderSpi: Bootstrap.getServices(CurrencyProviderSpi.class)) { 112 provList.add(currencyProviderSpi.getProviderName()); 113 } 114 } 115 return provList; 116 } 117 118 /** 119 * Get the names of the currently loaded providers. 120 * 121 * @return the names of the currently loaded providers, never null. 122 */ 123 @Override 124 public Set<String> getProviderNames() { 125 Set<String> result = new HashSet<>(); 126 for (CurrencyProviderSpi spi : Bootstrap.getServices(CurrencyProviderSpi.class)) { 127 try { 128 result.add(spi.getProviderName()); 129 } catch (Exception e) { 130 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()) 131 .log(Level.SEVERE, "Error loading currency provider names for " + spi.getClass().getName(), 132 e); 133 } 134 } 135 return result; 136 } 137 138}