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

com.liferay.poshi.runner.util.BufferedProcess Maven / Gradle / Ivy

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.poshi.runner.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import java.util.Arrays;

/**
 * @author Peter Yoo
 */
public class BufferedProcess extends Process {

	public BufferedProcess(int bufferSize, Process process) {
		_process = process;

		_standardErrorInputStreamBuffer = new InputStreamBuffer(
			bufferSize, _process.getErrorStream());

		_standardErrorInputStreamBuffer.start();

		_standardOutInputStreamBuffer = new InputStreamBuffer(
			bufferSize, _process.getInputStream());

		_standardOutInputStreamBuffer.start();
	}

	@Override
	public void destroy() {
		_process.destroy();
	}

	@Override
	public int exitValue() {
		int exitValue = _process.exitValue();

		ExecUtil.sleep(_MINIMUM_EXECUTION_TIME);

		return exitValue;
	}

	@Override
	public InputStream getErrorStream() {
		return _standardErrorInputStreamBuffer.toInputStream();
	}

	@Override
	public InputStream getInputStream() {
		return _standardOutInputStreamBuffer.toInputStream();
	}

	@Override
	public OutputStream getOutputStream() {
		return _process.getOutputStream();
	}

	@Override
	public int waitFor() throws InterruptedException {
		ExecUtil.sleep(_MINIMUM_EXECUTION_TIME);

		return _process.waitFor();
	}

	private static final long _MINIMUM_EXECUTION_TIME = 10;

	private final Process _process;
	private final InputStreamBuffer _standardErrorInputStreamBuffer;
	private final InputStreamBuffer _standardOutInputStreamBuffer;

	private class InputStreamBuffer extends Thread {

		public InputStreamBuffer(int bufferSize, InputStream inputStream) {
			_buffer = new byte[bufferSize];
			_inputStream = inputStream;
		}

		public void run() {
			try {
				byte[] bytes = new byte[Math.min(256, _buffer.length)];

				int bytesRead = 0;

				_index = 0;

				while (bytesRead != -1) {
					int spaceAvailable = _buffer.length - _index;

					bytesRead = _inputStream.read(bytes);

					if (bytesRead > 0) {
						if (bytesRead > spaceAvailable) {
							int spaceNeeded = bytesRead - spaceAvailable;

							_makeSpace(spaceNeeded);
						}

						synchronized (_buffer) {
							System.arraycopy(
								bytes, 0, _buffer, _index, bytesRead);

							_index += bytesRead;
							_totalBytesRead += bytesRead;
						}
					}
				}
			}
			catch (IOException ioException) {
				throw new RuntimeException(ioException);
			}
		}

		public InputStream toInputStream() {
			byte[] bytes = null;

			if (_totalBytesRead > _buffer.length) {
				String message = StringUtil.combine(
					"[Truncated ",
					String.valueOf(_totalBytesRead - _buffer.length),
					" bytes] \n...");

				byte[] messageBytes = message.getBytes();

				bytes = new byte[messageBytes.length + _index];

				System.arraycopy(
					messageBytes, 0, bytes, 0, messageBytes.length);

				System.arraycopy(
					_buffer, 0, bytes, messageBytes.length, _index);
			}
			else {
				bytes = Arrays.copyOf(_buffer, _index);
			}

			return new ByteArrayInputStream(bytes);
		}

		private void _makeSpace(int spacesNeeded) {
			if ((_index - spacesNeeded) < 0) {
				throw new IllegalArgumentException(
					StringUtil.combine(
						"Unable to shift buffer content left ",
						String.valueOf(spacesNeeded), " spaces"));
			}

			System.arraycopy(
				_buffer, spacesNeeded, _buffer, 0, _index - spacesNeeded);

			_index -= spacesNeeded;
		}

		private final byte[] _buffer;
		private int _index;
		private final InputStream _inputStream;
		private int _totalBytesRead;

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy