001/*
002 * Units of Measurement API
003 * Copyright (c) 2014-2023, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385 nor the names of its contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package javax.measure.test.unit;
031
032import javax.measure.Prefix;
033import javax.measure.Quantity;
034import javax.measure.Unit;
035import javax.measure.UnitConverter;
036import javax.measure.quantity.Temperature;
037import javax.measure.test.TestUnit;
038
039/**
040 * @author Werner Keil
041 * @version 0.7, $Date: 2019-02-06 $
042 */
043public class TemperatureUnit extends TestUnit<Temperature> {
044        private static final char DEG = '\u00B0';
045        /** Kelvin, commonly used in scientific endeavors. */
046        public static final TemperatureUnit KELVIN = new TemperatureUnit(1d, 0d, null, 273.15d, 373.15d, "K",
047                        "William Thomson, 1st Baron Kelvin");
048
049        /** Rankine, used in scientific endeavors. */
050        public static final TemperatureUnit RANKINE = new TemperatureUnit(5 / 9, 0d, KELVIN, 491.67d, 671.641d, DEG + "R",
051                        "William John Macquorn Rankine");
052
053        /** Celsius, used by most of the world's population. */
054        public static final TemperatureUnit CELSIUS = new TemperatureUnit(0d, 273.15d, KELVIN, 0d, 100d, DEG + "C",
055                        "Anders Celsius");
056
057        /** Fahrenheit, commonly used in the United States. */
058        public static final TemperatureUnit FAHRENHEIT = new TemperatureUnit(0d, 459.67d, RANKINE, 32d, 212d, DEG + "F",
059                        "Daniel Gabriel Fahrenheit");
060
061        /** Units by which this temperature scale is expressed. */
062        private final String description;
063
064        private final double multFactor;
065
066        /** Name of person that this temperature scale is named for. */
067        private final String namedFor;
068
069        /**
070         * Constructor for TemperatureUnit that accepts key characteristics of each
071         * temperature scale.
072         * @param rel The temperature unit this is relative to.
073         * @param newFreezingPoint Freezing point for this temperature scale.
074         * @param newBoilingPoint  Boiling point for this temperature scale.
075         * @param newSymbol        Unit symbol for this temperature scale.
076         * @param newNamedFor      Name of person after which temperature scale was
077         *                         named.
078         * @param newMult          new multiplier
079         * @param shift            the shift factor
080         */
081        public TemperatureUnit(double newMult, double shift, final TemperatureUnit rel, double newFreezingPoint,
082                        double newBoilingPoint, final String newSymbol, final String newNamedFor) {
083                this.multFactor = newMult;
084                this.description = newSymbol;
085                this.namedFor = newNamedFor;
086        }
087
088        public String getSymbol() {
089                return description;
090        }
091
092        public double getFactor() {
093                return multFactor;
094        }
095
096        public String getName() {
097                return namedFor;
098        }
099
100        public Unit<Temperature> getSystemUnit() {
101                return KELVIN;
102        }
103
104        public static TemperatureUnit getBySymbol(String symbol) {
105                if (CELSIUS.getSymbol().equals(symbol)) {
106                        return CELSIUS;
107                }
108                if (FAHRENHEIT.getSymbol().equals(symbol)) {
109                        return FAHRENHEIT;
110                }
111                return KELVIN;
112        }
113
114        public boolean isCompatible(Unit<?> that) {
115                return that instanceof TemperatureUnit;
116        }
117
118        @SuppressWarnings({ "unchecked" })
119        public final <T extends Quantity<T>> Unit<T> asType(Class<T> type) {
120                Unit<T> metricUnit = (Unit<T>) getSystemUnit();
121                if ((metricUnit == null) || metricUnit.isCompatible(this))
122                        return (Unit<T>) this;
123                throw new ClassCastException("The unit: " + this //$NON-NLS-1$
124                                + " is not of parameterized type " + type); //$NON-NLS-1$
125        }
126
127        public Unit<Temperature> multiply(double factor) {
128                return this;
129        }
130
131        public Unit<?> multiply(Unit<?> that) {
132                return this;
133        }
134
135        public Unit<?> pow(int n) {
136                return this;
137        }
138
139        public Unit<?> root(int n) {
140                return this;
141        }
142
143        public Unit<Temperature> transform(UnitConverter operation) {
144                return this;
145        }
146
147        public Unit<Temperature> shift(double v) {
148                return this;
149        }
150
151        public String getDescription() {
152                return description;
153        }
154
155        @Override
156        public Unit<Temperature> prefix(Prefix prefix) {
157                return this.multiply(Math.pow(prefix.getValue().doubleValue(), 
158                                prefix.getExponent()));
159        }
160}