Created
September 25, 2010 07:11
-
-
Save frsyuki/596574 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
// MessagePackerインタフェース | |
public interface MessagePacker { | |
public void pack(Packer into, Object target) throws IOException; | |
} | |
// MessageConverterインタフェース | |
public interface MessageConverter { | |
public void convert(Object into, MessagePackObject from) throws TypeException; | |
} | |
// カスタムシリアライザを登録しておく | |
public class CustomPacker { | |
static void register(Class target, MessagePacker packer); | |
static boolean isRegistered(Class target); | |
static MessagePacker getRegistered(Class target); | |
} | |
// カスタム型変換を登録しておく | |
public class CustomConverter { | |
static void register(Class target, MessageConverter converter); | |
static boolean isRegistered(Class target); | |
static MessageConverter getRegistered(Class target); | |
} | |
// @MessagePackMessageアノテーション | |
@Target(ElementType.TYPE) | |
@Retention(RetentionPolicy.RUNTIME) | |
public @interface MessagePackMessage { } | |
// @MessagePackDelegate("memberName")アノテーション | |
@Target(ElementType.TYPE) | |
@Retention(RetentionPolicy.RUNTIME) | |
public @interface MessagePackDelegate { } | |
// @MessagePackOrdinalEnumアノテーション | |
@Target(ElementType.TYPE) | |
@Retention(RetentionPolicy.RUNTIME) | |
public @interface MessagePackOrdinalEnum { } | |
// リフレクション+コード生成でシリアライズするMessagePackerを作成するクラス | |
public abstract MessagePackMessagePacker implements MessagePacker { | |
public static MessagePackMessagePacker createPacker(Class target); | |
} | |
// シリアライズをメンバメソッドに委譲するMessagePackerを作成するクラス | |
public abstract DelegatePacker implements MessagePacker { | |
public static DelegatePacker createPacker(Class target); | |
} | |
// ordinal()でシリアライズするMessagePackerを作成するクラス | |
public abstract OrdinalEnumPacker implements MessagePacker { | |
public static OrdinalEnumPacker createPacker(Class target); | |
} | |
// MessagePackableインタフェース | |
public interface MessagePackable { | |
public void messagePack(Packer into) throws IOException; | |
} | |
// MessageConvertableインタフェース | |
public interface MessageConvertable { | |
public void messageConvert(MessagePackObject from) throws TypeException;; | |
} | |
// Packerクラス | |
public class Packer { | |
public void pack(Object obj) { | |
if(/*プリミティブ型なら*/) { | |
// プリミティブ型 | |
// ほげほげする(実装済み) | |
} else if(obj instanceof MessagePackable) { | |
// MessagePackableなオブジェクト | |
// ユーザーが自前でカスタムシリアライザを実装したクラスや、newEnhancedIntance()で作ったオブジェクトは、ここで引っかかる | |
// キャストしてシリアライズ | |
((MessagePackable)obj).messagePack(this); | |
} else if(CustomPacker.isRegistered(obj.getClass())) { | |
// カスタムシリアライザが登録されているクラス | |
CustomPacker.getRegistered(obj.getClass()).pack(this, obj); | |
} else if(/*@MessagePackMessageアノテーションが付いているなら*/) { | |
// MessagePackMessagePackerを作成 | |
MessagePacker packer = MessagePackMessagePacker.createPacker(obj.getClass()); | |
CustomPacker.register(obj.getClass(), packer); // 作成したpackerはキャッシュ -> 以後は「カスタムシリアライザが登録されているクラス」に引っかかる | |
packer.pack(this, obj); | |
} else if(/*@MessagePackDelegateアノテーションが付いているなら*/) { | |
// DelegatePackerを作成 | |
MessagePacker packer = DelegatePacker.createPacker(obj.getClass()); | |
CustomPacker.register(obj.getClass(), packer); // 作成したpackerはキャッシュ -> 以後は「カスタムシリアライザが登録されているクラス」に引っかかる | |
packer.pack(this, obj); | |
} else if(/*@MessagePackOrdinalEnumアノテーションが付いているなら*/) { | |
// OrdinalEnumPackerを作成 | |
MessagePacker packer = OrdinalEnumPacker.createPacker(obj.getClass()); | |
CustomPacker.register(obj.getClass(), packer); // 作成したpackerはキャッシュ -> 以後は「カスタムシリアライザが登録されているクラス」に引っかかる | |
packer.pack(this, obj); | |
} else { | |
// エラー | |
} | |
} | |
} | |
// | |
// 使い方: | |
// | |
// | |
// ・自分で定義したクラスをシリアライズしたい | |
// 1. @MessagePackMessageアノテーションを付ける | |
// | |
// ・自分で定義したクラスをシリアライズしたい(独自のシリアライズ方法で) | |
// 1. MessagePackableインタフェースをimplementsする | |
// | |
// ・自分で定義したクラスをシリアライズしたい(メンバ変数1つを直接シリアライズするように委譲) | |
// 1. @MessagePackaDelegate("memberName")アノテーションを付ける | |
// | |
// | |
// ・他人が定義したクラスをシリアライズしたい | |
// 1. CustomPacker.register(ThatClass.class, MessagePackMessagePacker.createPacker(ThatClass.class)); を実行する | |
// | |
// ・他人が定義したクラスをシリアライズしたい(独自のシリアライズ方法で) | |
// 1. MessagePackerインタフェースをimplementsしたクラスを作る | |
// 2. CustomPacker.register(ThatClass.class, new YourPackerClass()); を実行する | |
// | |
// ・他人が定義したクラスをシリアライズしたい(メンバ変数1つを直接シリアライズするように委譲) | |
// 2. CustomPacker.register(ThatClass.class, DelegatePacker.createPacker(ThatClass.class)); を実行する | |
// | |
// | |
// ・自分で定義したEnumをシリアライズしたい | |
// 1. enumの定義で、値を表現するメンバ変数を持たせる | |
// 2. @MessagePackDelegate("memberName")アノテーションを付ける | |
// | |
// ・自分で定義したEnumをシリアライズしたい(宣言する順番が変えたときに互換性が無くなってもいいよ) | |
// 1. @MessagePackOrdinalEnumアノテーションを付ける | |
// | |
// | |
// ・他人が定義したEnumをシリアライズしたい | |
// 1. enumの定義で、値を表現するメンバ変数を持っていることを確認する | |
// 2. CustomPacker.register(ThatEnum.class, DelegatePacker.createPacker(ThatEnum.class, "memberName")); を実行する | |
// | |
// ・他人が定義したEnumをシリアライズしたい(宣言する順番が変えたときに互換性が無くなってもいいよ) | |
// 1. CustomPacker.register(ThatEnum.class, OrdinalEnumPacker.createPacker(ThatEnum.class)); を実行する | |
// | |
// 所感:全般に命名が良く無いので要検討。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment