tomee4hobbysign/tools/PDFPrinter.java

260 lines
10 KiB
Java

import java.io.*;
import java.nio.file.*;
import java.util.concurrent.TimeUnit;
public class PDFPrinter {
// Default values
private static final String DEFAULT_PRINTER = "null_printer";
private static final String DEFAULT_FILE_PATH = "/usr/local/tomee/output/SystemtestScott.pdf";
public static void main(String[] args) {
String filePath = DEFAULT_FILE_PATH;
String printerName = DEFAULT_PRINTER;
System.out.println("=== PDF Printing Utility ===");
// Parse command line arguments
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-d") && i + 1 < args.length) {
// -d option: specify printer
printerName = args[i + 1];
i++; // Skip next argument since we used it
} else if (args[i].equals("-h") || args[i].equals("--help")) {
// Help option
printHelp();
System.exit(0);
} else if (args[i].equals("-l") || args[i].equals("--list")) {
// List printers option
try {
listAvailablePrinters();
} catch (Exception e) {
System.err.println("ERROR: Failed to list printers: " + e.getMessage());
}
System.exit(0);
} else if (!args[i].startsWith("-")) {
// Positional argument: treat as file path
filePath = args[i];
} else {
System.err.println("ERROR: Unknown option: " + args[i]);
printHelp();
System.exit(1);
}
}
// Display selected options
System.out.println("Target file: " + filePath);
System.out.println("Printer: " + printerName);
try {
boolean success = printPDF(filePath, printerName);
if (success) {
System.out.println("SUCCESS: Print job submitted successfully!");
System.exit(0);
} else {
System.out.println("FAILURE: Print job failed");
System.exit(1);
}
} catch (Exception e) {
System.err.println("ERROR: " + e.getMessage());
System.exit(1);
}
}
/**
* Display help message
*/
private static void printHelp() {
System.out.println("Usage: java PDFPrinter [options] [file-path]");
System.out.println();
System.out.println("Options:");
System.out.println(" -d <printer> Specify printer name (default: null_printer)");
System.out.println(" -l, --list List available printers");
System.out.println(" -h, --help Display this help message");
System.out.println();
System.out.println("Examples:");
System.out.println(" java PDFPrinter");
System.out.println(" Prints default file to null_printer printer");
System.out.println();
System.out.println(" java PDFPrinter -d HP-LaserJet");
System.out.println(" Prints default file to HP-LaserJet printer");
System.out.println();
System.out.println(" java PDFPrinter /path/to/file.pdf");
System.out.println(" Prints specified file to null_printer printer");
System.out.println();
System.out.println(" java PDFPrinter /path/to/file.pdf -d Office-Printer");
System.out.println(" Prints specified file to Office-Printer");
System.out.println();
System.out.println("Default values:");
System.out.println(" File: " + DEFAULT_FILE_PATH);
System.out.println(" Printer: " + DEFAULT_PRINTER);
}
/**
* Prints a PDF file using the Linux 'lp' command
*
* @param filePath Path to the PDF file
* @param printerName Printer name (cannot be null, default is "null_printer")
* @return true if print job submitted successfully
* @throws IOException if file not found or command fails
* @throws InterruptedException if process interrupted
*/
public static boolean printPDF(String filePath, String printerName)
throws IOException, InterruptedException {
// Validate printer name is not null or empty
if (printerName == null || printerName.trim().isEmpty()) {
printerName = DEFAULT_PRINTER;
}
// 1. Validate the file exists and is readable
System.out.println("Validating PDF file...");
Path pdfPath = Paths.get(filePath);
if (!Files.exists(pdfPath)) {
throw new IOException("File does not exist: " + filePath);
}
if (!Files.isReadable(pdfPath)) {
throw new IOException("File is not readable: " + filePath);
}
if (!filePath.toLowerCase().endsWith(".pdf")) {
System.out.println("Warning: File does not have .pdf extension");
}
long fileSize = Files.size(pdfPath);
System.out.println("File validation passed");
System.out.println("File size: " + fileSize + " bytes");
// 2. Build the lp command - ALWAYS use -d option with printerName
ProcessBuilder pb;
System.out.println("Using printer: " + printerName);
pb = new ProcessBuilder("lp", "-d", printerName, filePath);
// 3. Configure ProcessBuilder
pb.redirectErrorStream(true); // Combine stdout and stderr
// 4. Execute the command
System.out.println("Executing: " + String.join(" ", pb.command()));
Process process;
try {
process = pb.start();
} catch (IOException e) {
throw new IOException("Failed to start lp command. Is CUPS/lp installed? " +
"Install with: sudo apt-get install cups-client", e);
}
// 5. Capture and display output
StringBuilder output = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
System.out.println("lp output: " + line);
}
}
// 6. Wait for completion with timeout (60 seconds)
System.out.println("Waiting for print job submission...");
boolean completed = process.waitFor(60, TimeUnit.SECONDS);
if (!completed) {
process.destroyForcibly();
throw new IOException("Print command timed out after 60 seconds");
}
// 7. Check exit code
int exitCode = process.exitValue();
if (exitCode == 0) {
// Success - extract job ID if available
String response = output.toString();
if (response.contains("request id is")) {
String jobId = extractJobId(response);
System.out.println("Print job ID: " + jobId);
}
return true;
} else {
// Failure - provide helpful error messages
String errorMsg = output.toString().trim();
if (errorMsg.contains("No such file or directory")) {
throw new IOException("lp command not found. Install CUPS: sudo apt-get install cups-client");
} else if (errorMsg.contains("Unable to open")) {
throw new IOException("Printer error: " + errorMsg);
} else if (errorMsg.contains("invalid destination")) {
throw new IOException("Invalid printer name: " + printerName +
". Use -l option to list available printers.");
} else if (errorMsg.contains("Unsupported format")) {
throw new IOException("PDF format not supported by printer");
} else if (!errorMsg.isEmpty()) {
throw new IOException("Print failed: " + errorMsg);
} else {
throw new IOException("Print failed with exit code: " + exitCode);
}
}
}
/**
* Extracts print job ID from lp output
*/
private static String extractJobId(String response) {
// Example: "request id is HP-LaserJet-123 (1 file(s))"
if (response.contains("request id is")) {
String[] parts = response.split("request id is");
if (parts.length > 1) {
String jobPart = parts[1].trim();
int endIndex = jobPart.indexOf(" (");
if (endIndex > 0) {
return jobPart.substring(0, endIndex);
}
return jobPart;
}
}
return "Unknown";
}
/**
* Utility method to check available printers
*/
public static void listAvailablePrinters() throws IOException, InterruptedException {
System.out.println("\n=== Available Printers ===");
System.out.println("Looking for printers...");
ProcessBuilder pb = new ProcessBuilder("lpstat", "-p");
pb.redirectErrorStream(true);
Process process = pb.start();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
boolean hasPrinters = false;
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("printer ")) {
hasPrinters = true;
String printerName = line.split("\\s+")[1];
String status = line.contains("enabled") ? "[ENABLED]" : "[DISABLED]";
System.out.println(status + " " + printerName);
}
}
if (!hasPrinters) {
System.out.println("No printers found via lpstat.");
System.out.println("\nTroubleshooting steps:");
System.out.println("1. Check if CUPS is running: sudo systemctl status cups");
System.out.println("2. Check all print services: lpstat -v");
System.out.println("3. Install CUPS if needed: sudo apt-get install cups cups-client");
} else {
System.out.println("\nNote: Default printer is 'null_printer'");
}
}
process.waitFor();
}
}