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