1
0
mirror of https://github.com/Stirling-Tools/Stirling-PDF.git synced 2024-11-16 12:20:12 +01:00
Stirling-PDF/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

167 lines
5.9 KiB
Java
Raw Normal View History

package stirling.software.SPDF.utils;
import java.io.BufferedReader;
2023-07-22 17:57:40 +02:00
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
public class ProcessExecutor {
public enum Processes {
2023-07-22 17:57:40 +02:00
LIBRE_OFFICE,
OCR_MY_PDF,
PYTHON_OPENCV,
GHOSTSCRIPT,
WEASYPRINT
}
private static final Map<Processes, ProcessExecutor> instances = new ConcurrentHashMap<>();
public static ProcessExecutor getInstance(Processes processType) {
return instances.computeIfAbsent(
processType,
key -> {
int semaphoreLimit =
switch (key) {
case LIBRE_OFFICE -> 1;
case OCR_MY_PDF -> 2;
2023-05-01 22:57:48 +02:00
case PYTHON_OPENCV -> 8;
case GHOSTSCRIPT -> 16;
2023-07-22 17:57:40 +02:00
case WEASYPRINT -> 16;
};
return new ProcessExecutor(semaphoreLimit);
});
}
private final Semaphore semaphore;
private ProcessExecutor(int semaphoreLimit) {
this.semaphore = new Semaphore(semaphoreLimit);
}
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public ProcessExecutorResult runCommandWithOutputHandling(List<String> command)
throws IOException, InterruptedException {
2023-07-22 17:57:40 +02:00
return runCommandWithOutputHandling(command, null);
}
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public ProcessExecutorResult runCommandWithOutputHandling(
List<String> command, File workingDirectory) throws IOException, InterruptedException {
int exitCode = 1;
2023-07-29 14:53:30 +02:00
String messages = "";
semaphore.acquire();
try {
System.out.print("Running command: " + String.join(" ", command));
ProcessBuilder processBuilder = new ProcessBuilder(command);
2023-12-30 20:11:27 +01:00
2023-07-22 17:57:40 +02:00
// Use the working directory if it's set
if (workingDirectory != null) {
processBuilder.directory(workingDirectory);
}
Process process = processBuilder.start();
// Read the error stream and standard output stream concurrently
List<String> errorLines = new ArrayList<>();
List<String> outputLines = new ArrayList<>();
Thread errorReaderThread =
new Thread(
() -> {
try (BufferedReader errorReader =
new BufferedReader(
new InputStreamReader(
process.getErrorStream(),
StandardCharsets.UTF_8))) {
String line;
while ((line = errorReader.readLine()) != null) {
errorLines.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
});
2023-12-30 20:11:27 +01:00
Thread outputReaderThread =
new Thread(
() -> {
try (BufferedReader outputReader =
new BufferedReader(
new InputStreamReader(
process.getInputStream(),
StandardCharsets.UTF_8))) {
String line;
while ((line = outputReader.readLine()) != null) {
outputLines.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
});
errorReaderThread.start();
outputReaderThread.start();
// Wait for the conversion process to complete
exitCode = process.waitFor();
// Wait for the reader threads to finish
errorReaderThread.join();
outputReaderThread.join();
2023-12-30 20:11:27 +01:00
if (outputLines.size() > 0) {
String outputMessage = String.join("\n", outputLines);
2023-07-29 14:53:30 +02:00
messages += outputMessage;
System.out.println("Command output:\n" + outputMessage);
}
if (errorLines.size() > 0) {
String errorMessage = String.join("\n", errorLines);
2023-07-29 14:53:30 +02:00
messages += errorMessage;
System.out.println("Command error output:\n" + errorMessage);
if (exitCode != 0) {
throw new IOException(
"Command process failed with exit code "
+ exitCode
+ ". Error message: "
+ errorMessage);
}
}
} finally {
semaphore.release();
}
2023-07-29 14:53:30 +02:00
return new ProcessExecutorResult(exitCode, messages);
}
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public class ProcessExecutorResult {
int rc;
String messages;
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public ProcessExecutorResult(int rc, String messages) {
this.rc = rc;
this.messages = messages;
}
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public int getRc() {
return rc;
}
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public void setRc(int rc) {
this.rc = rc;
}
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public String getMessages() {
return messages;
}
2023-12-30 20:11:27 +01:00
2023-07-29 14:53:30 +02:00
public void setMessages(String messages) {
this.messages = messages;
}
}
}