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
020 *
021 */
022public class ExportCars extends XmlFile {
023
024    protected static final String LOCATION_TRACK_SEPARATOR = "-";
025    List<Car> _carList;
026
027    public ExportCars(List<Car> carList) {
028        _carList = carList;
029    }
030
031    /**
032     * Create CSV file based on the car list.
033     */
034    public void writeOperationsCarFile() {
035        makeBackupFile(defaultOperationsFilename());
036        try {
037            if (!checkFile(defaultOperationsFilename())) {
038                // The file does not exist, create it before writing
039                java.io.File file = new java.io.File(defaultOperationsFilename());
040                java.io.File parentDir = file.getParentFile();
041                if (!parentDir.exists()) {
042                    if (!parentDir.mkdir()) {
043                        log.error("Directory wasn't created");
044                    }
045                }
046                if (file.createNewFile()) {
047                    log.debug("File created");
048                }
049            }
050            writeFile(defaultOperationsFilename());
051        } catch (IOException e) {
052            log.error("Exception while writing the new CSV operations file, may not be complete", e);
053        }
054    }
055
056    /**
057     * Any changes to the column order should also be made to the ImportCars.java
058     * file.
059     *
060     * @param name file name
061     */
062    private void writeFile(String name) {
063        log.debug("writeFile {}", name);
064        // This is taken in large part from "Java and XML" page 368
065        File file = findFile(name);
066        if (file == null) {
067            file = new File(name);
068        }
069
070        try (CSVPrinter fileOut = new CSVPrinter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)),
071                CSVFormat.DEFAULT)) {
072
073            // create header
074            fileOut.printRecord(Bundle.getMessage("Number"),
075                    Bundle.getMessage("Road"),
076                    Bundle.getMessage("Type"),
077                    Bundle.getMessage("Length"),
078                    Bundle.getMessage("Weight"),
079                    Bundle.getMessage("Color"),
080                    Bundle.getMessage("Owner"),
081                    Bundle.getMessage("Built"),
082                    Bundle.getMessage("Location"),
083                    LOCATION_TRACK_SEPARATOR,
084                    Bundle.getMessage("Track"),
085                    Bundle.getMessage("Load"),
086                    Bundle.getMessage("Kernel"),
087                    Bundle.getMessage("Moves"),
088                    Setup.getValueLabel(),
089                    Bundle.getMessage("Comment"),
090                    Bundle.getMessage("Miscellaneous"),
091                    Bundle.getMessage("Extensions"),
092                    Bundle.getMessage("Wait"),
093                    Bundle.getMessage("Pickup"),
094                    Bundle.getMessage("Last"),
095                    Bundle.getMessage("RWELocation"),
096                    LOCATION_TRACK_SEPARATOR,
097                    Bundle.getMessage("Track"),
098                    Bundle.getMessage("RWELoad"),
099                    Bundle.getMessage("RWLLocation"),
100                    LOCATION_TRACK_SEPARATOR,
101                    Bundle.getMessage("Track"),
102                    Bundle.getMessage("RWLLoad"),
103                    Bundle.getMessage("Division"),
104                    Bundle.getMessage("Train"),
105                    Bundle.getMessage("Destination"),
106                    LOCATION_TRACK_SEPARATOR,
107                    Bundle.getMessage("Track"),
108                    Bundle.getMessage("FinalDestination"),
109                    LOCATION_TRACK_SEPARATOR,
110                    Bundle.getMessage("Track"),
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.getDivision(),
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.getRfid());
153            }
154            fileOut.flush();
155            fileOut.close();
156            log.info("Exported {} cars to file {}", _carList.size(), defaultOperationsFilename());
157            JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ExportedCarsToFile",
158                _carList.size(), defaultOperationsFilename()), Bundle.getMessage("ExportComplete"),
159                    JmriJOptionPane.INFORMATION_MESSAGE);
160        } catch (IOException e) {
161            log.error("Can not open export cars CSV file: {}", file.getName());
162            JmriJOptionPane.showMessageDialog(null,
163                    Bundle.getMessage("ExportedCarsToFile",
164                            0, defaultOperationsFilename()),
165                    Bundle.getMessage("ExportFailed"), JmriJOptionPane.ERROR_MESSAGE);
166        }
167    }
168
169    // Operation files always use the same directory
170    public static String defaultOperationsFilename() {
171        return OperationsSetupXml.getFileLocation()
172                + OperationsSetupXml.getOperationsDirectoryName()
173                + File.separator
174                + getOperationsFileName();
175    }
176
177    public static void setOperationsFileName(String name) {
178        operationsFileName = name;
179    }
180
181    public static String getOperationsFileName() {
182        return operationsFileName;
183    }
184
185    private static String operationsFileName = "ExportOperationsCarRoster.csv"; // NOI18N
186
187    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExportCars.class);
188
189}