342 lines
12 KiB
Java
342 lines
12 KiB
Java
/*
|
|
*
|
|
* ConfigManager
|
|
*
|
|
* This class is the central configuration file manager for all other classes and acts as a utility class for other classes to use.
|
|
* It is typical to define this class as a general object (not static instance) for each class in single-threaded actions. If you need
|
|
* a special function or action from this class; it is recommended to add it to this class and not make your own.
|
|
*
|
|
*
|
|
*/
|
|
|
|
package jesse.keeblarcraft.ConfigMgr;
|
|
|
|
import java.io.FileWriter;
|
|
import java.io.File;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.nio.file.Paths;
|
|
|
|
import com.google.common.base.Charsets;
|
|
import com.google.common.io.Files;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
import com.google.gson.JsonIOException;
|
|
import com.google.gson.JsonSyntaxException;
|
|
|
|
import java.util.List;
|
|
|
|
import org.apache.commons.io.FileUtils;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
|
|
import jesse.keeblarcraft.Keeblarcraft;
|
|
import net.minecraft.nbt.NbtCompound;
|
|
import net.minecraft.nbt.NbtIo;
|
|
import net.minecraft.nbt.NbtList;
|
|
|
|
public class ConfigManager {
|
|
// Pedantic empty constructor
|
|
private static final String GLOBAL_CONFIG = "config/keeblarcraft/";
|
|
|
|
public ConfigManager() {}
|
|
|
|
// Get a File reference to a file that is created on disk
|
|
private File GetFile(String confFile) {
|
|
File file = null;
|
|
try {
|
|
file = new File(GLOBAL_CONFIG + confFile);
|
|
} catch (Exception e) {}
|
|
return file;
|
|
}
|
|
|
|
// Returns the parent path to a given input.
|
|
// Ex: /home/Downloads/file.txt will return /home/Downloads/
|
|
// Ex: /home/Downloads will return /home/
|
|
// Ex: / will return /
|
|
private String GetPathOfFile(String file) {
|
|
String pathToFile = "";
|
|
if (file != null) {
|
|
for (int i = file.length() - 1; i >= 0; i--) {
|
|
if (file.charAt(i) != File.separatorChar) {
|
|
continue;
|
|
}
|
|
else {
|
|
// Trim and break
|
|
pathToFile = file.substring(0, i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
System.out.println("PathOfFile: " + pathToFile);
|
|
return pathToFile;
|
|
}
|
|
|
|
// Creates a directory and all necessary parent directories listed in dirname (under global config area)
|
|
public Boolean CreateDirectory(String dirName) {
|
|
Boolean success = false;
|
|
File directory = GetFile(dirName);
|
|
|
|
try {
|
|
if (directory != null) {
|
|
if (!directory.exists())
|
|
{
|
|
success = directory.mkdirs();
|
|
} else if (directory.isDirectory()) {
|
|
success = true;
|
|
} else {
|
|
System.out.println("Directory " + dirName + " is an already existing file!");
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
System.out.println("Failed to create directory with name " + dirName);
|
|
e.printStackTrace();
|
|
}
|
|
return success;
|
|
}
|
|
|
|
// Create a file on the disk
|
|
public Boolean CreateFile(String fileName) {
|
|
Boolean success = false;
|
|
File file = GetFile(fileName);
|
|
String parentDir = GetPathOfFile(fileName);
|
|
|
|
// CreateDirectory will verify that the parent directories exist & at least the parent directory is in fact a directory
|
|
if (file != null && !file.exists() && CreateDirectory(parentDir)) {
|
|
try {
|
|
success = file.createNewFile();
|
|
} catch (Exception e) {
|
|
System.out.println("Failed to create file " + fileName);
|
|
e.printStackTrace();
|
|
}
|
|
} else {
|
|
System.out.println("CreateFile failed to finish. File may have been null (empty string input, unlikely), or parent directories could not be created/have overlapped name");
|
|
success = false;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
public Boolean DeleteFile(String fileName) {
|
|
Boolean success = false;
|
|
File file = GetFile(fileName);
|
|
|
|
success = !file.exists();
|
|
|
|
if (!success) {
|
|
try {
|
|
success = file.delete();
|
|
} catch (Exception e) {
|
|
System.out.println("Failed to delete file " + fileName);
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn WriteNbtListToFile
|
|
///
|
|
/// @param[in] fileName is the file location to write to
|
|
///
|
|
/// @param[in] key is the compound key type to store
|
|
///
|
|
/// @param[in] data is the NbtList to write
|
|
///
|
|
/// @brief Writes NbtList data to disk
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void WriteNbtListToFile(String fileName, String key, NbtList data) {
|
|
// fileName = "config/keeblarcraft/" + fileName;
|
|
|
|
File file = GetFile(fileName);
|
|
if (!file.exists()) {
|
|
file.getParentFile().mkdirs();
|
|
}
|
|
|
|
try {
|
|
NbtCompound compound = new NbtCompound();
|
|
compound.put(key, data);
|
|
NbtIo.writeCompressed(compound, file);
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn ReadAllNbtListFromDirectory
|
|
///
|
|
/// @param[in] dir is the directory path to read from
|
|
///
|
|
/// @param[in] listType is the NBT Compound list type
|
|
///
|
|
/// @brief Reads in NBTList data from a directory; using file names as key.
|
|
/// If a file is read in correctly, the file is deleted
|
|
///
|
|
/// @return A map of NbtList data with the key being the file name (minus ext)
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public HashMap<String, NbtList> ReadAllNbtListFromDirectory(String dir, int listType) {
|
|
HashMap<String, NbtList> list = new HashMap<String, NbtList>();
|
|
// dir = "config/keeblarcraft/" + dir;
|
|
|
|
File directory = GetFile(dir);
|
|
|
|
File[] files = directory.listFiles();
|
|
|
|
if (files != null) {
|
|
for (File file : files) {
|
|
String key = file.getName().substring(0, file.getName().length() - 4);
|
|
NbtList nbtList = ReadNbtListFromFile(file, key, listType);
|
|
|
|
if (nbtList != null) {
|
|
// Subtract out '.nbt' from name
|
|
list.put(key, nbtList);
|
|
file.delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn ReadNbtListFromFile
|
|
///
|
|
/// @param[in] file handler object to read nbt list data from
|
|
///
|
|
/// @param[in] key for the nbt compound object
|
|
///
|
|
/// @param[in] listType is the NBT Compound list type
|
|
///
|
|
/// @brief Reads in NBTList data from a single file
|
|
///
|
|
/// @return NbtList data
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public NbtList ReadNbtListFromFile(File file, String key, int listType) {
|
|
NbtList list = null;
|
|
|
|
try {
|
|
NbtCompound c = NbtIo.readCompressed(file);
|
|
list = c.getList(key, listType);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
// WriteToFile
|
|
//
|
|
// Will write or append to file (valid modes: "w" or "a") if file is available. Returns false if not
|
|
public Boolean WriteToFile(String fileName, String data, String mode) {
|
|
Boolean ret = false;
|
|
|
|
FileWriter file;
|
|
try {
|
|
file = new FileWriter(GetFile(fileName));
|
|
switch(mode) {
|
|
case "w":
|
|
file.write(data);
|
|
ret = true;
|
|
break;
|
|
case "a":
|
|
file.append(data);
|
|
ret = true;
|
|
break;
|
|
default:
|
|
Keeblarcraft.LOGGER.debug("Invalid mode to WriteToFile!!");
|
|
break;
|
|
}
|
|
|
|
file.close();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
Keeblarcraft.LOGGER.error("Could not open file " + fileName + " to write to it! Possible permissions issue??");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
// WriteToJsonFile
|
|
//
|
|
// Will write to or append to a json file. It will search if the key exists first & update the field;
|
|
// or add a new entry. It should be noted that json objects *can* be buried inside each other. It is
|
|
// considered best (and only) practice to call the "GetJsonStringFromFile" function first from this
|
|
// class and simply iterate to what you would need and then update the entire entry alongside the
|
|
// top-level key.
|
|
//
|
|
// NOTE: THIS DOES NOT SAFE UPDATE THE KEY OBJECT. PRE-EXISTING DATA WILL BE DELETED FOREVER
|
|
public void WriteToJsonFile(String fileName, Object data) {
|
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
|
try {
|
|
// The FileWriter cannot create objects; so we create parent directories before writing. This may be
|
|
// changed in the future
|
|
File parent = GetFile(fileName).getParentFile();
|
|
if (!parent.exists()) {
|
|
parent.mkdirs();
|
|
}
|
|
|
|
FileWriter writer = new FileWriter(GetFile(fileName));
|
|
gson.toJson(data, writer);
|
|
writer.flush();
|
|
writer.close();
|
|
} catch (JsonIOException | IOException e) {
|
|
Keeblarcraft.LOGGER.error("Could not successfully write to json file ["+fileName+"]");
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
// GetJsonStringFromFile
|
|
//
|
|
// Retrieves json file and converts to desired object. Returns JsonSyntaxException if file could not be fitted to class input
|
|
public <T> T GetJsonObjectFromFile(String fileName, Class<T> classToConvertTo) throws JsonSyntaxException {
|
|
Gson gson = new Gson();
|
|
String ret = "";
|
|
|
|
// hot fix: Not sure how to return "false" for invalid conversion when I'm forced to convert or just catch... Look into a better
|
|
// return value in the future - but for now throw JsonSyntaxException no matter what exception is caught
|
|
try {
|
|
File file = GetFile(fileName);
|
|
ret = FileUtils.readFileToString(file, "UTF-8");
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
System.out.println("Caught an exception in retrieving JSON Object from file " + fileName);
|
|
// throw new JsonSyntaxException("");
|
|
}
|
|
|
|
return gson.fromJson(ret, classToConvertTo);
|
|
}
|
|
|
|
public Boolean DoesFileExist(String fileName) {
|
|
return GetFile(fileName).exists();
|
|
}
|
|
|
|
public Boolean DoesDirectoryExist(String dirName) {
|
|
File file = GetFile(dirName);
|
|
return file != null && file.isDirectory();
|
|
}
|
|
|
|
public Boolean DeleteDirectory(String dirName) {
|
|
return DeleteFile(dirName);
|
|
}
|
|
|
|
// GetFile
|
|
//
|
|
// Returns a file as an arraylist of all the lines in the file. Generally only used for testing
|
|
//
|
|
// NOTE: Returns UTF-8 Encoding of file
|
|
public List<String> GetFileLines(String fileName) {
|
|
List<String> ret = new ArrayList<String>();
|
|
|
|
try {
|
|
return Files.readLines(GetFile(fileName), Charsets.UTF_8);
|
|
} catch (IOException e) {
|
|
ret.clear();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
}
|