← joda-money  /  src/main/java/org/joda/money/format/SignedPrinterParser.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.format;
17
18
import java.io.IOException;
19
import java.io.Serializable;
20
import java.math.BigDecimal;
21
22
import org.joda.money.BigMoney;
23
24
/**
25
 * Prints and parses using delegated formatters, one for positive and one for megative.
26
 * <p>
27
 * This class is immutable and thread-safe.
28
 */
29
final class SignedPrinterParser implements MoneyPrinter, MoneyParser, Serializable {
30
31
    /** Serialization version. */
32
    private static final long serialVersionUID = 1L;
33
34
    /** The formatter to use when positive. */
35
    private final MoneyFormatter whenPositive;
36
    /** The formatter to use when zero. */
37
    private final MoneyFormatter whenZero;
38
    /** The formatter to use when negative. */
39
    private final MoneyFormatter whenNegative;
40
41
    /**
42
     * Constructor.
43
     * @param whenPositive  the formatter to use when the amount is positive
44
     * @param whenZero  the formatter to use when the amount is zero
45
     * @param whenNegative  the formatter to use when the amount is positive
46
     */
47
    SignedPrinterParser(MoneyFormatter whenPositive, MoneyFormatter whenZero, MoneyFormatter whenNegative) {
48
        this.whenPositive = whenPositive;
49
        this.whenZero = whenZero;
50
        this.whenNegative = whenNegative;
51
    }
52
53
    //-----------------------------------------------------------------------
54
    @Override
55
    public void print(MoneyPrintContext context, Appendable appendable, BigMoney money) throws IOException {
56
        var fmt = (money.isZero() ? whenZero : money.isPositive() ? whenPositive : whenNegative);
57
        fmt.getPrinterParser().print(context, appendable, money);
58
    }
59
60
    @Override
61
    public void parse(MoneyParseContext context) {
62
        var positiveContext = context.createChild();
63
        whenPositive.getPrinterParser().parse(positiveContext);
64
        var zeroContext = context.createChild();
65
        whenZero.getPrinterParser().parse(zeroContext);
66
        var negativeContext = context.createChild();
67
        whenNegative.getPrinterParser().parse(negativeContext);
68
        var best = (MoneyParseContext) null;
69
        if (!positiveContext.isError()) {
70
            best = positiveContext;
71
        }
72
        if (!zeroContext.isError()) {
73
            if (best == null || zeroContext.getIndex() > best.getIndex()) {
74
                best = zeroContext;
75
            }
76
        }
77
        if (!negativeContext.isError()) {
78
            if (best == null || negativeContext.getIndex() > best.getIndex()) {
79
                best = negativeContext;
80
            }
81
        }
82
        if (best == null) {
83
            context.setError();
84
        } else {
85
            context.mergeChild(best);
86
            if (best == zeroContext) {
87
                if (context.getAmount() == null || context.getAmount().compareTo(BigDecimal.ZERO) != 0) {
88
                    context.setAmount(BigDecimal.ZERO);
89
                }
90
            } else if (best == negativeContext && context.getAmount().compareTo(BigDecimal.ZERO) > 0) {
91
                context.setAmount(context.getAmount().negate());
92
            }
93
        }
94
    }
95
96
    @Override
97
    public String toString() {
98
        return "PositiveZeroNegative(" + whenPositive + "," + whenZero + "," + whenNegative + ")";
99
    }
100
101
}
102