Created
September 26, 2010 17:20
-
-
Save frsyuki/598124 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// カスタムシリアライザ(自分をシリアライズ):直接使うことはまず無い | |
public interface MessagePackable { | |
public void messagePack(Packer); | |
} | |
// カスタムデシリアライザ(自分にマージ):直接使うことはまず無い | |
public interface MessageUnpackable { | |
public void messageUnpack(Unpacker); | |
} | |
// カスタム型変換(自分にマージ):直接使うことはまず無い | |
public interface MessageConvertable { | |
public void messageConvert(MessagePackObject); | |
} | |
// カスタムシリアライザ:シリアライズ時に使う人もいるかも知れない | |
public interface MessagePacker { | |
public void pack(Packer, Object); | |
} | |
// カスタムデシリアライザ:直接使うことはまず無い | |
public interface MessageUnpacker { | |
public Object unpack(Unpacker); | |
} | |
// カスタム型変換:直接使うことはまず無い | |
public interface MessageConverter { | |
public Object convert(MessagePackObject obj); | |
} | |
// 型情報を表現する:デシリアライズ・型変換時に使う | |
public interface Template extends MessageUnpacker, MessageConverter { | |
} | |
public abstract class AbstractTemplate implements MessageUnpacker { | |
public Object unpack(Unpacker pac) { | |
return convert(pac.unpackObject()); | |
} | |
public Object convert(MessagePackObject from); | |
} | |
// 直接使うことはまずない。CustomMessageを経由して使う | |
class CustomOperatorRegistry<E> { | |
public static void register(Class target, E converter) { | |
map.put(target, converter); | |
} | |
public static E get(Class target) { | |
return map.get(target); | |
} | |
public static boolean isRegistered(Class target) { | |
return map.containsKey(target); | |
} | |
private static Map<Class, E> map = new HashMap<Class, E>(); | |
} | |
// 直接使うことはまずない。CustomMessageを経由して使う | |
public class CustomPacker extends CustomOperatorRegistry<MessagePacker> { | |
} | |
// 直接使うことはまずない。CustomMessageを経由して使う | |
public class CustomUnpacker extends CustomOperatorRegistry<MessageUnpacker> { | |
} | |
// 直接使うことはまずない。CustomMessageを経由して使う | |
public class CustomConverter extends CustomOperatorRegistry<MessageConverter> { | |
} | |
// カスタムシリアライザ・デシリアライザ・型変換を登録するクラス | |
public class CustomMessage { | |
public static void registerPacker(Class target, MessagePacker packer) { | |
CustomPacker.register(target, packer); | |
} | |
public static void registerTemplate(Class target, Template tmpl) { | |
CustomUnpacker.register(target, packer); | |
CustomConverter.register(target, packer); | |
} | |
} | |
// Packer | |
public void pack(Object obj) { | |
// primitive types... | |
if(obj instanceof MessagePackable) { | |
obj.messagePack(this); | |
return; | |
} | |
MessagePacker packer = CustomPacker.getRegistered(obj.getClass()); | |
if(packer != null) { | |
packer.pack(this, obj); | |
return; | |
} | |
Class klass = obj.getClass(); | |
if(/*@MessagePackMessageアノテーションをチェック*/) { | |
MessagePacker packer = FieldPacker.create(klass); // リフレクションでシリアライズするpackerを作成 | |
CustomMessage.register(klass, packer); | |
packer.pack(this, obj); | |
return; | |
} | |
// @MessagePackDelegateアノテーションをチェック => DelegatePacker.create(klass) | |
// @MessagePackOrdinalEnumアノテーションをチェック => OrdinalEnumPacker.create(klass) | |
// エラー | |
} | |
// Unpacker | |
public Object unpack(MessageUnpacker unpacker) { | |
return unpacker.unpack(this); | |
} | |
public Object unpack(MessageUnpackable obj) { | |
return obj.messageUnpack(this); | |
} | |
public Object unpack(Class klass) { | |
if(klass.isAssignableFrom(MessageUnpackable)) { | |
Object obj = klass.newInstance(); | |
((MessageUnpackable)obj).messageUnpack(this); | |
return obj; | |
} | |
MessageUnpacker unpacker = CustomUnpacker.get(klass); | |
if(unpacker != null) { | |
return unpacker.unpack(this); | |
} | |
if(/*@MessagePackMessageアノテーションをチェック*/) { | |
Template tmpl = FieldTemplate.create(klass); // リフレクションでデシリアライズ・型変換するtemplateを作成 | |
CustomMessage.register(klass, tmpl); | |
return tmpl.unpack(this); | |
} | |
// @MessagePackDelegateアノテーションをチェック => DelegateTemplate.create(klass) | |
// @MessagePackOrdinalEnumアノテーションをチェック => OrdinalEnumTemplate.create(klass) | |
// エラー | |
} | |
public class ClassTemplate implements Template { | |
private Class klass; | |
public ClassTemplate(Class klass) { | |
this.klass = klass; | |
} | |
public Object unpack(Unpacker pac) { | |
return pac.unpack(klass); | |
} | |
public Object convert(MessagePackObject from) { | |
MessageConverter converter = CustomConverter.get(klass); | |
if(converter != null) { | |
return converter.convert(from); | |
} | |
if(/* @MessagePackMessageアノテーションをチェック*/) { | |
Template tmpl = FieldTemplate.createTemplate(klass); | |
CustomMessage.register(klass, tmpl); | |
return tmpl; | |
} | |
// @MessagePackDelegateアノテーションをチェック => DelegateTemplate.create(klass) | |
// @MessagePackOrdinalEnumアノテーションをチェック => OrdinalEnumTemplate.create(klass) | |
// エラー | |
} | |
} | |
// MessagePackObject | |
public Object convert(Template tmpl) { | |
return tmpl.convert(this); | |
} | |
// import static Templates.*;用 | |
public class Templates { | |
public static Tempalte tList(Template elementTemplate) { | |
return new ListTemplate(elementTemplate); | |
} | |
public static Tempalte tMap(Template keyTemplate, Template valueTemplate) { | |
return new MapTemplate(keyTemplate, valueTemplate); | |
} | |
// ... | |
public static final TString = StringTemplate.instance; | |
public static Tempalte tString() { | |
return TString; | |
} | |
public static final TByteArray = ByteArrayTemplate.instance; | |
public static Tempalte tByteArray() { | |
return TByteArray; | |
} | |
// ... | |
} | |
// 標準提供Template群 | |
public class ListTemplate implements Template { | |
private Template elementTemplate; | |
public ListTemplate(Template elementTemplate) { | |
this.elementTemplate = elementTemplate; | |
} | |
public Object unpack(Unpacker pac) { | |
int length = pac.unpackArray(); | |
List<Object> list = new ArrayList(length); | |
for(; length > 0; length--) { | |
list.add( elementTemplate.unpack(pack) ); | |
} | |
return list; | |
} | |
public Object convert(MessagePackObject from) { | |
MessagePackObject[] array = from.asArray(); | |
List<Object> list = new ArrayList(array.length); | |
for(MessagePackObject element : array) { | |
list.add( elementTemplate.convert(element) ); | |
} | |
return list; | |
} | |
} | |
public class StringTemplate implements Template { | |
public Object unpack(Unpacker pac) { | |
pac.asString(); | |
} | |
public Object convert(MessagePackObject from) { | |
return from.asString(); | |
} | |
static final StringTemplate instance = new StringTemplate(); | |
static { | |
CustomMessage.registerTemplate(String.class, instance); | |
} | |
private StringTemplate() { } | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment