= Updated initialization of ObjectBuilderFactory to include localizers

This commit is contained in:
Matthew Cech
2019-04-14 00:29:31 -07:00
parent f00160714a
commit 841cc51ed1
6 changed files with 80 additions and 46 deletions
+17
View File
@@ -0,0 +1,17 @@
package core;
import java.util.HashMap;
public class CommandEnabler
{
// Config/const variables
public static final String filename = "commands.config";
// Local variables
private HashMap<String, Boolean> enabledMap;
public CommandEnabler()
{
enabledMap = new HashMap<>();
}
}
+3 -3
View File
@@ -8,7 +8,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import dataStructures.SectionedKeyValueStore; import dataStructures.TaggedPairStore;
import utils.FileUtils; import utils.FileUtils;
import utils.GlobalLog; import utils.GlobalLog;
import utils.LogFilter; import utils.LogFilter;
@@ -25,7 +25,7 @@ public abstract class LocBase
public final String functionName; // Example: "Localizer.Stub"; public final String functionName; // Example: "Localizer.Stub";
// Local translation storage // Local translation storage
private SectionedKeyValueStore stringStore; 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); }
@@ -139,7 +139,7 @@ public abstract class LocBase
file.createNewFile(); file.createNewFile();
} }
stringStore = new SectionedKeyValueStore(fileContents); stringStore = new TaggedPairStore(fileContents);
} }
catch(IOException e) catch(IOException e)
{ {
+12
View File
@@ -1,8 +1,12 @@
package core; package core;
import java.util.ArrayList;
import utils.GlobalLog; import utils.GlobalLog;
import utils.LogFilter; import utils.LogFilter;
import dataStructures.Pair;
// Performs the same localization for the strings associated with command names as
// is performed with general strings in the application
public class LocCommands extends LocBase public class LocCommands extends LocBase
{ {
public static final String fileName = "locCommands.config"; public static final String fileName = "locCommands.config";
@@ -34,4 +38,12 @@ public class LocCommands extends LocBase
{ {
return instance.GetKey(toStub); return instance.GetKey(toStub);
} }
// Gets all of the un-translated defaults in the commands list.
public static ArrayList<String> GetUnlocalizedCommands()
{
ArrayList<String> raw = new ArrayList<>();
instance.stringStore.ForEach((pair) -> raw.add((String)((Pair<?, ?>)pair).First ));
return raw;
}
} }
+19 -6
View File
@@ -34,9 +34,17 @@ public class ObjectBuilderFactory
// RPManger for tracking RP system // RPManger for tracking RP system
private static RPManager rpManager; private static RPManager rpManager;
// Lazy initialization style for // Localization classes - these are singletons, but should be initialized before almost all other
// things so their inclusion in the factory is to ensure they're started at the correct time.
@SuppressWarnings("unused") private static Localizer locStrings;
@SuppressWarnings("unused") private static LocCommands locCommands;
// Lazy initialization multithreaded mutex stuff to prevent explosions.
// TODO: Investigate using 'synchronized' instead potentially
private static boolean hasInitialized; private static boolean hasInitialized;
private static Semaphore initMutex = new Semaphore(1); private static Semaphore initMutex = new Semaphore(1);
// This is it, this is how the lazy init starts!
private static void LazyInit() private static void LazyInit()
{ {
if(hasInitialized) if(hasInitialized)
@@ -47,26 +55,31 @@ public class ObjectBuilderFactory
initMutex.acquire(); initMutex.acquire();
try try
{ {
// Initialization here. This is where we could read from something external. // structure initialization
// Construct necessary data structures.
guildCache = new HashMap<String, KittyGuild>(); guildCache = new HashMap<String, KittyGuild>();
userCache = new HashMap<String, KittyUser>(); userCache = new HashMap<String, KittyUser>();
channelCache = new HashMap<String, KittyChannel>(); channelCache = new HashMap<String, KittyChannel>();
database = null; database = null;
stats = null; stats = null;
// Start by reading from things that are external. Because
// we require these things to be resolved before the rest of the application,
// we place them here.
locStrings = new Localizer();
locCommands = new LocCommands();
} }
finally finally
{ {
initMutex.release(); initMutex.release();
hasInitialized = true;
} }
} }
catch(InterruptedException ie) catch(InterruptedException ie)
{ {
GlobalLog.Error(LogFilter.Core, "Issue during object builder lazy initialization." GlobalLog.Error(LogFilter.Core, "Issue during object builder lazy initialization."
+ " The factory was not initialized, " + " The factory was not initialized, and kitty will not be able to continue functionally.");
+ "and kitty will not be able to continue functionally.");
} }
hasInitialized = true;
} }
// Explicitly locks: guildCache // Explicitly locks: guildCache
@@ -18,25 +18,25 @@ import java.util.function.Consumer;
// Note that the sections are NOT designed to allow for duplicate keys across them. // 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. // 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. // The only value not allowed in a key or value is the KeyValueSplit.
public class SectionedKeyValueStore public class TaggedPairStore
{ {
// Variables // Variables
public final char SectionStart = '['; public final char SectionStart = '[';
public final char SectionEnd = ']'; public final char SectionEnd = ']';
public final char KeyValueLineSeparator = '\n'; public final char PairLineSeparator = '\n';
public final String KeyValueSplit = "="; public final String PairSplit = "=";
// [Key: SectionName, [Key: KeyString, Value: ValueString]] // [Key: SectionName, [Key: KeyString, Value: ValueString]]
private HashMap<String, HashMap<String, String>> sectionKeyValue; private HashMap<String, HashMap<String, String>> taggedPairs;
// [Key: KeyString, Value: ValueString]] // [Key: KeyString, Value: ValueString]]
private HashMap<String, String> keyValue; private HashMap<String, String> allPairs;
// String constructor that parses the input string into the object // String constructor that parses the input string into the object
public SectionedKeyValueStore(String input) public TaggedPairStore(String input)
{ {
sectionKeyValue = new HashMap<String, HashMap<String, String>>(); taggedPairs = new HashMap<String, HashMap<String, String>>();
keyValue = new HashMap<String, String>(); allPairs = new HashMap<String, String>();
Parse(input); Parse(input);
} }
@@ -44,7 +44,7 @@ public class SectionedKeyValueStore
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public void ForEach(BiConsumer<? super String, Pair<? super String, ? super String>> action) public void ForEach(BiConsumer<? super String, Pair<? super String, ? super String>> action)
{ {
Iterator it = sectionKeyValue.entrySet().iterator(); Iterator it = taggedPairs.entrySet().iterator();
while (it.hasNext()) while (it.hasNext())
{ {
Map.Entry pair = (Map.Entry)it.next(); Map.Entry pair = (Map.Entry)it.next();
@@ -62,7 +62,7 @@ public class SectionedKeyValueStore
@SuppressWarnings({"rawtypes"}) @SuppressWarnings({"rawtypes"})
public void ForEach(Consumer<Pair<? super String, ? super String>> action) public void ForEach(Consumer<Pair<? super String, ? super String>> action)
{ {
Iterator it = keyValue.entrySet().iterator(); Iterator it = allPairs.entrySet().iterator();
while (it.hasNext()) while (it.hasNext())
{ {
Map.Entry pair = (Map.Entry)it.next(); Map.Entry pair = (Map.Entry)it.next();
@@ -79,11 +79,11 @@ public class SectionedKeyValueStore
String out = ""; String out = "";
// Iterates over the sections and // Iterates over the sections and
Iterator it = sectionKeyValue.entrySet().iterator(); Iterator it = taggedPairs.entrySet().iterator();
while (it.hasNext()) while (it.hasNext())
{ {
Map.Entry pair = (Map.Entry)it.next(); Map.Entry pair = (Map.Entry)it.next();
out += ("" + SectionStart + pair.getKey() + SectionEnd + KeyValueLineSeparator); out += ("" + SectionStart + pair.getKey() + SectionEnd + PairLineSeparator);
Iterator internal = ((HashMap<String, String>)pair.getValue()).entrySet().iterator(); Iterator internal = ((HashMap<String, String>)pair.getValue()).entrySet().iterator();
while(internal.hasNext()) while(internal.hasNext())
@@ -93,12 +93,12 @@ public class SectionedKeyValueStore
String value = (String)internalPair.getValue(); String value = (String)internalPair.getValue();
if(key == value) if(key == value)
out += (key + KeyValueSplit) + KeyValueLineSeparator; out += (key + PairSplit) + PairLineSeparator;
else else
out += (key + KeyValueSplit + value) + KeyValueLineSeparator; out += (key + PairSplit + value) + PairLineSeparator;
} }
out += KeyValueLineSeparator; out += PairLineSeparator;
} }
return out; return out;
@@ -131,21 +131,21 @@ public class SectionedKeyValueStore
// Parse out the pairs within the section, split them all out. // Parse out the pairs within the section, split them all out.
String unparsedPairs = section.substring(pos + 1); String unparsedPairs = section.substring(pos + 1);
String[] pairs = unparsedPairs.split("\\" + KeyValueLineSeparator); String[] pairs = unparsedPairs.split("\\" + PairLineSeparator);
// Parse out valid key-value pairs, and store them in the specified section. // 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. // At this point, we can be guarenteed that sectionName is in the Hashmap.
for(int pair = 0; pair < pairs.length; ++pair) for(int pair = 0; pair < pairs.length; ++pair)
{ {
String line = pairs[pair]; String line = pairs[pair];
int splitPos = line.indexOf(KeyValueSplit); int splitPos = line.indexOf(PairSplit);
if(splitPos < 0) if(splitPos < 0)
continue; continue;
String key = line.substring(0, splitPos); String key = line.substring(0, splitPos);
String value = line.substring(splitPos + KeyValueSplit.length()); String value = line.substring(splitPos + PairSplit.length());
sectionKeyValue.get(sectionName).putIfAbsent(key, value); taggedPairs.get(sectionName).putIfAbsent(key, value);
keyValue.putIfAbsent(key, value); allPairs.putIfAbsent(key, value);
} }
} }
} }
@@ -165,28 +165,28 @@ public class SectionedKeyValueStore
public void AddKeyValue(String sectionName, String key, String value) public void AddKeyValue(String sectionName, String key, String value)
{ {
AddSection(sectionName); AddSection(sectionName);
sectionKeyValue.get(sectionName).putIfAbsent(key, value); taggedPairs.get(sectionName).putIfAbsent(key, value);
keyValue.putIfAbsent(key, value); allPairs.putIfAbsent(key, value);
} }
// Adds a given section to the hashmap if it's not already present // Adds a given section to the hashmap if it's not already present
public void AddSection(String sectionName) public void AddSection(String sectionName)
{ {
sectionKeyValue.putIfAbsent(sectionName, new HashMap<String, String>()); taggedPairs.putIfAbsent(sectionName, new HashMap<String, String>());
} }
// Returns a HashMap of Keys to Values for a given section // Returns a HashMap of Keys to Values for a given section
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public HashMap<String, String> GetSection(String sectionName) public HashMap<String, String> GetSection(String sectionName)
{ {
return (HashMap<String, String>) sectionKeyValue.get(sectionName).clone(); return (HashMap<String, String>) taggedPairs.get(sectionName).clone();
} }
// Look up a global key // Look up a global key
public String GetKey(String key) public String GetKey(String key)
{ {
if(keyValue.containsKey(key)) if(allPairs.containsKey(key))
return keyValue.get(key); return allPairs.get(key);
return null; return null;
} }
+1 -9
View File
@@ -13,7 +13,6 @@ import net.dv8tion.jda.core.entities.*;
import net.dv8tion.jda.core.events.message.guild.*; import net.dv8tion.jda.core.events.message.guild.*;
import net.dv8tion.jda.core.hooks.ListenerAdapter; import net.dv8tion.jda.core.hooks.ListenerAdapter;
import offline.*; import offline.*;
import core.Localizer;
import utils.GlobalLog; import utils.GlobalLog;
import net.dv8tion.jda.core.*; import net.dv8tion.jda.core.*;
@@ -29,18 +28,11 @@ public class Main extends ListenerAdapter
private static DatabaseManager databaseManager; private static DatabaseManager databaseManager;
private static Stats stats; private static Stats stats;
private static RPManager rpManager; private static RPManager rpManager;
private static Localizer locStrings;
private static LocCommands locCommands;
// Main test location // Main test location
public static void main(String[] args) throws InterruptedException, LoginException, Exception public static void main(String[] args) throws InterruptedException, LoginException, Exception
{ {
// Localizer startup - Potentially integrate with the factory. Needs to happen first tho. // Factory startup. The ordering is intentional.
locStrings = new Localizer();
locCommands = new LocCommands();
// Factory startup
databaseManager = ObjectBuilderFactory.ConstructDatabaseManager(); databaseManager = ObjectBuilderFactory.ConstructDatabaseManager();
commandManager = ObjectBuilderFactory.ConstructCommandManager(); commandManager = ObjectBuilderFactory.ConstructCommandManager();
rpManager = ObjectBuilderFactory.ConstructRPManager(); rpManager = ObjectBuilderFactory.ConstructRPManager();