messageformat.java
来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 850 行 · 第 1/3 页
JAVA
850 行
}
} else {
switch (ch) {
case ',':
if (part < 3)
part += 1;
else
segments[part].append(ch);
break;
case '{':
++braceStack;
segments[part].append(ch);
break;
case '}':
if (braceStack == 0) {
part = 0;
makeFormat(i, formatNumber, segments);
formatNumber++;
} else {
--braceStack;
segments[part].append(ch);
}
break;
case '\'':
inQuote = true;
// fall through, so we keep quotes in other parts
default:
segments[part].append(ch);
break;
}
}
}
pattern = segments[0].toString();
}
/**
* Gets the pattern. See the class description.
*/
public String toPattern() {
// later, make this more extensible
int lastOffset = 0;
StringBuffer result = new StringBuffer();
for (int i = 0; i <= maxOffset; ++i) {
copyAndFixQuotes(pattern, lastOffset, offsets[i],result);
lastOffset = offsets[i];
result.append('{');
result.append(argumentNumbers[i]);
if (formats[i] == null) {
// do nothing, string format
} else if (formats[i] instanceof DecimalFormat) {
if (formats[i].equals(NumberFormat.getInstance(locale))) {
result.append(",number");
} else if (formats[i].equals(
NumberFormat.getCurrencyInstance(locale))) {
result.append(",number,currency");
} else if (formats[i].equals(
NumberFormat.getPercentInstance(locale))) {
result.append(",number,percent");
} else if (formats[i].equals(getIntegerFormat(locale))) {
result.append(",number,integer");
} else {
result.append(",number," +
((DecimalFormat)formats[i]).toPattern());
}
} else if (formats[i] instanceof SimpleDateFormat) {
if (formats[i].equals(DateFormat.getDateInstance(
DateFormat.DEFAULT,locale))) {
result.append(",date");
} else if (formats[i].equals(DateFormat.getDateInstance(
DateFormat.SHORT,locale))) {
result.append(",date,short");
} else if (formats[i].equals(DateFormat.getDateInstance(
DateFormat.DEFAULT,locale))) {
result.append(",date,medium");
} else if (formats[i].equals(DateFormat.getDateInstance(
DateFormat.LONG,locale))) {
result.append(",date,long");
} else if (formats[i].equals(DateFormat.getDateInstance(
DateFormat.FULL,locale))) {
result.append(",date,full");
} else if (formats[i].equals(DateFormat.getTimeInstance(
DateFormat.DEFAULT,locale))) {
result.append(",time");
} else if (formats[i].equals(DateFormat.getTimeInstance(
DateFormat.SHORT,locale))) {
result.append(",time,short");
} else if (formats[i].equals(DateFormat.getTimeInstance(
DateFormat.DEFAULT,locale))) {
result.append(",time,medium");
} else if (formats[i].equals(DateFormat.getTimeInstance(
DateFormat.LONG,locale))) {
result.append(",time,long");
} else if (formats[i].equals(DateFormat.getTimeInstance(
DateFormat.FULL,locale))) {
result.append(",time,full");
} else {
result.append(",date,"
+ ((SimpleDateFormat)formats[i]).toPattern());
}
} else if (formats[i] instanceof ChoiceFormat) {
result.append(",choice,"
+ ((ChoiceFormat)formats[i]).toPattern());
} else {
//result.append(", unknown");
}
result.append('}');
}
copyAndFixQuotes(pattern, lastOffset, pattern.length(), result);
return result.toString();
}
/**
* Sets formats to use on parameters.
* See the class description about format numbering.
*/
public void setFormats(Format[] newFormats) {
try {
formats = (Format[]) newFormats.clone();
} catch (Exception e) {
return; // should never occur!
}
}
/**
* Sets formats individually to use on parameters.
* See the class description about format numbering.
*/
public void setFormat(int variable, Format newFormat) {
formats[variable] = newFormat;
}
/**
* Gets formats that were set with setFormats.
* See the class description about format numbering.
*/
public Format[] getFormats() {
try {
return (Format[]) formats.clone();
} catch (Exception e) {
return formats; // should never occur!
}
}
/**
* Returns pattern with formatted objects.
* @param source an array of objects to be formatted & substituted.
* @param result where text is appended.
* @param ignore no useful status is returned.
*/
public final StringBuffer format(Object[] source, StringBuffer result,
FieldPosition ignore)
{
return format(source,result,ignore, 0);
}
/**
* Convenience routine.
* Avoids explicit creation of MessageFormat,
* but doesn't allow future optimizations.
*/
public static String format(String pattern, Object[] arguments) {
MessageFormat temp = new MessageFormat(pattern);
return temp.format(arguments);
}
// Overrides
public final StringBuffer format(Object source, StringBuffer result,
FieldPosition ignore)
{
return format((Object[])source,result,ignore, 0);
}
/**
* Parses the string.
*
* <p>Caveats: The parse may fail in a number of circumstances.
* For example:
* <ul>
* <li>If one of the arguments does not occur in the pattern.
* <li>If the format of an argument is loses information, such as
* with a choice format where a large number formats to "many".
* <li>Does not yet handle recursion (where
* the substituted strings contain {n} references.)
* <li>Will not always find a match (or the correct match)
* if some part of the parse is ambiguous.
* For example, if the pattern "{1},{2}" is used with the
* string arguments {"a,b", "c"}, it will format as "a,b,c".
* When the result is parsed, it will return {"a", "b,c"}.
* <li>If a single argument is formatted twice in the string,
* then the later parse wins.
* </ul>
*/
public Object[] parse(String source, ParsePosition status) {
Object[] resultArray = new Object[10];
int patternOffset = 0;
int sourceOffset = status.index;
ParsePosition tempStatus = new ParsePosition(0);
for (int i = 0; i <= maxOffset; ++i) {
// match up to format
int len = offsets[i] - patternOffset;
if (len == 0 || pattern.regionMatches(patternOffset,
source, sourceOffset, len)) {
sourceOffset += len;
patternOffset += len;
} else {
return null; // leave index as is to signal error
}
// now use format
if (formats[i] == null) { // string format
// if at end, use longest possible match
// otherwise uses first match to intervening string
// does NOT recursively try all possibilities
int tempLength = (i != maxOffset) ? offsets[i+1] : pattern.length();
int next;
if (patternOffset >= tempLength) {
next = source.length();
}else{
next = source.indexOf( pattern.substring(patternOffset,tempLength), sourceOffset);
}
if (next < 0) {
return null; // leave index as is to signal error
} else {
resultArray[argumentNumbers[i]]
= source.substring(sourceOffset,next);
sourceOffset = next;
}
} else {
tempStatus.index = sourceOffset;
resultArray[argumentNumbers[i]]
= formats[i].parseObject(source,tempStatus);
if (tempStatus.index == sourceOffset) {
return null; // leave index as is to signal error
}
sourceOffset = tempStatus.index; // update
}
}
int len = pattern.length() - patternOffset;
if (len == 0 || pattern.regionMatches(patternOffset,
source, sourceOffset, len)) {
status.index = sourceOffset + len;
} else {
return null; // leave index as is to signal error
}
return resultArray;
}
/**
* Parses the string. Does not yet handle recursion (where
* the substituted strings contain {n} references.)
* @exception ParseException if the string can't be parsed.
*/
public Object[] parse(String source) throws ParseException {
ParsePosition status = new ParsePosition(0);
Object[] result = parse(source, status);
if (status.index == 0) // unchanged, returned object is null
throw new ParseException("MessageFormat parse error!", 0);
return result;
}
/**
* Parses the string. Does not yet handle recursion (where
* the substituted strings contain %n references.)
*/
public Object parseObject (String text, ParsePosition status) {
return parse(text, status);
}
/**
* Overrides Cloneable
*/
public Object clone()
{
MessageFormat other = (MessageFormat) super.clone();
// clone arrays. Can't do with utility because of bug in Cloneable
other.formats = (Format[]) formats.clone(); // shallow clone
for (int i = 0; i < formats.length; ++i) {
if (formats[i] != null)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?