001/* 002 * Unit-API - Units of Measurement API for Java 003 * Copyright (c) 2005-2015, Jean-Marie Dautelle, Werner Keil, V2COM. 004 * 005 * All rights reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 008 * 009 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 010 * 011 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 012 * 013 * 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 014 * 015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 017 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 022 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 024 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 025 */ 026package systems.uom.ucum.internal; 027 028import java.util.HashMap; 029 030import javax.measure.Quantity; 031import javax.measure.Unit; 032import javax.measure.quantity.*; 033 034import si.uom.quantity.Action; 035import si.uom.quantity.DynamicViscosity; 036import si.uom.quantity.ElectricPermittivity; 037import si.uom.quantity.IonizingRadiation; 038import si.uom.quantity.KinematicViscosity; 039import si.uom.quantity.Luminance; 040import si.uom.quantity.MagneticFieldStrength; 041import si.uom.quantity.MagneticPermeability; 042//import si.uom.quantity.*; 043import si.uom.quantity.MagnetomotiveForce; 044import si.uom.quantity.WaveNumber; 045import tec.uom.se.AbstractUnit; 046import tec.uom.se.function.LogConverter; 047import tec.uom.se.function.MultiplyConverter; 048import tec.uom.se.function.PiMultiplierConverter; 049import tec.uom.se.function.RationalConverter; 050import tec.uom.se.unit.AlternateUnit; 051import tec.uom.se.unit.ProductUnit; 052import tec.uom.se.unit.TransformedUnit; 053import tec.uom.se.unit.Units; 054 055/** 056 * <p> This class defines all SI (Système International d'Unités) base units and 057 * derived units as well as units that are accepted for use with the 058 * SI units.</p> 059 * 060 * @see <a href="http://en.wikipedia.org/wiki/International_System_of_Units">Wikipedia: International System of Units</a> 061 * @see <a href="http://physics.nist.gov/cuu/Units/outside.html>Units outside the SI that are accepted for use with the SI</a> 062 * @see <a href="http://www.bipm.org/utils/common/pdf/si_brochure_8.pdf>SI 2006 - Official Specification</a> 063 * @see SIPrefix 064 * 065 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 066 * @author <a href="mailto:units@catmedia.us">Werner Keil</a> 067 * @version 0.7.1, July 21, 2015 068*/ 069public final class SI extends Units { 070 071 /** 072 * The singleton instance. 073 */ 074 private static final SI INSTANCE = new SI(); 075 076 /** 077 * Holds the mapping quantity to unit. 078 */ 079 private final HashMap<Class<? extends Quantity>, AbstractUnit> 080 quantityToUnit = new HashMap<Class<? extends Quantity>, AbstractUnit>(); 081 082 /** 083 * Default constructor (prevents this class from being instantiated). 084 */ 085 private SI() { 086 } 087 088 /** 089 * Returns the singleton instance of this class. 090 * 091 * @return the metric system instance. 092 */ 093 public static SI getInstance() { 094 return INSTANCE; 095 } 096 097 //////////////////////////////// 098 // SI DERIVED ALTERNATE UNITS // 099 //////////////////////////////// 100 101 /** 102 * The SI unit for magnetomotive force (standard name <code>At</code>). 103 */ 104 public static final AlternateUnit<MagnetomotiveForce> AMPERE_TURN 105 = addUnit(new AlternateUnit<MagnetomotiveForce>(SI.AMPERE, "At"), 106 MagnetomotiveForce.class); 107 108 ////////////////////////////// 109 // SI DERIVED PRODUCT UNITS // 110 ////////////////////////////// 111 112 /** 113 * The SI unit for acceleration quantities (standard name <code>m/s2</code>). 114 */ 115 public static final Unit<Acceleration> METRES_PER_SQUARE_SECOND 116 = addUnit(new ProductUnit<Acceleration>( 117 METRES_PER_SECOND.divide(SECOND)), Acceleration.class); 118 119 /** 120 * The SI unit for action quantities (standard name <code>j.s</code>). 121 */ 122 public static final Unit<Action> JOULE_SECOND 123 = addUnit(new ProductUnit<Action>( 124 JOULE.multiply(SECOND)), Action.class); 125 126 /** 127 * The SI unit for electric permittivity quantities (standard name <code>F/m</code>). 128 */ 129 public static final Unit<ElectricPermittivity> FARADS_PER_METRE 130 = addUnit(new ProductUnit<ElectricPermittivity>( 131 FARAD.divide(METRE)), ElectricPermittivity.class); 132 133 /** 134 * The SI unit for magnetic permeability quantities (standard name <code>N/A2</code>). 135 */ 136 public static final Unit<MagneticPermeability> NEWTONS_PER_SQUARE_AMPERE 137 = addUnit(new ProductUnit<MagneticPermeability>( 138 NEWTON.divide(AMPERE.pow(2))), MagneticPermeability.class); 139 140 /** 141 * The SI unit for wave number quantities (standard name <code>1/m</code>). 142 */ 143 public static final Unit<WaveNumber> RECIPROCAL_METRE 144 = addUnit(new ProductUnit<WaveNumber>( 145 METRE.pow(-1)), WaveNumber.class); 146 147 /** 148 * The SI unit for dynamic viscosity quantities (standard name <code>Pa.s</code>). 149 */ 150 public static final Unit<DynamicViscosity> PASCAL_SECOND 151 = addUnit(new ProductUnit<DynamicViscosity>( 152 PASCAL.multiply(SECOND)), DynamicViscosity.class); 153 154 /** 155 * The SI unit for kinematic viscosity quantities (standard name <code>m2/s"</code>). 156 */ 157 public static final Unit<KinematicViscosity> SQUARE_METRES_PER_SECOND 158 = addUnit(new ProductUnit<KinematicViscosity>( 159 SQUARE_METRE.divide(SECOND)), KinematicViscosity.class); 160 161 /** 162 * The SI unit for magnetic field strength quantities (standard name <code>A/m"</code>). 163 */ 164 public static final Unit<MagneticFieldStrength> AMPERES_PER_METRE 165 = addUnit(new ProductUnit<MagneticFieldStrength>( 166 AMPERE.divide(METRE)), MagneticFieldStrength.class); 167 168 /** 169 * The SI unit for ionizing radiation quantities (standard name <code>C/kg"</code>). 170 */ 171 public static final Unit<IonizingRadiation> COULOMBS_PER_KILOGRAM 172 = addUnit(new ProductUnit<IonizingRadiation>( 173 COULOMB.divide(KILOGRAM)), IonizingRadiation.class); 174 175 ///////////////////////////////////////////////////////////////// 176 // Units outside the SI that are accepted for use with the SI. // 177 ///////////////////////////////////////////////////////////////// 178 179 /** 180 * An angle unit accepted for use with SI units (standard name <code>deg/code>). 181 */ 182 public static final Unit<Angle> DEGREE_ANGLE 183 = new TransformedUnit<Angle>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter(1, 180))); 184 185 /** 186 * An angle unit accepted for use with SI units (standard name <code>'/code>). 187 */ 188 public static final Unit<Angle> MINUTE_ANGLE 189 = new TransformedUnit<Angle>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter(1, 180 * 60))); 190 191 /** 192 * An angle unit accepted for use with SI units (standard name <code>''</code>). 193 */ 194 public static final Unit<Angle> SECOND_ANGLE 195 = new TransformedUnit<Angle>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter(1, 180 * 60 * 60))); 196 197 /** 198 * A volume unit accepted for use with SI units (standard name <code>l</code>). 199 */ 200 public static final Unit<Volume> LITRE 201 = new TransformedUnit<Volume>(CUBIC_METRE, new RationalConverter(1, 1000)); 202 203 /** 204 * A mass unit accepted for use with SI units (standard name <code>t</code>). 205 */ 206 public static final Unit<Mass> TONNE 207 = new TransformedUnit<Mass>(KILOGRAM, new RationalConverter(1000, 1)); 208 209 /** 210 * A dimensionless unit accepted for use with SI units (standard name <code>Np</code>). 211 * Although the neper is coherent with SI units and is accepted by the CIPM, 212 * it has not been adopted by the General Conference on Weights and Measures 213 * (CGPM, Conférence Générale des Poids et Mesures) and is thus not an SI unit. 214 */ 215 public static final Unit<Dimensionless> NEPER 216 = new TransformedUnit<Dimensionless>(ONE, new LogConverter(E).inverse()); 217 218 /** 219 * A dimensionless unit accepted for use with SI units (standard name <code>B</code>). 220 * The bel is most commonly used with the SI prefix deci: 1 dB = 0.1 B 221 */ 222 public static final Unit<Dimensionless> BEL 223 = new TransformedUnit<Dimensionless>(ONE, new LogConverter(10).inverse()); 224 225 /** 226 * An energy unit accepted for use with SI units (standard name <code>eV</code>). 227 * The electronvolt is the kinetic energy acquired by an electron passing 228 * through a potential difference of 1 V in vacuum. 229 * The value must be obtained by experiment, and is therefore not known exactly. 230 */ 231 public static final Unit<Energy> ELECTRON_VOLT 232 = new TransformedUnit<Energy>(JOULE, new MultiplyConverter(1.602176487E-19)); 233 // CODATA 2006 - http://physics.nist.gov/cuu/Constants/codata.pdf 234 235 /** 236 * A mass unit accepted for use with SI units (standard name <code>u</code>). 237 * The unified atomic mass unit is equal to 1/12 of the mass of an unbound 238 * atom of the nuclide 12C, at rest and in its ground state. The value must 239 * be obtained by experiment, and is therefore not known exactly. 240 */ 241 public static final Unit<Mass> UNIFIED_ATOMIC_MASS 242 = new TransformedUnit<Mass>(KILOGRAM, new MultiplyConverter(1.660538782E-27)); 243 // CODATA 2006 - http://physics.nist.gov/cuu/Constants/codata.pdf 244 245 /** 246 * A length unit accepted for use with SI units (standard name <code>UA</code>). 247 * The astronomical unit is a unit of length. Its value is such that, 248 * when used to describe the motion of bodies in the solar system, 249 * the heliocentric gravitation constant is (0.017 202 098 95)2 ua3·d-2. 250 * The value must be obtained by experiment, and is therefore not known exactly. 251 */ 252 public static final Unit<Length> ASTRONOMICAL_UNIT 253 = addUnit(new TransformedUnit<Length>(METRE, new MultiplyConverter(149597871000.0))); 254 // Best estimate source: http://maia.usno.navy.mil/NSFA/CBE.html 255 256 /** 257 * An angle unit accepted for use with SI units (standard name <code>rev</code>). 258 */ 259 public static final Unit<Angle> REVOLUTION 260 = new TransformedUnit<Angle>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter(2, 1))); 261 262 /** 263 * An angle unit accepted for use with SI units (standard name <code>ha</code>). 264 */ 265 public static final Unit<Area> HECTARE 266 = new TransformedUnit<Area>(SQUARE_METRE, new RationalConverter(10000, 1)); 267 268 ///////////////////// 269 // Collection View // 270 ///////////////////// 271 272 @Override 273 public String getName() { 274 return "SI"; 275 } 276 277 @SuppressWarnings("unchecked") 278 @Override 279 public <Q extends Quantity<Q>> AbstractUnit<Q> getUnit(Class<Q> quantityType) { 280 return quantityToUnit.get(quantityType); 281 } 282 283 /** 284 * Adds a new unit not mapped to any specified quantity type. 285 * 286 * @param unit the unit being added. 287 * @return <code>unit</code>. 288 */ 289 private static <U extends Unit<?>> U addUnit(U unit) { 290 INSTANCE.units.add(unit); 291 return unit; 292 } 293 294 /** 295 * Adds a new unit and maps it to the specified quantity type. 296 * 297 * @param unit the unit being added. 298 * @param type the quantity type. 299 * @return <code>unit</code>. 300 */ 301 private static <U extends AbstractUnit<?>> U addUnit(U unit, Class<? extends Quantity<?>> type) { 302 INSTANCE.units.add(unit); 303 INSTANCE.quantityToUnit.put(type, unit); 304 return unit; 305 } 306}