1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.util;
17
18 import java.math.BigDecimal;
19
20 import org.apache.commons.lang.StringUtils;
21
22
23
24
25
26
27
28
29
30
31 public abstract class AbstractKualiDecimal<T extends AbstractKualiDecimal> extends Number implements Comparable {
32
33 public static final int ROUND_BEHAVIOR = BigDecimal.ROUND_HALF_UP;
34
35 public static final KualiDecimal ZERO = new KualiDecimal(BigDecimal.ZERO);
36
37 protected BigDecimal value;
38
39 public AbstractKualiDecimal() {
40 }
41
42
43
44
45
46
47
48 public AbstractKualiDecimal(String value, int scale) {
49 if (StringUtils.isBlank(value)) {
50 this.value = BigDecimal.ZERO.setScale(scale,ROUND_BEHAVIOR);
51 } else {
52 this.value = new BigDecimal(value).setScale(scale, ROUND_BEHAVIOR);
53 }
54 }
55
56 public AbstractKualiDecimal(int value, int scale) {
57 this.value = new BigDecimal(value).setScale(scale, ROUND_BEHAVIOR);
58 }
59
60 public AbstractKualiDecimal(double value, int scale) {
61 this.value = new BigDecimal(value).setScale(scale, ROUND_BEHAVIOR);
62 }
63
64 public AbstractKualiDecimal(BigDecimal value, int scale) {
65 this(value.toPlainString(), scale);
66 }
67
68
69
70
71
72
73 public boolean isLessThan(AbstractKualiDecimal operand) {
74 if (operand == null) {
75 throw new IllegalArgumentException("invalid (null) operand");
76 }
77
78 return (this.compareTo(operand) == -1);
79 }
80
81
82
83
84
85
86 public boolean isGreaterThan(AbstractKualiDecimal operand) {
87 if (operand == null) {
88 throw new IllegalArgumentException("invalid (null) operand");
89 }
90
91 return (this.compareTo(operand) == 1);
92 }
93
94
95
96
97
98
99 public boolean isLessEqual(AbstractKualiDecimal operand) {
100 if (operand == null) {
101 throw new IllegalArgumentException("invalid (null) operand");
102 }
103
104 return !isGreaterThan(operand);
105 }
106
107
108
109
110
111
112 public boolean isGreaterEqual(AbstractKualiDecimal operand) {
113 if (operand == null) {
114 throw new IllegalArgumentException("invalid (null) operand");
115 }
116
117 return !isLessThan(operand);
118 }
119
120
121
122
123
124 public static boolean isNumeric(String s) {
125 boolean isValid = false;
126
127 if (!StringUtils.isBlank(s)) {
128 try {
129 new BigDecimal(s);
130 isValid = true;
131 } catch (NumberFormatException e) {
132 }
133 }
134
135 return isValid;
136 }
137
138
139
140
141
142 @Override
143 public double doubleValue() {
144 return this.value.doubleValue();
145 }
146
147
148
149
150 @Override
151 public float floatValue() {
152 return this.value.floatValue();
153 }
154
155
156
157
158 @Override
159 public int intValue() {
160 return this.value.intValue();
161 }
162
163
164
165
166 @Override
167 public long longValue() {
168 return this.value.longValue();
169 }
170
171
172
173
174 public BigDecimal bigDecimalValue() {
175 return this.value;
176 }
177
178
179
180
181
182
183
184
185
186
187
188
189 public int compareTo(Object o) {
190 return compareTo((AbstractKualiDecimal) o);
191 }
192
193
194
195
196
197
198
199 public int compareTo(AbstractKualiDecimal k) {
200 return this.value.compareTo(k.value);
201 }
202
203
204
205
206
207 @Override
208 public boolean equals(Object obj) {
209 boolean equals = false;
210
211 if (obj instanceof AbstractKualiDecimal) {
212 AbstractKualiDecimal k = (AbstractKualiDecimal) obj;
213
214
215
216
217
218
219 equals = (this.compareTo(k) == 0);
220 }
221
222 return equals;
223 }
224
225
226
227
228
229 @Override
230 public int hashCode() {
231 return this.value.hashCode();
232 }
233
234
235
236
237 @Override
238 public String toString() {
239 return this.value.toString();
240 }
241
242
243
244
245 public boolean isNegative() {
246 return (this.compareTo(ZERO) == -1);
247 }
248
249
250
251
252 public boolean isPositive() {
253 return (this.compareTo(ZERO) == 1);
254 }
255
256
257
258
259 public boolean isZero() {
260 return (this.compareTo(ZERO) == 0);
261 }
262
263
264
265
266 public T abs() {
267 T absolute = null;
268
269 if (isNegative()) {
270 absolute = negated();
271 } else {
272 absolute = newInstance(this.value, this.value.scale());
273 }
274
275 return absolute;
276 }
277
278
279
280
281 public boolean isNonZero() {
282 return !this.isZero();
283 }
284
285
286
287
288
289
290
291
292
293
294
295 public T add(T addend) {
296 if (addend == null) {
297 throw new IllegalArgumentException("invalid (null) addend");
298 }
299
300 BigDecimal sum = this.value.add(addend.value);
301 return newInstance(sum, sum.scale());
302 }
303
304
305
306
307
308
309
310
311
312
313
314 public T subtract(T subtrahend) {
315 if (subtrahend == null) {
316 throw new IllegalArgumentException("invalid (null) subtrahend");
317 }
318
319 BigDecimal difference = this.value.subtract(subtrahend.value);
320 return newInstance(difference, difference.scale());
321 }
322
323
324
325
326
327
328
329
330
331
332
333 public T multiply(T multiplier) {
334 return multiply(multiplier, true);
335 }
336
337
338
339
340
341
342
343
344
345
346 public T multiply(T multiplier, boolean applyScale) {
347 if (multiplier == null) {
348 throw new IllegalArgumentException("invalid (null) multiplier");
349 }
350
351 BigDecimal product = this.value.multiply(multiplier.value);
352 return newInstance(product, applyScale ? this.value.scale() : product.scale());
353 }
354
355
356
357
358
359
360
361
362
363
364
365 public T mod(T modulus) {
366 return mod(modulus, true);
367 }
368
369
370
371
372
373
374
375
376
377
378
379
380 public T mod(T modulus, boolean applyScale) {
381 if (modulus == null) {
382 throw new IllegalArgumentException("invalid (null) modulus");
383 }
384 double difference = this.value.doubleValue() % modulus.doubleValue();
385
386 int scaleToApply = applyScale ? this.value.scale() : new BigDecimal(difference).scale();
387
388
389 return (T) newInstance(new BigDecimal(difference), scaleToApply);
390 }
391
392
393
394
395
396
397
398
399
400
401
402 public T divide(T divisor) {
403 return divide(divisor, true);
404 }
405
406
407
408
409
410 public T negated() {
411 return multiply(newInstance("-1"));
412 }
413
414 public T divide(T divisor, boolean applyScale) {
415 if (divisor == null) {
416 throw new IllegalArgumentException("invalid (null) divisor");
417 }
418 BigDecimal quotient = this.value.divide(divisor.value, ROUND_BEHAVIOR);
419
420 T result = newInstance(quotient, applyScale ? this.value.scale() : quotient.scale());
421 return result;
422 }
423
424 protected abstract T newInstance(String value);
425
426 protected abstract T newInstance(double value);
427
428 protected abstract T newInstance(double value, int scale);
429
430 protected abstract T newInstance(BigDecimal value);
431
432 protected abstract T newInstance(BigDecimal value, int scale);
433 }