package team.unstudio.udpl.config;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.serialization.ConfigurationSerializable;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;

public interface SerializationHelper {

	static Map<String,Object> serialize(ConfigurationSerializable obj){
		Validate.notNull(obj);
		
		Map<String,Object> map = Maps.newLinkedHashMap();
		Class<?> clazz = obj.getClass();
		while(ArrayUtils.contains(clazz.getInterfaces(), ConfigurationSerializable.class)){
			for(Field field:clazz.getDeclaredFields()){
				int modifiers = field.getModifiers();
				if(Modifier.isFinal(modifiers)||Modifier.isStatic(modifiers)||Modifier.isTransient(modifiers))
					continue;
				
				field.setAccessible(true);
				
				String key = field.getName();
				
				ConfigItem setting = field.getAnnotation(ConfigItem.class);
				if(setting != null && !Strings.isNullOrEmpty(key))
					key = setting.value();
				
				try {
					map.put(key, field.get(obj));
				} catch (IllegalArgumentException | IllegalAccessException e) {
					throw new SerializationException("Serialize failed.",e);
				}
			}
			clazz = clazz.getSuperclass();
		}
		
		return map;
	}
	
	static <T extends ConfigurationSerializable> T deserialize(T obj, Map<String,Object> map){
		Validate.notNull(obj);
		Validate.notNull(map);
		
		Class<?> clazz = obj.getClass();
		while(ArrayUtils.contains(clazz.getInterfaces(), ConfigurationSerializable.class)){
			for(Field field:clazz.getDeclaredFields()){
				int modifiers = field.getModifiers();
				if(Modifier.isFinal(modifiers)||Modifier.isStatic(modifiers)||Modifier.isTransient(modifiers))
					continue;
				
				field.setAccessible(true);
				
				String key = field.getName();
				
				ConfigItem setting = field.getAnnotation(ConfigItem.class);
				if(setting != null && !Strings.isNullOrEmpty(key))
					key = setting.value();
				
				if(map.containsKey(key)){
					try {
						field.set(obj, map.get(key));
					} catch (IllegalArgumentException | IllegalAccessException e) {
						throw new SerializationException("Deserialize failed.",e);
					}
				}
			}
			clazz = clazz.getSuperclass();
		}
		
		return obj;
	}
}

@@ -136,45 +136,38 @@
 ort 
-org.apache.commons.lang.ArrayUtils
+javax.annotation.Nullable
 ;%0D%0A
+%0D%0A
 impo
@@ -441,16 +441,26 @@
 rialize(
+@Nullable 
 Configur
@@ -615,51 +615,8 @@
 ile(
-ArrayUtils.contains(clazz.getInterfaces(), 
 Conf
@@ -634,32 +634,55 @@
 rializable.class
+.isAssignableFrom(clazz
 ))%7B%0D%0A%09%09%09for(Fiel
@@ -1390,42 +1390,8 @@
 c %3CT
- extends ConfigurationSerializable
 %3E T 
@@ -1539,51 +1539,8 @@
 ile(
-ArrayUtils.contains(clazz.getInterfaces(), 
 Conf
@@ -1566,16 +1566,39 @@
 le.class
+.isAssignableFrom(clazz
 ))%7B%0D%0A%09%09%09

Update SerializationHelper