001package jmri.configurexml; 002 003import java.io.File; 004import java.io.FileNotFoundException; 005import java.io.IOException; 006import jmri.jmrit.XmlFile; 007import jmri.util.FileUtil; 008import org.jdom2.Document; 009import org.jdom2.Element; 010import org.jdom2.JDOMException; 011 012/** 013 * Load and store scale xml data files. 014 * <p> 015 * Custom changes to scale information result in the scale data being stored 016 * at the user files location. Subsequent scale data loading uses the custom 017 * data file. The default scale data file is part of the JMRI distribution. 018 * @author Dave Sand Copyright (C) 2018 019 * @since 4.13.6 020 */ 021public class ScaleConfigXML { 022 023 public static boolean doStore() { 024 ScaleXmlFile x = new ScaleXmlFile(); 025 File file = x.getStoreFile(); 026 if (file == null) { 027 log.warn("Unable to create local scale file"); 028 return false; 029 } 030 031 // Create root element 032 Element root = new Element("scale-data"); // NOI18N 033 root.setAttribute("noNamespaceSchemaLocation", // NOI18N 034 "http://jmri.org/xml/schema/scale.xsd", // NOI18N 035 org.jdom2.Namespace.getNamespace("xsi", 036 "http://www.w3.org/2001/XMLSchema-instance")); // NOI18N 037 Document doc = new Document(root); 038 Element values; 039 040 root.addContent(values = new Element("scales")); // NOI18N 041 for (jmri.Scale scale : jmri.ScaleManager.getScales()) { 042 Element e = new Element("scale"); // NOI18N 043 e.addContent(new Element("scale_name").addContent(scale.getScaleName())); // NOI18N 044 e.addContent(new Element("user_name").addContent(scale.getUserName())); // NOI18N 045 e.addContent(new Element("scale_ratio").addContent(Double.toString(scale.getScaleRatio()))); // NOI18N 046 values.addContent(e); 047 } 048 049 try { 050 x.writeXML(file, doc); 051 } catch (FileNotFoundException ex) { 052 log.error("File not found when writing", ex); // NOI18N 053 return false; 054 } catch (IOException ex) { 055 log.error("IO Exception when writing", ex); // NOI18N 056 return false; 057 } 058 059 return true; 060 } 061 062 public static boolean doLoad() { 063 ScaleXmlFile x = new ScaleXmlFile(); 064 File file = x.getLoadFile(); 065 066 // Find root 067 Element root; 068 try { 069 root = x.rootFromFile(file); 070 if (root == null) { 071 log.debug("File could not be read"); // NOI18N 072 return false; 073 } 074 075 Element scales = root.getChild("scales"); // NOI18N 076 if (scales == null) { 077 log.error("Unable to find a scale entry"); // NOI18N 078 return false; 079 } 080 for (Element scale : scales.getChildren("scale")) { // NOI18N 081 Element scale_name = scale.getChild("scale_name"); // NOI18N 082 String scaleName = (scale_name == null) ? "" : scale_name.getValue(); 083 Element user_name = scale.getChild("user_name"); // NOI18N 084 String userName = (user_name == null) ? "" : user_name.getValue(); 085 Element scale_ratio = scale.getChild("scale_ratio"); // NOI18N 086 double scaleRatio = (scale_ratio == null) ? 1.0 : Double.parseDouble(scale_ratio.getValue()); 087 088 jmri.ScaleManager.addScale(scaleName, userName, scaleRatio); 089 } 090 091 } catch (JDOMException ex) { 092 log.error("File invalid", ex); // NOI18N 093 return false; 094 } catch (IOException ex) { 095 log.error("Error reading file", ex); // NOI18N 096 return false; 097 } 098 099 return true; 100 } 101 102 private static class ScaleXmlFile extends XmlFile { 103 private static String prodPath = FileUtil.getProgramPath() + "resources/scales/"; // NOI18N 104 private static String userPath = FileUtil.getUserFilesPath() + "resources/scales/"; // NOI18N 105 private static String fileName = "ScaleData.xml"; // NOI18N 106 107 public static String getStoreFileName() { 108 return userPath + fileName; 109 } 110 111 public File getStoreFile() { 112 File chkdir = new File(userPath); 113 if (!chkdir.exists()) { 114 if (!chkdir.mkdirs()) { 115 return null; 116 } 117 } 118 File file = findFile(getStoreFileName()); 119 if (file == null) { 120 log.info("Create new scale file"); // NOI18N 121 file = new File(getStoreFileName()); 122 } else { 123 try { 124 FileUtil.rotate(file, 4, "bup"); // NOI18N 125 } catch (IOException ex) { 126 log.warn("Rotate failed, reverting to xml backup"); // NOI18N 127 makeBackupFile(getStoreFileName()); 128 } 129 } 130 return file; 131 } 132 133 public File getLoadFile() { 134 File file = findFile(userPath + fileName); 135 if (file == null) { 136 file = findFile(prodPath + fileName); 137 } 138 return file; 139 } 140 } 141 142 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScaleConfigXML.class); 143}