001/*
002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003 * Copyright (C) 2006 - JScience (http://jscience.org/)
004 * All rights reserved.
005 * 
006 * Permission to use, copy, modify, and distribute this software is
007 * freely granted, provided that this notice is preserved.
008 */
009package javax.measure.converter;
010
011/**
012 * <p> This class represents a converter multiplying numeric values by a 
013 *     constant scaling factor (approximated as a <code>double</code>). 
014 *     For exact scaling conversions {@link RationalConverter} is preferred.</p>
015 *      
016 * <p> Instances of this class are immutable.</p>
017 *
018 * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
019 * @version 3.1, April 22, 2006
020 */
021public final class MultiplyConverter extends UnitConverter {
022
023    /**
024     * Holds the scale factor.
025     */
026    private final double _factor;
027
028    /**
029     * Creates a multiply converter with the specified scale factor.
030     *
031     * @param  factor the scale factor.
032     * @throws IllegalArgumentException if offset is one (or close to one).
033     */
034    public MultiplyConverter(double factor) {
035        if ((float)factor == 1.0)
036            throw new IllegalArgumentException("Identity converter not allowed");
037        _factor = factor;
038    }
039
040    /**
041     * Returns the scale factor.
042     *
043     * @return the scale factor.
044     */
045    public double getFactor() {
046        return _factor;
047    }
048
049    @Override
050    public UnitConverter inverse() {
051        return new MultiplyConverter(1.0 / _factor);
052    }
053
054    @Override
055    public double convert(double amount) {
056        return _factor * amount;
057    }
058
059    @Override
060    public boolean isLinear() {
061        return true;
062    }
063
064    @Override
065    public UnitConverter concatenate(UnitConverter converter) {
066        if (converter instanceof MultiplyConverter) {
067            double factor = _factor * ((MultiplyConverter) converter)._factor;
068            return valueOf(factor);
069        } else if (converter instanceof RationalConverter) {
070            double factor = _factor
071                    * ((RationalConverter) converter).getDividend()
072                    / ((RationalConverter) converter).getDivisor();
073            return valueOf(factor);
074        } else {
075            return super.concatenate(converter);
076        }
077    }
078
079    private static UnitConverter valueOf(double factor) {
080        float asFloat = (float) factor;
081        return asFloat == 1.0f ? UnitConverter.IDENTITY
082                : new MultiplyConverter(factor);
083    }
084
085    private static final long serialVersionUID = 1L;
086}