001/*
002 * Copyright (c) 2012, 2013, Werner Keil, Credit Suisse (Anatole Tresch). Licensed under the Apache
003 * License, Version 2.0 (the "License"); you may not use this file except in compliance with the
004 * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
005 * Unless required by applicable law or agreed to in writing, software distributed under the License
006 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
007 * or implied. See the License for the specific language governing permissions and limitations under
008 * the License. Contributors: Anatole Tresch - initial version.
009 */
010package org.javamoney.tck.tests.internal;
011
012import javax.money.CurrencyUnit;
013import javax.money.MonetaryAmount;
014import javax.money.MonetaryAmountFactory;
015import javax.money.MonetaryContext;
016import javax.money.MonetaryContextBuilder;
017import javax.money.Monetary;
018import javax.money.MonetaryException;
019import javax.money.MonetaryOperator;
020import javax.money.MonetaryQuery;
021import javax.money.NumberValue;
022import java.io.Serializable;
023import java.math.BigDecimal;
024import java.util.Objects;
025
026/**
027 * Test amount class.
028 */
029public final class TestAmount implements MonetaryAmount, Serializable {
030
031    private BigDecimal value;
032    private CurrencyUnit currencyUnit;
033    public static final MonetaryContext MONETARY_CONTEXT =
034            MonetaryContextBuilder.of().setAmountType(TestAmount.class).setMaxScale(-1).setPrecision(0).build();
035
036    public TestAmount(Number number, CurrencyUnit currency) {
037        this.currencyUnit = currency;
038        this.value = new BigDecimal(String.valueOf(number));
039    }
040
041    @Override
042    public MonetaryAmount with(MonetaryOperator operator) {
043        try {
044            return operator.apply(this);
045        } catch (MonetaryException e) {
046            throw e;
047        } catch (Exception e) {
048            throw new MonetaryException("Exception during operator execution.", e);
049        }
050    }
051
052    @Override
053    public MonetaryAmountFactory<? extends MonetaryAmount> getFactory() {
054
055
056        return new MonetaryAmountFactory<TestAmount>() {
057
058            private CurrencyUnit currency = TestAmount.this.currencyUnit;
059            private BigDecimal number = TestAmount.this.value;
060
061            @Override
062            public Class<? extends MonetaryAmount> getAmountType() {
063                return TestAmount.class;
064            }
065
066            @Override
067            public MonetaryAmountFactory setCurrency(String currencyCode) {
068                this.currency = Monetary.getCurrency(currencyCode);
069                return this;
070            }
071
072            @Override
073            public MonetaryAmountFactory setCurrency(CurrencyUnit currency) {
074                Objects.requireNonNull(currency);
075                this.currency = currency;
076                return this;
077            }
078
079            @Override
080            public MonetaryAmountFactory setNumber(double number) {
081                Objects.requireNonNull(number);
082                this.number = new BigDecimal(String.valueOf(number));
083                return this;
084            }
085
086            @Override
087            public MonetaryAmountFactory setNumber(long number) {
088                Objects.requireNonNull(number);
089                this.number = new BigDecimal(String.valueOf(number));
090                return this;
091            }
092
093            @Override
094            public MonetaryAmountFactory setNumber(Number number) {
095                Objects.requireNonNull(number);
096                this.number = new BigDecimal(String.valueOf(number));
097                return this;
098            }
099
100            @Override
101            public NumberValue getMaxNumber() {
102                return null;
103            }
104
105            @Override
106            public NumberValue getMinNumber() {
107                return null;
108            }
109
110            @Override
111            public MonetaryAmountFactory setContext(MonetaryContext monetaryContext) {
112                return this;
113            }
114
115            @Override
116            public MonetaryAmountFactory setAmount(MonetaryAmount amount) {
117                this.currency = amount.getCurrency();
118                this.number = amount.getNumber().numberValue(BigDecimal.class);
119                return this;
120            }
121
122            @Override
123            public TestAmount create() {
124                return new TestAmount(number, currency);
125            }
126
127            @Override
128            public MonetaryContext getDefaultMonetaryContext() {
129                return MONETARY_CONTEXT;
130            }
131
132            @Override
133            public MonetaryContext getMaximalMonetaryContext() {
134                return MONETARY_CONTEXT;
135            }
136        };
137    }
138
139    @Override
140    public MonetaryAmount subtract(MonetaryAmount amount) {
141        return this;
142    }
143
144    @Override
145    public MonetaryAmount stripTrailingZeros() {
146        value = value.stripTrailingZeros();
147        return this;
148    }
149
150    @Override
151    public int signum() {
152        return value.signum();
153    }
154
155    @Override
156    public MonetaryAmount add(MonetaryAmount amount) {
157        return null;
158    }
159
160    @Override
161    public MonetaryAmount scaleByPowerOfTen(int power) {
162        return this;
163    }
164
165    @Override
166    public MonetaryAmount abs() {
167        return null;
168    }
169
170    @Override
171    public MonetaryAmount remainder(Number divisor) {
172        return this;
173    }
174
175    @Override
176    public MonetaryAmount[] divideAndRemainder(long divisor) {
177        return new MonetaryAmount[0];
178    }
179
180    @Override
181    public MonetaryAmount[] divideAndRemainder(double divisor) {
182        return new MonetaryAmount[0];
183    }
184
185    @Override
186    public MonetaryAmount[] divideAndRemainder(Number divisor) {
187        return new MonetaryAmount[0];
188    }
189
190    @Override
191    public MonetaryAmount divideToIntegralValue(long divisor) {
192        return null;
193    }
194
195    @Override
196    public MonetaryAmount divideToIntegralValue(double divisor) {
197        return null;
198    }
199
200    @Override
201    public MonetaryAmount divideToIntegralValue(Number divisor) {
202        return null;
203    }
204
205    @Override
206    public MonetaryAmount remainder(double divisor) {
207        return this;
208    }
209
210    @Override
211    public MonetaryAmount remainder(long divisor) {
212        return this;
213    }
214
215    @Override
216    public <R> R query(MonetaryQuery<R> query) {
217        return query.queryFrom(this);
218    }
219
220    @Override
221    public MonetaryAmount plus() {
222        return this;
223    }
224
225    @Override
226    public MonetaryAmount negate() {
227        return this;
228    }
229
230    @Override
231    public MonetaryAmount multiply(Number multiplicand) {
232        return new TestAmount(this.value.multiply(new BigDecimal(String.valueOf(multiplicand))), getCurrency());
233    }
234
235    @Override
236    public MonetaryAmount divide(long divisor) {
237        return null;
238    }
239
240    @Override
241    public MonetaryAmount divide(double divisor) {
242        return null;
243    }
244
245    @Override
246    public MonetaryAmount divide(Number divisor) {
247        return null;
248    }
249
250    @Override
251    public MonetaryAmount multiply(double multiplicand) {
252        return this;
253    }
254
255    @Override
256    public MonetaryAmount multiply(long multiplicand) {
257        return this;
258    }
259
260    @Override
261    public boolean isZero() {
262        return false;
263    }
264
265    @Override
266    public boolean isPositiveOrZero() {
267        return true;
268    }
269
270    @Override
271    public boolean isPositive() {
272        return true;
273    }
274
275    @Override
276    public boolean isNegativeOrZero() {
277        return false;
278    }
279
280    @Override
281    public boolean isNegative() {
282        return false;
283    }
284
285    @Override
286    public boolean isLessThanOrEqualTo(MonetaryAmount amount) {
287        return this.value.stripTrailingZeros()
288                .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) == 0;
289    }
290
291    @Override
292    public boolean isLessThan(MonetaryAmount amount) {
293        return this.value.stripTrailingZeros()
294                .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) < 0;
295    }
296
297    @Override
298    public boolean isGreaterThanOrEqualTo(MonetaryAmount amount) {
299        return this.value.stripTrailingZeros()
300                .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) >= 0;
301    }
302
303    @Override
304    public boolean isGreaterThan(MonetaryAmount amount) {
305        return this.value.stripTrailingZeros()
306                .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) > 0;
307    }
308
309    @Override
310    public boolean isEqualTo(MonetaryAmount amount) {
311        return this.value.stripTrailingZeros()
312                .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) == 0;
313    }
314
315    @Override
316    public CurrencyUnit getCurrency() {
317        return currencyUnit;
318    }
319
320    @Override
321    public MonetaryContext getContext() {
322        return MONETARY_CONTEXT;
323    }
324
325    @Override
326    public int compareTo(MonetaryAmount o) {
327        return 0;
328    }
329
330    @Override
331    public String toString() {
332        return currencyUnit.getCurrencyCode() + ' ' + String.valueOf(value);
333    }
334
335    @Override
336    public NumberValue getNumber() {
337        return new TestNumberValue(this.value);
338    }
339
340}