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 javax.measure.UnitConverter; 033 034import tech.uom.impl.enums.format.SimpleUnitFormat; 035 036import java.util.Map; 037 038import javax.measure.Dimension; 039import javax.measure.IncommensurableException; 040import javax.measure.Prefix; 041import javax.measure.Quantity; 042import javax.measure.UnconvertibleException; 043import javax.measure.Unit; 044 045/** 046 * <p> 047 * This class represents multi-radix units (such as "hour:min:sec" or "ft, in"). Instances of this class are created using the {@link Unit#mix 048 * Unit.mix} method. 049 * </p> 050 * 051 * <p> 052 * Examples of mixed units:<code> Unit<Time> HOUR_MINUTE_SECOND = HOUR.mix(MINUTE).mix(SECOND); <br>Unit<Length> FOOT_INCH = 053 * FOOT.mix(INCH); </code> 054 * </p> 055 * 056 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 057 * @author <a href="mailto:werner@units.tech">Werner Keil</a> 058 * @version 2.0, Oct 3, 2020 059 * @since 2.0 060 */ 061public final class MixedUnit<Q extends Quantity<Q>> implements Unit<Q> { 062 063 /** 064 * Holds the upper unit. 065 */ 066 private final Unit<Q> upper; 067 068 /** 069 * Holds the lower unit. 070 */ 071 private final Unit<Q> lower; 072 073 /** 074 * Creates a mixed unit from the specified units. 075 * 076 * @param up 077 * the upper unit. 078 * @param low 079 * the lower unit(s) 080 * @throws IllegalArgumentException 081 * if both units do not the same system unit. 082 */ 083 public MixedUnit(Unit<Q> up, Unit<Q> low) { 084 if (!up.getSystemUnit().equals(low.getSystemUnit())) 085 throw new IllegalArgumentException("Both units do not have the same system unit"); 086 upper = up; 087 lower = low; 088 } 089 090 /** 091 * Returns the lower unit of this mixed unit. 092 * 093 * @return the lower unit. 094 */ 095 public Unit<Q> getLower() { 096 return lower; 097 } 098 099 /** 100 * Returns the upper unit of this mixed unit. 101 * 102 * @return the upper unit. 103 */ 104 public Unit<Q> getUpper() { 105 return upper; 106 } 107 108 /** 109 * Indicates if this mixed unit is considered equals to the specified object (both are mixed units with same composing units in the same 110 * order). 111 * 112 * @param obj 113 * the object to compare for equality. 114 * @return <code>true</code> if <code>this</code> and <code>obj</code> are considered equal; <code>false</code>otherwise. 115 */ 116 public boolean equals(Object obj) { 117 if (this == obj) { 118 return true; 119 } 120 if (obj instanceof MixedUnit) { 121 MixedUnit<?> thatUnit = (MixedUnit<?>) obj; 122 return this.upper.equals(thatUnit.upper) && this.lower.equals(thatUnit.lower); 123 } 124 return super.equals(obj); 125 } 126 127 @Override 128 public int hashCode() { 129 return upper.hashCode() ^ lower.hashCode(); 130 } 131 132 @Override 133 public Unit<Q> getSystemUnit() { 134 return lower.getSystemUnit(); 135 } 136 137 @Override 138 public Dimension getDimension() { 139 return lower.getDimension(); 140 } 141 142 @Override 143 public String getSymbol() { 144 return upper.getSymbol() + ":" + lower.getSymbol(); 145 } 146 147 @Override 148 public String getName() { 149 return upper.getName() + ":" + lower.getName(); 150 } 151 152 @Override 153 public Map<? extends Unit<?>, Integer> getBaseUnits() { 154 // TODO Auto-generated method stub 155 return null; 156 } 157 158 @Override 159 public boolean isCompatible(Unit<?> that) { 160 // TODO Auto-generated method stub 161 return false; 162 } 163 164 @Override 165 public <T extends Quantity<T>> Unit<T> asType(Class<T> type) throws ClassCastException { 166 // TODO Auto-generated method stub 167 return null; 168 } 169 170 @Override 171 public UnitConverter getConverterTo(Unit<Q> that) throws UnconvertibleException { 172 // TODO Auto-generated method stub 173 return null; 174 } 175 176 @Override 177 public UnitConverter getConverterToAny(Unit<?> that) throws IncommensurableException, UnconvertibleException { 178 // TODO Auto-generated method stub 179 return null; 180 } 181 182 @Override 183 public Unit<Q> alternate(String symbol) { 184 // TODO Auto-generated method stub 185 return null; 186 } 187 188 @Override 189 public Unit<Q> shift(double offset) { 190 // TODO Auto-generated method stub 191 return null; 192 } 193 194 @Override 195 public Unit<Q> multiply(double multiplier) { 196 // TODO Auto-generated method stub 197 return null; 198 } 199 200 @Override 201 public Unit<?> multiply(Unit<?> multiplier) { 202 // TODO Auto-generated method stub 203 return null; 204 } 205 206 @Override 207 public Unit<?> inverse() { 208 return this; 209 } 210 211 @Override 212 public Unit<Q> divide(double divisor) { 213 return this; 214 } 215 216 @Override 217 public Unit<?> divide(Unit<?> divisor) { 218 return this; 219 } 220 221 @Override 222 public Unit<?> root(int n) { 223 return this; 224 } 225 226 @Override 227 public Unit<?> pow(int n) { 228 return this; 229 } 230 231 @Override 232 public Unit<Q> transform(UnitConverter operation) { 233 return this; 234 } 235 236 @Override 237 public Unit<Q> prefix(Prefix prefix) { 238 return this.multiply(Math.pow(prefix.getValue().doubleValue(), prefix.getExponent())); 239 } 240 241 public Unit<Q> mix(Unit<Q> that) { 242 return new MixedUnit<Q>(this, that); 243 } 244 245 /** 246 * Returns the standard representation of this physics unit. The string produced 247 * for a given unit is always the same; it is not affected by the locale. It can 248 * be used as a canonical string representation for exchanging units, or as a 249 * key for a Hashtable, etc. 250 * 251 * Locale-sensitive unit parsing could be handled using {@link LocalUnitFormat} 252 * in subclasses of AbstractUnit. 253 * 254 * @return <code>SimpleUnitFormat.getInstance().format(this)</code> 255 */ 256 @Override 257 public String toString() { 258 return SimpleUnitFormat.getInstance().format(this); 259 } 260 261 @Override 262 public Unit<Q> shift(Number offset) { 263 return this; 264 } 265 266 @Override 267 public Unit<Q> multiply(Number multiplier) { 268 return this; 269 } 270 271 @Override 272 public Unit<Q> divide(Number divisor) { 273 return this; 274 } 275 276 @Override 277 public boolean isEquivalentTo(Unit<Q> that) { 278 return equals(that); 279 } 280}