Skip to content

Commit

Permalink
Polish codes
Browse files Browse the repository at this point in the history
  • Loading branch information
vjh0107 committed Apr 18, 2024
1 parent f21dbf3 commit 9770784
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package kr.junhyung.springbukkit;

import kr.junhyung.springbukkit.serializer.BukkitDeserializer;
import kr.junhyung.springbukkit.serializer.BukkitSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.configuration.file.FileConfiguration;
Expand All @@ -16,7 +18,7 @@
@ConditionalOnClass(Bukkit.class)
@Role(BeanDefinition.ROLE_SUPPORT)
@AutoConfiguration
public class BukkitAutoConfiguration {
public class SpringBukkitAutoConfiguration {
@Role(BeanDefinition.ROLE_SUPPORT)
@ConditionalOnMissingBean
@Bean(destroyMethod = "")
Expand Down Expand Up @@ -51,4 +53,16 @@ FileConfiguration fileConfiguration(Plugin plugin) {
Plugin plugin() {
throw new IllegalStateException();
}

@Role(BeanDefinition.ROLE_SUPPORT)
@Bean
BukkitSerializer bukkitSerializer() {
return new BukkitSerializer();
}

@Role(BeanDefinition.ROLE_SUPPORT)
@Bean
BukkitDeserializer bukkitDeserializer() {
return new BukkitDeserializer();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
import java.lang.reflect.Method;
import java.util.*;

class BukkitResourceLoader extends DefaultResourceLoader {
class SpringBukkitResourceLoader extends DefaultResourceLoader {
private final List<InternalResourceLoader> resourceLoaders = new ArrayList<>();

BukkitResourceLoader(JavaPlugin javaPlugin, PluginManager pluginManager) {
SpringBukkitResourceLoader(JavaPlugin javaPlugin, PluginManager pluginManager) {
super(getClassLoader(javaPlugin));

Set<String> dependPluginNames = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void initialize(@NonNull GenericApplicationContext applicationContext) {

@Override
public void onEnable() {
ResourceLoader resourceLoader = new BukkitResourceLoader(this, getServer().getPluginManager());
ResourceLoader resourceLoader = new SpringBukkitResourceLoader(this, getServer().getPluginManager());
SpringApplicationBuilder builder = new SpringApplicationBuilder()
.resourceLoader(resourceLoader)
.sources(getApplicationClass())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import org.springframework.context.annotation.Role;

@AutoConfiguration
public class BukkitListenerConfiguration {
@Role(BeanDefinition.ROLE_SUPPORT)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class BukkitListenerAutoConfiguration {
@Bean
static BukkitListenerBeanPostProcessor listenerBeanPostProcessor() {
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BukkitListenerBeanPostProcessor bukkitListenerAdvisor() {
return new BukkitListenerBeanPostProcessor();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package kr.junhyung.springbukkit.listener;

import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.springframework.aop.framework.AopInfrastructureBean;
Expand All @@ -18,13 +14,27 @@
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.NonNull;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.Set;
import java.util.function.Supplier;

public class BukkitListenerBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
private Supplier<BukkitListenerRegistrar> registrar;

public BukkitListenerBeanPostProcessor() {}

public void configure(Supplier<BukkitListenerRegistrar> registrar) {
this.registrar = registrar;
}

@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
this.registrar = () -> {
Plugin plugin = applicationContext.getBean(Plugin.class);
PluginManager pluginManager = applicationContext.getBean(PluginManager.class);
return new SimpleBukkitListenerRegistrar(plugin, pluginManager);
};
}

@Override
public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {
Expand All @@ -36,51 +46,12 @@ public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull Stri
if (!AnnotationUtils.isCandidateClass(targetClass, EventHandler.class)) {
return bean;
}
Set<Method> annotatedMethods = MethodIntrospector
.selectMethods(targetClass, (Method method) -> AnnotatedElementUtils.isAnnotated(method, EventHandler.class));

Set<Method> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (Method method) -> AnnotatedElementUtils.isAnnotated(method, EventHandler.class));
if (annotatedMethods.isEmpty()) {
return bean;
}

Plugin plugin = applicationContext.getBean(Plugin.class);
PluginManager pluginManager = applicationContext.getBean(PluginManager.class);

for (Method method : annotatedMethods) {
List<Parameter> methodParameters = Arrays.stream(method.getParameters()).toList();
if (methodParameters.size() != 1) {
throw new IllegalStateException("A event handler can only have one event parameter.");
}
Parameter methodParameter = methodParameters.stream().findFirst().get();
System.out.println(methodParameter.getType().toString());

if (methodParameter.getType().isAssignableFrom(Event.class)) {
throw new IllegalStateException("first parameter of event handler must be event.");
}
@SuppressWarnings("unchecked")
Class<? extends Event> event = (Class<? extends Event>) methodParameter.getType();

EventHandler eventHandler = AnnotationUtils.getAnnotation(method, EventHandler.class);
Objects.requireNonNull(eventHandler);
EventExecutor eventExecutor = bakeEventExecutor(bean, event, method);
pluginManager.registerEvent(event, new Listener() {}, eventHandler.priority(), eventExecutor, plugin, eventHandler.ignoreCancelled());
}
registrar.get().registerEventHandler(bean);
return bean;
}

private static EventExecutor bakeEventExecutor(Object listenerInstance, Class<? extends Event> eventClass, Method method) {
return (unused, event) -> {
try {
if (eventClass.isAssignableFrom(event.getClass())) {
method.invoke(listenerInstance, event);
}
} catch (InvocationTargetException | IllegalAccessException exception) {
throw new EventException(exception.getCause());
}
};
}

@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package kr.junhyung.springbukkit.listener;

public interface BukkitListenerRegistrar {
void registerEventHandler(Object listenerInstance);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package kr.junhyung.springbukkit.listener;

import org.bukkit.event.*;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;

public class SimpleBukkitListenerRegistrar implements BukkitListenerRegistrar {
private final Plugin plugin;
private final PluginManager pluginManager;

public SimpleBukkitListenerRegistrar(Plugin plugin, PluginManager pluginManager) {
this.plugin = plugin;
this.pluginManager = pluginManager;
}

public void registerEventHandler(Object listenerInstance) {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(listenerInstance);
Set<Method> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (Method method) -> AnnotatedElementUtils.isAnnotated(method, EventHandler.class));
if (annotatedMethods.isEmpty()) {
return;
}
for (Method method : annotatedMethods) {
List<Parameter> methodParameters = Arrays.stream(method.getParameters()).toList();
if (methodParameters.size() != 1) {
throw new IllegalStateException("A event handler can only have one event parameter.");
}
Parameter methodParameter = methodParameters.stream().findFirst().get();
if (methodParameter.getType().isAssignableFrom(Event.class)) {
throw new IllegalStateException("first parameter of event handler must be event.");
}
@SuppressWarnings("unchecked")
Class<? extends Event> event = (Class<? extends Event>) methodParameter.getType();

EventHandler eventHandler = AnnotationUtils.getAnnotation(method, EventHandler.class);
EventExecutor eventExecutor = bakeEventExecutor(listenerInstance, event, method);
Objects.requireNonNull(eventHandler);
registerEventHandler(event, eventHandler, plugin, eventExecutor);
}
}

private void registerEventHandler(Class<? extends Event> event, EventHandler eventHandler, Plugin plugin, EventExecutor eventExecutor) {
EventPriority priority = eventHandler.priority();
boolean ignoreCancelled = eventHandler.ignoreCancelled();
pluginManager.registerEvent(event, new Listener() {}, priority, eventExecutor, plugin, ignoreCancelled);
}

private static EventExecutor bakeEventExecutor(Object listenerInstance, Class<? extends Event> eventClass, Method method) {
return (unused, event) -> {
try {
if (eventClass.isAssignableFrom(event.getClass())) {
method.invoke(listenerInstance, event);
}
} catch (InvocationTargetException | IllegalAccessException exception) {
throw new EventException(exception.getCause());
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package kr.junhyung.springbukkit.serializer;

import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.springframework.core.serializer.Deserializer;
import org.springframework.lang.NonNull;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class BukkitDeserializer implements Deserializer<ConfigurationSerializable> {
@Override
public @NonNull ConfigurationSerializable deserialize(@NonNull InputStream inputStream) throws IOException {
try (BukkitObjectInputStream bukkitObjectInputStream = new BukkitObjectInputStream(inputStream)) {
return (ConfigurationSerializable) bukkitObjectInputStream.readObject();
} catch (ClassNotFoundException exception) {
throw new IOException(exception);
}
}

@Override
public @NonNull ConfigurationSerializable deserializeFromByteArray(@NonNull byte[] serialized) throws IOException {
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(serialized)) {
return deserialize(byteArrayInputStream);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package kr.junhyung.springbukkit.serializer;

import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import org.springframework.core.serializer.Deserializer;
import org.springframework.core.serializer.Serializer;
import org.springframework.lang.NonNull;

import java.io.*;

public class BukkitSerializer implements Serializer<ConfigurationSerializable>, Deserializer<ConfigurationSerializable> {
public class BukkitSerializer implements Serializer<ConfigurationSerializable> {
@Override
public void serialize(@NonNull ConfigurationSerializable object, @NonNull OutputStream outputStream) throws IOException {
try (BukkitObjectOutputStream bukkitObjectOutputStream = new BukkitObjectOutputStream(outputStream)) {
Expand All @@ -24,20 +22,4 @@ public void serialize(@NonNull ConfigurationSerializable object, @NonNull Output
return byteArrayOutputStream.toByteArray();
}
}

@Override
public @NonNull ConfigurationSerializable deserialize(@NonNull InputStream inputStream) throws IOException {
try (BukkitObjectInputStream bukkitObjectInputStream = new BukkitObjectInputStream(inputStream)) {
return (ConfigurationSerializable) bukkitObjectInputStream.readObject();
} catch (ClassNotFoundException exception) {
throw new IOException(exception);
}
}

@Override
public @NonNull ConfigurationSerializable deserializeFromByteArray(@NonNull byte[] serialized) throws IOException {
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(serialized)) {
return deserialize(byteArrayInputStream);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
kr.junhyung.springbukkit.BukkitAutoConfiguration
kr.junhyung.springbukkit.listener.BukkitListenerConfiguration
kr.junhyung.springbukkit.serializer.BukkitSerializerConfiguration
kr.junhyung.springbukkit.SpringBukkitAutoConfiguration
kr.junhyung.springbukkit.listener.BukkitListenerAutoConfiguration

0 comments on commit 9770784

Please sign in to comment.