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}