17
17
18
18
import static java .lang .Math .abs ;
19
19
import static java .lang .Math .floor ;
20
+ import static java .util .Objects .requireNonNull ;
20
21
22
+ import java .math .RoundingMode ;
21
23
import java .text .DecimalFormat ;
22
24
import java .text .DecimalFormatSymbols ;
23
25
import java .text .NumberFormat ;
24
26
import java .text .ParsePosition ;
25
27
import java .util .Locale ;
26
28
import java .util .Optional ;
29
+ import java .util .concurrent .atomic .AtomicReference ;
27
30
28
31
/**
29
32
* Represents one of the existing location fields: latitude, longitude and
30
33
* elevation.
31
34
*
32
35
* @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
33
- * @version 2.2
36
+ * @version !__version__!
34
37
* @since 1.4
35
38
*/
36
39
abstract class Field implements Format {
37
40
38
- final static DecimalFormatSymbols SYMBOLS =
41
+ static final DecimalFormatSymbols SYMBOLS =
39
42
DecimalFormatSymbols .getInstance (Locale .US );
40
43
41
- protected NumberFormat _numberFormat ;
42
- protected final String _pattern ;
44
+ final String _pattern ;
43
45
44
- Field (final String pattern ){
45
- final var decimalPattern = toDecimalPattern (pattern );
46
- _numberFormat = new DecimalFormat (decimalPattern , SYMBOLS );
47
- _pattern = pattern ;
46
+ private final AtomicReference <NumberFormat > _format = new AtomicReference <>();
47
+
48
+ Field (final String pattern ) {
49
+ _pattern = requireNonNull (pattern );
50
+ _format .set (new DecimalFormat (toDecimalPattern (pattern ), SYMBOLS ));
48
51
}
49
52
50
53
/**
@@ -57,6 +60,18 @@ abstract class Field implements Format {
57
60
void setPrefixSign (final boolean b ) {
58
61
}
59
62
63
+ void setFormat (final NumberFormat format ) {
64
+ _format .set (requireNonNull (format ));
65
+ }
66
+
67
+ void setRoundingMode (final RoundingMode mode ) {
68
+ _format .get ().setRoundingMode (mode );
69
+ }
70
+
71
+ int getMinimumFractionDigits () {
72
+ return _format .get ().getMinimumFractionDigits ();
73
+ }
74
+
60
75
static double toMinutes (final double degrees ) {
61
76
double dd = abs (degrees );
62
77
return (dd - floor (dd )) * 60.0 ;
@@ -108,21 +123,43 @@ public String toPattern() {
108
123
return _pattern ;
109
124
}
110
125
111
- double parseDouble (final CharSequence in , final ParsePosition pos ) {
126
+ /**
127
+ * Formatting the given double value with the field formatter.
128
+ *
129
+ * @param value the double value to format
130
+ * @return the formatted double value
131
+ */
132
+ String format (final double value ) {
133
+ return _format .get ().format (value );
134
+ }
135
+
136
+ /**
137
+ * Parsers the given input string.
138
+ *
139
+ * @param in the input string to parse
140
+ * @param pos the parse position
141
+ * @return the parsed double value
142
+ */
143
+ double parse (final CharSequence in , final ParsePosition pos ) {
112
144
int i = pos .getIndex ();
113
145
String s = in .toString ();
114
- boolean strictWidth = 1 < _numberFormat .getMinimumIntegerDigits (); //better?
146
+ boolean strictWidth = 1 < _format . get () .getMinimumIntegerDigits (); //better?
115
147
if (strictWidth ) {
116
148
int end = i + toPattern ().length (); // toPattern() rather than pattern because LatitudeDegree.toPattern()
117
149
s = in .subSequence (0 , end ).toString (); // don't eat more digits
118
150
}
119
151
120
- Number n = _numberFormat .parse (s , pos );
152
+ final Number n ;
153
+ synchronized (_format ) {
154
+ n = _format .get ().parse (s , pos );
155
+ }
156
+
121
157
if (i == pos .getIndex ()) {
122
158
pos .setErrorIndex (i );
123
159
throw new ParseException ("Not found " + _pattern , in , i );
124
160
}
125
161
126
162
return n .doubleValue ();
127
163
}
164
+
128
165
}
0 commit comments