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