// Externally synchronized via the two calling methods having a mutex on
// flashInfoMap
private void doAnsiFlash(final int row, final Level level,
final String message) {
final ANSIBuffer buff = JLineLogHandler.getANSIBuffer();
if (APPLE_TERMINAL) {
buff.append(ESCAPE + "7");
}
else {
buff.append(ANSICodes.save());
}
// Figure out the longest line we're presently displaying (or were) and
// erase the line from that position
int mostFurtherLeftColNumber = Integer.MAX_VALUE;
for (final Integer candidate : rowErasureMap.values()) {
if (candidate < mostFurtherLeftColNumber) {
mostFurtherLeftColNumber = candidate;
}
}
if (mostFurtherLeftColNumber == Integer.MAX_VALUE) {
// There is nothing to erase
}
else {
buff.append(ANSICodes.gotoxy(row, mostFurtherLeftColNumber));
// Clear what was present on the line
buff.append(ANSICodes.clreol());
}
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.getTermwidth() - message.length() + 1;
if (startFrom < 1) {
startFrom = 1;
}
buff.append(ANSICodes.gotoxy(row, startFrom));
buff.reverse(message);
// Record we want to erase from this positioning next time (so we
// clean up after ourselves)
rowErasureMap.put(row, startFrom);
}
if (APPLE_TERMINAL) {
buff.append(ESCAPE + "8");
}
else {
buff.append(ANSICodes.restore());
}
final String stg = buff.toString();
try {
reader.printString(stg);
reader.flushConsole();
}
catch (final IOException ignored) {