/** * Copyright (C) 2018 Adrien Hopkins * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package org.unitConverter.unit; import java.util.Objects; import org.unitConverter.dimension.StandardDimensions; import org.unitConverter.dimension.UnitDimension; /** * A unit that is the base for its dimension. It does not have to be for a base dimension, so units like the Newton and * Joule are still base units. *

* {@code BaseUnit} does not have any public constructors or static factories. There are two ways to obtain * {@code BaseUnit} instances. *

    *
  1. The class {@link SI} in this package has constants for all of the SI base units. You can use these constants and * multiply or divide them to get other units. For example: * *
     * BaseUnit JOULE = SI.KILOGRAM.times(SI.METRE.toExponent(2)).dividedBy(SI.SECOND.toExponent(2));
     * 
    * *
  2. *
  3. You can also query a unit system for a base unit using a unit dimension. The previously mentioned {@link SI} * class can do this for SI and SI-derived units (including imperial and USC), but if you want to use another system, * this is the way to do it. {@link StandardDimensions} contains common unit dimensions that you can use for this. Here * is an example: * *
     * BaseUnit JOULE = SI.SI.getBaseUnit(StandardDimensions.ENERGY);
     * 
    * *
  4. *
* * @author Adrien Hopkins * @since 2018-12-23 * @since v0.1.0 */ public final class BaseUnit extends LinearUnit { /** * Is this unit a full base (i.e. m, s, ... but not N, J, ...) * * @since 2019-01-15 * @since v0.1.0 */ private final boolean isFullBase; /** * Creates the {@code BaseUnit}. * * @param dimension * dimension measured by unit * @param system * system that unit is a part of * @param name * name of unit * @param symbol * symbol of unit * @since 2018-12-23 * @since v0.1.0 */ BaseUnit(final UnitDimension dimension, final UnitSystem system) { super(dimension, system, 1); this.isFullBase = dimension.isBase(); } /** * Returns the quotient of this unit and another. *

* Two units can be divided if they are part of the same unit system. If {@code divisor} does not meet this * condition, an {@code IllegalArgumentException} should be thrown. *

* * @param divisor * unit to divide by * @return quotient of two units * @throws IllegalArgumentException * if {@code divisor} is not compatible for division as described above * @throws NullPointerException * if {@code divisor} is null * @since 2018-12-22 * @since v0.1.0 */ public BaseUnit dividedBy(final BaseUnit divisor) { Objects.requireNonNull(divisor, "other must not be null."); // check that these units can be multiplied if (!this.getSystem().equals(divisor.getSystem())) throw new IllegalArgumentException( String.format("Incompatible units for division \"%s\" and \"%s\".", this, divisor)); return new BaseUnit(this.getDimension().dividedBy(divisor.getDimension()), this.getSystem()); } /** * @return true if the unit is a "full base" unit like the metre or second. * @since 2019-04-10 * @since v0.2.0 */ public final boolean isFullBase() { return this.isFullBase; } /** * Returns the product of this unit and another. *

* Two units can be multiplied if they are part of the same unit system. If {@code multiplier} does not meet this * condition, an {@code IllegalArgumentException} should be thrown. *

* * @param multiplier * unit to multiply by * @return product of two units * @throws IllegalArgumentException * if {@code multiplier} is not compatible for multiplication as described above * @throws NullPointerException * if {@code multiplier} is null * @since 2018-12-22 * @since v0.1.0 */ public BaseUnit times(final BaseUnit multiplier) { Objects.requireNonNull(multiplier, "other must not be null"); // check that these units can be multiplied if (!this.getSystem().equals(multiplier.getSystem())) throw new IllegalArgumentException( String.format("Incompatible units for multiplication \"%s\" and \"%s\".", this, multiplier)); // multiply the units return new BaseUnit(this.getDimension().times(multiplier.getDimension()), this.getSystem()); } /** * Returns this unit, but to an exponent. * * @param exponent * exponent * @return result of exponentiation * @since 2019-01-15 * @since v0.1.0 */ @Override public BaseUnit toExponent(final int exponent) { return this.getSystem().getBaseUnit(this.getDimension().toExponent(exponent)); } @Override public String toString() { return String.format("%s base unit of%s dimension %s", this.getSystem(), this.isFullBase ? " base" : "", this.getDimension()); } }