001package jmri.jmrit.symbolicprog;
002
003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
004
005import java.io.BufferedReader;
006import java.io.File;
007import java.io.FileReader;
008import java.io.IOException;
009import org.slf4j.Logger;
010import org.slf4j.LoggerFactory;
011
012/**
013 * Import CV values from a LokProgrammer CV list file written by the ESU
014 * LokProgrammer software.
015 * <hr>
016 * This file is part of JMRI.
017 * <p>
018 * JMRI is free software; you can redistribute it and/or modify it under the
019 * terms of version 2 of the GNU General Public License as published by the Free
020 * Software Foundation. See the "COPYING" file for a copy of this license.
021 * <p>
022 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
024 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
025 *
026 * @author Alex Shepherd Copyright (C) 2003
027 * @author Dave Heap Copyright (C) 2014
028 */
029public class LokProgImporter {
030
031    private static final Logger log = LoggerFactory.getLogger(LokProgImporter.class);
032    private static final String DECODER_PREFIX = "Decoder:";
033    private static final String CREATED_PREFIX = "Created:";
034    private static final String INDEX_PREFIX = "Index:";
035    private static final String INDEX_1 = "CV31=";
036    private static final String INDEX_1_TERMINATOR = ",";
037    private static final String INDEX_2 = "CV32=";
038    private static final String INDEX_2_TERMINATOR = ")";
039    private static final String CV_PREFIX = "CV ";
040    private static final String CV_SEPARATOR = " = ";
041    private static final String NOWARN_THESE_CVs = "(1\\.1\\.\\d+|1\\.0\\.2(58|59|60))";
042
043    @SuppressFBWarnings(value = "SBSC_USE_STRINGBUFFER_CONCATENATION",
044        justification = "string not kept between iterations, reduces object creation on each iteration")
045    public LokProgImporter(File file, CvTableModel cvModel) throws IOException {
046        FileReader fileReader = null;
047        BufferedReader bufferedReader = null;
048
049        try {
050            CvValue cvObject;
051            String cvIndex = "";
052            String line;
053            String name;
054            int value;
055
056            fileReader = new FileReader(file);
057            bufferedReader = new BufferedReader(fileReader);
058
059            while ((line = bufferedReader.readLine()) != null) {
060                if (line.startsWith(INDEX_PREFIX)) {
061                    cvIndex = line.substring(line.indexOf(INDEX_1) + INDEX_1.length(), line.indexOf(INDEX_1_TERMINATOR)) + ".";
062                    cvIndex = cvIndex + line.substring(line.indexOf(INDEX_2) + INDEX_2.length(), line.indexOf(INDEX_2_TERMINATOR)) + ".";
063                } else if (line.startsWith(CV_PREFIX) && line.regionMatches(6, CV_SEPARATOR, 0, 3)) {
064                    name = cvIndex + String.valueOf(Integer.parseInt(line.substring(3, 6)));
065                    value = Integer.parseInt(line.substring(9, 12));
066                    cvObject = cvModel.allCvMap().get(name);
067                    if (cvObject == null) {
068                        if (name.matches(NOWARN_THESE_CVs)) {
069                            log.debug("Skipping warning for added CV {}, not yet supported by JMRI", name);
070                        } else {
071                            log.warn("CV {} was in import file, but not defined by the decoder definition", name);
072                        }
073                        cvModel.addCV(name, false, false, false);
074                        cvObject = cvModel.allCvMap().get(name);
075                    }
076                    log.debug("Settting CV {} to {}", name, value);
077                    cvObject.setValue(value);
078                } else if (line.startsWith(DECODER_PREFIX) || line.startsWith(CREATED_PREFIX)) {
079                    log.info("Imorting CVs from file {}", line);
080                }
081            }
082        } catch (IOException e) {
083            log.error("Error reading file", e);
084        } finally {
085            if (bufferedReader != null) {
086                bufferedReader.close();
087            }
088            if (fileReader != null) {
089                fileReader.close();
090            }
091        }
092        log.info("Completed import from LokProgrammer CV List file");
093    }
094}