| // © 2020 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html |
| |
| package com.ibm.icu.impl.units; |
| |
| import com.ibm.icu.util.MeasureUnit; |
| |
| public class SingleUnitImpl { |
| /** |
| * Simple unit index, unique for every simple unit, -1 for the dimensionless |
| * unit. This is an index into a string list in unit.txt {ConversionUnits}. |
| * <p> |
| * The default value is -1, meaning the dimensionless unit: |
| * isDimensionless() will return true, until index is changed. |
| */ |
| private int index = -1; |
| /** |
| * SimpleUnit is the simplest form of a Unit. For example, for "square-millimeter", the simple unit would be "meter"Ò |
| * <p> |
| * The default value is "", meaning the dimensionless unit: |
| * isDimensionless() will return true, until index is changed. |
| */ |
| private String simpleUnit = ""; |
| /** |
| * Determine the power of the `SingleUnit`. For example, for "square-meter", the dimensionality will be `2`. |
| * <p> |
| * NOTE: |
| * Default dimensionality is 1. |
| */ |
| private int dimensionality = 1; |
| /** |
| * SI Prefix |
| */ |
| private MeasureUnit.SIPrefix siPrefix = MeasureUnit.SIPrefix.ONE; |
| |
| public SingleUnitImpl clone() { |
| SingleUnitImpl result = new SingleUnitImpl(); |
| result.index = this.index; |
| result.dimensionality = this.dimensionality; |
| result.simpleUnit = this.simpleUnit; |
| result.siPrefix = this.siPrefix; |
| |
| return result; |
| } |
| |
| public MeasureUnit build() { |
| MeasureUnitImpl measureUnit = new MeasureUnitImpl(this); |
| return measureUnit.build(); |
| } |
| |
| /** |
| * Generates an neutral identifier string for a single unit which means we do not include the dimension signal. |
| * |
| * @throws IllegalArgumentException |
| */ |
| public String getNeutralIdentifier() { |
| StringBuilder result = new StringBuilder(); |
| int posPower = Math.abs(this.getDimensionality()); |
| |
| assert posPower > 0 : "getIdentifier does not support the dimensionless"; |
| |
| if (posPower == 1) { |
| // no-op |
| } else if (posPower == 2) { |
| result.append("square-"); |
| } else if (posPower == 3) { |
| result.append("cubic-"); |
| } else if (posPower <= 15) { |
| result.append("pow"); |
| result.append(posPower); |
| result.append('-'); |
| } else { |
| throw new IllegalArgumentException("Unit Identifier Syntax Error"); |
| } |
| |
| result.append(this.getSiPrefix().getIdentifier()); |
| result.append(this.getSimpleUnit()); |
| |
| return result.toString(); |
| } |
| |
| /** |
| * Compare this SingleUnitImpl to another SingleUnitImpl for the sake of |
| * sorting and coalescing. |
| * <p> |
| * Takes the sign of dimensionality into account, but not the absolute |
| * value: per-meter is not considered the same as meter, but meter is |
| * considered the same as square-meter. |
| * <p> |
| * The dimensionless unit generally does not get compared, but if it did, it |
| * would sort before other units by virtue of index being < 0 and |
| * dimensionality not being negative. |
| */ |
| int compareTo(SingleUnitImpl other) { |
| if (dimensionality < 0 && other.dimensionality > 0) { |
| // Positive dimensions first |
| return 1; |
| } |
| if (dimensionality > 0 && other.dimensionality < 0) { |
| return -1; |
| } |
| if (index < other.index) { |
| return -1; |
| } |
| if (index > other.index) { |
| return 1; |
| } |
| if (this.getSiPrefix().getPower() < other.getSiPrefix().getPower()) { |
| return -1; |
| } |
| if (this.getSiPrefix().getPower() > other.getSiPrefix().getPower()) { |
| return 1; |
| } |
| return 0; |
| } |
| |
| /** |
| * Checks whether this SingleUnitImpl is compatible with another for the purpose of coalescing. |
| * <p> |
| * Units with the same base unit and SI prefix should match, except that they must also have |
| * the same dimensionality sign, such that we don't merge numerator and denominator. |
| */ |
| boolean isCompatibleWith(SingleUnitImpl other) { |
| return (compareTo(other) == 0); |
| } |
| |
| public String getSimpleUnit() { |
| return simpleUnit; |
| } |
| |
| public void setSimpleUnit(int simpleUnitIndex, String[] simpleUnits) { |
| this.index = simpleUnitIndex; |
| this.simpleUnit = simpleUnits[simpleUnitIndex]; |
| } |
| |
| public int getDimensionality() { |
| return dimensionality; |
| } |
| |
| public void setDimensionality(int dimensionality) { |
| this.dimensionality = dimensionality; |
| } |
| |
| public MeasureUnit.SIPrefix getSiPrefix() { |
| return siPrefix; |
| } |
| |
| public void setSiPrefix(MeasureUnit.SIPrefix siPrefix) { |
| this.siPrefix = siPrefix; |
| } |
| |
| public int getIndex() { |
| return index; |
| } |
| |
| } |