blob: 79902d3c5fb520ce6df81a872a88c7803df2a713 [file] [log] [blame]
/**
* Copyright (c) 2005, 2013, Werner Keil and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Werner Keil, Jean-Marie Dautelle - initial API and implementation
*/
package org.eclipse.uomo.business.money;
import static java.util.FormattableFlags.LEFT_JUSTIFY;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Formattable;
import java.util.Formatter;
import java.util.List;
import org.eclipse.osgi.util.NLS;
import org.eclipse.uomo.business.internal.CurrencyUnit;
import org.eclipse.uomo.business.internal.ExchangeRate;
import org.eclipse.uomo.business.internal.Messages;
import org.eclipse.uomo.business.types.IMoney;
import javax.measure.Unit;
import javax.measure.UnitConverter;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.ULocale;
/**
* <p>
* This class represents a converter between two currencies.
* </p>
*
* <p>
* Currency converters convert values based upon the current exchange rate
* {@link Currency#getExchangeRate() exchange rate}. If the
* {@link Currency#getExchangeRate() exchange rate} from the target currency to
* the source currency is not set, conversion fails. In others words, the
* converter from a currency <code>A</code> to a currency <code>B</code> is
* independant from the converter from <code>B</code> to <code>A</code>.
* </p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @author <a href="mailto:units@catmedia.us">Werner Keil</a>
* @version 5.4, $Date: 2020-03-17 $
* @deprecated use JSR 354
*/
public class MoneyConverter implements UnitConverter, Formattable {
/**
*
*/
private static final long serialVersionUID = -3943843029548497620L;
/**
* Holds the exchange rate.
*/
private final ExchangeRate rate;
private void checkFactor(Number factor) {
if (factor == null)
throw new UnsupportedOperationException(NLS.bind(
Messages.CurrencyConverter_exchangeRate_not_set,
rate.getBase(), rate.getTerm())); //$NON-NLS-1$
}
private CurrencyUnit fromJDK(java.util.Currency currency) {
// TODO use JDKAdapter
return fromICU(Currency.getInstance(currency.getCurrencyCode()));
}
private CurrencyUnit fromICU(Currency currency) {
return MoneyCurrency.of(currency);
}
/**
* Creates the currency converter from the source currency to the target
* currency.
*
* @param source
* the source currency.
* @param target
* the target currency.
* @param factor
* the multiplier factor from source to target.
* @return the corresponding converter.
*/
private MoneyConverter(CurrencyUnit source, CurrencyUnit target, Number factor) {
rate = new MoneyExchangeRate(source, target, factor);
}
/**
* Creates the currency converter from the source currency to the target
* currency.
*
* @param source
* the source currency.
* @param target
* the target currency.
* @param factor
* the multiplier factor from source to target.
* @return the corresponding converter.
*/
private MoneyConverter(Currency source, Currency target, Number factor) {
rate = new MoneyExchangeRate(fromICU(source), fromICU(target), factor);
}
/**
* Creates the currency converter from the source currency to the target
* currency.
*
* @param source
* the source currency.
* @param target
* the target currency.
* @param factor
* the multiplier factor from source to target.
* @return the corresponding converter.
*/
@SuppressWarnings("unchecked")
public MoneyConverter(Unit<?> source, Unit<IMoney> target,
Number factor) {
CurrencyUnit defCurrency = MoneyCurrency.of(Currency.getInstance(ULocale.getDefault()));
rate = new MoneyExchangeRate(defCurrency, defCurrency, factor);
}
/**
* Creates the currency converter from the source currency to the target
* currency using <strong>JDK</strong> types.
*
* @param source
* the source currency (<strong>JDK</strong>).
* @param target
* the target currency (<strong>JDK</strong>).
* @param factor
* the multiplier factor from source to target.
* @return the corresponding converter.
*/
public MoneyConverter(java.util.Currency source,
java.util.Currency target, Number factor) {
rate = new MoneyExchangeRate(fromJDK(source), fromJDK(target), factor);
}
/**
* Returns the source currency.
*
* @return the source currency.
*/
public CurrencyUnit getSource() {
return rate.getBase();
}
/**
* Returns the target currency.
*
* @return the target currency.
*/
public CurrencyUnit getTarget() {
return rate.getTerm();
}
public MoneyConverter inverse() {
return new MoneyConverter(getTarget(), getSource(),
rate.getFactor());
}
public MoneyConverter negate() {
return new MoneyConverter(getSource(), getTarget(), -rate
.getFactor().doubleValue());
}
public double convert(double value) {
// Number factor = getExchangeRate(rate.getTarget());
Number factor = rate.getFactor();
checkFactor(factor);
return factor.doubleValue() * value;
}
public BigDecimal convert(BigDecimal value, MathContext ctx)
throws ArithmeticException {
// Number factor = rate.getSource().getExchangeRate(rate.getTarget());
Number factor = rate.getFactor();
checkFactor(factor);
if (factor instanceof BigDecimal)
return value.multiply((BigDecimal) factor, ctx);
if (factor instanceof Number) {
return value.multiply(
(BigDecimal.valueOf(((Number) factor).doubleValue())), ctx);
} else { // Reverts to double convert.
return value
.multiply(BigDecimal.valueOf(factor.doubleValue()), ctx);
}
}
public Number convert(Number value) {
if (value instanceof BigDecimal) {
return convert((BigDecimal) value, MathContext.DECIMAL128);
} else {
return convert(value.doubleValue());
}
}
@Override
public boolean equals(Object cvtr) {
if (!(cvtr instanceof MoneyConverter))
return false;
MoneyConverter that = (MoneyConverter) cvtr;
return this.getSource().equals(that.getSource())
&& this.getTarget().equals(that.getTarget());
}
@Override
public int hashCode() {
return getSource().hashCode() + getTarget().hashCode();
}
@Override
public final String toString() {
if (getSource().equals(getTarget())) {
return getSource().getCurrencyCode();
}
return String.format(Messages.CurrencyConverter_toString, getSource()
.getCurrencyCode(), getTarget().getCurrencyCode());
}
public boolean isLinear() {
return true;
}
public UnitConverter concatenate(UnitConverter converter) {
// TODO Auto-generated method stub
return null;
}
public List<UnitConverter> getCompoundConverters() {
// TODO Auto-generated method stub
return null;
}
public boolean isIdentity() {
return false;
}
public ExchangeRate getExchangeRate() {
return rate;
}
public void formatTo(Formatter fmt, int f, int width, int precision) {
StringBuilder sb = new StringBuilder();
// decide form of name
String name = getSource().toString();
String symbol = getSource().getCurrencyCode();
// if (fmt.locale().equals(Locale.FRANCE))
// name = frenchCompanyName;
// boolean alternate = (f & ALTERNATE) == ALTERNATE;
boolean usesymbol = true; // alternate || (precision != -1 && precision
// < 10);
String out = (usesymbol ? symbol : name);
// apply precision
if (precision == -1 || out.length() < precision) {
// write it all
sb.append(out);
} else {
sb.append(out.substring(0, precision - 1)).append('*');
}
// apply width and justification
int len = sb.length();
if (len < width)
for (int i = 0; i < width - len; i++)
if ((f & LEFT_JUSTIFY) == LEFT_JUSTIFY)
sb.append(' ');
else
sb.insert(0, ' ');
fmt.format(sb.toString());
}
@Override
public List<? extends UnitConverter> getConversionSteps() {
// TODO Auto-generated method stub
return null;
}
}