001package jmri.jmrit.operations.trains.csv; 002 003import java.io.IOException; 004import java.util.List; 005 006import org.apache.commons.csv.CSVPrinter; 007 008import jmri.InstanceManager; 009import jmri.jmrit.operations.locations.Location; 010import jmri.jmrit.operations.locations.Track; 011import jmri.jmrit.operations.rollingstock.cars.Car; 012import jmri.jmrit.operations.rollingstock.cars.CarManager; 013import jmri.jmrit.operations.rollingstock.engines.Engine; 014import jmri.jmrit.operations.routes.RouteLocation; 015import jmri.jmrit.operations.setup.Setup; 016import jmri.jmrit.operations.trains.Train; 017import jmri.jmrit.operations.trains.trainbuilder.TrainCommon; 018import jmri.util.FileUtil; 019 020/** 021 * Contains the csv operators for manifests and switch lists 022 * 023 * @author Daniel Boudreau Copyright (C) 2011, 2013, 2015, 2022, 2026 024 */ 025public class TrainCsvCommon extends TrainCommon { 026 027 protected final void printDepartureTime(CSVPrinter printer, String time) throws IOException { 028 printer.printRecord("DT", Bundle.getMessage("csvDepartureTime"), time); // NOI18N 029 } 030 031 protected final void printHeader(CSVPrinter printer) throws IOException { 032 printer.printRecord(Bundle.getMessage("csvOperator"), Bundle.getMessage("csvDescription"), 033 Bundle.getMessage("csvParameters")); // NOI18N 034 } 035 036 protected final void printLocationSwitchListComment(CSVPrinter printer, String comment, String textColorName) 037 throws IOException { 038 printer.printRecord("SWLC", Bundle.getMessage("csvSwitchListComment"), comment, textColorName); // NOI18N 039 } 040 041 protected final void printLocationComment(CSVPrinter printer, String comment, String textColorName) 042 throws IOException { 043 printer.printRecord("LC", Bundle.getMessage("csvLocationComment"), comment, textColorName); // NOI18N 044 } 045 046 protected final void printLocationName(CSVPrinter printer, String name) throws IOException { 047 printer.printRecord("LN", Bundle.getMessage("csvLocationName"), name); // NOI18N 048 } 049 050 protected final void printPrinterName(CSVPrinter printer, String name) throws IOException { 051 printer.printRecord("PRNTR", Bundle.getMessage("csvPrinterName"), name); // NOI18N 052 } 053 054 protected final void printRailroadName(CSVPrinter printer, String name) throws IOException { 055 printer.printRecord("RN", Bundle.getMessage("csvRailroadName"), name); // NOI18N 056 } 057 058 protected final void printRemoveHelpers(CSVPrinter printer) throws IOException { 059 printer.printRecord("RH", Bundle.getMessage("csvRemoveHelpers")); // NOI18N 060 } 061 062 protected final void printRouteLocationComment(CSVPrinter printer, String comment, String textColorName) 063 throws IOException { 064 printer.printRecord("RLC", Bundle.getMessage("csvRouteLocationComment"), comment, textColorName); // NOI18N 065 } 066 067 protected final void printTrainDeparts(CSVPrinter printer, String name, String direction) throws IOException { 068 printer.printRecord("TD", Bundle.getMessage("csvTrainDeparts"), name, direction); // NOI18N 069 } 070 071 protected final void printTrainDescription(CSVPrinter printer, String description) throws IOException { 072 printer.printRecord("TM", Bundle.getMessage("csvTrainManifestDescription"), description); // NOI18N 073 } 074 075 protected final void printTrainLength(CSVPrinter printer, int length, int empty, int total) throws IOException { 076 printer.printRecord("TL", Bundle.getMessage("csvTrainLengthEmptiesCars"), length, empty, total); // NOI18N 077 } 078 079 protected final void printTrainName(CSVPrinter printer, String name) throws IOException { 080 printer.printRecord("TN", Bundle.getMessage("csvTrainName"), name); // NOI18N 081 } 082 083 protected final void printTrainTerminates(CSVPrinter printer, String name) throws IOException { 084 printer.printRecord("TT", Bundle.getMessage("csvTrainTerminates"), name); 085 } 086 087 protected final void printTrainWeight(CSVPrinter printer, int weight) throws IOException { 088 printer.printRecord("TW", Bundle.getMessage("csvTrainWeight"), weight); // NOI18N 089 } 090 091 protected final void printValidity(CSVPrinter printer, String date) throws IOException { 092 printer.printRecord("VT", Bundle.getMessage("csvValid"), date); // NOI18N 093 } 094 095 protected final void printLocationSwitchListComment(CSVPrinter fileOut, Location location) throws IOException { 096 String textColorName = TrainCommon.getTextColorName(location.getSwitchListCommentWithColor()); 097 // comment can have multiple lines 098 String[] comments = location.getSwitchListComment().split(NEW_LINE); // NOI18N 099 for (String comment : comments) { 100 printLocationSwitchListComment(fileOut, comment, textColorName); 101 } 102 } 103 104 protected final void printLocationComment(CSVPrinter fileOut, Location location) throws IOException { 105 if (!location.getComment().equals(Location.NONE)) { 106 String textColorName = TrainCommon.getTextColorName(location.getCommentWithColor()); 107 // comment can have multiple lines 108 String[] comments = location.getComment().split(NEW_LINE); // NOI18N 109 for (String comment : comments) { 110 printLocationComment(fileOut, comment, textColorName); 111 } 112 } 113 } 114 115 protected final void printRouteLocationComment(CSVPrinter fileOut, RouteLocation rl) throws IOException { 116 if (!rl.getComment().equals(RouteLocation.NONE)) { 117 String textColorName = rl.getCommentTextColor(); 118 // comment can have multiple lines 119 String[] comments = rl.getComment().split(NEW_LINE); // NOI18N 120 for (String comment : comments) { 121 printRouteLocationComment(fileOut, comment, textColorName); 122 } 123 } 124 } 125 126 protected final void printTrainComment(CSVPrinter fileOut, Train train) throws IOException { 127 if (!train.getComment().equals(Train.NONE)) { 128 String textColorName = TrainCommon.getTextColorName(train.getCommentWithColor()); 129 String[] comments = train.getComment().split(NEW_LINE); 130 for (String comment : comments) { 131 fileOut.printRecord("TC", Bundle.getMessage("csvTrainComment"), comment, textColorName); // NOI18N 132 } 133 } 134 } 135 136 protected final void printRouteComment(CSVPrinter fileOut, Train train) throws IOException { 137 if (!train.getRoute().getComment().isBlank()) { 138 fileOut.printRecord("RC", Bundle.getMessage("csvRouteComment"), train.getRoute().getComment()); // NOI18N 139 } 140 } 141 142 protected void printLogoURL(CSVPrinter fileOut, Train train) throws IOException { 143 String logoURL = FileUtil.getExternalFilename(Setup.getManifestLogoURL()); 144 if (!train.getManifestLogoPathName().equals(Train.NONE)) { 145 logoURL = FileUtil.getExternalFilename(train.getManifestLogoPathName()); 146 } 147 if (!logoURL.isEmpty()) { 148 fileOut.printRecord("LOGO", Bundle.getMessage("csvLogoFilePath"), logoURL); 149 } 150 } 151 152 protected void printCar(CSVPrinter fileOut, Car car, String code, String message, int count) throws IOException { 153 fileOut.printRecord(code, 154 message, 155 car.getRoadName(), 156 car.getNumber(), 157 car.getTypeName(), 158 car.getLength(), 159 car.getLoadName(), 160 car.getColor(), 161 car.getLocationName(), 162 car.getTrackName(), 163 car.getDestinationName(), 164 car.getDestinationTrackName(), 165 car.getOwnerName(), 166 car.getKernelName(), 167 car.getComment(), 168 car.getPickupComment(), 169 car.getDropComment(), 170 car.isCaboose() ? "C" : "", 171 car.hasFred() ? "F" : "", 172 car.isHazardous() ? "H" : "", 173 car.getRfid(), 174 car.getReturnWhenEmptyDestinationName(), 175 car.getReturnWhenEmptyDestTrackName(), 176 car.isUtility() ? "U" : "", 177 count, 178 car.getFinalDestinationName(), 179 car.getFinalDestinationTrackName(), 180 car.getLoadType(), 181 car.getReturnWhenLoadedDestinationName(), 182 car.getReturnWhenLoadedDestTrackName(), 183 car.getRoutePath(), 184 car.getDivisionName(), 185 car.getBlocking()); 186 } 187 188 protected void printEngine(CSVPrinter fileOut, Engine engine, String code, String message) throws IOException { 189 fileOut.printRecord(code, 190 message, 191 engine.getRoadName(), 192 engine.getNumber(), 193 engine.getModel(), 194 engine.getLength(), 195 engine.getTypeName(), 196 engine.getHp(), 197 engine.getLocationName(), 198 engine.getTrackName(), 199 engine.getDestinationName(), 200 engine.getDestinationTrackName(), 201 engine.getOwnerName(), 202 engine.getConsistName(), 203 engine.isLead() ? "Lead loco" : "", // NOI18N 204 engine.getComment(), 205 engine.getRfid(), 206 engine.getDccAddress(), 207 engine.getBlocking()); 208 } 209 210 protected final void checkForEngineOrCabooseChange(CSVPrinter fileOut, Train train, RouteLocation rl) 211 throws IOException { 212 if (train.getSecondLegOptions() != Train.NO_CABOOSE_OR_FRED) { 213 if (rl == train.getSecondLegStartRouteLocation()) { 214 engineCsvChange(fileOut, rl, train.getSecondLegOptions()); 215 } 216 if (rl == train.getSecondLegEndRouteLocation()) { 217 printRemoveHelpers(fileOut); 218 } 219 } 220 if (train.getThirdLegOptions() != Train.NO_CABOOSE_OR_FRED) { 221 if (rl == train.getThirdLegStartRouteLocation()) { 222 engineCsvChange(fileOut, rl, train.getThirdLegOptions()); 223 } 224 if (rl == train.getThirdLegEndRouteLocation()) { 225 printRemoveHelpers(fileOut); 226 } 227 } 228 } 229 230 protected void engineCsvChange(CSVPrinter fileOut, RouteLocation rl, int legOptions) throws IOException { 231 if ((legOptions & Train.HELPER_ENGINES) == Train.HELPER_ENGINES) { 232 fileOut.printRecord("AH", Bundle.getMessage("csvAddHelpers")); 233 } 234 if ((legOptions & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE || 235 (legOptions & Train.ADD_CABOOSE) == Train.ADD_CABOOSE) { 236 fileOut.printRecord("CC", Bundle.getMessage("csvChangeCaboose")); 237 } 238 if ((legOptions & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES) { 239 fileOut.printRecord("CL", Bundle.getMessage("csvChangeLocos")); 240 } 241 } 242 243 protected void printTrackComments(CSVPrinter fileOut, RouteLocation rl, List<Car> carList) throws IOException { 244 Location location = rl.getLocation(); 245 if (location != null) { 246 List<Track> tracks = location.getTracksByNameList(null); 247 for (Track track : tracks) { 248 // any pick ups or set outs to this track? 249 boolean pickup = false; 250 boolean setout = false; 251 for (Car car : carList) { 252 if (car.getRouteLocation() == rl && car.getTrack() != null && car.getTrack() == track) { 253 pickup = true; 254 } 255 if (car.getRouteDestination() == rl && 256 car.getDestinationTrack() != null && 257 car.getDestinationTrack() == track) { 258 setout = true; 259 } 260 } 261 // print the appropriate comment if there's one 262 // each comment can have multiple lines 263 if (pickup && setout && !track.getCommentBoth().equals(Track.NONE)) { 264 String textColorName = TrainCommon.getTextColorName(track.getCommentBothWithColor()); 265 String[] comments = track.getCommentBoth().split(NEW_LINE); 266 for (String comment : comments) { 267 fileOut.printRecord("TKCB", Bundle.getMessage("csvTrackCommentBoth"), comment, textColorName); // NOI18N 268 } 269 } else if (pickup && !setout && !track.getCommentPickup().equals(Track.NONE)) { 270 String textColorName = TrainCommon.getTextColorName(track.getCommentPickupWithColor()); 271 String[] comments = track.getCommentPickup().split(NEW_LINE); 272 for (String comment : comments) { 273 fileOut.printRecord("TKCP", Bundle.getMessage("csvTrackCommentPickUp"), comment, textColorName); // NOI18N 274 } 275 } else if (!pickup && setout && !track.getCommentSetout().equals(Track.NONE)) { 276 String textColorName = TrainCommon.getTextColorName(track.getCommentSetoutWithColor()); 277 String[] comments = track.getCommentSetout().split(NEW_LINE); 278 for (String comment : comments) { 279 fileOut.printRecord("TKCS", Bundle.getMessage("csvTrackCommentSetOut"), comment, textColorName); // NOI18N 280 } 281 } 282 } 283 } 284 } 285 286 protected void listCarsLocationUnknown(CSVPrinter fileOut) throws IOException { 287 List<Car> cars = InstanceManager.getDefault(CarManager.class).getCarsLocationUnknown(); 288 if (cars.isEmpty()) { 289 return; // no cars to search for! 290 } 291 fileOut.printRecord("SMCM", Bundle.getMessage("csvSearchMiaMessage"), Setup.getMiaComment()); 292 for (Car car : cars) { 293 printCar(fileOut, car, "SMC", Bundle.getMessage("csvSearchMissingCar"), 0); 294 } 295 } 296}