Class MessageText
Use it for text the engine shows as it came: a message a language logs itself, the message of an exception its own
library sees first, and the issues it throws in an
InvalidExpressionException, which the engine copies untouched into
the RuleCompilationException it reports. Use quote(java.lang.String) for a
name and escape(truncate(text)) for other text. To end such text with a note of the language's own, such as
" (caused by ...)", cut it with escapeWithin(String, int),
escapeWithin(String, int, int) or quoteWithin(String, int), giving it the room the rest of the
message leaves: the escaped result, its ... (N more characters) included, fits in that room, so the note
stays whole. To end text it shortened its own way with the engine's note, use leftOut(int).
The engine shortens to 1,000 characters and escapes the message of an
InvalidExpressionException, the message of a warning's issue when
it logs it, and the message of an exception from ExpressionCompiler.checkFactName(java.lang.String) when it logs it or, at
load(), reports it for a declared fact. Leave a message the engine shortens raw: the engine escapes it
itself, and the count of what was left out of escaped text counts escaped characters. Every cut the engine and
this class make, but truncate(java.lang.String)'s, falls between code points and never inside an escape the engine writes or
inside raw text that reads as one (a backslash and n, r or t, or a backslash, u and
four lowercase hex digits): such text is left out whole, so up to 5 fewer characters show. A language may instead
escape such a message itself, when the escaped message fits in 1,000 characters, as
escapeWithin(text, MAX_TEXT_LENGTH) makes it; the engine then never shortens it.
The escapes, the note ... (N more characters) and the limits, MAX_NAME_LENGTH (200 characters,
UTF-16 units) for a name and MAX_TEXT_LENGTH (1,000) for other text, are fixed for 2.x. javac inlines the
two constants into the classes that read them. Which characters above U+00FF are escaped follows Unicode 15.0 to
17.0, as JDK 21 to 26 have it, from a table of the engine's own, whatever the running JDK's Unicode version, so a
later JDK escapes the same characters until a later 2.x release updates the table; below U+0100 the running JDK
decides, the same way on JDK 21 to 26. A later 2.x release may also escape more kinds of character.
On Linux and macOS, with no engine built, the JVM's first read of a character of a string holding one above U+00FF,
such as "π", initializes the JDK's java.lang.StringUTF16, and a first read deep in a stack
can break that class for the life of the JVM (#1295). So make a first escape of such text near the top of a stack, or
after an engine is built: the first build initializes the class.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe most characters (UTF-16 units) of a namequote(java.lang.String)shows: 200, fixed for 2.x.static final intThe most characters (UTF-16 units) of other texttruncate(java.lang.String)keeps, and the length above which the engine shortens the messages the class description lists: 1,000, fixed for 2.x. -
Method Summary
Modifier and TypeMethodDescriptionstatic StringEscapes text for a message, without shortening it.static StringescapeWithin(String text, int room) Escapes text for a message asescape(java.lang.String)does, shortened first if its escaped form is longer thanroomcharacters: to as many of its first characters as fit inroomwith... (N more characters)after them, astruncate(java.lang.String)writes it.static StringescapeWithin(String text, int most, int room) Escapes text within a room asescapeWithin(String, int)does, showing at most its firstmostcharacters (UTF-16 units).static StringleftOut(int count) Writes the note that follows shortened text, astruncate(java.lang.String),quote(java.lang.String)and the engine's own messages write it:... (N more characters), N being how many characters of the text were left out.static StringShortens a name for a message to at most 200 characters (MAX_NAME_LENGTH, UTF-16 units), thenescapesit.static StringquoteWithin(String name, int room) Quotes a name for a message asquote(java.lang.String)does, or, if that is longer thanroomcharacters, escapes it within the room asescapeWithin(String, int)does.static StringShortens text for a message to at most 1,000 characters (UTF-16 units), without escaping it.
-
Field Details
-
MAX_NAME_LENGTH
public static final int MAX_NAME_LENGTHThe most characters (UTF-16 units) of a namequote(java.lang.String)shows: 200, fixed for 2.x. javac inlines it into the classes that read it.- See Also:
-
MAX_TEXT_LENGTH
public static final int MAX_TEXT_LENGTHThe most characters (UTF-16 units) of other texttruncate(java.lang.String)keeps, and the length above which the engine shortens the messages the class description lists: 1,000, fixed for 2.x. javac inlines it into the classes that read it.- See Also:
-
-
Method Details
-
leftOut
Writes the note that follows shortened text, astruncate(java.lang.String),quote(java.lang.String)and the engine's own messages write it:... (N more characters), N being how many characters of the text were left out. For a language that shortens text its own way, such as to the room a message leaves after it, and ends it with the engine's note. The count is written as given, whatever it is. It allocates the note.- Parameters:
count- How many characters were left out- Returns:
... (+count+more characters)
-
escape
Escapes text for a message, without shortening it.\n,\rand\tbecome those two-character escapes. Every other ISO control character, line or paragraph separator, space separator (category Zs) other than U+0020, format character (category Cf), otherDefault_Ignorable_Code_Pointcharacter and lone surrogate becomes a backslash,uand four lowercase hex digits, one for each UTF-16 unit, so an escaped character outside the Basic Multilingual Plane becomes two escapes, and each escaped unit shows as 2 or 6 characters. Everything else is kept, a valid surrogate pair such as an emoji included. A backslash isn't escaped, so escaping text twice gives the same text.Space separators and format characters above U+00FF are those of Unicode 15.0 to 17.0, as JDK 21 to 26 have them, from a table of the engine's own rather than from the running JDK's
Character.getType(int), which above U+00FF reads a table the JVM builds on its first use (#1286); below U+0100 the running JDK decides, the same way on JDK 21 to 26. The space separators are U+00A0, U+1680, U+2000 to U+200A, U+202F, U+205F and U+3000 besides U+0020. The other default-ignorable characters are U+034F, U+115F to U+1160, U+17B4 to U+17B5, U+180B to U+180F, U+2065, U+3164, U+FE00 to U+FE0F, U+FFA0, U+FFF0 to U+FFF8 and U+E0000 to U+E0FFF.To put long text in a message, shorten it first and escape it after,
escape(truncate(text)), so a cut never falls inside an escape this writes. The result can be up to six times longer than the 1,000 characters kept, since a character escapes to at most 6, so use it only for text the engine won't shorten again. Leave a message the engine shortens raw: the engine escapes it itself (see the class description). To fit escaped text into a room, useescapeWithin(String, int).- Parameters:
text- The text- Returns:
- The text, escaped
- Throws:
NullPointerException- iftextisnull
-
truncate
Shortens text for a message to at most 1,000 characters (UTF-16 units), without escaping it. Text of at most 1,000 characters is returned as it is. Longer text keeps its first 1,000 characters, or 999 when the 1,000th is a high surrogate, so the text never ends in half a character, followed by... (N more characters), where N counts the text's own characters left out. 1,000 is also the length above which the engine shortens the messages the class description lists, such as that of anInvalidExpressionException.Shorten first and escape after,
escape(truncate(text)), so a cut never falls inside an escape and N counts the original text. Don't shorten text that is already escaped.- Parameters:
text- The text, not escaped- Returns:
- The text, shortened if it was longer
- Throws:
NullPointerException- iftextisnull
-
quote
Shortens a name for a message to at most 200 characters (MAX_NAME_LENGTH, UTF-16 units), thenescapesit. The cut falls between code points and before raw text that reads as an escape, which is left out whole, so up to 5 fewer characters show;... (N more characters)follows, astruncate(java.lang.String)writes it, N counting the name's own characters left out. It adds no quotes: write them around it, as in"fact '" + MessageText.quote(name) + "'".- Parameters:
name- The name, such as a fact's, an option's or a class's- Returns:
- The name, shortened if it was longer, then escaped
- Throws:
NullPointerException- ifnameisnull
-
escapeWithin
Escapes text for a message asescape(java.lang.String)does, shortened first if its escaped form is longer thanroomcharacters: to as many of its first characters as fit inroomwith... (N more characters)after them, astruncate(java.lang.String)writes it. Use it to keep what a message says after the text, such as a closing note, whole: give it the room the rest of the message leaves.N counts the text's own characters left out, as given, not escaped ones. The cut falls between code points, so never inside a surrogate pair or an escape this writes, and never inside an escape the text already holds, or inside raw text that reads as one (
\n,\r,\t, or a backslash,uand four lowercase hex digits): such text is left out whole.escape(java.lang.String)leaves an escape the text holds as it is, so a cut inside one would show it cut in half.The result is at most
roomcharacters, unlessroomis too small for the note alone: then the result is the note alone, and nothing is thrown. A negative room is taken as 0. Empty text is returned empty, whatever the room.- Parameters:
text- The text, raw, or with escapes the engine already wroteroom- The most characters the escaped text may take, the note included- Returns:
- The text, shortened if it didn't fit, then escaped
- Throws:
NullPointerException- iftextisnull
-
escapeWithin
Escapes text within a room asescapeWithin(String, int)does, showing at most its firstmostcharacters (UTF-16 units). Wheremostfalls inside a surrogate pair, or inside an escape the text holds or raw text that reads as one, that is left out whole, asquote(java.lang.String)leaves it out at 200, so up to 5 fewer characters show. Amostof 0 or less shows none of a non-empty text, only the note. With aroomofInteger.MAX_VALUE, the text is shortened tomostcharacters alone.- Parameters:
text- The text, raw, or with escapes the engine already wrotemost- The most of its characters to showroom- The most characters the escaped text may take, the note included- Returns:
- The text, shortened if it didn't fit or is longer than
most, then escaped - Throws:
NullPointerException- iftextisnull
-
quoteWithin
Quotes a name for a message asquote(java.lang.String)does, or, if that is longer thanroomcharacters, escapes it within the room asescapeWithin(String, int)does. Either way it shows no more of the name thanquote(java.lang.String)does. An empty name is quoted as empty, whatever the room. It adds no quotes.- Parameters:
name- The name, such as a fact's, an option's or a class'sroom- The most characters the quoted name may take, the note included- Returns:
- The name, shortened if it was longer or didn't fit, then escaped
- Throws:
NullPointerException- ifnameisnull
-