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 elem.setAttribute("time", clock.getStartTime().toString()); 041 elem.setAttribute("rate", "" + clock.userGetRate()); 042 elem.setAttribute("startrate", "" + clock.getStartRate()); 043 elem.setAttribute("run", (clock.getClockInitialRunState() == DO_START ? "yes" : "no")); 044 elem.setAttribute("master", (clock.getInternalMaster() ? "yes" : "no")); 045 if (!clock.getInternalMaster()) { 046 elem.setAttribute("mastername", clock.getMasterName()); 047 } 048 elem.setAttribute("sync", (clock.getSynchronize() ? "yes" : "no")); 049 elem.setAttribute("correct", (clock.getCorrectHardware() ? "yes" : "no")); 050 elem.setAttribute("display", (clock.use12HourDisplay() ? "yes" : "no")); 051 elem.setAttribute("startstopped", (clock.getClockInitialRunState() == DO_STOP ? "yes" : "no")); 052 elem.setAttribute("startrunning", ((clock.getClockInitialRunState() == DO_START) ? "yes" : "no")); 053 elem.setAttribute("startsettime", (clock.getStartSetTime() ? "yes" : "no")); 054 elem.setAttribute("startclockoption", Integer.toString( 055 clock.getStartClockOption())); 056 elem.setAttribute("showbutton", (clock.getShowStopButton() ? "yes" : "no")); 057 elem.setAttribute("startsetrate", (clock.getSetRateAtStart() ? "yes" : "no")); 058 059 return elem; 060 } 061 062 @Override 063 public boolean load(Element shared, Element perNode) { 064 boolean result = true; 065 Timebase clock = InstanceManager.getDefault(jmri.Timebase.class); 066 String val, val2; 067 if (shared.getAttribute("master") != null) { 068 val = shared.getAttributeValue("master"); 069 if (val.equals("yes")) { 070 clock.setInternalMaster(true, false); 071 } 072 if (val.equals("no")) { 073 clock.setInternalMaster(false, false); 074 if (shared.getAttribute("mastername") != null) { 075 clock.setMasterName(shared.getAttributeValue("mastername")); 076 } 077 } 078 } 079 if (shared.getAttribute("sync") != null) { 080 val = shared.getAttributeValue("sync"); 081 if (val.equals("yes")) { 082 clock.setSynchronize(true, false); 083 } 084 if (val.equals("no")) { 085 clock.setSynchronize(false, false); 086 } 087 } 088 if (shared.getAttribute("correct") != null) { 089 val = shared.getAttributeValue("correct"); 090 if (val.equals("yes")) { 091 clock.setCorrectHardware(true, false); 092 } 093 if (val.equals("no")) { 094 clock.setCorrectHardware(false, false); 095 } 096 } 097 if (shared.getAttribute("display") != null) { 098 val = shared.getAttributeValue("display"); 099 if (val.equals("yes")) { 100 clock.set12HourDisplay(true, false); 101 } 102 if (val.equals("no")) { 103 clock.set12HourDisplay(false, false); 104 } 105 } 106 if (shared.getAttribute("showbutton") != null) { 107 val = shared.getAttributeValue("showbutton"); 108 if (val.equals("yes")) { 109 clock.setShowStopButton(true); 110 } 111 if (val.equals("no")) { 112 clock.setShowStopButton(false); 113 } 114 } 115 if ("yes".equals(shared.getAttributeValue("startrunning"))) { 116 clock.setRun(true); 117 clock.setClockInitialRunState(DO_START); 118 } else if ("yes".equals(shared.getAttributeValue("startstopped"))) { 119 clock.setRun(false); 120 clock.setClockInitialRunState(DO_STOP); 121 } else if (shared.getAttribute("startrunning") != null){ 122 clock.setClockInitialRunState(DO_NOTHING); 123 } else { 124 // legacy XML 125 if (shared.getAttribute("run") != null) { 126 val = shared.getAttributeValue("run"); 127 if (val.equals("yes")) { 128 clock.setRun(true); 129 clock.setClockInitialRunState(DO_START); 130 } 131 if (val.equals("no")) { 132 clock.setRun(false); 133 clock.setClockInitialRunState(DO_STOP); 134 } 135 } 136 } 137 if (shared.getAttribute("startsetrate") != null) { 138 val = shared.getAttributeValue("startsetrate"); 139 clock.setSetRateAtStart(!val.equals("no")); 140 } 141 boolean hasRate = false; 142 if (shared.getAttribute("startrate") != null) { 143 try { 144 double r = shared.getAttribute("startrate").getDoubleValue(); 145 clock.setStartRate(r); 146 hasRate = true; 147 } catch (org.jdom2.DataConversionException e2) { 148 log.error("Cannot convert start rate", e2); 149 result = false; 150 } 151 } 152 if (!hasRate && shared.getAttribute("rate") != null) { 153 try { 154 double r = shared.getAttribute("rate").getDoubleValue(); 155 clock.setStartRate(r); 156 hasRate = true; 157 } catch (org.jdom2.DataConversionException e2) { 158 log.error("Cannot convert rate", e2); 159 result = false; 160 } 161 } 162 if (clock.getSetRateAtStart() && hasRate) { 163 try { 164 clock.userSetRate(clock.getStartRate()); 165 } catch (jmri.TimebaseRateException e1) { 166 log.error("Cannot restore rate: {}", clock.getStartRate(), e1); 167 result = false; 168 } 169 } 170 if (shared.getAttribute("startsettime") != null) { 171 val = shared.getAttributeValue("startsettime"); 172 if (val.equals("yes")) { 173 if (shared.getAttribute("time") != null) { 174 val2 = shared.getAttributeValue("time"); 175 try { 176 clock.setStartSetTime(true, format.parse(val2)); 177 clock.setTime(format.parse(val2)); 178 } catch (ParseException e) { 179 // if non-invertable date format, just skip 180 log.warn("Cannot set date using value stored in file: {}", val2); 181 result = false; 182 } 183 } 184 } else if (val.equals("no")) { 185 if (shared.getAttribute("time") != null) { 186 val2 = shared.getAttributeValue("time"); 187 try { 188 clock.setStartSetTime(false, format.parse(val2)); 189 } catch (ParseException e) { 190 // if non-invertable date format, just skip 191 log.warn("Cannot set date using value stored in file: {}", val2); 192 result = false; 193 } 194 } 195 } 196 } else if (shared.getAttribute("time") != null) { 197 // this only to preserve previous behavior for preexisting files 198 val2 = shared.getAttributeValue("time"); 199 try { 200 clock.setStartSetTime(true, format.parse(val2)); 201 clock.setTime(format.parse(val2)); 202 } catch (ParseException e) { 203 // if non-invertable date format, just skip 204 log.warn("Cannot set date using value stored in file: {}", val2); 205 result = false; 206 } 207 } 208 if (shared.getAttribute("startclockoption") != null) { 209 int option = Integer.parseInt(shared.getAttribute( 210 "startclockoption").getValue()); 211 clock.setStartClockOption(option); 212 clock.initializeClock(); 213 } 214 clock.initializeHardwareClock(); 215 return result; 216 } 217 218 // Conversion format for dates created by Java Date.toString(). 219 // The Locale needs to be always US, irrelevant from computer's and program's settings! 220 final SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); 221 222 @Override 223 public int loadOrder() { 224 return jmri.Manager.TIMEBASE; 225 } 226 227 private final static Logger log = LoggerFactory.getLogger(SimpleTimebaseXml.class); 228 229}