--- old/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/MessageOutput.java 2018-10-16 20:53:02.000000000 -0700 +++ new/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/MessageOutput.java 2018-10-16 20:53:02.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package com.sun.tools.example.debug.tty; +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; import java.util.*; import java.text.MessageFormat; /** @@ -52,6 +54,12 @@ */ static ResourceBundle textResources; + /** If set then used to buffer the output before writing it to System.out */ + private final static ThreadLocal bufferedOutput = new ThreadLocal<>(); + + /** Default writer to System.out */ + private final static PrintWriter systemOutWriter = new PrintWriter(System.out, true); + /** Our message formatter. Allocated once, used many times */ private static MessageFormat messageFormat; @@ -105,13 +113,13 @@ * method. */ static void printDirectln(String line) { - System.out.println(line); + getWriter().println(line); } static void printDirect(String line) { - System.out.print(line); + getWriter().print(line); } static void printDirect(char c) { - System.out.print(c); + getWriter().print(c); } /** @@ -119,20 +127,20 @@ * Use this instead of '\n' */ static void println() { - System.out.println(); + getWriter().println(); } /** * Format and print a simple string. */ static void print(String key) { - System.out.print(format(key)); + getWriter().print(format(key)); } /** * Format and print a simple string. */ static void println(String key) { - System.out.println(format(key)); + getWriter().println(format(key)); } @@ -141,10 +149,10 @@ * This is the most common usage. */ static void print(String key, String argument) { - System.out.print(format(key, argument)); + getWriter().print(format(key, argument)); } static void println(String key, String argument) { - System.out.println(format(key, argument)); + getWriter().println(format(key, argument)); } /** @@ -152,25 +160,25 @@ * number of message arguments. */ static void println(String key, Object [] arguments) { - System.out.println(format(key, arguments)); + getWriter().println(format(key, arguments)); } /** * Print a newline, followed by the string. */ static void lnprint(String key) { - System.out.println(); - System.out.print(textResources.getString(key)); + getWriter().println(); + getWriter().print(textResources.getString(key)); } static void lnprint(String key, String argument) { - System.out.println(); - System.out.print(format(key, argument)); + getWriter().println(); + getWriter().print(format(key, argument)); } static void lnprint(String key, Object [] arguments) { - System.out.println(); - System.out.print(format(key, arguments)); + getWriter().println(); + getWriter().print(format(key, arguments)); } /** @@ -184,8 +192,8 @@ printDirectln(key); } } - System.out.flush(); - e.printStackTrace(); + getWriter().flush(); + e.printStackTrace(getWriter()); } static void printPrompt() { @@ -195,15 +203,65 @@ static void printPrompt(boolean simple) { ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); if (simple || threadInfo == null) { - System.out.print + getWriter().print (MessageOutput.format("jdb prompt with no current thread")); } else { - System.out.print + getWriter().print (MessageOutput.format("jdb prompt thread name and current stack frame", new Object [] { threadInfo.getThread().name(), Integer.valueOf(threadInfo.getCurrentFrameIndex() + 1)})); } - System.out.flush(); + getWriter().flush(); + } + + /** Starts buffering the output to the internal buffer */ + static void startBuffering() { + assert (bufferedOutput.get() == null); + bufferedOutput.set(new BufferedOutput()); + } + + /** Stops buffering the output and writes the buffer to System.out */ + static void stopBuffering() { + BufferedOutput bo = bufferedOutput.get(); + assert (bo != null); + bufferedOutput.set(null); + bo.close(); + systemOutWriter.print(bo.toString()); + systemOutWriter.flush(); + } + + /** + * If bufferedOutput is set returns the writer the writes to the internal buffer, otherwise + * returns writer that writes to System.out + */ + private static PrintWriter getWriter() { + return bufferedOutput.get() != null? bufferedOutput.get().getPrintWriter() : systemOutWriter; + } + + /** Provides a writer that buffers the output to the string */ + private static class BufferedOutput { + private final ByteArrayOutputStream baos; + private final PrintWriter pw; + + BufferedOutput() { + baos = new ByteArrayOutputStream(); + pw = new PrintWriter(baos); + } + + PrintWriter getPrintWriter() { + return pw; + } + + void close() { + pw.flush(); + pw.close(); + } + + @Override + public String toString() { + return baos.toString(); + } + } }