ICU-10606 Introduce DontCareFieldPosition.
X-SVN-Rev: 34799
This commit is contained in:
parent
652d2952a2
commit
6f82c4b2d3
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -272,6 +272,7 @@ icu4j/main/classes/core/.settings/edu.umd.cs.findbugs.core.prefs -text
|
||||
icu4j/main/classes/core/.settings/org.eclipse.core.resources.prefs -text
|
||||
icu4j/main/classes/core/.settings/org.eclipse.jdt.core.prefs -text
|
||||
icu4j/main/classes/core/manifest.stub -text
|
||||
icu4j/main/classes/core/src/com/ibm/icu/impl/DontCareFieldPosition.java -text
|
||||
icu4j/main/classes/core/src/com/ibm/icu/text/QuantityFormatter.java -text
|
||||
icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java -text
|
||||
icu4j/main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
package com.ibm.icu.impl;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
|
||||
/**
|
||||
* DontCareFieldPosition is a subclass of FieldPosition that indicates that the
|
||||
* caller is not interested in the start and end position of any field.
|
||||
* <p>
|
||||
* DontCareFieldPosition is a singleton, and its instance is immutable.
|
||||
* <p>
|
||||
* A <code>format</code> method use <code>fpos == DontCareFieldPosition.INSTANCE</code>
|
||||
* to tell whether or not it needs to calculate a field position.
|
||||
*
|
||||
*/
|
||||
public final class DontCareFieldPosition extends FieldPosition {
|
||||
|
||||
public static final DontCareFieldPosition INSTANCE = new DontCareFieldPosition();
|
||||
|
||||
private DontCareFieldPosition() {
|
||||
// Pick some random number to be sure that we don't accidentally match with
|
||||
// a field.
|
||||
super(-913028704);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeginIndex(int i) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEndIndex(int i) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
}
|
@ -28,6 +28,7 @@ import java.util.Map.Entry;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.icu.impl.DontCareFieldPosition;
|
||||
import com.ibm.icu.impl.ICUResourceBundle;
|
||||
import com.ibm.icu.impl.SimpleCache;
|
||||
import com.ibm.icu.util.Currency;
|
||||
@ -239,6 +240,10 @@ public class MeasureFormat extends UFormat {
|
||||
* then its indices are set to the beginning and end of the first such field
|
||||
* encountered. MeasureFormat itself does not supply any fields.
|
||||
*
|
||||
* Calling a
|
||||
* <code>formatMeasures</code> method is preferred over calling
|
||||
* this method as they give better performance.
|
||||
*
|
||||
* @param obj must be a Collection<? extends Measure>, Measure[], or Measure object.
|
||||
* @param toAppendTo Formatted string appended here.
|
||||
* @pram pos Identifies a field in the formatted text.
|
||||
@ -296,7 +301,7 @@ public class MeasureFormat extends UFormat {
|
||||
*/
|
||||
public String formatMeasures(Measure... measures) {
|
||||
StringBuilder result = this.formatMeasures(
|
||||
new StringBuilder(), new FieldPosition(0), measures);
|
||||
new StringBuilder(), DontCareFieldPosition.INSTANCE, measures);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@ -335,48 +340,29 @@ public class MeasureFormat extends UFormat {
|
||||
}
|
||||
}
|
||||
|
||||
// Zero out our field position so that we can tell when we find our field.
|
||||
FieldPosition fpos = new FieldPosition(fieldPosition.getFieldAttribute(), fieldPosition.getField());
|
||||
FieldPosition dummyPos = new FieldPosition(0);
|
||||
|
||||
int fieldPositionFoundIndex = -1;
|
||||
StringBuilder[] results = new StringBuilder[measures.length];
|
||||
for (int i = 0; i < measures.length; ++i) {
|
||||
if (fieldPositionFoundIndex == -1) {
|
||||
results[i] = formatMeasure(measures[i], new StringBuilder(), fpos);
|
||||
if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
|
||||
fieldPositionFoundIndex = i;
|
||||
}
|
||||
} else {
|
||||
results[i] = formatMeasure(measures[i], new StringBuilder(), dummyPos);
|
||||
}
|
||||
}
|
||||
ListFormatter listFormatter = ListFormatter.getInstance(getLocale(),
|
||||
length == FormatWidth.WIDE ? ListFormatter.Style.DURATION : ListFormatter.Style.DURATION_SHORT);
|
||||
|
||||
// Fix up FieldPosition indexes if our field is found.
|
||||
if (fieldPositionFoundIndex != -1) {
|
||||
String listPattern = listFormatter.getPatternForNumItems(measures.length);
|
||||
int positionInPattern = listPattern.indexOf("{" + fieldPositionFoundIndex + "}");
|
||||
if (positionInPattern == -1) {
|
||||
throw new IllegalStateException("Can't find position with ListFormatter.");
|
||||
}
|
||||
// Now we have to adjust our position in pattern
|
||||
// based on the previous values.
|
||||
for (int i = 0; i < fieldPositionFoundIndex; i++) {
|
||||
positionInPattern += (results[i].length() - ("{" + i + "}").length());
|
||||
}
|
||||
fieldPosition.setBeginIndex(fpos.getBeginIndex() + positionInPattern);
|
||||
fieldPosition.setEndIndex(fpos.getEndIndex() + positionInPattern);
|
||||
}
|
||||
String[] results = null;
|
||||
if (fieldPosition == DontCareFieldPosition.INSTANCE) {
|
||||
|
||||
// Fast track: No field position.
|
||||
results = new String[measures.length];
|
||||
for (int i = 0; i < measures.length; i++) {
|
||||
results[i] = formatMeasure(measures[i]);
|
||||
}
|
||||
} else {
|
||||
|
||||
// Slow track: Have to calculate field position.
|
||||
results = formatMeasuresSlowTrack(listFormatter, fieldPosition, measures);
|
||||
}
|
||||
|
||||
// This is safe because appendable is of type T.
|
||||
try {
|
||||
return (T) appendable.append(listFormatter.format((Object[]) results));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Two MeasureFormats, a and b, are equal if and only if they have the same width,
|
||||
@ -612,6 +598,12 @@ public class MeasureFormat extends UFormat {
|
||||
return unitToStyleToCountToFormat;
|
||||
}
|
||||
|
||||
private String formatMeasure(Measure measure) {
|
||||
return formatMeasure(
|
||||
measure, new StringBuilder(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
}
|
||||
|
||||
private <T extends Appendable> T formatMeasure(
|
||||
Measure measure, T appendable, FieldPosition fieldPosition) {
|
||||
Number n = measure.getNumber();
|
||||
@ -689,6 +681,43 @@ public class MeasureFormat extends UFormat {
|
||||
return new MeasureProxy(getLocale(), length, numberFormat.get(), CURRENCY_FORMAT);
|
||||
}
|
||||
|
||||
private String[] formatMeasuresSlowTrack(ListFormatter listFormatter, FieldPosition fieldPosition,
|
||||
Measure... measures) {
|
||||
String[] results = new String[measures.length];
|
||||
|
||||
// Zero out our field position so that we can tell when we find our field.
|
||||
FieldPosition fpos = new FieldPosition(fieldPosition.getFieldAttribute(), fieldPosition.getField());
|
||||
|
||||
int fieldPositionFoundIndex = -1;
|
||||
for (int i = 0; i < measures.length; ++i) {
|
||||
if (fieldPositionFoundIndex == -1) {
|
||||
results[i] = formatMeasure(measures[i], new StringBuilder(), fpos).toString();
|
||||
if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
|
||||
fieldPositionFoundIndex = i;
|
||||
}
|
||||
} else {
|
||||
results[i] = formatMeasure(measures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix up FieldPosition indexes if our field is found.
|
||||
if (fieldPositionFoundIndex != -1) {
|
||||
String listPattern = listFormatter.getPatternForNumItems(measures.length);
|
||||
int positionInPattern = listPattern.indexOf("{" + fieldPositionFoundIndex + "}");
|
||||
if (positionInPattern == -1) {
|
||||
throw new IllegalStateException("Can't find position with ListFormatter.");
|
||||
}
|
||||
// Now we have to adjust our position in pattern
|
||||
// based on the previous values.
|
||||
for (int i = 0; i < fieldPositionFoundIndex; i++) {
|
||||
positionInPattern += (results[i].length() - ("{" + i + "}").length());
|
||||
}
|
||||
fieldPosition.setBeginIndex(fpos.getBeginIndex() + positionInPattern);
|
||||
fieldPosition.setEndIndex(fpos.getEndIndex() + positionInPattern);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// type is one of "hm", "ms" or "hms"
|
||||
private static DateFormat loadNumericDurationFormat(
|
||||
ICUResourceBundle r, String type) {
|
||||
|
@ -515,7 +515,7 @@ if ( searchPluralCount.equals("other") ) {
|
||||
|
||||
// boilerplate code to make TimeUnitFormat otherwise follow the contract of
|
||||
// MeasureFormat
|
||||
|
||||
|
||||
/**
|
||||
* @draft ICU 53
|
||||
* @provisional
|
||||
|
@ -163,6 +163,11 @@ public class MeasureUnitTest extends TestFmwk {
|
||||
assertSame("Identity check", expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
public void testFormatMeasureSingleArg() {
|
||||
MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
|
||||
assertEquals("", "5 meters", mf.format(new Measure(5, MeasureUnit.METER)));
|
||||
}
|
||||
|
||||
public void testMultiples() {
|
||||
ULocale russia = new ULocale("ru");
|
||||
|
Loading…
Reference in New Issue
Block a user