001/* 002 * Units of Measurement Enum Implementation 003 * Copyright © 2005-2021, Werner Keil and others. 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, Unit-API nor the names of their 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 tech.uom.impl.enums.unit; 031 032import tech.uom.lib.common.function.DescriptionSupplier; 033import tech.uom.lib.common.function.DoubleFactorSupplier; 034import tech.uom.impl.enums.DimensionalModel; 035import tech.uom.impl.enums.function.AbstractConverter; 036 037import static tech.uom.impl.enums.unit.Constants.DEG; 038 039import java.util.HashMap; 040import java.util.Map; 041 042import javax.measure.Dimension; 043import javax.measure.IncommensurableException; 044import javax.measure.Prefix; 045import javax.measure.Quantity; 046import javax.measure.UnconvertibleException; 047import javax.measure.Unit; 048import javax.measure.UnitConverter; 049import javax.measure.quantity.Temperature; 050 051/** 052 * @author Werner Keil 053 * @version 1.0, $Date: 2020-10-03 $ 054 */ 055public enum TemperatureUnit implements Unit<Temperature>, DoubleFactorSupplier, DescriptionSupplier { 056 057 /** Kelvin, commonly used in scientific endeavors. */ 058 KELVIN(1d, 0d, null, 273.15d, 373.15d, "K", "William Thomson, 1st Baron Kelvin"), 059 060 /** Rankine, used in scientific endeavors. */ 061 RANKINE(5 / 9, 0d, KELVIN, 491.67d, 671.641d, DEG + "R", "William John Macquorn Rankine"), 062 063 /** Celsius, used by most of the world's population. */ 064 CELSIUS(0d, 273.15d, KELVIN, 0d, 100d, DEG + "C", "Anders Celsius"), 065 066 /** Fahrenheit, commonly used in the United States. */ 067 FAHRENHEIT(0d, 459.67d, RANKINE, 32d, 212d, DEG + "F", "Daniel Gabriel Fahrenheit"); 068 069 /** Units by which this temperature scale is expressed. */ 070 private final String description; 071 072 private final double multFactor; 073 074 /** Freezing point of water for each temperature scale. */ 075 private final double freezingPoint; 076 077 /** Boiling point of water for each temperature scale. */ 078 private final double boilingPoint; 079 080 /** Name of person that this temperature scale is named for. */ 081 private final String namedFor; 082 083 private final TemperatureUnit relativeTo; 084 085 // private static final Double FIVE = new Double("5"); 086 // private static final Double NINE = new Double("9"); 087 // private static final Double THIRTY_TWO = new Double("32"); 088 // private static final Double KELVIN_CELSIUS_DELTA = new Double("273"); 089 private static final double RANKINE_FAHRENHEIT_DELTA = 459.67d; 090 091 /** 092 * Constructor for TemperatureUnit that accepts key characteristics of each 093 * temperature scale. 094 * 095 * @param newFreezingPoint 096 * Freezing point for this temperature scale. 097 * @param newBoilingPoint 098 * Boiling point for this temperature scale. 099 * @param newUnits 100 * Unit symbol for this temperature scale. 101 * @param newNamedFor 102 * Name of person after which temperature scale was named. 103 */ 104 private TemperatureUnit(double newMult, double shift, final TemperatureUnit rel, double newFreezingPoint, 105 double newBoilingPoint, final String newSymbol, final String newNamedFor) { 106 this.multFactor = newMult; 107 this.relativeTo = rel; 108 this.freezingPoint = newFreezingPoint; 109 this.boilingPoint = newBoilingPoint; 110 this.description = newSymbol; 111 this.namedFor = newNamedFor; 112 } 113 114 public String getSymbol() { 115 return description; 116 } 117 118 public double getFactor() { 119 return multFactor; 120 } 121 122 public String getName() { 123 return namedFor; 124 } 125 126 public Unit<Temperature> getSystemUnit() { 127 return KELVIN; 128 } 129 130 public Map<? extends Unit<Temperature>, Integer> getBaseUnits() { 131 Map<Unit<Temperature>, Integer> prodUnits = new HashMap<Unit<Temperature>, Integer>(); 132 prodUnits.put(KELVIN, Integer.valueOf(2)); 133 return prodUnits; 134 } 135 136 public static TemperatureUnit getBySymbol(String symbol) { 137 if (CELSIUS.name().equals(symbol)) { 138 return CELSIUS; 139 } 140 if (FAHRENHEIT.name().equals(symbol)) { 141 return FAHRENHEIT; 142 } 143 return KELVIN; 144 } 145 146 public UnitConverter getConverterTo(Unit<Temperature> that) throws UnconvertibleException { 147 if ((this == that) || this.equals(that)) 148 return AbstractConverter.IDENTITY; // Shortcut. 149 Unit<Temperature> thisSystemUnit = this.getSystemUnit(); 150 Unit<Temperature> thatSystemUnit = that.getSystemUnit(); 151 if (!thisSystemUnit.equals(thatSystemUnit)) 152 try { 153 return getConverterToAny(that); 154 } catch (IncommensurableException e) { 155 throw new UnconvertibleException(e); 156 } 157 return that.getConverterTo(thatSystemUnit); 158 } 159 160 public UnitConverter getConverterToAny(Unit<?> that) throws IncommensurableException, UnconvertibleException { 161 if (!isCompatible(that)) 162 throw new IncommensurableException(this + " is not compatible with " + that); 163 DimensionalModel model = DimensionalModel.current(); 164 return model.getDimensionalTransform(this.getSystemUnit().getDimension()); // .concatenate(this.getConverterToSI()); 165 } 166 167 public Unit<Temperature> alternate(String s) { 168 return this; 169 } 170 171 public Dimension getDimension() { 172 return SimpleDimension.INSTANCE; 173 } 174 175 public Unit<?> inverse() { 176 return this; 177 } 178 179 public Unit<Temperature> divide(double v) { 180 return null; // To change body of implemented methods use File | 181 // Settings | File TemplateBuilder. 182 } 183 184 public Unit<?> divide(Unit<?> unit) { 185 return null; // To change body of implemented methods use File | 186 // Settings | File TemplateBuilder. 187 } 188 189 public boolean isCompatible(Unit<?> that) { 190 if (that instanceof TemperatureUnit) 191 return true; 192 return false; 193 } 194 195 @SuppressWarnings({ "unchecked" }) 196 public final <T extends Quantity<T>> Unit<T> asType(Class<T> type) { 197 Unit<T> metricUnit = (Unit<T>) getSystemUnit(); 198 if ((metricUnit == null) || metricUnit.isCompatible(this)) 199 return (Unit<T>) this; 200 throw new ClassCastException("The unit: " + this //$NON-NLS-1$ 201 + " is not of parameterized type " + type); //$NON-NLS-1$ 202 } 203 204 public Unit<Temperature> multiply(double factor) { 205 return this; 206 } 207 208 public Unit<?> multiply(Unit<?> that) { 209 return this; 210 } 211 212 public Unit<?> pow(int n) { 213 return this; 214 } 215 216 public Unit<?> root(int n) { 217 return this; 218 } 219 220 public Unit<Temperature> transform(UnitConverter operation) { 221 return this; 222 } 223 224 public Unit<Temperature> shift(double v) { 225 return this; 226 } 227 228 public String getDescription() { 229 return description; 230 } 231 232 @Override 233 public Unit<Temperature> prefix(Prefix prefix) { 234 return this.multiply(Math.pow(prefix.getValue().doubleValue(), prefix.getExponent())); 235 } 236 237 @Override 238 public Unit<Temperature> shift(Number offset) { 239 return this; 240 } 241 242 @Override 243 public Unit<Temperature> multiply(Number multiplier) { 244 return this; 245 } 246 247 @Override 248 public Unit<Temperature> divide(Number divisor) { 249 return this; 250 } 251 252 @Override 253 public boolean isEquivalentTo(Unit<Temperature> that) { 254 return equals(that); 255 } 256}