001package jmri.jmrix.loconet.loconetovertcp;
002
003import java.io.File;
004import java.io.FileInputStream;
005import java.io.FileNotFoundException;
006import java.io.IOException;
007import java.util.Properties;
008import java.util.prefs.BackingStoreException;
009import java.util.prefs.Preferences;
010import jmri.InstanceManager;
011import jmri.beans.PreferencesBean;
012import jmri.profile.ProfileManager;
013import jmri.profile.ProfileUtils;
014import jmri.util.FileUtil;
015import org.slf4j.Logger;
016import org.slf4j.LoggerFactory;
017
018/**
019 * Preferences for the LocoNet over TCP server.
020 *
021 * @author Randall Wood (C) 2017
022 */
023public class LnTcpPreferences extends PreferencesBean {
024
025    public final static String PORT = jmri.web.server.WebServerPreferences.PORT;
026    private static final String PORT_NUMBER_KEY = "PortNumber";
027    private static final String SETTINGS_FILE_NAME = "LocoNetOverTcpSettings.ini";
028
029    public static LnTcpPreferences getDefault() {
030        return InstanceManager.getOptionalDefault(LnTcpPreferences.class).orElseGet(() -> {
031            return InstanceManager.setDefault(LnTcpPreferences.class, new LnTcpPreferences());
032        });
033    }
034
035    private int port = 1234;
036    private final static Logger log = LoggerFactory.getLogger(LnTcpPreferences.class);
037
038    public LnTcpPreferences() {
039        super(ProfileManager.getDefault().getActiveProfile());
040        Preferences sharedPreferences = ProfileUtils.getPreferences(super.getProfile(), this.getClass(), true);
041        this.readPreferences(sharedPreferences);
042    }
043
044    private void readPreferences(Preferences sharedPreferences) {
045        boolean migrate = false;
046        try {
047            if (sharedPreferences.keys().length == 0) {
048                log.debug("No LocoNetOverTCP preferences exist.");
049                migrate = true;
050            }
051        } catch (BackingStoreException ex) {
052            log.debug("No preferences file exists.");
053            migrate = true;
054        }
055        if (!migrate) {
056            this.port = sharedPreferences.getInt(PORT, this.getPort());
057            this.setIsDirty(false);
058        } else {
059            Properties settings = new Properties();
060            File file = new File(FileUtil.getUserFilesPath(), SETTINGS_FILE_NAME);
061            log.debug("Opening settings file {}", file);
062            try (FileInputStream stream = new FileInputStream(file)) {
063                settings.load(stream);
064                this.port = Integer.parseInt(settings.getProperty(PORT_NUMBER_KEY, Integer.toString(this.getPort())));
065                this.setIsDirty(true);
066            } catch (FileNotFoundException ex) {
067                log.debug("old preferences file not found");
068            } catch (IOException ex) {
069                log.debug("exception reading old preferences file", ex);
070            }
071        }
072    }
073
074    public void savePreferences() {
075        Preferences sharedPreferences = ProfileUtils.getPreferences(this.getProfile(), this.getClass(), true);
076        sharedPreferences.putInt(PORT, this.getPort());
077        try {
078            sharedPreferences.sync();
079            setIsDirty(false);  //  Resets only when stored
080        } catch (BackingStoreException ex) {
081            log.error("Exception while saving web server preferences", ex);
082        }
083    }
084
085    boolean isPreferencesValid() {
086        return this.port > 0 && this.port < 65536;
087    }
088
089    /**
090     * Get the port used by the LocoNetOverTCP server.
091     *
092     * @return the port
093     */
094    public int getPort() {
095        return port;
096    }
097
098    /**
099     * Set the port used by the LocoNetOverTCP server.
100     *
101     * @param value the port
102     */
103    public void setPort(int value) {
104        int old = this.port;
105        if (old != value) {
106            this.port = value;
107            this.firePropertyChange(PORT, old, value);
108            this.setRestartRequired();
109        }
110    }
111
112}