= Migrated to CSV
This commit is contained in:
@@ -1,68 +0,0 @@
|
|||||||
package core;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ListIterator;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import dataStructures.Pair;
|
|
||||||
|
|
||||||
public class BaseKeyValueFile
|
|
||||||
{
|
|
||||||
// Variables
|
|
||||||
public static final String headerStart = "[";
|
|
||||||
public static final String headerEnd = "]";
|
|
||||||
public static final String pairSplit = "=";
|
|
||||||
public static final char pairSeparator = '\n';
|
|
||||||
|
|
||||||
protected final String header;
|
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public BaseKeyValueFile()
|
|
||||||
{
|
|
||||||
this.header = headerStart + this.getClass().getSimpleName() + headerEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads in and calls the specifid function for each keyvalue pair we find
|
|
||||||
protected void parse(String content, Consumer<? super Pair<String, String>> keyValueCallback)
|
|
||||||
{
|
|
||||||
content = content.trim();
|
|
||||||
String[] lines = content.split("" + pairSeparator);
|
|
||||||
|
|
||||||
for(int i = 0; i < lines.length; ++i)
|
|
||||||
{
|
|
||||||
if(lines[i].contains(header))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
String[] pair = lines[i].split(pairSplit);
|
|
||||||
|
|
||||||
if(pair.length < 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
String key = pair[0].trim().toLowerCase();
|
|
||||||
String value = pair[1].trim().toLowerCase();
|
|
||||||
|
|
||||||
keyValueCallback.accept(new Pair<String, String>(key, value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writes the set of keyvalue pairs to a string
|
|
||||||
protected String write(List<Pair<String, String>> toWrite)
|
|
||||||
{
|
|
||||||
ListIterator<Pair<String, String>> iter = toWrite.listIterator();
|
|
||||||
|
|
||||||
String outString = "";
|
|
||||||
outString += header + pairSeparator;
|
|
||||||
|
|
||||||
while(iter.hasNext())
|
|
||||||
{
|
|
||||||
Pair<String, String> pair = iter.next();
|
|
||||||
String key = pair.First.toLowerCase();
|
|
||||||
String value = pair.Second.toLowerCase();
|
|
||||||
|
|
||||||
outString += key + pairSplit + value + pairSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
return outString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+82
-46
@@ -2,41 +2,58 @@ package core;
|
|||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import dataStructures.TaggedPairStore;
|
|
||||||
import utils.GlobalLog;
|
import utils.GlobalLog;
|
||||||
import utils.LogFilter;
|
import utils.LogFilter;
|
||||||
import utils.io.FileMonitor;
|
|
||||||
import utils.io.FileUtils;
|
import utils.io.FileUtils;
|
||||||
|
|
||||||
|
|
||||||
// A quick-and-dirty localization tool that scrapes the project for calls to itself, then
|
// A quick-and-dirty localization tool that scrapes the project for calls to itself, then
|
||||||
// generates/updates a file externally with all the stub values as keys that are localized.
|
// generates/updates a file externally with all the stub values as keys that are localized.
|
||||||
public abstract class BaseLocFile
|
public abstract class BaseLocFile implements IConfigSection
|
||||||
{
|
{
|
||||||
// Filename
|
// Variables
|
||||||
public final String functionName; // Example: "Localizer.Stub";
|
protected final String headerName; // Example: Loc Strings
|
||||||
|
protected final String functionName; // Example: "Localizer.Stub";
|
||||||
// Local translation storage
|
protected Map<String, String> localized;
|
||||||
protected TaggedPairStore stringStore;
|
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
private void log(String str) { GlobalLog.log(LogFilter.Strings, str); }
|
private void log(String str) { GlobalLog.log(LogFilter.Strings, str); }
|
||||||
private void warn(String str) { GlobalLog.warn(LogFilter.Strings, str); }
|
private void warn(String str) { GlobalLog.warn(LogFilter.Strings, str); }
|
||||||
private void error(String str) { GlobalLog.error(LogFilter.Strings, str); }
|
private void error(String str) { GlobalLog.error(LogFilter.Strings, str); }
|
||||||
|
|
||||||
// File monitoring
|
|
||||||
protected FileMonitor fileMonitor;
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public BaseLocFile(String functionName)
|
public BaseLocFile(String headerName, String functionName)
|
||||||
{
|
{
|
||||||
|
this.headerName = headerName;
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
|
localized = new HashMap<String, String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// First Step: Populating with existing strings //
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void buildLocalized(List<ConfigItem> pairs)
|
||||||
|
{
|
||||||
|
for(ConfigItem item : pairs)
|
||||||
|
{
|
||||||
|
localized.put(item.key, item.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Second Step: Scraping existing files //
|
||||||
|
//////////////////////////////////////////
|
||||||
|
|
||||||
// Structure used for holding a pair of strings and any other info we need
|
// Structure used for holding a pair of strings and any other info we need
|
||||||
// about localized information that is being looked up.
|
// about localized information that is being looked up.
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private class LocInfo
|
private class LocInfo
|
||||||
{
|
{
|
||||||
public String file;
|
public String file;
|
||||||
@@ -49,8 +66,21 @@ public abstract class BaseLocFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to perform stripping java files for contents to localize
|
||||||
|
private void tryStripSpecified(Path path, ArrayList<LocInfo> toFill)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stripForContents(path, toFill);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
error("issue with file: " + path.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Do processing on each path in the scraped directory here, assuming it's .java
|
// Do processing on each path in the scraped directory here, assuming it's .java
|
||||||
public void stripForContents(Path path, ArrayList<LocInfo> strings)
|
private void stripForContents(Path path, ArrayList<LocInfo> strings)
|
||||||
{
|
{
|
||||||
String filename = path.getFileName().toString();
|
String filename = path.getFileName().toString();
|
||||||
if(filename.contains(".java"))
|
if(filename.contains(".java"))
|
||||||
@@ -68,8 +98,8 @@ public abstract class BaseLocFile
|
|||||||
{
|
{
|
||||||
if(noWhitespace.charAt(noWhitespace.indexOf(")") - 1) == '"' && split[i].charAt(loc - 2) != '\\')
|
if(noWhitespace.charAt(noWhitespace.indexOf(")") - 1) == '"' && split[i].charAt(loc - 2) != '\\')
|
||||||
{
|
{
|
||||||
// At this point, we find the first ), then verify there's a ") behind it, and that
|
// At this point we find the first ), then verify there's a ") behind it,
|
||||||
// the " is not an escaped character.
|
// and that the " is not an escaped character.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String toLocalize = split[i].substring(2, loc - 1);
|
String toLocalize = split[i].substring(2, loc - 1);
|
||||||
@@ -88,61 +118,67 @@ public abstract class BaseLocFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing for now, but in the future will return a parsed and localized version of
|
// Returns the value. If the localized string is empty,
|
||||||
// the string in question if one can be found. If the localized string is empty,
|
|
||||||
// returns a the key instead which is the default phrase.
|
// returns a the key instead which is the default phrase.
|
||||||
public String getKey(String input)
|
public String getKey(String input)
|
||||||
{
|
{
|
||||||
if(stringStore == null)
|
if(localized == null)
|
||||||
|
{
|
||||||
return input;
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
String value = stringStore.getKey(input);
|
String value = localized.get(input);
|
||||||
if(value == null || value.trim().length() < 1)
|
if(value == null || value.trim().length() < 1)
|
||||||
|
{
|
||||||
return input;
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update localization from the disk on file. Creates the file if it doesn't exist.
|
|
||||||
// This file is internally formatted as an ini file.
|
|
||||||
public void updateLocFromString(String fileContents)
|
|
||||||
{
|
|
||||||
log("Attempting to read localization file contents");
|
|
||||||
|
|
||||||
stringStore = new TaggedPairStore(fileContents);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryStripSpecified(Path path, ArrayList<LocInfo> toFill)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
stripForContents(path, toFill);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
error("issue with file: " + path.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scrape the project and generate all the possible localizeable phrases.
|
// Scrape the project and generate all the possible localizeable phrases.
|
||||||
// This stubs out phrases to be localized.
|
// This stubs out phrases to be localized, by default placing the key in as the value.
|
||||||
public void scrapeAll()
|
public void scrapeAll()
|
||||||
{
|
{
|
||||||
ArrayList<LocInfo> localizeList = new ArrayList<LocInfo>();
|
ArrayList<LocInfo> localizeList = new ArrayList<LocInfo>();
|
||||||
FileUtils.acquireAllFiles(Constants.SourceDirectory).forEach((path) -> tryStripSpecified(path, localizeList));
|
FileUtils.acquireAllFiles(Constants.SourceDirectory).forEach((path) -> tryStripSpecified(path, localizeList));
|
||||||
|
|
||||||
for(LocInfo toStub : localizeList)
|
for(LocInfo toStub : localizeList)
|
||||||
stringStore.addKeyValue(toStub.file, toStub.phrase, toStub.phrase);
|
{
|
||||||
|
localized.putIfAbsent(toStub.phrase, toStub.phrase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts this to a string
|
///////////////////////////////////
|
||||||
public String toString()
|
// IConfigSection Implementation //
|
||||||
|
///////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSectionTitle()
|
||||||
{
|
{
|
||||||
return stringStore.toString();
|
return headerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ConfigItem> toConfigList();
|
@Override
|
||||||
|
public void consume(List<ConfigItem> pairs)
|
||||||
{
|
{
|
||||||
|
localized.clear();
|
||||||
|
buildLocalized(pairs);
|
||||||
|
scrapeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ConfigItem> produce()
|
||||||
|
{
|
||||||
|
List<ConfigItem> items = new Vector<ConfigItem>();
|
||||||
|
|
||||||
|
for(Entry<String, String> entry : localized.entrySet())
|
||||||
|
{
|
||||||
|
items.add(new ConfigItem(headerName, entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
items.sort((item1, item2) -> item1.key.compareToIgnoreCase(item2.key));
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import utils.LogFilter;
|
|||||||
// commands that are being looked up will behave slightly differently so trimming
|
// commands that are being looked up will behave slightly differently so trimming
|
||||||
// rules for this file are different than the localization ones - this is more
|
// rules for this file are different than the localization ones - this is more
|
||||||
// aggresive with whitespace removal.
|
// aggresive with whitespace removal.
|
||||||
public class CommandEnabler extends BaseKeyValueFile implements DEPRECATED_IConfigSection
|
public class CommandEnabler implements IConfigSection
|
||||||
{
|
{
|
||||||
// Config/const variables
|
// Config/const variables
|
||||||
public static final String enabled = "1";
|
public static final String enabled = "1";
|
||||||
@@ -48,14 +48,15 @@ public class CommandEnabler extends BaseKeyValueFile implements DEPRECATED_IConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reads in the config file and parses it, keeping tabs on the order it read things
|
// Reads in the config file and parses it, keeping tabs on the order it read things
|
||||||
private void readIn(String contents)
|
private void readIn(List<ConfigItem> items)
|
||||||
{
|
{
|
||||||
parse(contents, (pair) ->{
|
for(ConfigItem item : items)
|
||||||
String key = pair.First;
|
{
|
||||||
String value = pair.Second;
|
String key = item.key;
|
||||||
|
String value = item.value;
|
||||||
|
|
||||||
keyList.add(key);
|
keyList.add(key);
|
||||||
|
|
||||||
if(value.equalsIgnoreCase(enabled))
|
if(value.equalsIgnoreCase(enabled))
|
||||||
{
|
{
|
||||||
enabledMap.putIfAbsent(key, true);
|
enabledMap.putIfAbsent(key, true);
|
||||||
@@ -64,7 +65,7 @@ public class CommandEnabler extends BaseKeyValueFile implements DEPRECATED_IConf
|
|||||||
{
|
{
|
||||||
enabledMap.putIfAbsent(key, false);
|
enabledMap.putIfAbsent(key, false);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up the already scraped values from the localizer and store them if they
|
// Look up the already scraped values from the localizer and store them if they
|
||||||
@@ -86,8 +87,9 @@ public class CommandEnabler extends BaseKeyValueFile implements DEPRECATED_IConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write out enabled/disabled file info.
|
// Write out enabled/disabled file info.
|
||||||
private String writeOut()
|
private List<ConfigItem> writeOut()
|
||||||
{
|
{
|
||||||
|
// Parse in original format
|
||||||
List<Pair<String, String>> list = new Vector<Pair<String, String>>();
|
List<Pair<String, String>> list = new Vector<Pair<String, String>>();
|
||||||
|
|
||||||
for(int i = 0; i < keyList.size(); ++i)
|
for(int i = 0; i < keyList.size(); ++i)
|
||||||
@@ -105,7 +107,15 @@ public class CommandEnabler extends BaseKeyValueFile implements DEPRECATED_IConf
|
|||||||
|
|
||||||
Collections.sort(list, (c1, c2) -> { return c1.First.compareTo(c2.First); });
|
Collections.sort(list, (c1, c2) -> { return c1.First.compareTo(c2.First); });
|
||||||
|
|
||||||
return write(list);
|
// Convert to new ConfigItem list format for return
|
||||||
|
List<ConfigItem> configItems = new Vector<ConfigItem>();
|
||||||
|
|
||||||
|
for(Pair<String, String> pair : list)
|
||||||
|
{
|
||||||
|
configItems.add(new ConfigItem(HeaderName, pair.First, pair.Second));
|
||||||
|
}
|
||||||
|
|
||||||
|
return configItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looks up a key to see if it's enabled or not
|
// Looks up a key to see if it's enabled or not
|
||||||
@@ -122,18 +132,21 @@ public class CommandEnabler extends BaseKeyValueFile implements DEPRECATED_IConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHeader() {
|
public String getSectionTitle()
|
||||||
|
{
|
||||||
return HeaderName;
|
return HeaderName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(String contents) {
|
public void consume(List<ConfigItem> pairs)
|
||||||
|
{
|
||||||
|
readIn(pairs);
|
||||||
getTrackedCommands();
|
getTrackedCommands();
|
||||||
readIn(contents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String write() {
|
public List<ConfigItem> produce()
|
||||||
|
{
|
||||||
return writeOut();
|
return writeOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-5
@@ -2,11 +2,15 @@ package core;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
import utils.io.FileMonitor;
|
||||||
|
|
||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
ConfigCSV configCSV;
|
private static final String filepath = Constants.AssetDirectory + Constants.ConfigFilename;
|
||||||
List<IConfigSection> sections;
|
|
||||||
|
private ConfigCSV configCSV;
|
||||||
|
private List<IConfigSection> sections;
|
||||||
|
private FileMonitor monitoredConfigFile;
|
||||||
|
|
||||||
public static Config instance;
|
public static Config instance;
|
||||||
|
|
||||||
@@ -15,10 +19,16 @@ public class Config
|
|||||||
if(instance == null)
|
if(instance == null)
|
||||||
{
|
{
|
||||||
sections = new Vector<IConfigSection>();
|
sections = new Vector<IConfigSection>();
|
||||||
|
|
||||||
configCSV = new ConfigCSV(sections, "./config.csv");
|
|
||||||
configCSV.writeFile();
|
|
||||||
|
|
||||||
|
// Add all sections
|
||||||
|
sections.add(new LocCommands());
|
||||||
|
sections.add(new LocStrings());
|
||||||
|
sections.add(new CommandEnabler());
|
||||||
|
|
||||||
|
// Being monitoring configs and mark this as the instance now that it's made
|
||||||
|
monitoredConfigFile = new FileMonitor(filepath);
|
||||||
|
build(filepath);
|
||||||
|
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -28,4 +38,17 @@ public class Config
|
|||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void build(String path)
|
||||||
|
{
|
||||||
|
configCSV = new ConfigCSV(sections, path);
|
||||||
|
configCSV.writeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void upkeep()
|
||||||
|
{
|
||||||
|
monitoredConfigFile.update((monitoredFile) -> {
|
||||||
|
build(monitoredFile.path.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ public final class Constants
|
|||||||
{
|
{
|
||||||
public static final Color ColorDefault = new Color(7*16, 8*16, 9*16); // A slate-grey
|
public static final Color ColorDefault = new Color(7*16, 8*16, 9*16); // A slate-grey
|
||||||
public static final String AssetDirectory = "./assets/";
|
public static final String AssetDirectory = "./assets/";
|
||||||
public static final String ConfigFilename = "config.config";
|
public static final String ConfigFilename = "config.csv";
|
||||||
public static final String SourceDirectory = "./src";
|
public static final String SourceDirectory = "./src";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,172 +0,0 @@
|
|||||||
package core;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Vector;
|
|
||||||
import utils.GlobalLog;
|
|
||||||
import utils.LogFilter;
|
|
||||||
import utils.io.FileMonitor;
|
|
||||||
import utils.io.FileUtils;
|
|
||||||
|
|
||||||
public class DEPRECATED_Config
|
|
||||||
{
|
|
||||||
private static final String filepath = Constants.AssetDirectory + Constants.ConfigFilename;
|
|
||||||
|
|
||||||
public static DEPRECATED_Config instance;
|
|
||||||
|
|
||||||
// Private
|
|
||||||
private Vector<DEPRECATED_IConfigSection> sections;
|
|
||||||
private FileMonitor monitoredConfigFile;
|
|
||||||
|
|
||||||
public DEPRECATED_Config()
|
|
||||||
{
|
|
||||||
if(instance == null)
|
|
||||||
{
|
|
||||||
// Create local variables
|
|
||||||
sections = new Vector<DEPRECATED_IConfigSection>();
|
|
||||||
|
|
||||||
// Add all sections
|
|
||||||
sections.add(new LocCommands());
|
|
||||||
sections.add(new LocStrings());
|
|
||||||
sections.add(new CommandEnabler());
|
|
||||||
|
|
||||||
// Read file in and parse everything out
|
|
||||||
performStartup();
|
|
||||||
|
|
||||||
// Being monitoring configs and mark this as the instance now that it's made
|
|
||||||
monitoredConfigFile = new FileMonitor(filepath);
|
|
||||||
instance = this;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GlobalLog.error(LogFilter.Core, "You can't have two of the following: " + this.getClass().getSimpleName());
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform startup
|
|
||||||
private void performStartup()
|
|
||||||
{
|
|
||||||
File configFile = new File(filepath);
|
|
||||||
|
|
||||||
if(configFile.exists())
|
|
||||||
{
|
|
||||||
reformConfig(configFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
configFile.createNewFile();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
GlobalLog.error(LogFilter.Core, "Failed to load config or create empty config at " + filepath);
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String sectionStart = "[[";
|
|
||||||
public static final String sectionEnd = "]]";
|
|
||||||
public static final String headerStart = "[";
|
|
||||||
public static final String headerEnd = "]";
|
|
||||||
public static final String pairSplit = "=";
|
|
||||||
public static final String pairSeparator = "\n";
|
|
||||||
|
|
||||||
private void reformConfig(File configFile)
|
|
||||||
{
|
|
||||||
// Read and update
|
|
||||||
String configContents = FileUtils.readContent(configFile);
|
|
||||||
readConfigs(configContents);
|
|
||||||
|
|
||||||
// Form updated data as necessary for autogeneration
|
|
||||||
String output = combineConfigs();
|
|
||||||
|
|
||||||
// Write to file.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OutputStreamWriter fileWriter = new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8);
|
|
||||||
fileWriter.write(output);
|
|
||||||
fileWriter.close();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
GlobalLog.error(LogFilter.Core, "Config writing failure.");
|
|
||||||
GlobalLog.error(LogFilter.Core, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void readConfigs(String fullContents)
|
|
||||||
{
|
|
||||||
String[] str = fullContents.split(pairSeparator);
|
|
||||||
HashMap<String, String> parsedSections = new HashMap<String, String>();
|
|
||||||
|
|
||||||
String currentHeader = "";
|
|
||||||
for(int i = 0; i < str.length; ++i)
|
|
||||||
{
|
|
||||||
String line = str[i].trim();
|
|
||||||
if(line.startsWith(sectionStart) && line.endsWith(sectionEnd))
|
|
||||||
{
|
|
||||||
currentHeader = line.substring(sectionStart.length(), line.length() - sectionEnd.length());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String sectionContents = parsedSections.getOrDefault(currentHeader, "");
|
|
||||||
parsedSections.put(currentHeader, sectionContents + line + pairSeparator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < sections.size(); ++i)
|
|
||||||
{
|
|
||||||
DEPRECATED_IConfigSection section = sections.get(i);
|
|
||||||
String header = section.getHeader();
|
|
||||||
String content = parsedSections.getOrDefault(header, null);
|
|
||||||
|
|
||||||
if(content != null)
|
|
||||||
{
|
|
||||||
section.read(content);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GlobalLog.warn(LogFilter.Core, "Mismatch during config parsing - expected but did not find " + header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String combineConfigs()
|
|
||||||
{
|
|
||||||
String output = "";
|
|
||||||
|
|
||||||
for(int i = 0; i < sections.size(); ++i)
|
|
||||||
{
|
|
||||||
// If not the first section, add spacing!
|
|
||||||
if(i != 0)
|
|
||||||
{
|
|
||||||
for(int spacing = 0; spacing < 3; ++spacing)
|
|
||||||
{
|
|
||||||
output += pairSeparator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEPRECATED_IConfigSection section = sections.get(i);
|
|
||||||
output += sectionStart + section.getHeader() + sectionEnd + pairSeparator;
|
|
||||||
output += section.write() + pairSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void upkeep()
|
|
||||||
{
|
|
||||||
monitoredConfigFile.update((monitoredFile) -> {
|
|
||||||
File configFile = new File(filepath);
|
|
||||||
reformConfig(configFile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package core;
|
package core;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import utils.GlobalLog;
|
import utils.GlobalLog;
|
||||||
import utils.LogFilter;
|
import utils.LogFilter;
|
||||||
@@ -18,7 +17,7 @@ public class LocCommands extends BaseLocFile implements IConfigSection
|
|||||||
|
|
||||||
public LocCommands()
|
public LocCommands()
|
||||||
{
|
{
|
||||||
super(function);
|
super(HeaderName, function);
|
||||||
|
|
||||||
GlobalLog.log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName());
|
GlobalLog.log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName());
|
||||||
|
|
||||||
@@ -42,39 +41,7 @@ public class LocCommands extends BaseLocFile implements IConfigSection
|
|||||||
public static ArrayList<String> getUnlocalizedCommands()
|
public static ArrayList<String> getUnlocalizedCommands()
|
||||||
{
|
{
|
||||||
ArrayList<String> raw = new ArrayList<>();
|
ArrayList<String> raw = new ArrayList<>();
|
||||||
instance.stringStore.forEach((pair) -> raw.add((String)((Pair<?, ?>)pair).First ));
|
instance.localized.keySet().forEach((key) -> raw.add(key));
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public String getHeader() {
|
|
||||||
// return HeaderName;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void read(String contents) {
|
|
||||||
// updateLocFromString(contents);
|
|
||||||
// scrapeAll();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public String write() {
|
|
||||||
// return toString();
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSectionTitle() {
|
|
||||||
return HeaderName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consume(List<ConfigItem> pairs) {
|
|
||||||
scrapeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ConfigItem> produce() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package core;
|
package core;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import utils.GlobalLog;
|
import utils.GlobalLog;
|
||||||
import utils.LogFilter;
|
import utils.LogFilter;
|
||||||
|
|
||||||
// A quick-and-dirty localization tool that scrapes the project for calls to itself, then
|
// A quick-and-dirty localization tool that scrapes the project for calls to itself, then
|
||||||
// generates/updates a file externally (phrases.config) with all the stub values as keys that
|
// generates/updates a file externally (phrases.config) with all the stub values as keys that
|
||||||
// can then be localized.
|
// can then be localized.
|
||||||
public class LocStrings extends BaseLocFile implements IConfigSection
|
public class LocStrings extends BaseLocFile
|
||||||
{
|
{
|
||||||
public static final String HeaderName = "Localized Strings";
|
public static final String HeaderName = "Localized Strings";
|
||||||
public static final String function = "LocStrings.stub";
|
public static final String function = "LocStrings.stub";
|
||||||
@@ -17,7 +15,7 @@ public class LocStrings extends BaseLocFile implements IConfigSection
|
|||||||
|
|
||||||
public LocStrings()
|
public LocStrings()
|
||||||
{
|
{
|
||||||
super(function);
|
super(HeaderName, function);
|
||||||
|
|
||||||
GlobalLog.log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName());
|
GlobalLog.log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName());
|
||||||
|
|
||||||
@@ -41,36 +39,4 @@ public class LocStrings extends BaseLocFile implements IConfigSection
|
|||||||
{
|
{
|
||||||
return instance.getKey(stubbedPreviously);
|
return instance.getKey(stubbedPreviously);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSectionTitle() {
|
|
||||||
return HeaderName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consume(List<ConfigItem> pairs) {
|
|
||||||
scrapeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ConfigItem> produce() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public String getHeader() {
|
|
||||||
// return HeaderName;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void read(String contents) {
|
|
||||||
// updateLocFromString(contents);
|
|
||||||
// scrapeAll();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public String write() {
|
|
||||||
// return toString();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ public class ObjectBuilderFactory
|
|||||||
@SuppressWarnings("unused") private static LocCommands locCommands;
|
@SuppressWarnings("unused") private static LocCommands locCommands;
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
@SuppressWarnings("unused") private static DEPRECATED_Config config;
|
@SuppressWarnings("unused") private static Config config;
|
||||||
|
|
||||||
// Lazy initialization multithreaded mutex stuff to prevent explosions.
|
// Lazy initialization multithreaded mutex stuff to prevent explosions.
|
||||||
// TODO: Investigate using 'synchronized' instead potentially
|
// TODO: Investigate using 'synchronized' instead potentially
|
||||||
@@ -88,7 +88,7 @@ public class ObjectBuilderFactory
|
|||||||
// Start by reading from things that are external. Because
|
// Start by reading from things that are external. Because
|
||||||
// we require these things to be resolved before the rest of the application,
|
// we require these things to be resolved before the rest of the application,
|
||||||
// we place them here.
|
// we place them here.
|
||||||
config = new DEPRECATED_Config();
|
config = new Config();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,212 +0,0 @@
|
|||||||
package dataStructures;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import utils.StringUtils;
|
|
||||||
|
|
||||||
// This is a class designed to parse ini inspired key-value pairs that are sectioned off.
|
|
||||||
// The difference here is that this is more permissive than an ini file, and only accepts
|
|
||||||
// a single split character, not the traditional set an ini does. All of the following are valid:
|
|
||||||
//
|
|
||||||
// [ExampleSection]
|
|
||||||
// Key=Value
|
|
||||||
// Valid Ridiculous Key&\n\t_.:;foo = \tValid Ridiculous Value*&%$()^.[]{}@
|
|
||||||
// EmptyValue=
|
|
||||||
//
|
|
||||||
// Note that the sections are NOT designed to allow for duplicate keys across them.
|
|
||||||
// This is a restriction of the structure, but can be changed later potentially.
|
|
||||||
// The only value not allowed in a key or value is the KeyValueSplit.
|
|
||||||
public class TaggedPairStore
|
|
||||||
{
|
|
||||||
// Variables
|
|
||||||
public final char SectionStart = '[';
|
|
||||||
public final char SectionEnd = ']';
|
|
||||||
public final char PairLineSeparator = '\n';
|
|
||||||
public final String PairSplit = "=";
|
|
||||||
|
|
||||||
// [Key: SectionName, [Key: KeyString, Value: ValueString]]
|
|
||||||
private HashMap<String, HashMap<String, String>> taggedPairs;
|
|
||||||
|
|
||||||
// [Key: KeyString, Value: ValueString]]
|
|
||||||
private HashMap<String, String> allPairs;
|
|
||||||
|
|
||||||
// String constructor that parses the input string into the object
|
|
||||||
public TaggedPairStore(String input)
|
|
||||||
{
|
|
||||||
taggedPairs = new HashMap<String, HashMap<String, String>>();
|
|
||||||
allPairs = new HashMap<String, String>();
|
|
||||||
parse(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls back on each item in the entire structure. Provides section, then a pair of the keyString and valueString.
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
public void forEach(BiConsumer<? super String, Pair<? super String, ? super String>> action)
|
|
||||||
{
|
|
||||||
Iterator it = taggedPairs.entrySet().iterator();
|
|
||||||
while (it.hasNext())
|
|
||||||
{
|
|
||||||
Map.Entry pair = (Map.Entry)it.next();
|
|
||||||
Iterator internal = ((HashMap<String, String>)pair.getValue()).entrySet().iterator();
|
|
||||||
|
|
||||||
while(internal.hasNext())
|
|
||||||
{
|
|
||||||
Map.Entry internalPair = (Map.Entry)internal.next();
|
|
||||||
action.accept((String)pair.getKey(), new Pair<String, String>((String)internalPair.getKey(), (String)internalPair.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls back each item in the structure but does not priv
|
|
||||||
@SuppressWarnings({"rawtypes"})
|
|
||||||
public void forEach(Consumer<Pair<? super String, ? super String>> action)
|
|
||||||
{
|
|
||||||
Iterator it = allPairs.entrySet().iterator();
|
|
||||||
while (it.hasNext())
|
|
||||||
{
|
|
||||||
Map.Entry pair = (Map.Entry)it.next();
|
|
||||||
action.accept(new Pair<String, String>((String)pair.getKey(), (String)pair.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses the internal hashmap as a string then reutrns it, featuring sections.
|
|
||||||
// Iterates over all key/value pairs in the section and print them. Does not print
|
|
||||||
// the value of a given key if it is the same as the key.
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
String out = "";
|
|
||||||
|
|
||||||
// Iterates over the sections and
|
|
||||||
Iterator it = taggedPairs.entrySet().iterator();
|
|
||||||
while (it.hasNext())
|
|
||||||
{
|
|
||||||
Map.Entry pair = (Map.Entry)it.next();
|
|
||||||
out += ("" + SectionStart + pair.getKey() + SectionEnd + PairLineSeparator);
|
|
||||||
|
|
||||||
Iterator internal = ((HashMap<String, String>)pair.getValue()).entrySet().iterator();
|
|
||||||
while(internal.hasNext())
|
|
||||||
{
|
|
||||||
Map.Entry internalPair = (Map.Entry)internal.next();
|
|
||||||
String key = (String)internalPair.getKey();
|
|
||||||
String value = (String)internalPair.getValue();
|
|
||||||
key = StringUtils.reEscape(key);
|
|
||||||
value = StringUtils.reEscape(value);
|
|
||||||
|
|
||||||
if(key.endsWith("\\r"))
|
|
||||||
{
|
|
||||||
if(!key.endsWith("\\r\\r"))
|
|
||||||
key = key.substring(0, key.length() - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(value.endsWith("\\r"))
|
|
||||||
{
|
|
||||||
if(!value.endsWith("\\r\\r"))
|
|
||||||
value = value.substring(0, value.length() - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(key == value)
|
|
||||||
out += (key + PairSplit) + PairLineSeparator;
|
|
||||||
else
|
|
||||||
out += (key + PairSplit + value) + PairLineSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
out += PairLineSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses out the string passed in into the sectionkeyValue HashMap.
|
|
||||||
// Any character used in a split call is escaped just in case on
|
|
||||||
// account of some characters having specific regex meanings.
|
|
||||||
private void parse(String input)
|
|
||||||
{
|
|
||||||
if(input == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
String[] sections = input.split("\\" + SectionStart);
|
|
||||||
|
|
||||||
for(int sec = 0; sec < sections.length; ++sec)
|
|
||||||
{
|
|
||||||
// Gather information about the contents of the section, and the header.
|
|
||||||
String section = sections[sec];
|
|
||||||
if(section.length() < 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int pos = section.indexOf(SectionEnd);
|
|
||||||
if(pos == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Parse section name. If it already exists, don't bother making it.
|
|
||||||
String sectionName = section.substring(0, pos);
|
|
||||||
addSection(sectionName);
|
|
||||||
|
|
||||||
// Parse out the pairs within the section, split them all out.
|
|
||||||
String unparsedPairs = section.substring(pos + 1);
|
|
||||||
String[] pairs = unparsedPairs.split("\\" + PairLineSeparator);
|
|
||||||
|
|
||||||
// Parse out valid key-value pairs, and store them in the specified section.
|
|
||||||
// At this point, we can be guarenteed that sectionName is in the Hashmap.
|
|
||||||
for(int pair = 0; pair < pairs.length; ++pair)
|
|
||||||
{
|
|
||||||
String line = pairs[pair];
|
|
||||||
int splitPos = line.indexOf(PairSplit);
|
|
||||||
if(splitPos < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
String key = line.substring(0, splitPos);
|
|
||||||
String value = line.substring(splitPos + PairSplit.length());
|
|
||||||
key = StringUtils.unEscape(key);
|
|
||||||
value = StringUtils.unEscape(value);
|
|
||||||
|
|
||||||
taggedPairs.get(sectionName).putIfAbsent(key, value);
|
|
||||||
allPairs.putIfAbsent(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dumps out a string array
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private void dump(String[] toPrint)
|
|
||||||
{
|
|
||||||
System.out.println("Length: " + toPrint.length);
|
|
||||||
|
|
||||||
for(int i = 0; i < toPrint.length; ++i)
|
|
||||||
System.out.println(toPrint[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a KeyValue pair to the specified section if it's not already there.
|
|
||||||
// Also creates the section if it's not already present.
|
|
||||||
public void addKeyValue(String sectionName, String key, String value)
|
|
||||||
{
|
|
||||||
addSection(sectionName);
|
|
||||||
taggedPairs.get(sectionName).putIfAbsent(key, value);
|
|
||||||
allPairs.putIfAbsent(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a given section to the hashmap if it's not already present
|
|
||||||
public void addSection(String sectionName)
|
|
||||||
{
|
|
||||||
taggedPairs.putIfAbsent(sectionName, new HashMap<String, String>());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a HashMap of Keys to Values for a given section
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public HashMap<String, String> getSection(String sectionName)
|
|
||||||
{
|
|
||||||
return (HashMap<String, String>) taggedPairs.get(sectionName).clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look up a global key
|
|
||||||
public String getKey(String key)
|
|
||||||
{
|
|
||||||
if(allPairs.containsKey(key))
|
|
||||||
return allPairs.get(key);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,6 @@ import javax.security.auth.login.LoginException;
|
|||||||
import core.CharacterManager;
|
import core.CharacterManager;
|
||||||
import core.CommandEnabler;
|
import core.CommandEnabler;
|
||||||
import core.CommandManager;
|
import core.CommandManager;
|
||||||
import core.DEPRECATED_Config;
|
|
||||||
import core.DatabaseManager;
|
import core.DatabaseManager;
|
||||||
import core.ObjectBuilderFactory;
|
import core.ObjectBuilderFactory;
|
||||||
import core.RPManager;
|
import core.RPManager;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package main;
|
|||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import core.DEPRECATED_Config;
|
import core.Config;
|
||||||
import core.DatabaseManager;
|
import core.DatabaseManager;
|
||||||
import core.RPManager;
|
import core.RPManager;
|
||||||
import core.Stats;
|
import core.Stats;
|
||||||
@@ -74,7 +74,7 @@ public class Superintendent
|
|||||||
public static boolean perCommandUpkeepPre()
|
public static boolean perCommandUpkeepPre()
|
||||||
{
|
{
|
||||||
// Upkeep the config file monitoring
|
// Upkeep the config file monitoring
|
||||||
DEPRECATED_Config.instance.upkeep();
|
Config.instance.upkeep();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user