001package jmri.jmrit.operations.trains.tools;
002
003import java.io.*;
004import java.nio.charset.StandardCharsets;
005
006import org.apache.commons.csv.CSVFormat;
007import org.apache.commons.csv.CSVPrinter;
008
009import jmri.InstanceManager;
010import jmri.jmrit.XmlFile;
011import jmri.jmrit.operations.routes.RouteLocation;
012import jmri.jmrit.operations.setup.OperationsSetupXml;
013import jmri.jmrit.operations.trains.Train;
014import jmri.jmrit.operations.trains.TrainManager;
015import jmri.util.swing.JmriJOptionPane;
016
017/**
018 * Builds the train lineups in a comma delimited file (CSV). Only trains that
019 * are built and have the "Build" checkbox selected are exported.
020 *
021 * @author Daniel Boudreau Copyright (C) 2020
022 */
023public class ExportTrainLineups extends XmlFile {
024
025    public ExportTrainLineups() {
026        // do nothing
027    }
028
029    public void writeOperationsTrainsFile() {
030        makeBackupFile(defaultOperationsFilename());
031        try {
032            if (!checkFile(defaultOperationsFilename())) {
033                // The file does not exist, create it before writing
034                java.io.File file = new java.io.File(defaultOperationsFilename());
035                java.io.File parentDir = file.getParentFile();
036                if (!parentDir.exists()) {
037                    if (!parentDir.mkdir()) {
038                        log.error("Directory wasn't created");
039                    }
040                }
041                if (file.createNewFile()) {
042                    log.debug("File created");
043                }
044            }
045            writeFile(defaultOperationsFilename());
046        } catch (Exception e) {
047            log.error("Exception while writing the new CSV operations file, may not be complete", e);
048        }
049    }
050
051    /**
052     * Writes the train lineups for each location a train visits. The lineup
053     * includes: Train Name, Lead Engine, Location, Arrival Time, Departure
054     * Time, Direction, Pulls, Drops, Loads, Empties, Length, Weight, Engineer, Conductor,
055     * Train Description, Train Comment
056     *
057     * @param name file path name
058     */
059    public void writeFile(String name) {
060        log.debug("writeFile {}", name);
061        // This is taken in large part from "Java and XML" page 368
062        File file = findFile(name);
063        if (file == null) {
064            file = new File(name);
065        }
066
067        try (CSVPrinter fileOut = new CSVPrinter(
068                new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)),
069                CSVFormat.DEFAULT)) {
070
071            // create header
072            fileOut.printRecord(Bundle.getMessage("Name"),
073                    Bundle.getMessage("Engine"),
074                    Bundle.getMessage("Location"),
075                    Bundle.getMessage("Direction"),
076                    Bundle.getMessage("Arrives"),
077                    Bundle.getMessage("Departs"),
078                    Bundle.getMessage("Pulls"),
079                    Bundle.getMessage("Drops"),
080                    Bundle.getMessage("Loads"),
081                    Bundle.getMessage("Empties"),
082                    Bundle.getMessage("Length"),
083                    Bundle.getMessage("Weight"),
084                    Bundle.getMessage("Engineer"),
085                    Bundle.getMessage("Conductor"),
086                    Bundle.getMessage("RouteLocationComment"),
087                    Bundle.getMessage("Description"),
088                    Bundle.getMessage("Comment"));
089
090            int count = 0; // number of trains that were exported
091
092            for (Train train : InstanceManager.getDefault(TrainManager.class).getTrainsByTimeList()) {
093                if (!train.isBuildEnabled() || !train.isBuilt() || train.getRoute() == null) {
094                    continue;
095                }
096                count++;
097                for (RouteLocation rl : train.getRoute().getLocationsBySequenceList()) {
098                    fileOut.printRecord(train.getName(),
099                            train.getLeadEngineRoadAndNumber(),
100                            rl.getLocation().getSplitName(),
101                            rl.getTrainDirectionString(),
102                            train.getExpectedArrivalTime(rl),
103                            train.getExpectedDepartureTime(rl),
104                            train.getNumberCarsPickedUp(rl),
105                            train.getNumberCarsSetout(rl),
106                            train.getNumberLoadedCarsInTrain(rl),
107                            train.getNumberEmptyCarsInTrain(rl),
108                            train.getTrainLength(rl),
109                            train.getTrainWeight(rl),
110                            "",
111                            "",
112                            rl.getComment(),
113                            train.getDescription(),
114                            train.getComment());
115                }
116                fileOut.println();
117            }
118
119            fileOut.flush();
120            fileOut.close();
121            log.info("Exported {} trains to file {}", count, defaultOperationsFilename());
122            JmriJOptionPane.showMessageDialog(null,
123                    Bundle.getMessage("ExportedTrainsToFile",
124                            count, defaultOperationsFilename()),
125                    Bundle.getMessage("ExportComplete"),
126                    JmriJOptionPane.INFORMATION_MESSAGE);
127
128        } catch (IOException e) {
129            log.error("Can not open export trains CSV file: {}", file.getName());
130            JmriJOptionPane.showMessageDialog(null,
131                    Bundle.getMessage("ExportedTrainsToFile",
132                            0, defaultOperationsFilename()),
133                    Bundle.getMessage("ExportFailed"),
134                    JmriJOptionPane.ERROR_MESSAGE);
135        }
136    }
137
138    // Operation files always use the same directory
139    public static String defaultOperationsFilename() {
140        return OperationsSetupXml.getFileLocation()
141                + OperationsSetupXml.getOperationsDirectoryName()
142                + File.separator
143                + getOperationsFileName();
144    }
145
146    public static void setOperationsFileName(String name) {
147        operationsFileName = name;
148    }
149
150    public static String getOperationsFileName() {
151        return operationsFileName;
152    }
153
154    private static String operationsFileName = "ExportOperationsTrainLineups.csv"; // NOI18N
155
156    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExportTrainLineups.class);
157
158}