blob: 0ba961d29529c9e7c9fbc9618d0d91a034258a93 [file] [log] [blame]
// © 2020 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl.number;
import java.util.ArrayList;
import java.util.List;
import com.ibm.icu.number.NumberFormatter;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.ULocale;
/**
* A MicroPropsGenerator that multiplexes between different LongNameHandlers,
* depending on the outputUnit.
*
* See processQuantity() for the input requirements.
*/
public class LongNameMultiplexer implements MicroPropsGenerator {
/**
* LongNameMultiplexer calls the parent MicroPropsGenerator itself,
* receiving the MicroProps instance in use for this formatting pipeline.
* Next it multiplexes between name handlers (fHandlers) which are not given
* access to a parent. Consequently LongNameMultiplexer must give these
* handlers the MicroProps instance.
*/
public static interface ParentlessMicroPropsGenerator {
public MicroProps processQuantityWithMicros(DecimalQuantity quantity, MicroProps micros);
}
private final MicroPropsGenerator fParent;
private List<ParentlessMicroPropsGenerator> fHandlers;
// Each MeasureUnit corresponds to the same-index MicroPropsGenerator
// pointed to in fHandlers.
private List<MeasureUnit> fMeasureUnits;
public LongNameMultiplexer(MicroPropsGenerator fParent) {
this.fParent = fParent;
}
// Produces a multiplexer for LongNameHandlers, one for each unit in
// `units`. An individual unit might be a mixed unit.
public static LongNameMultiplexer forMeasureUnits(ULocale locale,
List<MeasureUnit> units,
NumberFormatter.UnitWidth width,
String unitDisplayCase,
PluralRules rules,
MicroPropsGenerator parent) {
LongNameMultiplexer result = new LongNameMultiplexer(parent);
assert (units.size() > 0);
result.fMeasureUnits = new ArrayList<>();
result.fHandlers = new ArrayList<>();
for (int i = 0; i < units.size(); i++) {
MeasureUnit unit = units.get(i);
result.fMeasureUnits.add(unit);
if (unit.getComplexity() == MeasureUnit.Complexity.MIXED) {
MixedUnitLongNameHandler mlnh = MixedUnitLongNameHandler
.forMeasureUnit(locale, unit, width, unitDisplayCase, rules, null);
result.fHandlers.add(mlnh);
} else {
LongNameHandler lnh = LongNameHandler.forMeasureUnit(locale, unit, width, unitDisplayCase, rules, null);
result.fHandlers.add(lnh);
}
}
return result;
}
// The output unit must be provided via `micros.outputUnit`, it must match
// one of the units provided to the factory function.
@Override
public MicroProps processQuantity(DecimalQuantity quantity) {
// We call parent.processQuantity() from the Multiplexer, instead of
// letting LongNameHandler handle it: we don't know which LongNameHandler to
// call until we've called the parent!
MicroProps micros = this.fParent.processQuantity(quantity);
// Call the correct LongNameHandler based on outputUnit
for (int i = 0; i < this.fHandlers.size(); i++) {
if (fMeasureUnits.get(i).equals(micros.outputUnit)) {
ParentlessMicroPropsGenerator handler = fHandlers.get(i);
return handler.processQuantityWithMicros(quantity, micros);
}
}
throw new AssertionError
(" We shouldn't receive any outputUnit for which we haven't already got a LongNameHandler");
}
}