* unitsShort/duration/hour contains other{"{0} hrs"}.
*/
class UnitPatternSink extends UResource.TableSink {
- QuantityFormatter.Builder builder = new QuantityFormatter.Builder();
-
@Override
public void put(UResource.Key key, UResource.Value value) {
if (key.contentEquals("dnam")) {
// The key must be one of the plural form strings. For example:
// one{"{0} hr"}
// other{"{0} hrs"}
- if (!hasPatterns) {
- builder.add(key, value.getString());
- }
- }
- }
- @Override
- public void leave() {
- if (builder.hasPatterns()) {
+ QuantityFormatter countToFormat;
EnumMap<FormatWidth, QuantityFormatter> styleToCountToFormat =
cacheData.unitToStyleToCountToFormat.get(unit);
if (styleToCountToFormat == null) {
styleToCountToFormat =
new EnumMap<FormatWidth, QuantityFormatter>(FormatWidth.class);
cacheData.unitToStyleToCountToFormat.put(unit, styleToCountToFormat);
+ countToFormat = null;
+ } else {
+ countToFormat = styleToCountToFormat.get(width);
+ }
+ if (countToFormat == null) {
+ countToFormat = new QuantityFormatter();
+ styleToCountToFormat.put(width, countToFormat);
}
- styleToCountToFormat.put(width, builder.build());
+ countToFormat.addIfAbsent(key, value);
}
}
}
public UResource.TableSink getOrCreateTableSink(UResource.Key key, int initialSize) {
// Should we ignore or reject unknown units?
unit = MeasureUnit.internalGetInstance(type, key.toString()); // never null
- Map<FormatWidth, QuantityFormatter> styleToCountToFormat =
- cacheData.unitToStyleToCountToFormat.get(unit);
- hasPatterns = styleToCountToFormat != null && styleToCountToFormat.containsKey(width);
return patternSink;
}
}
FormatWidth width;
String type;
MeasureUnit unit;
-
- /** True if we already have plural-form display patterns for width/type/subtype. */
- boolean hasPatterns;
}
/**
package com.ibm.icu.text;
import com.ibm.icu.impl.SimplePatternFormatter;
+import com.ibm.icu.impl.UResource;
/**
* QuantityFormatter represents an unknown quantity of something and formats a known quantity
}
private static final int INDEX_COUNT = 6;
+ private final SimplePatternFormatter[] templates = new SimplePatternFormatter[INDEX_COUNT];
+
+ public QuantityFormatter() {}
+
/**
- * Builder builds a QuantityFormatter.
- *
- * @author rocketman
+ * Adds a template if there is none yet for the plural form.
+ *
+ * @param variant the plural variant, e.g "zero", "one", "two", "few", "many", "other"
+ * @param template the text for that plural variant with "{0}" as the quantity. For
+ * example, in English, the template for the "one" variant may be "{0} apple" while the
+ * template for the "other" variant may be "{0} apples"
+ * @throws IllegalArgumentException if variant is not recognized or
+ * if template has more than just the {0} placeholder.
*/
- static class Builder {
- private SimplePatternFormatter[] templates;
+ public void addIfAbsent(CharSequence variant, String template) {
+ addIfAbsent(variant, template, null);
+ }
- boolean hasPatterns() {
- return templates != null;
- }
+ /**
+ * Adds a template if there is none yet for the plural form.
+ * This version only calls UResource.Value.getString()
+ * if there is no template yet for the plural form.
+ *
+ * @param variant the plural variant, e.g "zero", "one", "two", "few", "many", "other"
+ * @param template the text for that plural variant with "{0}" as the quantity. For
+ * example, in English, the template for the "one" variant may be "{0} apple" while the
+ * template for the "other" variant may be "{0} apples"
+ * @throws IllegalArgumentException if variant is not recognized or
+ * if template has more than just the {0} placeholder.
+ */
+ public void addIfAbsent(CharSequence variant, UResource.Value template) {
+ addIfAbsent(variant, null, template);
+ }
- /**
- * Adds a template.
- * @param variant the plural variant, e.g "zero", "one", "two", "few", "many", "other"
- * @param template the text for that plural variant with "{0}" as the quantity. For
- * example, in English, the template for the "one" variant may be "{0} apple" while the
- * template for the "other" variant may be "{0} apples"
- * @return a reference to this Builder for chaining.
- * @throws IllegalArgumentException if variant is not recognized or
- * if template has more than just the {0} placeholder.
- */
- public Builder add(CharSequence variant, String template) {
- int idx = getPluralIndex(variant);
- if (idx < 0) {
- throw new IllegalArgumentException(variant.toString());
- }
- SimplePatternFormatter newT = SimplePatternFormatter.compile(template);
- if (newT.getPlaceholderCount() > 1) {
- throw new IllegalArgumentException(
- "Extra placeholders: " + template);
- }
- // Keep templates == null until we add one.
- ensureCapacity();
- templates[idx] = newT;
- return this;
+ private void addIfAbsent(CharSequence variant, String template, UResource.Value templateValue) {
+ int idx = getPluralIndex(variant);
+ if (idx < 0) {
+ throw new IllegalArgumentException(variant.toString());
}
-
- /**
- * Builds the new QuantityFormatter and resets this Builder to its initial state.
- * @return the new QuantityFormatter object.
- * @throws IllegalStateException if no template is specified for the "other" variant.
- * When throwing this exception, build leaves this builder in its current state.
- */
- public QuantityFormatter build() {
- if (templates == null || templates[0] == null) {
- throw new IllegalStateException("At least other variant must be set.");
- }
- QuantityFormatter result = new QuantityFormatter(templates);
- templates = null;
- return result;
+ if (templates[idx] != null) {
+ return;
}
-
- /**
- * Resets this builder to its initial state.
- */
- public Builder reset() {
- templates = null;
- return this;
+ if (template == null) {
+ template = templateValue.getString();
}
-
- private void ensureCapacity() {
- if (templates == null) {
- templates = new SimplePatternFormatter[INDEX_COUNT];
- }
+ SimplePatternFormatter newT = SimplePatternFormatter.compile(template);
+ if (newT.getPlaceholderCount() > 1) {
+ throw new IllegalArgumentException(
+ "Extra placeholders: " + template);
}
-
+ templates[idx] = newT;
}
- private final SimplePatternFormatter[] templates;
-
- private QuantityFormatter(SimplePatternFormatter[] templates) {
- this.templates = templates;
+ /**
+ * @return true if this object has at least the "other" variant
+ */
+ public boolean isValid() {
+ return templates[0] != null;
}
/**
* @return the SimplePatternFormatter
*/
public SimplePatternFormatter getByVariant(CharSequence variant) {
+ assert isValid();
int idx = getPluralIndex(variant);
SimplePatternFormatter template = templates[idx < 0 ? 0 : idx];
return template == null ? templates[0] : template;
ICUResourceBundle timeUnitBundle,
RelativeUnit relativeUnit,
EnumMap<RelativeUnit, QuantityFormatter[]> quantitativeUnitMap) {
- QuantityFormatter.Builder future = new QuantityFormatter.Builder();
- QuantityFormatter.Builder past = new QuantityFormatter.Builder();
+ QuantityFormatter future = new QuantityFormatter();
+ QuantityFormatter past = new QuantityFormatter();
timeUnitBundle = timeUnitBundle.getWithFallback("relativeTime");
addTimeUnit(
timeUnitBundle.getWithFallback("future"),
timeUnitBundle.getWithFallback("past"),
past);
quantitativeUnitMap.put(
- relativeUnit, new QuantityFormatter[] { past.build(), future.build() });
+ relativeUnit, new QuantityFormatter[] { past, future });
}
private static void addTimeUnit(
- ICUResourceBundle pastOrFuture, QuantityFormatter.Builder builder) {
+ ICUResourceBundle pastOrFuture, QuantityFormatter qf) {
int size = pastOrFuture.getSize();
for (int i = 0; i < size; i++) {
UResourceBundle r = pastOrFuture.get(i);
- builder.add(r.getKey(), r.getString());
+ qf.addIfAbsent(r.getKey(), r.getString());
}
}