001package jmri.jmris;
002
003import java.io.File;
004import java.io.IOException;
005import java.util.prefs.BackingStoreException;
006import java.util.prefs.Preferences;
007import jmri.beans.Bean;
008import jmri.jmrit.XmlFile;
009import jmri.profile.ProfileManager;
010import jmri.profile.ProfileUtils;
011import jmri.util.FileUtil;
012import org.jdom2.Attribute;
013import org.jdom2.DataConversionException;
014import org.jdom2.Element;
015import org.jdom2.JDOMException;
016import org.slf4j.Logger;
017import org.slf4j.LoggerFactory;
018
019abstract public class AbstractServerPreferences extends Bean {
020
021    static final String XML_PREFS_ELEMENT = "AbstractServerPreferences"; // NOI18N
022    static final String PORT = "port"; // NOI18N
023    private int port;
024    // as loaded prefences
025    private int asLoadedPort;
026    private final static Logger log = LoggerFactory.getLogger(AbstractServerPreferences.class);
027
028    public AbstractServerPreferences(String fileName) {
029        boolean migrate = false;
030        Preferences sharedPreferences = ProfileUtils.getPreferences(ProfileManager.getDefault().getActiveProfile(), this.getClass(), true);
031        try {
032            if (sharedPreferences.keys().length == 0) {
033                log.info("No preferences exist.");
034                migrate = true;
035            }
036        } catch (BackingStoreException ex) {
037            log.info("No preferences file exists.");
038            migrate = true;
039        }
040        if (migrate) {
041            if (fileName != null) {
042                this.openFile(fileName);
043            } else {
044                migrate = false;
045            }
046        }
047        this.readPreferences(sharedPreferences);
048        if (migrate) {
049            try {
050                log.info("Migrating from old preferences in {} to new format in {}.", fileName, FileUtil.getAbsoluteFilename("profile:profile"));
051                sharedPreferences.sync();
052            } catch (BackingStoreException ex) {
053                log.error("Unable to write preferences.", ex);
054            }
055        }
056    }
057
058    public AbstractServerPreferences() {
059        Preferences sharedPreferences = ProfileUtils.getPreferences(ProfileManager.getDefault().getActiveProfile(), this.getClass(), true);
060        this.readPreferences(sharedPreferences);
061    }
062
063    protected void readPreferences(Preferences sharedPreferences) {
064        this.setPort(sharedPreferences.getInt(PORT, this.getDefaultPort()));
065        this.asLoadedPort = this.getPort();
066    }
067
068    public void load(Element child) {
069        Attribute a;
070        a = child.getAttribute(PORT);
071        if (a != null) {
072            try {
073                this.setPort(a.getIntValue());
074                this.asLoadedPort = this.getPort();
075            } catch (DataConversionException e) {
076                this.setPort(getDefaultPort());
077                log.error("Unable to read port. Setting to default value.", e);
078            }
079        }
080    }
081
082    public boolean compareValuesDifferent(AbstractServerPreferences prefs) {
083        return this.getPort() != prefs.getPort();
084    }
085
086    public void apply(AbstractServerPreferences prefs) {
087        this.setPort(prefs.getPort());
088    }
089
090    public Element store() {
091        Element prefs = new Element(XML_PREFS_ELEMENT);
092        prefs.setAttribute(PORT, Integer.toString(this.getPort()));
093        return prefs;
094    }
095    private String fileName;
096
097    public final void openFile(String fileName) {
098        this.fileName = fileName;
099        AbstractServerPreferencesXml prefsXml = new AbstractServerPreferences.AbstractServerPreferencesXml();
100        File file = new File(this.fileName);
101        Element root;
102        try {
103            root = prefsXml.rootFromFile(file);
104        } catch (java.io.FileNotFoundException ea) {
105            log.info("Could not find Server preferences file.  Normal if preferences have not been saved before.");
106            root = null;
107        } catch (IOException | JDOMException eb) {
108            log.error("Exception while loading server preferences: {}", eb.getLocalizedMessage());
109            root = null;
110        }
111        if (root != null) {
112            this.load(root);
113        }
114    }
115
116    public void save() {
117        Preferences sharedPreferences = ProfileUtils.getPreferences(ProfileManager.getDefault().getActiveProfile(), this.getClass(), true);
118        sharedPreferences.putInt(PORT, this.port);
119    }
120
121    public boolean isDirty() {
122        return (this.getPort() != this.asLoadedPort);
123    }
124
125    public boolean isRestartRequired() {
126        // return true only if the server port changes.
127        return (this.getPort() != this.asLoadedPort);
128    }
129
130    public int getPort() {
131        return this.port;
132    }
133
134    public void setPort(int value) {
135        this.port = value;
136    }
137
138    abstract public int getDefaultPort();
139
140    private static class AbstractServerPreferencesXml extends XmlFile {
141    }
142}