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

com.oracle.bedrock.runtime.console.CapturingApplicationConsole Maven / Gradle / Ivy

Go to download

Interfaces, classes and resources to construct, inspect and manage runtime processes.

There is a newer version: 7.0.3
Show newest version
/*
 * File: CapturingApplicationConsole.java
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * The contents of this file are subject to the terms and conditions of 
 * the Common Development and Distribution License 1.0 (the "License").
 *
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the License by consulting the LICENSE.txt file
 * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL
 *
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file LICENSE.txt.
 *
 * MODIFICATIONS:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 */

package com.oracle.bedrock.runtime.console;

import com.oracle.bedrock.runtime.ApplicationConsole;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * An implementation of an {@link ApplicationConsole} that
 * captures and keeps the last n lines of output on StdOut and StdErr. This
 * console also allows StdIn to be piped to the application.
 * The number of lines to capture and keep is configurable by a constructor argument.
 * 

* Copyright (c) 2014. All Rights Reserved. Oracle Corporation.
* Oracle is a registered trademark of Oracle Corporation and/or its affiliates. * * @author Jonathan Knight */ public class CapturingApplicationConsole extends AbstractPipedApplicationConsole { /** * The maximum number of lines of output that will be captured and stored * by this {link CapturingApplicationConsole}. */ private int maximumLines; /** * The lines of output captured from StdOut */ private ConcurrentLinkedQueue stdoutBuffer; /** * The lines of output captured from StdErr */ private ConcurrentLinkedQueue stderrBuffer; /** * The {@link Thread} capturing StdOut lines */ protected Thread stdoutThread; /** * The {@link Thread} capturing StdErr lines */ protected Thread stderrThread; /** * Constructs {@link CapturingApplicationConsole}. *

* This constructor will set the maximum number of lines to capture to {@link Integer#MAX_VALUE}. */ public CapturingApplicationConsole() { this(Integer.MAX_VALUE, false, DEFAULT_PIPE_SIZE); } /** * Constructs {@link CapturingApplicationConsole}. * * @param maximumLines the number of lines of output to capture */ public CapturingApplicationConsole(int maximumLines) { this(maximumLines, false, DEFAULT_PIPE_SIZE); } /** * Constructs {@link CapturingApplicationConsole}. * * @param maximumLines the number of lines of output to keep * @param diagnosticMode if true, output to this console is not formatted * with application details or line numbers */ public CapturingApplicationConsole(int maximumLines, boolean diagnosticMode) { this(maximumLines, diagnosticMode, DEFAULT_PIPE_SIZE); } /** * Constructs {@link CapturingApplicationConsole}. * * @param maximumLines the number of lines of output to keep * @param diagnosticMode if true, output to this console is not formatted * with application details or line numbers * @param pipeSize the size of the pipe's buffers */ public CapturingApplicationConsole(int maximumLines, boolean diagnosticMode, int pipeSize) { super(pipeSize, diagnosticMode); this.maximumLines = maximumLines; this.stdoutBuffer = new ConcurrentLinkedQueue<>(); this.stderrBuffer = new ConcurrentLinkedQueue<>(); this.stdoutThread = new Thread(new OutputCaptor(stdoutReader, stdoutBuffer)); this.stderrThread = new Thread(new OutputCaptor(stderrReader, stderrBuffer)); this.stdoutThread.start(); this.stderrThread.start(); } @Override public void close() { super.close(); try { stdoutThread.join(); stderrThread.join(); } catch (InterruptedException e) { // Ignored } } /** * Obtain a {@link LinkedList} containing the lines captured * from the applications StdOut. The most recent line will * be at the tail of the list and the oldest line will be * at the head of the list. * * @return a {@link LinkedList} containing the lines captured * from the applications StdOut */ public Queue getCapturedOutputLines() { return stdoutBuffer; } /** * Obtain a {@link LinkedList} containing the lines captured * from the applications StdErr. The most recent line will * be at the tail of the list and the oldest line will be * at the head of the list. * * @return a {@link LinkedList} containing the lines captured * from the applications StdErr */ public Queue getCapturedErrorLines() { return stderrBuffer; } /** * Obtains a {@link PrintWriter} that can be used to write to the stdin * of an {@link ApplicationConsole}. * * @return a {@link PrintWriter} */ public PrintWriter getInputWriter() { return stdinWriter; } /** * The {@link Runnable} used to capture lines of output. */ class OutputCaptor implements Runnable { /** * The {@link BufferedReader} to capture output from */ BufferedReader reader; /** * The {@link LinkedList} to store lines of output in */ ConcurrentLinkedQueue lines; /** * Create an {@link OutputCaptor}. * * @param reader The {@link BufferedReader} to capture output from * @param lines The {@link LinkedList} to store lines of output in */ OutputCaptor(BufferedReader reader, ConcurrentLinkedQueue lines) { this.reader = reader; this.lines = lines; } /** * The {@link Runnable#run()} method for this {@link OutputCaptor} * that will capture output. */ @Override public void run() { try { String line = reader.readLine(); while (line != null) { if (lines.size() >= CapturingApplicationConsole.this.maximumLines) { lines.poll(); } lines.add(line); line = reader.readLine(); } } catch (IOException e) { // Skip: Likely caused by application termination } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy