diff --git a/java/src/main/java/org/msgpack/CustomPacker.java b/java/src/main/java/org/msgpack/CustomPacker.java index f0c6b62c..743a52bb 100644 --- a/java/src/main/java/org/msgpack/CustomPacker.java +++ b/java/src/main/java/org/msgpack/CustomPacker.java @@ -17,23 +17,20 @@ // package org.msgpack; -import java.util.Map; -import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; -// FIXME package private? public class CustomPacker { - public static void register(Class target, MessagePacker converter) { - map.put(target, converter); + private static ConcurrentHashMap, MessagePacker> map = new ConcurrentHashMap, MessagePacker>(); + + public static void register(Class target, MessagePacker packer) { + map.putIfAbsent(target, packer); } - public static MessagePacker get(Class target) { + public static MessagePacker get(Class target) { return map.get(target); } - public static boolean isRegistered(Class target) { + public static boolean isRegistered(Class target) { return map.containsKey(target); } - - private static Map map = new HashMap(); } - diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index dd8cdee2..2f34bde8 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -22,8 +22,13 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.List; import java.util.Map; +import java.lang.annotation.Annotation; import java.math.BigInteger; +import org.msgpack.annotation.MessagePackDelegate; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; + /** * Packer enables you to serialize objects into OutputStream. * @@ -473,19 +478,36 @@ public class Packer { return packDouble((Double)o); } else if(o instanceof BigInteger) { return packBigInteger((BigInteger)o); - } + } - Class klass = o.getClass(); - - MessagePacker packer = CustomPacker.get(klass); - if(packer != null) { + Class klass = o.getClass(); + if (CustomPacker.isRegistered(klass)) { + MessagePacker packer = CustomPacker.get(klass); packer.pack(this, o); return this; + } else if (isAnnotated(klass, MessagePackMessage.class)) { + MessagePacker packer = ReflectionPacker.create(klass); + CustomPacker.register(klass, packer); + packer.pack(this, o); + return this; + } else if (isAnnotated(klass, MessagePackDelegate.class)) { + throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); + } else if (isAnnotated(klass, MessagePackOrdinalEnum.class)) { + throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); } - - // FIXME check annotations -> code generation -> CustomMessage.registerPacker +// Class klass = o.getClass(); +// MessagePacker packer = CustomPacker.get(klass); +// if(packer != null) { +// packer.pack(this, o); +// return this; +// } +// +// // FIXME check annotations -> code generation -> CustomMessage.registerPacker throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")"); } + + static boolean isAnnotated(Class target, Class with) { + return target.getAnnotation(with) != null; + } } - diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java b/java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java new file mode 100644 index 00000000..2a72d730 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java @@ -0,0 +1,12 @@ +package org.msgpack.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MessagePackDelegate { + +} diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackMessage.java b/java/src/main/java/org/msgpack/annotation/MessagePackMessage.java new file mode 100644 index 00000000..6efeb9d3 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/MessagePackMessage.java @@ -0,0 +1,12 @@ +package org.msgpack.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MessagePackMessage { + +} diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackOrdinalEnum.java b/java/src/main/java/org/msgpack/annotation/MessagePackOrdinalEnum.java new file mode 100644 index 00000000..4b0d9bb2 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/MessagePackOrdinalEnum.java @@ -0,0 +1,12 @@ +package org.msgpack.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MessagePackOrdinalEnum { + +} diff --git a/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java index f361eb46..27edde1f 100644 --- a/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java +++ b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java @@ -42,5 +42,33 @@ public class TestReflectionPackerTemplate { assertEquals(src.s1, dst.s1); assertEquals(src.s2, dst.s2); } + + @Test + public void testPackConvert02() throws Exception { + tString(); // FIXME link StringTemplate + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + CustomPacker.register(StringFieldClass.class, ReflectionPacker.create(StringFieldClass.class)); + + + StringFieldClass src = new StringFieldClass(); + + src.s1 = "kumofs"; + src.s2 = "frsyuki"; + + new Packer(out).pack(src); + + Template tmpl = ReflectionTemplate.create(StringFieldClass.class); + + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + + Object obj = tmpl.unpack(new Unpacker(in)); + assertEquals(obj.getClass(), StringFieldClass.class); + + StringFieldClass dst = (StringFieldClass)obj; + assertEquals(src.s1, dst.s1); + assertEquals(src.s2, dst.s2); + } }