001package jmri.jmrit.simpleclock.configurexml; 002 003import java.text.ParseException; 004import java.text.SimpleDateFormat; 005import java.util.Locale; 006import jmri.InstanceManager; 007import jmri.Timebase; 008import org.jdom2.Element; 009import org.slf4j.Logger; 010import org.slf4j.LoggerFactory; 011 012import static jmri.Timebase.ClockInitialRunState.DO_NOTHING; 013import static jmri.Timebase.ClockInitialRunState.DO_START; 014import static jmri.Timebase.ClockInitialRunState.DO_STOP; 015 016/** 017 * Handle XML persistance of SimpleTimebase objects. 018 * 019 * @author Bob Jacobsen Copyright (c) 2003, 2008, 2017 020 */ 021public class SimpleTimebaseXml extends jmri.configurexml.AbstractXmlAdapter { 022 023 public SimpleTimebaseXml() { 024 } 025 026 /** 027 * Default implementation for storing the contents of a SimpleTimebase. 028 * 029 * @param o Object to start process, but not actually used 030 * @return Element containing the complete info 031 */ 032 @Override 033 public Element store(Object o) { 034 035 Timebase clock = InstanceManager.getDefault(jmri.Timebase.class); 036 037 Element elem = new Element("timebase"); 038 elem.setAttribute("class", this.getClass().getName()); 039 040 var loadAndStorePreferences = InstanceManager.getDefault(jmri.configurexml.LoadAndStorePreferences.class); 041 if (! loadAndStorePreferences.isExcludeTimebase() ) { 042 elem.setAttribute("time", clock.getStartTime().toString()); 043 } 044 045 elem.setAttribute("rate", "" + clock.userGetRate()); 046 elem.setAttribute("startrate", "" + clock.getStartRate()); 047 elem.setAttribute("run", (clock.getClockInitialRunState() == DO_START ? "yes" : "no")); 048 elem.setAttribute("master", (clock.getInternalMaster() ? "yes" : "no")); 049 if (!clock.getInternalMaster()) { 050 elem.setAttribute("mastername", clock.getMasterName()); 051 } 052 elem.setAttribute("sync", (clock.getSynchronize() ? "yes" : "no")); 053 elem.setAttribute("correct", (clock.getCorrectHardware() ? "yes" : "no")); 054 elem.setAttribute("display", (clock.use12HourDisplay() ? "yes" : "no")); 055 elem.setAttribute("startstopped", (clock.getClockInitialRunState() == DO_STOP ? "yes" : "no")); 056 elem.setAttribute("startrunning", ((clock.getClockInitialRunState() == DO_START) ? "yes" : "no")); 057 elem.setAttribute("startsettime", (clock.getStartSetTime() ? "yes" : "no")); 058 elem.setAttribute("startclockoption", Integer.toString( 059 clock.getStartClockOption())); 060 elem.setAttribute("showbutton", (clock.getShowStopButton() ? "yes" : "no")); 061 elem.setAttribute("startsetrate", (clock.getSetRateAtStart() ? "yes" : "no")); 062 063 return elem; 064 } 065 066 @Override 067 public boolean load(Element shared, Element perNode) { 068 boolean result = true; 069 Timebase clock = InstanceManager.getDefault(jmri.Timebase.class); 070 String val, val2; 071 if (shared.getAttribute("master") != null) { 072 val = shared.getAttributeValue("master"); 073 if (val.equals("yes")) { 074 clock.setInternalMaster(true, false); 075 } 076 if (val.equals("no")) { 077 clock.setInternalMaster(false, false); 078 if (shared.getAttribute("mastername") != null) { 079 clock.setMasterName(shared.getAttributeValue("mastername")); 080 } 081 } 082 } 083 if (shared.getAttribute("sync") != null) { 084 val = shared.getAttributeValue("sync"); 085 if (val.equals("yes")) { 086 clock.setSynchronize(true, false); 087 } 088 if (val.equals("no")) { 089 clock.setSynchronize(false, false); 090 } 091 } 092 if (shared.getAttribute("correct") != null) { 093 val = shared.getAttributeValue("correct"); 094 if (val.equals("yes")) { 095 clock.setCorrectHardware(true, false); 096 } 097 if (val.equals("no")) { 098 clock.setCorrectHardware(false, false); 099 } 100 } 101 if (shared.getAttribute("display") != null) { 102 val = shared.getAttributeValue("display"); 103 if (val.equals("yes")) { 104 clock.set12HourDisplay(true, false); 105 } 106 if (val.equals("no")) { 107 clock.set12HourDisplay(false, false); 108 } 109 } 110 if (shared.getAttribute("showbutton") != null) { 111 val = shared.getAttributeValue("showbutton"); 112 if (val.equals("yes")) { 113 clock.setShowStopButton(true); 114 } 115 if (val.equals("no")) { 116 clock.setShowStopButton(false); 117 } 118 } 119 if ("yes".equals(shared.getAttributeValue("startrunning"))) { 120 clock.setRun(true); 121 clock.setClockInitialRunState(DO_START); 122 } else if ("yes".equals(shared.getAttributeValue("startstopped"))) { 123 clock.setRun(false); 124 clock.setClockInitialRunState(DO_STOP); 125 } else if (shared.getAttribute("startrunning") != null){ 126 clock.setClockInitialRunState(DO_NOTHING); 127 } else { 128 // legacy XML 129 if (shared.getAttribute("run") != null) { 130 val = shared.getAttributeValue("run"); 131 if (val.equals("yes")) { 132 clock.setRun(true); 133 clock.setClockInitialRunState(DO_START); 134 } 135 if (val.equals("no")) { 136 clock.setRun(false); 137 clock.setClockInitialRunState(DO_STOP); 138 } 139 } 140 } 141 if (shared.getAttribute("startsetrate") != null) { 142 val = shared.getAttributeValue("startsetrate"); 143 clock.setSetRateAtStart(!val.equals("no")); 144 } 145 boolean hasRate = false; 146 if (shared.getAttribute("startrate") != null) { 147 try { 148 double r = shared.getAttribute("startrate").getDoubleValue(); 149 clock.setStartRate(r); 150 hasRate = true; 151 } catch (org.jdom2.DataConversionException e2) { 152 log.error("Cannot convert start rate", e2); 153 result = false; 154 } 155 } 156 if (!hasRate && shared.getAttribute("rate") != null) { 157 try { 158 double r = shared.getAttribute("rate").getDoubleValue(); 159 clock.setStartRate(r); 160 hasRate = true; 161 } catch (org.jdom2.DataConversionException e2) { 162 log.error("Cannot convert rate", e2); 163 result = false; 164 } 165 } 166 if (clock.getSetRateAtStart() && hasRate) { 167 try { 168 clock.userSetRate(clock.getStartRate()); 169 } catch (jmri.TimebaseRateException e1) { 170 log.error("Cannot restore rate: {}", clock.getStartRate(), e1); 171 result = false; 172 } 173 } 174 if (shared.getAttribute("startsettime") != null) { 175 val = shared.getAttributeValue("startsettime"); 176 if (val.equals("yes")) { 177 if (shared.getAttribute("time") != null) { 178 val2 = shared.getAttributeValue("time"); 179 try { 180 clock.setStartSetTime(true, format.parse(val2)); 181 clock.setTime(format.parse(val2)); 182 } catch (ParseException e) { 183 // if non-invertable date format, just skip 184 log.warn("Cannot set date using value stored in file: {}", val2); 185 result = false; 186 } 187 } 188 } else if (val.equals("no")) { 189 if (shared.getAttribute("time") != null) { 190 val2 = shared.getAttributeValue("time"); 191 try { 192 clock.setStartSetTime(false, format.parse(val2)); 193 } catch (ParseException e) { 194 // if non-invertable date format, just skip 195 log.warn("Cannot set date using value stored in file: {}", val2); 196 result = false; 197 } 198 } 199 } 200 } else if (shared.getAttribute("time") != null) { 201 // this only to preserve previous behavior for preexisting files 202 val2 = shared.getAttributeValue("time"); 203 try { 204 clock.setStartSetTime(true, format.parse(val2)); 205 clock.setTime(format.parse(val2)); 206 } catch (ParseException e) { 207 // if non-invertable date format, just skip 208 log.warn("Cannot set date using value stored in file: {}", val2); 209 result = false; 210 } 211 } 212 if (shared.getAttribute("startclockoption") != null) { 213 int option = Integer.parseInt(shared.getAttribute( 214 "startclockoption").getValue()); 215 clock.setStartClockOption(option); 216 clock.initializeClock(); 217 } 218 clock.initializeHardwareClock(); 219 return result; 220 } 221 222 // Conversion format for dates created by Java Date.toString(). 223 // The Locale needs to be always US, irrelevant from computer's and program's settings! 224 final SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); 225 226 @Override 227 public int loadOrder() { 228 return jmri.Manager.TIMEBASE; 229 } 230 231 private final static Logger log = LoggerFactory.getLogger(SimpleTimebaseXml.class); 232 233}