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