0

code style: tabs -> spaces

This commit is contained in:
2021-01-08 21:00:00 +03:00
parent 16ae1743c7
commit 36fc374356
24 changed files with 1059 additions and 1059 deletions

View File

@@ -229,7 +229,7 @@ _Отменяет действие указателя `useOnlyConsole`_
```java ```java
CommandManager.Builder builder = CommandManager.create("start") CommandManager.Builder builder = CommandManager.create("start")
.useOnlyPlayer("Команду могут использовать только игроки"); .useOnlyPlayer("Команду могут использовать только игроки");
``` ```
### useOnlyConsole ### useOnlyConsole
@@ -240,7 +240,7 @@ _Отменяет действие указателя `useOnlyPlayer`_
```java ```java
CommandManager.Builder builder = CommandManager.create("start") CommandManager.Builder builder = CommandManager.create("start")
.useOnlyConsole(ChatColor.RED + "Команду можно использовать только в консоли"); .useOnlyConsole(ChatColor.RED + "Команду можно использовать только в консоли");
``` ```
### register ### register

View File

@@ -19,129 +19,129 @@ import java.util.UUID;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class BuildHelper { public class BuildHelper {
private final Class<?> CLASS_BLOCKPOSITION = getClassForName("net.minecraft.server.v1_12_R1.BlockPosition"); private final Class<?> CLASS_BLOCKPOSITION = getClassForName("net.minecraft.server.v1_12_R1.BlockPosition");
private final Class<?> CLASS_GAMEPROFILE = getClassForName("com.mojang.authlib.GameProfile"); private final Class<?> CLASS_GAMEPROFILE = getClassForName("com.mojang.authlib.GameProfile");
/** /**
* Установка черепа. * Установка черепа.
* <p> * <p>
* После установки, необходимо выполнить <code>skull.update(true);</code> * После установки, необходимо выполнить <code>skull.update(true);</code>
* *
* @param location место установки. * @param location место установки.
* @param face куда будет повёрнут череп. * @param face куда будет повёрнут череп.
* @return Блок типа {@link Skull} * @return Блок типа {@link Skull}
*/ */
public Skull placeSkull(Location location, BlockFace face) { public Skull placeSkull(Location location, BlockFace face) {
Location fixedLocation = GhastTools.copyLocation(location); Location fixedLocation = GhastTools.copyLocation(location);
fixedLocation.setZ(fixedLocation.getZ() - 1); fixedLocation.setZ(fixedLocation.getZ() - 1);
Block block = location.getWorld().getBlockAt(location); Block block = location.getWorld().getBlockAt(location);
block.setType(Material.SKULL); block.setType(Material.SKULL);
Skull skull = (Skull) block.getState(); Skull skull = (Skull) block.getState();
skull.setRotation(face); skull.setRotation(face);
org.bukkit.material.Skull skullMaterial = (org.bukkit.material.Skull) skull.getData(); org.bukkit.material.Skull skullMaterial = (org.bukkit.material.Skull) skull.getData();
skullMaterial.setFacingDirection(BlockFace.SELF); skullMaterial.setFacingDirection(BlockFace.SELF);
return skull; return skull;
} }
/** /**
* Установка головы игрока. * Установка головы игрока.
* <p> * <p>
* После установки, необходимо выполнить <code>skull.update(true);</code> * После установки, необходимо выполнить <code>skull.update(true);</code>
* *
* @param location место установки. * @param location место установки.
* @param face куда будет повёрнута голова. * @param face куда будет повёрнута голова.
* @return Блок типа {@link Skull} * @return Блок типа {@link Skull}
*/ */
public static Skull placePlayerHead(Location location, BlockFace face) { public static Skull placePlayerHead(Location location, BlockFace face) {
Location fixedLocation = GhastTools.copyLocation(location); Location fixedLocation = GhastTools.copyLocation(location);
fixedLocation.setZ(fixedLocation.getZ() - 1); fixedLocation.setZ(fixedLocation.getZ() - 1);
Block block = fixedLocation.getWorld().getBlockAt(fixedLocation); Block block = fixedLocation.getWorld().getBlockAt(fixedLocation);
block.setType(Material.SKULL); block.setType(Material.SKULL);
Skull skull = (Skull) block.getState(); Skull skull = (Skull) block.getState();
skull.setSkullType(SkullType.PLAYER); skull.setSkullType(SkullType.PLAYER);
skull.setRotation(face); skull.setRotation(face);
org.bukkit.material.Skull skullMaterial = (org.bukkit.material.Skull) skull.getData(); org.bukkit.material.Skull skullMaterial = (org.bukkit.material.Skull) skull.getData();
skullMaterial.setFacingDirection(BlockFace.SELF); skullMaterial.setFacingDirection(BlockFace.SELF);
return skull; return skull;
} }
/** /**
* Установка текстурированной головы игрока. * Установка текстурированной головы игрока.
* *
* @param location место установки. * @param location место установки.
* @param face куда будет повёрнута голова. * @param face куда будет повёрнута голова.
* @param skinUrl URL на текстуру * @param skinUrl URL на текстуру
* @return Блок типа {@link Skull} * @return Блок типа {@link Skull}
*/ */
public static Skull placePlayerHead(Location location, BlockFace face, String skinUrl) { public static Skull placePlayerHead(Location location, BlockFace face, String skinUrl) {
Skull playerHead = placePlayerHead(location, face); Skull playerHead = placePlayerHead(location, face);
playerHead.update(true); playerHead.update(true);
setPlayerHeadSkin(playerHead, skinUrl); setPlayerHeadSkin(playerHead, skinUrl);
return playerHead; return playerHead;
} }
/** /**
* Установка текстуры для головы игрока. * Установка текстуры для головы игрока.
* *
* @param skull блок головы игрока * @param skull блок головы игрока
* @param skinUrl URL на текстуру * @param skinUrl URL на текстуру
*/ */
public static void setPlayerHeadSkin(Skull skull, String skinUrl) { public static void setPlayerHeadSkin(Skull skull, String skinUrl) {
//TODO заменить рефлексию на "фантомные" классы //TODO заменить рефлексию на "фантомные" классы
ReflectionObject refobjBlockPosition = new ReflectionClass(CLASS_BLOCKPOSITION) ReflectionObject refobjBlockPosition = new ReflectionClass(CLASS_BLOCKPOSITION)
.constructor(double.class, double.class, double.class) .constructor(double.class, double.class, double.class)
.newInstance(skull.getX(), skull.getY(), skull.getZ()); .newInstance(skull.getX(), skull.getY(), skull.getZ());
new ReflectionObject(skull.getWorld()) new ReflectionObject(skull.getWorld())
.method("getHandle").invoke() .method("getHandle").invoke()
.method("getTileEntity", CLASS_BLOCKPOSITION) .method("getTileEntity", CLASS_BLOCKPOSITION)
.invoke(refobjBlockPosition.getOriginalObject()) .invoke(refobjBlockPosition.getOriginalObject())
.method("setGameProfile", CLASS_GAMEPROFILE) .method("setGameProfile", CLASS_GAMEPROFILE)
.invoke(getRefObjPlayerProfile(skinUrl).getOriginalObject()); .invoke(getRefObjPlayerProfile(skinUrl).getOriginalObject());
} }
public Sign placeSignWall(Location location, BlockFace face) { public Sign placeSignWall(Location location, BlockFace face) {
Block block = location.getWorld().getBlockAt(location); Block block = location.getWorld().getBlockAt(location);
block.setType(Material.WALL_SIGN); block.setType(Material.WALL_SIGN);
Sign sign = (Sign) block.getState(); Sign sign = (Sign) block.getState();
org.bukkit.material.Sign signMaterial = (org.bukkit.material.Sign) sign.getData(); org.bukkit.material.Sign signMaterial = (org.bukkit.material.Sign) sign.getData();
signMaterial.setFacingDirection(face); signMaterial.setFacingDirection(face);
return sign; return sign;
} }
private ReflectionObject getRefObjPlayerProfile(String url){ private ReflectionObject getRefObjPlayerProfile(String url){
ReflectionObject refobjProperty = new ReflectionClass( ReflectionObject refobjProperty = new ReflectionClass(
getClassForName("com.mojang.authlib.properties.Property")) getClassForName("com.mojang.authlib.properties.Property"))
.constructor(String.class, String.class) .constructor(String.class, String.class)
.newInstance("textures", Base64.getEncoder() .newInstance("textures", Base64.getEncoder()
.encodeToString(("{textures:{SKIN:{url:\"" + url + "\"}}}").getBytes(StandardCharsets.UTF_8))); .encodeToString(("{textures:{SKIN:{url:\"" + url + "\"}}}").getBytes(StandardCharsets.UTF_8)));
ReflectionObject refobjGameProfile = new ReflectionClass(CLASS_GAMEPROFILE) ReflectionObject refobjGameProfile = new ReflectionClass(CLASS_GAMEPROFILE)
.constructor(UUID.class, String.class) .constructor(UUID.class, String.class)
.newInstance(UUID.randomUUID(), null); .newInstance(UUID.randomUUID(), null);
refobjGameProfile refobjGameProfile
.method("getProperties").invoke() .method("getProperties").invoke()
.method("put", Object.class, Object.class) .method("put", Object.class, Object.class)
.invoke("textures", refobjProperty.getOriginalObject()); .invoke("textures", refobjProperty.getOriginalObject());
return refobjGameProfile; return refobjGameProfile;
} }
private Class<?> getClassForName(String className) { private Class<?> getClassForName(String className) {
try { try {
return Class.forName(className); return Class.forName(className);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
} }

View File

@@ -11,17 +11,17 @@ import org.bukkit.util.Vector;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class EffectsHelper { public class EffectsHelper {
public void playSound(Location location, Sound sound, float pitch) { public void playSound(Location location, Sound sound, float pitch) {
location.getWorld().playSound(location, sound, SoundCategory.MASTER, 1.0f, pitch); location.getWorld().playSound(location, sound, SoundCategory.MASTER, 1.0f, pitch);
} }
public void particle(Location location, Particle particle, double dx, double dy, double dz, double speed, int amount) { public void particle(Location location, Particle particle, double dx, double dy, double dz, double speed, int amount) {
location.getWorld().spawnParticle(particle, location, amount, dx, dy, dz, speed); location.getWorld().spawnParticle(particle, location, amount, dx, dy, dz, speed);
} }
//TODO нужно проверить //TODO нужно проверить
public void particle(Location location, Particle particle, Vector vector, double speed, int amount) { public void particle(Location location, Particle particle, Vector vector, double speed, int amount) {
particle(location, particle, vector.getX(), vector.getY(), vector.getZ(), speed, amount); particle(location, particle, vector.getX(), vector.getY(), vector.getZ(), speed, amount);
} }
} }

View File

@@ -17,55 +17,55 @@ import java.util.function.Consumer;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class EventContext implements Listener { public class EventContext implements Listener {
private static final BooleanSupplier EMPTY_FILTER = () -> true; private static final BooleanSupplier EMPTY_FILTER = () -> true;
private static final Consumer<Cancellable> CANCEL_EVENT = event -> event.setCancelled(true); private static final Consumer<Cancellable> CANCEL_EVENT = event -> event.setCancelled(true);
private final Map<Class<? extends Event>, Consumer<?>> eventMap = new HashMap<>(); private final Map<Class<? extends Event>, Consumer<?>> eventMap = new HashMap<>();
private BooleanSupplier filter = EMPTY_FILTER; private BooleanSupplier filter = EMPTY_FILTER;
public EventContext filter(BooleanSupplier filter) { public EventContext filter(BooleanSupplier filter) {
this.filter = (filter != null ? filter : EMPTY_FILTER); this.filter = (filter != null ? filter : EMPTY_FILTER);
return this; return this;
} }
public <T extends Event> EventContext onEvent(Class<T> eventType, EventPriority eventPriority, Consumer<T> consumer) { public <T extends Event> EventContext onEvent(Class<T> eventType, EventPriority eventPriority, Consumer<T> consumer) {
if (consumer == null) { if (consumer == null) {
eventMap.remove(eventType); eventMap.remove(eventType);
} else { } else {
eventMap.put(eventType, consumer); eventMap.put(eventType, consumer);
bukkitRegisterEvent(eventType, eventPriority); bukkitRegisterEvent(eventType, eventPriority);
} }
return this; return this;
} }
public <T extends Event> EventContext onEvent(Class<T> eventType, Consumer<T> consumer) { public <T extends Event> EventContext onEvent(Class<T> eventType, Consumer<T> consumer) {
return onEvent(eventType, EventPriority.NORMAL, consumer); return onEvent(eventType, EventPriority.NORMAL, consumer);
} }
public <T extends Event & Cancellable> EventContext cancelEvent(Class<T> eventType, EventPriority eventPriority) { public <T extends Event & Cancellable> EventContext cancelEvent(Class<T> eventType, EventPriority eventPriority) {
eventMap.put(eventType, CANCEL_EVENT); eventMap.put(eventType, CANCEL_EVENT);
bukkitRegisterEvent(eventType, eventPriority); bukkitRegisterEvent(eventType, eventPriority);
return this; return this;
} }
public <T extends Event & Cancellable> EventContext cancelEvent(Class<T> eventType) { public <T extends Event & Cancellable> EventContext cancelEvent(Class<T> eventType) {
return cancelEvent(eventType, EventPriority.NORMAL); return cancelEvent(eventType, EventPriority.NORMAL);
} }
private void bukkitRegisterEvent(Class<? extends Event> eventType, EventPriority eventPriority) { private void bukkitRegisterEvent(Class<? extends Event> eventType, EventPriority eventPriority) {
Bukkit.getPluginManager().registerEvent(eventType, this, eventPriority, Bukkit.getPluginManager().registerEvent(eventType, this, eventPriority,
this::eventExecute, GhastTools.getPlugin()); this::eventExecute, GhastTools.getPlugin());
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private void eventExecute(Listener listener, Event event) { private void eventExecute(Listener listener, Event event) {
Consumer consumer = eventMap.get(event.getClass()); Consumer consumer = eventMap.get(event.getClass());
if (consumer != null && filter.getAsBoolean()) { if (consumer != null && filter.getAsBoolean()) {
consumer.accept(event); consumer.accept(event);
} }
} }
public static EventContext create() { public static EventContext create() {
return new EventContext(); return new EventContext();
} }
} }

View File

@@ -14,49 +14,49 @@ import java.lang.ref.WeakReference;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class GhastTools { public class GhastTools {
private static WeakReference<Plugin> refPlugin; private static WeakReference<Plugin> refPlugin;
@SuppressWarnings("java:S2696") @SuppressWarnings("java:S2696")
public void setPlugin(Plugin plugin) { public void setPlugin(Plugin plugin) {
if (plugin == null) { if (plugin == null) {
refPlugin = null; refPlugin = null;
} else { } else {
refPlugin = new WeakReference<>(plugin); refPlugin = new WeakReference<>(plugin);
} }
} }
@SuppressWarnings("java:S112") @SuppressWarnings("java:S112")
public Plugin getPlugin() { public Plugin getPlugin() {
if (refPlugin == null) { if (refPlugin == null) {
throw new RuntimeException("Plugin not set."); throw new RuntimeException("Plugin not set.");
} }
Plugin plugin = refPlugin.get(); Plugin plugin = refPlugin.get();
if (plugin == null) { if (plugin == null) {
throw new RuntimeException("Plugin not set."); throw new RuntimeException("Plugin not set.");
} }
return plugin; return plugin;
} }
@SuppressWarnings("java:S112") @SuppressWarnings("java:S112")
public YamlConfiguration loadConfig(boolean saveDefault) { public YamlConfiguration loadConfig(boolean saveDefault) {
if (saveDefault) { if (saveDefault) {
getPlugin().saveDefaultConfig(); getPlugin().saveDefaultConfig();
} }
try (Reader reader = AssetsManager.getAsReader("config.yml", saveDefault)) { try (Reader reader = AssetsManager.getAsReader("config.yml", saveDefault)) {
return YamlConfiguration.loadConfiguration(reader); return YamlConfiguration.loadConfiguration(reader);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException("Error load config: " + e.getMessage(), e); throw new RuntimeException("Error load config: " + e.getMessage(), e);
} }
} }
public YamlConfiguration loadConfig() { public YamlConfiguration loadConfig() {
return loadConfig(true); return loadConfig(true);
} }
public Location copyLocation(Location location) { public Location copyLocation(Location location) {
return new Location(location.getWorld(), location.getX(), location.getY(), location.getZ()); return new Location(location.getWorld(), location.getX(), location.getY(), location.getZ());
} }
} }

View File

@@ -18,74 +18,74 @@ import java.util.Map;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class I18n { public class I18n {
private final String DEFAULT_LANG = "en"; private final String DEFAULT_LANG = "en";
private final Table<String/*Lang*/, String/*Key*/, String/*Template|Message*/> messagesMap = HashBasedTable.create(); private final Table<String/*Lang*/, String/*Key*/, String/*Template|Message*/> messagesMap = HashBasedTable.create();
//region Load messages //region Load messages
@SuppressWarnings("java:S112") @SuppressWarnings("java:S112")
public void loadMessages(String lang, Reader reader) { public void loadMessages(String lang, Reader reader) {
Map<String, String> map = messagesMap.row(lang.toLowerCase()); Map<String, String> map = messagesMap.row(lang.toLowerCase());
try { try {
BufferedReader bufferedReader = new BufferedReader(reader); BufferedReader bufferedReader = new BufferedReader(reader);
String line; String line;
while ((line = bufferedReader.readLine()) != null) { while ((line = bufferedReader.readLine()) != null) {
String[] split = line.split("=", 2); String[] split = line.split("=", 2);
map.put(split[0].trim().toLowerCase(), split[1].trim()); map.put(split[0].trim().toLowerCase(), split[1].trim());
} }
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException("Error load messages: " + e.getMessage(), e); throw new RuntimeException("Error load messages: " + e.getMessage(), e);
} }
} }
public void loadMessages(String lang, Map<String, String> messages) { public void loadMessages(String lang, Map<String, String> messages) {
Map<String, String> map = messagesMap.row(lang.toLowerCase()); Map<String, String> map = messagesMap.row(lang.toLowerCase());
messages.forEach((k, v) -> map.put(k.toLowerCase(), v)); messages.forEach((k, v) -> map.put(k.toLowerCase(), v));
} }
public void loadMessages(Reader reader) { public void loadMessages(Reader reader) {
loadMessages(DEFAULT_LANG, reader); loadMessages(DEFAULT_LANG, reader);
} }
public void loadMessages(Map<String, String> messages) { public void loadMessages(Map<String, String> messages) {
loadMessages(DEFAULT_LANG, messages); loadMessages(DEFAULT_LANG, messages);
} }
//endregion //endregion
//region Get message //region Get message
public String get(String lang, String key) { public String get(String lang, String key) {
return messagesMap.row(lang.toLowerCase()).getOrDefault(key.toLowerCase(), StringUtils.EMPTY); return messagesMap.row(lang.toLowerCase()).getOrDefault(key.toLowerCase(), StringUtils.EMPTY);
} }
public String get(String lang, String key, Map<String, Object> params) { public String get(String lang, String key, Map<String, Object> params) {
return StringSubstitutor.replace(get(lang, key.toLowerCase()), params, "{", "}"); return StringSubstitutor.replace(get(lang, key.toLowerCase()), params, "{", "}");
} }
public String get(String key) { public String get(String key) {
return get(DEFAULT_LANG, key); return get(DEFAULT_LANG, key);
} }
public String get(String key, Map<String, Object> params) { public String get(String key, Map<String, Object> params) {
return get(DEFAULT_LANG, key, params); return get(DEFAULT_LANG, key, params);
} }
//endregion //endregion
public ParamBuilder paramBuilder() { public ParamBuilder paramBuilder() {
return new ParamBuilder(); return new ParamBuilder();
} }
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class ParamBuilder { public static class ParamBuilder {
private final Map<String, Object> params = new HashMap<>(); private final Map<String, Object> params = new HashMap<>();
public ParamBuilder add(String key, Object value) { public ParamBuilder add(String key, Object value) {
params.put(key, value); params.put(key, value);
return this; return this;
} }
public Map<String, Object> build() { public Map<String, Object> build() {
return params; return params;
} }
} }
} }

View File

@@ -10,68 +10,68 @@ import static java.text.MessageFormat.format;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class XLog { public class XLog {
//region Debug //region Debug
public void debug(String pattern, Object... objects) { public void debug(String pattern, Object... objects) {
if (objects.length > 1 && objects[objects.length - 1] instanceof Throwable) { if (objects.length > 1 && objects[objects.length - 1] instanceof Throwable) {
Throwable throwable = (Throwable) objects[objects.length - 1]; Throwable throwable = (Throwable) objects[objects.length - 1];
Object[] values = new Object[objects.length - 1]; Object[] values = new Object[objects.length - 1];
System.arraycopy(objects, 0, values, 0, values.length); System.arraycopy(objects, 0, values, 0, values.length);
debug(format(pattern, values), throwable); debug(format(pattern, values), throwable);
} else { } else {
debug(format(pattern, objects)); debug(format(pattern, objects));
} }
} }
public void debug(String message, Throwable throwable) { public void debug(String message, Throwable throwable) {
GhastTools.getPlugin().getLogger().log(Level.FINE, message, throwable); GhastTools.getPlugin().getLogger().log(Level.FINE, message, throwable);
} }
public void debug(String message) { public void debug(String message) {
GhastTools.getPlugin().getLogger().fine(message); GhastTools.getPlugin().getLogger().fine(message);
} }
//endregion //endregion
//region Info //region Info
public void info(String pattern, Object... objects) { public void info(String pattern, Object... objects) {
info(format(pattern, objects)); info(format(pattern, objects));
} }
public void info(String message) { public void info(String message) {
GhastTools.getPlugin().getLogger().info(message); GhastTools.getPlugin().getLogger().info(message);
} }
//endregion //endregion
//region Warning //region Warning
public void warn(String pattern, Object... objects) { public void warn(String pattern, Object... objects) {
warn(format(pattern, objects)); warn(format(pattern, objects));
} }
public void warn(String message) { public void warn(String message) {
GhastTools.getPlugin().getLogger().warning(message); GhastTools.getPlugin().getLogger().warning(message);
} }
//endregion //endregion
//region Error //region Error
public void error(String pattern, Object... objects) { public void error(String pattern, Object... objects) {
if (objects.length > 1 && objects[objects.length - 1] instanceof Throwable) { if (objects.length > 1 && objects[objects.length - 1] instanceof Throwable) {
Throwable throwable = (Throwable) objects[objects.length - 1]; Throwable throwable = (Throwable) objects[objects.length - 1];
Object[] values = new Object[objects.length - 1]; Object[] values = new Object[objects.length - 1];
System.arraycopy(objects, 0, values, 0, values.length); System.arraycopy(objects, 0, values, 0, values.length);
error(format(pattern, values), throwable); error(format(pattern, values), throwable);
} else { } else {
error(format(pattern, objects)); error(format(pattern, objects));
} }
} }
public void error(String message) { public void error(String message) {
GhastTools.getPlugin().getLogger().severe(message); GhastTools.getPlugin().getLogger().severe(message);
} }
public void error(String message, Throwable throwable) { public void error(String message, Throwable throwable) {
GhastTools.getPlugin().getLogger().log(Level.SEVERE, message, throwable); GhastTools.getPlugin().getLogger().log(Level.SEVERE, message, throwable);
} }
//endregion //endregion
} }

View File

@@ -2,12 +2,12 @@ package ghast.assets;
public class AssetsException extends RuntimeException { public class AssetsException extends RuntimeException {
public AssetsException(String message) { public AssetsException(String message) {
super(message); super(message);
} }
public AssetsException(String message, Throwable cause) { public AssetsException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
} }

View File

@@ -18,146 +18,146 @@ import static java.text.MessageFormat.format;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class AssetsManager { public class AssetsManager {
private static final String ERROR_NOT_FOUND = "Asset \"{0}\" not found"; private static final String ERROR_NOT_FOUND = "Asset \"{0}\" not found";
private static final String ERROR_OPEN = "Error open asset \"{0}\": {1}"; private static final String ERROR_OPEN = "Error open asset \"{0}\": {1}";
//region getAsInputStream methods //region getAsInputStream methods
public InputStream getAsInputStream(String resourceName, String defaultResourceName, boolean saveDefault) { public InputStream getAsInputStream(String resourceName, String defaultResourceName, boolean saveDefault) {
Plugin plugin = GhastTools.getPlugin(); Plugin plugin = GhastTools.getPlugin();
InputStream inputStream; InputStream inputStream;
Path pathToResource = plugin.getDataFolder().toPath().resolve(resourceName); Path pathToResource = plugin.getDataFolder().toPath().resolve(resourceName);
if (Files.exists(pathToResource)) { if (Files.exists(pathToResource)) {
inputStream = openResource(pathToResource); inputStream = openResource(pathToResource);
} else if (defaultResourceName != null) { } else if (defaultResourceName != null) {
URL resourceUrl = getResourceUrl(defaultResourceName); URL resourceUrl = getResourceUrl(defaultResourceName);
if (saveDefault) { if (saveDefault) {
doSaveTo(resourceUrl, pathToResource); doSaveTo(resourceUrl, pathToResource);
inputStream = openResource(pathToResource); inputStream = openResource(pathToResource);
} else { } else {
inputStream = openResource(resourceUrl); inputStream = openResource(resourceUrl);
} }
} else { } else {
throw new AssetsException(format(ERROR_NOT_FOUND, resourceName)); throw new AssetsException(format(ERROR_NOT_FOUND, resourceName));
} }
return inputStream; return inputStream;
} }
public InputStream getAsInputStream(String resourceName, String defaultResourceName) { public InputStream getAsInputStream(String resourceName, String defaultResourceName) {
return getAsInputStream(resourceName, defaultResourceName, true); return getAsInputStream(resourceName, defaultResourceName, true);
} }
public InputStream getAsInputStream(String resourceName, boolean saveDefault) { public InputStream getAsInputStream(String resourceName, boolean saveDefault) {
return getAsInputStream(resourceName, resourceName, saveDefault); return getAsInputStream(resourceName, resourceName, saveDefault);
} }
public InputStream getAsInputStream(String resourceName) { public InputStream getAsInputStream(String resourceName) {
return getAsInputStream(resourceName, resourceName, true); return getAsInputStream(resourceName, resourceName, true);
} }
//endregion //endregion
//region getAsReader methods //region getAsReader methods
public Reader getAsReader(String resourceName, String defaultResourceName, boolean saveDefault) { public Reader getAsReader(String resourceName, String defaultResourceName, boolean saveDefault) {
return new InputStreamReader(getAsInputStream(resourceName, defaultResourceName, saveDefault)); return new InputStreamReader(getAsInputStream(resourceName, defaultResourceName, saveDefault));
} }
public Reader getAsReader(String resourceName, String defaultResourceName) { public Reader getAsReader(String resourceName, String defaultResourceName) {
return new InputStreamReader(getAsInputStream(resourceName, defaultResourceName, true)); return new InputStreamReader(getAsInputStream(resourceName, defaultResourceName, true));
} }
public Reader getAsReader(String resourceName, boolean saveDefault) { public Reader getAsReader(String resourceName, boolean saveDefault) {
return new InputStreamReader(getAsInputStream(resourceName, resourceName, saveDefault)); return new InputStreamReader(getAsInputStream(resourceName, resourceName, saveDefault));
} }
public Reader getAsReader(String resourceName) { public Reader getAsReader(String resourceName) {
return new InputStreamReader(getAsInputStream(resourceName, resourceName, true)); return new InputStreamReader(getAsInputStream(resourceName, resourceName, true));
} }
//endregion //endregion
//region getAsString methods //region getAsString methods
public String getAsString(String resourceName, String defaultResourceName, Charset charset, boolean saveDefault) { public String getAsString(String resourceName, String defaultResourceName, Charset charset, boolean saveDefault) {
try (InputStream inputStream = getAsInputStream(resourceName, defaultResourceName, saveDefault); try (InputStream inputStream = getAsInputStream(resourceName, defaultResourceName, saveDefault);
Scanner scanner = new Scanner(inputStream, charset.name()).useDelimiter("\\A")) { Scanner scanner = new Scanner(inputStream, charset.name()).useDelimiter("\\A")) {
return scanner.next(); return scanner.next();
} catch (IOException e) { } catch (IOException e) {
throw new AssetsException(format(ERROR_OPEN, resourceName, e.getMessage()), e); throw new AssetsException(format(ERROR_OPEN, resourceName, e.getMessage()), e);
} }
} }
public String getAsString(String resourceName, String defaultResourceName, Charset charset) { public String getAsString(String resourceName, String defaultResourceName, Charset charset) {
return getAsString(resourceName, defaultResourceName, charset, true); return getAsString(resourceName, defaultResourceName, charset, true);
} }
public String getAsString(String resourceName, String defaultResourceName, boolean saveDefault) { public String getAsString(String resourceName, String defaultResourceName, boolean saveDefault) {
return getAsString(resourceName, defaultResourceName, StandardCharsets.UTF_8, saveDefault); return getAsString(resourceName, defaultResourceName, StandardCharsets.UTF_8, saveDefault);
} }
public String getAsString(String resourceName, String defaultResourceName) { public String getAsString(String resourceName, String defaultResourceName) {
return getAsString(resourceName, defaultResourceName, StandardCharsets.UTF_8, true); return getAsString(resourceName, defaultResourceName, StandardCharsets.UTF_8, true);
} }
public String getAsString(String resourceName, Charset charset, boolean saveDefault) { public String getAsString(String resourceName, Charset charset, boolean saveDefault) {
return getAsString(resourceName, resourceName, charset, saveDefault); return getAsString(resourceName, resourceName, charset, saveDefault);
} }
public String getAsString(String resourceName, Charset charset) { public String getAsString(String resourceName, Charset charset) {
return getAsString(resourceName, resourceName, charset, true); return getAsString(resourceName, resourceName, charset, true);
} }
public String getAsString(String resourceName, boolean saveDefault) { public String getAsString(String resourceName, boolean saveDefault) {
return getAsString(resourceName, resourceName, StandardCharsets.UTF_8, saveDefault); return getAsString(resourceName, resourceName, StandardCharsets.UTF_8, saveDefault);
} }
public String getAsString(String resourceName) { public String getAsString(String resourceName) {
return getAsString(resourceName, resourceName, StandardCharsets.UTF_8, true); return getAsString(resourceName, resourceName, StandardCharsets.UTF_8, true);
} }
//endregion //endregion
private URL getResourceUrl(String resourceName) {
URL resourceUrl = AssetsManager.class.getClassLoader().getResource(resourceName);
if (resourceUrl == null) {
throw new AssetsException(format(ERROR_NOT_FOUND, resourceName));
}
return resourceUrl; private URL getResourceUrl(String resourceName) {
} URL resourceUrl = AssetsManager.class.getClassLoader().getResource(resourceName);
if (resourceUrl == null) {
throw new AssetsException(format(ERROR_NOT_FOUND, resourceName));
}
private void doSaveTo(URL resourceUrl, Path saveToPath) { return resourceUrl;
try { }
Files.createDirectories(saveToPath.getParent());
try (InputStream inputStream = resourceUrl.openStream(); private void doSaveTo(URL resourceUrl, Path saveToPath) {
OutputStream outputStream = Files.newOutputStream(saveToPath)) { try {
Files.createDirectories(saveToPath.getParent());
byte[] buffer = new byte[8192]; try (InputStream inputStream = resourceUrl.openStream();
int count; OutputStream outputStream = Files.newOutputStream(saveToPath)) {
while ((count = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
outputStream.flush();
}
} catch (IOException e) {
throw new AssetsException(format("Error save asset \"{0}\" to \"{1}\": {2}",
resourceUrl, saveToPath, e.getMessage()), e);
}
}
private InputStream openResource(Path pathToResource) { byte[] buffer = new byte[8192];
try { int count;
return Files.newInputStream(pathToResource); while ((count = inputStream.read(buffer)) != -1) {
} catch (IOException e) { outputStream.write(buffer, 0, count);
throw new AssetsException(format(ERROR_OPEN, pathToResource, e.getMessage()), e); }
} outputStream.flush();
} }
} catch (IOException e) {
throw new AssetsException(format("Error save asset \"{0}\" to \"{1}\": {2}",
resourceUrl, saveToPath, e.getMessage()), e);
}
}
private InputStream openResource(URL resourceUrl) { private InputStream openResource(Path pathToResource) {
try { try {
return resourceUrl.openStream(); return Files.newInputStream(pathToResource);
} catch (IOException e) { } catch (IOException e) {
throw new AssetsException(format(ERROR_OPEN, resourceUrl, e.getMessage()), e); throw new AssetsException(format(ERROR_OPEN, pathToResource, e.getMessage()), e);
} }
} }
private InputStream openResource(URL resourceUrl) {
try {
return resourceUrl.openStream();
} catch (IOException e) {
throw new AssetsException(format(ERROR_OPEN, resourceUrl, e.getMessage()), e);
}
}
} }

View File

@@ -4,5 +4,5 @@ import org.bukkit.command.CommandSender;
public interface CommandExecuter { public interface CommandExecuter {
void execute(CommandSender sender, String[] args); void execute(CommandSender sender, String[] args);
} }

View File

@@ -11,61 +11,61 @@ import ru.dmitriymx.reflection.ReflectionObject;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class CommandManager { public class CommandManager {
public Builder create(String name) { public Builder create(String name) {
return new Builder(name); return new Builder(name);
} }
public void register(String name, CommandExecuter executer) { public void register(String name, CommandExecuter executer) {
create(name).executer(executer).register(); create(name).executer(executer).register();
} }
@RequiredArgsConstructor(access = AccessLevel.PRIVATE) @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public static class Builder { public static class Builder {
private final String name; private final String name;
private CommandExecuter executer; private CommandExecuter executer;
private ErrorConsumer errorConsumer; private ErrorConsumer errorConsumer;
private Boolean onlyPlayer; private Boolean onlyPlayer;
private String deniedMessage; private String deniedMessage;
public Builder executer(CommandExecuter executer) { public Builder executer(CommandExecuter executer) {
this.executer = executer; this.executer = executer;
return this; return this;
} }
public Builder onError(ErrorConsumer errorConsumer) { public Builder onError(ErrorConsumer errorConsumer) {
this.errorConsumer = errorConsumer; this.errorConsumer = errorConsumer;
return this; return this;
} }
public Builder useOnlyPlayer(String deniedMessage) { public Builder useOnlyPlayer(String deniedMessage) {
this.onlyPlayer = true; this.onlyPlayer = true;
this.deniedMessage = deniedMessage; this.deniedMessage = deniedMessage;
return this; return this;
} }
public Builder useOnlyPlayer() { public Builder useOnlyPlayer() {
return useOnlyPlayer(null); return useOnlyPlayer(null);
} }
public Builder useOnlyConsole(String deniedMessage) { public Builder useOnlyConsole(String deniedMessage) {
this.onlyPlayer = false; this.onlyPlayer = false;
this.deniedMessage = deniedMessage; this.deniedMessage = deniedMessage;
return this; return this;
} }
public Builder useOnlyConsole() { public Builder useOnlyConsole() {
return useOnlyConsole(null); return useOnlyConsole(null);
} }
public void register() { public void register() {
//TODO для Paper такие "извращения" не требуются. Нужно продумать. //TODO для Paper такие "извращения" не требуются. Нужно продумать.
new ReflectionObject(Bukkit.getServer()) new ReflectionObject(Bukkit.getServer())
.method("getCommandMap").invoke() .method("getCommandMap").invoke()
.method("register", String.class, Command.class).invoke( .method("register", String.class, Command.class).invoke(
name, new CommandWrapper(name, this.onlyPlayer, this.deniedMessage, name, new CommandWrapper(name, this.onlyPlayer, this.deniedMessage,
this.executer, this.errorConsumer) this.executer, this.errorConsumer)
); );
} }
} }
} }

View File

@@ -8,64 +8,64 @@ import org.bukkit.entity.Player;
class CommandWrapper extends BukkitCommand { class CommandWrapper extends BukkitCommand {
private static final String DEFAULT_DENIED_MESSAGE_PLAYERS = ChatColor.RED + "This command use only players"; private static final String DEFAULT_DENIED_MESSAGE_PLAYERS = ChatColor.RED + "This command use only players";
private static final String DEFAULT_DENIED_MESSAGE_CONSOLE = ChatColor.RED + "This command use only in console"; private static final String DEFAULT_DENIED_MESSAGE_CONSOLE = ChatColor.RED + "This command use only in console";
private static final ErrorConsumer DEFAULT_ERROR_CONSUMER = private static final ErrorConsumer DEFAULT_ERROR_CONSUMER =
(sender, commandName, args, exception) -> { (sender, commandName, args, exception) -> {
sender.sendMessage(String.format("%sError execute command '%s'!", ChatColor.RED, commandName)); sender.sendMessage(String.format("%sError execute command '%s'!", ChatColor.RED, commandName));
XLog.error("Error execute command ''{0}'' with args ''{1}''", XLog.error("Error execute command ''{0}'' with args ''{1}''",
commandName, String.join(" ", args), exception); commandName, String.join(" ", args), exception);
}; };
private final CommandExecuter executer; private final CommandExecuter executer;
private final ErrorConsumer errorConsumer; private final ErrorConsumer errorConsumer;
private final Boolean onlyPlayer; private final Boolean onlyPlayer;
private String deniedMessage; private String deniedMessage;
protected CommandWrapper(String name, Boolean onlyPlayer, String deniedMessage, protected CommandWrapper(String name, Boolean onlyPlayer, String deniedMessage,
CommandExecuter executer, ErrorConsumer errorConsumer) { CommandExecuter executer, ErrorConsumer errorConsumer) {
super(name); super(name);
this.onlyPlayer = onlyPlayer; this.onlyPlayer = onlyPlayer;
this.executer = executer; this.executer = executer;
if (onlyPlayer != null) { if (onlyPlayer != null) {
if (deniedMessage == null) { if (deniedMessage == null) {
this.deniedMessage = Boolean.TRUE.equals(onlyPlayer) ? DEFAULT_DENIED_MESSAGE_PLAYERS this.deniedMessage = Boolean.TRUE.equals(onlyPlayer) ? DEFAULT_DENIED_MESSAGE_PLAYERS
: DEFAULT_DENIED_MESSAGE_CONSOLE; : DEFAULT_DENIED_MESSAGE_CONSOLE;
} else { } else {
this.deniedMessage = deniedMessage; this.deniedMessage = deniedMessage;
} }
} }
if(errorConsumer == null) { if(errorConsumer == null) {
this.errorConsumer = DEFAULT_ERROR_CONSUMER; this.errorConsumer = DEFAULT_ERROR_CONSUMER;
} else { } else {
this.errorConsumer = errorConsumer; this.errorConsumer = errorConsumer;
} }
} }
@Override @Override
@SuppressWarnings("java:S1066") @SuppressWarnings("java:S1066")
public boolean execute(CommandSender commandSender, String commandName, String[] args) { public boolean execute(CommandSender commandSender, String commandName, String[] args) {
if (Boolean.TRUE.equals(onlyPlayer)) { if (Boolean.TRUE.equals(onlyPlayer)) {
if (!(commandSender instanceof Player)) { if (!(commandSender instanceof Player)) {
commandSender.sendMessage(deniedMessage); commandSender.sendMessage(deniedMessage);
return true; return true;
} }
} else if (Boolean.FALSE.equals(onlyPlayer)) { // use console only } else if (Boolean.FALSE.equals(onlyPlayer)) { // use console only
if (commandSender instanceof Player) { if (commandSender instanceof Player) {
commandSender.sendMessage(deniedMessage); commandSender.sendMessage(deniedMessage);
return true; return true;
} }
} }
try { try {
executer.execute(commandSender, args); executer.execute(commandSender, args);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
errorConsumer.accept(commandSender, commandName, args, e); errorConsumer.accept(commandSender, commandName, args, e);
return false; return false;
} }
} }
} }

View File

@@ -4,5 +4,5 @@ import org.bukkit.command.CommandSender;
public interface ErrorConsumer { public interface ErrorConsumer {
void accept(CommandSender sender, String commandName, String[] args, Exception exception); void accept(CommandSender sender, String commandName, String[] args, Exception exception);
} }

View File

@@ -4,7 +4,7 @@ import java.sql.SQLException;
public class CannotGetJdbcConnectionException extends DataAccessException { public class CannotGetJdbcConnectionException extends DataAccessException {
public CannotGetJdbcConnectionException(String msg, SQLException ex) { public CannotGetJdbcConnectionException(String msg, SQLException ex) {
super(msg, ex); super(msg, ex);
} }
} }

View File

@@ -6,14 +6,14 @@ import lombok.Getter;
@Getter @Getter
public class DataAccessException extends RuntimeException { public class DataAccessException extends RuntimeException {
private String sql; private String sql;
public DataAccessException(String msg, Throwable cause) { public DataAccessException(String msg, Throwable cause) {
super(msg, cause); super(msg, cause);
} }
public DataAccessException(String msg, String sql, Throwable cause) { public DataAccessException(String msg, String sql, Throwable cause) {
this(msg, cause); this(msg, cause);
this.sql = sql; this.sql = sql;
} }
} }

View File

@@ -6,17 +6,17 @@ import java.util.Optional;
public interface JdbcOperations { public interface JdbcOperations {
void execute(String sql) throws DataAccessException; void execute(String sql) throws DataAccessException;
<T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException; <T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;
<T> Optional<T> queryOne(String sql, ResultSetExtractor<T> rse) throws DataAccessException; <T> Optional<T> queryOne(String sql, ResultSetExtractor<T> rse) throws DataAccessException;
<T> List<T> queryList(String sql, RowMapper<T> rowMapper) throws DataAccessException; <T> List<T> queryList(String sql, RowMapper<T> rowMapper) throws DataAccessException;
Map<String, Object> queryForMap(String sql) throws DataAccessException; Map<String, Object> queryForMap(String sql) throws DataAccessException;
List<Map<String, Object>> queryForMapList(String sql) throws DataAccessException; List<Map<String, Object>> queryForMapList(String sql) throws DataAccessException;
int update(String sql) throws DataAccessException; int update(String sql) throws DataAccessException;
} }

View File

@@ -15,230 +15,230 @@ import java.util.*;
@Setter @Setter
public class JdbcTemplate implements JdbcOperations { public class JdbcTemplate implements JdbcOperations {
private static final String DBG_SQL_INFO = "Execute SQL: {0}"; private static final String DBG_SQL_INFO = "Execute SQL: {0}";
private DataSource dataSource; private DataSource dataSource;
public JdbcTemplate(DataSource dataSource) { public JdbcTemplate(DataSource dataSource) {
setDataSource(dataSource); setDataSource(dataSource);
} }
@Override @Override
public void execute(String sql) throws DataAccessException { public void execute(String sql) throws DataAccessException {
XLog.debug(DBG_SQL_INFO, sql); XLog.debug(DBG_SQL_INFO, sql);
Connection connection = openConnection(); Connection connection = openConnection();
Statement statement = null; Statement statement = null;
try { try {
statement = connection.createStatement(); statement = connection.createStatement();
statement.execute(sql); statement.execute(sql);
} catch (SQLException e) { } catch (SQLException e) {
throw new DataAccessException("Error execute SQL", sql, e); throw new DataAccessException("Error execute SQL", sql, e);
} finally { } finally {
closeStatement(statement); closeStatement(statement);
closeConnection(connection); closeConnection(connection);
} }
} }
@Override @Override
public <T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException { public <T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
XLog.debug(DBG_SQL_INFO, sql); XLog.debug(DBG_SQL_INFO, sql);
Connection connection = openConnection(); Connection connection = openConnection();
Statement statement = null; Statement statement = null;
ResultSet resultSet = null; ResultSet resultSet = null;
try { try {
statement = connection.createStatement(); statement = connection.createStatement();
resultSet = statement.executeQuery(sql); resultSet = statement.executeQuery(sql);
return rse.extractData(resultSet); return rse.extractData(resultSet);
} catch (SQLException e) { } catch (SQLException e) {
throw new DataAccessException("Error execute SQL", sql, e); throw new DataAccessException("Error execute SQL", sql, e);
} finally { } finally {
closeResultSet(resultSet); closeResultSet(resultSet);
closeStatement(statement); closeStatement(statement);
closeConnection(connection); closeConnection(connection);
} }
} }
@Override @Override
public <T> Optional<T> queryOne(String sql, ResultSetExtractor<T> rse) throws DataAccessException { public <T> Optional<T> queryOne(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
return query(sql, rs -> { return query(sql, rs -> {
if (rs.next()) { if (rs.next()) {
return Optional.ofNullable(rse.extractData(rs)); return Optional.ofNullable(rse.extractData(rs));
} else { } else {
return Optional.empty(); return Optional.empty();
} }
}); });
} }
@Override @Override
public <T> List<T> queryList(String sql, final RowMapper<T> rowMapper) throws DataAccessException { public <T> List<T> queryList(String sql, final RowMapper<T> rowMapper) throws DataAccessException {
return query(sql, rs -> { return query(sql, rs -> {
List<T> resultList; List<T> resultList;
int rowNum = 0; int rowNum = 0;
if (rs.next()) { if (rs.next()) {
resultList = new ArrayList<>(); resultList = new ArrayList<>();
do { do {
resultList.add(rowMapper.mapRow(rs, rowNum++)); resultList.add(rowMapper.mapRow(rs, rowNum++));
} while (rs.next()); } while (rs.next());
} else { } else {
resultList = Collections.emptyList(); resultList = Collections.emptyList();
} }
return resultList; return resultList;
}); });
} }
@Override @Override
public Map<String, Object> queryForMap(String sql) throws DataAccessException { public Map<String, Object> queryForMap(String sql) throws DataAccessException {
return query(sql, rs -> { return query(sql, rs -> {
if (rs.next()) { if (rs.next()) {
ResultSetMetaData metaData = rs.getMetaData(); ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount(); int columnCount = metaData.getColumnCount();
return rowToMap(columnCount, metaData, rs); return rowToMap(columnCount, metaData, rs);
} else { } else {
return Collections.emptyMap(); return Collections.emptyMap();
} }
}); });
} }
@Override @Override
public List<Map<String, Object>> queryForMapList(String sql) throws DataAccessException { public List<Map<String, Object>> queryForMapList(String sql) throws DataAccessException {
return query(sql, rs -> { return query(sql, rs -> {
List<Map<String, Object>> resultList; List<Map<String, Object>> resultList;
if (rs.next()) { if (rs.next()) {
resultList = new ArrayList<>(); resultList = new ArrayList<>();
ResultSetMetaData metaData = rs.getMetaData(); ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount(); int columnCount = metaData.getColumnCount();
do { do {
resultList.add(rowToMap(columnCount, metaData, rs)); resultList.add(rowToMap(columnCount, metaData, rs));
} while (rs.next()); } while (rs.next());
} else { } else {
resultList = Collections.emptyList(); resultList = Collections.emptyList();
} }
return resultList; return resultList;
}); });
} }
@Override @Override
public int update(String sql) throws DataAccessException { public int update(String sql) throws DataAccessException {
XLog.debug(DBG_SQL_INFO, sql); XLog.debug(DBG_SQL_INFO, sql);
Connection connection = openConnection(); Connection connection = openConnection();
Statement statement = null; Statement statement = null;
try { try {
statement = connection.createStatement(); statement = connection.createStatement();
int rows = statement.executeUpdate(sql); int rows = statement.executeUpdate(sql);
XLog.debug("Affected {0} rows", rows); XLog.debug("Affected {0} rows", rows);
return rows; return rows;
} catch (SQLException e) { } catch (SQLException e) {
XLog.error("Error execute SQL: {0}", e.getMessage(), e); XLog.error("Error execute SQL: {0}", e.getMessage(), e);
return 0; return 0;
} finally { } finally {
closeStatement(statement); closeStatement(statement);
closeConnection(connection); closeConnection(connection);
} }
} }
private Connection openConnection() { private Connection openConnection() {
try { try {
return getDataSource().getConnection(); return getDataSource().getConnection();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex); throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
} }
} }
private String lookupColumnName(ResultSetMetaData resultSetMetaData, int columnIndex) throws SQLException { private String lookupColumnName(ResultSetMetaData resultSetMetaData, int columnIndex) throws SQLException {
String name = resultSetMetaData.getColumnLabel(columnIndex); String name = resultSetMetaData.getColumnLabel(columnIndex);
if (name == null || name.isEmpty()) { if (name == null || name.isEmpty()) {
name = resultSetMetaData.getColumnName(columnIndex); name = resultSetMetaData.getColumnName(columnIndex);
} }
return name; return name;
} }
private Map<String, Object> rowToMap(int columnCount, ResultSetMetaData metaData, ResultSet rs) throws SQLException { private Map<String, Object> rowToMap(int columnCount, ResultSetMetaData metaData, ResultSet rs) throws SQLException {
Map<String, Object> rowMap = new LinkedHashMap<>(columnCount); Map<String, Object> rowMap = new LinkedHashMap<>(columnCount);
for (int i = 1; i <= columnCount; i++) { for (int i = 1; i <= columnCount; i++) {
String key = lookupColumnName(metaData, i); String key = lookupColumnName(metaData, i);
Object value = getResultSetRawValue(rs, i); Object value = getResultSetRawValue(rs, i);
rowMap.put(key, value); rowMap.put(key, value);
} }
return rowMap; return rowMap;
} }
private Object getResultSetRawValue(ResultSet resultSet, int index) throws SQLException { private Object getResultSetRawValue(ResultSet resultSet, int index) throws SQLException {
Object obj = resultSet.getObject(index); Object obj = resultSet.getObject(index);
if (obj == null) { if (obj == null) {
return null; return null;
} }
String className = obj.getClass().getName(); String className = obj.getClass().getName();
if (obj instanceof Blob) { if (obj instanceof Blob) {
Blob blob = (Blob) obj; Blob blob = (Blob) obj;
obj = blob.getBytes(1, (int) blob.length()); obj = blob.getBytes(1, (int) blob.length());
} else if (obj instanceof Clob) { } else if (obj instanceof Clob) {
Clob clob = (Clob) obj; Clob clob = (Clob) obj;
obj = clob.getSubString(1, (int) clob.length()); obj = clob.getSubString(1, (int) clob.length());
} else if ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className)) { } else if ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className)) {
obj = resultSet.getTimestamp(index); obj = resultSet.getTimestamp(index);
} else if (className.startsWith("oracle.sql.DATE")) { } else if (className.startsWith("oracle.sql.DATE")) {
String metaDataClassName = resultSet.getMetaData().getColumnClassName(index); String metaDataClassName = resultSet.getMetaData().getColumnClassName(index);
if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) { if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) {
obj = resultSet.getTimestamp(index); obj = resultSet.getTimestamp(index);
} else { } else {
obj = resultSet.getDate(index); obj = resultSet.getDate(index);
} }
} else if (obj instanceof Date } else if (obj instanceof Date
&& "java.sql.Timestamp".equals(resultSet.getMetaData().getColumnClassName(index))) { && "java.sql.Timestamp".equals(resultSet.getMetaData().getColumnClassName(index))) {
obj = resultSet.getTimestamp(index); obj = resultSet.getTimestamp(index);
} }
return obj; return obj;
} }
private void closeResultSet(ResultSet resultSet) { private void closeResultSet(ResultSet resultSet) {
if (resultSet != null) { if (resultSet != null) {
try { try {
resultSet.close(); resultSet.close();
} catch (SQLException e) { } catch (SQLException e) {
XLog.debug("Could not close JDBC ResultSet", e); XLog.debug("Could not close JDBC ResultSet", e);
} catch (Exception e) { } catch (Exception e) {
XLog.debug("Unexpected exception on closing JDBC ResultSet", e); XLog.debug("Unexpected exception on closing JDBC ResultSet", e);
} }
} }
} }
private void closeStatement(Statement statement) { private void closeStatement(Statement statement) {
if (statement != null) { if (statement != null) {
try { try {
statement.close(); statement.close();
} catch (SQLException e) { } catch (SQLException e) {
XLog.debug("Could not close JDBC Statement", e); XLog.debug("Could not close JDBC Statement", e);
} catch (Exception e) { } catch (Exception e) {
XLog.debug("Unexpected exception on closing JDBC Statement", e); XLog.debug("Unexpected exception on closing JDBC Statement", e);
} }
} }
} }
private void closeConnection(Connection con) { private void closeConnection(Connection con) {
if (con == null) { if (con == null) {
return; return;
} }
try { try {
con.close(); con.close();
} catch (SQLException e) { } catch (SQLException e) {
XLog.debug("Could not close JDBC Connection", e); XLog.debug("Could not close JDBC Connection", e);
} catch (Exception e) { } catch (Exception e) {
XLog.debug("Unexpected exception on closing JDBC Connection", e); XLog.debug("Unexpected exception on closing JDBC Connection", e);
} }
} }
} }

View File

@@ -5,5 +5,5 @@ import java.sql.SQLException;
public interface ResultSetExtractor<T> { public interface ResultSetExtractor<T> {
T extractData(ResultSet rs) throws SQLException, DataAccessException; T extractData(ResultSet rs) throws SQLException, DataAccessException;
} }

View File

@@ -5,5 +5,5 @@ import java.sql.SQLException;
public interface RowMapper<T> { public interface RowMapper<T> {
T mapRow(ResultSet rs, int rowNum) throws SQLException; T mapRow(ResultSet rs, int rowNum) throws SQLException;
} }

View File

@@ -8,26 +8,26 @@ import java.util.function.Supplier;
@RequiredArgsConstructor @RequiredArgsConstructor
public class BukkitScheduleTask implements ScheduleTask { public class BukkitScheduleTask implements ScheduleTask {
private final Supplier<BukkitTask> generator; private final Supplier<BukkitTask> generator;
private BukkitTask bukkitTask; private BukkitTask bukkitTask;
@Override @Override
public void start() { public void start() {
if (isCanceled()) { if (isCanceled()) {
bukkitTask = generator.get(); bukkitTask = generator.get();
} }
} }
@Override @Override
public boolean isCanceled() { public boolean isCanceled() {
return bukkitTask == null || bukkitTask.isCancelled(); return bukkitTask == null || bukkitTask.isCancelled();
} }
@Override @Override
public void cancel() { public void cancel() {
if (bukkitTask != null) { if (bukkitTask != null) {
bukkitTask.cancel(); bukkitTask.cancel();
bukkitTask = null; bukkitTask = null;
} }
} }
} }

View File

@@ -8,26 +8,26 @@ import java.util.function.Supplier;
@RequiredArgsConstructor @RequiredArgsConstructor
public class JavaScheduleTask implements ScheduleTask { public class JavaScheduleTask implements ScheduleTask {
private final Supplier<Future<?>> generator; private final Supplier<Future<?>> generator;
private Future<?> future; private Future<?> future;
@Override @Override
public void start() { public void start() {
if (future == null || future.isDone()) { if (future == null || future.isDone()) {
future = generator.get(); future = generator.get();
} }
} }
@Override @Override
public boolean isCanceled() { public boolean isCanceled() {
return future == null || future.isCancelled(); return future == null || future.isCancelled();
} }
@Override @Override
public void cancel() { public void cancel() {
if (future != null) { if (future != null) {
future.cancel(true); future.cancel(true);
future = null; future = null;
} }
} }
} }

View File

@@ -14,100 +14,100 @@ import java.util.concurrent.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ScheduleManager { public class ScheduleManager {
private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder() private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder()
.setNameFormat("ScheduleManager-Thread-%d") .setNameFormat("ScheduleManager-Thread-%d")
.setDaemon(true) .setDaemon(true)
.build(); .build();
public Builder createTask() { public Builder createTask() {
return new Builder(); return new Builder();
} }
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class Builder { public static class Builder {
private static final long MS_PER_ONE_TICK = 1000L/*one second by ms*/ / 20L/*tick per second*/; private static final long MS_PER_ONE_TICK = 1000L/*one second by ms*/ / 20L/*tick per second*/;
private boolean useBukkitScheduler = false; private boolean useBukkitScheduler = false;
private Long afterMs; private Long afterMs;
private Long everyMs; private Long everyMs;
public Builder useBukkitScheduler() { public Builder useBukkitScheduler() {
this.useBukkitScheduler = true; this.useBukkitScheduler = true;
return this; return this;
} }
public Builder after(long value, TimeUnit unit) { public Builder after(long value, TimeUnit unit) {
this.afterMs = unit.toMillis(value); this.afterMs = unit.toMillis(value);
return this; return this;
} }
public Builder every(long value, TimeUnit unit) { public Builder every(long value, TimeUnit unit) {
this.everyMs = unit.toMillis(value); this.everyMs = unit.toMillis(value);
return this; return this;
} }
public ScheduleTask create(Runnable runnable) { public ScheduleTask create(Runnable runnable) {
if (useBukkitScheduler) { if (useBukkitScheduler) {
return createBukkitSchedule(runnable); return createBukkitSchedule(runnable);
} else { } else {
return createSchedule(runnable); return createSchedule(runnable);
} }
} }
public ScheduleTask execute(Runnable runnable) { public ScheduleTask execute(Runnable runnable) {
ScheduleTask scheduleTask = create(runnable); ScheduleTask scheduleTask = create(runnable);
scheduleTask.start(); scheduleTask.start();
return scheduleTask; return scheduleTask;
} }
private ScheduleTask createBukkitSchedule(Runnable runnable) { private ScheduleTask createBukkitSchedule(Runnable runnable) {
BukkitScheduler bukkitScheduler = Bukkit.getScheduler(); BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
BukkitScheduleTask resultTask; BukkitScheduleTask resultTask;
if (this.afterMs == null && this.everyMs == null) { if (this.afterMs == null && this.everyMs == null) {
resultTask = new BukkitScheduleTask(() -> bukkitScheduler.runTask(GhastTools.getPlugin(), runnable)); resultTask = new BukkitScheduleTask(() -> bukkitScheduler.runTask(GhastTools.getPlugin(), runnable));
} else if (this.everyMs != null) { } else if (this.everyMs != null) {
long everyTicks = this.everyMs / MS_PER_ONE_TICK; long everyTicks = this.everyMs / MS_PER_ONE_TICK;
long afterTicks = this.afterMs != null ? this.afterMs / MS_PER_ONE_TICK : 0; long afterTicks = this.afterMs != null ? this.afterMs / MS_PER_ONE_TICK : 0;
resultTask = new BukkitScheduleTask(() -> resultTask = new BukkitScheduleTask(() ->
bukkitScheduler.runTaskTimer(GhastTools.getPlugin(), runnable, afterTicks, everyTicks)); bukkitScheduler.runTaskTimer(GhastTools.getPlugin(), runnable, afterTicks, everyTicks));
} else { } else {
long ticks = this.afterMs / MS_PER_ONE_TICK; long ticks = this.afterMs / MS_PER_ONE_TICK;
resultTask = new BukkitScheduleTask(() -> resultTask = new BukkitScheduleTask(() ->
bukkitScheduler.runTaskLater(GhastTools.getPlugin(), runnable, ticks)); bukkitScheduler.runTaskLater(GhastTools.getPlugin(), runnable, ticks));
} }
return resultTask; return resultTask;
} }
private ScheduleTask createSchedule(Runnable runnable) { private ScheduleTask createSchedule(Runnable runnable) {
ExecutorService executorService; ExecutorService executorService;
JavaScheduleTask resultTask; JavaScheduleTask resultTask;
if (this.afterMs == null && this.everyMs == null) { if (this.afterMs == null && this.everyMs == null) {
executorService = Executors.newSingleThreadExecutor(THREAD_FACTORY); executorService = Executors.newSingleThreadExecutor(THREAD_FACTORY);
resultTask = new JavaScheduleTask(() -> executorService.submit(runnable)); resultTask = new JavaScheduleTask(() -> executorService.submit(runnable));
} else if (this.everyMs != null) { } else if (this.everyMs != null) {
ScheduledExecutorService scheduledExecutorService ScheduledExecutorService scheduledExecutorService
= Executors.newScheduledThreadPool(1, THREAD_FACTORY); = Executors.newScheduledThreadPool(1, THREAD_FACTORY);
resultTask = new JavaScheduleTask(() -> resultTask = new JavaScheduleTask(() ->
scheduledExecutorService.scheduleAtFixedRate(runnable, scheduledExecutorService.scheduleAtFixedRate(runnable,
this.afterMs != null ? this.afterMs : 0, this.afterMs != null ? this.afterMs : 0,
everyMs, TimeUnit.MILLISECONDS)); everyMs, TimeUnit.MILLISECONDS));
executorService = scheduledExecutorService; executorService = scheduledExecutorService;
} else { } else {
ScheduledExecutorService scheduledExecutorService ScheduledExecutorService scheduledExecutorService
= Executors.newScheduledThreadPool(1, THREAD_FACTORY); = Executors.newScheduledThreadPool(1, THREAD_FACTORY);
resultTask = new JavaScheduleTask(() -> resultTask = new JavaScheduleTask(() ->
scheduledExecutorService.schedule(runnable, afterMs, TimeUnit.MILLISECONDS)); scheduledExecutorService.schedule(runnable, afterMs, TimeUnit.MILLISECONDS));
executorService = scheduledExecutorService; executorService = scheduledExecutorService;
} }
executorService.shutdown(); executorService.shutdown();
return resultTask; return resultTask;
} }
} }
} }

View File

@@ -2,9 +2,9 @@ package ghast.scheduler;
public interface ScheduleTask { public interface ScheduleTask {
void start(); void start();
boolean isCanceled(); boolean isCanceled();
void cancel(); void cancel();
} }

View File

@@ -29,261 +29,261 @@ import static org.mockito.Mockito.when;
class JdbcTemplateTest { class JdbcTemplateTest {
static final String JDBC_USER = "sa"; static final String JDBC_USER = "sa";
static final String JDBC_PASSWORD = ""; static final String JDBC_PASSWORD = "";
static final String JDBC_DB_NAME = "in_mem_db"; static final String JDBC_DB_NAME = "in_mem_db";
static final String JDBC_URL = "jdbc:h2:mem:" + JDBC_DB_NAME + ";DB_CLOSE_DELAY=-1"; static final String JDBC_URL = "jdbc:h2:mem:" + JDBC_DB_NAME + ";DB_CLOSE_DELAY=-1";
static final String TABLE_NAME = "TEST_TABLE"; static final String TABLE_NAME = "TEST_TABLE";
static final String COLUMN_ID = "ID"; static final String COLUMN_ID = "ID";
static final String COLUMN_NAME = "C_NAME"; static final String COLUMN_NAME = "C_NAME";
static final String COLUMN_VALUE = "C_VALUE"; static final String COLUMN_VALUE = "C_VALUE";
static final Object[][] DATA = new Object[][]{ static final Object[][] DATA = new Object[][]{
{ "Player 1", 100 }, { "Player 2", 250 }, { "Player 1", 100 }, { "Player 2", 250 },
{ "Player 3", 0 }, { "Player 4", 780 } { "Player 3", 0 }, { "Player 4", 780 }
}; };
static DataSource dataSource; static DataSource dataSource;
JdbcTemplate jdbcTemplate; JdbcTemplate jdbcTemplate;
@BeforeAll @BeforeAll
static void beforeAll() { static void beforeAll() {
Logger logger = Logger.getLogger(JdbcTemplateTest.class.getName()); Logger logger = Logger.getLogger(JdbcTemplateTest.class.getName());
Plugin mockPlugin = mock(Plugin.class); Plugin mockPlugin = mock(Plugin.class);
when(mockPlugin.getLogger()).thenReturn(logger); when(mockPlugin.getLogger()).thenReturn(logger);
GhastTools.setPlugin(mockPlugin); GhastTools.setPlugin(mockPlugin);
JdbcDataSource jdbcDataSource = new JdbcDataSource(); JdbcDataSource jdbcDataSource = new JdbcDataSource();
jdbcDataSource.setUser(JDBC_USER); jdbcDataSource.setUser(JDBC_USER);
jdbcDataSource.setPassword(JDBC_PASSWORD); jdbcDataSource.setPassword(JDBC_PASSWORD);
jdbcDataSource.setURL(JDBC_URL); jdbcDataSource.setURL(JDBC_URL);
dataSource = jdbcDataSource; dataSource = jdbcDataSource;
} }
@BeforeEach @BeforeEach
void before() { void before() {
jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate = new JdbcTemplate(dataSource);
createTable(); createTable();
String sql_head = MessageFormat.format("INSERT INTO {0} ({1}, {2}) VALUES ", String sql_head = MessageFormat.format("INSERT INTO {0} ({1}, {2}) VALUES ",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE);
StringJoiner sql_sj = new StringJoiner(", "); StringJoiner sql_sj = new StringJoiner(", ");
for (Object[] datum : DATA) { for (Object[] datum : DATA) {
sql_sj.add(MessageFormat.format("( ''{0}'', {1} )", datum[0], datum[1])); sql_sj.add(MessageFormat.format("( ''{0}'', {1} )", datum[0], datum[1]));
} }
jdbcTemplate.execute(sql_head + sql_sj.toString()); jdbcTemplate.execute(sql_head + sql_sj.toString());
} }
@AfterEach @AfterEach
void after() { void after() {
dropTable(); dropTable();
} }
@Test @Test
void testQuery_Simple_Single() { void testQuery_Simple_Single() {
String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''", String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]);
Integer value = jdbcTemplate.query(sql, rs -> { Integer value = jdbcTemplate.query(sql, rs -> {
if (rs.next()) { if (rs.next()) {
return rs.getInt(1); return rs.getInt(1);
} else { } else {
return null; return null;
} }
}); });
assertEquals(DATA[0][1], value); assertEquals(DATA[0][1], value);
} }
@Test @Test
void testQuery_Simple_Optional() { void testQuery_Simple_Optional() {
String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''", String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]);
Optional<Integer> optValue = jdbcTemplate.queryOne(sql, rs -> rs.getInt(1)); Optional<Integer> optValue = jdbcTemplate.queryOne(sql, rs -> rs.getInt(1));
assertTrue(optValue.isPresent()); assertTrue(optValue.isPresent());
assertEquals(DATA[0][1], optValue.get()); assertEquals(DATA[0][1], optValue.get());
} }
@Test @Test
void testQuery_Simple_List() { void testQuery_Simple_List() {
String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}'' OR {1} LIKE ''{4}''", String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}'' OR {1} LIKE ''{4}''",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0], DATA[1][0]); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0], DATA[1][0]);
List<Integer> listValues = jdbcTemplate.queryList(sql, (rs, rowNum) -> rs.getInt(1)); List<Integer> listValues = jdbcTemplate.queryList(sql, (rs, rowNum) -> rs.getInt(1));
assertIterableEquals(Lists.newArrayList(DATA[0][1], DATA[1][1]), listValues); assertIterableEquals(Lists.newArrayList(DATA[0][1], DATA[1][1]), listValues);
} }
@Test @Test
void testQuery_Object_Single() { void testQuery_Object_Single() {
String sql = MessageFormat.format("SELECT {1}, {2} FROM {0} WHERE {1} LIKE ''{3}''", String sql = MessageFormat.format("SELECT {1}, {2} FROM {0} WHERE {1} LIKE ''{3}''",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]);
Player actualPlayer = jdbcTemplate.query(sql, rs -> { Player actualPlayer = jdbcTemplate.query(sql, rs -> {
if (rs.next()) { if (rs.next()) {
Player player0 = new Player(); Player player0 = new Player();
player0.name = rs.getString(COLUMN_NAME); player0.name = rs.getString(COLUMN_NAME);
player0.value = rs.getInt(COLUMN_VALUE); player0.value = rs.getInt(COLUMN_VALUE);
return player0; return player0;
} else { } else {
return null; return null;
} }
}); });
Player expectedPlayer = new Player(); Player expectedPlayer = new Player();
expectedPlayer.name = (String) DATA[0][0]; expectedPlayer.name = (String) DATA[0][0];
expectedPlayer.value = (int) DATA[0][1]; expectedPlayer.value = (int) DATA[0][1];
assertEquals(expectedPlayer, actualPlayer); assertEquals(expectedPlayer, actualPlayer);
} }
@Test @Test
void testQuery_Object_List() { void testQuery_Object_List() {
String sql = MessageFormat.format("SELECT {1}, {2} FROM {0}", String sql = MessageFormat.format("SELECT {1}, {2} FROM {0}",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE);
List<Player> actualPlayers = jdbcTemplate.queryList(sql, (rs, num) -> { List<Player> actualPlayers = jdbcTemplate.queryList(sql, (rs, num) -> {
Player player0 = new Player(); Player player0 = new Player();
player0.name = rs.getString(COLUMN_NAME); player0.name = rs.getString(COLUMN_NAME);
player0.value = rs.getInt(COLUMN_VALUE); player0.value = rs.getInt(COLUMN_VALUE);
return player0; return player0;
}); });
List<Player> expectedPlayers = Stream.of(DATA) List<Player> expectedPlayers = Stream.of(DATA)
.map(datum -> { .map(datum -> {
Player player1 = new Player(); Player player1 = new Player();
player1.name = (String) datum[0]; player1.name = (String) datum[0];
player1.value = (int) datum[1]; player1.value = (int) datum[1];
return player1; return player1;
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
assertIterableEquals(expectedPlayers, actualPlayers); assertIterableEquals(expectedPlayers, actualPlayers);
} }
@Test @Test
void testQueryForMap() { void testQueryForMap() {
String sql = MessageFormat.format("SELECT {1}, {2} FROM {0} WHERE {1} LIKE ''{3}''", String sql = MessageFormat.format("SELECT {1}, {2} FROM {0} WHERE {1} LIKE ''{3}''",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]);
Map<String, Object> actualMap = jdbcTemplate.queryForMap(sql); Map<String, Object> actualMap = jdbcTemplate.queryForMap(sql);
Map<String, Object> expectedMap = ImmutableMap.of( Map<String, Object> expectedMap = ImmutableMap.of(
COLUMN_NAME, DATA[0][0], COLUMN_NAME, DATA[0][0],
COLUMN_VALUE, DATA[0][1]); COLUMN_VALUE, DATA[0][1]);
assertIterableEquals(expectedMap.entrySet(), actualMap.entrySet()); assertIterableEquals(expectedMap.entrySet(), actualMap.entrySet());
} }
@Test @Test
void testQueryForMapList() { void testQueryForMapList() {
String sql = MessageFormat.format("SELECT {1}, {2} FROM {0}", String sql = MessageFormat.format("SELECT {1}, {2} FROM {0}",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE);
List<Map<String, Object>> actualMapList = jdbcTemplate.queryForMapList(sql); List<Map<String, Object>> actualMapList = jdbcTemplate.queryForMapList(sql);
List<Map<String, Object>> expectedMapList = Stream.of(DATA) List<Map<String, Object>> expectedMapList = Stream.of(DATA)
.map(datum -> ImmutableMap.of(COLUMN_NAME, datum[0], COLUMN_VALUE, datum[1])) .map(datum -> ImmutableMap.of(COLUMN_NAME, datum[0], COLUMN_VALUE, datum[1]))
.collect(Collectors.toList()); .collect(Collectors.toList());
assertIterableEquals(expectedMapList, actualMapList); assertIterableEquals(expectedMapList, actualMapList);
} }
@Test @Test
void testUpdate() { void testUpdate() {
String newName = "Player X"; String newName = "Player X";
String sql = MessageFormat.format("UPDATE {0} SET {1} = ''{3}'' WHERE {1} LIKE ''{2}''", String sql = MessageFormat.format("UPDATE {0} SET {1} = ''{3}'' WHERE {1} LIKE ''{2}''",
TABLE_NAME, COLUMN_NAME, DATA[0][0], newName); TABLE_NAME, COLUMN_NAME, DATA[0][0], newName);
int rows = jdbcTemplate.update(sql); int rows = jdbcTemplate.update(sql);
assertEquals(1, rows); assertEquals(1, rows);
sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''", sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''",
TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, newName); TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, newName);
Integer value = jdbcTemplate.query(sql, rs -> { Integer value = jdbcTemplate.query(sql, rs -> {
if (rs.next()) { if (rs.next()) {
return rs.getInt(1); return rs.getInt(1);
} else { } else {
return null; return null;
} }
}); });
assertEquals(DATA[0][1], value); assertEquals(DATA[0][1], value);
} }
private void createTable() { private void createTable() {
jdbcTemplate.execute("CREATE TABLE " + TABLE_NAME + " (" + jdbcTemplate.execute("CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_ID + " bigint auto_increment," + COLUMN_ID + " bigint auto_increment," +
COLUMN_NAME + " varchar(16)," + COLUMN_NAME + " varchar(16)," +
COLUMN_VALUE + " integer)"); COLUMN_VALUE + " integer)");
} }
private void dropTable() { private void dropTable() {
jdbcTemplate.execute("DROP TABLE IF EXISTS " + TABLE_NAME); jdbcTemplate.execute("DROP TABLE IF EXISTS " + TABLE_NAME);
} }
class Player { class Player {
String name; String name;
int value; int value;
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (!(o instanceof Player)) return false; if (!(o instanceof Player)) return false;
Player player = (Player) o; Player player = (Player) o;
return new EqualsBuilder().append(value, player.value).append(name, player.name).isEquals(); return new EqualsBuilder().append(value, player.value).append(name, player.name).isEquals();
} }
@Override @Override
public int hashCode() { public int hashCode() {
return new HashCodeBuilder(17, 37).append(name).append(value).toHashCode(); return new HashCodeBuilder(17, 37).append(name).append(value).toHashCode();
} }
} }
@Nested @Nested
class JdbcTemplateTest_ExecuteTestCase { class JdbcTemplateTest_ExecuteTestCase {
@BeforeEach @BeforeEach
void before() { void before() {
jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate = new JdbcTemplate(dataSource);
dropTable(); dropTable();
} }
@AfterEach @AfterEach
void after() { void after() {
dropTable(); dropTable();
} }
@Test @Test
void test() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException { void test() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException {
createTable(); createTable();
//region Check result //region Check result
Class.forName("org.h2.Driver").newInstance(); Class.forName("org.h2.Driver").newInstance();
Connection connection = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD); Connection connection = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
ResultSet resultSet = connection.getMetaData().getTables(JDBC_DB_NAME.toUpperCase(), "PUBLIC", ResultSet resultSet = connection.getMetaData().getTables(JDBC_DB_NAME.toUpperCase(), "PUBLIC",
TABLE_NAME.toUpperCase(), new String[]{"TABLE"}); TABLE_NAME.toUpperCase(), new String[]{"TABLE"});
assertTrue(resultSet.next()); assertTrue(resultSet.next());
resultSet.close(); resultSet.close();
connection.close(); connection.close();
//endregion //endregion
} }
} }
} }