All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.squarespace.cldr.MessageArgsUnitParser Maven / Gradle / Ivy

package com.squarespace.cldr;

import static com.squarespace.cldr.MessageArgsDecimalParser.isEmpty;

import com.squarespace.cldr.units.Unit;
import com.squarespace.cldr.units.UnitCategory;
import com.squarespace.cldr.units.UnitConverter;
import com.squarespace.cldr.units.UnitFactorSet;
import com.squarespace.cldr.units.UnitFactorSets;
import com.squarespace.cldr.units.UnitFormat;
import com.squarespace.cldr.units.UnitFormatOptions;


class MessageArgsUnitParser implements MessageArgsParser {

  private final UnitFormatOptions opts = new UnitFormatOptions();
  
  protected Unit inputUnit;
  protected Unit exactUnit;
  protected Unit[] exactUnits;
  protected String compact;
  protected Unit[] sequence;
  protected UnitFactorSet factorSet;
  
  public UnitFormatOptions options() {
    return opts;
  }
  
  public void reset() {
    opts.reset();
    inputUnit = null;
    exactUnit = null;
    exactUnits = null;
    compact = null;
    sequence = null;
    factorSet = null;
  }
  
  @Override
  public void set(String key, String value) {
    if (!isEmpty(value)) {
      switch (key) {
        case "compact":
          compact = value;
          break;
          
        case "in":
          inputUnit = Unit.fromIdentifier(value);
          break;
          
        case "out":
          if (value.indexOf(",") == -1) {
            exactUnit = Unit.fromIdentifier(value);
          } else {
            exactUnits = parseUnitList(value);
          }
          break;
        
        case "sequence":
          if (sequence == null && compact == null) {
            sequence = parseUnitList(value);
          }
          break;
          
        case "format":
          switch (value) {
            case "long":
              opts.setFormat(UnitFormat.LONG);
              break;
            case "narrow":
              opts.setFormat(UnitFormat.NARROW);
              break;
            case "short":
              opts.setFormat(UnitFormat.SHORT);
              break;
            default:
              break;
          }
          
        default:
          MessageArgsDecimalParser.setNumberOption(key, value, opts);
          break;
      }
      
    } else {
      MessageArgsDecimalParser.setNumberOption(key, value, opts);
    }
  }
  
  /**
   * Some categories only have a single possible unit depending the locale.
   */
  protected static Unit selectExactUnit(String compact, UnitConverter converter) {
    if (compact != null) {
      switch (compact) {
        case "consumption":
          return converter.consumptionUnit();
        case "light":
          return Unit.LUX;
        case "speed":
          return converter.speedUnit();
        case "temp":
        case "temperature":
          return converter.temperatureUnit();
        default:
          break;
      }
    }
    return null;
  }

  /**
   * Select a factor set based on a name, used to format compact units. For example,
   * if compact="bytes" we return a factor set DIGITAL_BYTES. This set is then used
   * to produce the most compact form for a given value, e.g. "1.2MB", "37TB", etc.
   */
  protected static UnitFactorSet selectFactorSet(String compact, UnitConverter converter) {
    if (compact != null) {
      switch (compact) {
        case "angle":
        case "angles":
          return UnitFactorSets.ANGLE;
        case "area":
          return converter.areaFactors();
        case "bit":
        case "bits":
          return UnitFactorSets.DIGITAL_BITS;
        case "byte":
        case "bytes":
          return UnitFactorSets.DIGITAL_BYTES;
        case "duration":
          return UnitFactorSets.DURATION;
        case "duration-large":
          return UnitFactorSets.DURATION_LARGE;
        case "duration-small":
          return UnitFactorSets.DURATION_SMALL;
        case "electric":
          return UnitFactorSets.ELECTRIC;
        case "energy":
          return UnitFactorSets.ENERGY;
        case "frequency":
          return UnitFactorSets.FREQUENCY;
        case "length":
          return converter.lengthFactors();
        case "mass":
          return converter.massFactors();
        case "power":
          return UnitFactorSets.POWER;
        case "volume":
          return converter.volumeFactors();
        case "liquid":
          return converter.volumeLiquidFactors();
        default:
          break;
      }
    }
    return null;
  }

  /**
   * Based on the unit we're converting to, guess the input unit. For example, if we're
   * converting to MEGABIT and no input unit was specified, assume BIT.
   */
  protected static Unit inputFromExactUnit(Unit exact, UnitConverter converter) {
    switch (exact) {
      case TERABIT:
      case GIGABIT:
      case MEGABIT:
      case KILOBIT:
      case BIT:
        return Unit.BIT;

      case TERABYTE:
      case GIGABYTE:
      case MEGABYTE:
      case KILOBYTE:
      case BYTE:
        return Unit.BYTE;

      default:
        break;
    }

    UnitCategory category = exact.category();
    switch (category) {
      case CONSUMPTION:
        return converter.consumptionUnit();
      case ELECTRIC:
        return Unit.AMPERE;
      case FREQUENCY:
        return Unit.HERTZ;
      case LIGHT:
        return Unit.LUX;
      case PRESSURE:
        return Unit.MILLIBAR;
      case SPEED:
        return converter.speedUnit();
      case TEMPERATURE:
        return converter.temperatureUnit();

      default:
        UnitFactorSet factorSet = getDefaultFactorSet(category, converter);
        if (factorSet != null) {
          return factorSet.base();
        }
        break;
    }
    return null;
  }
  
  /**
   * Default conversion factors for each category. Some of these differ based on the locale
   * of the converter.
   */
  protected static UnitFactorSet getDefaultFactorSet(UnitCategory category, UnitConverter converter) {
    switch (category) {
      case ANGLE:
        return UnitFactorSets.ANGLE;
      case AREA:
        return converter.areaFactors();
      case DURATION:
        return UnitFactorSets.DURATION;
      case ELECTRIC:
        return UnitFactorSets.ELECTRIC;
      case ENERGY:
        return converter.energyFactors();
      case FREQUENCY:
        return UnitFactorSets.FREQUENCY;
      case LENGTH:
        return converter.lengthFactors();
      case MASS:
        return converter.massFactors();
      case POWER:
        return UnitFactorSets.POWER;
      case VOLUME:
        return converter.volumeFactors();
      default:
        break;
    }
    return null;
  }


  private static Unit[] parseUnitList(String value) {
    String[] parts = value.split(",");
    UnitCategory category = null;
    Unit[] units = new Unit[parts.length];
    for (int i = 0; i < parts.length; i++) {
      Unit unit = Unit.fromIdentifier(parts[i]);

      // Bail out on invalid or incompatible units
      if (unit == null) {
        return null;
      }

      if (category == null) {
        category = unit.category();
      } else if (unit.category() != category) {
        return null;
      }
      units[i] = unit;
    }
    return units;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy