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.internal; 014 015import org.javamoney.moneta.spi.MonetaryConfig; 016 017import javax.money.CurrencyQuery; 018import javax.money.CurrencyUnit; 019import javax.money.spi.Bootstrap; 020import javax.money.spi.CurrencyProviderSpi; 021import javax.money.spi.MonetaryCurrenciesSingletonSpi; 022import java.util.ArrayList; 023import java.util.HashSet; 024import java.util.List; 025import java.util.Set; 026import java.util.logging.Level; 027import java.util.logging.Logger; 028 029/** 030 * Factory singleton for {@link javax.money.CurrencyUnit} instances as provided by the 031 * different registered {@link javax.money.spi.CurrencyProviderSpi} instances. 032 * <p/> 033 * This class is thread safe. 034 * 035 * @author Anatole Tresch 036 */ 037public class DefaultMonetaryCurrenciesSingletonSpi implements MonetaryCurrenciesSingletonSpi { 038 039 @Override 040 public Set<CurrencyUnit> getCurrencies(CurrencyQuery query) { 041 Set<CurrencyUnit> result = new HashSet<>(); 042 List<CurrencyProviderSpi> providers = collectProviders(query); 043 for (CurrencyProviderSpi spi : providers) { 044 try { 045 result.addAll(spi.getCurrencies(query)); 046 } catch (Exception e) { 047 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()) 048 .log(Level.SEVERE, "Error loading currency provider names for " + spi.getClass().getName(), 049 e); 050 } 051 } 052 return result; 053 } 054 055 private List<CurrencyProviderSpi> collectProviders(CurrencyQuery query) { 056 List<CurrencyProviderSpi> result = new ArrayList<>(); 057 if (!query.getProviderNames().isEmpty()) { 058 for (String providerName : query.getProviderNames()) { 059 CurrencyProviderSpi provider = getProvider(providerName); 060 if (provider == null) { 061 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()).warning("No such currenvcy " + 062 "provider found, ignoring: " + providerName); 063 } else { 064 result.add(provider); 065 } 066 } 067 } 068 else{ 069 for(String providerName:getDefaultProviderChain()){ 070 CurrencyProviderSpi provider = getProvider(providerName); 071 if (provider == null) { 072 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()).warning("No such currenvcy " + 073 "provider found, ignoring: " + providerName); 074 } else { 075 result.add(provider); 076 } 077 } 078 } 079 return result; 080 } 081 082 private CurrencyProviderSpi getProvider(String providerName) { 083 for(CurrencyProviderSpi provider:Bootstrap.getServices(CurrencyProviderSpi.class)){ 084 if(provider.getProviderName().equals(providerName)){ 085 return provider; 086 } 087 } 088 return null; 089 } 090 091 /** 092 * This default implementation simply returns all providers defined in arbitrary order. 093 * 094 * @return the default provider chain, never null. 095 */ 096 @Override 097 public List<String> getDefaultProviderChain() { 098 List<String> provList = new ArrayList<>(); 099 String defaultChain = MonetaryConfig.getConfig().get("currencies.default-chain"); 100 if(defaultChain!=null) { 101 String[] items = defaultChain.split(","); 102 for (String item : items) { 103 if (getProviderNames().contains(item.trim())) { 104 provList.add(item); 105 } else { 106 Logger.getLogger(getClass().getName()) 107 .warning("Ignoring non existing default provider: " + item); 108 } 109 } 110 } 111 else{ 112 Bootstrap.getServices(CurrencyProviderSpi.class).forEach( 113 p -> provList.add(p.getProviderName()) 114 ); 115 } 116 return provList; 117 } 118 119 /** 120 * Get the names of the currently loaded providers. 121 * 122 * @return the names of the currently loaded providers, never null. 123 */ 124 @Override 125 public Set<String> getProviderNames() { 126 Set<String> result = new HashSet<>(); 127 for (CurrencyProviderSpi spi : Bootstrap.getServices(CurrencyProviderSpi.class)) { 128 try { 129 result.add(spi.getProviderName()); 130 } catch (Exception e) { 131 Logger.getLogger(DefaultMonetaryCurrenciesSingletonSpi.class.getName()) 132 .log(Level.SEVERE, "Error loading currency provider names for " + spi.getClass().getName(), 133 e); 134 } 135 } 136 return result; 137 } 138 139}