001/* 002 * ============================================================================ 003 * Copyright © 2002-2026 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * Licensed to the public under the agreements of the GNU Lesser General Public 007 * License, version 3.0 (the "License"). You may obtain a copy of the License at 008 * 009 * http://www.gnu.org/licenses/lgpl.html 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package org.tquadrat.foundation.value; 019 020import org.apiguardian.api.API; 021import org.tquadrat.foundation.annotation.ClassVersion; 022import org.tquadrat.foundation.lang.value.DimensionWithLinearConversion; 023 024import java.math.BigDecimal; 025 026import static java.lang.String.format; 027import static java.util.Arrays.stream; 028import static org.apiguardian.api.API.Status.STABLE; 029import static org.tquadrat.foundation.lang.Objects.requireNotEmptyArgument; 030 031/** 032 * The various instances of volume … 033 * 034 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 035 * @version $Id: Volume.java 1195 2026-04-15 21:33:40Z tquadrat $ 036 * @since 0.1.0 037 * 038 * @UMLGraph.link 039 */ 040@SuppressWarnings( "NewClassNamingConvention" ) 041@ClassVersion( sourceVersion = "$Id: Volume.java 1195 2026-04-15 21:33:40Z tquadrat $" ) 042@API( status = STABLE, since = "0.1.0" ) 043public enum Volume implements DimensionWithLinearConversion 044{ 045 /*------------------*\ 046 ====** Enum Declaration **================================================= 047 \*------------------*/ 048 /** 049 * A cubic millimeter. 050 */ 051 CUBIC_MILLIMETER( new BigDecimal( "0.000000001" ), "mm^3" ) 052 { 053 /** 054 * {@inheritDoc} 055 */ 056 @Override 057 public final String unitSymbolForPrinting() { return "mm³"; } 058 }, 059 060 /** 061 * A micro liter. 062 */ 063 MICRO_LITER( new BigDecimal( "0.000000001" ), "µl" ), 064 065 /** 066 * A cubic centimeter. 067 */ 068 CUBIC_CENTIMETER( new BigDecimal( "0.000001" ), "cm^3" ) 069 { 070 /** 071 * {@inheritDoc} 072 */ 073 @Override 074 public final String unitSymbolForPrinting() { return "cm³"; } 075 }, 076 077 /** 078 * A milliliter. 079 */ 080 MILLI_LITER( new BigDecimal( "0.000001" ), "ml" ), 081 082 /** 083 * A centiliter. 084 */ 085 CENTI_LITER( new BigDecimal( "0.00001" ), "cl" ), 086 087 /** 088 * A cubic inch. 089 */ 090 CUBIC_INCH( new BigDecimal( "0.000016387064" ), "in^3",1 ) 091 { 092 /** 093 * {@inheritDoc} 094 */ 095 @Override 096 public final String unitSymbolForPrinting() { return "in³"; } 097 }, 098 099 /** 100 * An imperial fluid ounce. 101 */ 102 FLUID_OUNCE_IMPERIAL( new BigDecimal( "0.0000284130625" ), "floz" ), 103 104 /** 105 * A deciliter. 106 */ 107 DECI_LITER( new BigDecimal( "0.0001" ), "dl" ), 108 109 /** 110 * A pint liquid imperial. 111 */ 112 PINT_LIQUID_IMPERIAL( new BigDecimal( "0.00056826128524935" ), "pt",1 ), 113 114 /** 115 * A cubic decimeter. 116 */ 117 CUBIC_DECIMETER( new BigDecimal( "0.001" ), "dm^3",1 ) 118 { 119 /** 120 * {@inheritDoc} 121 */ 122 @Override 123 public final String unitSymbolForPrinting() { return "dm³"; } 124 }, 125 126 /** 127 * A liter. 128 */ 129 LITER( new BigDecimal( "0.001" ), "l",1 ), 130 131 /** 132 * A bucket ("Eimer" in German). Obviously, this is not an 133 * official unit for a volume, but it is used quit often on a colloquial 134 * basis in Germany and other German-speaking countries to describe the 135 * amount of 10 litres. 136 */ 137 BUCKET( new BigDecimal( "0.01" ), "Eimer" ), 138 139 /** 140 * A US (liquid) gallon. 141 */ 142 US_GALLON( new BigDecimal( "0.003785411784" ), "USGallon",1 ) 143 { 144 /** 145 * {@inheritDoc} 146 */ 147 @Override 148 public final String unitSymbolForPrinting() { return "US Gallon"; } 149 }, 150 151 /** 152 * An imperial gallon. 153 */ 154 GALLON( new BigDecimal( "0.00454609" ), "gal",1 ), 155 156 /** 157 * A cubic foot. 158 */ 159 CUBIC_FOOT( new BigDecimal( "0.028316846592" ), "ft^3" ) 160 { 161 /** 162 * {@inheritDoc} 163 */ 164 @Override 165 public final String unitSymbolForPrinting() { return "ft³"; } 166 }, 167 168 /** 169 * A hekto liter. 170 */ 171 HEKTO_LITER( new BigDecimal( "0.1" ), "hl",1 ), 172 173 /** 174 * A barrel as used for mineral oil. 175 */ 176 BARREL_OIL( new BigDecimal( "0.158987294928" ), "barrel(oil)" ) 177 { 178 /** 179 * {@inheritDoc} 180 */ 181 @Override 182 public final String unitSymbolForPrinting() { return "barrel (oil)"; } 183 }, 184 185 /** 186 * An imperial barrel. 187 */ 188 IMPERIAL_BARREL( new BigDecimal( "0.16365924" ), "barrel(imperial)",1 ) 189 { 190 /** 191 * {@inheritDoc} 192 */ 193 @Override 194 public final String unitSymbolForPrinting() { return "barrel (imperial)"; } 195 }, 196 197 /** 198 * A cubic yard. 199 */ 200 CUBIC_YARD( new BigDecimal( "0.764554857984" ), "yd^3" ) 201 { 202 /** 203 * {@inheritDoc} 204 */ 205 @Override 206 public final String unitSymbolForPrinting() { return "yd³"; } 207 }, 208 209 /** 210 * A cubic meter. 211 */ 212 CUBIC_METER( BigDecimal.ONE, "m^3",3 ) 213 { 214 /** 215 * {@inheritDoc} 216 */ 217 @Override 218 public final String unitSymbolForPrinting() { return "m³"; } 219 }, 220 221 /** 222 * A "Festmeter"; this is used (in Germany) to specify an amount 223 * of wood. 224 */ 225 FESTMETER( BigDecimal.ONE, "Festmeter",1 ), 226 227 /** 228 * <p>{@summary A ton as used by <i>Traveller</i>® to specify the volume 229 * of a starship or other space going vessels or orbital installations.} 230 * It is defined as the volume of one metric ton or 1000 kg of liquid 231 * hydrogen (H<sub>2</sub>) with a specific density of 232 * 71 kg/m<sup>3</sup>.</p> 233 * <p>The <i>Traveller</i>® literature also uses a value of 234 * 13.5 m<sup>3</sup>, based on the dimensions used with ship floor 235 * plans: a square on such a plan has a side length of 1.5 m and the 236 * room height is taken as 3 m, with each square is the equivalent of 237 * half a ton (or 6.75 m<sup>3</sup>). For mapping purposes this is a 238 * valid approximation.</p> 239 */ 240 TON( new BigDecimal( "14.084507"), "ton" ), 241 242 /** 243 * A cubic kilometer. 244 */ 245 CUBIC_KILO_METER( new BigDecimal( "1000000000" ), "km^3",3 ) 246 { 247 /** 248 * {@inheritDoc} 249 */ 250 @Override 251 public final String unitSymbolForPrinting() { return "km³"; } 252 }, 253 254 /** 255 * A cubic mile. 256 */ 257 CUBIC_MILE( new BigDecimal( "4168181825.4406" ), "mi^3" ) 258 { 259 /** 260 * {@inheritDoc} 261 */ 262 @Override 263 public final String unitSymbolForPrinting() { return "mi³"; } 264 }; 265 266 /*------------*\ 267 ====** Attributes **======================================================= 268 \*------------*/ 269 /** 270 * The factor. 271 */ 272 private final BigDecimal m_Factor; 273 274 /** 275 * The default precision. 276 */ 277 private final int m_Precision; 278 279 /** 280 * The unit string. 281 */ 282 private final String m_UnitSymbol; 283 284 /*--------------*\ 285 ====** Constructors **===================================================== 286 \*--------------*/ 287 /** 288 * Creates a new {@code Volume} instance, with a default precision of zero 289 * mantissa digits. 290 * 291 * @param factor The factor. 292 * @param unitSymbol The unit symbol String. 293 */ 294 private Volume( final BigDecimal factor, final String unitSymbol ) 295 { 296 this( factor, unitSymbol, 0 ); 297 } // Volume() 298 299 /** 300 * Creates a new {@code Volume} instance. 301 * 302 * @param factor The factor. 303 * @param unitSymbol The unit symbol String. 304 * @param precision The default precision. 305 */ 306 private Volume( final BigDecimal factor, final String unitSymbol, final int precision ) 307 { 308 m_Factor = factor.stripTrailingZeros(); 309 m_UnitSymbol = unitSymbol; 310 m_Precision = precision; 311 } // Volume() 312 313 /*---------*\ 314 ====** Methods **========================================================== 315 \*---------*/ 316 /** 317 * {@inheritDoc} 318 */ 319 @Override 320 @SuppressWarnings( "unchecked" ) 321 public final Volume baseUnit() { return CUBIC_METER; } 322 323 /** 324 * {@inheritDoc} 325 */ 326 @Override 327 public final BigDecimal factor() { return m_Factor; } 328 329 /** 330 * Returns the {@code Volume} instance for the given unit symbol. 331 * 332 * @param unitSymbol The unit symbol. 333 * @return The respective instance. 334 * @throws IllegalArgumentException The given unit is unknown. 335 */ 336 public static final Volume forUnit( final String unitSymbol ) throws IllegalArgumentException 337 { 338 requireNotEmptyArgument( unitSymbol, "unitSymbol" ); 339 340 final var retValue = stream( values() ) 341 .filter( v -> v.unitSymbol().equals( unitSymbol ) ) 342 .findFirst() 343 .orElseThrow( () -> new IllegalArgumentException( format( MSG_UnknownUnit, unitSymbol ) ) ); 344 345 //---* Done *---------------------------------------------------------- 346 return retValue; 347 } // forUnit() 348 349 /** 350 * {@inheritDoc} 351 */ 352 @Override 353 public final int getPrecision() { return m_Precision; } 354 355 /** 356 * {@inheritDoc} 357 */ 358 @Override 359 public final String unitSymbol() { return m_UnitSymbol; } 360} 361// enum Volume 362 363/* 364 * End of File 365 */