/* * Copyright 2014 Mikhail Vorontsov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package info.javaperformance.money; import java.math.BigDecimal; import java.math.MathContext; /** * Some shared methods are kept here */ abstract class AbstractMoney implements Money { /** * Add another Money object to this one. * * @param other Other Money object * @return A new Money object normalized to the efficient representation if possible */ public Money add( final Money other ) { if ( other instanceof MoneyLong ) return add( ( MoneyLong ) other ); else return add( ( MoneyBigDecimal ) other ); } protected abstract Money add( final MoneyLong other ); protected Money add( final MoneyBigDecimal other ) { final BigDecimal res = toBigDecimal().add( other.toBigDecimal(), MathContext.DECIMAL128 ); return MoneyFactory.fromBigDecimal( res ); } public boolean isZero() { return this.toDouble() == 0; } /** * Subtract another Money object from this one. * * @param other Other money object * @return A new Money object normalized to the efficient representation if possible */ public Money subtract( final Money other ) { return add( other.negate() ); } /** * Compares another Money object to this one. Should be used like {@link BigDecimal#compareTo(Object)}. May or may * not share the same specification, read return. However this method is up to specification as defined in * {@link Comparable} * <p> * Two {@code Money} objects that are equal in value but have a different scale (like 2.0 and 2.00) * are considered equal by this method. This method is provided in preference to individual methods for each of * the six boolean comparison operators ({@literal <}, ==, {@literal >}, {@literal >=}, !=, {@literal <=}). The * suggested idiom for performing these comparisons is: {@code (x.compareTo(y)} <<i>op</i>> {@code 0)}, where * {@code op} is one of the six comparison operators. * @param other Other money object * @return As of this version, -1, 0, or 1 as this {@code Money} is numerically less than, equal to, or greater * than {@code other}. This specification may possibly change to -x or x with x representing the difference in * precision. I.E If the number is negative than it will still be numerically less than {@code other}. */ public int compareTo(final Money other) { if (other instanceof MoneyLong) return compareTo((MoneyLong) other); else return compareTo((MoneyBigDecimal) other); } protected abstract int compareTo(final MoneyLong other); public int compareTo(final MoneyBigDecimal other) { return toBigDecimal().compareTo(other.toBigDecimal()); } }