All Downloads are FREE. Search and download functionalities are using the official Maven repository.

name.didier.david.test4j.utils.StdCaptor Maven / Gradle / Ivy

The newest version!
package name.didier.david.test4j.utils;

import static name.didier.david.check4j.ConciseCheckers.checkStrictlyPositive;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

/**
 * Capture the standard output stream and the standard error stream. Usage:
 * 
 * 
 * StdCaptor captor = new StdCaptor();
 * try {
 *     captor.startStdOutCapture();
 *     captor.startStdErrCapture();
 *     outputSomething();
 * } catch (Exception e) {
 *     propagate(e);
 * } finally {
 *     String stdOutCapture = captor.stopStdOutCapture(printStdOut);
 *     String stdErrCapture = captor.stopStdErrCapture(printStdErr);
 *     doSomething(stdOutCapture, stdErrCapture);
 * }
 * 
* * @author ddidier */ public class StdCaptor { /** The default size of the capturing buffers. */ private static final int DEFAULT_BUFFER_SIZE = 1024; /** The size of the capturing buffers. */ private final Integer bufferSize; /** The backup STDOUT. */ private PrintStream oldStdOut; /** The capturing STDOUT. */ private ByteArrayOutputStream newStdOut; /** The backup STDERR. */ private PrintStream oldStdErr; /** The capturing STDERR. */ private ByteArrayOutputStream newStdErr; /** Default constructor. */ public StdCaptor() { this(DEFAULT_BUFFER_SIZE); } /** * Default constructor. * * @param bufferSize the size of the capturing buffers. */ public StdCaptor(final int bufferSize) { super(); this.bufferSize = checkStrictlyPositive(bufferSize, "bufferSize"); } /** * Start to capture the standard output. The standard output stream is reassigned so do not forget to restore the * previous state with {@link #stopStdOutCapture()}. Use a {@code finally} block! * * @throws IllegalStateException if already capturing STDOUT. */ public void startStdOutCapture() { if (isCapturingStdOut()) { throw new IllegalStateException("Already capturing STDOUT"); } oldStdOut = System.out; newStdOut = new ByteArrayOutputStream(bufferSize); System.setOut(newPrintStream(newStdOut)); } /** * Stop to capture the standard output. The previous output stream is restored. Should be used in a {@code finally} * block! * * @return the captured data. * @throws IllegalStateException if not capturing STDOUT. */ public String stopStdOutCapture() { return stopStdOutCapture(false); } /** * Stop to capture the standard output then print the capture data to STDOUT. The previous output stream is * restored. Should be used in a {@code finally} block! * * @param print true to print the capture data to STDOUT, false otherwise. * @return the captured data. * @throws IllegalStateException if not capturing STDOUT. */ public String stopStdOutCapture(final boolean print) { if (!isCapturingStdOut()) { throw new IllegalStateException("Not capturing STDOUT"); } System.out.flush(); System.setOut(oldStdOut); String capture = toString(newStdOut); resetStdOut(); if (print) { // CSOFF: RegexpCheck +1 System.out.print(capture); } return capture; } /** * @return true if capturing the standard stream, false otherwise. */ public boolean isCapturingStdOut() { return newStdOut != null; } // ----------------------------------------------------------------------------------------------------------------- /** * Start to capture the standard error. The standard error stream is reassigned so do not forget to restore the * previous state with {@link #stopStdErrCapture()}. Use a {@code finally} block! * * @throws IllegalStateException if already capturing STDERR. */ public void startStdErrCapture() { if (isCapturingStdErr()) { throw new IllegalStateException("Already capturing STDERR"); } oldStdErr = System.err; newStdErr = new ByteArrayOutputStream(bufferSize); System.setErr(newPrintStream(newStdErr)); } /** * Stop to capture the standard error. The previous error stream is restored. Should be used in a {@code finally} * block! * * @return the captured data. * @throws IllegalStateException if not capturing STDERR. */ public String stopStdErrCapture() { return stopStdErrCapture(false); } /** * Stop to capture the standard error then print the capture data to STDERR. The previous error stream is restored. * Should be used in a {@code finally} block! * * @param print true to print the capture data to STDERR, false otherwise. * @return the captured data. * @throws IllegalStateException if not capturing STDERR. */ public String stopStdErrCapture(final boolean print) { if (!isCapturingStdErr()) { throw new IllegalStateException("Not capturing STDERR"); } System.err.flush(); System.setErr(oldStdErr); String capture = toString(newStdErr); resetStdErr(); if (print) { // CSOFF: RegexpCheck +1 System.err.print(capture); } return capture; } /** * @return true if capturing the error stream, false otherwise. */ public boolean isCapturingStdErr() { return newStdErr != null; } // ----------------------------------------------------------------------------------------------------------------- /** * Reset the capturing state of STDOUT. */ private void resetStdOut() { oldStdOut = null; newStdOut = null; } /** * Reset the capturing state of STDERR. */ private void resetStdErr() { oldStdErr = null; newStdErr = null; } /** * @param out the output stream to which values and objects will be printed. * @return a new {@link PrintStream} with UTF-8 encoding. */ private PrintStream newPrintStream(final OutputStream out) { try { return new PrintStream(out, false, StandardCharsets.UTF_8.name()); } catch (UnsupportedEncodingException e) { // should never happen throw new RuntimeException("Error while creating stream", e); } } /** * @param baos the stream to decode. * @return the content of the stream. */ private String toString(final ByteArrayOutputStream baos) { try { return baos.toString(StandardCharsets.UTF_8.name()); } catch (UnsupportedEncodingException e) { // should never happen throw new RuntimeException("Error while printing stream", e); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy