001package jmri.jmrit.operations; 002 003import java.io.*; 004 005import org.jdom2.JDOMException; 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009import jmri.InstanceManager; 010import jmri.jmrit.XmlFile; 011import jmri.jmrit.operations.locations.LocationManagerXml; 012import jmri.jmrit.operations.rollingstock.cars.CarManagerXml; 013import jmri.jmrit.operations.rollingstock.engines.EngineManagerXml; 014import jmri.jmrit.operations.routes.RouteManagerXml; 015import jmri.jmrit.operations.setup.OperationsSetupXml; 016import jmri.jmrit.operations.trains.TrainManagerXml; 017import jmri.util.FileUtil; 018 019/** 020 * Loads and stores the operation setup using xml files. 021 * 022 * @author Daniel Boudreau Copyright (C) 2008 023 */ 024public abstract class OperationsXml extends XmlFile { 025 026 /** 027 * Store the all of the operation train objects in the default place, 028 * including making a backup if needed 029 */ 030 public void writeOperationsFile() { 031 createFile(getDefaultOperationsFilename(), true); // make backup 032 try { 033 writeFile(getDefaultOperationsFilename()); 034 } catch (IOException e) { 035 log.error("Exception while writing operation file, may not be complete: {}", e.getLocalizedMessage()); 036 } 037 } 038 039 protected void load() { 040 try { 041 readFile(getDefaultOperationsFilename()); 042 } catch (IOException | JDOMException e) { 043 log.error("Exception during operations file reading: {}", e.getLocalizedMessage()); 044 } 045 } 046 047 protected File createFile(String fullPathName, boolean backupFile) { 048 if (backupFile) { 049 makeBackupFile(fullPathName); 050 } 051 File file = null; 052 try { 053 if (!checkFile(fullPathName)) { 054 // log.debug("File "+fullPathName+ " does not exist, creating it"); 055 // The file does not exist, create it before writing 056 file = new File(fullPathName); 057 File parentDir = file.getParentFile(); 058 if (!parentDir.exists()) { 059 if (!parentDir.mkdir()) { 060 log.error("Directory wasn't created"); 061 } 062 } 063 if (file.createNewFile()) { 064 log.debug("File created {}", fullPathName); 065 } 066 } else { 067 file = new File(fullPathName); 068 } 069 } catch (IOException e) { 070 log.error("Exception while creating operations file, may not be complete: {}", e.getLocalizedMessage()); 071 } 072 return file; 073 } 074 075 protected void writeFile(String filename) throws FileNotFoundException, IOException { 076 log.error("writeFile not overridden"); 077 } 078 079 /** 080 * @param filename The string file name. 081 * @throws org.jdom2.JDOMException Due to XML parsing error 082 * @throws java.io.IOException Due to trouble accessing named file 083 */ 084 abstract public void readFile(String filename) throws org.jdom2.JDOMException, java.io.IOException; 085 086 private boolean dirty = false; 087 088 public void setDirty(boolean b) { 089 dirty = b; 090 } 091 092 public boolean isDirty() { 093 return dirty; 094 } 095 096 public void writeFileIfDirty() { 097 if (isDirty()) { 098 writeOperationsFile(); 099 } 100 } 101 102 public String getDefaultOperationsFilename() { 103 return getFileLocation() + getOperationsDirectoryName() + File.separator + getOperationsFileName(); 104 } 105 106 public static void setOperationsDirectoryName(String name) { 107 operationsDirectoryName = name; 108 } 109 110 public static String getOperationsDirectoryName() { 111 return operationsDirectoryName; 112 } 113 114 private static String operationsDirectoryName = "operations"; // NOI18N 115 116 public void setOperationsFileName(String name) { 117 operationsFileName = name; 118 } 119 120 public String getOperationsFileName() { 121 return operationsFileName; 122 } 123 124 private String operationsFileName = "DefaultOperations.xml"; // should be overridden // NOI18N 125 126 /** 127 * Absolute path to location of Operations files. 128 * <p> 129 * Default is in the user's files path, but can be set to anything. 130 * 131 * @return The string path name. 132 * 133 * @see jmri.util.FileUtil#getUserFilesPath() 134 */ 135 public static String getFileLocation() { 136 return fileLocation; 137 } 138 139 /** 140 * Set path to location of Operations files. 141 * <p> 142 * Default is in the user's files path, but can be set to anything. 143 * 144 * @param location path to file, including trailing file separator. 145 */ 146 public static void setFileLocation(String location) { 147 fileLocation = location; 148 } 149 150 private static String fileLocation = FileUtil.getUserFilesPath(); 151 152 /** 153 * Checks name for the file control characters: 154 * 155 * @param name The string to check for a valid file name. 156 * @return true if name is okay, false if name contains a control character. 157 */ 158 public static boolean checkFileName(String name) { 159 if (name.contains(".") || name.contains("<") || name.contains(">") // NOI18N 160 || name.contains(":") || name.contains("\"") || name.contains("\\") // NOI18N 161 || name.contains("/") || name.contains("|") || name.contains("?") // NOI18N 162 || name.contains("*")) { // NOI18N 163 return false; 164 } 165 return true; 166 } 167 168 /** 169 * Saves operation files that have been modified. 170 */ 171 public static void save() { 172 InstanceManager.getDefault(OperationsSetupXml.class).writeFileIfDirty(); 173 InstanceManager.getDefault(LocationManagerXml.class).writeFileIfDirty(); // Need to save "moves" for track location 174 InstanceManager.getDefault(RouteManagerXml.class).writeFileIfDirty(); // Only if user used setX&Y 175 InstanceManager.getDefault(CarManagerXml.class).writeFileIfDirty(); // save train assignments 176 InstanceManager.getDefault(EngineManagerXml.class).writeFileIfDirty(); // save train assignments 177 InstanceManager.getDefault(TrainManagerXml.class).writeFileIfDirty(); // save train changes 178 } 179 180 /** 181 * Checks to see if any operations files are dirty 182 * 183 * @return True if any operations parameters have been modified. 184 */ 185 public static boolean areFilesDirty() { 186 return InstanceManager.getDefault(OperationsSetupXml.class).isDirty() 187 || InstanceManager.getDefault(LocationManagerXml.class).isDirty() 188 || InstanceManager.getDefault(RouteManagerXml.class).isDirty() 189 || InstanceManager.getDefault(CarManagerXml.class).isDirty() 190 || InstanceManager.getDefault(EngineManagerXml.class).isDirty() 191 || InstanceManager.getDefault(TrainManagerXml.class).isDirty(); 192 } 193 194 private final static Logger log = LoggerFactory.getLogger(OperationsXml.class); 195 196}