Class MessagePattern
- java.lang.Object
-
- com.ibm.icu.text.MessagePattern
-
- All Implemented Interfaces:
Freezable<MessagePattern>,Cloneable
public final class MessagePattern extends Object implements Cloneable, Freezable<MessagePattern>
Parses and represents ICU MessageFormat patterns. Also handles patterns for ChoiceFormat, PluralFormat and SelectFormat. Used in the implementations of those classes as well as in tools for message validation, translation and format conversion.The parser handles all syntax relevant for identifying message arguments. This includes "complex" arguments whose style strings contain nested MessageFormat pattern substrings. For "simple" arguments (with no nested MessageFormat pattern substrings), the argument style is not parsed any further.
The parser handles named and numbered message arguments and allows both in one message.
Once a pattern has been parsed successfully, iterate through the parsed data with countParts(), getPart() and related methods.
The data logically represents a parse tree, but is stored and accessed as a list of "parts" for fast and simple parsing and to minimize object allocations. Arguments and nested messages are best handled via recursion. For every _START "part",
getLimitPartIndex(int)efficiently returns the index of the corresponding _LIMIT "part".List of "parts":
message = MSG_START (SKIP_SYNTAX | INSERT_CHAR | REPLACE_NUMBER | argument)* MSG_LIMIT argument = noneArg | simpleArg | complexArg complexArg = choiceArg | pluralArg | selectArg noneArg = ARG_START.NONE (ARG_NAME | ARG_NUMBER) ARG_LIMIT.NONE simpleArg = ARG_START.SIMPLE (ARG_NAME | ARG_NUMBER) ARG_TYPE [ARG_STYLE] ARG_LIMIT.SIMPLE choiceArg = ARG_START.CHOICE (ARG_NAME | ARG_NUMBER) choiceStyle ARG_LIMIT.CHOICE pluralArg = ARG_START.PLURAL (ARG_NAME | ARG_NUMBER) pluralStyle ARG_LIMIT.PLURAL selectArg = ARG_START.SELECT (ARG_NAME | ARG_NUMBER) selectStyle ARG_LIMIT.SELECT choiceStyle = ((ARG_INT | ARG_DOUBLE) ARG_SELECTOR message)+ pluralStyle = [ARG_INT | ARG_DOUBLE] (ARG_SELECTOR [ARG_INT | ARG_DOUBLE] message)+ selectStyle = (ARG_SELECTOR message)+
- Literal output text is not represented directly by "parts" but accessed between parts of a message, from one part's getLimit() to the next part's getIndex().
ARG_START.CHOICEstands for an ARG_START Part with ArgType CHOICE.- In the choiceStyle, the ARG_SELECTOR has the '<', the '#' or the less-than-or-equal-to sign (U+2264).
- In the pluralStyle, the first, optional numeric Part has the "offset:" value. The optional numeric Part between each (ARG_SELECTOR, message) pair is the value of an explicit-number selector like "=2", otherwise the selector is a non-numeric identifier.
- The REPLACE_NUMBER Part can occur only in an immediate sub-message of the pluralStyle.
This class is not intended for public subclassing.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classMessagePattern.ApostropheModeMode for when an apostrophe starts quoted literal text for MessageFormat output.static classMessagePattern.ArgTypeArgument type constants.static classMessagePattern.PartA message pattern "part", representing a pattern parsing event.
-
Field Summary
Fields Modifier and Type Field Description static intARG_NAME_NOT_NUMBERReturn value fromvalidateArgumentName(String)for when the string is a valid "pattern identifier" but not a number.static intARG_NAME_NOT_VALIDReturn value fromvalidateArgumentName(String)for when the string is invalid.static doubleNO_NUMERIC_VALUESpecial value that is returned by getNumericValue(Part) when no numeric value is defined for a part.
-
Constructor Summary
Constructors Constructor Description MessagePattern()Constructs an empty MessagePattern with default ApostropheMode.MessagePattern(MessagePattern.ApostropheMode mode)Constructs an empty MessagePattern.MessagePattern(String pattern)Constructs a MessagePattern with default ApostropheMode and parses the MessageFormat pattern string.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description StringautoQuoteApostropheDeep()Returns a version of the parsed pattern string where each ASCII apostrophe is doubled (escaped) if it is not already, and if it is not interpreted as quoting syntax.voidclear()Clears this MessagePattern.voidclearPatternAndSetApostropheMode(MessagePattern.ApostropheMode mode)Clears this MessagePattern and sets the ApostropheMode.Objectclone()Creates and returns a copy of this object.MessagePatterncloneAsThawed()Creates and returns an unfrozen copy of this object.intcountParts()Returns the number of "parts" created by parsing the pattern string.booleanequals(Object other)Compares this instance with the specified object and indicates if they are equal.MessagePatternfreeze()Freezes this object, making it immutable and thread-safe.MessagePattern.ApostropheModegetApostropheMode()intgetLimitPartIndex(int start)Returns the index of the ARG|MSG_LIMIT part corresponding to the ARG|MSG_START at start.doublegetNumericValue(MessagePattern.Part part)Returns the numeric value associated with an ARG_INT or ARG_DOUBLE.MessagePattern.PartgetPart(int i)Gets the i-th pattern "part".MessagePattern.Part.TypegetPartType(int i)Returns the Part.Type of the i-th pattern "part".intgetPatternIndex(int partIndex)Returns the pattern index of the specified pattern "part".StringgetPatternString()doublegetPluralOffset(int pluralStart)Returns the "offset:" value of a PluralFormat argument, or 0 if none is specified.StringgetSubstring(MessagePattern.Part part)Returns the substring of the pattern string indicated by the Part.inthashCode()Returns an integer hash code for this object.booleanhasNamedArguments()Does the parsed pattern have named arguments like {first_name}?booleanhasNumberedArguments()Does the parsed pattern have numbered arguments like {2}?booleanisFrozen()Determines whether this object is frozen (immutable) or not.MessagePatternparse(String pattern)Parses a MessageFormat pattern string.MessagePatternparseChoiceStyle(String pattern)Parses a ChoiceFormat pattern string.MessagePatternparsePluralStyle(String pattern)Parses a PluralFormat pattern string.MessagePatternparseSelectStyle(String pattern)Parses a SelectFormat pattern string.booleanpartSubstringMatches(MessagePattern.Part part, String s)Compares the part's substring with the input string s.StringtoString()Returns a string containing a concise, human-readable description of this object.static intvalidateArgumentName(String name)Validates and parses an argument name or argument number string.
-
-
-
Field Detail
-
ARG_NAME_NOT_NUMBER
public static final int ARG_NAME_NOT_NUMBER
Return value fromvalidateArgumentName(String)for when the string is a valid "pattern identifier" but not a number.- See Also:
- Constant Field Values
-
ARG_NAME_NOT_VALID
public static final int ARG_NAME_NOT_VALID
Return value fromvalidateArgumentName(String)for when the string is invalid. It might not be a valid "pattern identifier", or it have only ASCII digits but there is a leading zero or the number is too large.- See Also:
- Constant Field Values
-
NO_NUMERIC_VALUE
public static final double NO_NUMERIC_VALUE
Special value that is returned by getNumericValue(Part) when no numeric value is defined for a part.
-
-
Constructor Detail
-
MessagePattern
public MessagePattern()
Constructs an empty MessagePattern with default ApostropheMode.
-
MessagePattern
public MessagePattern(MessagePattern.ApostropheMode mode)
Constructs an empty MessagePattern.- Parameters:
mode- Explicit ApostropheMode.
-
MessagePattern
public MessagePattern(String pattern)
Constructs a MessagePattern with default ApostropheMode and parses the MessageFormat pattern string.- Parameters:
pattern- a MessageFormat pattern string- Throws:
IllegalArgumentException- for syntax errors in the pattern stringIndexOutOfBoundsException- if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)NumberFormatException- if a number could not be parsed
-
-
Method Detail
-
parse
public MessagePattern parse(String pattern)
Parses a MessageFormat pattern string.- Parameters:
pattern- a MessageFormat pattern string- Returns:
- this
- Throws:
IllegalArgumentException- for syntax errors in the pattern stringIndexOutOfBoundsException- if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)NumberFormatException- if a number could not be parsed
-
parseChoiceStyle
public MessagePattern parseChoiceStyle(String pattern)
Parses a ChoiceFormat pattern string.- Parameters:
pattern- a ChoiceFormat pattern string- Returns:
- this
- Throws:
IllegalArgumentException- for syntax errors in the pattern stringIndexOutOfBoundsException- if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)NumberFormatException- if a number could not be parsed
-
parsePluralStyle
public MessagePattern parsePluralStyle(String pattern)
Parses a PluralFormat pattern string.- Parameters:
pattern- a PluralFormat pattern string- Returns:
- this
- Throws:
IllegalArgumentException- for syntax errors in the pattern stringIndexOutOfBoundsException- if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)NumberFormatException- if a number could not be parsed
-
parseSelectStyle
public MessagePattern parseSelectStyle(String pattern)
Parses a SelectFormat pattern string.- Parameters:
pattern- a SelectFormat pattern string- Returns:
- this
- Throws:
IllegalArgumentException- for syntax errors in the pattern stringIndexOutOfBoundsException- if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)NumberFormatException- if a number could not be parsed
-
clear
public void clear()
Clears this MessagePattern. countParts() will return 0.
-
clearPatternAndSetApostropheMode
public void clearPatternAndSetApostropheMode(MessagePattern.ApostropheMode mode)
Clears this MessagePattern and sets the ApostropheMode. countParts() will return 0.- Parameters:
mode- The new ApostropheMode.
-
equals
public boolean equals(Object other)
Description copied from class:ObjectCompares this instance with the specified object and indicates if they are equal. In order to be equal,omust represent the same object as this instance using a class-specific comparison. The general contract is that this comparison should be reflexive, symmetric, and transitive. Also, no object reference other than null is equal to null.The default implementation returns
trueonly ifthis == o. See Writing a correctequalsmethod if you intend implementing your ownequalsmethod.The general contract for the
equalsandObject.hashCode()methods is that ifequalsreturnstruefor any two objects, thenhashCode()must return the same value for these objects. This means that subclasses ofObjectusually override either both methods or neither of them.- Overrides:
equalsin classObject- Parameters:
other- another object to compare with.- Returns:
- true if this object is equivalent to the other one.
- See Also:
Object.hashCode()
-
hashCode
public int hashCode()
Returns an integer hash code for this object. By contract, any two objects for whichObject.equals(java.lang.Object)returnstruemust return the same hash code value. This means that subclasses ofObjectusually override both methods or neither method.Note that hash values must not change over time unless information used in equals comparisons also changes.
See Writing a correct
hashCodemethod if you intend implementing your ownhashCodemethod.- Overrides:
hashCodein classObject- Returns:
- this object's hash code.
- See Also:
Object.equals(java.lang.Object)
-
getApostropheMode
public MessagePattern.ApostropheMode getApostropheMode()
- Returns:
- this instance's ApostropheMode.
-
getPatternString
public String getPatternString()
- Returns:
- the parsed pattern string (null if none was parsed).
-
hasNamedArguments
public boolean hasNamedArguments()
Does the parsed pattern have named arguments like {first_name}?- Returns:
- true if the parsed pattern has at least one named argument.
-
hasNumberedArguments
public boolean hasNumberedArguments()
Does the parsed pattern have numbered arguments like {2}?- Returns:
- true if the parsed pattern has at least one numbered argument.
-
toString
public String toString()
Returns a string containing a concise, human-readable description of this object. Subclasses are encouraged to override this method and provide an implementation that takes into account the object's type and data. The default implementation is equivalent to the following expression:getClass().getName() + '@' + Integer.toHexString(hashCode())
See Writing a useful
toStringmethod if you intend implementing your owntoStringmethod.
-
validateArgumentName
public static int validateArgumentName(String name)
Validates and parses an argument name or argument number string. An argument name must be a "pattern identifier", that is, it must contain no Unicode Pattern_Syntax or Pattern_White_Space characters. If it only contains ASCII digits, then it must be a small integer with no leading zero.- Parameters:
name- Input string.- Returns:
- >=0 if the name is a valid number, ARG_NAME_NOT_NUMBER (-1) if it is a "pattern identifier" but not all ASCII digits, ARG_NAME_NOT_VALID (-2) if it is neither.
-
autoQuoteApostropheDeep
public String autoQuoteApostropheDeep()
Returns a version of the parsed pattern string where each ASCII apostrophe is doubled (escaped) if it is not already, and if it is not interpreted as quoting syntax.For example, this turns "I don't '{know}' {gender,select,female{h''er}other{h'im}}." into "I don''t '{know}' {gender,select,female{h''er}other{h''im}}."
- Returns:
- the deep-auto-quoted version of the parsed pattern string.
- See Also:
MessageFormat.autoQuoteApostrophe(String)
-
countParts
public int countParts()
Returns the number of "parts" created by parsing the pattern string. Returns 0 if no pattern has been parsed or clear() was called.- Returns:
- the number of pattern parts.
-
getPart
public MessagePattern.Part getPart(int i)
Gets the i-th pattern "part".- Parameters:
i- The index of the Part data. (0..countParts()-1)- Returns:
- the i-th pattern "part".
- Throws:
IndexOutOfBoundsException- if i is outside the (0..countParts()-1) range
-
getPartType
public MessagePattern.Part.Type getPartType(int i)
Returns the Part.Type of the i-th pattern "part". Convenience method for getPart(i).getType().- Parameters:
i- The index of the Part data. (0..countParts()-1)- Returns:
- The Part.Type of the i-th Part.
- Throws:
IndexOutOfBoundsException- if i is outside the (0..countParts()-1) range
-
getPatternIndex
public int getPatternIndex(int partIndex)
Returns the pattern index of the specified pattern "part". Convenience method for getPart(partIndex).getIndex().- Parameters:
partIndex- The index of the Part data. (0..countParts()-1)- Returns:
- The pattern index of this Part.
- Throws:
IndexOutOfBoundsException- if partIndex is outside the (0..countParts()-1) range
-
getSubstring
public String getSubstring(MessagePattern.Part part)
Returns the substring of the pattern string indicated by the Part. Convenience method for getPatternString().substring(part.getIndex(), part.getLimit()).- Parameters:
part- a part of this MessagePattern.- Returns:
- the substring associated with part.
-
partSubstringMatches
public boolean partSubstringMatches(MessagePattern.Part part, String s)
Compares the part's substring with the input string s.- Parameters:
part- a part of this MessagePattern.s- a string.- Returns:
- true if getSubstring(part).equals(s).
-
getNumericValue
public double getNumericValue(MessagePattern.Part part)
Returns the numeric value associated with an ARG_INT or ARG_DOUBLE.- Parameters:
part- a part of this MessagePattern.- Returns:
- the part's numeric value, or NO_NUMERIC_VALUE if this is not a numeric part.
-
getPluralOffset
public double getPluralOffset(int pluralStart)
Returns the "offset:" value of a PluralFormat argument, or 0 if none is specified.- Parameters:
pluralStart- the index of the first PluralFormat argument style part. (0..countParts()-1)- Returns:
- the "offset:" value.
- Throws:
IndexOutOfBoundsException- if pluralStart is outside the (0..countParts()-1) range
-
getLimitPartIndex
public int getLimitPartIndex(int start)
Returns the index of the ARG|MSG_LIMIT part corresponding to the ARG|MSG_START at start.- Parameters:
start- The index of some Part data (0..countParts()-1); this Part should be of Type ARG_START or MSG_START.- Returns:
- The first i>start where getPart(i).getType()==ARG|MSG_LIMIT at the same nesting level, or start itself if getPartType(msgStart)!=ARG|MSG_START.
- Throws:
IndexOutOfBoundsException- if start is outside the (0..countParts()-1) range
-
clone
public Object clone()
Creates and returns a copy of this object.
-
cloneAsThawed
public MessagePattern cloneAsThawed()
Creates and returns an unfrozen copy of this object.- Specified by:
cloneAsThawedin interfaceFreezable<MessagePattern>- Returns:
- a copy of this object.
-
freeze
public MessagePattern freeze()
Freezes this object, making it immutable and thread-safe.- Specified by:
freezein interfaceFreezable<MessagePattern>- Returns:
- this
-
isFrozen
public boolean isFrozen()
Determines whether this object is frozen (immutable) or not.- Specified by:
isFrozenin interfaceFreezable<MessagePattern>- Returns:
- true if this object is frozen.
-
-