001package jmri.jmrix.can.cbus.eventtable; 002 003import java.io.File; 004import java.io.IOException; 005import java.text.SimpleDateFormat; 006import java.util.Date; 007import jmri.util.FileUtil; 008import org.jdom2.Document; 009import org.jdom2.Element; 010import org.jdom2.JDOMException; 011import org.slf4j.Logger; 012import org.slf4j.LoggerFactory; 013 014/** 015 * Save / Load routines for the EventTableData.xml file. 016 * @author Steve Young Copyright (C) 2019 017 */ 018public class CbusEventTableXmlAction { 019 020 protected static SimpleDateFormat getXmlDateStyle() { 021 return new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 022 } 023 024 // if a CBUS Event xml file is found 025 // import table data into it 026 protected static void restoreEventsFromXmlTablestart(CbusEventTableDataModel model) { 027 log.debug("restore events from conn {}",model._memo); 028 CbusEventTableXmlFile x = new CbusEventTableXmlFile(model._memo); 029 File file = x.getFile(false); 030 if (file == null) { 031 return; 032 } 033 034 try { 035 Element root = x.rootFromFile(file); 036 root.getChildren("Event").forEach((xmlEvent) -> addSingleEventToModel(xmlEvent, model)); 037 model.fireTableDataChanged(); 038 FileUtil.rotate(file, 10, "bup"); // NOI18N 039 040 } catch (JDOMException | IOException ex) { 041 log.error("File Error", ex); // NOI18N 042 } 043 } 044 045 private static void addSingleEventToModel(Element xmlEvent, CbusEventTableDataModel model) { 046 047 if (xmlEvent.getAttribute("NodeNum") == null || xmlEvent.getAttribute("EventNum") == null ) { // NOI18N 048 log.error("Node or event number missing in event {}", xmlEvent.getAttributes() ); 049 } else try { 050 051 CbusTableEvent tabEv = model.provideEvent( 052 Integer.parseInt( xmlEvent.getAttribute("NodeNum").getValue() ), 053 Integer.parseInt( xmlEvent.getAttribute("EventNum").getValue() )); // NOI18N 054 055 if (xmlEvent.getChild("Name") != null ) { // NOI18N 056 tabEv.setName( xmlEvent.getChild("Name").getValue() ); // NOI18N 057 } 058 if (xmlEvent.getChild("Comment") != null ) { // NOI18N 059 tabEv.setComment( xmlEvent.getChild("Comment").getValue() ); // NOI18N 060 } 061 062 setEventDate(xmlEvent.getChild("LastHeard"), tabEv); // NOI18N 063 064 tabEv.setCounts(getChild(xmlEvent, "On"), getChild(xmlEvent, "Off"), 065 getChild(xmlEvent, "In"), getChild(xmlEvent, "Out")); // NOI18N 066 067 } catch (java.lang.NumberFormatException ex) { 068 log.error("Incorrect value in event {}", xmlEvent.getAttributes()); // NOI18N 069 } 070 071 } 072 073 private static void setEventDate(Element element, CbusTableEvent tabEv){ 074 if ( element != null ) { // NOI18N 075 try { 076 Date newDate = getXmlDateStyle().parse(element.getValue()); // NOI18N 077 tabEv.setDate( newDate ); 078 } catch (java.text.ParseException e) { 079 log.error("Unable to parse date {}", element.getValue()); // NOI18N 080 } 081 } 082 } 083 084 private static int getChild(Element element, String child){ 085 if (element.getChild(child) != null ) { // NOI18N 086 return ( Integer.parseInt( element.getChild(child).getValue() ) ); // NOI18N 087 } 088 return 0; 089 } 090 091 /** 092 * Saves table event data to the EventTableData.xml file. 093 * @param model Table Model to save. 094 */ 095 protected static void storeEventsToXml(CbusEventTableDataModel model) { 096 layoutEventsToXml(model); 097 } 098 099 private static void layoutEventsToXml(CbusEventTableDataModel model) { 100 101 log.info("Saving {} CBUS Event xml file.", model._memo.getUserName() ); // NOI18N 102 CbusEventTableXmlFile x = new CbusEventTableXmlFile(model._memo); 103 104 Element root = new Element("CbusEventDetails"); // NOI18N 105 root.setAttribute("noNamespaceSchemaLocation", // NOI18N 106 "https://raw.githubusercontent.com/MERG-DEV/JMRI/master/schema/MergCBUSEventTable.xsd", // NOI18N 107 org.jdom2.Namespace.getNamespace("xsi", 108 "http://www.w3.org/2001/XMLSchema-instance")); // NOI18N 109 110 model.getEvents().forEach((event) -> addSingleEventToXml(event, root)); 111 112 try { 113 x.writeXML(x.getFile(true), new Document(root)); 114 } catch ( IOException ex) { 115 log.error("File Error while writing", ex); // NOI18N 116 } 117 } 118 119 private static void addSingleEventToXml(CbusTableEvent event, Element root){ 120 121 Element values = new Element("Event"); // NOI18N 122 root.addContent(values); 123 values.setAttribute("NodeNum", "" + event.getNn() ); // NOI18N 124 values.setAttribute("EventNum", "" + event.getEn() ); // NOI18N 125 if ( !event.getName().isEmpty() ){ 126 values.addContent(new Element("Name").addContent("" + event.getName() )); // NOI18N 127 } 128 if ( !event.getComment().isEmpty() ){ 129 values.addContent(new Element("Comment").addContent("" + event.getComment() )); // NOI18N 130 } 131 if ( event.getDate() != null ){ 132 values.addContent(new Element("LastHeard").addContent( 133 "" + getXmlDateStyle().format( event.getDate() ) )); // NOI18N 134 } 135 136 addIntContent(event.getTotalOnOff(true), "On", values); // NOI18N 137 addIntContent(event.getTotalOnOff(false), "Off", values); // NOI18N 138 addIntContent(event.getTotalInOut(true), "In", values); // NOI18N 139 addIntContent(event.getTotalInOut(false), "Out", values); // NOI18N 140 141 } 142 143 private static void addIntContent(int val, String name, Element values){ 144 if (val > 0) { 145 values.addContent(new Element(name).addContent("" + val )); // NOI18N 146 } 147 } 148 149 private final static Logger log = LoggerFactory.getLogger(CbusEventTableXmlAction.class); 150 151}