Skip to content

Commit

Permalink
リファクタリング
Browse files Browse the repository at this point in the history
  • Loading branch information
Maru32768 committed Jan 4, 2023
1 parent 44fcf7e commit e739bee
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 179 deletions.
76 changes: 7 additions & 69 deletions bukkit/src/main/java/net/kunmc/lab/configlib/BaseConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,13 @@
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Team;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.Modifier;
import java.nio.file.*;
import java.util.*;

import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import java.util.Set;
import java.util.TimerTask;

public abstract class BaseConfig extends CommonBaseConfig implements Listener {
private static final Gson gson = new GsonBuilder().setPrettyPrinting()
Expand All @@ -44,60 +39,16 @@ public abstract class BaseConfig extends CommonBaseConfig implements Listener {
.registerTypeHierarchyAdapter(Set.class, new SetTypeAdapter())
.create();
private final transient Plugin plugin;
private final transient List<Runnable> onInitializeListeners = new ArrayList<>();

public BaseConfig(@NotNull Plugin plugin) {
this(plugin, true);
}

public BaseConfig(@NotNull Plugin plugin, boolean makeConfigFile) {
this.plugin = plugin;
this.makeConfigFile = makeConfigFile;

if (!makeConfigFile) {
return;
}
plugin.getDataFolder()
.mkdir();

// コンストラクタの処理内でシリアライズするとフィールドの初期化が終わってない状態でシリアライズされるため遅延させている.
new BukkitRunnable() {
@Override
public void run() {
saveConfigIfAbsent();
loadConfig();
onInitializeListeners.forEach(Runnable::run);
}
}.runTask(plugin);

Timer timer = new Timer();
WatchService watcher;
WatchKey watchKey;
try {
watcher = FileSystems.getDefault()
.newWatchService();
watchKey = plugin.getDataFolder()
.toPath()
.register(watcher, ENTRY_MODIFY);

timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
for (WatchEvent<?> e : watchKey.pollEvents()) {
Path filePath = plugin.getDataFolder()
.toPath()
.resolve((Path) e.context());
if (filePath.equals(getConfigFile().toPath())) {
loadConfig();
}
}

watchKey.reset();
}
}, 0, 500);
} catch (IOException e) {
e.printStackTrace();
throw new UncheckedIOException(e);
}
init();

// Pluginがenabledになっていない状態でregisterすると例外が発生するため遅延,ループさせている
timer.scheduleAtFixedRate(new TimerTask() {
Expand All @@ -109,13 +60,7 @@ public void run() {
@EventHandler
public void onPluginDisable(PluginDisableEvent e) {
if (e.getPlugin() == plugin) {
try {
timer.cancel();
watcher.close();
watchKey.cancel();
} catch (IOException ex) {
ex.printStackTrace();
}
close();
}
}
}, plugin);
Expand All @@ -126,13 +71,6 @@ public void onPluginDisable(PluginDisableEvent e) {
}, 100, 100);
}

/**
* set listener fired on initialization.
*/
protected final void onInitialize(Runnable onLoad) {
onInitializeListeners.add(onLoad);
}

public Plugin plugin() {
return plugin;
}
Expand All @@ -143,7 +81,7 @@ protected Gson gson() {
}

@Override
public File getConfigFile() {
return new File(plugin.getDataFolder(), entryName() + ".json");
File getConfigFolder() {
return plugin.getDataFolder();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.kunmc.lab.configlib.BaseConfig;
import net.kunmc.lab.configlib.value.UUIDValue;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;

Expand All @@ -10,5 +11,9 @@ public class Config extends BaseConfig {

public Config(@NotNull Plugin plugin) {
super(plugin);

onInitialize(() -> {
Bukkit.broadcastMessage("config initialize");
});
}
}
124 changes: 103 additions & 21 deletions common/src/main/java/net/kunmc/lab/configlib/CommonBaseConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.io.Files;
import com.google.gson.Gson;
import net.kunmc.lab.configlib.util.ConfigUtil;
import org.codehaus.plexus.util.ReflectionUtils;
import org.jetbrains.annotations.NotNull;

Expand All @@ -14,49 +15,112 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Collectors;

import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

public abstract class CommonBaseConfig {
protected transient boolean enableGet = true;
protected transient boolean enableList = true;
protected transient boolean enableModify = true;
protected transient boolean enableReload = true;
transient boolean makeConfigFile = true;
private transient volatile boolean initialized = false;
private transient String entryName = "";
private final transient List<Runnable> onInitializeListeners = new ArrayList<>();
protected final transient Timer timer = new Timer();
private transient WatchService watchService;
private transient WatchKey watchKey;

protected CommonBaseConfig() {
String s = getClass().getSimpleName();
this.entryName = s.substring(0, 1)
.toLowerCase() + s.substring(1);
}

protected void setEntryName(@NotNull String entryName) {
this.entryName = entryName;
}

public String entryName() {
if (entryName.equals("")) {
String n = getClass().getSimpleName();
return n.substring(0, 1)
.toLowerCase() + n.substring(1);
} else {
return entryName;
public final String entryName() {
return entryName;
}

final void init() {
if (!makeConfigFile) {
return;
}
getConfigFolder().mkdirs();

try {
watchService = FileSystems.getDefault()
.newWatchService();
watchKey = getConfigFolder().toPath()
.register(watchService, ENTRY_MODIFY);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
for (WatchEvent<?> e : watchKey.pollEvents()) {
Path filePath = getConfigFolder().toPath()
.resolve((Path) e.context());
if (filePath.equals(getConfigFile().toPath())) {
loadConfig();
}
}
watchKey.reset();
}
}, 0, 500);
} catch (IOException e) {
throw new UncheckedIOException(e);
}

// コンストラクタの処理内でシリアライズすると子クラスのフィールドの初期化が終わってない状態でシリアライズされるため別スレッドでループ待機させている.
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
List<Value<?, ?>> values = ConfigUtil.getValues(CommonBaseConfig.this);
if (values.stream()
.allMatch(Objects::nonNull)) {
saveConfigIfAbsent();
loadConfig();
cancel();
}
}
}, 0, 1);
}

/**
* set listener fired on initialization.
*/
protected final void onInitialize(Runnable onLoad) {
onInitializeListeners.add(onLoad);
}

boolean isGetEnabled() {
final boolean isGetEnabled() {
return enableGet;
}

boolean isListEnabled() {
final boolean isListEnabled() {
return enableList;
}

boolean isModifyEnabled() {
final boolean isModifyEnabled() {
return enableModify;
}

boolean isReloadEnabled() {
final boolean isReloadEnabled() {
return enableReload;
}

protected abstract Gson gson();

public abstract File getConfigFile();
abstract File getConfigFolder();

public final File getConfigFile() {
return new File(getConfigFolder(), entryName() + ".json");
}

protected void saveConfig() {
try {
Expand All @@ -79,21 +143,39 @@ protected void saveConfigIfPresent() {
}
}

protected boolean loadConfig() {
protected final synchronized boolean loadConfig() {
if (!getConfigFile().exists()) {
return false;
}

CommonBaseConfig config = gson().fromJson(readJson(getConfigFile()), this.getClass());
replaceFields(this.getClass(), config, this);
if (!initialized) {
onInitializeListeners.forEach(Runnable::run);
initialized = true;
}
return true;
}

public static <T extends CommonBaseConfig> T newInstanceFrom(@NotNull File configJSON,
protected final void close() {
try {
timer.cancel();
if (watchService != null) {
watchService.close();
}
if (watchKey != null) {
watchKey.cancel();
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public static <T extends CommonBaseConfig> T newInstanceFrom(@NotNull File jsonFile,
@NotNull Constructor<T> constructor,
Object... arguments) {
String filename = configJSON.getName();
String json = readJson(configJSON);
String filename = jsonFile.getName();
String json = readJson(jsonFile);
Class<T> clazz = constructor.getDeclaringClass();

try {
Expand All @@ -109,7 +191,7 @@ public static <T extends CommonBaseConfig> T newInstanceFrom(@NotNull File confi
}
}

protected static String readJson(File jsonFile) {
private static String readJson(File jsonFile) {
try {
return Files.readLines(jsonFile, StandardCharsets.UTF_8)
.stream()
Expand All @@ -119,7 +201,7 @@ protected static String readJson(File jsonFile) {
}
}

protected static void writeJson(File jsonFile, String json) {
private static void writeJson(File jsonFile, String json) {
try (OutputStreamWriter writer = new OutputStreamWriter(java.nio.file.Files.newOutputStream(jsonFile.toPath()),
StandardCharsets.UTF_8)) {
writer.write(json);
Expand All @@ -128,7 +210,7 @@ protected static void writeJson(File jsonFile, String json) {
}
}

protected static void replaceFields(Class<?> clazz, Object src, Object dst) {
private static void replaceFields(Class<?> clazz, Object src, Object dst) {
for (Field field : ReflectionUtils.getFieldsIncludingSuperclasses(clazz)) {
if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())) {
continue;
Expand All @@ -149,7 +231,7 @@ protected static void replaceFields(Class<?> clazz, Object src, Object dst) {
}
}

protected static void replaceField(Field field, Object src, Object dst) throws IllegalAccessException {
private static void replaceField(Field field, Object src, Object dst) throws IllegalAccessException {
try {
List<Field> fieldList = ReflectionUtils.getFieldsIncludingSuperclasses(field.getType());
Object srcObj = field.get(src);
Expand Down
Loading

0 comments on commit e739bee

Please sign in to comment.