}
}
// Externally synchronized via the two calling methods having a mutex on flashInfoMap
private void doAnsiFlash(final int row, final Level level, final String message) {
Ansi ansi = ansi();
if (isAppleTerminal()) {
ansi.a(ESCAPE + "7");
}
else {
ansi.saveCursorPosition();
}
// Figure out the longest line we're presently displaying (or were) and erase the line from that position
int mostFurtherLeftColNumber = Integer.MAX_VALUE;
for (Integer candidate : rowErasureMap.values()) {
if (candidate < mostFurtherLeftColNumber) {
mostFurtherLeftColNumber = candidate;
}
}
if (mostFurtherLeftColNumber == Integer.MAX_VALUE) {
// There is nothing to erase
}
else {
ansi.cursor(row, mostFurtherLeftColNumber);
ansi.eraseLine(Erase.FORWARD); // Clear what was present on the line
}
if (("".equals(message))) {
// They want the line blank; we've already achieved this if needed via the erasing above
// Just need to record we no longer care about this line the next time doAnsiFlash is invoked
rowErasureMap.remove(row);
}
else {
if (shutdownHookFired) {
return; // ROO-1599
}
// They want some message displayed
int startFrom = reader.getTerminal().getWidth() - message.length() + 1;
if (startFrom < 1) {
startFrom = 1;
}
ansi.cursor(row, startFrom);
ansi.a(Attribute.NEGATIVE_ON).a(message).a(Attribute.NEGATIVE_OFF);
// Record we want to erase from this positioning next time (so we clean up after ourselves)
rowErasureMap.put(row, startFrom);
}
if (isAppleTerminal()) {
ansi.a(ESCAPE + "8");
}
else {
ansi.reset();
}
try {
reader.print(ansi.toString());
reader.flush();
}
catch (IOException ignored) {
}
}