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

com.gemstone.gemfire.internal.process.ProcessStreamReader Maven / Gradle / Ivy

/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You
 * may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.internal.process;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.internal.LocalLogWriter;
import com.gemstone.gemfire.internal.LogWriterImpl;

/**
 * Reads the output stream of a Process.
 * 
 * @author Kirk Lund
 * @since 7.0
 */
public final class ProcessStreamReader implements Runnable {
 
  private final LogWriter logWriter = new LocalLogWriter(LogWriterImpl.INFO_LEVEL);

  private final InputStream inputStream;
  private final InputListener listener;

  private Thread thread;

  public ProcessStreamReader(final InputStream inputStream) {
    this.inputStream = inputStream;
    this.listener = new InputListener() {
      @Override
      public void notifyInputLine(String line) {
        // do nothing
      }
      @Override
      public String toString() {
        return "NullInputListener";
      }
    };
  }

  public ProcessStreamReader(final InputStream inputStream, final InputListener listener) {
    this.inputStream = inputStream;
    this.listener = listener;
  }

  @Override
  public void run() {
    this.logWriter.fine("Running " + this);
    BufferedReader reader = null;
    try {
      reader = new BufferedReader(new InputStreamReader(inputStream));
      String line;
      while ((line = reader.readLine()) != null) {
        this.listener.notifyInputLine(line);
      }
    } catch (IOException e) {
      this.logWriter.fine("Failure reading from buffered input stream: " + e.getMessage(), e);
    } finally {
      try {
        reader.close();
      } catch (IOException e) {
        this.logWriter.fine("Failure closing buffered input stream reader: " + e.getMessage(), e);
      }
      this.logWriter.fine("Terminating " + this);
    }
  }

  public ProcessStreamReader start() {
    synchronized (this) {
      if (this.thread == null) {
        this.thread = new Thread(this, createThreadName());
        this.thread.start();
      } else if (this.thread.isAlive()){
        throw new IllegalStateException(this + " has already started");
      } else {
        throw new IllegalStateException(this + " was stopped and cannot be restarted");
      }
    }
    return this;
  }

  public ProcessStreamReader stop() {
    synchronized (this) {
      if (this.thread != null && this.thread.isAlive()) {
        this.thread.interrupt();
      } else if (this.thread != null){
        this.logWriter.fine(this + " has already been stopped");
      } else {
        this.logWriter.fine(this + " has not been started");
      }
    }
    return this;
  }
  
  public boolean isRunning() {
    synchronized (this) {
      if (this.thread != null) {
        return this.thread.isAlive();
      }
    }
    return false;
  }
  
  public void join() throws InterruptedException {
    Thread thread;
    synchronized (this) {
      thread = this.thread;
    }
    if (thread != null) {
      thread.join();
    }
  }
  
  public void join(final long millis) throws InterruptedException {
    Thread thread;
    synchronized (this) {
      thread = this.thread;
    }
    if (thread != null) {
      thread.join(millis);
    }
  }
  
  public void join(final long millis, final int nanos) throws InterruptedException {
    Thread thread;
    synchronized (this) {
      thread = this.thread;
    }
    if (thread != null) {
      thread.join(millis, nanos);
    }
  }
  
  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder(getClass().getSimpleName());
    sb.append(" Thread").append(" #").append(System.identityHashCode(this));
    sb.append(" alive=").append(isRunning()); //this.thread == null ? false : this.thread.isAlive());
    sb.append(" listener=").append(this.listener);
    return sb.toString();
  }
  
  private String createThreadName() {
    return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
  }
  
  /**
   * Defines the callback for  lines of output found in the stream.
   */
  public static interface InputListener {
    public void notifyInputLine(String line);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy