001/*
002 *  Unit-API - Units of Measurement API for Java
003 *  Copyright (c) 2005-2016, 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.common;
027
028import static tec.units.ri.unit.MetricPrefix.MICRO;
029import static tec.units.ri.unit.Units.*;
030import static systems.uom.common.NonSI.AVOIRDUPOIS_POUND_DIVIDEND;
031import static systems.uom.common.NonSI.AVOIRDUPOIS_POUND_DIVISOR;
032
033import javax.measure.Unit;
034import javax.measure.quantity.Area;
035import javax.measure.quantity.Length;
036import javax.measure.quantity.Mass;
037import javax.measure.quantity.Temperature;
038import javax.measure.quantity.Time;
039import javax.measure.quantity.Volume;
040import javax.measure.spi.SystemOfUnits;
041
042import tec.units.ri.AbstractSystemOfUnits;
043import tec.units.ri.format.SimpleUnitFormat;
044import tec.units.ri.unit.ProductUnit;
045
046/**
047 * <p>
048 * This class contains units from the Imperial system.
049 * </p>
050 * <p>
051 * 
052 * @noextend This class is not intended to be extended by clients.
053 * 
054 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
055 * @version 0.6.1, $Date: 2016-09-09 $
056 * @see <a
057 *      href="http://en.wikipedia.org/wiki/http://en.wikipedia.org/wiki/Imperial_unit">Wikipedia:
058 *      Imperial Units</a>
059 */
060public final class Imperial extends AbstractSystemOfUnits {
061    private static final String SYSTEM_NAME = "Imperial";
062
063    /**
064     * Default constructor (prevents this class from being instantiated).
065     */
066    private Imperial() {
067    }
068
069    /**
070     * Returns the unique instance of this class.
071     * 
072     * @return the Imperial instance.
073     */
074    public static SystemOfUnits getInstance() {
075        return INSTANCE;
076    }
077
078    private static final Imperial INSTANCE = new Imperial();
079
080    // //////////
081    // Length //
082    // //////////
083
084    /**
085     * A unit of length equal to <code>0.0254 m</code> (standard name
086     * <code>in</code>).
087     */
088    public static final Unit<Length> INCH = INSTANCE.addUnit(USCustomary.INCH, "Inch", "in");
089
090    // ////////
091    // Mass //
092    // ////////
093
094    /**
095     * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
096     * standard name <code>lb</code>).
097     */
098    static final Unit<Mass> POUND = INSTANCE.addUnit(KILOGRAM.multiply(
099            AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR), "Pound", "lb");
100    /**
101     * An English and imperial unit of weight or mass now equal to 14
102     * avoirdupois pounds or 6.35029318 kg (<code>st</code>).
103     */
104    public static final Unit<Mass> STONE = INSTANCE.addUnit(KILOGRAM
105            .multiply(6.35029318), "Stone", "st");
106
107    /**
108     * A unit of mass equal to <code>1 / 16 {@link #POUND}</code> (standard name
109     * <code>oz</code>).
110     */
111    public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16));
112
113    /**
114     * A unit of mass equal to <code>2240 {@link #POUND}</code> (long ton,
115     * standard name <code>ton_uk</code>).
116     */
117    public static final Unit<Mass> TON_UK = addUnit(POUND.multiply(2240));
118
119    /**
120     * A unit of mass equal to <code>1000 kg</code> (metric ton, standard name
121     * <code>t</code>).
122     */
123    public static final Unit<Mass> METRIC_TON = addUnit(KILOGRAM.multiply(1000));
124
125    // ///////////////
126    // Temperature //
127    // ///////////////
128
129    /**
130     * A unit of temperature equal to <code>5/9 °K</code> (standard name
131     * <code>°R</code>).
132     */
133    static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5).divide(
134            9));
135
136    /**
137     * A unit of temperature equal to degree Rankine minus
138     * <code>459.67 °R</code> (standard name <code>°F</code>).
139     * 
140     * @see #RANKINE
141     */
142    static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE.shift(459.67));
143
144    // /////////
145    // Angle //
146    // /////////
147
148    // ////////////
149    // TimeUnit //
150    // ////////////
151    /**
152     * A unit of time equal to <code>60 s</code> (standard name <code>min</code>
153     * ).
154     */
155    static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60));
156
157    /**
158     * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard
159     * name <code>h</code>).
160     */
161    static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60));
162
163    // ////////////
164    // Velocity //
165    // ////////////
166
167    // ////////
168    // Area //
169    // ////////
170
171    /**
172     * A unit of area (standard name <code>sft</code> ).
173     */
174    public static final Unit<Area> SQUARE_FOOT = USCustomary.SQUARE_FOOT;
175
176    /**
177     * One acre is 43,560 <code>square feet</code> (standard name <code>a</code>
178     * ).
179     */
180    public static final Unit<Area> ACRE = addUnit(USCustomary.SQUARE_FOOT
181            .multiply(43560));
182
183    // //////////
184    // Energy //
185    // //////////
186
187    // //////////
188    // Volume //
189    // //////////
190    /**
191     * A unit of volume equal to one cubic decimeter (default label
192     * <code>L</code>, also recognized <code>µL, mL, cL, dL</code>).
193     */
194    static final Unit<Volume> LITRE = addUnit(CUBIC_METRE.divide(1000));
195
196    /**
197     * A unit of volume equal to one cubic inch (<code>in³</code>).
198     */
199    static final Unit<Volume> CUBIC_INCH = addUnit(new ProductUnit<Volume>(
200            USCustomary.INCH.pow(3))); // , "in³"));
201
202    /**
203     * A unit of volume equal to <code>4.546 09 {@link #LITRE}</code> (standard
204     * name <code>gal_uk</code>).
205     */
206    public static final Unit<Volume> GALLON_UK = addUnit(LITRE.multiply(454609)
207            .divide(100000));
208
209    /**
210     * A unit of volume equal to one UK gallon, Liquid Unit.
211     */
212    public static final Unit<Volume> GALLON_LIQUID = addUnit(CUBIC_INCH
213            .multiply(277.42));
214
215    /**
216     * A unit of volume equal to <code>1 / 160 {@link #GALLON_UK}</code>
217     * (standard name <code>oz_fl_uk</code>).
218     */
219    static final Unit<Volume> OUNCE_LIQUID_UK = addUnit(GALLON_UK.divide(160));
220
221    /**
222     * A unit of volume equal to <code>1 / 160 {@link #GALLON_LIQUID}</code>
223     * (standard name <code>oz_fl</code>).
224     */
225    public static final Unit<Volume> OUNCE_LIQUID = OUNCE_LIQUID_UK;
226
227    /**
228     * A unit of volume equal to <code>5 {@link #OUNCE_LIQUID}</code> (standard
229     * name <code>gi</code>).
230     */
231    public static final Unit<Volume> GILL = addUnit(OUNCE_LIQUID.multiply(5));
232
233    /**
234     * A unit of volume equal to <code>20 {@link #OUNCE_LIQUID}</code> (standard
235     * name <code>pt</code>).
236     */
237    public static final Unit<Volume> PINT = addUnit(OUNCE_LIQUID.multiply(20));
238
239    /**
240     * A unit of volume equal to <code>40 {@link #OUNCE_LIQUID}</code> (standard
241     * name <code>qt</code>).
242     */
243    public static final Unit<Volume> QUART = addUnit(OUNCE_LIQUID.multiply(40));
244
245    /**
246     * A unit of volume <code>~ 1 drop or 0.95 grain of water </code> (standard
247     * name <code>min</code>).
248     */
249    public static final Unit<Volume> MINIM = addUnit(MICRO(LITRE).multiply(
250            59.1938802d));
251
252    /**
253     * A unit of volume equal to <code>20 {@link #MINIM}</code> (standard name
254     * <code>fl scr</code>).
255     */
256    public static final Unit<Volume> FLUID_SCRUPLE = addUnit(MINIM.multiply(60));
257
258    /**
259     * A unit of volume equal to <code>3 {@link #FLUID_SCRUPLE}</code> (standard
260     * name <code>fl drc</code>).
261     */
262    public static final Unit<Volume> FLUID_DRACHM = addUnit(FLUID_SCRUPLE
263            .multiply(3));
264
265    /**
266     * Adds a new unit not mapped to any specified quantity type.
267     *
268     * @param unit
269     *            the unit being added.
270     * @return <code>unit</code>.
271     */
272    private static <U extends Unit<?>> U addUnit(U unit) {
273        INSTANCE.units.add(unit);
274        return unit;
275    }
276
277    // //////////////////////////////////////////////////////////////////////////
278    // Label adjustments for Imperial system
279    static {
280        SimpleUnitFormat.getInstance().label(POUND, "lb");
281        SimpleUnitFormat.getInstance().label(LITRE, "L");
282        SimpleUnitFormat.getInstance().label(FLUID_DRACHM, "fl drc");
283        SimpleUnitFormat.getInstance().label(FLUID_SCRUPLE, "fl scr");
284        SimpleUnitFormat.getInstance().label(PINT, "pt");
285    }
286
287    // ///////////////////
288    // Collection View //
289    // ///////////////////
290
291    @Override
292    public String getName() {
293        return SYSTEM_NAME;
294    }
295}