is.illuminati.block.spyros.garmin.model.Length.java Source code

Java tutorial

Introduction

Here is the source code for is.illuminati.block.spyros.garmin.model.Length.java

Source

/*
 * Copyright 2009 Ilja Booij
 * 
 * This file is part of GarminTrainer.
 * 
 * GarminTrainer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GarminTrainer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with GarminTrainer.  If not, see <http://www.gnu.org/licenses/>.
 */
package is.illuminati.block.spyros.garmin.model;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * Implements a measurement of Length. A Length object is immutable.
 * @author ilja booij <ibooij@gmail.com>
 */
public final class Length implements Comparable<Length>, Serializable {

    private static final long serialVersionUID = 1L;

    public enum Unit {
        Meter(1f, "m", 1), Kilometer(1000f, "km", 3), Foot(0.3048f, "ft", 1), Mile(1609.344f, "mi", 3);

        public final float conversionValue;
        public final String suffix;
        public final NumberFormat format;

        private Unit(final float conversionValue, final String suffix, final int scale) {
            this.conversionValue = conversionValue;
            this.suffix = suffix;

            final StringBuffer sb = new StringBuffer("#0.");
            for (int i = 0; i < scale; i++) {
                sb.append('0');
            }
            format = new DecimalFormat(sb.toString());
        }
    }

    // holds value in meters (the SI unit)
    private final double value;
    private final Unit unit;

    private Length(final double value, final Unit unit) {
        if (unit == null) {
            throw new IllegalArgumentException("unit should be non-null");
        }

        this.value = value * unit.conversionValue;
        this.unit = unit;
    }

    /**
     * Create a Length, with as its value given in meters
     * @param value the length in meters
     * @return the Length object
     * @throws NullPointerException if value is null
     */
    public static Length createLengthInMeters(final double value) {
        return new Length(value, Unit.Meter);
    }

    /**
     * Create a Length, with as its value given in the supplied unit.
     * @param value the length in the unit
     * @param unit the {@link Unit} of the length
     * @return the Length object
     * @throws IllegalArgumentException if value or unit are null.
     */
    public static Length createLength(final double value, final Unit unit) {
        return new Length(value, unit);
    }

    /**
     * Get the value of this Length in meters.
     * @return value in meters.
     */
    public double getValueInMeters() {
        return getValue(Unit.Meter);
    }

    /**
     * Get the value of this {@link Length} in it's {@link Unit}.
     * @return
     */
    public double getValue() {
        return getValue(unit);
    }

    /**
     * Get the value of this Length in the supplied {@link Unit}.
     * @param unit the {@link Unit} to give the Length in.
     * @return the value in the supplied {@link Unit}.
     * @throws IllegalArgumentException if unit is null.
     */
    public double getValue(final Unit unit) {
        if (unit == null) {
            throw new IllegalArgumentException("unit should not be null");
        }
        return value / unit.conversionValue;
    }

    /**
     * Get the unit of this Length
     * @return the unit of the length
     */
    public Unit getUnit() {
        return unit;
    }

    /**
     * Convert this Length to another Unit. 
     * @param unit the Unit to convert to.
     * @return the new converted length.
     * @throws IllegalArgumentException if unit is null.
     */
    public Length convert(final Unit unit) {
        if (unit == null)
            throw new IllegalArgumentException("unit cannot be null");

        return createLength(value / unit.conversionValue, unit);
    }

    /**
     * Return a new length that is the sum of this Length and and the Length
     * added. The new Length has the same Unit as this Length.
     * @param other Length to add.
     * @return the sum of the Lengths
     * @throws IllegalArgumentException if other is null. 
     */
    public Length add(final Length other) {
        if (other == null) {
            throw new IllegalArgumentException("subtractor should not be null");
        }
        return createLengthInMeters(this.value + other.value).convert(this.unit);
    }

    /**
     * return a new Length with the value of this subtracted by subtractor
     * @param subtractor the Length to subtract from this {@link Length}.
     * @return a new {@link Length} which is the result of the subtraction.
     */
    public Length substract(final Length subtractor) {
        if (subtractor == null) {
            throw new IllegalArgumentException("subtractor should not be null");
        }
        return createLengthInMeters(this.value - subtractor.value).convert(this.unit);
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final Length other = (Length) obj;

        return Double.doubleToLongBits(value) == Double.doubleToLongBits(other.value);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(7, 17).append(value).toHashCode();
    }

    @Override
    public String toString() {
        return unit.format.format(getValue()) + " " + unit.suffix;
    }

    @Override
    public int compareTo(final Length other) {
        if (other == null) {
            throw new IllegalArgumentException("cannot compare to null");
        }

        if (equals(other)) {
            return 0;
        }
        if (value > other.value) {
            return 1;
        } else {
            return -1;
        }
    }
}