package jetbrains.mps.execution.configurations.implementation.plugin.plugin; /*Generated by MPS */ import com.intellij.execution.process.BaseOSProcessHandler; import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import java.util.concurrent.Future; import jetbrains.mps.baseLanguage.unitTest.execution.server.TestInProcessExecutor; import com.intellij.execution.process.ProcessOutputTypes; import org.jetbrains.annotations.NotNull; import com.intellij.util.io.BaseOutputReader; import com.intellij.util.io.BaseDataReader; import java.io.IOException; import org.apache.log4j.Level; import java.io.IOError; import org.jetbrains.annotations.Nullable; import java.io.OutputStream; import com.intellij.openapi.util.Key; import java.io.Reader; public class FakeProcessHandler extends BaseOSProcessHandler { private static final Logger LOG = LogManager.getLogger(FakeProcessHandler.class); private final FakeProcess myFakeProcess; private final Future<?> myFuture; private final TestInProcessExecutor myExecutor; private final FakeProcessHandler.BlockingReader myOutputReader = new FakeProcessHandler.BlockingReader(createProcessOutReader(), ProcessOutputTypes.STDOUT, "output stream of " + myPresentableName); private final FakeProcessHandler.BlockingReader myErrorReader = new FakeProcessHandler.BlockingReader(createProcessErrReader(), ProcessOutputTypes.STDERR, "error stream of " + myPresentableName); public FakeProcessHandler(@NotNull FakeProcess fakeProcess, Future<?> future, TestInProcessExecutor executor) { super(fakeProcess, fakeProcess.toString(), null); myFakeProcess = fakeProcess; myFuture = future; myExecutor = executor; } @NotNull @Override protected final BaseOutputReader.Options readerOptions() { return BaseOutputReader.Options.BLOCKING; } @NotNull @Override protected final BaseDataReader createErrorDataReader() { return myErrorReader; } @NotNull @Override protected final BaseDataReader createOutputDataReader() { return myOutputReader; } @Override public void startNotify() { super.startNotify(); try { myFakeProcess.init(); } catch (IOException e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Process could not be constructed", e); } throw new IOError(e); } myOutputReader.startReading(); myErrorReader.startReading(); myExecutor.setReady(); } private void terminate() { myExecutor.terminateRun(); } @Override protected void destroyProcessImpl() { terminate(); } @Override protected void detachProcessImpl() { terminate(); } @Override public boolean isProcessTerminated() { return myFuture.isDone(); } @Override public boolean detachIsDefault() { return false; } @Nullable @Override public OutputStream getProcessInput() { return null; } private class BlockingReader extends BaseOutputReader { private final Key myProcessOutputType; private final String myPresentableName; public BlockingReader(Reader reader, Key outputType, @NotNull String presentableName) { super(reader, BaseOutputReader.Options.BLOCKING); myProcessOutputType = outputType; myPresentableName = presentableName; } public void startReading() { start(myPresentableName); } @Override protected void doRun() { try { boolean stopSignalled = false; while (true) { final boolean read = readAvailableBlocking(); if (stopSignalled) { break; } stopSignalled = isStopped; if (!(stopSignalled)) { synchronized (mySleepMonitor) { mySleepMonitor.wait(mySleepingPolicy.getTimeToSleep(read)); } } } } catch (IOException e) { if (LOG.isInfoEnabled()) { LOG.info("", e); } } catch (Exception e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("", e); } } finally { try { close(); } catch (IOException e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Cannot close stream", e); } } } } @NotNull @Override protected Future<?> executeOnPooledThread(@NotNull Runnable runnable) { return FakeProcessHandler.this.executeOnPooledThread(runnable); } @Override protected void onTextAvailable(@NotNull String text) { notifyTextAvailable(text, myProcessOutputType); } } }