• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

javadev / moneytostr-russian / #385

15 Apr 2024 02:23AM UTC coverage: 75.223%. Remained the same
#385

push

web-flow
Bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.0

337 of 448 relevant lines covered (75.22%)

0.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.22
src/main/java/com/github/moneytostr/MoneyToStr.java
1
/*
2
 * $Id$
3
 *
4
 * Copyright 2014 Valentyn Kolesnikov
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
package com.github.moneytostr;
19

20
import java.math.BigDecimal;
21
import java.util.ArrayList;
22
import java.util.LinkedHashMap;
23
import java.util.List;
24
import java.util.Map;
25

26
/**
27
 * Converts numbers to symbols.
28
 *
29
 * @author Valentyn Kolesnikov
30
 * @version $Revision$ $Date$
31
 */
32
public class MoneyToStr {
33
    private static final int INDEX_3 = 3;
34
    private static final int INDEX_2 = 2;
35
    private static final int INDEX_1 = 1;
36
    private static final int INDEX_0 = 0;
37
    private static Map<String, Object> jsonMap;
38
    private static final int NUM0 = 0;
39
    private static final int NUM1 = 1;
40
    private static final int NUM2 = 2;
41
    private static final int NUM3 = 3;
42
    private static final int NUM4 = 4;
43
    private static final int NUM5 = 5;
44
    private static final int NUM6 = 6;
45
    private static final int NUM7 = 7;
46
    private static final int NUM8 = 8;
47
    private static final int NUM9 = 9;
48
    private static final int NUM10 = 10;
49
    private static final int NUM11 = 11;
50
    private static final int NUM14 = 14;
51
    private static final int NUM100 = 100;
52
    private static final int NUM1000 = 1000;
53
    private static final int NUM10000 = 10000;
54
    private static final String CURRENCY_LIST =
55
            "{\n"
56
                    + "  \"CurrencyList\": {\n"
57
                    + "    \"language\": {\n"
58
                    + "      \"-value\": \"UKR\"\n"
59
                    + "    },\n"
60
                    + "    \"UKR\": {\n"
61
                    + "      \"item\": [\n"
62
                    + "        {\n"
63
                    + "          \"-value\": \"minus\",\n"
64
                    + "          \"-text\": \"мінус\"\n"
65
                    + "        },\n"
66
                    + "        {\n"
67
                    + "          \"-value\": \"0\",\n"
68
                    + "          \"-text\": \"нуль\"\n"
69
                    + "        },\n"
70
                    + "        {\n"
71
                    + "          \"-value\": \"1000_10\",\n"
72
                    + "          \"-text\": \"тисяч,мільйонів,мільярдів,трильйонів\"\n"
73
                    + "        },\n"
74
                    + "        {\n"
75
                    + "          \"-value\": \"1000_1\",\n"
76
                    + "          \"-text\": \"тисяча,мільйон,мільярд,трильйон\"\n"
77
                    + "        },\n"
78
                    + "        {\n"
79
                    + "          \"-value\": \"1000_234\",\n"
80
                    + "          \"-text\": \"тисячі,мільйона,мільярда,трильйона\"\n"
81
                    + "        },\n"
82
                    + "        {\n"
83
                    + "          \"-value\": \"1000_5\",\n"
84
                    + "          \"-text\": \"тисяч,мільйонів,мільярдів,трильйонів\"\n"
85
                    + "        },\n"
86
                    + "        {\n"
87
                    + "          \"-value\": \"10_19\",\n"
88
                    + "          \"-text\": \"десять,одинадцять,дванадцять,тринадцять,чотирнадцять,п'ятнадцять,шістнадцять,сімнадцять,вісімнадцять,дев'ятнадцять\"\n"
89
                    + "        },\n"
90
                    + "        {\n"
91
                    + "          \"-value\": \"1\",\n"
92
                    + "          \"-text\": \"одна,один,один,одна\"\n"
93
                    + "        },\n"
94
                    + "        {\n"
95
                    + "          \"-value\": \"2\",\n"
96
                    + "          \"-text\": \"дві,два,два,дві\"\n"
97
                    + "        },\n"
98
                    + "        {\n"
99
                    + "          \"-value\": \"3_9\",\n"
100
                    + "          \"-text\": \"три,чотири,п'ять,шість,сім,вісім,дев'ять\"\n"
101
                    + "        },\n"
102
                    + "        {\n"
103
                    + "          \"-value\": \"100_900\",\n"
104
                    + "          \"-text\": \"сто ,двісті ,триста ,чотириста ,п'ятсот ,шістсот ,сімсот ,вісімсот ,дев'ятсот \"\n"
105
                    + "        },\n"
106
                    + "        {\n"
107
                    + "          \"-value\": \"20_90\",\n"
108
                    + "          \"-text\": \"двадцять ,тридцять ,сорок ,п'ятдесят ,шістдесят ,сімдесят ,вісімдесят ,дев'яносто \"\n"
109
                    + "        },\n"
110
                    + "        {\n"
111
                    + "          \"-value\": \"pdv\",\n"
112
                    + "          \"-text\": \"в т.ч. ПДВ \"\n"
113
                    + "        },\n"
114
                    + "        {\n"
115
                    + "          \"-value\": \"pdv_value\",\n"
116
                    + "          \"-text\": \"20\"\n"
117
                    + "        }\n"
118
                    + "      ]\n"
119
                    + "    },\n"
120
                    + "    \"RUS\": {\n"
121
                    + "      \"item\": [\n"
122
                    + "        {\n"
123
                    + "          \"-value\": \"minus\",\n"
124
                    + "          \"-text\": \"минус\"\n"
125
                    + "        },\n"
126
                    + "        {\n"
127
                    + "          \"-value\": \"0\",\n"
128
                    + "          \"-text\": \"ноль\"\n"
129
                    + "        },\n"
130
                    + "        {\n"
131
                    + "          \"-value\": \"1000_10\",\n"
132
                    + "          \"-text\": \"тысяч,миллионов,миллиардов,триллионов\"\n"
133
                    + "        },\n"
134
                    + "        {\n"
135
                    + "          \"-value\": \"1000_1\",\n"
136
                    + "          \"-text\": \"тысяча,миллион,миллиард,триллион\"\n"
137
                    + "        },\n"
138
                    + "        {\n"
139
                    + "          \"-value\": \"1000_234\",\n"
140
                    + "          \"-text\": \"тысячи,миллиона,миллиарда,триллиона\"\n"
141
                    + "        },\n"
142
                    + "        {\n"
143
                    + "          \"-value\": \"1000_5\",\n"
144
                    + "          \"-text\": \"тысяч,миллионов,миллиардов,триллионов\"\n"
145
                    + "        },\n"
146
                    + "        {\n"
147
                    + "          \"-value\": \"10_19\",\n"
148
                    + "          \"-text\": \"десять,одиннадцать,двенадцать,тринадцать,четырнадцать,пятнадцать,шестнадцать,семнадцать,восемнадцать,девятнадцать\"\n"
149
                    + "        },\n"
150
                    + "        {\n"
151
                    + "          \"-value\": \"1\",\n"
152
                    + "          \"-text\": \"одна,один,один,одна\"\n"
153
                    + "        },\n"
154
                    + "        {\n"
155
                    + "          \"-value\": \"2\",\n"
156
                    + "          \"-text\": \"две,два,два,две\"\n"
157
                    + "        },\n"
158
                    + "        {\n"
159
                    + "          \"-value\": \"3_9\",\n"
160
                    + "          \"-text\": \"три,четыре,пять,шесть,семь,восемь,девять\"\n"
161
                    + "        },\n"
162
                    + "        {\n"
163
                    + "          \"-value\": \"100_900\",\n"
164
                    + "          \"-text\": \"сто ,двести ,триста ,четыреста ,пятьсот ,шестьсот ,семьсот ,восемьсот ,девятьсот \"\n"
165
                    + "        },\n"
166
                    + "        {\n"
167
                    + "          \"-value\": \"20_90\",\n"
168
                    + "          \"-text\": \"двадцать ,тридцать ,сорок ,пятьдесят ,шестьдесят ,семьдесят ,восемьдесят ,девяносто \"\n"
169
                    + "        },\n"
170
                    + "        {\n"
171
                    + "          \"-value\": \"pdv\",\n"
172
                    + "          \"-text\": \"в т.ч. НДС \"\n"
173
                    + "        },\n"
174
                    + "        {\n"
175
                    + "          \"-value\": \"pdv_value\",\n"
176
                    + "          \"-text\": \"18\"\n"
177
                    + "        }\n"
178
                    + "      ]\n"
179
                    + "    },\n"
180
                    + "    \"ENG\": {\n"
181
                    + "      \"item\": [\n"
182
                    + "        {\n"
183
                    + "          \"-value\": \"minus\",\n"
184
                    + "          \"-text\": \"minus\"\n"
185
                    + "        },\n"
186
                    + "        {\n"
187
                    + "          \"-value\": \"0\",\n"
188
                    + "          \"-text\": \"zero\"\n"
189
                    + "        },\n"
190
                    + "        {\n"
191
                    + "          \"-value\": \"1000_10\",\n"
192
                    + "          \"-text\": \"thousand,million,billion,trillion\"\n"
193
                    + "        },\n"
194
                    + "        {\n"
195
                    + "          \"-value\": \"1000_1\",\n"
196
                    + "          \"-text\": \"thousand,million,billion,trillion\"\n"
197
                    + "        },\n"
198
                    + "        {\n"
199
                    + "          \"-value\": \"1000_234\",\n"
200
                    + "          \"-text\": \"thousand,million,billion,trillion\"\n"
201
                    + "        },\n"
202
                    + "        {\n"
203
                    + "          \"-value\": \"1000_5\",\n"
204
                    + "          \"-text\": \"thousand,million,billion,trillion\"\n"
205
                    + "        },\n"
206
                    + "        {\n"
207
                    + "          \"-value\": \"10_19\",\n"
208
                    + "          \"-text\": \"ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen\"\n"
209
                    + "        },\n"
210
                    + "        {\n"
211
                    + "          \"-value\": \"1\",\n"
212
                    + "          \"-text\": \"one,one,one,one\"\n"
213
                    + "        },\n"
214
                    + "        {\n"
215
                    + "          \"-value\": \"2\",\n"
216
                    + "          \"-text\": \"two,two,two,two\"\n"
217
                    + "        },\n"
218
                    + "        {\n"
219
                    + "          \"-value\": \"3_9\",\n"
220
                    + "          \"-text\": \"three,four,five,six,seven,eight,nine\"\n"
221
                    + "        },\n"
222
                    + "        {\n"
223
                    + "          \"-value\": \"100_900\",\n"
224
                    + "          \"-text\": \"one hundred ,two hundred ,three hundred ,four hundred ,five hundred ,six hundred ,seven hundred ,eight hundred ,nine hundred \"\n"
225
                    + "        },\n"
226
                    + "        {\n"
227
                    + "          \"-value\": \"20_90\",\n"
228
                    + "          \"-text\": \"twenty-,thirty-,forty-,fifty-,sixty-,seventy-,eighty-,ninety-\"\n"
229
                    + "        },\n"
230
                    + "        {\n"
231
                    + "          \"-value\": \"pdv\",\n"
232
                    + "          \"-text\": \"including VAT \"\n"
233
                    + "        },\n"
234
                    + "        {\n"
235
                    + "          \"-value\": \"pdv_value\",\n"
236
                    + "          \"-text\": \"10\"\n"
237
                    + "        }\n"
238
                    + "      ]\n"
239
                    + "    },\n"
240
                    + "    \"RUR\": [\n"
241
                    + "      {\n"
242
                    + "        \"-CurrID\": \"810\",\n"
243
                    + "        \"-CurrName\": \"Российские рубли\",\n"
244
                    + "        \"-language\": \"RUS\",\n"
245
                    + "        \"-RubOneUnit\": \"рубль\",\n"
246
                    + "        \"-RubTwoUnit\": \"рубля\",\n"
247
                    + "        \"-RubFiveUnit\": \"рублей\",\n"
248
                    + "        \"-RubSex\": \"M\",\n"
249
                    + "        \"-RubShortUnit\": \"руб.\",\n"
250
                    + "        \"-KopOneUnit\": \"копейка\",\n"
251
                    + "        \"-KopTwoUnit\": \"копейки\",\n"
252
                    + "        \"-KopFiveUnit\": \"копеек\",\n"
253
                    + "        \"-KopSex\": \"F\"\n"
254
                    + "      },\n"
255
                    + "      {\n"
256
                    + "        \"-CurrID\": \"810\",\n"
257
                    + "        \"-CurrName\": \"Российские рубли\",\n"
258
                    + "        \"-language\": \"UKR\",\n"
259
                    + "        \"-RubOneUnit\": \"рубль\",\n"
260
                    + "        \"-RubTwoUnit\": \"рублі\",\n"
261
                    + "        \"-RubFiveUnit\": \"рублів\",\n"
262
                    + "        \"-RubSex\": \"M\",\n"
263
                    + "        \"-RubShortUnit\": \"руб.\",\n"
264
                    + "        \"-KopOneUnit\": \"копійка\",\n"
265
                    + "        \"-KopTwoUnit\": \"копійки\",\n"
266
                    + "        \"-KopFiveUnit\": \"копійок\",\n"
267
                    + "        \"-KopSex\": \"F\"\n"
268
                    + "      },\n"
269
                    + "      {\n"
270
                    + "        \"-CurrID\": \"810\",\n"
271
                    + "        \"-CurrName\": \"Российские рубли\",\n"
272
                    + "        \"-language\": \"ENG\",\n"
273
                    + "        \"-RubOneUnit\": \"ruble\",\n"
274
                    + "        \"-RubTwoUnit\": \"rubles\",\n"
275
                    + "        \"-RubFiveUnit\": \"rubles\",\n"
276
                    + "        \"-RubSex\": \"M\",\n"
277
                    + "        \"-RubShortUnit\": \"RUR.\",\n"
278
                    + "        \"-KopOneUnit\": \"kopeck\",\n"
279
                    + "        \"-KopTwoUnit\": \"kopecks\",\n"
280
                    + "        \"-KopFiveUnit\": \"kopecks\",\n"
281
                    + "        \"-KopSex\": \"M\"\n"
282
                    + "      }\n"
283
                    + "    ],\n"
284
                    + "    \"UAH\": [\n"
285
                    + "      {\n"
286
                    + "        \"-CurrID\": \"980\",\n"
287
                    + "        \"-CurrName\": \"Украинскі гривні\",\n"
288
                    + "        \"-language\": \"RUS\",\n"
289
                    + "        \"-RubOneUnit\": \"гривня\",\n"
290
                    + "        \"-RubTwoUnit\": \"гривни\",\n"
291
                    + "        \"-RubFiveUnit\": \"гривень\",\n"
292
                    + "        \"-RubSex\": \"F\",\n"
293
                    + "        \"-RubShortUnit\": \"грн.\",\n"
294
                    + "        \"-KopOneUnit\": \"копейка\",\n"
295
                    + "        \"-KopTwoUnit\": \"копейки\",\n"
296
                    + "        \"-KopFiveUnit\": \"копеек\",\n"
297
                    + "        \"-KopSex\": \"F\"\n"
298
                    + "      },\n"
299
                    + "      {\n"
300
                    + "        \"-CurrID\": \"980\",\n"
301
                    + "        \"-CurrName\": \"Украинскі гривні\",\n"
302
                    + "        \"-language\": \"UKR\",\n"
303
                    + "        \"-RubOneUnit\": \"гривня\",\n"
304
                    + "        \"-RubTwoUnit\": \"гривні\",\n"
305
                    + "        \"-RubFiveUnit\": \"гривень\",\n"
306
                    + "        \"-RubSex\": \"F\",\n"
307
                    + "        \"-RubShortUnit\": \"грн.\",\n"
308
                    + "        \"-KopOneUnit\": \"копійка\",\n"
309
                    + "        \"-KopTwoUnit\": \"копійки\",\n"
310
                    + "        \"-KopFiveUnit\": \"копійок\",\n"
311
                    + "        \"-KopSex\": \"F\"\n"
312
                    + "      },\n"
313
                    + "      {\n"
314
                    + "        \"-CurrID\": \"980\",\n"
315
                    + "        \"-CurrName\": \"Украинскі гривні\",\n"
316
                    + "        \"-language\": \"ENG\",\n"
317
                    + "        \"-RubOneUnit\": \"hryvnia\",\n"
318
                    + "        \"-RubTwoUnit\": \"hryvnias\",\n"
319
                    + "        \"-RubFiveUnit\": \"hryvnias\",\n"
320
                    + "        \"-RubSex\": \"M\",\n"
321
                    + "        \"-RubShortUnit\": \"UAH.\",\n"
322
                    + "        \"-KopOneUnit\": \"kopeck\",\n"
323
                    + "        \"-KopTwoUnit\": \"kopecks\",\n"
324
                    + "        \"-KopFiveUnit\": \"kopecks\",\n"
325
                    + "        \"-KopSex\": \"M\"\n"
326
                    + "      }\n"
327
                    + "    ],\n"
328
                    + "    \"USD\": [\n"
329
                    + "      {\n"
330
                    + "        \"-CurrID\": \"840\",\n"
331
                    + "        \"-CurrName\": \"Долари США\",\n"
332
                    + "        \"-language\": \"RUS\",\n"
333
                    + "        \"-RubOneUnit\": \"доллар\",\n"
334
                    + "        \"-RubTwoUnit\": \"доллара\",\n"
335
                    + "        \"-RubFiveUnit\": \"долларов\",\n"
336
                    + "        \"-RubSex\": \"M\",\n"
337
                    + "        \"-RubShortUnit\": \"дол.\",\n"
338
                    + "        \"-KopOneUnit\": \"цент\",\n"
339
                    + "        \"-KopTwoUnit\": \"цента\",\n"
340
                    + "        \"-KopFiveUnit\": \"центов\",\n"
341
                    + "        \"-KopSex\": \"M\"\n"
342
                    + "      },\n"
343
                    + "      {\n"
344
                    + "        \"-CurrID\": \"840\",\n"
345
                    + "        \"-CurrName\": \"Долари США\",\n"
346
                    + "        \"-language\": \"UKR\",\n"
347
                    + "        \"-RubOneUnit\": \"долар\",\n"
348
                    + "        \"-RubTwoUnit\": \"долара\",\n"
349
                    + "        \"-RubFiveUnit\": \"доларів\",\n"
350
                    + "        \"-RubSex\": \"M\",\n"
351
                    + "        \"-RubShortUnit\": \"дол.\",\n"
352
                    + "        \"-KopOneUnit\": \"цент\",\n"
353
                    + "        \"-KopTwoUnit\": \"цента\",\n"
354
                    + "        \"-KopFiveUnit\": \"центів\",\n"
355
                    + "        \"-KopSex\": \"M\"\n"
356
                    + "      },\n"
357
                    + "      {\n"
358
                    + "        \"-CurrID\": \"840\",\n"
359
                    + "        \"-CurrName\": \"Долари США\",\n"
360
                    + "        \"-language\": \"ENG\",\n"
361
                    + "        \"-RubOneUnit\": \"dollar\",\n"
362
                    + "        \"-RubTwoUnit\": \"dollars\",\n"
363
                    + "        \"-RubFiveUnit\": \"dollars\",\n"
364
                    + "        \"-RubSex\": \"M\",\n"
365
                    + "        \"-RubShortUnit\": \"USD.\",\n"
366
                    + "        \"-KopOneUnit\": \"cent\",\n"
367
                    + "        \"-KopTwoUnit\": \"cents\",\n"
368
                    + "        \"-KopFiveUnit\": \"cents\",\n"
369
                    + "        \"-KopSex\": \"M\"\n"
370
                    + "      }\n"
371
                    + "    ],\n"
372
                    + "    \"EUR\": [\n"
373
                    + "      {\n"
374
                    + "        \"-CurrID\": \"840\",\n"
375
                    + "        \"-CurrName\": \"Евро ЕС\",\n"
376
                    + "        \"-language\": \"RUS\",\n"
377
                    + "        \"-RubOneUnit\": \"евро\",\n"
378
                    + "        \"-RubTwoUnit\": \"евро\",\n"
379
                    + "        \"-RubFiveUnit\": \"евро\",\n"
380
                    + "        \"-RubSex\": \"M\",\n"
381
                    + "        \"-RubShortUnit\": \"евр.\",\n"
382
                    + "        \"-KopOneUnit\": \"цент\",\n"
383
                    + "        \"-KopTwoUnit\": \"цента\",\n"
384
                    + "        \"-KopFiveUnit\": \"центов\",\n"
385
                    + "        \"-KopSex\": \"M\"\n"
386
                    + "      },\n"
387
                    + "      {\n"
388
                    + "        \"-CurrID\": \"840\",\n"
389
                    + "        \"-CurrName\": \"Евро ЕС\",\n"
390
                    + "        \"-language\": \"UKR\",\n"
391
                    + "        \"-RubOneUnit\": \"євро\",\n"
392
                    + "        \"-RubTwoUnit\": \"євро\",\n"
393
                    + "        \"-RubFiveUnit\": \"євро\",\n"
394
                    + "        \"-RubSex\": \"M\",\n"
395
                    + "        \"-RubShortUnit\": \"дол.\",\n"
396
                    + "        \"-KopOneUnit\": \"цент\",\n"
397
                    + "        \"-KopTwoUnit\": \"цента\",\n"
398
                    + "        \"-KopFiveUnit\": \"центів\",\n"
399
                    + "        \"-KopSex\": \"M\"\n"
400
                    + "      },\n"
401
                    + "      {\n"
402
                    + "        \"-CurrID\": \"840\",\n"
403
                    + "        \"-CurrName\": \"Долари США\",\n"
404
                    + "        \"-language\": \"ENG\",\n"
405
                    + "        \"-RubOneUnit\": \"euro\",\n"
406
                    + "        \"-RubTwoUnit\": \"euros\",\n"
407
                    + "        \"-RubFiveUnit\": \"euros\",\n"
408
                    + "        \"-RubSex\": \"M\",\n"
409
                    + "        \"-RubShortUnit\": \"USD.\",\n"
410
                    + "        \"-KopOneUnit\": \"cent\",\n"
411
                    + "        \"-KopTwoUnit\": \"cents\",\n"
412
                    + "        \"-KopFiveUnit\": \"cents\",\n"
413
                    + "        \"-KopSex\": \"M\"\n"
414
                    + "      }\n"
415
                    + "    ],\n"
416
                    + "    \"PER10\": [\n"
417
                    + "      {\n"
418
                    + "        \"-CurrID\": \"556\",\n"
419
                    + "        \"-CurrName\": \"Вiдсотки з десятими частинами\",\n"
420
                    + "        \"-language\": \"RUS\",\n"
421
                    + "        \"-RubOneUnit\": \"целая,\",\n"
422
                    + "        \"-RubTwoUnit\": \"целых,\",\n"
423
                    + "        \"-RubFiveUnit\": \"целых,\",\n"
424
                    + "        \"-RubSex\": \"F\",\n"
425
                    + "        \"-KopOneUnit\": \"десятая процента\",\n"
426
                    + "        \"-KopTwoUnit\": \"десятых процента\",\n"
427
                    + "        \"-KopFiveUnit\": \"десятых процента\",\n"
428
                    + "        \"-KopSex\": \"F\"\n"
429
                    + "      },\n"
430
                    + "      {\n"
431
                    + "        \"-CurrID\": \"556\",\n"
432
                    + "        \"-CurrName\": \"Вiдсотки з десятими частинами\",\n"
433
                    + "        \"-language\": \"UKR\",\n"
434
                    + "        \"-RubOneUnit\": \"ціла,\",\n"
435
                    + "        \"-RubTwoUnit\": \"цілих,\",\n"
436
                    + "        \"-RubFiveUnit\": \"цілих,\",\n"
437
                    + "        \"-RubSex\": \"F\",\n"
438
                    + "        \"-KopOneUnit\": \"десята відсотка\",\n"
439
                    + "        \"-KopTwoUnit\": \"десятих відсотка\",\n"
440
                    + "        \"-KopFiveUnit\": \"десятих відсотка\",\n"
441
                    + "        \"-KopSex\": \"F\"\n"
442
                    + "      },\n"
443
                    + "      {\n"
444
                    + "        \"-CurrID\": \"560\",\n"
445
                    + "        \"-CurrName\": \"Вiдсотки з десятими частинами\",\n"
446
                    + "        \"-language\": \"ENG\",\n"
447
                    + "        \"-RubOneUnit\": \",\",\n"
448
                    + "        \"-RubTwoUnit\": \"integers,\",\n"
449
                    + "        \"-RubFiveUnit\": \"integers,\",\n"
450
                    + "        \"-RubSex\": \"F\",\n"
451
                    + "        \"-KopOneUnit\": \"tenth of one percent\",\n"
452
                    + "        \"-KopTwoUnit\": \"tenth of one percent\",\n"
453
                    + "        \"-KopFiveUnit\": \"tenth of one percent\",\n"
454
                    + "        \"-KopSex\": \"F\"\n"
455
                    + "      }\n"
456
                    + "    ],\n"
457
                    + "    \"PER100\": [\n"
458
                    + "      {\n"
459
                    + "        \"-CurrID\": \"557\",\n"
460
                    + "        \"-CurrName\": \"Вiдсотки з сотими частинами\",\n"
461
                    + "        \"-language\": \"RUS\",\n"
462
                    + "        \"-RubOneUnit\": \"целая,\",\n"
463
                    + "        \"-RubTwoUnit\": \"целых,\",\n"
464
                    + "        \"-RubFiveUnit\": \"целых,\",\n"
465
                    + "        \"-RubSex\": \"F\",\n"
466
                    + "        \"-KopOneUnit\": \"сотая процента\",\n"
467
                    + "        \"-KopTwoUnit\": \"сотых процента\",\n"
468
                    + "        \"-KopFiveUnit\": \"сотых процента\",\n"
469
                    + "        \"-KopSex\": \"F\"\n"
470
                    + "      },\n"
471
                    + "      {\n"
472
                    + "        \"-CurrID\": \"557\",\n"
473
                    + "        \"-CurrName\": \"Вiдсотки з сотими частинами\",\n"
474
                    + "        \"-language\": \"UKR\",\n"
475
                    + "        \"-RubOneUnit\": \"ціла,\",\n"
476
                    + "        \"-RubTwoUnit\": \"цілих,\",\n"
477
                    + "        \"-RubFiveUnit\": \"цілих,\",\n"
478
                    + "        \"-RubSex\": \"F\",\n"
479
                    + "        \"-KopOneUnit\": \"сота відсотка\",\n"
480
                    + "        \"-KopTwoUnit\": \"сотих відсотка\",\n"
481
                    + "        \"-KopFiveUnit\": \"сотих відсотка\",\n"
482
                    + "        \"-KopSex\": \"F\"\n"
483
                    + "      },\n"
484
                    + "      {\n"
485
                    + "        \"-CurrID\": \"561\",\n"
486
                    + "        \"-CurrName\": \"Вiдсотки з сотими частинами\",\n"
487
                    + "        \"-language\": \"ENG\",\n"
488
                    + "        \"-RubOneUnit\": \",\",\n"
489
                    + "        \"-RubTwoUnit\": \"integers,\",\n"
490
                    + "        \"-RubFiveUnit\": \"integers,\",\n"
491
                    + "        \"-RubSex\": \"F\",\n"
492
                    + "        \"-KopOneUnit\": \"hundred percent\",\n"
493
                    + "        \"-KopTwoUnit\": \"hundredth of percent\",\n"
494
                    + "        \"-KopFiveUnit\": \"hundredth of percent\",\n"
495
                    + "        \"-KopSex\": \"F\"\n"
496
                    + "      }\n"
497
                    + "    ],\n"
498
                    + "    \"PER1000\": [\n"
499
                    + "      {\n"
500
                    + "        \"-CurrID\": \"558\",\n"
501
                    + "        \"-CurrName\": \"Вiдсотки з тисячними частинами\",\n"
502
                    + "        \"-language\": \"RUS\",\n"
503
                    + "        \"-RubOneUnit\": \"целая,\",\n"
504
                    + "        \"-RubTwoUnit\": \"целых,\",\n"
505
                    + "        \"-RubFiveUnit\": \"целых,\",\n"
506
                    + "        \"-RubSex\": \"F\",\n"
507
                    + "        \"-KopOneUnit\": \"тысячная процента\",\n"
508
                    + "        \"-KopTwoUnit\": \"тысячных процента\",\n"
509
                    + "        \"-KopFiveUnit\": \"тысячных процента\",\n"
510
                    + "        \"-KopSex\": \"F\"\n"
511
                    + "      },\n"
512
                    + "      {\n"
513
                    + "        \"-CurrID\": \"558\",\n"
514
                    + "        \"-CurrName\": \"Вiдсотки з тисячними частинами\",\n"
515
                    + "        \"-language\": \"UKR\",\n"
516
                    + "        \"-RubOneUnit\": \"ціла,\",\n"
517
                    + "        \"-RubTwoUnit\": \"цілих,\",\n"
518
                    + "        \"-RubFiveUnit\": \"цілих,\",\n"
519
                    + "        \"-RubSex\": \"F\",\n"
520
                    + "        \"-KopOneUnit\": \"тисячна відсотка\",\n"
521
                    + "        \"-KopTwoUnit\": \"тисячних відсотка\",\n"
522
                    + "        \"-KopFiveUnit\": \"тисячних відсотка\",\n"
523
                    + "        \"-KopSex\": \"F\"\n"
524
                    + "      },\n"
525
                    + "      {\n"
526
                    + "        \"-CurrID\": \"562\",\n"
527
                    + "        \"-CurrName\": \"Вiдсотки з тисячними частинами\",\n"
528
                    + "        \"-language\": \"ENG\",\n"
529
                    + "        \"-RubOneUnit\": \",\",\n"
530
                    + "        \"-RubTwoUnit\": \"integers,\",\n"
531
                    + "        \"-RubFiveUnit\": \"integers,\",\n"
532
                    + "        \"-RubSex\": \"F\",\n"
533
                    + "        \"-KopOneUnit\": \"thousandth of percent\",\n"
534
                    + "        \"-KopTwoUnit\": \"thousandths of percent\",\n"
535
                    + "        \"-KopFiveUnit\": \"thousandths of percent\",\n"
536
                    + "        \"-KopSex\": \"F\"\n"
537
                    + "      }\n"
538
                    + "    ],\n"
539
                    + "    \"PER10000\": [\n"
540
                    + "      {\n"
541
                    + "        \"-CurrID\": \"559\",\n"
542
                    + "        \"-CurrName\": \"Вiдсотки з десяти тисячними частинами\",\n"
543
                    + "        \"-language\": \"RUS\",\n"
544
                    + "        \"-RubOneUnit\": \"целая,\",\n"
545
                    + "        \"-RubTwoUnit\": \"целых,\",\n"
546
                    + "        \"-RubFiveUnit\": \"целых,\",\n"
547
                    + "        \"-RubSex\": \"F\",\n"
548
                    + "        \"-KopOneUnit\": \"десятитысячная процента\",\n"
549
                    + "        \"-KopTwoUnit\": \"десятитысячные процента\",\n"
550
                    + "        \"-KopFiveUnit\": \"десятитысячных процента\",\n"
551
                    + "        \"-KopSex\": \"F\"\n"
552
                    + "      },\n"
553
                    + "      {\n"
554
                    + "        \"-CurrID\": \"559\",\n"
555
                    + "        \"-CurrName\": \"Вiдсотки з десяти тисячними частинами\",\n"
556
                    + "        \"-language\": \"UKR\",\n"
557
                    + "        \"-RubOneUnit\": \"ціла,\",\n"
558
                    + "        \"-RubTwoUnit\": \"цілих,\",\n"
559
                    + "        \"-RubFiveUnit\": \"цілих,\",\n"
560
                    + "        \"-RubSex\": \"F\",\n"
561
                    + "        \"-KopOneUnit\": \"десятитисячна відсотка\",\n"
562
                    + "        \"-KopTwoUnit\": \"десятитисячних відсотка\",\n"
563
                    + "        \"-KopFiveUnit\": \"десятитисячних відсотка\",\n"
564
                    + "        \"-KopSex\": \"M\"\n"
565
                    + "      },\n"
566
                    + "      {\n"
567
                    + "        \"-CurrID\": \"563\",\n"
568
                    + "        \"-CurrName\": \"Вiдсотки з десяти тисячними частинами\",\n"
569
                    + "        \"-language\": \"ENG\",\n"
570
                    + "        \"-RubOneUnit\": \",\",\n"
571
                    + "        \"-RubTwoUnit\": \"integers,\",\n"
572
                    + "        \"-RubFiveUnit\": \"integers,\",\n"
573
                    + "        \"-RubSex\": \"F\",\n"
574
                    + "        \"-KopOneUnit\": \"ten percent\",\n"
575
                    + "        \"-KopTwoUnit\": \"ten-percent\",\n"
576
                    + "        \"-KopFiveUnit\": \"ten-percent\",\n"
577
                    + "        \"-KopSex\": \"F\"\n"
578
                    + "      }\n"
579
                    + "    ]\n"
580
                    + "  }\n"
581
                    + "}";
582

583
    public static class FromJson {
×
584
        public static class ParseException extends RuntimeException {
585
            private final int offset;
586
            private final int line;
587
            private final int column;
588

589
            public ParseException(String message, int offset, int line, int column) {
590
                super(message + " at " + line + ":" + column);
1✔
591
                this.offset = offset;
1✔
592
                this.line = line;
1✔
593
                this.column = column;
1✔
594
            }
1✔
595

596
            public int getOffset() {
597
                return offset;
×
598
            }
599

600
            public int getLine() {
601
                return line;
×
602
            }
603

604
            public int getColumn() {
605
                return column;
×
606
            }
607
        }
608

609
        public static class JsonParser {
610
            private final String json;
611
            private int index;
612
            private int line;
613
            private int lineOffset;
614
            private int current;
615
            private StringBuilder captureBuffer;
616
            private int captureStart;
617

618
            public JsonParser(String string) {
1✔
619
                this.json = string;
1✔
620
                line = 1;
1✔
621
                captureStart = -1;
1✔
622
            }
1✔
623

624
            public Object parse() {
625
                read();
1✔
626
                skipWhiteSpace();
1✔
627
                final Object result = readValue();
1✔
628
                skipWhiteSpace();
1✔
629
                if (!isEndOfText()) {
1✔
630
                    throw error("Unexpected character");
×
631
                }
632
                return result;
1✔
633
            }
634

635
            private Object readValue() {
636
                switch (current) {
1✔
637
                    case 'n':
638
                        return readNull();
×
639
                    case 't':
640
                        return readTrue();
×
641
                    case 'f':
642
                        return readFalse();
×
643
                    case '"':
644
                        return readString();
1✔
645
                    case '[':
646
                        return readArray();
1✔
647
                    case '{':
648
                        return readObject();
1✔
649
                    case '-':
650
                    case '0':
651
                    case '1':
652
                    case '2':
653
                    case '3':
654
                    case '4':
655
                    case '5':
656
                    case '6':
657
                    case '7':
658
                    case '8':
659
                    case '9':
660
                        return readNumber();
×
661
                    default:
662
                        throw expected("value");
1✔
663
                }
664
            }
665

666
            private List<Object> readArray() {
667
                read();
1✔
668
                List<Object> array = new ArrayList<>();
1✔
669
                skipWhiteSpace();
1✔
670
                if (readChar(']')) {
1✔
671
                    return array;
×
672
                }
673
                do {
674
                    skipWhiteSpace();
1✔
675
                    array.add(readValue());
1✔
676
                    skipWhiteSpace();
1✔
677
                } while (readChar(','));
1✔
678
                if (!readChar(']')) {
1✔
679
                    throw expected("',' or ']'");
×
680
                }
681
                return array;
1✔
682
            }
683

684
            private Map<String, Object> readObject() {
685
                read();
1✔
686
                Map<String, Object> object = new LinkedHashMap<>();
1✔
687
                skipWhiteSpace();
1✔
688
                if (readChar('}')) {
1✔
689
                    return object;
×
690
                }
691
                do {
692
                    skipWhiteSpace();
1✔
693
                    String name = readName();
1✔
694
                    skipWhiteSpace();
1✔
695
                    if (!readChar(':')) {
1✔
696
                        throw expected("':'");
×
697
                    }
698
                    skipWhiteSpace();
1✔
699
                    object.put(name, readValue());
1✔
700
                    skipWhiteSpace();
1✔
701
                } while (readChar(','));
1✔
702
                if (!readChar('}')) {
1✔
703
                    throw expected("',' or '}'");
×
704
                }
705
                return object;
1✔
706
            }
707

708
            private String readName() {
709
                if (current != '"') {
1✔
710
                    throw expected("name");
×
711
                }
712
                return readString();
1✔
713
            }
714

715
            private String readNull() {
716
                read();
×
717
                readRequiredChar('u');
×
718
                readRequiredChar('l');
×
719
                readRequiredChar('l');
×
720
                return null;
×
721
            }
722

723
            private Boolean readTrue() {
724
                read();
×
725
                readRequiredChar('r');
×
726
                readRequiredChar('u');
×
727
                readRequiredChar('e');
×
728
                return Boolean.TRUE;
×
729
            }
730

731
            private Boolean readFalse() {
732
                read();
×
733
                readRequiredChar('a');
×
734
                readRequiredChar('l');
×
735
                readRequiredChar('s');
×
736
                readRequiredChar('e');
×
737
                return Boolean.FALSE;
×
738
            }
739

740
            private void readRequiredChar(char ch) {
741
                if (!readChar(ch)) {
×
742
                    throw expected("'" + ch + "'");
×
743
                }
744
            }
×
745

746
            private String readString() {
747
                read();
1✔
748
                startCapture();
1✔
749
                while (current != '"') {
1✔
750
                    if (current == '\\') {
1✔
751
                        pauseCapture();
×
752
                        readEscape();
×
753
                        startCapture();
×
754
                    } else if (current < 0x20) {
1✔
755
                        throw expected("valid string character");
×
756
                    } else {
757
                        read();
1✔
758
                    }
759
                }
760
                String string = endCapture();
1✔
761
                read();
1✔
762
                return string;
1✔
763
            }
764

765
            private void readEscape() {
766
                read();
×
767
                switch (current) {
×
768
                    case '"':
769
                    case '/':
770
                    case '\\':
771
                        captureBuffer.append((char) current);
×
772
                        break;
×
773
                    case 'b':
774
                        captureBuffer.append('\b');
×
775
                        break;
×
776
                    case 'f':
777
                        captureBuffer.append('\f');
×
778
                        break;
×
779
                    case 'n':
780
                        captureBuffer.append('\n');
×
781
                        break;
×
782
                    case 'r':
783
                        captureBuffer.append('\r');
×
784
                        break;
×
785
                    case 't':
786
                        captureBuffer.append('\t');
×
787
                        break;
×
788
                    case 'u':
789
                        char[] hexChars = new char[4];
×
790
                        boolean isHexCharsDigits = true;
×
791
                        for (int i = 0; i < 4; i++) {
×
792
                            read();
×
793
                            if (!isHexDigit()) {
×
794
                                isHexCharsDigits = false;
×
795
                            }
796
                            hexChars[i] = (char) current;
×
797
                        }
798
                        if (isHexCharsDigits) {
×
799
                            captureBuffer.append((char) Integer.parseInt(new String(hexChars), 16));
×
800
                        } else {
801
                            captureBuffer
×
802
                                    .append("\\u")
×
803
                                    .append(hexChars[0])
×
804
                                    .append(hexChars[1])
×
805
                                    .append(hexChars[2])
×
806
                                    .append(hexChars[3]);
×
807
                        }
808
                        break;
×
809
                    default:
810
                        throw expected("valid escape sequence");
×
811
                }
812
                read();
×
813
            }
×
814

815
            private Number readNumber() {
816
                startCapture();
×
817
                readChar('-');
×
818
                int firstDigit = current;
×
819
                if (!readDigit()) {
×
820
                    throw expected("digit");
×
821
                }
822
                if (firstDigit != '0') {
×
823
                    while (readDigit()) {}
×
824
                }
825
                readFraction();
×
826
                readExponent();
×
827
                final String number = endCapture();
×
828
                if (number.contains(".") || number.contains("e") || number.contains("E")) {
×
829
                    return Double.valueOf(number);
×
830
                } else {
831
                    return Long.valueOf(number);
×
832
                }
833
            }
834

835
            private boolean readFraction() {
836
                if (!readChar('.')) {
×
837
                    return false;
×
838
                }
839
                if (!readDigit()) {
×
840
                    throw expected("digit");
×
841
                }
842
                while (readDigit()) {}
×
843
                return true;
×
844
            }
845

846
            private boolean readExponent() {
847
                if (!readChar('e') && !readChar('E')) {
×
848
                    return false;
×
849
                }
850
                if (!readChar('+')) {
×
851
                    readChar('-');
×
852
                }
853
                if (!readDigit()) {
×
854
                    throw expected("digit");
×
855
                }
856
                while (readDigit()) {}
×
857
                return true;
×
858
            }
859

860
            private boolean readChar(char ch) {
861
                if (current != ch) {
1✔
862
                    return false;
1✔
863
                }
864
                read();
1✔
865
                return true;
1✔
866
            }
867

868
            private boolean readDigit() {
869
                if (!isDigit()) {
×
870
                    return false;
×
871
                }
872
                read();
×
873
                return true;
×
874
            }
875

876
            private void skipWhiteSpace() {
877
                while (isWhiteSpace()) {
1✔
878
                    read();
1✔
879
                }
880
            }
1✔
881

882
            private void read() {
883
                if (index == json.length()) {
1✔
884
                    current = -1;
1✔
885
                    return;
1✔
886
                }
887
                if (current == '\n') {
1✔
888
                    line++;
1✔
889
                    lineOffset = index;
1✔
890
                }
891
                current = json.charAt(index++);
1✔
892
            }
1✔
893

894
            private void startCapture() {
895
                if (captureBuffer == null) {
1✔
896
                    captureBuffer = new StringBuilder();
1✔
897
                }
898
                captureStart = index - 1;
1✔
899
            }
1✔
900

901
            private void pauseCapture() {
902
                captureBuffer.append(json.substring(captureStart, index - 1));
×
903
                captureStart = -1;
×
904
            }
×
905

906
            private String endCapture() {
907
                int end = current == -1 ? index : index - 1;
1✔
908
                String captured;
909
                if (captureBuffer.length() > 0) {
1✔
910
                    captureBuffer.append(json.substring(captureStart, end));
×
911
                    captured = captureBuffer.toString();
×
912
                    captureBuffer.setLength(0);
×
913
                } else {
914
                    captured = json.substring(captureStart, end);
1✔
915
                }
916
                captureStart = -1;
1✔
917
                return captured;
1✔
918
            }
919

920
            private ParseException expected(String expected) {
921
                if (isEndOfText()) {
1✔
922
                    return error("Unexpected end of input");
×
923
                }
924
                return error("Expected " + expected);
1✔
925
            }
926

927
            private ParseException error(String message) {
928
                int absIndex = index;
1✔
929
                int column = absIndex - lineOffset;
1✔
930
                int offset = isEndOfText() ? absIndex : absIndex - 1;
1✔
931
                return new ParseException(message, offset, line, column - 1);
1✔
932
            }
933

934
            private boolean isWhiteSpace() {
935
                return current == ' ' || current == '\t' || current == '\n' || current == '\r';
1✔
936
            }
937

938
            private boolean isDigit() {
939
                return current >= '0' && current <= '9';
×
940
            }
941

942
            private boolean isHexDigit() {
943
                return isDigit()
×
944
                        || current >= 'a' && current <= 'f'
945
                        || current >= 'A' && current <= 'F';
946
            }
947

948
            private boolean isEndOfText() {
949
                return current == -1;
1✔
950
            }
951
        }
952

953
        @SuppressWarnings("unchecked")
954
        public static Map<String, Object> fromJson(String string) {
955
            return (Map<String, Object>) new JsonParser(string).parse();
1✔
956
        }
957
    }
958

959
    private final java.util.Map<String, String[]> messages =
1✔
960
            new java.util.LinkedHashMap<String, String[]>();
961
    private final String rubOneUnit;
962
    private final String rubTwoUnit;
963
    private final String rubFiveUnit;
964
    private final String rubSex;
965
    private final String kopOneUnit;
966
    private final String kopTwoUnit;
967
    private final String kopFiveUnit;
968
    private final String kopSex;
969
    private final String rubShortUnit;
970
    private final Currency currency;
971
    private final Language language;
972
    private final Pennies pennies;
973

974
    static {
975
        initJsonMap(CURRENCY_LIST);
1✔
976
    }
1✔
977

978
    public static void initJsonMap(final String json) {
979
        jsonMap = FromJson.fromJson(json);
1✔
980
    }
1✔
981

982
    /** Currency. */
983
    public enum Currency {
1✔
984
        /** . */
985
        UAH,
1✔
986
        /** . */
987
        USD,
1✔
988
        /** . */
989
        EUR,
1✔
990
        /** . */
991
        RUR,
1✔
992
        /** . */
993
        PER10,
1✔
994
        /** . */
995
        PER100,
1✔
996
        /** . */
997
        PER1000,
1✔
998
        /** . */
999
        PER10000,
1✔
1000
        /** . */
1001
        Custom
1✔
1002
    }
1003

1004
    /** Language. */
1005
    public enum Language {
1✔
1006
        /** . */
1007
        UKR,
1✔
1008
        /** . */
1009
        ENG,
1✔
1010
        /** . */
1011
        RUS
1✔
1012
    }
1013

1014
    /** Pennies. */
1015
    public enum Pennies {
1✔
1016
        /** . */
1017
        NUMBER,
1✔
1018
        /** . */
1019
        TEXT
1✔
1020
    }
1021

1022
    /**
1023
     * Usage: MoneyToStr moneyToStr = new MoneyToStr( MoneyToStr.Currency.UAH,
1024
     * MoneyToStr.Language.UKR, MoneyToStr.Pennies.NUMBER);
1025
     *
1026
     * @param currency the currency (UAH, RUR, USD, EUR)
1027
     * @param language the language (UKR, RUS, ENG)
1028
     * @param pennies the pennies (NUMBER, TEXT)
1029
     */
1030
    @SuppressWarnings("unchecked")
1031
    public MoneyToStr(Currency currency, Language language, Pennies pennies) {
1✔
1032
        if (currency == null) {
1✔
1033
            throw new IllegalArgumentException("currency is null");
1✔
1034
        }
1035
        if (language == null) {
1✔
1036
            throw new IllegalArgumentException("language is null");
1✔
1037
        }
1038
        if (pennies == null) {
1✔
1039
            throw new IllegalArgumentException("pennies is null");
1✔
1040
        }
1041
        this.currency = currency;
1✔
1042
        this.language = language;
1✔
1043
        this.pennies = pennies;
1✔
1044
        String theISOstr = currency.name();
1✔
1045
        Map<String, Object> languageElement =
1✔
1046
                (Map<String, Object>)
1047
                        ((Map<String, Object>) jsonMap.get("CurrencyList")).get(language.name());
1✔
1048
        List<Map<String, Object>> items = (List<Map<String, Object>>) languageElement.get("item");
1✔
1049
        for (Map<String, Object> languageItem : items) {
1✔
1050
            messages.put(
1✔
1051
                    (String) languageItem.get("-value"),
1✔
1052
                    ((String) languageItem.get("-text")).split(","));
1✔
1053
        }
1✔
1054
        List<Map<String, Object>> theISOElements =
1✔
1055
                (List<Map<String, Object>>)
1056
                        ((Map<String, Object>) jsonMap.get("CurrencyList")).get(theISOstr);
1✔
1057
        Map<String, Object> theISOElement = null;
1✔
1058
        for (Map<String, Object> theISOElementLocal : theISOElements) {
1✔
1059
            if (theISOElementLocal.get("-language").equals(language.name())) {
1✔
1060
                theISOElement = theISOElementLocal;
1✔
1061
                break;
1✔
1062
            }
1063
        }
1✔
1064
        rubOneUnit = (String) theISOElement.get("-RubOneUnit");
1✔
1065
        rubTwoUnit = (String) theISOElement.get("-RubTwoUnit");
1✔
1066
        rubFiveUnit = (String) theISOElement.get("-RubFiveUnit");
1✔
1067
        kopOneUnit = (String) theISOElement.get("-KopOneUnit");
1✔
1068
        kopTwoUnit = (String) theISOElement.get("-KopTwoUnit");
1✔
1069
        kopFiveUnit = (String) theISOElement.get("-KopFiveUnit");
1✔
1070
        rubSex = (String) theISOElement.get("-RubSex");
1✔
1071
        kopSex = (String) theISOElement.get("-KopSex");
1✔
1072
        rubShortUnit =
1✔
1073
                theISOElement.containsKey("-RubShortUnit")
1✔
1074
                        ? (String) theISOElement.get("-RubShortUnit")
1✔
1075
                        : "";
1076
    }
1✔
1077

1078
    /**
1079
     * Inits class with currency. Usage: MoneyToStr moneyToStr = new MoneyToStr(
1080
     * MoneyToStr.Currency.UAH, MoneyToStr.Language.UKR, MoneyToStr.Pennies.NUMBER);
1081
     *
1082
     * @param currency the currency (UAH, RUR, USD, EUR)
1083
     * @param language the language (UKR, RUS, ENG)
1084
     * @param pennies the pennies (NUMBER, TEXT)
1085
     * @param names the custom names
1086
     */
1087
    @SuppressWarnings("unchecked")
1088
    public MoneyToStr(Currency currency, Language language, Pennies pennies, String[] names) {
1✔
1089
        if (currency == null) {
1✔
1090
            throw new IllegalArgumentException("currency is null");
1✔
1091
        }
1092
        if (language == null) {
1✔
1093
            throw new IllegalArgumentException("language is null");
1✔
1094
        }
1095
        if (pennies == null) {
1✔
1096
            throw new IllegalArgumentException("pennies is null");
1✔
1097
        }
1098
        if (names == null || names.length != 8) {
1✔
1099
            throw new IllegalArgumentException("names is null");
1✔
1100
        }
1101
        this.currency = currency;
1✔
1102
        this.language = language;
1✔
1103
        this.pennies = pennies;
1✔
1104
        Map<String, Object> languageElement =
1✔
1105
                (Map<String, Object>)
1106
                        ((Map<String, Object>) jsonMap.get("CurrencyList")).get(language.name());
1✔
1107
        List<Map<String, Object>> items = (List<Map<String, Object>>) languageElement.get("item");
1✔
1108
        for (Map<String, Object> languageItem : items) {
1✔
1109
            messages.put(
1✔
1110
                    (String) languageItem.get("-value"),
1✔
1111
                    ((String) languageItem.get("-text")).split(","));
1✔
1112
        }
1✔
1113
        rubOneUnit = names[0];
1✔
1114
        rubTwoUnit = names[1];
1✔
1115
        rubFiveUnit = names[2];
1✔
1116
        rubSex = names[3];
1✔
1117
        kopOneUnit = names[4];
1✔
1118
        kopTwoUnit = names[5];
1✔
1119
        kopFiveUnit = names[6];
1✔
1120
        kopSex = names[7];
1✔
1121
        rubShortUnit = names[0];
1✔
1122
    }
1✔
1123

1124
    /**
1125
     * Converts percent to string.
1126
     *
1127
     * @param amount the amount of percent
1128
     * @param lang the language (RUS, UKR)
1129
     * @return the string of percent
1130
     */
1131
    public static String percentToStr(Double amount, Language lang) {
1132
        return percentToStr(amount, lang, Pennies.TEXT);
1✔
1133
    }
1134

1135
    /**
1136
     * Converts percent to string.
1137
     *
1138
     * @param amount the amount of percent
1139
     * @param lang the language (RUS, UKR, ENG)
1140
     * @param pennies the pennies (NUMBER, TEXT)
1141
     * @return the string of percent
1142
     */
1143
    public static String percentToStr(Double amount, Language lang, Pennies pennies) {
1144
        if (amount == null) {
1✔
1145
            throw new IllegalArgumentException("amount is null");
1✔
1146
        }
1147
        if (lang == null) {
1✔
1148
            throw new IllegalArgumentException("language is null");
1✔
1149
        }
1150
        if (pennies == null) {
1✔
1151
            throw new IllegalArgumentException("pennies is null");
1✔
1152
        }
1153
        Long intPart = amount.longValue();
1✔
1154
        final long fractPart;
1155
        final String result;
1156
        int fractCount = BigDecimal.valueOf(amount).scale();
1✔
1157
        if (amount.floatValue() == amount.intValue()) {
1✔
1158
            result = new MoneyToStr(Currency.PER10, lang, pennies).convert(amount.longValue(), 0L);
1✔
1159
        } else if (fractCount == 1) {
1✔
1160
            fractPart = Math.round((amount - intPart) * NUM10);
1✔
1161
            result = new MoneyToStr(Currency.PER10, lang, pennies).convert(intPart, fractPart);
1✔
1162
        } else if (fractCount == 2) {
1✔
1163
            fractPart = Math.round((amount - intPart) * NUM100);
1✔
1164
            result = new MoneyToStr(Currency.PER100, lang, pennies).convert(intPart, fractPart);
1✔
1165
        } else if (fractCount == 3) {
1✔
1166
            fractPart = Math.round((amount - intPart) * NUM1000);
1✔
1167
            result = new MoneyToStr(Currency.PER1000, lang, pennies).convert(intPart, fractPart);
1✔
1168
        } else {
1169
            fractPart = Math.round((amount - intPart) * NUM10000);
1✔
1170
            result = new MoneyToStr(Currency.PER10000, lang, pennies).convert(intPart, fractPart);
1✔
1171
        }
1172
        return result;
1✔
1173
    }
1174

1175
    /**
1176
     * Converts double value to the text description.
1177
     *
1178
     * @param theMoney the amount of money in format major.minor
1179
     * @return the string description of money value
1180
     */
1181
    public String convert(Double theMoney) {
1182
        if (theMoney == null) {
1✔
1183
            throw new IllegalArgumentException("theMoney is null");
1✔
1184
        }
1185
        Long intPart = theMoney.longValue();
1✔
1186
        Long fractPart = Math.round((theMoney - intPart) * NUM100);
1✔
1187
        if (currency == Currency.PER1000) {
1✔
1188
            fractPart = Math.round((theMoney - intPart) * NUM1000);
1✔
1189
        }
1190
        return convert(intPart, fractPart);
1✔
1191
    }
1192

1193
    /**
1194
     * Converts amount to words. Usage: MoneyToStr moneyToStr = new
1195
     * MoneyToStr(MoneyToStr.Currency.UAH, MoneyToStr.Language.UKR, MoneyToStr.Pennies.NUMBER);
1196
     * String result = moneyToStr.convert(123D); Expected: result = сто двадцять три гривні 00
1197
     * копійок
1198
     *
1199
     * @param theMoney the amount of money major currency
1200
     * @param theKopeiki the amount of money minor currency
1201
     * @return the string description of money value
1202
     */
1203
    public String convert(Long theMoney, Long theKopeiki) {
1204
        if (theMoney == null) {
1✔
1205
            throw new IllegalArgumentException("theMoney is null");
1✔
1206
        }
1207
        if (theKopeiki == null) {
1✔
1208
            throw new IllegalArgumentException("theKopeiki is null");
1✔
1209
        }
1210
        StringBuilder money2str = new StringBuilder();
1✔
1211
        Long triadNum = 0L;
1✔
1212
        Long theTriad;
1213

1214
        Long intPart = Math.abs(theMoney);
1✔
1215
        if (intPart == 0) {
1✔
1216
            money2str.append(messages.get("0")[0] + " ");
1✔
1217
        }
1218
        do {
1219
            theTriad = intPart % NUM1000;
1✔
1220
            money2str.insert(0, triad2Word(theTriad, triadNum, rubSex));
1✔
1221
            if (triadNum == 0) {
1✔
1222
                if ((theTriad % NUM100) / NUM10 == NUM1) {
1✔
1223
                    money2str.append(rubFiveUnit);
1✔
1224
                } else {
1225
                    switch (Long.valueOf(theTriad % NUM10).byteValue()) {
1✔
1226
                        case NUM1:
1227
                            money2str.append(rubOneUnit);
1✔
1228
                            break;
1✔
1229
                        case NUM2:
1230
                        case NUM3:
1231
                        case NUM4:
1232
                            money2str.append(rubTwoUnit);
1✔
1233
                            break;
1✔
1234
                        default:
1235
                            money2str.append(rubFiveUnit);
1✔
1236
                            break;
1237
                    }
1238
                }
1239
            }
1240
            intPart /= NUM1000;
1✔
1241
            triadNum++;
1✔
1242
        } while (intPart > 0);
1✔
1243

1244
        if (theMoney < 0) {
1✔
1245
            money2str.insert(0, messages.get("minus")[0] + " ");
1✔
1246
        }
1247
        if (pennies == Pennies.TEXT) {
1✔
1248
            money2str
1✔
1249
                    .append(language == Language.ENG ? " and " : " ")
1✔
1250
                    .append(
1✔
1251
                            theKopeiki == 0
1✔
1252
                                    ? messages.get("0")[0] + " "
1✔
1253
                                    : triad2Word(Math.abs(theKopeiki), 0L, kopSex));
1✔
1254
        } else {
1255
            money2str.append(
1✔
1256
                    " "
1257
                            + (Math.abs(theKopeiki) < 10
1✔
1258
                                    ? "0" + Math.abs(theKopeiki)
1✔
1259
                                    : Math.abs(theKopeiki))
1✔
1260
                            + " ");
1261
        }
1262
        if (theKopeiki >= NUM11 && theKopeiki <= NUM14) {
1✔
1263
            money2str.append(kopFiveUnit);
1✔
1264
        } else {
1265
            switch ((byte) (theKopeiki % NUM10)) {
1✔
1266
                case NUM1:
1267
                    money2str.append(kopOneUnit);
1✔
1268
                    break;
1✔
1269
                case NUM2:
1270
                case NUM3:
1271
                case NUM4:
1272
                    money2str.append(kopTwoUnit);
1✔
1273
                    break;
1✔
1274
                default:
1275
                    money2str.append(kopFiveUnit);
1✔
1276
                    break;
1277
            }
1278
        }
1279
        return money2str.toString().trim();
1✔
1280
    }
1281

1282
    private String triad2Word(Long triad, Long triadNum, String sex) {
1283
        final StringBuilder triadWord = new StringBuilder(NUM100);
1✔
1284

1285
        if (triad == 0) {
1✔
1286
            return "";
1✔
1287
        }
1288

1289
        triadWord.append(
1✔
1290
                concat(new String[] {""}, messages.get("100_900"))[
1✔
1291
                        Long.valueOf(triad / NUM100).byteValue()]);
1✔
1292
        final Long range10 = (triad % NUM100) / NUM10;
1✔
1293
        triadWord.append(concat(new String[] {"", ""}, messages.get("20_90"))[range10.byteValue()]);
1✔
1294
        if (language == Language.ENG && triadWord.length() > 0 && triad % NUM10 == 0) {
1✔
1295
            triadWord.deleteCharAt(triadWord.length() - 1);
1✔
1296
            triadWord.append(" ");
1✔
1297
        }
1298

1299
        check2(triadNum, sex, triadWord, triad, range10);
1✔
1300
        switch (triadNum.byteValue()) {
1✔
1301
            case NUM0:
1302
                break;
1✔
1303
            case NUM1:
1304
            case NUM2:
1305
            case NUM3:
1306
            case NUM4:
1307
                if (range10 == NUM1) {
1✔
1308
                    triadWord.append(messages.get("1000_10")[triadNum.byteValue() - 1] + " ");
1✔
1309
                } else {
1310
                    final Long range = triad % NUM10;
1✔
1311
                    switch (range.byteValue()) {
1✔
1312
                        case NUM1:
1313
                            triadWord.append(
1✔
1314
                                    messages.get("1000_1")[triadNum.byteValue() - 1] + " ");
1✔
1315
                            break;
1✔
1316
                        case NUM2:
1317
                        case NUM3:
1318
                        case NUM4:
1319
                            triadWord.append(
1✔
1320
                                    messages.get("1000_234")[triadNum.byteValue() - 1] + " ");
1✔
1321
                            break;
1✔
1322
                        default:
1323
                            triadWord.append(
1✔
1324
                                    messages.get("1000_5")[triadNum.byteValue() - 1] + " ");
1✔
1325
                            break;
1326
                    }
1327
                }
1328
                break;
1✔
1329
            default:
1330
                triadWord.append("??? ");
1✔
1331
                break;
1332
        }
1333
        return triadWord.toString();
1✔
1334
    }
1335

1336
    /**
1337
     * @param triadNum the triad num
1338
     * @param sex the sex
1339
     * @param triadWord the triad word
1340
     * @param triad the triad
1341
     * @param range10 the range 10
1342
     */
1343
    private void check2(
1344
            Long triadNum, String sex, StringBuilder triadWord, Long triad, Long range10) {
1345
        final Long range = triad % NUM10;
1✔
1346
        if (range10 == 1) {
1✔
1347
            triadWord.append(messages.get("10_19")[range.byteValue()] + " ");
1✔
1348
        } else {
1349
            switch (range.byteValue()) {
1✔
1350
                case NUM1:
1351
                    if (triadNum == NUM1) {
1✔
1352
                        triadWord.append(messages.get("1")[INDEX_0] + " ");
1✔
1353
                    } else if (triadNum == NUM2 || triadNum == NUM3 || triadNum == NUM4) {
1✔
1354
                        triadWord.append(messages.get("1")[INDEX_1] + " ");
1✔
1355
                    } else if ("M".equals(sex)) {
1✔
1356
                        triadWord.append(messages.get("1")[INDEX_2] + " ");
1✔
1357
                    } else if ("F".equals(sex)) {
1✔
1358
                        triadWord.append(messages.get("1")[INDEX_3] + " ");
1✔
1359
                    }
1360
                    break;
1361
                case NUM2:
1362
                    if (triadNum == NUM1) {
1✔
1363
                        triadWord.append(messages.get("2")[INDEX_0] + " ");
1✔
1364
                    } else if (triadNum == NUM2 || triadNum == NUM3 || triadNum == NUM4) {
1✔
1365
                        triadWord.append(messages.get("2")[INDEX_1] + " ");
1✔
1366
                    } else if ("M".equals(sex)) {
1✔
1367
                        triadWord.append(messages.get("2")[INDEX_2] + " ");
1✔
1368
                    } else if ("F".equals(sex)) {
1✔
1369
                        triadWord.append(messages.get("2")[INDEX_3] + " ");
1✔
1370
                    }
1371
                    break;
1372
                case NUM3:
1373
                case NUM4:
1374
                case NUM5:
1375
                case NUM6:
1376
                case NUM7:
1377
                case NUM8:
1378
                case NUM9:
1379
                    triadWord.append(
1✔
1380
                            concat(new String[] {"", "", ""}, messages.get("3_9"))[
1✔
1381
                                            range.byteValue()]
1✔
1382
                                    + " ");
1383
                    break;
1✔
1384
                default:
1385
                    break;
1386
            }
1387
        }
1388
    }
1✔
1389

1390
    private <T> T[] concat(T[] first, T[] second) {
1391
        final T[] result = java.util.Arrays.copyOf(first, first.length + second.length);
1✔
1392
        System.arraycopy(second, 0, result, first.length, second.length);
1✔
1393
        return result;
1✔
1394
    }
1395

1396
    public static void main(String[] args) {
1397
        String amount = "123.25";
1✔
1398
        String language = "ENG";
1✔
1399
        String currency = "USD";
1✔
1400
        String pennies = "TEXT";
1✔
1401
        if (args.length == 0) {
1✔
1402
            System.out.println(
1✔
1403
                    "Usage: java -jar moneytostr.jar --amount=123.25 --language=rus|ukr|eng --currency=rur|uah|usd|eur --pennies=text|number");
1404
        } else {
1405
            for (String arg : args) {
1✔
1406
                if (arg.startsWith("--amount=")) {
1✔
1407
                    amount = arg.substring("--amount=".length()).trim().replace(",", ".");
1✔
1408
                } else if (arg.startsWith("--language=")) {
1✔
1409
                    language = arg.substring("--language=".length()).trim().toUpperCase();
1✔
1410
                } else if (arg.startsWith("--currency=")) {
1✔
1411
                    currency = arg.substring("--currency=".length()).trim().toUpperCase();
1✔
1412
                } else if (arg.startsWith("--pennies=")) {
1✔
1413
                    pennies = arg.substring("--pennies=".length()).trim().toUpperCase();
1✔
1414
                }
1415
            }
1416
            String result =
1✔
1417
                    new MoneyToStr(
1418
                                    Currency.valueOf(currency),
1✔
1419
                                    Language.valueOf(language),
1✔
1420
                                    Pennies.valueOf(pennies))
1✔
1421
                            .convert(Double.valueOf(amount));
1✔
1422
            System.out.println(result);
1✔
1423
        }
1424
    }
1✔
1425

1426
    public java.util.Map<String, String[]> getMessages() {
1427
        return messages;
1✔
1428
    }
1429

1430
    public String getRubShortUnit() {
1431
        return rubShortUnit;
1✔
1432
    }
1433

1434
    public Language getLanguage() {
1435
        return language;
1✔
1436
    }
1437
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc