001package jmri.jmrit.operations.trains; 002 003import java.awt.Frame; 004import java.io.*; 005import java.nio.charset.StandardCharsets; 006 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010import jmri.InstanceManager; 011import jmri.jmrit.operations.setup.Setup; 012import jmri.jmrit.operations.trains.trainbuilder.TrainCommon; 013import jmri.util.davidflanagan.HardcopyWriter; 014 015/** 016 * Used for train build reports. 017 * 018 * @author Daniel Boudreau (C) 2025 019 */ 020public class TrainPrintBuildReport extends TrainCommon { 021 022 /** 023 * Print or preview a build report. 024 * 025 * @param file File to be printed or previewed 026 * @param name Title of document 027 * @param isPreview true if preview 028 */ 029 public static void printReport(File file, String name, boolean isPreview) { 030 // obtain a OriginalHardcopyWriter to do this 031 032 String printerName = ""; 033 int fontSize = Setup.getBuildReportFontSize(); 034 boolean isLandScape = false; 035 036 try (HardcopyWriter writer = new HardcopyWriter(new Frame(), name, null, null, fontSize, .5 * 72, .5 * 72, 037 .5 * 72, .5 * 72, isPreview, printerName, isLandScape, true, null, null); 038 BufferedReader in = new BufferedReader(new InputStreamReader( 039 new FileInputStream(file), StandardCharsets.UTF_8));) { 040 041 String line; 042 while (true) { 043 try { 044 line = in.readLine(); 045 } catch (IOException e) { 046 log.debug("Print read failed"); 047 break; 048 } 049 if (line == null) { 050 if (isPreview) { 051 // need to do this in case the input file was empty to create preview 052 writer.write(" "); 053 } 054 break; 055 } 056 // check for build report print level 057 line = filterBuildReport(line, false); // no indent 058 if (line.isEmpty()) { 059 continue; 060 } 061 writer.write(line + NEW_LINE); 062 } 063 } catch (FileNotFoundException e) { 064 log.error("Build file doesn't exist", e); 065 } catch (HardcopyWriter.PrintCanceledException ex) { 066 log.debug("Print canceled"); 067 } catch (IOException e) { 068 log.warn("Exception printing: {}", e.getLocalizedMessage()); 069 } 070 } 071 072 /** 073 * Creates a new build report file with the print detail numbers replaced by 074 * indentations. Then calls open desktop editor. 075 * 076 * @param file build file 077 * @param name train name 078 */ 079 public static void editReport(File file, String name) { 080 // make a new file with the build report levels removed 081 File buildReport = InstanceManager.getDefault(TrainManagerXml.class) 082 .createTrainBuildReportFile(Bundle.getMessage("Report") + " " + name); 083 editReport(file, buildReport); 084 // open the file 085 TrainUtilities.openDesktop(buildReport); 086 } 087 088 /** 089 * Creates a new build report file with the print detail numbers replaced by 090 * indentations. 091 * 092 * @param file Raw file with detail level numbers 093 * @param fileOut Formated file with indentations 094 */ 095 public static void editReport(File file, File fileOut) { 096 try (BufferedReader in = new BufferedReader(new InputStreamReader( 097 new FileInputStream(file), StandardCharsets.UTF_8)); 098 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( 099 new FileOutputStream(fileOut), StandardCharsets.UTF_8)), true);) { 100 101 String line; 102 while (true) { 103 try { 104 line = in.readLine(); 105 if (line == null) { 106 break; 107 } 108 line = filterBuildReport(line, Setup.isBuildReportIndentEnabled()); 109 if (line.isEmpty()) { 110 continue; 111 } 112 out.println(line); // indent lines for each level 113 } catch (IOException e) { 114 log.debug("Print read failed"); 115 break; 116 } 117 } 118 } catch (FileNotFoundException e) { 119 log.error("Build file doesn't exist: {}", e.getLocalizedMessage()); 120 } catch (IOException e) { 121 log.error("Can not create build report file: {}", e.getLocalizedMessage()); 122 } 123 } 124 125 /* 126 * Removes the print levels from the build report 127 */ 128 private static String filterBuildReport(String line, boolean indent) { 129 String[] inputLine = line.split("\\s+"); // NOI18N 130 if (inputLine.length == 0) { 131 return ""; 132 } 133 if (inputLine[0].equals(Setup.BUILD_REPORT_VERY_DETAILED + BUILD_REPORT_CHAR) || 134 inputLine[0].equals(Setup.BUILD_REPORT_DETAILED + BUILD_REPORT_CHAR) || 135 inputLine[0].equals(Setup.BUILD_REPORT_NORMAL + BUILD_REPORT_CHAR) || 136 inputLine[0].equals(Setup.BUILD_REPORT_MINIMAL + BUILD_REPORT_CHAR)) { 137 138 if (Setup.getBuildReportLevel().equals(Setup.BUILD_REPORT_MINIMAL)) { 139 if (inputLine[0].equals(Setup.BUILD_REPORT_NORMAL + BUILD_REPORT_CHAR) || 140 inputLine[0].equals(Setup.BUILD_REPORT_DETAILED + BUILD_REPORT_CHAR) || 141 inputLine[0].equals(Setup.BUILD_REPORT_VERY_DETAILED + BUILD_REPORT_CHAR)) { 142 return ""; // don't print this line 143 } 144 } 145 if (Setup.getBuildReportLevel().equals(Setup.BUILD_REPORT_NORMAL)) { 146 if (inputLine[0].equals(Setup.BUILD_REPORT_DETAILED + BUILD_REPORT_CHAR) || 147 inputLine[0].equals(Setup.BUILD_REPORT_VERY_DETAILED + BUILD_REPORT_CHAR)) { 148 return ""; // don't print this line 149 } 150 } 151 if (Setup.getBuildReportLevel().equals(Setup.BUILD_REPORT_DETAILED)) { 152 if (inputLine[0].equals(Setup.BUILD_REPORT_VERY_DETAILED + BUILD_REPORT_CHAR)) { 153 return ""; // don't print this line 154 } 155 } 156 // do not indent if false 157 int start = 0; 158 if (indent) { 159 // indent lines based on level 160 if (inputLine[0].equals(Setup.BUILD_REPORT_VERY_DETAILED + BUILD_REPORT_CHAR)) { 161 inputLine[0] = " "; 162 } else if (inputLine[0].equals(Setup.BUILD_REPORT_DETAILED + BUILD_REPORT_CHAR)) { 163 inputLine[0] = " "; 164 } else if (inputLine[0].equals(Setup.BUILD_REPORT_NORMAL + BUILD_REPORT_CHAR)) { 165 inputLine[0] = " "; 166 } else if (inputLine[0].equals(Setup.BUILD_REPORT_MINIMAL + BUILD_REPORT_CHAR)) { 167 inputLine[0] = ""; 168 } 169 } else { 170 start = 1; 171 } 172 // rebuild line 173 StringBuffer buf = new StringBuffer(); 174 for (int i = start; i < inputLine.length; i++) { 175 buf.append(inputLine[i] + " "); 176 } 177 // blank line? 178 if (buf.length() == 0) { 179 return " "; 180 } 181 return buf.toString(); 182 } else { 183 log.debug("ERROR first characters of build report not valid ({})", line); 184 return "ERROR " + line; // NOI18N 185 } 186 } 187 188 private final static Logger log = LoggerFactory.getLogger(TrainPrintBuildReport.class); 189}