Servant.java
package Hoot.Compiler.Mojo;
import java.io.*;
import java.util.Properties;
import org.apache.commons.lang3.SystemUtils;
import org.eclipse.aether.artifact.Artifact;
import static Hoot.Runtime.Functions.Exceptional.*;
import Hoot.Runtime.Faces.Logging;
/**
* Compiles Hoot code in a separate process.
*
* @author nik <nikboyd@sonic.net>
* @see "Copyright 2010,2021 Nikolas S Boyd."
* @see "Permission is granted to copy this work provided this copyright statement is retained in all copies."
*/
public class Servant implements Logging {
private Process remoteProcess = null;
public void runCompiler(String... args) {
runLoudly(() -> {
remoteProcess = buildProcess(args).start();
new Thread(() -> pipeShellOutput()).start();
remoteProcess.waitFor();
});
}
InputStream processStream() { return remoteProcess.getInputStream(); }
BufferedReader processReader() { return new BufferedReader(new InputStreamReader(processStream())); }
void pipeShellOutput() {
String line; BufferedReader reader = processReader();
try { while((line = reader.readLine()) != null) report(line); }
catch (IOException x) { error(x); }
}
Properties p = new Properties();
static final String Version = "version"; // loaded value name
static final String MojoVersion = "/version.properties";
String version() { runLoudly(() -> loadVersion(p)); return p.getProperty(Version); }
void loadVersion(Properties p) throws IOException { try (InputStream in = versionStream()) { p.load(in); } }
InputStream versionStream() throws IOException { return getClass().getResourceAsStream(MojoVersion); }
static final String CompilerSpec = "hoot-smalltalk:hoot-compiler-boot:";
Artifact locateArtifact() { return Discovery.lookup(CompilerSpec + version()).getArtifact(); }
String locateCompiler() { return locateArtifact().getFile().getAbsolutePath(); }
static final String Quote = "\"";
static final String WinShell = "cmd.exe";
static final String WinCommand = "'%%JAVA_HOME%%\\bin\\java' -jar %s";
String buildWinCommand(String... args) {
String result = format(WinCommand, locateCompiler()).replace("'", Quote);
for (String s : args) { result += " " + s; }
report("running "+result);
return result; }
static final String Shell = "/bin/sh";
static final String JavaCommand = "$JAVA_HOME/bin/java -jar %s";
String buildJavaCommand(String... args) {
String result = format(JavaCommand, locateCompiler());
for (String s : args) { result += " " + s; }
report("running "+result);
return result; }
ProcessBuilder buildProcess(String... args) {
return SystemUtils.IS_OS_WINDOWS ?
new ProcessBuilder(WinShell, "/c", buildWinCommand(args)) :
new ProcessBuilder(Shell, "-c", buildJavaCommand(args)); }
} // Servant