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