/** * Copyright (c) Lambda Innovation, 2013-2015 * 本作品版权由Lambda Innovation所有。 * http://www.li-dev.cn/ * * This project is open-source, and it is distributed under * the terms of GNU General Public License. You can modify * and distribute freely as long as you follow the license. * 本项目是一个开源项目,且遵循GNU通用公共授权协议。 * 在遵照该协议的情况下,您可以自由传播和修改。 * http://www.gnu.org/licenses/gpl.html */ package cn.annoreg.mc.s11n; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; public class ReflectionAutoSerializer implements DataSerializer { private Class clazz; private List<Field> fieldList = new ArrayList(); private List<DataSerializer> serList = new ArrayList(); public ReflectionAutoSerializer(Class clazz) { this.clazz = clazz; if (!clazz.isAnnotationPresent(RegSerializable.class)) { throw new RuntimeException("Trying to creating auto serializer for class " + clazz.getCanonicalName() + "."); } for (Field f : clazz.getDeclaredFields()) { if (f.isAnnotationPresent(RegSerializable.SerializeField.class) && !Modifier.isStatic(f.getModifiers())) { //Now only support data serialization for fields. DataSerializer ser = SerializationManager.INSTANCE.getDataSerializer(f.getType()); if (ser == null) { throw new RuntimeException("Can not create serializer for " + f.toString() + "."); } f.setAccessible(true); fieldList.add(f); serList.add(ser); } } } @Override public Object readData(NBTBase nbt, Object obj) throws Exception { if (obj == null) { throw new Exception("Auto serializer can not create new instance for class " + this.clazz.getCanonicalName() + "."); } if (!obj.getClass().equals(this.clazz)) { throw new Exception("Auto serializer for " + this.clazz.getCanonicalName() + " is used on " + obj.getClass().getCanonicalName() + "."); } NBTTagCompound tag = (NBTTagCompound) nbt; for (int i = 0; i < fieldList.size(); ++i) { Field f = fieldList.get(i); DataSerializer ser = serList.get(i); Object fieldValue = ser.readData(tag.getTag(f.getName()), f.get(obj)); f.set(obj, fieldValue); } return obj; } @Override public NBTBase writeData(Object obj) throws Exception { NBTTagCompound tag = new NBTTagCompound(); if (!obj.getClass().equals(this.clazz)) { throw new Exception("Auto serializer for " + this.clazz.getCanonicalName() + " is used on " + obj.getClass().getCanonicalName() + "."); } for (int i = 0; i < fieldList.size(); ++i) { Field f = fieldList.get(i); DataSerializer ser = serList.get(i); NBTBase fieldNBT = ser.writeData(f.get(obj)); tag.setTag(f.getName(), fieldNBT); } return tag; } }