![JAR search and dependency download from the Maven repository](/logo.png)
com.telenav.cactus.maven.util.StringProcessResultConverterImpl Maven / Gradle / Ivy
package com.telenav.cactus.maven.util;
import com.mastfrog.util.preconditions.Exceptions;
import com.telenav.cactus.maven.log.BuildLog;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.function.IntPredicate;
import java.util.function.Supplier;
/**
*
* @author Tim Boudreau
*/
final class StringProcessResultConverterImpl implements StringProcessResultConverter
{
final IntPredicate exitCodeTest;
private volatile OutputReader stderr;
private volatile OutputReader stdout;
private final BuildLog log = BuildLog.get();
public StringProcessResultConverterImpl(IntPredicate exitCodeTest)
{
this.exitCodeTest = exitCodeTest;
}
public StringProcessResultConverterImpl()
{
this(code -> code == 0);
}
@Override
public AwaitableCompletionStage onProcessStarted(Supplier description, Process process)
{
stderr = new OutputReader(process.getErrorStream()).start();
stdout = new OutputReader(process.getInputStream()).start();
// Note: This really needs to be thenApplyAsync(), or you sometimes get
// immediately called back before the process has *started*.
return AwaitableCompletionStage.of(process).thenApplyAsync(proc ->
{
log.debug(() ->
{
return "exit " + proc.exitValue() + ":\n" + stdout.toString() + "\n"
+ (proc.exitValue() != 0 ? stderr.toString() : "");
});
if (exitCodeTest.test(proc.exitValue()))
{
return stdout.done();
}
throw new ProcessFailedException(description, process, stdout.done(), stderr.done());
});
}
private static class OutputReader implements Runnable
{
private final BufferedReader in;
private final StringBuilder sb = new StringBuilder();
private final Thread thread = new Thread(this, "process-output-reader");
private volatile Throwable thrown;
// Sigh... 27 years of Java and the API for interacting with processes
// is still goshawful.
public OutputReader(InputStream in)
{
this.in = new BufferedReader(new InputStreamReader(in, Charset.defaultCharset()), 512);
}
@Override
public String toString()
{
synchronized (this)
{
return sb.toString();
}
}
public String done()
{
thread.interrupt();
Throwable t = thrown;
if (t != null)
{
// unlikely but cover all the bases
return Exceptions.chuck(t);
}
return toString();
}
public OutputReader start()
{
thread.start();
return this;
}
@Override
public void run()
{
char[] buf = new char[1024];
int count;
try
{
while ((count = in.read(buf)) != -1)
{
synchronized (this)
{
sb.append(buf, 0, count);
}
}
} catch (IOException ex)
{
ex.printStackTrace();
thrown = ex;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy