001/*
002 * Units of Measurement Implementation for Java SE
003 * Copyright (c) 2005-2017, 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,
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-363 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 tec.uom.se.unit;
031
032import tec.uom.lib.common.function.SymbolSupplier;
033import tec.uom.lib.common.function.UnitConverterSupplier;
034import tec.uom.se.function.RationalConverter;
035
036import javax.measure.Quantity;
037import javax.measure.Unit;
038import javax.measure.UnitConverter;
039
040import java.math.BigInteger;
041
042/**
043 * <p>
044 * This class provides support for the 20 prefixes used in the metric system (decimal multiples and submultiples of units). For example:
045 * 
046 * <pre>
047 * <code>
048 *     import static tec.uom.se.unit.Units.*;  // Static import.
049 *     import static tec.uom.se.unit.MetricPrefix.*; // Static import.
050 *     import javax.measure.*;
051 *     import javax.measure.quantity.*;
052 *     ...
053 *     Unit<Pressure> HECTOPASCAL = HECTO(PASCAL);
054 *     Unit<Length> KILOMETRE = KILO(METRE);
055 *     </code>
056 * </pre>
057 * 
058 * </p>
059 *
060 * @see <a href="http://en.wikipedia.org/wiki/Metric_prefix">Wikipedia: Metric Prefix</a>
061 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
062 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
063 * @version 0.9, 2015-12-30
064 */
065public enum MetricPrefix implements SymbolSupplier, UnitConverterSupplier {
066  YOTTA("Y", new RationalConverter(BigInteger.TEN.pow(24), BigInteger.ONE)), ZETTA("Z", new RationalConverter(BigInteger.TEN.pow(21), BigInteger.ONE)), EXA(
067      "E", new RationalConverter(BigInteger.TEN.pow(18), BigInteger.ONE)), PETA("P", new RationalConverter(BigInteger.TEN.pow(15), BigInteger.ONE)), TERA(
068      "T", new RationalConverter(BigInteger.TEN.pow(12), BigInteger.ONE)), GIGA("G", new RationalConverter(BigInteger.TEN.pow(9), BigInteger.ONE)), MEGA(
069      "M", new RationalConverter(BigInteger.TEN.pow(6), BigInteger.ONE)), KILO("k", new RationalConverter(BigInteger.TEN.pow(3), BigInteger.ONE)), HECTO(
070      "h", new RationalConverter(BigInteger.TEN.pow(2), BigInteger.ONE)), DEKA("da", new RationalConverter(BigInteger.TEN.pow(1), BigInteger.ONE)), DECI(
071      "d", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(1))), CENTI("c", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(2))), MILLI(
072      "m", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(3))), MICRO("ยต", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(6))), NANO(
073      "n", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(9))), PICO("p", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(12))), FEMTO(
074      "f", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(15))), ATTO("a", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(18))), ZEPTO(
075      "z", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(21))), YOCTO("y", new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(24)));
076
077  /**
078   * The symbol of this prefix, as returned by {@link #getSymbol}.
079   *
080   * @serial
081   * @see #getSymbol()
082   */
083  private final String symbol;
084
085  /**
086   * The <code>UnitConverter</code> of this prefix, as returned by {@link #getConverter}.
087   *
088   * @serial
089   * @see #getConverter()
090   * @see {@link UnitConverter}
091   */
092  private final UnitConverter converter;
093
094  /**
095   * Creates a new prefix.
096   *
097   * @param symbol
098   *          the symbol of this prefix.
099   * @param converter
100   *          the associated unit converter.
101   */
102  MetricPrefix(String symbol, RationalConverter converter) {
103    this.symbol = symbol;
104    this.converter = converter;
105  }
106
107  /**
108   * Returns the symbol of this prefix.
109   *
110   * @return this prefix symbol, not {@code null}.
111   */
112  public String getSymbol() {
113    return symbol;
114  }
115
116  /**
117   * Returns the corresponding unit converter.
118   *
119   * @return the unit converter.
120   */
121  public UnitConverter getConverter() {
122    return converter;
123  }
124
125  /**
126   * Returns the specified unit multiplied by the factor <code>10<sup>24</sup></code>
127   *
128   * @param <Q>
129   *          The type of the quantity measured by the unit.
130   * @param unit
131   *          any unit.
132   * @return <code>unit.times(1e24)</code>.
133   */
134  public static <Q extends Quantity<Q>> Unit<Q> YOTTA(Unit<Q> unit) {
135    return unit.transform(YOTTA.getConverter());
136  }
137
138  /**
139   * Returns the specified unit multiplied by the factor <code>10<sup>21</sup></code>
140   *
141   * @param <Q>
142   *          The type of the quantity measured by the unit.
143   * @param unit
144   *          any unit.
145   * @return <code>unit.times(1e21)</code>.
146   */
147  public static <Q extends Quantity<Q>> Unit<Q> ZETTA(Unit<Q> unit) {
148    return unit.transform(ZETTA.getConverter());
149  }
150
151  /**
152   * Returns the specified unit multiplied by the factor <code>10<sup>18</sup></code>
153   *
154   * @param <Q>
155   *          The type of the quantity measured by the unit.
156   * @param unit
157   *          any unit.
158   * @return <code>unit.times(1e18)</code>.
159   */
160  public static <Q extends Quantity<Q>> Unit<Q> EXA(Unit<Q> unit) {
161    return unit.transform(EXA.getConverter());
162  }
163
164  /**
165   * Returns the specified unit multiplied by the factor <code>10<sup>15</sup></code>
166   *
167   * @param <Q>
168   *          The type of the quantity measured by the unit.
169   * @param unit
170   *          any unit.
171   * @return <code>unit.times(1e15)</code>.
172   */
173  public static <Q extends Quantity<Q>> Unit<Q> PETA(Unit<Q> unit) {
174    return unit.transform(PETA.getConverter());
175  }
176
177  /**
178   * Returns the specified unit multiplied by the factor <code>10<sup>12</sup></code>
179   *
180   * @param <Q>
181   *          The type of the quantity measured by the unit.
182   * @param unit
183   *          any unit.
184   * @return <code>unit.times(1e12)</code>.
185   */
186  public static <Q extends Quantity<Q>> Unit<Q> TERA(Unit<Q> unit) {
187    return unit.transform(TERA.getConverter());
188  }
189
190  /**
191   * Returns the specified unit multiplied by the factor <code>10<sup>9</sup></code>
192   *
193   * @param <Q>
194   *          The type of the quantity measured by the unit.
195   * @param unit
196   *          any unit.
197   * @return <code>unit.times(1e9)</code>.
198   */
199  public static <Q extends Quantity<Q>> Unit<Q> GIGA(Unit<Q> unit) {
200    return unit.transform(GIGA.getConverter());
201  }
202
203  /**
204   * Returns the specified unit multiplied by the factor <code>10<sup>6</sup></code>
205   *
206   * @param <Q>
207   *          The type of the quantity measured by the unit.
208   * @param unit
209   *          any unit.
210   * @return <code>unit.times(1e6)</code>.
211   */
212  public static <Q extends Quantity<Q>> Unit<Q> MEGA(Unit<Q> unit) {
213    return unit.transform(MEGA.getConverter());
214  }
215
216  /**
217   * Returns the specified unit multiplied by the factor <code>10<sup>3</sup></code>
218   *
219   * @param <Q>
220   *          The type of the quantity measured by the unit.
221   * @param unit
222   *          any unit.
223   * @return <code>unit.times(1e3)</code>.
224   */
225  public static <Q extends Quantity<Q>> Unit<Q> KILO(Unit<Q> unit) {
226    return unit.transform(KILO.getConverter());
227  }
228
229  /**
230   * Returns the specified unit multiplied by the factor <code>10<sup>2</sup></code>
231   *
232   * @param <Q>
233   *          The type of the quantity measured by the unit.
234   * @param unit
235   *          any unit.
236   * @return <code>unit.times(1e2)</code>.
237   */
238  public static <Q extends Quantity<Q>> Unit<Q> HECTO(Unit<Q> unit) {
239    return unit.transform(HECTO.getConverter());
240  }
241
242  /**
243   * Returns the specified unit multiplied by the factor <code>10<sup>1</sup></code>
244   *
245   * @param <Q>
246   *          The type of the quantity measured by the unit.
247   * @param unit
248   *          any unit.
249   * @return <code>unit.times(1e1)</code>.
250   */
251  public static <Q extends Quantity<Q>> Unit<Q> DEKA(Unit<Q> unit) {
252    return unit.transform(DEKA.getConverter());
253  }
254
255  /**
256   * Returns the specified unit multiplied by the factor <code>10<sup>-1</sup></code>
257   *
258   * @param <Q>
259   *          The type of the quantity measured by the unit.
260   * @param unit
261   *          any unit.
262   * @return <code>unit.times(1e-1)</code>.
263   */
264  public static <Q extends Quantity<Q>> Unit<Q> DECI(Unit<Q> unit) {
265    return unit.transform(DECI.getConverter());
266  }
267
268  /**
269   * Returns the specified unit multiplied by the factor <code>10<sup>-2</sup></code>
270   *
271   * @param <Q>
272   *          The type of the quantity measured by the unit.
273   * @param unit
274   *          any unit.
275   * @return <code>unit.times(1e-2)</code>.
276   */
277  public static <Q extends Quantity<Q>> Unit<Q> CENTI(Unit<Q> unit) {
278    return unit.transform(CENTI.getConverter());
279  }
280
281  /**
282   * Returns the specified unit multiplied by the factor <code>10<sup>-3</sup></code>
283   *
284   * @param <Q>
285   *          The type of the quantity measured by the unit.
286   * @param unit
287   *          any unit.
288   * @return <code>unit.times(1e-3)</code>.
289   */
290  public static <Q extends Quantity<Q>> Unit<Q> MILLI(Unit<Q> unit) {
291    return unit.transform(MILLI.getConverter());
292  }
293
294  /**
295   * Returns the specified unit multiplied by the factor <code>10<sup>-6</sup></code>
296   *
297   * @param <Q>
298   *          The type of the quantity measured by the unit.
299   * @param unit
300   *          any unit.
301   * @return <code>unit.times(1e-6)</code>.
302   */
303  public static <Q extends Quantity<Q>> Unit<Q> MICRO(Unit<Q> unit) {
304    return unit.transform(MICRO.getConverter());
305  }
306
307  /**
308   * Returns the specified unit multiplied by the factor <code>10<sup>-9</sup></code>
309   *
310   * @param <Q>
311   *          The type of the quantity measured by the unit.
312   * @param unit
313   *          any unit.
314   * @return <code>unit.times(1e-9)</code>.
315   */
316  public static <Q extends Quantity<Q>> Unit<Q> NANO(Unit<Q> unit) {
317    return unit.transform(NANO.getConverter());
318  }
319
320  /**
321   * Returns the specified unit multiplied by the factor <code>10<sup>-12</sup></code>
322   *
323   * @param <Q>
324   *          The type of the quantity measured by the unit.
325   * @param unit
326   *          any unit.
327   * @return <code>unit.times(1e-12)</code>.
328   */
329  public static <Q extends Quantity<Q>> Unit<Q> PICO(Unit<Q> unit) {
330    return unit.transform(PICO.getConverter());
331  }
332
333  /**
334   * Returns the specified unit multiplied by the factor <code>10<sup>-15</sup></code>
335   *
336   * @param <Q>
337   *          The type of the quantity measured by the unit.
338   * @param unit
339   *          any unit.
340   * @return <code>unit.times(1e-15)</code>.
341   */
342  public static <Q extends Quantity<Q>> Unit<Q> FEMTO(Unit<Q> unit) {
343    return unit.transform(FEMTO.getConverter());
344  }
345
346  /**
347   * Returns the specified unit multiplied by the factor <code>10<sup>-18</sup></code>
348   *
349   * @param <Q>
350   *          The type of the quantity measured by the unit.
351   * @param unit
352   *          any unit.
353   * @return <code>unit.times(1e-18)</code>.
354   */
355  public static <Q extends Quantity<Q>> Unit<Q> ATTO(Unit<Q> unit) {
356    return unit.transform(ATTO.getConverter());
357  }
358
359  /**
360   * Returns the specified unit multiplied by the factor <code>10<sup>-21</sup></code>
361   *
362   * @param <Q>
363   *          The type of the quantity measured by the unit.
364   * @param unit
365   *          any unit.
366   * @return <code>unit.times(1e-21)</code>.
367   */
368  public static <Q extends Quantity<Q>> Unit<Q> ZEPTO(Unit<Q> unit) {
369    return unit.transform(ZEPTO.getConverter());
370  }
371
372  /**
373   * Returns the specified unit multiplied by the factor <code>10<sup>-24</sup></code>
374   *
375   * @param <Q>
376   *          The type of the quantity measured by the unit.
377   * @param unit
378   *          any unit.
379   * @return <code>unit.times(1e-24)</code>.
380   */
381  public static <Q extends Quantity<Q>> Unit<Q> YOCTO(Unit<Q> unit) {
382    return unit.transform(YOCTO.getConverter());
383  }
384}