001package jmri.managers.configurexml; 002 003import java.io.File; 004import java.io.FileNotFoundException; 005import java.io.IOException; 006import java.util.List; 007 008import org.jdom2.Document; 009import org.jdom2.Element; 010import org.jdom2.JDOMException; 011import org.jdom2.ProcessingInstruction; 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014 015import jmri.Application; 016import jmri.IdTag; 017import jmri.IdTagManager; 018import jmri.jmrit.XmlFile; 019import jmri.util.FileUtil; 020 021/** 022 * Concrete implementation of abstract {@link jmri.jmrit.XmlFile} for 023 * the {@link jmri.managers.DefaultIdTagManager}. 024 * 025 * @author Bob Jacobsen Copyright (C) 2010 026 * @author Matthew Harris Copyright (C) 2011 027 * @since 2.11.4 028 */ 029public class DefaultIdTagManagerXml extends XmlFile { 030 031 private final IdTagManager manager; 032 033 public DefaultIdTagManagerXml(IdTagManager tagMan, String baseFileName){ 034 manager = tagMan; 035 IDTAG_BASE_FILENAME = baseFileName; 036 } 037 038 public void store() throws java.io.IOException { 039 log.debug("Storing..."); 040 log.debug("Using file: {}", getDefaultIdTagFileName()); 041 createFile(getDefaultIdTagFileName(), true); 042 try { 043 writeFile(getDefaultIdTagFileName()); 044 } catch (FileNotFoundException ex) { 045 log.error("File not found while writing IdTag file, may not be complete", ex); 046 } 047 } 048 049 public void load() { 050 log.debug("Loading..."); 051 try { 052 readFile(getDefaultIdTagFileName()); 053 } catch (JDOMException | IOException ex) { 054 log.error("Exception during IdTag file reading", ex); 055 } 056 } 057 058 private File createFile(String fileName, boolean backup) { 059 if (backup) { 060 makeBackupFile(fileName); 061 } 062 063 File file = null; 064 try { 065 if (!checkFile(fileName)) { 066 // The file does not exist, create it before writing 067 file = new File(fileName); 068 File parentDir = file.getParentFile(); 069 if (!parentDir.exists()) { 070 if (!parentDir.mkdir()) { 071 log.error("Directory wasn't created"); 072 } 073 } 074 if (file.createNewFile()) { 075 log.debug("New file created"); 076 } 077 } else { 078 file = new File(fileName); 079 } 080 } catch (java.io.IOException ex) { 081 log.error("Exception while creating IdTag file, may not be complete", (Object) ex); 082 } 083 return file; 084 } 085 086 private void writeFile(String fileName) throws FileNotFoundException, java.io.IOException { 087 log.debug("writeFile {}", fileName); 088 // This is taken in large part from "Java and XML" page 368 089 File file = findFile(fileName); 090 if (file == null) { 091 file = new File(fileName); 092 } 093 // Create root element 094 Element root = new Element("idtagtable"); // NOI18N 095 root.setAttribute("noNamespaceSchemaLocation", // NOI18N 096 "http://jmri.org/xml/schema/idtags.xsd", // NOI18N 097 org.jdom2.Namespace.getNamespace("xsi", // NOI18N 098 "http://www.w3.org/2001/XMLSchema-instance")); // NOI18N 099 Document doc = newDocument(root); 100 101 // add XSLT processing instruction 102 java.util.Map<String, String> m = new java.util.HashMap<>(); 103 m.put("type", "text/xsl"); // NOI18N 104 m.put("href", xsltLocation + "idtags.xsl"); // NOI18N 105 ProcessingInstruction p = new ProcessingInstruction("xml-stylesheet", m); // NOI18N 106 doc.addContent(0, p); 107 108 Element values; 109 110 // Store configuration 111 root.addContent(values = new Element("configuration")); // NOI18N 112 values.addContent(new Element("storeState").addContent(manager.isStateStored() ? "yes" : "no")); // NOI18N 113 values.addContent(new Element("useFastClock").addContent(manager.isFastClockUsed() ? "yes" : "no")); // NOI18N 114 115 // Loop through RfidTags 116 root.addContent(values = new Element("idtags")); // NOI18N 117 for (IdTag t : manager.getNamedBeanSet()) { 118 log.debug("Writing IdTag: {}", t.getSystemName()); 119 values.addContent(t.store(manager.isStateStored())); 120 } 121 writeXML(file, doc); 122 } 123 124 private void readFile(String fileName) throws org.jdom2.JDOMException, java.io.IOException, IllegalArgumentException { 125 // Check file exists 126 if (findFile(fileName) == null) { 127 log.debug("{} file could not be found", fileName); 128 return; 129 } 130 131 // Find root 132 Element root = rootFromName(fileName); 133 if (root == null) { 134 log.debug("{} file could not be read", fileName); 135 return; 136 } 137 138 // First read configuration 139 if (root.getChild("configuration") != null) { // NOI18N 140 List<Element> l = root.getChild("configuration").getChildren(); // NOI18N 141 log.debug("readFile sees {} configurations", l.size()); 142 for (Element e : l) { 143 log.debug("Configuration {} value {}", e.getName(), e.getValue()); 144 if (e.getName().equals("storeState")) { // NOI18N 145 manager.setStateStored(e.getValue().equals("yes")); // NOI18N 146 } 147 if (e.getName().equals("useFastClock")) { // NOI18N 148 manager.setFastClockUsed(e.getValue().equals("yes")); // NOI18N 149 } 150 } 151 } 152 153 // Now read tag information 154 if (root.getChild("idtags") != null) { // NOI18N 155 List<Element> l = root.getChild("idtags").getChildren("idtag"); // NOI18N 156 log.debug("readFile sees {} idtags", l.size()); 157 for (Element e : l) { 158 String systemName = e.getChild("systemName").getText(); // NOI18N 159 try { 160 IdTag t = manager.provideIdTag(systemName); 161 t.load(e); 162 } catch (jmri.NamedBean.BadSystemNameException ex) { 163 log.error("Could not create tag from ({}) during loading, ignored", systemName); 164 } 165 } 166 } 167 } 168 169 public String getDefaultIdTagFileName() { 170 return getFileLocation() + getIdTagDirectoryName() + File.separator + getIdTagFileName(); 171 } 172 173 private static final String IDTAG_DIRECTORY_NAME = "idtags"; // NOI18N 174 175 public String getIdTagDirectoryName() { 176 return IDTAG_DIRECTORY_NAME; 177 } 178 179 private String IDTAG_BASE_FILENAME = "IdTags.xml"; // NOI18N 180 181 public String getIdTagFileName() { 182 String appName = Application.getApplicationName(); 183 if (appName.equals("LccPro")) appName = "PanelPro"; 184 String retval = appName + IDTAG_BASE_FILENAME; 185 // as a special case, the LccPro application uses 186 // the PanelPro id tag files 187 jmri.util.LoggingUtil.infoOnce(log, "Using "+retval+" for tag storage"); 188 return retval; 189 } 190 191 /** 192 * Absolute path to location of IdTag files. 193 * 194 * @return path to location 195 */ 196 public String getFileLocation() { 197 return FILE_LOCATION; 198 } 199 200 private final String FILE_LOCATION = FileUtil.getUserFilesPath(); 201 202 private final Logger log = LoggerFactory.getLogger(DefaultIdTagManagerXml.class); 203 204}