001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2024, Jean-Marie Dautelle, Werner Keil, Otavio Santana. 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.Quantity; 039import javax.measure.Quantity.Scale; 040import javax.measure.Unit; 041 042import tech.units.indriya.ComparableQuantity; 043import tech.units.indriya.format.SimpleQuantityFormat; 044import tech.units.indriya.function.MixedRadix; 045 046/** 047 * Facade to access {@link Quantity} instances. 048 * 049 * @version 3.0, October 3, 2024 050 * @author Werner Keil 051 * @author Otavio Santana 052 * @since 1.0 053 */ 054public final class Quantities { 055 /** 056 * Private singleton constructor. 057 */ 058 private Quantities() { 059 } 060 061 /** 062 * Returns the scalar quantity of unknown type corresponding to the specified 063 * representation. This method can be used to parse {@link MixedQuantity mixed} 064 * quantities. All of these expressions:<br> 065 * <code> 066 * Quantity<Length> height = Quantities.getQuantity("1.70 m").asType(Length.class);<br> 067 * Quantity<Length> heightinCm = Quantities.getQuantity("170 cm").asType(Length.class);<br> 068 * Quantity<Length> heightMixed = Quantities.getQuantity("1 m 70 cm").asType(Length.class); 069 * </code> 070 * are equally supported. 071 * 072 * <p> 073 * <b>Note:</b> This method handles only <code>Locale</code>-neutral quantity formatting and parsing 074 * are handled by the {@link SimpleQuantityFormat} class.<br> 075 * Due to the versatile parsing of this method recognizing both single and mixed quantities, a unit must be provided, otherwise it'll fail. 076 * If you need to parse a unit-less quantity, please use the <code>parse()</code> method of {@link tech.units.indriya.AbstractQuantity AbstractQuantity} instead. 077 * </p> 078 * 079 * @param csq the decimal value(s) and unit(s) separated by space(s). 080 * @return <code>SimpleQuantityFormat.getInstance("n u~ ").parse(csq)</code> 081 * @throws IllegalArgumentException if no unit part was provided to parse 082 */ 083 public static Quantity<?> getQuantity(CharSequence csq) { 084 //try { 085 return SimpleQuantityFormat.getInstance("n u~ ").parse(csq); 086 //} catch (MeasurementParseException e) { 087// throw new IllegalArgumentException(e.getParsedString()); 088 // } 089 } 090 091 /** 092 * Returns the scalar quantity of type {@link NumberQuantity} in the specified unit and scale. 093 * 094 * @param value the measurement value. 095 * @param unit the measurement unit. 096 * @param scale the measurement scale. 097 * @return the corresponding <code>numeric</code> quantity. 098 * @throws NullPointerException if value, unit or scale were null 099 * @since 2.0 100 */ 101 public static <Q extends Quantity<Q>> ComparableQuantity<Q> getQuantity(Number value, Unit<Q> unit, Scale scale) { 102 Objects.requireNonNull(value); 103 Objects.requireNonNull(unit); 104 Objects.requireNonNull(scale); 105 return new NumberQuantity<>(value, unit, scale); 106 } 107 108 /** 109 * Returns the scalar quantity of type {@link NumberQuantity} in the specified unit and {@code ABSOLUTE} scale. 110 * 111 * @param value the measurement value. 112 * @param unit the measurement unit. 113 * @return the corresponding <code>numeric</code> quantity. 114 * @throws NullPointerException when value or unit were null 115 */ 116 public static <Q extends Quantity<Q>> ComparableQuantity<Q> getQuantity(Number value, Unit<Q> unit) { 117 return getQuantity(value, unit, ABSOLUTE); 118 } 119 120 /** 121 * Returns the mixed radix values and units combined into a single quantity of type {@link NumberQuantity} in the 122 * specified unit and scale. 123 * 124 * @param values the measurement values. 125 * @param units the measurement units. 126 * @param scale the measurement scale. 127 * @return the corresponding quantity. 128 * @throws NullPointerException if values or scale were null 129 * @throws IllegalArgumentException if the size of the values array does not 130 * match that of units. 131 * @since 2.0 132 */ 133 public static <Q extends Quantity<Q>> Quantity<Q> getQuantity(Number[] values, Unit<Q>[] units, Scale scale) { 134 Objects.requireNonNull(values); 135 Objects.requireNonNull(units); 136 if (values.length == units.length) { 137 return MixedRadix.of(units).createQuantity(values, scale); 138 } else { 139 throw new IllegalArgumentException( 140 String.format("%s values don't match %s units", values.length, units.length)); 141 } 142 } 143 144 /** 145 * Returns the mixed radix values and units combined into a single quantity in 146 * the {@code ABSOLUTE} scale. 147 * 148 * @param values the measurement values. 149 * @param units the measurement units. 150 * @return the corresponding quantity. 151 * @throws NullPointerException if values or units were null 152 * @throws IllegalArgumentException if the size of the values array does not 153 * match that of units. 154 * @since 2.0 155 */ 156 @SafeVarargs 157 public static <Q extends Quantity<Q>> Quantity<Q> getQuantity(Number[] values, Unit<Q>... units) { 158 return getQuantity(values, units, ABSOLUTE); 159 } 160 161 /** 162 * Returns the mixed radix values and units as {@link MixedQuantity} in the 163 * specified scale. 164 * 165 * @param values the measurement values. 166 * @param units the measurement units. 167 * @param scale the measurement scale. 168 * @return the corresponding mixed quantity. 169 * @throws NullPointerException if values, units or scale were null 170 * @throws IllegalArgumentException if the size of the values array does not 171 * match that of units. 172 * @since 2.1.2 173 */ 174 public static <Q extends Quantity<Q>> MixedQuantity<Q> getMixedQuantity(Number[] values, Unit<Q>[] units, 175 Scale scale) { 176 Objects.requireNonNull(values); 177 Objects.requireNonNull(units); 178 if (values.length == units.length) { 179 return MixedRadix.of(units).createMixedQuantity(values, scale); 180 } else { 181 throw new IllegalArgumentException( 182 String.format("%s values don't match %s units", values.length, units.length)); 183 } 184 } 185 186 /** 187 * Returns the mixed radix values and units as {@link MixedQuantity} in the 188 * {@code ABSOLUTE} scale. 189 * 190 * @param values the measurement values. 191 * @param units the measurement units. 192 * @return the corresponding mixed quantity. 193 * @throws NullPointerException if values, units or scale were null 194 * @throws IllegalArgumentException if the size of the values array does not 195 * match that of units. 196 * @since 2.1.2 197 */ 198 public static <Q extends Quantity<Q>> MixedQuantity<Q> getMixedQuantity(final Number[] values, 199 final Unit<Q>[] units) { 200 return getMixedQuantity(values, units, ABSOLUTE); 201 } 202}