001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2020, Units of Measurement project. 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, Indriya 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.units.indriya.quantity; 031 032import static javax.measure.Quantity.Scale.ABSOLUTE; 033 034import java.math.BigDecimal; 035import java.math.BigInteger; 036import java.util.Objects; 037 038import javax.measure.MeasurementException; 039import javax.measure.Quantity; 040import javax.measure.Quantity.Scale; 041import javax.measure.Unit; 042import javax.measure.format.MeasurementParseException; 043 044import tech.units.indriya.ComparableQuantity; 045import tech.units.indriya.format.AbstractQuantityFormat; 046import tech.units.indriya.format.SimpleQuantityFormat; 047import tech.units.indriya.function.MixedRadix; 048 049/** 050 * Singleton class for accessing {@link Quantity} instances. 051 * 052 * @version 1.10, April 20, 2019 053 * @author keilw 054 * @author otaviojava 055 * @since 1.0 056 */ 057public final class Quantities { 058 /** 059 * Private singleton constructor. 060 */ 061 private Quantities() { 062 } 063 064 /** 065 * Returns the {@link #valueOf(java.math.BigDecimal, javax.measure.unit.Unit) 066 * decimal} quantity of unknown type corresponding to the specified 067 * representation. This method can be used to parse dimensionless 068 * quantities.<br> 069 * <code> 070 * Quantity<Dimensionless> proportion = Quantities.getQuantity("0.234").asType(Dimensionless.class); 071 * </code> 072 * 073 * <p> 074 * Note: This method handles only Locale-neutral quantity formatting and parsing 075 * are handled by the {@link AbstractQuantityFormat} class and its subclasses. 076 * </p> 077 * 078 * @param csq the decimal value and its unit (if any) separated by space(s). 079 * @return <code>QuantityFormat.getInstance(LOCALE_NEUTRAL).parse(csq)</code> 080 */ 081 public static Quantity<?> getQuantity(CharSequence csq) { 082 try { 083 return SimpleQuantityFormat.getInstance("n u~ ").parse(csq); 084 } catch (MeasurementParseException e) { 085 throw new IllegalArgumentException(e.getParsedString()); 086 } 087 } 088 089 /** 090 * Returns the scalar quantity. When the {@link Number} was {@link BigDecimal} 091 * or {@link BigInteger} will uses {@link DecimalQuantity}, when the 092 * {@link Number} was {@link Double} will {@link DoubleQuantity} otherwise will 093 * {@link NumberQuantity}. in the specified unit. 094 * 095 * @param value the measurement value. 096 * @param unit the measurement unit. 097 * @param scale the measurement scale. 098 * @return the corresponding <code>numeric</code> quantity. 099 * @throws NullPointerException if value, unit or scale were null 100 * @throws MeasurementException if unit is a MixedUnit 101 * @since 2.0 102 */ 103 public static <Q extends Quantity<Q>> ComparableQuantity<Q> getQuantity(Number value, Unit<Q> unit, Scale scale) { 104 Objects.requireNonNull(value); 105 Objects.requireNonNull(unit); 106 Objects.requireNonNull(scale); 107 return new NumberQuantity<>(value, unit, scale); 108 } 109 110 /** 111 * Returns the scalar quantity. When the {@link Number} was {@link BigDecimal} 112 * or {@link BigInteger} will uses {@link DecimalQuantity}, when the 113 * {@link Number} was {@link Double} will {@link DoubleQuantity} otherwise will 114 * {@link NumberQuantity}. in the specified unit. 115 * 116 * @param value the measurement value. 117 * @param unit the measurement unit. 118 * @return the corresponding <code>numeric</code> quantity. 119 * @throws NullPointerException when value or unit were null 120 */ 121 public static <Q extends Quantity<Q>> ComparableQuantity<Q> getQuantity(Number value, Unit<Q> unit) { 122 return getQuantity(value, unit, ABSOLUTE); 123 } 124 125 /** 126 * Returns the mixed radix values and units combined into a single quantity. 127 * When the {@link Number} was {@link BigDecimal} or {@link BigInteger} will 128 * uses {@link DecimalQuantity}, when the {@link Number} was {@link Double} will 129 * {@link DoubleQuantity} otherwise will {@link NumberQuantity}. in the 130 * specified unit. 131 * 132 * @param values the measurement values. 133 * @param units the measurement units. 134 * @param scale the measurement scale. 135 * @return the corresponding quantity. 136 * @throws NullPointerException if value or scale were null 137 * @throws IllegalArgumentException if the size of the values array does not 138 * match that of units. 139 * @since 2.0 140 */ 141 public static <Q extends Quantity<Q>> Quantity<Q> getQuantity(Number[] values, Unit<Q>[] units, Scale scale) { 142 if (values.length == units.length) { 143 return MixedRadix.of(units).createQuantity(values, scale); 144 } else { 145 throw new IllegalArgumentException( 146 String.format("%s values don't match %s units", values.length, units.length)); 147 } 148 } 149 150 /** 151 * Returns the mixed radix values and units combined into a single quantity in 152 * the {@code ABSOLUTE} scale. 153 * 154 * @param values the measurement values. 155 * @param units the measurement units. 156 * @return the corresponding quantity. 157 * @throws NullPointerException if value or unit were null 158 * @throws IllegalArgumentException if the size of the values array does not 159 * match that of units. 160 * @since 2.0 161 */ 162 @SafeVarargs 163 public static <Q extends Quantity<Q>> Quantity<Q> getQuantity(Number[] values, Unit<Q>... units) { 164 return getQuantity(values, units, ABSOLUTE); 165 } 166 167 /** 168 * Returns the mixed radix values and units as {@link CompoundQuantity} in the 169 * specified scale. 170 * 171 * @param values the measurement values. 172 * @param units the measurement units. 173 * @param scale the measurement scale. 174 * @return the corresponding compound quantity. 175 * @throws NullPointerException if values, units or scale were null 176 * @throws IllegalArgumentException if the size of the values array does not 177 * match that of units. 178 * @since 2.0 179 */ 180 public static <Q extends Quantity<Q>> CompoundQuantity<Q> getCompoundQuantity(Number[] values, Unit<Q>[] units, 181 Scale scale) { 182 if (values.length == units.length) { 183 return MixedRadix.of(units).createCompoundQuantity(values, scale); 184 } else { 185 throw new IllegalArgumentException( 186 String.format("%s values don't match %s units", values.length, units.length)); 187 } 188 } 189 190 /** 191 * Returns the mixed radix values and units as {@link CompoundQuantity} in the 192 * {@code ABSOLUTE} scale. 193 * 194 * @param values the measurement values. 195 * @param units the measurement units. 196 * @return the corresponding compound quantity. 197 * @throws NullPointerException if values, units or scale were null 198 * @throws IllegalArgumentException if the size of the values array does not 199 * match that of units. 200 * @since 2.0 201 */ 202 public static <Q extends Quantity<Q>> CompoundQuantity<Q> getCompoundQuantity(final Number[] values, 203 final Unit<Q>[] units) { 204 return getCompoundQuantity(values, units, ABSOLUTE); 205 } 206}