← joda-money  /  src/main/java/org/joda/money/DefaultCurrencyUnitDataProvider.java

1
/*
2
 *  Copyright 2009-present, Stephen Colebourne
3
 *
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
5
 *  you may not use this file except in compliance with the License.
6
 *  You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *  Unless required by applicable law or agreed to in writing, software
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *  See the License for the specific language governing permissions and
14
 *  limitations under the License.
15
 */
16
package org.joda.money;
17
18
import java.io.BufferedReader;
19
import java.io.FileNotFoundException;
20
import java.io.InputStreamReader;
21
import java.util.ArrayList;
22
import java.util.List;
23
import java.util.regex.Pattern;
24
25
/**
26
 * Provider for available currencies using a file.
27
 * <p>
28
 * This reads currencies from various files.
29
 * Firstly it reads the mandatory resource named {@code /org/joda/money/CurencyData.csv}.
30
 * Then it reads the mandatory resource named {@code /org/joda/money/CountryData.csv}.
31
 * These files are located in the joda-money jar file.
32
 * <p>
33
 * Then it reads optional resources named {@code META-INF/org/joda/money/CurencyDataExtension.csv}.
34
 * Then it reads optional resources named {@code META-INF/org/joda/money/CountryDataExtension.csv}.
35
 * These will be read using {@link ClassLoader#getResources(String)}.
36
 * These files may augment or replace data from the first two files.
37
 */
38
class DefaultCurrencyUnitDataProvider extends CurrencyUnitDataProvider {
39
40
    /** Regex format for the money csv line. */
41
    private static final Pattern CURRENCY_REGEX_LINE = Pattern.compile("([A-Z]{3}),(-1|[0-9]{1,3}),(-1|[0-9]|[1-2][0-9]|30) *(#.*)?");
42
    /** Regex format for the country csv line. */
43
    private static final Pattern COUNTRY_REGEX_LINE = Pattern.compile("([A-Z]{2}),([A-Z]{3}) *(#.*)?");
44
45
    /**
46
     * Registers all the currencies known by this provider.
47
     *
48
     * @throws Exception if an error occurs
49
     */
50
    @Override
51
    protected void registerCurrencies() throws Exception {
52
        parseCurrencies(loadFromFile("/org/joda/money/CurrencyData.csv"));
53
        parseCountries(loadFromFile("/org/joda/money/CountryData.csv"));
54
        parseCurrencies(loadFromFiles("META-INF/org/joda/money/CurrencyDataExtension.csv"));
55
        parseCountries(loadFromFiles("META-INF/org/joda/money/CountryDataExtension.csv"));
56
    }
57
58
    // loads a file
59
    private List<String> loadFromFile(String fileName) throws Exception {
60
        try (var in = getClass().getResourceAsStream(fileName)) {
61
            if (in == null) {
62
                throw new FileNotFoundException("Data file " + fileName + " not found");
63
            }
64
            try (var reader = new BufferedReader(new InputStreamReader(in, "UTF-8"))) {
65
                String line;
66
                List<String> content = new ArrayList<>();
67
                while ((line = reader.readLine()) != null) {
68
                    content.add(line);
69
                }
70
                return content;
71
            }
72
        }
73
    }
74
75
    // loads a file
76
    private List<String> loadFromFiles(String fileName) throws Exception {
77
        List<String> content = new ArrayList<>();
78
        var en = getClass().getClassLoader().getResources(fileName);
79
        while (en.hasMoreElements()) {
80
            var url = en.nextElement();
81
            try (var in = url.openStream()) {
82
                try (var reader = new BufferedReader(new InputStreamReader(in, "UTF-8"))) {
83
                    String line;
84
                    while ((line = reader.readLine()) != null) {
85
                        content.add(line);
86
                    }
87
                }
88
            }
89
        }
90
        return content;
91
    }
92
93
    // parse the currencies
94
    private void parseCurrencies(List<String> content) throws Exception {
95
        for (String line : content) {
96
            var matcher = CURRENCY_REGEX_LINE.matcher(line);
97
            if (matcher.matches()) {
98
                var currencyCode = matcher.group(1);
99
                var numericCode = Integer.parseInt(matcher.group(2));
100
                var digits = Integer.parseInt(matcher.group(3));
101
                registerCurrency(currencyCode, numericCode, digits);
102
            }
103
        }
104
    }
105
106
    // parse the countries
107
    private void parseCountries(List<String> content) throws Exception {
108
        for (String line : content) {
109
            var matcher = COUNTRY_REGEX_LINE.matcher(line);
110
            if (matcher.matches()) {
111
                var countryCode = matcher.group(1);
112
                var currencyCode = matcher.group(2);
113
                registerCountry(countryCode, currencyCode);
114
            }
115
        }
116
    }
117
118
}
119