ICU-10646 Change SimplePatternFormatter.format() method to take String... instead of Object. replace formatValues() with format method that takes a StringBuilder and an int[].

X-SVN-Rev: 35034
This commit is contained in:
Travis Keep 2014-01-30 07:00:03 +00:00
parent a4074397ec
commit 0f59bff9aa
2 changed files with 82 additions and 200 deletions

View File

@ -113,59 +113,7 @@ public class SimplePatternFormatter {
return new SimplePatternFormatter(newPattern.toString(), placeholdersBuilder);
}
/**
* Formats given value.
* @throws UnsupportedOperationException if this object's pattern expects
* more than one value
*/
public String format(Object arg0) {
StringResultBuilder builder = new StringResultBuilder();
if (!formatPrivate(new Object[] {arg0}, builder)) {
throw new UnsupportedOperationException();
}
return builder.build();
}
/**
* Formats given values.
* @throws UnsupportedOperationException if this object's pattern expects more than two
* values.
*/
public String format(Object arg0, Object arg1) {
StringResultBuilder builder = new StringResultBuilder();
if (!formatPrivate(new Object[] {arg0, arg1}, builder)) {
throw new UnsupportedOperationException();
}
return builder.build();
}
/**
* Formats given values.
* @throws UnsupportedOperationException if this object's pattern expects more than three
* values.
*/
public String format(Object arg0, Object arg1, Object arg2) {
StringResultBuilder builder = new StringResultBuilder();
if (!formatPrivate(new Object[] {arg0, arg1, arg2}, builder)) {
throw new UnsupportedOperationException();
}
return builder.build();
}
/**
* Formats given values.
* @throws IllegalArgumentException if args.length < this.getPlaceholderCount()
* values.
*/
public Formatted formatValues(Object[] args) {
FormattedResultBuilder builder = new FormattedResultBuilder();
if (!formatPrivate(args, builder)) {
throw new IllegalArgumentException();
}
return builder.build();
}
/**
* Returns the max placeholder ID + 1.
*/
@ -173,6 +121,64 @@ public class SimplePatternFormatter {
return placeholderCount;
}
/**
* Formats the given values.
*/
public String format(String... values) {
return format(new StringBuilder(), null, values).toString();
}
/**
* Formats the given values.
*
* @param appendTo the result appended here.
* @param offsets position of first value in result stored in offfsets[0];
* second in offsets[1]; third in offsets[2] etc.
* @param values the values
* @return appendTo
*/
public StringBuilder format(
StringBuilder appendTo, int[] offsets, String... values) {
if (values.length < placeholderCount) {
throw new IllegalArgumentException("Too few values.");
}
int offsetLen = offsets == null ? 0 : offsets.length;
for (int i = 0; i < offsetLen; i++) {
offsets[i] = -1;
}
if (placeholderIdsOrderedByOffset.length == 0) {
appendTo.append(patternWithoutPlaceholders);
return appendTo;
}
appendTo.append(
patternWithoutPlaceholders,
0,
placeholderIdsOrderedByOffset[0]);
setPlaceholderOffset(
placeholderIdsOrderedByOffset[1],
appendTo.length(),
offsets,
offsetLen);
appendTo.append(values[placeholderIdsOrderedByOffset[1]]);
for (int i = 2; i < placeholderIdsOrderedByOffset.length; i += 2) {
appendTo.append(
patternWithoutPlaceholders,
placeholderIdsOrderedByOffset[i - 2],
placeholderIdsOrderedByOffset[i]);
setPlaceholderOffset(
placeholderIdsOrderedByOffset[i + 1],
appendTo.length(),
offsets,
offsetLen);
appendTo.append(values[placeholderIdsOrderedByOffset[i + 1]]);
}
appendTo.append(
patternWithoutPlaceholders,
placeholderIdsOrderedByOffset[placeholderIdsOrderedByOffset.length - 2],
patternWithoutPlaceholders.length());
return appendTo;
}
/**
* Formats this object using values {0}, {1} etc. Note that this is
* not the same as the original pattern string used to build this object.
@ -183,80 +189,16 @@ public class SimplePatternFormatter {
for (int i = 0; i < values.length; i++) {
values[i] = String.format("{%d}", i);
}
return formatValues(values).toString();
return format(new StringBuilder(), null, values).toString();
}
/**
* The immutable representation of a formatted value.
*/
public static class Formatted {
private final String result;
private final int[] offsets;
private Formatted(String result, int[] placeholderOffsets) {
this.result = result;
this.offsets = placeholderOffsets;
private static void setPlaceholderOffset(
int placeholderId, int offset, int[] offsets, int offsetLen) {
if (placeholderId < offsetLen) {
offsets[placeholderId] = offset;
}
/**
* Returns the offset of a particular placeholder in this formatted
* value. Returns -1 if the placeholder does not exist.
* @throws IndexOutOfBoundsException if placeholderId is negative.
*/
public int getOffset(int placeholderId) {
if (placeholderId < 0) {
throw new IndexOutOfBoundsException();
}
if (placeholderId >= offsets.length) {
return -1;
}
return offsets[placeholderId];
}
/**
* Returns the formatted string
*/
public String toString() {
return result;
}
}
private boolean formatPrivate(Object[] values, ResultBuilder builder) {
if (values.length < placeholderCount) {
return false;
}
builder.setPlaceholderCount(placeholderCount);
if (placeholderIdsOrderedByOffset.length == 0) {
builder.setResult(patternWithoutPlaceholders);
return true;
}
StringBuilder result = new StringBuilder();
result.append(
patternWithoutPlaceholders,
0,
placeholderIdsOrderedByOffset[0]);
builder.setPlaceholderOffset(
placeholderIdsOrderedByOffset[1], result.length());
result.append(values[placeholderIdsOrderedByOffset[1]]);
for (int i = 2; i < placeholderIdsOrderedByOffset.length; i += 2) {
result.append(
patternWithoutPlaceholders,
placeholderIdsOrderedByOffset[i - 2],
placeholderIdsOrderedByOffset[i]);
builder.setPlaceholderOffset(
placeholderIdsOrderedByOffset[i + 1], result.length());
result.append(values[placeholderIdsOrderedByOffset[i + 1]]);
}
result.append(
patternWithoutPlaceholders,
placeholderIdsOrderedByOffset[placeholderIdsOrderedByOffset.length - 2],
patternWithoutPlaceholders.length());
builder.setResult(result.toString());
return true;
}
private static enum State {
INIT,
APOSTROPHE,
@ -316,55 +258,4 @@ public class SimplePatternFormatter {
return result;
}
}
private static interface ResultBuilder {
void setPlaceholderCount(int length);
void setPlaceholderOffset(int i, int length);
void setResult(String patternWithoutPlaceholders);
}
private static class StringResultBuilder implements ResultBuilder {
private String result;
public void setPlaceholderCount(int count) {
}
public void setPlaceholderOffset(int placeholderId, int offset) {
}
public void setResult(String result) {
this.result = result;
}
public String build() {
return result;
}
}
private static class FormattedResultBuilder implements ResultBuilder {
private int[] placeholderOffsets;
private String result;
public void setPlaceholderCount(int count) {
placeholderOffsets = new int[count];
for (int i = 0; i < count; i++) {
placeholderOffsets[i] = -1;
}
}
public void setPlaceholderOffset(int placeholderId, int offset) {
placeholderOffsets[placeholderId] = offset;
}
public void setResult(String result) {
this.result = result;
}
public Formatted build() {
return new Formatted(this.result, this.placeholderOffsets);
}
}
}

View File

@ -44,15 +44,15 @@ public class SimplePatternFormatterTest extends TestFmwk {
"toString",
"This doesn't have templates {0}",
fmt.toString());
SimplePatternFormatter.Formatted formatted = fmt.formatValues(new Object[] {});
int[] offsets = new int[1];
assertEquals(
"toString2",
"This doesn't have templates {0}",
formatted.toString());
fmt.format(new StringBuilder(), offsets).toString());
assertEquals(
"getOffset(0)",
"offsets[0]",
-1,
formatted.getOffset(0));
offsets[0]);
fmt = SimplePatternFormatter.compile("Some {} messed {12d up stuff.");
assertEquals(
"getPlaceholderCount",
@ -67,7 +67,7 @@ public class SimplePatternFormatterTest extends TestFmwk {
public void TestOnePlaceholder() {
assertEquals("TestOnePlaceholder",
"1 meter",
SimplePatternFormatter.compile("{0} meter").format(1));
SimplePatternFormatter.compile("{0} meter").format("1"));
}
public void TestWithPlaceholders() {
@ -78,38 +78,29 @@ public class SimplePatternFormatterTest extends TestFmwk {
5,
fmt.getPlaceholderCount());
try {
fmt.format("freddy", "tommy", "frog");
fmt.format("freddy", "tommy", "frog", "leg");
fail("Expected UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
// Expected
}
try {
fmt.formatValues(new String[] {"freddy", "tommy", "frog", "leg"});
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// Expected
}
String[] args = new String[] {"freddy", "tommy", "frog", "leg", "{0}"};
assertEquals(
"evaluate",
"Templates frogtommy and {0} are out of order.",
fmt.formatValues(args).toString());
assertEquals(
"toString",
"Templates {2}{1} and {4} are out of order.",
fmt.toString());
SimplePatternFormatter.Formatted formatted =
fmt.formatValues(args);
int[] offsets = {-1, 14, 10, -1, 24, -1};
int[] offsets = new int[6];
assertEquals(
"evaluate",
"123456: Templates frogtommy and {0} are out of order.",
fmt.format(
new StringBuilder("123456: "),
offsets,
"freddy", "tommy", "frog", "leg", "{0}").toString());
int[] expectedOffsets = {-1, 22, 18, -1, 32, -1};
for (int i = 0; i < offsets.length; i++) {
if (offsets[i] != formatted.getOffset(i)) {
if (offsets[i] != expectedOffsets[i]) {
fail("getOffset() returned wrong value for " + i);
}
}
assertEquals(
"toString2",
"Templates frogtommy and {0} are out of order.",
formatted.toString());
}
}