/* * EU3Scenario.java * * Created on July 2, 2007, 1:59 PM */ package eug.specific.eu3; import eug.parser.EUGFileIO; import eug.parser.ParserSettings; import eug.shared.FilenameResolver; import eug.shared.GenericObject; import eug.shared.ObjectVariable; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Implementation of <code>EU3DataSource</code> which gets country and province * data from the history files. * @author Michael Myers * @since EUGFile 1.06.00pre1 */ public class EU3Scenario implements EU3DataSource { private FilenameResolver resolver; private final Map<Object, GenericObject> historyCache; private static final ParserSettings settings = ParserSettings.getDefaults().setPrintTimingInfo(false); /** Creates a new instance of EU3Scenario */ public EU3Scenario(FilenameResolver resolver) { this.resolver = resolver; historyCache = new HashMap<Object, GenericObject>(); } public EU3Scenario(String mainDir, String modDir) { resolver = new FilenameResolver(mainDir, modDir); historyCache = new HashMap<Object, GenericObject>(); } public void setResolver(FilenameResolver resolver) { this.resolver = resolver; } public GenericObject getCountry(String tag) { return getCtryHistory(tag); } public GenericObject getCountryHistory(String tag) { return getCtryHistory(tag); } public GenericObject getProvince(int id) { return getProvHistory(id); } public GenericObject getProvinceHistory(int id) { return getProvHistory(id); } public List<GenericObject> getWars() { List<GenericObject> ret = new ArrayList<GenericObject>(); for (File file : resolver.listFiles("history/wars")) { GenericObject obj = EUGFileIO.load(file, settings); if (obj != null) ret.add(obj); } return ret; } public List<GenericObject> getWars(final String date) { List<GenericObject> ret = new ArrayList<GenericObject>(); for (File file : resolver.listFiles("history/wars")) { GenericObject obj = EUGFileIO.load(file, settings); if (obj != null) { List<String> participants = EU3History.getHistStrings(obj, date, "add_attacker", "rem_attacker"); if (!participants.isEmpty()) ret.add(obj); } } return ret; } public void removeWar(String name) { String filename = resolver.resolveFilename("history/wars/" + name + ".txt"); File file = new File(filename); if (file.exists()) { if (!file.delete()) System.err.println("Could not delete " + filename); } else { // What do we do here? Assume it's a war name, not a filename? // If so, what do we do about it? } } public String getCountryAsStr(String tag) { return loadFile(resolver.getCountryHistoryFile(tag)); } public String getCountryHistoryAsStr(String tag) { return loadFile(resolver.getCountryHistoryFile(tag)); } public String getProvinceAsStr(int id) { return loadFile(resolver.getProvinceHistoryFile(id)); } public String getProvinceHistoryAsStr(int id) { return loadFile(resolver.getProvinceHistoryFile(id)); } public void saveCountry(String tag, String cname, final String data) { String filename = resolver.getCountryHistoryFile(tag); if (filename == null) { filename = resolver.resolveDirectory("history") + "countries/" + tag + " - " + cname + ".txt"; } else { filename = filename.substring(Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'))); filename = resolver.resolveDirectory("history") + "countries/" + filename; } File file = new File(filename); String backupFilename = getBackupFilename(filename); if (file.exists()) { file.renameTo(new File(backupFilename)); } saveFile(filename, data); } public void saveProvince(int id, String pname, final String data) { String filename = resolver.getProvinceHistoryFile(id); if (filename == null) { filename = resolver.resolveDirectory("history") + "provinces/" + id + " - " + pname + ".txt"; } else { filename = filename.substring(Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'))); filename = resolver.resolveDirectory("history") + "provinces/" + filename; } File file = new File(filename); if (file.exists()) { String backupFilename = getBackupFilename(filename); file.renameTo(new File(backupFilename)); } saveFile(filename, data); } public void saveWar(String name, String data) { String filename = resolver.resolveFilename("history/wars/" + name + ".txt"); File file = new File(filename); // if (!file.exists()) { // // we were given the war name, not the filename // // or is this reasonable? Left commented out for now. // for (File warFile : resolver.listFiles("history/wars")) { // GenericObject war = EUGFileIO.load(warFile, settings); // if (war.getString("name").equals(name)) { // file = warFile; // filename = file.getAbsolutePath(); // break; // } // } // } if (!file.exists()) { // new file filename = filename.substring(Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'))); filename = resolver.resolveDirectory("history") + "wars/" + filename; } else { file.renameTo(new File(getBackupFilename(filename))); } saveFile(filename, data); } private static final String getBackupFilename(String filename) { File f = new File(filename); return f.getParent() + File.separatorChar + "~" + f.getName(); } public void saveChanges() { // do nothing } public boolean hasUnsavedChanges() { return false; } public void reloadCountry(String tag) { historyCache.remove(tag); resolver.reset(); } public void reloadCountryHistory(String tag) { historyCache.remove(tag); resolver.reset(); } public void reloadProvince(int id) { historyCache.remove(id); resolver.reset(); } public void reloadProvinceHistory(int id) { historyCache.remove(id); resolver.reset(); } public void preloadProvinces(int last) { preloadProvHistory(1, last); } public void preloadCountries() { preloadCountryHistory(); } private void preloadProvHistory(int start, int end) { GenericObject hist; for (int id = start; id < end; id++) { hist = historyCache.get(id); if (hist == null) { String histFile = resolver.getProvinceHistoryFile(id); if (histFile == null) { // System.err.println("Cannot find province history file for ID " + id); continue; } hist = EUGFileIO.load(histFile, settings); if (hist == null) { // System.err.println("Failed to load province history file for ID " + id); } else { historyCache.put(id, hist); } } } } private void preloadCountryHistory() { GenericObject hist; String tag; final GenericObject countries = EUGFileIO.load(resolver.resolveFilename("common/countries.txt"), settings); for (ObjectVariable def : countries.values) { tag = def.varname; hist = historyCache.get(tag); if (hist == null) { String histFile = resolver.getCountryHistoryFile(tag); if (histFile == null) { // System.err.println("Cannot find country history file for " + tag); continue; } hist = EUGFileIO.load(histFile, settings); if (hist == null) { System.err.println("Failed to load country history file for " + tag); } else { historyCache.put(tag, hist); } } } } /** Gets the province history for the given id, using the cache. */ private final GenericObject getProvHistory(final int id) { GenericObject hist = historyCache.get(id); if (hist == null) { String histFile = resolver.getProvinceHistoryFile(id); if (histFile == null) { System.err.println("Cannot find province history file for ID " + id); return null; } hist = EUGFileIO.load(histFile, settings); if (hist == null) { System.err.println("Failed to load province history file for ID " + id); } else { // java.util.Collections.sort(hist.children, DATE_OBJECT_COMPARATOR); historyCache.put(id, hist); } } return hist; } /** Gets the country history for the given tag, using the cache. */ private final GenericObject getCtryHistory(final String tag) { GenericObject hist = historyCache.get(tag); if (hist == null) { String histFile = resolver.getCountryHistoryFile(tag); if (histFile == null) { System.err.println("Cannot find country history file for " + tag); return null; } hist = EUGFileIO.load(histFile, settings); if (hist == null) { System.err.println("Failed to load country history file for " + tag); } else { // java.util.Collections.sort(hist.children, DATE_OBJECT_COMPARATOR); historyCache.put(tag, hist); } } return hist; } private final String loadFile(final String filename) { if (filename == null) return null; final File file = new File(filename); final char[] data = new char[(int)file.length()]; try { final FileReader reader = new FileReader(file); if (reader.read(data) != data.length) System.err.println("???"); reader.close(); return String.valueOf(data); } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } return null; } private final void saveFile(final String filename, final String data) { try { final FileWriter writer = new FileWriter(filename); writer.write(data); writer.close(); } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } }