/****************************************************************************** * This program test the Currency class. * * Copyright © 2021 Richard Lesh. All rights reserved. *****************************************************************************/ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import org.pureprogrammer.Utils; public class CurrencyClass { static class Currency { // Internal representation is in USD private double value = 0.0; private static int NONBREAKING_SPACE = 0xA0; private static Map CONVERSION_RATES = new HashMap<>(); private static Map CURRENCY_SYMBOLS = Utils.map(new Object[][] { {"AUD", "$\u00A0"}, {"CAD", "$\u00A0"}, {"CNY", "¥\u00A0"}, {"EUR", "\u00A0€"}, {"GBP", "£\u00A0"}, {"INR", "₹\u00A0"}, {"JPY", "¥\u00A0"}, {"MXN", "$\u00A0"}, {"RUB", "\u00A0₽"}, {"USD", "$"}, {"XBT", "\u00A0BTC"} }); private static Map CURRENCY_SEPARATORS = Utils.map(new Object[][] { {"AUD", ",."}, {"CAD", ",."}, {"CNY", ",."}, {"EUR", ".,"}, {"GBP", ",."}, {"INR", ",."}, {"JPY", ",."}, {"MXN", ",."}, {"RUB", ".,"}, {"USD", ",."}, {"XBT", ",."} }); // List of legal currency codes. public static List CURRENCY_CODES = new ArrayList<>(); // Constructor public Currency(double value, String currencyCode) throws RuntimeException { double conversionRate = 1.0; if (CONVERSION_RATES.containsKey(currencyCode)) { conversionRate = CONVERSION_RATES.get(currencyCode); } else { throw new RuntimeException(Utils.join("", "Illegal currency code: ", currencyCode)); } this.value = value / conversionRate; } // getter public double get(String currencyCode) throws RuntimeException { double conversionRate = 1.0; if (CONVERSION_RATES.containsKey(currencyCode)) { conversionRate = CONVERSION_RATES.get(currencyCode); } else { throw new RuntimeException(Utils.join("", "Illegal currency code: ", currencyCode)); } return value * conversionRate; } public String addSeparators(double d, String sep) { final String s = Utils.format("{0:.2f}", d); final String COMMA = Utils.uniAt(sep, 0); final String PERIOD = Utils.uniAt(sep, 1); final List parts = Arrays.asList(Pattern.compile("\\.").split(s)); String dollars = Utils.join("", parts.get(0), PERIOD); List matches = new ArrayList<>(); final Pattern PATTERN = Pattern.compile("(\\d+?)(\\d{3,3}[,.].*)"); matches = Utils.findFirst(PATTERN, dollars); while (matches.size() != 0) { dollars = Utils.join("", matches.get(1), COMMA, matches.get(2)); matches = Utils.findFirst(PATTERN, dollars); } return Utils.join("", dollars, parts.get(1)); } // string conversion public String getString(String currencyCode) throws RuntimeException { String currencySymbol = "$"; String currencySeparator = ",."; if (CURRENCY_SYMBOLS.containsKey(currencyCode)) { currencySymbol = CURRENCY_SYMBOLS.get(currencyCode); currencySeparator = CURRENCY_SEPARATORS.get(currencyCode); } String formatStr = ""; // If non-breaking space is first in symbol then it goes at end if (Utils.cpLength(currencySymbol) > 1 && Utils.cpIndexOf(currencySymbol, NONBREAKING_SPACE) == 0) { formatStr = "{1:s}{0:s}"; } else { formatStr = "{0:s}{1:s}"; } final String CURRENCY_VALUE = addSeparators(get(currencyCode), currencySeparator); return Utils.format(formatStr, currencySymbol, CURRENCY_VALUE); } public static void setConversionRates(final Map rates) { CONVERSION_RATES = rates; CURRENCY_CODES = Utils.sort(List.copyOf(CONVERSION_RATES.keySet())); } } public static void main(String[] args) { Map todaysRates = Utils.map(new Object[][] { {"AUD", 1.26}, {"CAD", 1.26}, {"CNY", 6.47}, {"EUR", 0.82}, {"GBP", 0.71}, {"INR", 72.49}, {"JPY", 105.07}, {"MXN", 20.68}, {"RUB", 74.29}, {"USD", 1.0}, {"XBT", 0.00001900} }); Currency.setConversionRates(todaysRates); System.out.println("Today's currency rates set."); try { Currency c = new Currency(1.0, "USD"); for (String code : Currency.CURRENCY_CODES) { System.out.println(Utils.format("{0:s} to {1:s}: {2:s} = {3:s}", "USD", code, c.getString("USD"), c.getString(code))); } System.out.println(); c = new Currency(1234.56, "EUR"); for (String code : Currency.CURRENCY_CODES) { System.out.println(Utils.format("{0:s} to {1:s}: {2:s} = {3:s}", "USD", code, c.getString("USD"), c.getString(code))); } } catch (RuntimeException ex) { System.out.println(Utils.join("", "Error: ", Utils.exceptionMessage(ex))); } } }