summaryrefslogtreecommitdiff
path: root/src/org/unitConverter
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/unitConverter')
-rw-r--r--src/org/unitConverter/newUnits/AbstractUnit.java76
-rw-r--r--src/org/unitConverter/newUnits/BaseUnit.java102
-rw-r--r--src/org/unitConverter/newUnits/FunctionalUnit.java98
-rw-r--r--src/org/unitConverter/newUnits/Unit.java145
-rw-r--r--src/org/unitConverter/newUnits/package-info.java23
5 files changed, 444 insertions, 0 deletions
diff --git a/src/org/unitConverter/newUnits/AbstractUnit.java b/src/org/unitConverter/newUnits/AbstractUnit.java
new file mode 100644
index 0000000..909ea8b
--- /dev/null
+++ b/src/org/unitConverter/newUnits/AbstractUnit.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
+ */
+package org.unitConverter.newUnits;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.unitConverter.dimension.BaseDimension;
+import org.unitConverter.math.ObjectProduct;
+
+/**
+ * @author Adrien Hopkins
+ * @since 2019-10-16
+ */
+public abstract class AbstractUnit implements Unit {
+ /**
+ * The combination of units that this unit is based on.
+ */
+ private final ObjectProduct<BaseUnit> unitBase;
+
+ /**
+ * Cache storing the result of getDimension()
+ */
+ private transient ObjectProduct<BaseDimension> dimension = null;
+
+ /**
+ * Creates the {@code AbstractUnit}.
+ *
+ * @param unitBase
+ * @since 2019-10-16
+ * @throws NullPointerException
+ * if unitBase is null
+ */
+ public AbstractUnit(final ObjectProduct<BaseUnit> unitBase) {
+ this.unitBase = Objects.requireNonNull(unitBase, "unitBase must not be null.");
+ }
+
+ /**
+ * @return unitBase
+ * @since 2019-10-16
+ */
+ @Override
+ public final ObjectProduct<BaseUnit> getBase() {
+ return this.unitBase;
+ }
+
+ @Override
+ public ObjectProduct<BaseDimension> getDimension() {
+ if (this.dimension == null) {
+ final Map<BaseUnit, Integer> mapping = this.unitBase.exponentMap();
+ final Map<BaseDimension, Integer> dimensionMap = new HashMap<>();
+
+ for (final BaseUnit key : mapping.keySet()) {
+ dimensionMap.put(key.getBaseDimension(), mapping.get(key));
+ }
+
+ this.dimension = ObjectProduct.fromExponentMapping(dimensionMap);
+ }
+ return this.dimension;
+ }
+}
diff --git a/src/org/unitConverter/newUnits/BaseUnit.java b/src/org/unitConverter/newUnits/BaseUnit.java
new file mode 100644
index 0000000..69e8b8b
--- /dev/null
+++ b/src/org/unitConverter/newUnits/BaseUnit.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
+ */
+package org.unitConverter.newUnits;
+
+import java.util.Objects;
+
+import org.unitConverter.dimension.BaseDimension;
+import org.unitConverter.math.ObjectProduct;
+
+/**
+ * A unit that other units are defined by.
+ *
+ * @author Adrien Hopkins
+ * @since 2019-10-16
+ */
+public final class BaseUnit implements Unit {
+ private final BaseDimension dimension;
+ private final String name;
+ private final String symbol;
+
+ /**
+ * Creates the {@code BaseUnit}.
+ *
+ * @param dimension
+ * dimension of unit
+ * @param name
+ * name of unit
+ * @param symbol
+ * symbol of unit
+ * @throws NullPointerException
+ * if any argument is null
+ * @since 2019-10-16
+ */
+ private BaseUnit(final BaseDimension dimension, final String name, final String symbol) {
+ this.dimension = Objects.requireNonNull(dimension, "dimension must not be null.");
+ this.name = Objects.requireNonNull(name, "name must not be null.");
+ this.symbol = Objects.requireNonNull(symbol, "symbol must not be null.");
+ }
+
+ @Override
+ public double convertFromBase(final double value) {
+ return value;
+ }
+
+ @Override
+ public double convertToBase(final double value) {
+ return value;
+ }
+
+ @Override
+ public ObjectProduct<BaseUnit> getBase() {
+ return ObjectProduct.oneOf(this);
+ }
+
+ /**
+ * @return dimension
+ * @since 2019-10-16
+ */
+ public final BaseDimension getBaseDimension() {
+ return this.dimension;
+ }
+
+ @Override
+ public ObjectProduct<BaseDimension> getDimension() {
+ return ObjectProduct.oneOf(this.getBaseDimension());
+ }
+
+ /**
+ * @return name
+ * @since 2019-10-16
+ */
+ public final String getName() {
+ return this.name;
+ }
+
+ /**
+ * @return symbol
+ * @since 2019-10-16
+ */
+ public final String getSymbol() {
+ return this.symbol;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s (%s)", this.getName(), this.getSymbol());
+ }
+}
diff --git a/src/org/unitConverter/newUnits/FunctionalUnit.java b/src/org/unitConverter/newUnits/FunctionalUnit.java
new file mode 100644
index 0000000..99ff833
--- /dev/null
+++ b/src/org/unitConverter/newUnits/FunctionalUnit.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
+ */
+package org.unitConverter.newUnits;
+
+import java.util.Objects;
+import java.util.function.DoubleUnaryOperator;
+
+import org.unitConverter.math.ObjectProduct;
+
+/**
+ * A unit that uses functional objects to convert to and from its base.
+ *
+ * @author Adrien Hopkins
+ * @since 2019-05-22
+ */
+final class FunctionalUnit extends AbstractUnit {
+ /**
+ * Returns a unit from its base and the functions it uses to convert to and from its base.
+ *
+ * @param base
+ * unit's base
+ * @param converterFrom
+ * function that accepts a value expressed in the unit's base and returns that value expressed in this
+ * unit.
+ * @param converterTo
+ * function that accepts a value expressed in the unit and returns that value expressed in the unit's
+ * base.
+ * @return a unit that uses the provided functions to convert.
+ * @since 2019-05-22
+ * @throws NullPointerException
+ * if any argument is null
+ */
+ public static FunctionalUnit valueOf(final ObjectProduct<BaseUnit> base, final DoubleUnaryOperator converterFrom,
+ final DoubleUnaryOperator converterTo) {
+ return new FunctionalUnit(base, converterFrom, converterTo);
+ }
+
+ /**
+ * A function that accepts a value expressed in the unit's base and returns that value expressed in this unit.
+ *
+ * @since 2019-05-22
+ */
+ private final DoubleUnaryOperator converterFrom;
+
+ /**
+ * A function that accepts a value expressed in the unit and returns that value expressed in the unit's base.
+ *
+ * @since 2019-05-22
+ */
+ private final DoubleUnaryOperator converterTo;
+
+ /**
+ * Creates the {@code FunctionalUnit}.
+ *
+ * @param base
+ * unit's base
+ * @param converterFrom
+ * function that accepts a value expressed in the unit's base and returns that value expressed in this
+ * unit.
+ * @param converterTo
+ * function that accepts a value expressed in the unit and returns that value expressed in the unit's
+ * base.
+ * @throws NullPointerException
+ * if any argument is null
+ * @since 2019-05-22
+ */
+ private FunctionalUnit(final ObjectProduct<BaseUnit> base, final DoubleUnaryOperator converterFrom,
+ final DoubleUnaryOperator converterTo) {
+ super(base);
+ this.converterFrom = Objects.requireNonNull(converterFrom, "converterFrom must not be null.");
+ this.converterTo = Objects.requireNonNull(converterTo, "converterTo must not be null.");
+ }
+
+ @Override
+ public double convertFromBase(final double value) {
+ return this.converterFrom.applyAsDouble(value);
+ }
+
+ @Override
+ public double convertToBase(final double value) {
+ return this.converterTo.applyAsDouble(value);
+ }
+
+}
diff --git a/src/org/unitConverter/newUnits/Unit.java b/src/org/unitConverter/newUnits/Unit.java
new file mode 100644
index 0000000..339afde
--- /dev/null
+++ b/src/org/unitConverter/newUnits/Unit.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
+ */
+package org.unitConverter.newUnits;
+
+import java.util.Objects;
+import java.util.function.DoubleUnaryOperator;
+
+import org.unitConverter.dimension.BaseDimension;
+import org.unitConverter.math.ObjectProduct;
+
+/**
+ * @author Adrien Hopkins
+ * @since 2019-10-16
+ */
+public interface Unit {
+ /**
+ * Returns a unit from its base and the functions it uses to convert to and from its base.
+ *
+ * <p>
+ * For example, to get a unit representing the degree Celsius, the following code can be used:
+ *
+ * {@code Unit.fromConversionFunctions(SI.KELVIN, tempK -> tempK - 273.15, tempC -> tempC + 273.15);}
+ * </p>
+ *
+ * @param base
+ * unit's base
+ * @param converterFrom
+ * function that accepts a value expressed in the unit's base and returns that value expressed in this
+ * unit.
+ * @param converterTo
+ * function that accepts a value expressed in the unit and returns that value expressed in the unit's
+ * base.
+ * @return a unit that uses the provided functions to convert.
+ * @since 2019-05-22
+ * @throws NullPointerException
+ * if any argument is null
+ */
+ public static Unit fromConversionFunctions(final ObjectProduct<BaseUnit> base,
+ final DoubleUnaryOperator converterFrom, final DoubleUnaryOperator converterTo) {
+ return FunctionalUnit.valueOf(base, converterFrom, converterTo);
+ }
+
+ /**
+ * Checks if a value expressed in this unit can be converted to a value expressed in {@code other}
+ *
+ * @param other
+ * unit to test with
+ * @return true if the units are compatible
+ * @since 2019-01-13
+ * @since v0.1.0
+ * @throws NullPointerException
+ * if other is null
+ */
+ default boolean canConvertTo(final Unit other) {
+ Objects.requireNonNull(other, "other must not be null.");
+ return Objects.equals(this.getBase(), other.getBase());
+ }
+
+ /**
+ * Converts from a value expressed in this unit's base unit to a value expressed in this unit.
+ * <p>
+ * This must be the inverse of {@code convertToBase}, so {@code convertFromBase(convertToBase(value))} must be equal
+ * to {@code value} for any value, ignoring precision loss by roundoff error.
+ * </p>
+ * <p>
+ * If this unit <i>is</i> a base unit, this method should return {@code value}.
+ * </p>
+ *
+ * @param value
+ * value expressed in <b>base</b> unit
+ * @return value expressed in <b>this</b> unit
+ * @since 2018-12-22
+ * @since v0.1.0
+ */
+ double convertFromBase(double value);
+
+ /**
+ * Converts a value expressed in this unit to a value expressed in {@code other}.
+ *
+ * @param other
+ * unit to convert to
+ * @param value
+ * value to convert
+ * @return converted value
+ * @since 2019-05-22
+ * @throws IllegalArgumentException
+ * if {@code other} is incompatible for conversion with this unit (as tested by
+ * {@link Unit#canConvertTo}).
+ * @throws NullPointerException
+ * if other is null
+ */
+ default double convertTo(final Unit other, final double value) {
+ Objects.requireNonNull(other, "other must not be null.");
+ if (this.canConvertTo(other))
+ return other.convertFromBase(this.convertToBase(value));
+ else
+ throw new IllegalArgumentException(String.format("Cannot convert from %s to %s.", this, other));
+ }
+
+ /**
+ * Converts from a value expressed in this unit to a value expressed in this unit's base unit.
+ * <p>
+ * This must be the inverse of {@code convertFromBase}, so {@code convertToBase(convertFromBase(value))} must be
+ * equal to {@code value} for any value, ignoring precision loss by roundoff error.
+ * </p>
+ * <p>
+ * If this unit <i>is</i> a base unit, this method should return {@code value}.
+ * </p>
+ *
+ * @param value
+ * value expressed in <b>this</b> unit
+ * @return value expressed in <b>base</b> unit
+ * @since 2018-12-22
+ * @since v0.1.0
+ */
+ double convertToBase(double value);
+
+ /**
+ * @return combination of units that this unit is based on
+ * @since 2018-12-22
+ * @since v0.1.0
+ */
+ ObjectProduct<BaseUnit> getBase();
+
+ /**
+ * @return dimension measured by this unit
+ * @since 2018-12-22
+ * @since v0.1.0
+ */
+ ObjectProduct<BaseDimension> getDimension();
+} \ No newline at end of file
diff --git a/src/org/unitConverter/newUnits/package-info.java b/src/org/unitConverter/newUnits/package-info.java
new file mode 100644
index 0000000..9cd0d1a
--- /dev/null
+++ b/src/org/unitConverter/newUnits/package-info.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
+ */
+/**
+ * The new definition for units.
+ *
+ * @author Adrien Hopkins
+ * @since 2019-10-16
+ */
+package org.unitConverter.newUnits; \ No newline at end of file