001package jmri.jmrit.operations.rollingstock.cars.tools;
002
003import java.io.*;
004import java.nio.charset.StandardCharsets;
005import java.util.List;
006
007import org.apache.commons.csv.CSVFormat;
008import org.apache.commons.csv.CSVPrinter;
009
010import jmri.jmrit.XmlFile;
011import jmri.jmrit.operations.rollingstock.cars.Car;
012import jmri.jmrit.operations.setup.OperationsSetupXml;
013import jmri.jmrit.operations.setup.Setup;
014import jmri.util.swing.JmriJOptionPane;
015
016/**
017 * Exports the car roster into a comma delimited file (CSV).
018 *
019 * @author Daniel Boudreau Copyright (C) 2010, 2011, 2016, 2024
020 */
021public class ExportCars extends XmlFile {
022
023    protected static final String LOCATION_TRACK_SEPARATOR = "-";
024    List<Car> _carList;
025
026    public ExportCars(List<Car> carList) {
027        _carList = carList;
028    }
029
030    /**
031     * Create CSV file based on the car list.
032     */
033    public void writeOperationsCarFile() {
034        makeBackupFile(defaultOperationsFilename());
035        try {
036            if (!checkFile(defaultOperationsFilename())) {
037                // The file does not exist, create it before writing
038                java.io.File file = new java.io.File(defaultOperationsFilename());
039                java.io.File parentDir = file.getParentFile();
040                if (!parentDir.exists()) {
041                    if (!parentDir.mkdir()) {
042                        log.error("Directory wasn't created");
043                    }
044                }
045                if (file.createNewFile()) {
046                    log.debug("File created");
047                }
048            }
049            writeFile(defaultOperationsFilename());
050        } catch (IOException e) {
051            log.error("Exception while writing the new CSV operations file, may not be complete", e);
052        }
053    }
054
055    /**
056     * Any changes to the column order should also be made to the ImportCars.java
057     * file.
058     *
059     * @param name file name
060     */
061    private void writeFile(String name) {
062        log.debug("writeFile {}", name);
063        // This is taken in large part from "Java and XML" page 368
064        File file = findFile(name);
065        if (file == null) {
066            file = new File(name);
067        }
068
069        try (CSVPrinter fileOut = new CSVPrinter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)),
070                CSVFormat.DEFAULT)) {
071
072            // create header
073            fileOut.printRecord(Bundle.getMessage("Number"),
074                    Bundle.getMessage("Road"),
075                    Bundle.getMessage("Type"),
076                    Bundle.getMessage("Length"),
077                    Bundle.getMessage("Weight"),
078                    Bundle.getMessage("Color"),
079                    Bundle.getMessage("Owner"),
080                    Bundle.getMessage("Built"),
081                    Bundle.getMessage("Location"),
082                    LOCATION_TRACK_SEPARATOR,
083                    Bundle.getMessage("Track"),
084                    Bundle.getMessage("Load"),
085                    Bundle.getMessage("Kernel"),
086                    Bundle.getMessage("Moves"),
087                    Setup.getValueLabel(),
088                    Bundle.getMessage("Comment"),
089                    Bundle.getMessage("Miscellaneous"),
090                    Bundle.getMessage("Extensions"),
091                    Bundle.getMessage("Wait"),
092                    Bundle.getMessage("Pickup"),
093                    Bundle.getMessage("Last"),
094                    Bundle.getMessage("RWELocation"),
095                    LOCATION_TRACK_SEPARATOR,
096                    Bundle.getMessage("Track"),
097                    Bundle.getMessage("RWELoad"),
098                    Bundle.getMessage("RWLLocation"),
099                    LOCATION_TRACK_SEPARATOR,
100                    Bundle.getMessage("Track"),
101                    Bundle.getMessage("RWLLoad"),
102                    Bundle.getMessage("Division"),
103                    Bundle.getMessage("Train"),
104                    Bundle.getMessage("Destination"),
105                    LOCATION_TRACK_SEPARATOR,
106                    Bundle.getMessage("Track"),
107                    Bundle.getMessage("FinalDestination"),
108                    LOCATION_TRACK_SEPARATOR,
109                    Bundle.getMessage("Track"),
110                    Bundle.getMessage("SchId"),
111                    Bundle.getMessage( "RFID_Tag"));
112
113            // store car attributes
114            for (Car car : _carList) {
115                fileOut.printRecord(car.getNumber(),
116                        car.getRoadName(),
117                        car.getTypeName(),
118                        car.getLength(),
119                        car.getWeight(),
120                        car.getColor(),
121                        car.getOwnerName(),
122                        car.getBuilt(),
123                        car.getLocationName(),
124                        LOCATION_TRACK_SEPARATOR,
125                        car.getTrackName(),
126                        car.getLoadName(),
127                        car.getKernelName(),
128                        car.getMoves(),
129                        car.getValue(),
130                        car.getComment(),
131                        car.isOutOfService() ? Bundle.getMessage("OutOfService") : "",
132                        car.getTypeExtensions(),
133                        car.getWait(),
134                        car.getPickupScheduleName(),
135                        car.getLastDate(),
136                        car.getReturnWhenEmptyDestinationName(),
137                        LOCATION_TRACK_SEPARATOR,
138                        car.getReturnWhenEmptyDestTrackName(),
139                        car.getReturnWhenEmptyLoadName(),
140                        car.getReturnWhenLoadedDestinationName(),
141                        LOCATION_TRACK_SEPARATOR,
142                        car.getReturnWhenLoadedDestTrackName(),
143                        car.getReturnWhenLoadedLoadName(),
144                        car.getDivisionName(),
145                        car.getTrainName(),
146                        car.getDestinationName(),
147                        LOCATION_TRACK_SEPARATOR,
148                        car.getDestinationTrackName(),
149                        car.getFinalDestinationName(),
150                        LOCATION_TRACK_SEPARATOR,
151                        car.getFinalDestinationTrackName(),
152                        car.getScheduleItemId(),
153                        car.getRfid());
154            }
155            fileOut.flush();
156            fileOut.close();
157            log.info("Exported {} cars to file {}", _carList.size(), defaultOperationsFilename());
158            JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ExportedCarsToFile",
159                _carList.size(), defaultOperationsFilename()), Bundle.getMessage("ExportComplete"),
160                    JmriJOptionPane.INFORMATION_MESSAGE);
161        } catch (IOException e) {
162            log.error("Can not open export cars CSV file: {}", file.getName());
163            JmriJOptionPane.showMessageDialog(null,
164                    Bundle.getMessage("ExportedCarsToFile",
165                            0, defaultOperationsFilename()),
166                    Bundle.getMessage("ExportFailed"), JmriJOptionPane.ERROR_MESSAGE);
167        }
168    }
169
170    // Operation files always use the same directory
171    public static String defaultOperationsFilename() {
172        return OperationsSetupXml.getFileLocation()
173                + OperationsSetupXml.getOperationsDirectoryName()
174                + File.separator
175                + getOperationsFileName();
176    }
177
178    public static void setOperationsFileName(String name) {
179        operationsFileName = name;
180    }
181
182    public static String getOperationsFileName() {
183        return operationsFileName;
184    }
185
186    private static String operationsFileName = "ExportOperationsCarRoster.csv"; // NOI18N
187
188    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExportCars.class);
189
190}