001package jmri.jmrix.rps.swing;
002
003import java.awt.event.ActionEvent;
004import java.io.File;
005import java.io.FileOutputStream;
006import java.io.IOException;
007import java.io.OutputStreamWriter;
008import java.nio.charset.StandardCharsets;
009import java.util.ArrayList;
010import java.util.Arrays;
011import javax.swing.AbstractAction;
012import javax.swing.JFileChooser;
013import javax.swing.JFrame;
014import javax.swing.JMenuItem;
015import jmri.jmrix.rps.Distributor;
016import jmri.jmrix.rps.Reading;
017import jmri.jmrix.rps.ReadingListener;
018import jmri.jmrix.rps.RpsSystemConnectionMemo;
019import org.apache.commons.csv.CSVFormat;
020import org.apache.commons.csv.CSVPrinter;
021import org.slf4j.Logger;
022import org.slf4j.LoggerFactory;
023
024/**
025 * Action to export the incoming raw data to a CSV-format file.
026 *
027 * @author Bob Jacobsen Copyright (C) 2008
028 * @since 2.3.1
029 */
030public class CsvExportAction extends AbstractAction implements ReadingListener {
031
032    RpsSystemConnectionMemo memo = null;
033
034    public CsvExportAction(String actionName, RpsSystemConnectionMemo _memo) {
035        super(actionName);
036        memo = _memo;
037    }
038
039    public CsvExportAction(RpsSystemConnectionMemo _memo) {
040        this("Start CSV Export Reading...", _memo);
041    }
042
043    JFrame mParent;
044
045    boolean logging = false;
046    CSVPrinter str;
047    JFileChooser fileChooser;
048
049    @Override
050    public void actionPerformed(ActionEvent e) {
051        if (logging) {
052            stopLogging(e);
053        } else {
054            startLogging(e);
055        }
056    }
057
058    void stopLogging(ActionEvent e) {
059        Distributor.instance().removeReadingListener(this);
060
061        // reset menu item
062        ((JMenuItem) (e.getSource())).setText("Start CSV Export Reading...");
063
064        logging = false;
065
066        try {
067            str.flush();
068            str.close();
069        } catch (IOException ex) {
070            log.error("Error closing file: {}", ex);
071        }
072    }
073
074    void startLogging(ActionEvent e) {
075
076        log.debug("{}", e);
077        ((JMenuItem) (e.getSource())).setText("Stop CSV Export Reading...");
078
079        // initialize chooser
080        if (fileChooser == null) {
081            fileChooser = new jmri.util.swing.JmriJFileChooser();
082        } else {
083            fileChooser.rescanCurrentDirectory();
084        }
085
086        // get file
087        int retVal = fileChooser.showSaveDialog(mParent);
088
089        if (retVal == JFileChooser.APPROVE_OPTION) {
090            File file = fileChooser.getSelectedFile();
091            log.debug("start to log to file {}", file);
092
093            try {
094
095                str = new CSVPrinter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8), CSVFormat.DEFAULT);
096
097                Distributor.instance().addReadingListener(this);
098
099                logging = true;
100            } catch (IOException ex) {
101                log.error("Error opening file: {}", ex);
102            }
103        }
104    }
105
106    @Override
107    public void notify(Reading r) {
108        if (!logging || str == null) {
109            return;
110        }
111        ArrayList<Object> values = new ArrayList<>(r.getNValues() + 1);
112        values.add(r.getId());
113        values.addAll(Arrays.asList(r.getValues()));
114        try {
115            str.printRecord(values);
116        } catch (IOException ex) {
117            log.error("Error writing file: {}", ex);
118        }
119    }
120
121    private final static Logger log = LoggerFactory.getLogger(CsvExportAction.class);
122
123}