From dfb97e7961e7947d09240f18234a5aaced6e2d6f Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Mon, 27 Sep 2010 10:00:47 +0900 Subject: [PATCH 1/9] java: adds several annotations in an org.msgpack.annotation package and edits Packer.java and its test program --- .../main/java/org/msgpack/CustomPacker.java | 17 ++++----- java/src/main/java/org/msgpack/Packer.java | 38 +++++++++++++++---- .../annotation/MessagePackDelegate.java | 12 ++++++ .../annotation/MessagePackMessage.java | 12 ++++++ .../annotation/MessagePackOrdinalEnum.java | 12 ++++++ .../msgpack/TestReflectionPackerTemplate.java | 28 ++++++++++++++ 6 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java create mode 100644 java/src/main/java/org/msgpack/annotation/MessagePackMessage.java create mode 100644 java/src/main/java/org/msgpack/annotation/MessagePackOrdinalEnum.java 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); + } } From 02342ba540d9b1a30917c08c8892e2347f508798 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Mon, 27 Sep 2010 10:10:10 +0900 Subject: [PATCH 2/9] java: refactor a Packer class --- java/src/main/java/org/msgpack/Packer.java | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index 2f34bde8..00a3aae4 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -481,12 +481,12 @@ public class Packer { } Class klass = o.getClass(); - if (CustomPacker.isRegistered(klass)) { - MessagePacker packer = CustomPacker.get(klass); + MessagePacker packer = CustomPacker.get(klass); + if(packer != null) { packer.pack(this, o); return this; } else if (isAnnotated(klass, MessagePackMessage.class)) { - MessagePacker packer = ReflectionPacker.create(klass); + ReflectionPacker.create(klass); CustomPacker.register(klass, packer); packer.pack(this, o); return this; @@ -495,14 +495,8 @@ public class Packer { } else if (isAnnotated(klass, MessagePackOrdinalEnum.class)) { throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); } -// 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 + + // FIXME check annotations -> code generation -> CustomMessage.registerPacker throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")"); } From ee1ba5c0f22968b580200b001fc2b94a705b5521 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Mon, 27 Sep 2010 10:16:32 +0900 Subject: [PATCH 3/9] java: fixed a bug within a Packer class --- java/src/main/java/org/msgpack/Packer.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index 00a3aae4..b4526cde 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -486,8 +486,7 @@ public class Packer { packer.pack(this, o); return this; } else if (isAnnotated(klass, MessagePackMessage.class)) { - ReflectionPacker.create(klass); - CustomPacker.register(klass, packer); + packer = ReflectionPacker.create(klass); packer.pack(this, o); return this; } else if (isAnnotated(klass, MessagePackDelegate.class)) { @@ -495,7 +494,7 @@ public class Packer { } else if (isAnnotated(klass, MessagePackOrdinalEnum.class)) { throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); } - + CustomPacker.register(klass, packer); // FIXME check annotations -> code generation -> CustomMessage.registerPacker throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")"); From 1c0afbc5c5abba1bddff6743581d4e1e48b895f8 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Mon, 27 Sep 2010 17:42:00 +0900 Subject: [PATCH 4/9] java: loads template classes when Unpacker, MessagePackObject or ClassTemplate is loaded --- java/src/main/java/org/msgpack/MessagePackObject.java | 4 ++++ java/src/main/java/org/msgpack/Templates.java | 2 ++ java/src/main/java/org/msgpack/Unpacker.java | 3 +++ .../test/java/org/msgpack/TestReflectionPackerTemplate.java | 4 ---- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/java/src/main/java/org/msgpack/MessagePackObject.java b/java/src/main/java/org/msgpack/MessagePackObject.java index f7e9e0e6..8dd9d8b5 100644 --- a/java/src/main/java/org/msgpack/MessagePackObject.java +++ b/java/src/main/java/org/msgpack/MessagePackObject.java @@ -23,6 +23,10 @@ import java.util.Map; import java.math.BigInteger; public abstract class MessagePackObject implements Cloneable, MessagePackable { + static { + Templates.load(); + } + public boolean isNil() { return false; } diff --git a/java/src/main/java/org/msgpack/Templates.java b/java/src/main/java/org/msgpack/Templates.java index 222f6257..b6938400 100644 --- a/java/src/main/java/org/msgpack/Templates.java +++ b/java/src/main/java/org/msgpack/Templates.java @@ -20,6 +20,8 @@ package org.msgpack; import org.msgpack.template.*; public class Templates { + public static void load() { } + public static Template tList(Template elementTemplate) { return new ListTemplate(elementTemplate); } diff --git a/java/src/main/java/org/msgpack/Unpacker.java b/java/src/main/java/org/msgpack/Unpacker.java index 4e397488..9966fcad 100644 --- a/java/src/main/java/org/msgpack/Unpacker.java +++ b/java/src/main/java/org/msgpack/Unpacker.java @@ -103,6 +103,9 @@ import java.math.BigInteger; * */ public class Unpacker implements Iterable { + static { + Templates.load(); + } // buffer: // +---------------------------------------------+ diff --git a/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java index 27edde1f..1f0016d7 100644 --- a/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java +++ b/java/src/test/java/org/msgpack/TestReflectionPackerTemplate.java @@ -18,8 +18,6 @@ public class TestReflectionPackerTemplate { @Test public void testPackConvert() throws Exception { - tString(); // FIXME link StringTemplate - ByteArrayOutputStream out = new ByteArrayOutputStream(); MessagePacker packer = ReflectionPacker.create(StringFieldClass.class); @@ -45,8 +43,6 @@ public class TestReflectionPackerTemplate { @Test public void testPackConvert02() throws Exception { - tString(); // FIXME link StringTemplate - ByteArrayOutputStream out = new ByteArrayOutputStream(); CustomPacker.register(StringFieldClass.class, ReflectionPacker.create(StringFieldClass.class)); From e739c60e9f37c9d9903df7f11c866e15f2c12404 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Mon, 27 Sep 2010 17:42:22 +0900 Subject: [PATCH 5/9] java: pom.xml: v0.4 --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index 70da6a6f..eb7930d5 100755 --- a/java/pom.xml +++ b/java/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.msgpack msgpack - 0.3 + 0.4 MessagePack for Java MessagePack for Java From 2736b88dd569cc0e11c9ea18a917ba4dfc1a095e Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Mon, 27 Sep 2010 17:55:48 +0900 Subject: [PATCH 6/9] edit Packer and Unpacker classes, and move org.msgpack.util.annotation.*.java to org.msgpack.util.codegen.*.java --- .../java/org/msgpack/CustomConverter.java | 15 +- .../main/java/org/msgpack/CustomMessage.java | 11 +- .../main/java/org/msgpack/CustomUnpacker.java | 16 +- .../java/org/msgpack/MessageConverter.java | 4 +- java/src/main/java/org/msgpack/Packer.java | 19 +- java/src/main/java/org/msgpack/Unpacker.java | 26 +- .../annotation/PackUnpackUtilException.java | 12 - .../msgpack/util/codegen/BasicConstants.java | 160 ++++++++++++ .../org/msgpack/util/codegen/Constants.java | 7 + .../msgpack/util/codegen/DynamicCodeGen.java | 232 ++++++++++++++++++ .../util/codegen/DynamicCodeGenBase.java | 189 ++++++++++++++ .../util/codegen/DynamicCodeGenException.java | 12 + .../util/codegen/DynamicCodeGenPacker.java | 18 ++ .../util/codegen/DynamicCodeGenTemplate.java | 17 ++ .../MessagePackOptional.java | 2 +- .../MessagePackRequired.java | 2 +- .../MessagePackUnpackable.java | 2 +- .../PackUnpackUtil.java | 18 +- .../codegen/TestDynamicCodeGenPacker.java | 51 ++++ .../TestMessagePackUnpackable.java | 27 +- 20 files changed, 766 insertions(+), 74 deletions(-) delete mode 100644 java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/BasicConstants.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/Constants.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java rename java/src/main/java/org/msgpack/util/{annotation => codegen}/MessagePackOptional.java (88%) rename java/src/main/java/org/msgpack/util/{annotation => codegen}/MessagePackRequired.java (88%) rename java/src/main/java/org/msgpack/util/{annotation => codegen}/MessagePackUnpackable.java (87%) rename java/src/main/java/org/msgpack/util/{annotation => codegen}/PackUnpackUtil.java (99%) create mode 100644 java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java rename java/src/test/java/org/msgpack/util/{annotation => codegen}/TestMessagePackUnpackable.java (96%) diff --git a/java/src/main/java/org/msgpack/CustomConverter.java b/java/src/main/java/org/msgpack/CustomConverter.java index 4351464c..abbc88ab 100644 --- a/java/src/main/java/org/msgpack/CustomConverter.java +++ b/java/src/main/java/org/msgpack/CustomConverter.java @@ -17,23 +17,22 @@ // package org.msgpack; -import java.util.Map; -import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; // FIXME package private? public class CustomConverter { - public static void register(Class target, MessageConverter converter) { - map.put(target, converter); + private static ConcurrentHashMap, MessageConverter> map = new ConcurrentHashMap, MessageConverter>(); + + public static void register(Class target, MessageConverter converter) { + map.putIfAbsent(target, converter); } - public static MessageConverter get(Class target) { + public static MessageConverter 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/CustomMessage.java b/java/src/main/java/org/msgpack/CustomMessage.java index f87898cd..53f83236 100644 --- a/java/src/main/java/org/msgpack/CustomMessage.java +++ b/java/src/main/java/org/msgpack/CustomMessage.java @@ -17,14 +17,19 @@ // package org.msgpack; +import java.lang.annotation.Annotation; + public class CustomMessage { - public static void registerPacker(Class target, MessagePacker packer) { + public static void registerPacker(Class target, MessagePacker packer) { CustomPacker.register(target, packer); } - public static void registerTemplate(Class target, Template tmpl) { + public static void registerTemplate(Class target, Template tmpl) { CustomUnpacker.register(target, tmpl); CustomConverter.register(target, tmpl); } -} + static boolean isAnnotated(Class target, Class with) { + return target.getAnnotation(with) != null; + } +} diff --git a/java/src/main/java/org/msgpack/CustomUnpacker.java b/java/src/main/java/org/msgpack/CustomUnpacker.java index b6047b84..b45292b5 100644 --- a/java/src/main/java/org/msgpack/CustomUnpacker.java +++ b/java/src/main/java/org/msgpack/CustomUnpacker.java @@ -17,23 +17,21 @@ // package org.msgpack; -import java.util.Map; -import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; // FIXME package private? public class CustomUnpacker { - public static void register(Class target, MessageUnpacker converter) { - map.put(target, converter); + private static ConcurrentHashMap, MessageUnpacker> map = new ConcurrentHashMap, MessageUnpacker>(); + + public static void register(Class target, MessageUnpacker converter) { + map.putIfAbsent(target, converter); } - public static MessageUnpacker get(Class target) { + public static MessageUnpacker 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/MessageConverter.java b/java/src/main/java/org/msgpack/MessageConverter.java index 8ad60ae0..5e5f4378 100644 --- a/java/src/main/java/org/msgpack/MessageConverter.java +++ b/java/src/main/java/org/msgpack/MessageConverter.java @@ -17,9 +17,7 @@ // package org.msgpack; -import java.io.IOException; - public interface MessageConverter { - public Object convert(MessagePackObject from) throws MessageTypeException; + Object convert(MessagePackObject from) throws MessageTypeException; } diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index b4526cde..9ea4ea21 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -485,22 +485,21 @@ public class Packer { if(packer != null) { packer.pack(this, o); return this; - } else if (isAnnotated(klass, MessagePackMessage.class)) { + } else if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) { packer = ReflectionPacker.create(klass); packer.pack(this, o); return this; - } else if (isAnnotated(klass, MessagePackDelegate.class)) { + } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) { + // FIXME DelegatePacker throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } else if (isAnnotated(klass, MessagePackOrdinalEnum.class)) { + } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) { + // FIXME OrdinalEnumPacker throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); } - CustomPacker.register(klass, packer); - // FIXME check annotations -> code generation -> CustomMessage.registerPacker - + if (packer != null) { + CustomMessage.registerPacker(klass, packer); + } 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/Unpacker.java b/java/src/main/java/org/msgpack/Unpacker.java index 4e397488..add33125 100644 --- a/java/src/main/java/org/msgpack/Unpacker.java +++ b/java/src/main/java/org/msgpack/Unpacker.java @@ -18,12 +18,17 @@ package org.msgpack; import java.lang.Iterable; +import java.lang.annotation.Annotation; import java.io.InputStream; import java.io.IOException; import java.util.Iterator; import java.nio.ByteBuffer; import java.math.BigInteger; +import org.msgpack.annotation.MessagePackDelegate; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; + /** * Unpacker enables you to deserialize objects from stream. * @@ -573,7 +578,7 @@ public class Unpacker implements Iterable { obj.messageUnpack(this); } - final public Object unpack(Class klass) throws IOException, MessageTypeException, InstantiationException, IllegalAccessException { + final public Object unpack(Class klass) throws IOException, MessageTypeException, InstantiationException, IllegalAccessException { if(MessageUnpackable.class.isAssignableFrom(klass)) { Object obj = klass.newInstance(); ((MessageUnpackable)obj).messageUnpack(this); @@ -584,14 +589,25 @@ public class Unpacker implements Iterable { if(unpacker != null) { return unpacker.unpack(this); } - - // FIXME check annotations -> code generation -> CustomMessage.registerTemplate - + + Template tmpl = null; + if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) { + tmpl = ReflectionTemplate.create(klass); + return tmpl.unpack(this); + } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) { + // FIXME DelegateTemplate + throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); + } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) { + // FIXME OrdinalEnumTemplate + throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); + } + if (tmpl != null) { + CustomMessage.registerTemplate(klass, tmpl); + } MessageConverter converter = CustomConverter.get(klass); if(converter != null) { return converter.convert(unpackObject()); } - throw new MessageTypeException(); } } diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java deleted file mode 100644 index df3af058..00000000 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.msgpack.util.annotation; - -public class PackUnpackUtilException extends RuntimeException { - - public PackUnpackUtilException(String reason) { - super(reason); - } - - public PackUnpackUtilException(String reason, Throwable t) { - super(reason, t); - } -} diff --git a/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java new file mode 100644 index 00000000..53a8a4ce --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java @@ -0,0 +1,160 @@ +package org.msgpack.util.codegen; + +public interface BasicConstants { + + String KEYWORD_MODIFIER_PUBLIC = "public"; + + String KEYWORD_CATCH = "catch"; + + String KEYWORD_ELSE = "else"; + + String KEYWORD_ELSEIF = "else if"; + + String KEYWORD_FOR = "for"; + + String KEYWORD_IF = "if"; + + String KEYWORD_INSTANCEOF = "instanceof"; + + String KEYWORD_NEW = "new"; + + String KEYWORD_NULL = "null"; + + String KEYWORD_THROW = "throw"; + + String KEYWORD_THROWS = "throws"; + + String KEYWORD_TRY = "try"; + + String CHAR_NAME_SPACE = " "; + + String CHAR_NAME_COMMA = ","; + + String CHAR_NAME_EQUAL = "="; + + String CHAR_NAME_PLUS = "+"; + + String CHAR_NAME_LESSTHAN = "<"; + + String CHAR_NAME_RIGHT_PARENTHESIS = ")"; + + String CHAR_NAME_LEFT_PARENTHESIS = "("; + + String CHAR_NAME_RIGHT_CURLY_BRACKET = "}"; + + String CHAR_NAME_LEFT_CURLY_BRACKET = "{"; + + String CHAR_NAME_RIGHT_SQUARE_BRACKET = "]"; + + String CHAR_NAME_LEFT_SQUARE_BRACKET = "["; + + String CHAR_NAME_DOT = "."; + + String CHAR_NAME_SEMICOLON = ";"; + + String VARIABLE_NAME_PK = "_$$_pk"; + + String VARIABLE_NAME_OBJ = "_$$_obj"; + + String VARIABLE_NAME_TARGET = "_$$_target"; + + String VARIABLE_NAME_SIZE = "_$$_len"; + + String VARIABLE_NAME_ARRAY = "_$$_ary"; + + String VARIABLE_NAME_LIST = "_$$_list"; + + String VARIABLE_NAME_MAP = "_$$_map"; + + String VARIABLE_NAME_KEY = "_$$_key"; + + String VARIABLE_NAME_VAL = "_$$_val"; + + String VARIABLE_NAME_ITER = "_$$_iter"; + + String VARIABLE_NAME_MPO = "_$$_mpo"; + + String VARIABLE_NAME_I = "i"; + + String METHOD_NAME_VALUEOF = "valueOf"; + + String METHOD_NAME_ADD = "add"; + + String METHOD_NAME_PUT = "put"; + + String METHOD_NAME_GET = "get"; + + String METHOD_NAME_SIZE = "size"; + + String METHOD_NAME_KEYSET = "keySet"; + + String METHOD_NAME_ITERATOR = "iterator"; + + String METHOD_NAME_HASNEXT = "hasNext"; + + String METHOD_NAME_NEXT = "next"; + + String METHOD_NAME_MSGPACK = "messagePack"; + + String METHOD_NAME_MSGUNPACK = "messageUnpack"; + + String METHOD_NAME_MSGCONVERT = "messageConvert"; + + String METHOD_NAME_PACK = "pack"; + + String METHOD_NAME_PACKARRAY = "packArray"; + + String METHOD_NAME_UNPACK = "unpack"; + + String METHOD_NAME_UNPACKBOOLEAN = "unpackBoolean"; + + String METHOD_NAME_UNPACKBYTE = "unpackByte"; + + String METHOD_NAME_UNPACKDOUBLE = "unpackDouble"; + + String METHOD_NAME_UNPACKFLOAT = "unpackFloat"; + + String METHOD_NAME_UNPACKINT = "unpackInt"; + + String METHOD_NAME_UNPACKLONG = "unpackLong"; + + String METHOD_NAME_UNPACKSHORT = "unpackShort"; + + String METHOD_NAME_UNPACKSTRING = "unpackString"; + + String METHOD_NAME_UNPACKBIGINTEGER = "unpackBigInteger"; + + String METHOD_NAME_UNPACKOBJECT = "unpackObject"; + + String METHOD_NAME_UNPACKBYTEARRAY = "unpackByteArray"; + + String METHOD_NAME_UNPACKARRAY = "unpackArray"; + + String METHOD_NAME_UNPACKMAP = "unpackMap"; + + String METHOD_NAME_ASARRAY = "asArray"; + + String METHOD_NAME_ASBOOLEAN = "asBoolean"; + + String METHOD_NAME_ASBYTE = "asByte"; + + String METHOD_NAME_ASSHORT = "asShort"; + + String METHOD_NAME_ASINT = "asInt"; + + String METHOD_NAME_ASFLOAT = "asFloat"; + + String METHOD_NAME_ASLONG = "asLong"; + + String METHOD_NAME_ASDOUBLE = "asDouble"; + + String METHOD_NAME_ASSTRING = "asString"; + + String METHOD_NAME_ASBYTEARRAY = "asByteArray"; + + String METHOD_NAME_ASBIGINTEGER = "asBigInteger"; + + String METHOD_NAME_ASLIST = "asList"; + + String METHOD_NAME_ASMAP = "asMap"; +} diff --git a/java/src/main/java/org/msgpack/util/codegen/Constants.java b/java/src/main/java/org/msgpack/util/codegen/Constants.java new file mode 100644 index 00000000..ddeef31f --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/Constants.java @@ -0,0 +1,7 @@ +package org.msgpack.util.codegen; + +public interface Constants extends BasicConstants { + String POSTFIX_TYPE_NAME_PACKER = "_$$_Packer"; + + String POSTFIX_TYPE_NAME_ENHANCER = "_$$_Enhanced"; +} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java new file mode 100644 index 00000000..9f63242d --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java @@ -0,0 +1,232 @@ +package org.msgpack.util.codegen; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtMethod; +import javassist.CtNewConstructor; +import javassist.CtNewMethod; +import javassist.NotFoundException; + +import org.msgpack.MessagePacker; +import org.msgpack.Packer; +import org.msgpack.Template; + +public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { + + private static DynamicCodeGen INSTANCE; + + private static AtomicInteger COUNTER; + + public static DynamicCodeGen getInstance() { + if (INSTANCE == null) { + INSTANCE = new DynamicCodeGen(); + } + return INSTANCE; + } + + private ClassPool pool; + + private DynamicCodeGen() { + this.pool = ClassPool.getDefault(); + } + + public Class generateMessagePackerClass(Class origClass) { + try { + String origName = origClass.getName(); + String packerName = origName + POSTFIX_TYPE_NAME_PACKER; + checkClassValidation(origClass); + checkDefaultConstructorValidation(origClass); + CtClass packerCtClass = pool.makeClass(packerName); + setInterface(packerCtClass, MessagePacker.class); + addDefaultConstructor(packerCtClass); + Field[] fields = getDeclaredFields(origClass); + addPackMethod(packerCtClass, origClass, fields); + return createClass(packerCtClass); + } catch (NotFoundException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } catch (CannotCompileException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } + } + + public Class generateTemplateClass(Class origClass) { + try { + String origName = origClass.getName(); + String packerName = origName + POSTFIX_TYPE_NAME_PACKER; + checkClassValidation(origClass); + checkDefaultConstructorValidation(origClass); + CtClass packerCtClass = pool.makeClass(packerName); + setInterface(packerCtClass, Template.class); + addDefaultConstructor(packerCtClass); + Field[] fields = getDeclaredFields(origClass); + addPackMethod(packerCtClass, origClass, fields); + return createClass(packerCtClass); + } catch (NotFoundException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } catch (CannotCompileException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } + } + + private void checkClassValidation(Class origClass) { + // not public, abstract, final + int mod = origClass.getModifiers(); + if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) + || Modifier.isAbstract(mod) || Modifier.isFinal(mod)) { + throwClassValidationException(origClass, + "it must be a public class"); + } + // interface, enum + if (origClass.isInterface() || origClass.isEnum()) { + throwClassValidationException(origClass, + "it must not be an interface or enum"); + } + } + + private static void throwClassValidationException(Class origClass, + String msg) { + throw new DynamicCodeGenException(msg + ": " + origClass.getName()); + } + + private void checkDefaultConstructorValidation(Class origClass) { + Constructor cons = null; + try { + cons = origClass.getDeclaredConstructor(new Class[0]); + } catch (Exception e1) { + throwConstructoValidationException(origClass); + } + + int mod = cons.getModifiers(); + if (!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) { + throwConstructoValidationException(origClass); + } + } + + private static void throwConstructoValidationException(Class origClass) { + throw new DynamicCodeGenException( + "it must have a public zero-argument constructor: " + + origClass.getName()); + } + + private void setInterface(CtClass packerCtClass, Class infClass) + throws NotFoundException { + CtClass infCtClass = pool.get(infClass.getName()); + packerCtClass.addInterface(infCtClass); + } + + private void addDefaultConstructor(CtClass enhCtClass) + throws CannotCompileException { + CtConstructor newCtCons = CtNewConstructor + .defaultConstructor(enhCtClass); + enhCtClass.addConstructor(newCtCons); + } + + private Field[] getDeclaredFields(Class origClass) { + ArrayList allFields = new ArrayList(); + Class nextClass = origClass; + while (nextClass != Object.class) { + Field[] fields = nextClass.getDeclaredFields(); + for (Field field : fields) { + try { + checkFieldValidation(field, allFields); + allFields.add(field); + } catch (DynamicCodeGenException e) { // ignore + } + } + nextClass = nextClass.getSuperclass(); + } + return allFields.toArray(new Field[0]); + } + + private void checkFieldValidation(Field field, List fields) { + // check modifiers (public or protected) + int mod = field.getModifiers(); + if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) + || Modifier.isStatic(mod) || Modifier.isFinal(mod) + || Modifier.isTransient(mod) || field.isSynthetic()) { + throwFieldValidationException(field); + } + // check same name + for (Field f : fields) { + if (f.getName().equals(field.getName())) { + throwFieldValidationException(field); + } + } + } + + private static void throwFieldValidationException(Field field) { + throw new DynamicCodeGenException("it must be a public field: " + + field.getName()); + } + + private void addPackMethod(CtClass packerCtClass, Class c, Field[] fs) + throws CannotCompileException, NotFoundException { + StringBuilder sb = new StringBuilder(); + sb.append(KEYWORD_MODIFIER_PUBLIC); + sb.append(CHAR_NAME_SPACE); + sb.append(void.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(METHOD_NAME_PACK); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Packer.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_PK); + sb.append(CHAR_NAME_COMMA); + sb.append(CHAR_NAME_SPACE); + sb.append(Object.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_OBJ); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SPACE); + sb.append(KEYWORD_THROWS); + sb.append(CHAR_NAME_SPACE); + sb.append(IOException.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + insertPackMethodBody(sb, c, fs); + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + // System.out.println("pack method: " + sb.toString()); + CtMethod newCtMethod = CtNewMethod.make(sb.toString(), packerCtClass); + packerCtClass.addMethod(newCtMethod); + } + + private void insertPackMethodBody(StringBuilder sb, Class c, Field[] fs) { + insertLocalVariableDecl(sb, c, VARIABLE_NAME_TARGET); + StringBuilder mc = new StringBuilder(); + insertTypeCast(mc, c, VARIABLE_NAME_OBJ); + insertValueInsertion(sb, mc.toString()); + insertSemicolon(sb); + insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACKARRAY, + new String[] { new Integer(fs.length).toString() }); + insertSemicolon(sb); + for (Field f : fs) { + insertCodeOfPackCall(sb, f); + } + } + + private void insertCodeOfPackCall(StringBuilder sb, Field field) { + StringBuilder aname = new StringBuilder(); + aname.append(VARIABLE_NAME_TARGET); + aname.append(CHAR_NAME_DOT); + aname.append(field.getName()); + insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACK, + new String[] { aname.toString() }); + insertSemicolon(sb); + } + + private Class createClass(CtClass packerCtClass) + throws CannotCompileException { + return packerCtClass.toClass(null, null); + } +} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java new file mode 100644 index 00000000..24ae579a --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java @@ -0,0 +1,189 @@ +package org.msgpack.util.codegen; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +public class DynamicCodeGenBase implements BasicConstants { + public DynamicCodeGenBase() { + } + + public void insertSemicolon(StringBuilder sb) { + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + } + + public void insertPublicFieldDecl(StringBuilder sb, Class type, + String name) { + sb.append(KEYWORD_MODIFIER_PUBLIC); + sb.append(CHAR_NAME_SPACE); + sb.append(type.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(name); + } + + public void insertLocalVariableDecl(StringBuilder sb, Class type, + String name) { + sb.append(type.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(name); + } + + public void insertValueInsertion(StringBuilder sb, String expr) { + // = expr + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(expr); + } + + public void insertDefaultConsCall(StringBuilder sb, Class type) { + // new tname() + insertConsCall(sb, type, null); + } + + public void insertConsCall(StringBuilder sb, Class type, String expr) { + // new tname(expr) + sb.append(KEYWORD_NEW); + sb.append(CHAR_NAME_SPACE); + sb.append(type.getName()); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + if (expr != null) { + sb.append(expr); + } + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } + + public void insertMethodCall(StringBuilder sb, String tname, String mname, + String[] anames) { + // tname.mname(anames[0], anames[1], ...) + int len = anames.length; + sb.append(tname); + sb.append(CHAR_NAME_DOT); + sb.append(mname); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + for (int i = 0; i < len; ++i) { + sb.append(anames[i]); + if (i + 1 != len) { + sb.append(CHAR_NAME_COMMA); + sb.append(CHAR_NAME_SPACE); + } + } + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } + + public void insertTypeCast(StringBuilder sb, Class type) { + // (type) + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(type.getName()); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } + + public void insertTypeCast(StringBuilder sb, Class type, String varName) { + // ((type)var) + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(type.getName()); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(varName); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } + + public void insertTypeConvToObjectType(StringBuilder sb, Class type, + String expr) throws DynamicCodeGenException { + if (type.isPrimitive()) { // primitive type + if (type.equals(boolean.class)) { + // new Boolean(expr) + insertConsCall(sb, Boolean.class, expr); + } else if (type.equals(byte.class)) { + insertConsCall(sb, Byte.class, expr); + } else if (type.equals(short.class)) { + insertConsCall(sb, Short.class, expr); + } else if (type.equals(int.class)) { + insertConsCall(sb, Integer.class, expr); + } else if (type.equals(long.class)) { + insertConsCall(sb, Long.class, expr); + } else if (type.equals(float.class)) { + insertConsCall(sb, Float.class, expr); + } else if (type.equals(double.class)) { + insertConsCall(sb, Double.class, expr); + } else { + throw new DynamicCodeGenException("Type error: " + + type.getName()); + } + } else { // reference type + sb.append(expr); + } + } + + public void insertTryCatchBlocks(StringBuilder sb, String tryBody, + List> types, List names, List catchBodies) { + int len = types.size(); + sb.append(KEYWORD_TRY); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + sb.append(tryBody); + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + for (int i = 0; i < len; ++i) { + sb.append(KEYWORD_CATCH); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(types.get(i).getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(names.get(i)); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + sb.append(catchBodies.get(i)); + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + } + } + + public String getAsMethod(Class c) throws DynamicCodeGenException { + if (c.equals(boolean.class)) { + return METHOD_NAME_ASBOOLEAN; + } else if (c.equals(byte.class)) { + return METHOD_NAME_ASBYTE; + } else if (c.equals(short.class)) { + return METHOD_NAME_ASSHORT; + } else if (c.equals(int.class)) { + return METHOD_NAME_ASINT; + } else if (c.equals(float.class)) { + return METHOD_NAME_ASFLOAT; + } else if (c.equals(long.class)) { + return METHOD_NAME_ASLONG; + } else if (c.equals(double.class)) { + return METHOD_NAME_ASDOUBLE; + } else if (c.equals(Boolean.class)) { + return METHOD_NAME_ASBOOLEAN; + } else if (c.equals(Byte.class)) { + return METHOD_NAME_ASBYTE; + } else if (c.equals(Short.class)) { + return METHOD_NAME_ASSHORT; + } else if (c.equals(Integer.class)) { + return METHOD_NAME_ASINT; + } else if (c.equals(Float.class)) { + return METHOD_NAME_ASFLOAT; + } else if (c.equals(Long.class)) { + return METHOD_NAME_ASLONG; + } else if (c.equals(Double.class)) { + return METHOD_NAME_ASDOUBLE; + } else if (c.equals(String.class)) { + return METHOD_NAME_ASSTRING; + } else if (c.equals(byte[].class)) { + return METHOD_NAME_ASBYTEARRAY; + } else if (c.equals(BigInteger.class)) { + return METHOD_NAME_ASBIGINTEGER; + } else if (List.class.isAssignableFrom(c)) { + return METHOD_NAME_ASLIST; + } else if (Map.class.isAssignableFrom(c)) { + return METHOD_NAME_ASMAP; + } else { + throw new DynamicCodeGenException("Type error: " + c.getName()); + } + } +} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java new file mode 100644 index 00000000..1877ed50 --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java @@ -0,0 +1,12 @@ +package org.msgpack.util.codegen; + +public class DynamicCodeGenException extends RuntimeException { + + public DynamicCodeGenException(String reason) { + super(reason); + } + + public DynamicCodeGenException(String reason, Throwable t) { + super(reason, t); + } +} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java new file mode 100644 index 00000000..2a014b8f --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java @@ -0,0 +1,18 @@ +package org.msgpack.util.codegen; + +import org.msgpack.MessagePacker; + +public class DynamicCodeGenPacker { + + public static MessagePacker create(Class c) { + try { + DynamicCodeGen gen = DynamicCodeGen.getInstance(); + Class packerClass = gen.generateMessagePackerClass(c); + return (MessagePacker)packerClass.newInstance(); + } catch (InstantiationException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } + } +} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java new file mode 100644 index 00000000..1e12f2ed --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java @@ -0,0 +1,17 @@ +package org.msgpack.util.codegen; + +import org.msgpack.Template; + +public class DynamicCodeGenTemplate { + public static Template create(Class c) { + try { + DynamicCodeGen gen = DynamicCodeGen.getInstance(); + Class tmplClass = gen.generateTemplateClass(c); + return (Template) tmplClass.newInstance(); + } catch (InstantiationException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } + } +} diff --git a/java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java similarity index 88% rename from java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java rename to java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java index a565292d..736c2ed3 100644 --- a/java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java +++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java @@ -1,4 +1,4 @@ -package org.msgpack.util.annotation; +package org.msgpack.util.codegen; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java similarity index 88% rename from java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java rename to java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java index 03e50cf3..a0c956f2 100644 --- a/java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java +++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java @@ -1,4 +1,4 @@ -package org.msgpack.util.annotation; +package org.msgpack.util.codegen; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java similarity index 87% rename from java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java rename to java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java index 77f6e6de..e5aff401 100644 --- a/java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java +++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java @@ -1,4 +1,4 @@ -package org.msgpack.util.annotation; +package org.msgpack.util.codegen; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java similarity index 99% rename from java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java rename to java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java index 0aeb6d87..2062ee40 100644 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java +++ b/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java @@ -1,4 +1,4 @@ -package org.msgpack.util.annotation; +package org.msgpack.util.codegen; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -230,7 +230,7 @@ public class PackUnpackUtil { } private static void throwClassValidationException(Class origClass) { - throw new PackUnpackUtilException( + throw new DynamicCodeGenException( "it must be a public class and have @" + MessagePackUnpackable.class.getName() + ": " + origClass.getName()); @@ -260,7 +260,7 @@ public class PackUnpackUtil { private static void throwConstructoValidationException( Class origClass) { - throw new PackUnpackUtilException( + throw new DynamicCodeGenException( "it must have a public zero-argument constructor: " + origClass.getName()); } @@ -295,7 +295,7 @@ public class PackUnpackUtil { try { checkFieldValidation(field, allFields); allFields.add(field); - } catch (PackUnpackUtilException e) { // ignore + } catch (DynamicCodeGenException e) { // ignore } } nextClass = nextClass.getSuperclass(); @@ -320,7 +320,7 @@ public class PackUnpackUtil { } private static void throwFieldValidationException(Field field) { - throw new PackUnpackUtilException("it must be a public field: " + throw new DynamicCodeGenException("it must be a public field: " + field.getName()); } @@ -1267,9 +1267,9 @@ public class PackUnpackUtil { try { enhClass = enhancer.generate(origClass, packUnpackable); } catch (NotFoundException e) { - throw new PackUnpackUtilException(e.getMessage(), e); + throw new DynamicCodeGenException(e.getMessage(), e); } catch (CannotCompileException e) { - throw new PackUnpackUtilException(e.getMessage(), e); + throw new DynamicCodeGenException(e.getMessage(), e); } // set the generated class to the cache enhancer.setCache(origName, enhClass); @@ -1306,9 +1306,9 @@ public class PackUnpackUtil { // create a new object of the generated class return enhClass.newInstance(); } catch (InstantiationException e) { - throw new PackUnpackUtilException(e.getMessage(), e); + throw new DynamicCodeGenException(e.getMessage(), e); } catch (IllegalAccessException e) { - throw new PackUnpackUtilException(e.getMessage(), e); + throw new DynamicCodeGenException(e.getMessage(), e); } } diff --git a/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java b/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java new file mode 100644 index 00000000..d4e9c166 --- /dev/null +++ b/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java @@ -0,0 +1,51 @@ +package org.msgpack.util.codegen; + +import static org.msgpack.Templates.tString; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +import org.junit.Test; +import org.msgpack.MessagePacker; +import org.msgpack.Packer; +import org.msgpack.ReflectionPacker; +import org.msgpack.ReflectionTemplate; +import org.msgpack.Template; +import org.msgpack.Unpacker; + +import junit.framework.TestCase; + + +public class TestDynamicCodeGenPacker extends TestCase { + public static class StringFieldClass { + public String s1; + public String s2; + public StringFieldClass() { } + } + + @Test + public void testPackConvert() throws Exception { + tString(); // FIXME link StringTemplate + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MessagePacker packer = DynamicCodeGenPacker.create(StringFieldClass.class); + + StringFieldClass src = new StringFieldClass(); + + src.s1 = "kumofs"; + src.s2 = "frsyuki"; + + packer.pack(new Packer(out), 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); + } +} diff --git a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java b/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java similarity index 96% rename from java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java rename to java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java index 08c4fa82..7e0baccd 100644 --- a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java +++ b/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java @@ -1,4 +1,4 @@ -package org.msgpack.util.annotation; +package org.msgpack.util.codegen; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -16,6 +16,9 @@ import org.msgpack.MessagePackObject; import org.msgpack.MessageUnpackable; import org.msgpack.Packer; import org.msgpack.Unpacker; +import org.msgpack.util.codegen.MessagePackUnpackable; +import org.msgpack.util.codegen.PackUnpackUtil; +import org.msgpack.util.codegen.DynamicCodeGenException; public class TestMessagePackUnpackable extends TestCase { @@ -350,7 +353,7 @@ public class TestMessagePackUnpackable extends TestCase { try { PackUnpackUtil.newEnhancedInstance(NoDefaultConstructorClass.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); @@ -358,7 +361,7 @@ public class TestMessagePackUnpackable extends TestCase { PackUnpackUtil .newEnhancedInstance(PrivateDefaultConstructorClass.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); @@ -366,7 +369,7 @@ public class TestMessagePackUnpackable extends TestCase { PackUnpackUtil .newEnhancedInstance(ProtectedDefaultConstructorClass.class); assertTrue(true); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { fail(); } assertTrue(true); @@ -374,7 +377,7 @@ public class TestMessagePackUnpackable extends TestCase { PackUnpackUtil .newEnhancedInstance(PackageDefaultConstructorClass.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); @@ -409,21 +412,21 @@ public class TestMessagePackUnpackable extends TestCase { try { PackUnpackUtil.newEnhancedInstance(PrivateModifierClass.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); try { PackUnpackUtil.newEnhancedInstance(ProtectedModifierClass.class); assertTrue(true); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { fail(); } assertTrue(true); try { PackUnpackUtil.newEnhancedInstance(PackageModifierClass.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); @@ -448,14 +451,14 @@ public class TestMessagePackUnpackable extends TestCase { try { PackUnpackUtil.newEnhancedInstance(FinalModifierClass.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); try { PackUnpackUtil.newEnhancedInstance(AbstractModifierClass.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); @@ -474,14 +477,14 @@ public class TestMessagePackUnpackable extends TestCase { try { PackUnpackUtil.newEnhancedInstance(SampleInterface.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); try { PackUnpackUtil.newEnhancedInstance(SampleEnum.class); fail(); - } catch (PackUnpackUtilException e) { + } catch (DynamicCodeGenException e) { assertTrue(true); } assertTrue(true); From bffe0443f9e20fb9bf55e58ab95510ed19e74ab7 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Tue, 28 Sep 2010 12:17:32 +0900 Subject: [PATCH 7/9] edit DynamicCodeGenPacker and DynamicCodeGenUnpacker class --- .../java/org/msgpack/MessageUnpacker.java | 2 +- java/src/main/java/org/msgpack/Packer.java | 1 - java/src/main/java/org/msgpack/Unpacker.java | 1 - .../msgpack/util/codegen/BasicConstants.java | 50 ++- .../org/msgpack/util/codegen/Constants.java | 6 +- .../msgpack/util/codegen/DynamicCodeGen.java | 396 +++++++++++++++-- .../util/codegen/DynamicCodeGenBase.java | 406 ++++++++++-------- .../util/codegen/DynamicCodeGenUnpacker.java | 17 + .../codegen/TestDynamicCodeGenPacker.java | 50 ++- 9 files changed, 674 insertions(+), 255 deletions(-) create mode 100644 java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenUnpacker.java diff --git a/java/src/main/java/org/msgpack/MessageUnpacker.java b/java/src/main/java/org/msgpack/MessageUnpacker.java index 18172697..2a89e457 100644 --- a/java/src/main/java/org/msgpack/MessageUnpacker.java +++ b/java/src/main/java/org/msgpack/MessageUnpacker.java @@ -20,6 +20,6 @@ package org.msgpack; import java.io.IOException; public interface MessageUnpacker { - public Object unpack(Unpacker pac) throws IOException, MessageTypeException; + Object unpack(Unpacker pac) throws IOException, MessageTypeException; } diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index 9ea4ea21..52bd29de 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -22,7 +22,6 @@ 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; diff --git a/java/src/main/java/org/msgpack/Unpacker.java b/java/src/main/java/org/msgpack/Unpacker.java index 33c7d4ce..d91fc0ef 100644 --- a/java/src/main/java/org/msgpack/Unpacker.java +++ b/java/src/main/java/org/msgpack/Unpacker.java @@ -18,7 +18,6 @@ package org.msgpack; import java.lang.Iterable; -import java.lang.annotation.Annotation; import java.io.InputStream; import java.io.IOException; import java.util.Iterator; diff --git a/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java index 53a8a4ce..f675f815 100644 --- a/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java +++ b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java @@ -2,29 +2,31 @@ package org.msgpack.util.codegen; public interface BasicConstants { - String KEYWORD_MODIFIER_PUBLIC = "public"; + String KEYWORD_MODIFIER_PUBLIC = "public"; - String KEYWORD_CATCH = "catch"; + String KEYWORD_CATCH = "catch"; - String KEYWORD_ELSE = "else"; + String KEYWORD_ELSE = "else"; - String KEYWORD_ELSEIF = "else if"; + String KEYWORD_ELSEIF = "else if"; - String KEYWORD_FOR = "for"; + String KEYWORD_FOR = "for"; - String KEYWORD_IF = "if"; + String KEYWORD_IF = "if"; - String KEYWORD_INSTANCEOF = "instanceof"; + String KEYWORD_INSTANCEOF = "instanceof"; - String KEYWORD_NEW = "new"; + String KEYWORD_NEW = "new"; - String KEYWORD_NULL = "null"; + String KEYWORD_NULL = "null"; + + String KEYWORD_RETURN = "return"; - String KEYWORD_THROW = "throw"; + String KEYWORD_THROW = "throw"; - String KEYWORD_THROWS = "throws"; + String KEYWORD_THROWS = "throws"; - String KEYWORD_TRY = "try"; + String KEYWORD_TRY = "try"; String CHAR_NAME_SPACE = " "; @@ -34,28 +36,30 @@ public interface BasicConstants { String CHAR_NAME_PLUS = "+"; + String CHAR_NAME_MINUS = "-"; + String CHAR_NAME_LESSTHAN = "<"; - String CHAR_NAME_RIGHT_PARENTHESIS = ")"; + String CHAR_NAME_RIGHT_PARENTHESIS = ")"; - String CHAR_NAME_LEFT_PARENTHESIS = "("; + String CHAR_NAME_LEFT_PARENTHESIS = "("; - String CHAR_NAME_RIGHT_CURLY_BRACKET = "}"; + String CHAR_NAME_RIGHT_CURLY_BRACKET = "}"; - String CHAR_NAME_LEFT_CURLY_BRACKET = "{"; + String CHAR_NAME_LEFT_CURLY_BRACKET = "{"; - String CHAR_NAME_RIGHT_SQUARE_BRACKET = "]"; + String CHAR_NAME_RIGHT_SQUARE_BRACKET = "]"; - String CHAR_NAME_LEFT_SQUARE_BRACKET = "["; + String CHAR_NAME_LEFT_SQUARE_BRACKET = "["; String CHAR_NAME_DOT = "."; String CHAR_NAME_SEMICOLON = ";"; String VARIABLE_NAME_PK = "_$$_pk"; - - String VARIABLE_NAME_OBJ = "_$$_obj"; - + + String VARIABLE_NAME_OBJECT = "_$$_obj"; + String VARIABLE_NAME_TARGET = "_$$_target"; String VARIABLE_NAME_SIZE = "_$$_len"; @@ -153,8 +157,8 @@ public interface BasicConstants { String METHOD_NAME_ASBYTEARRAY = "asByteArray"; String METHOD_NAME_ASBIGINTEGER = "asBigInteger"; - + String METHOD_NAME_ASLIST = "asList"; - + String METHOD_NAME_ASMAP = "asMap"; } diff --git a/java/src/main/java/org/msgpack/util/codegen/Constants.java b/java/src/main/java/org/msgpack/util/codegen/Constants.java index ddeef31f..22265946 100644 --- a/java/src/main/java/org/msgpack/util/codegen/Constants.java +++ b/java/src/main/java/org/msgpack/util/codegen/Constants.java @@ -2,6 +2,8 @@ package org.msgpack.util.codegen; public interface Constants extends BasicConstants { String POSTFIX_TYPE_NAME_PACKER = "_$$_Packer"; - - String POSTFIX_TYPE_NAME_ENHANCER = "_$$_Enhanced"; + + String POSTFIX_TYPE_NAME_UNPACKER = "_$$_Unpacker"; + + String POSTFIX_TYPE_NAME_TEMPLATE = "_$$_Template"; } diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java index 9f63242d..bd010eac 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java @@ -4,8 +4,12 @@ import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.math.BigInteger; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import javassist.CannotCompileException; @@ -17,15 +21,24 @@ import javassist.CtNewConstructor; import javassist.CtNewMethod; import javassist.NotFoundException; +import org.msgpack.MessagePackObject; import org.msgpack.MessagePacker; +import org.msgpack.MessageTypeException; +import org.msgpack.MessageUnpackable; +import org.msgpack.MessageUnpacker; import org.msgpack.Packer; import org.msgpack.Template; +import org.msgpack.Unpacker; public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { private static DynamicCodeGen INSTANCE; - private static AtomicInteger COUNTER; + private static AtomicInteger COUNTER = new AtomicInteger(0); + + private static int inc() { + return COUNTER.addAndGet(1); + } public static DynamicCodeGen getInstance() { if (INSTANCE == null) { @@ -43,7 +56,7 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { public Class generateMessagePackerClass(Class origClass) { try { String origName = origClass.getName(); - String packerName = origName + POSTFIX_TYPE_NAME_PACKER; + String packerName = origName + POSTFIX_TYPE_NAME_PACKER + inc(); checkClassValidation(origClass); checkDefaultConstructorValidation(origClass); CtClass packerCtClass = pool.makeClass(packerName); @@ -59,18 +72,38 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { } } + public Class generateMessageUnpackerClass(Class origClass) { + try { + String origName = origClass.getName(); + String unpackerName = origName + POSTFIX_TYPE_NAME_UNPACKER + inc(); + checkClassValidation(origClass); + checkDefaultConstructorValidation(origClass); + CtClass unpackerCtClass = pool.makeClass(unpackerName); + setInterface(unpackerCtClass, MessageUnpacker.class); + addDefaultConstructor(unpackerCtClass); + Field[] fields = getDeclaredFields(origClass); + addUnpackMethod(unpackerCtClass, origClass, fields); + return createClass(unpackerCtClass); + } catch (NotFoundException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } catch (CannotCompileException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } + } + public Class generateTemplateClass(Class origClass) { try { String origName = origClass.getName(); - String packerName = origName + POSTFIX_TYPE_NAME_PACKER; + String tmplName = origName + POSTFIX_TYPE_NAME_TEMPLATE + inc(); checkClassValidation(origClass); checkDefaultConstructorValidation(origClass); - CtClass packerCtClass = pool.makeClass(packerName); - setInterface(packerCtClass, Template.class); - addDefaultConstructor(packerCtClass); + CtClass tmplCtClass = pool.makeClass(tmplName); + setInterface(tmplCtClass, Template.class); + addDefaultConstructor(tmplCtClass); Field[] fields = getDeclaredFields(origClass); - addPackMethod(packerCtClass, origClass, fields); - return createClass(packerCtClass); + addUnpackMethod(tmplCtClass, origClass, fields); + addConvertMethod(tmplCtClass, origClass, fields); + return createClass(tmplCtClass); } catch (NotFoundException e) { throw new DynamicCodeGenException(e.getMessage(), e); } catch (CannotCompileException e) { @@ -172,31 +205,13 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { private void addPackMethod(CtClass packerCtClass, Class c, Field[] fs) throws CannotCompileException, NotFoundException { StringBuilder sb = new StringBuilder(); - sb.append(KEYWORD_MODIFIER_PUBLIC); - sb.append(CHAR_NAME_SPACE); - sb.append(void.class.getName()); - sb.append(CHAR_NAME_SPACE); - sb.append(METHOD_NAME_PACK); - sb.append(CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Packer.class.getName()); - sb.append(CHAR_NAME_SPACE); - sb.append(VARIABLE_NAME_PK); - sb.append(CHAR_NAME_COMMA); - sb.append(CHAR_NAME_SPACE); - sb.append(Object.class.getName()); - sb.append(CHAR_NAME_SPACE); - sb.append(VARIABLE_NAME_OBJ); - sb.append(CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(CHAR_NAME_SPACE); - sb.append(KEYWORD_THROWS); - sb.append(CHAR_NAME_SPACE); - sb.append(IOException.class.getName()); - sb.append(CHAR_NAME_SPACE); - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - insertPackMethodBody(sb, c, fs); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - // System.out.println("pack method: " + sb.toString()); + StringBuilder bsb = new StringBuilder(); + insertPackMethodBody(bsb, c, fs); + addPublicMethodDecl(sb, METHOD_NAME_PACK, void.class, new Class[] { + Packer.class, Object.class }, new String[] { VARIABLE_NAME_PK, + VARIABLE_NAME_OBJECT }, new Class[] { IOException.class }, bsb + .toString()); + System.out.println("pack method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), packerCtClass); packerCtClass.addMethod(newCtMethod); } @@ -204,7 +219,7 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { private void insertPackMethodBody(StringBuilder sb, Class c, Field[] fs) { insertLocalVariableDecl(sb, c, VARIABLE_NAME_TARGET); StringBuilder mc = new StringBuilder(); - insertTypeCast(mc, c, VARIABLE_NAME_OBJ); + insertTypeCast(mc, c, VARIABLE_NAME_OBJECT); insertValueInsertion(sb, mc.toString()); insertSemicolon(sb); insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACKARRAY, @@ -225,6 +240,319 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { insertSemicolon(sb); } + private void addUnpackMethod(CtClass unpackerCtClass, Class c, Field[] fs) + throws CannotCompileException, NotFoundException { + // Object unpack(Unpacker pac) throws IOException, MessageTypeException; + StringBuilder sb = new StringBuilder(); + StringBuilder bsb = new StringBuilder(); + insertUnpackMethodBody(bsb, c, fs); + addPublicMethodDecl(sb, METHOD_NAME_UNPACK, Object.class, + new Class[] { Unpacker.class }, + new String[] { VARIABLE_NAME_PK }, new Class[] { + MessageTypeException.class, IOException.class }, bsb + .toString()); + System.out.println("unpack method: " + sb.toString()); + CtMethod newCtMethod = CtNewMethod.make(sb.toString(), unpackerCtClass); + unpackerCtClass.addMethod(newCtMethod); + } + + private void insertUnpackMethodBody(StringBuilder sb, Class c, Field[] fs) { + insertLocalVariableDecl(sb, c, VARIABLE_NAME_TARGET); + StringBuilder mc = new StringBuilder(); + insertDefaultConsCall(mc, c); + insertValueInsertion(sb, mc.toString()); + insertSemicolon(sb); + insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_UNPACKARRAY, + new String[0]); + insertSemicolon(sb); + for (Field f : fs) { + insertCodeOfUnpackMethodCall(sb, f, f.getType()); + } + insertReturnStat(sb, VARIABLE_NAME_TARGET); + insertSemicolon(sb); + } + + private void insertCodeOfUnpackMethodCall(StringBuilder sb, Field f, + Class c) { + if (c.isPrimitive()) { + // primitive type + insertCodeOfUnpackMethodCallForPrimTypes(sb, f, c); + } else if (c.equals(Boolean.class) || // Boolean + c.equals(Byte.class) || // Byte + c.equals(Double.class) || // Double + c.equals(Float.class) || // Float + c.equals(Integer.class) || // Integer + c.equals(Long.class) || // Long + c.equals(Short.class)) { // Short + // reference type (wrapper type) + insertCodeOfUnpackMethodCallForWrapTypes(sb, f, c); + } else if (c.equals(BigInteger.class) || // BigInteger + c.equals(String.class) || // String + c.equals(byte[].class)) { // byte[] + // reference type (other type) + insertCodeOfUnpackMethodCallForPrimTypes(sb, f, c); + } else if (List.class.isAssignableFrom(c)) { + // List + insertCodeOfUnpackMethodCallForListType(sb, f, c); + } else if (Map.class.isAssignableFrom(c)) { + // Map + insertCodeOfUnpackMethodCallForMapType(sb, f, c); + } else if (MessageUnpackable.class.isAssignableFrom(c)) { + // MessageUnpackable + insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, f, c); + } else { + throw new MessageTypeException("unknown type: " + c.getName()); + } + } + + private void insertCodeOfUnpackMethodCallForPrimTypes(StringBuilder sb, + Field f, Class c) { + if (f != null) { + sb.append(VARIABLE_NAME_TARGET); + sb.append(CHAR_NAME_DOT); + sb.append(f.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + } + insertMethodCall(sb, VARIABLE_NAME_PK, getUnpackMethodName(c), + new String[0]); + if (f != null) { + insertSemicolon(sb); + } + } + + private void insertCodeOfUnpackMethodCallForWrapTypes(StringBuilder sb, + Field f, Class c) { + if (f != null) { + sb.append(VARIABLE_NAME_TARGET); + sb.append(f.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + } + StringBuilder mc = new StringBuilder(); + insertMethodCall(mc, VARIABLE_NAME_PK, getUnpackMethodName(c), + new String[0]); + insertMethodCall(sb, c.getName(), METHOD_NAME_VALUEOF, + new String[] { mc.toString() }); + if (f != null) { + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + } + } + + private void insertCodeOfUnpackMethodCallForListType(StringBuilder sb, + Field field, Class type) { + ParameterizedType generic = (ParameterizedType) field.getGenericType(); + Class genericType = (Class) generic.getActualTypeArguments()[0]; + + // len + sb.append(int.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_SIZE); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_PK); + sb.append(CHAR_NAME_DOT); + sb.append(METHOD_NAME_UNPACKARRAY); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + + // field initializer + sb.append(field.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(KEYWORD_NEW); + sb.append(CHAR_NAME_SPACE); + sb.append(ArrayList.class.getName()); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + + // for loop + sb.append(KEYWORD_FOR); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(int.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_I); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(0); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_I); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LESSTHAN); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_SIZE); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_PLUS); + sb.append(CHAR_NAME_PLUS); + sb.append(VARIABLE_NAME_I); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + + // block + sb.append(field.getName()); + sb.append(CHAR_NAME_DOT); + sb.append(METHOD_NAME_ADD); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + insertCodeOfUnpackMethodCall(sb, null, genericType); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + } + + private void insertCodeOfUnpackMethodCallForMapType(StringBuilder sb, + Field field, Class type) { + ParameterizedType generic = (ParameterizedType) field.getGenericType(); + Class genericType0 = (Class) generic.getActualTypeArguments()[0]; + Class genericType1 = (Class) generic.getActualTypeArguments()[1]; + + // len + sb.append(int.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_SIZE); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_PK); + sb.append(CHAR_NAME_DOT); + sb.append(METHOD_NAME_UNPACKMAP); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + + // field initializer + sb.append(field.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(KEYWORD_NEW); + sb.append(CHAR_NAME_SPACE); + sb.append(HashMap.class.getName()); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + + // for loop + sb.append(KEYWORD_FOR); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(int.class.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_I); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(0); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_I); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LESSTHAN); + sb.append(CHAR_NAME_SPACE); + sb.append(VARIABLE_NAME_SIZE); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_PLUS); + sb.append(CHAR_NAME_PLUS); + sb.append(VARIABLE_NAME_I); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + + // block map. + sb.append(field.getName()); + sb.append(CHAR_NAME_DOT); + sb.append(METHOD_NAME_PUT); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + insertCodeOfUnpackMethodCall(sb, null, genericType0); + sb.append(CHAR_NAME_COMMA); + sb.append(CHAR_NAME_SPACE); + insertCodeOfUnpackMethodCall(sb, null, genericType1); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + } + + // private void insertCodeOfMessageUnpackCallForEnhancedType(StringBuilder + // sb, + // Field f, Class c) { + // c = this.getCache(c.getName()); + // insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, f, c); + // } + + private void insertCodeOfMessageUnpackCallForMsgUnpackableType( + StringBuilder sb, Field f, Class c) { + // if (fi == null) { fi = new Foo_$$_Enhanced(); } + sb.append(KEYWORD_IF); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(f.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(KEYWORD_NULL); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + sb.append(f.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(KEYWORD_NEW); + sb.append(CHAR_NAME_SPACE); + sb.append(c.getName()); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + + // insert a right variable // ignore + sb.append(VARIABLE_NAME_PK); + sb.append(CHAR_NAME_DOT); + sb.append(METHOD_NAME_UNPACK); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessageUnpackable.class.getName()); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(f.getName()); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + } + + private void addConvertMethod(CtClass tmplCtClass, Class c, Field[] fs) + throws CannotCompileException, NotFoundException { + // Object convert(MessagePackObject from) throws MessageTypeException; + // FIXME + } + private Class createClass(CtClass packerCtClass) throws CannotCompileException { return packerCtClass.toClass(null, null); diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java index 24ae579a..1c907a23 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java @@ -5,185 +5,245 @@ import java.util.List; import java.util.Map; public class DynamicCodeGenBase implements BasicConstants { - public DynamicCodeGenBase() { - } + public DynamicCodeGenBase() { + } - public void insertSemicolon(StringBuilder sb) { - sb.append(CHAR_NAME_SEMICOLON); - sb.append(CHAR_NAME_SPACE); - } + public void addPublicFieldDecl(StringBuilder sb, Class type, String name) { + sb.append(KEYWORD_MODIFIER_PUBLIC); + sb.append(CHAR_NAME_SPACE); + sb.append(type.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(name); + } + + public void addPublicMethodDecl(StringBuilder sb, String mname, + Class returnType, Class[] paramTypes, String[] anames, + Class[] exceptTypes, String methodBody) { + sb.append(KEYWORD_MODIFIER_PUBLIC); + sb.append(CHAR_NAME_SPACE); + sb.append(returnType.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(mname); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + for (int i = 0; i < paramTypes.length; ++i) { + sb.append(paramTypes[i].getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(anames[i]); + if (i + 1 != paramTypes.length) { + sb.append(CHAR_NAME_COMMA); + sb.append(CHAR_NAME_SPACE); + } + } + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SPACE); + sb.append(KEYWORD_THROWS); + sb.append(CHAR_NAME_SPACE); + for (int i = 0; i < exceptTypes.length; ++i) { + sb.append(exceptTypes[i].getName()); + if (i + 1 != exceptTypes.length) { + sb.append(CHAR_NAME_COMMA); + sb.append(CHAR_NAME_SPACE); + } + } + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + sb.append(methodBody); + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + } - public void insertPublicFieldDecl(StringBuilder sb, Class type, - String name) { - sb.append(KEYWORD_MODIFIER_PUBLIC); - sb.append(CHAR_NAME_SPACE); - sb.append(type.getName()); - sb.append(CHAR_NAME_SPACE); - sb.append(name); - } + public void insertSemicolon(StringBuilder sb) { + sb.append(CHAR_NAME_SEMICOLON); + sb.append(CHAR_NAME_SPACE); + } - public void insertLocalVariableDecl(StringBuilder sb, Class type, - String name) { - sb.append(type.getName()); - sb.append(CHAR_NAME_SPACE); - sb.append(name); - } - - public void insertValueInsertion(StringBuilder sb, String expr) { - // = expr - sb.append(CHAR_NAME_SPACE); - sb.append(CHAR_NAME_EQUAL); - sb.append(CHAR_NAME_SPACE); - sb.append(expr); - } + public void insertLocalVariableDecl(StringBuilder sb, Class type, + String name) { + sb.append(type.getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(name); + } - public void insertDefaultConsCall(StringBuilder sb, Class type) { - // new tname() - insertConsCall(sb, type, null); - } + public void insertValueInsertion(StringBuilder sb, String expr) { + // = expr + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_EQUAL); + sb.append(CHAR_NAME_SPACE); + sb.append(expr); + } - public void insertConsCall(StringBuilder sb, Class type, String expr) { - // new tname(expr) - sb.append(KEYWORD_NEW); - sb.append(CHAR_NAME_SPACE); - sb.append(type.getName()); - sb.append(CHAR_NAME_LEFT_PARENTHESIS); - if (expr != null) { - sb.append(expr); - } - sb.append(CHAR_NAME_RIGHT_PARENTHESIS); - } + public void insertDefaultConsCall(StringBuilder sb, Class type) { + // new tname() + insertConsCall(sb, type, null); + } - public void insertMethodCall(StringBuilder sb, String tname, String mname, - String[] anames) { - // tname.mname(anames[0], anames[1], ...) - int len = anames.length; - sb.append(tname); - sb.append(CHAR_NAME_DOT); - sb.append(mname); - sb.append(CHAR_NAME_LEFT_PARENTHESIS); - for (int i = 0; i < len; ++i) { - sb.append(anames[i]); - if (i + 1 != len) { - sb.append(CHAR_NAME_COMMA); - sb.append(CHAR_NAME_SPACE); - } - } - sb.append(CHAR_NAME_RIGHT_PARENTHESIS); - } - - public void insertTypeCast(StringBuilder sb, Class type) { - // (type) - sb.append(CHAR_NAME_LEFT_PARENTHESIS); - sb.append(type.getName()); - sb.append(CHAR_NAME_RIGHT_PARENTHESIS); - } - - public void insertTypeCast(StringBuilder sb, Class type, String varName) { - // ((type)var) - sb.append(CHAR_NAME_LEFT_PARENTHESIS); - sb.append(CHAR_NAME_LEFT_PARENTHESIS); - sb.append(type.getName()); - sb.append(CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(varName); - sb.append(CHAR_NAME_RIGHT_PARENTHESIS); - } - - public void insertTypeConvToObjectType(StringBuilder sb, Class type, - String expr) throws DynamicCodeGenException { - if (type.isPrimitive()) { // primitive type - if (type.equals(boolean.class)) { - // new Boolean(expr) - insertConsCall(sb, Boolean.class, expr); - } else if (type.equals(byte.class)) { - insertConsCall(sb, Byte.class, expr); - } else if (type.equals(short.class)) { - insertConsCall(sb, Short.class, expr); - } else if (type.equals(int.class)) { - insertConsCall(sb, Integer.class, expr); - } else if (type.equals(long.class)) { - insertConsCall(sb, Long.class, expr); - } else if (type.equals(float.class)) { - insertConsCall(sb, Float.class, expr); - } else if (type.equals(double.class)) { - insertConsCall(sb, Double.class, expr); - } else { - throw new DynamicCodeGenException("Type error: " - + type.getName()); - } - } else { // reference type - sb.append(expr); - } - } + public void insertConsCall(StringBuilder sb, Class type, String expr) { + // new tname(expr) + sb.append(KEYWORD_NEW); + sb.append(CHAR_NAME_SPACE); + sb.append(type.getName()); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + if (expr != null) { + sb.append(expr); + } + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } - public void insertTryCatchBlocks(StringBuilder sb, String tryBody, - List> types, List names, List catchBodies) { - int len = types.size(); - sb.append(KEYWORD_TRY); - sb.append(CHAR_NAME_SPACE); - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - sb.append(tryBody); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - for (int i = 0; i < len; ++i) { - sb.append(KEYWORD_CATCH); - sb.append(CHAR_NAME_SPACE); - sb.append(CHAR_NAME_LEFT_PARENTHESIS); - sb.append(types.get(i).getName()); - sb.append(CHAR_NAME_SPACE); - sb.append(names.get(i)); - sb.append(CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(CHAR_NAME_SPACE); - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - sb.append(catchBodies.get(i)); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - } - } + public void insertMethodCall(StringBuilder sb, String tname, String mname, + String[] anames) { + // tname.mname(anames[0], anames[1], ...) + int len = anames.length; + sb.append(tname); + sb.append(CHAR_NAME_DOT); + sb.append(mname); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + for (int i = 0; i < len; ++i) { + sb.append(anames[i]); + if (i + 1 != len) { + sb.append(CHAR_NAME_COMMA); + sb.append(CHAR_NAME_SPACE); + } + } + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } - public String getAsMethod(Class c) throws DynamicCodeGenException { - if (c.equals(boolean.class)) { - return METHOD_NAME_ASBOOLEAN; - } else if (c.equals(byte.class)) { - return METHOD_NAME_ASBYTE; - } else if (c.equals(short.class)) { - return METHOD_NAME_ASSHORT; - } else if (c.equals(int.class)) { - return METHOD_NAME_ASINT; - } else if (c.equals(float.class)) { - return METHOD_NAME_ASFLOAT; - } else if (c.equals(long.class)) { - return METHOD_NAME_ASLONG; - } else if (c.equals(double.class)) { - return METHOD_NAME_ASDOUBLE; - } else if (c.equals(Boolean.class)) { - return METHOD_NAME_ASBOOLEAN; - } else if (c.equals(Byte.class)) { - return METHOD_NAME_ASBYTE; - } else if (c.equals(Short.class)) { - return METHOD_NAME_ASSHORT; - } else if (c.equals(Integer.class)) { - return METHOD_NAME_ASINT; - } else if (c.equals(Float.class)) { - return METHOD_NAME_ASFLOAT; - } else if (c.equals(Long.class)) { - return METHOD_NAME_ASLONG; - } else if (c.equals(Double.class)) { - return METHOD_NAME_ASDOUBLE; - } else if (c.equals(String.class)) { - return METHOD_NAME_ASSTRING; - } else if (c.equals(byte[].class)) { - return METHOD_NAME_ASBYTEARRAY; - } else if (c.equals(BigInteger.class)) { - return METHOD_NAME_ASBIGINTEGER; - } else if (List.class.isAssignableFrom(c)) { - return METHOD_NAME_ASLIST; - } else if (Map.class.isAssignableFrom(c)) { - return METHOD_NAME_ASMAP; - } else { - throw new DynamicCodeGenException("Type error: " + c.getName()); - } - } + public void insertTypeCast(StringBuilder sb, Class type) { + // (type) + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(type.getName()); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } + + public void insertTypeCast(StringBuilder sb, Class type, String varName) { + // ((type)var) + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(type.getName()); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(varName); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + } + + public void insertReturnStat(StringBuilder sb, String expr) { + // return expr + sb.append(KEYWORD_RETURN); + sb.append(CHAR_NAME_SPACE); + sb.append(expr); + } + + public void insertTypeConvToObjectType(StringBuilder sb, Class type, + String expr) throws DynamicCodeGenException { + if (type.isPrimitive()) { // primitive type + if (type.equals(boolean.class)) { + // new Boolean(expr) + insertConsCall(sb, Boolean.class, expr); + } else if (type.equals(byte.class)) { + insertConsCall(sb, Byte.class, expr); + } else if (type.equals(short.class)) { + insertConsCall(sb, Short.class, expr); + } else if (type.equals(int.class)) { + insertConsCall(sb, Integer.class, expr); + } else if (type.equals(long.class)) { + insertConsCall(sb, Long.class, expr); + } else if (type.equals(float.class)) { + insertConsCall(sb, Float.class, expr); + } else if (type.equals(double.class)) { + insertConsCall(sb, Double.class, expr); + } else { + throw new DynamicCodeGenException("Type error: " + + type.getName()); + } + } else { // reference type + sb.append(expr); + } + } + + public void insertTryCatchBlocks(StringBuilder sb, String tryBody, + List> types, List names, List catchBodies) { + int len = types.size(); + sb.append(KEYWORD_TRY); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + sb.append(tryBody); + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + for (int i = 0; i < len; ++i) { + sb.append(KEYWORD_CATCH); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_PARENTHESIS); + sb.append(types.get(i).getName()); + sb.append(CHAR_NAME_SPACE); + sb.append(names.get(i)); + sb.append(CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(CHAR_NAME_SPACE); + sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + sb.append(catchBodies.get(i)); + sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(CHAR_NAME_SPACE); + } + } + + public String getUnpackMethodName(Class c) + throws DynamicCodeGenException { + if (c.equals(boolean.class) || c.equals(Boolean.class)) { + return METHOD_NAME_UNPACKBOOLEAN; + } else if (c.equals(byte.class) || c.equals(Byte.class)) { + return METHOD_NAME_UNPACKBYTE; + } else if (c.equals(short.class) || c.equals(Short.class)) { + return METHOD_NAME_UNPACKSHORT; + } else if (c.equals(int.class) || c.equals(Integer.class)) { + return METHOD_NAME_UNPACKINT; + } else if (c.equals(float.class) || c.equals(Float.class)) { + return METHOD_NAME_UNPACKFLOAT; + } else if (c.equals(long.class) || c.equals(Long.class)) { + return METHOD_NAME_UNPACKLONG; + } else if (c.equals(double.class) || c.equals(Double.class)) { + return METHOD_NAME_UNPACKDOUBLE; + } else if (c.equals(String.class)) { + return METHOD_NAME_UNPACKSTRING; + } else if (c.equals(byte[].class)) { + return METHOD_NAME_UNPACKBYTEARRAY; + } else if (c.equals(BigInteger.class)) { + return METHOD_NAME_UNPACKBIGINTEGER; + } else if (List.class.isAssignableFrom(c)) { + return METHOD_NAME_UNPACK; + } else if (Map.class.isAssignableFrom(c)) { + return METHOD_NAME_UNPACK; + } else { + throw new DynamicCodeGenException("Type error: " + c.getName()); + } + } + + public String getAsMethodName(Class c) throws DynamicCodeGenException { + if (c.equals(boolean.class) || c.equals(Boolean.class)) { + return METHOD_NAME_ASBOOLEAN; + } else if (c.equals(byte.class) || c.equals(Byte.class)) { + return METHOD_NAME_ASBYTE; + } else if (c.equals(short.class) || c.equals(Short.class)) { + return METHOD_NAME_ASSHORT; + } else if (c.equals(int.class) || c.equals(Integer.class)) { + return METHOD_NAME_ASINT; + } else if (c.equals(float.class) || c.equals(Float.class)) { + return METHOD_NAME_ASFLOAT; + } else if (c.equals(long.class) || c.equals(Long.class)) { + return METHOD_NAME_ASLONG; + } else if (c.equals(double.class) || c.equals(Double.class)) { + return METHOD_NAME_ASDOUBLE; + } else if (c.equals(String.class)) { + return METHOD_NAME_ASSTRING; + } else if (c.equals(byte[].class)) { + return METHOD_NAME_ASBYTEARRAY; + } else if (c.equals(BigInteger.class)) { + return METHOD_NAME_ASBIGINTEGER; + } else if (List.class.isAssignableFrom(c)) { + return METHOD_NAME_ASLIST; + } else if (Map.class.isAssignableFrom(c)) { + return METHOD_NAME_ASMAP; + } else { + throw new DynamicCodeGenException("Type error: " + c.getName()); + } + } } diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenUnpacker.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenUnpacker.java new file mode 100644 index 00000000..e4fe76bd --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenUnpacker.java @@ -0,0 +1,17 @@ +package org.msgpack.util.codegen; + +import org.msgpack.MessageUnpacker; + +public class DynamicCodeGenUnpacker { + public static MessageUnpacker create(Class c) { + try { + DynamicCodeGen gen = DynamicCodeGen.getInstance(); + Class unpackerClass = gen.generateMessageUnpackerClass(c); + return (MessageUnpacker) unpackerClass.newInstance(); + } catch (InstantiationException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new DynamicCodeGenException(e.getMessage(), e); + } + } +} diff --git a/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java b/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java index d4e9c166..88515378 100644 --- a/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java +++ b/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java @@ -1,50 +1,60 @@ package org.msgpack.util.codegen; -import static org.msgpack.Templates.tString; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.junit.Test; import org.msgpack.MessagePacker; +import org.msgpack.MessageUnpacker; import org.msgpack.Packer; -import org.msgpack.ReflectionPacker; -import org.msgpack.ReflectionTemplate; import org.msgpack.Template; import org.msgpack.Unpacker; import junit.framework.TestCase; - public class TestDynamicCodeGenPacker extends TestCase { public static class StringFieldClass { public String s1; public String s2; - public StringFieldClass() { } + + public StringFieldClass() { + } } @Test - public void testPackConvert() throws Exception { - tString(); // FIXME link StringTemplate - + public void testPackConvert01() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicCodeGenPacker.create(StringFieldClass.class); + MessagePacker packer = DynamicCodeGenPacker + .create(StringFieldClass.class); + MessageUnpacker unpacker = DynamicCodeGenUnpacker + .create(StringFieldClass.class); StringFieldClass src = new StringFieldClass(); - - src.s1 = "kumofs"; - src.s2 = "frsyuki"; - + src.s1 = "muga"; + src.s2 = "nishizawa"; packer.pack(new Packer(out), src); - Template tmpl = ReflectionTemplate.create(StringFieldClass.class); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + StringFieldClass dst = (StringFieldClass) new Unpacker(in) + .unpack(unpacker); + assertEquals(src.s1, dst.s1); + assertEquals(src.s2, dst.s2); + } + + @Test + public void testPackConvert02() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MessagePacker packer = DynamicCodeGenPacker + .create(StringFieldClass.class); + Template tmpl = DynamicCodeGenTemplate.create(StringFieldClass.class); + + StringFieldClass src = new StringFieldClass(); + src.s1 = "muga"; + src.s2 = "nishizawa"; + packer.pack(new Packer(out), src); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - - Object obj = tmpl.unpack(new Unpacker(in)); - assertEquals(obj.getClass(), StringFieldClass.class); - - StringFieldClass dst = (StringFieldClass)obj; + StringFieldClass dst = (StringFieldClass) tmpl.unpack(new Unpacker(in)); assertEquals(src.s1, dst.s1); assertEquals(src.s2, dst.s2); } From 190af1d32b0ddec84525e9e0a6d90b19c6b72768 Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Tue, 28 Sep 2010 15:24:47 +0900 Subject: [PATCH 8/9] delete old programs: org.msgpack.util.codegen.MessagePackOptional, MessagePackRequired, MessagePackUnpackable, and PackUnpackUtil classes --- .../util/codegen/MessagePackOptional.java | 12 - .../util/codegen/MessagePackRequired.java | 12 - .../util/codegen/MessagePackUnpackable.java | 11 - .../msgpack/util/codegen/PackUnpackUtil.java | 1372 ----------------- 4 files changed, 1407 deletions(-) delete mode 100644 java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java delete mode 100644 java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java delete mode 100644 java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java delete mode 100644 java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java diff --git a/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java deleted file mode 100644 index 736c2ed3..00000000 --- a/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.msgpack.util.codegen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.CLASS) -public @interface MessagePackOptional { - int value() default -1; -} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java deleted file mode 100644 index a0c956f2..00000000 --- a/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.msgpack.util.codegen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.CLASS) -public @interface MessagePackRequired { - int value() default -1; -} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java deleted file mode 100644 index e5aff401..00000000 --- a/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.msgpack.util.codegen; - -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 MessagePackUnpackable { -} diff --git a/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java deleted file mode 100644 index 2062ee40..00000000 --- a/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java +++ /dev/null @@ -1,1372 +0,0 @@ -package org.msgpack.util.codegen; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javassist.CannotCompileException; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtConstructor; -import javassist.CtMethod; -import javassist.CtNewConstructor; -import javassist.CtNewMethod; -import javassist.NotFoundException; - -import org.msgpack.MessageConvertable; -import org.msgpack.MessagePackObject; -import org.msgpack.MessagePackable; -import org.msgpack.MessageTypeException; -import org.msgpack.MessageUnpackable; -import org.msgpack.Packer; -import org.msgpack.Unpacker; - -public class PackUnpackUtil { - static class Constants { - static final String POSTFIX_TYPE_NAME_ENHANCER = "_$$_Enhanced"; - - static final String KEYWORD_MODIFIER_PUBLIC = "public"; - - static final String KEYWORD_FOR = "for"; - - static final String KEYWORD_IF = "if"; - - static final String KEYWORD_THROWS = "throws"; - - static final String KEYWORD_NEW = "new"; - - static final String KEYWORD_NULL = "null"; - - static final String CHAR_NAME_SPACE = " "; - - static final String CHAR_NAME_COMMA = ","; - - static final String CHAR_NAME_EQUAL = "="; - - static final String CHAR_NAME_PLUS = "+"; - - static final String CHAR_NAME_LESSTHAN = "<"; - - static final String CHAR_NAME_RIGHT_PARENTHESIS = ")"; - - static final String CHAR_NAME_LEFT_PARENTHESIS = "("; - - static final String CHAR_NAME_RIGHT_CURLY_BRACHET = "}"; - - static final String CHAR_NAME_LEFT_CURLY_BRACHET = "{"; - - static final String CHAR_NAME_RIGHT_SQUARE_BRACKET = "]"; - - static final String CHAR_NAME_LEFT_SQUARE_BRACKET = "["; - - static final String CHAR_NAME_DOT = "."; - - static final String CHAR_NAME_SEMICOLON = ";"; - - static final String VARIABLE_NAME_PK = "_$$_pk"; - - static final String VARIABLE_NAME_SIZE = "_$$_len"; - - static final String VARIABLE_NAME_ARRAY = "_$$_ary"; - - static final String VARIABLE_NAME_LIST = "_$$_list"; - - static final String VARIABLE_NAME_MAP = "_$$_map"; - - static final String VARIABLE_NAME_KEY = "_$$_key"; - - static final String VARIABLE_NAME_VAL = "_$$_val"; - - static final String VARIABLE_NAME_ITER = "_$$_iter"; - - static final String VARIABLE_NAME_MPO = "_$$_mpo"; - - static final String VARIABLE_NAME_I = "i"; - - static final String METHOD_NAME_VALUEOF = "valueOf"; - - static final String METHOD_NAME_ADD = "add"; - - static final String METHOD_NAME_PUT = "put"; - - static final String METHOD_NAME_GET = "get"; - - static final String METHOD_NAME_SIZE = "size"; - - static final String METHOD_NAME_KEYSET = "keySet"; - - static final String METHOD_NAME_ITERATOR = "iterator"; - - static final String METHOD_NAME_HASNEXT = "hasNext"; - - static final String METHOD_NAME_NEXT = "next"; - - static final String METHOD_NAME_MSGPACK = "messagePack"; - - static final String METHOD_NAME_MSGUNPACK = "messageUnpack"; - - static final String METHOD_NAME_MSGCONVERT = "messageConvert"; - - static final String METHOD_NAME_PACK = "pack"; - - static final String METHOD_NAME_PACKARRAY = "packArray"; - - static final String METHOD_NAME_UNPACK = "unpack"; - - static final String METHOD_NAME_UNPACKBOOLEAN = "unpackBoolean"; - - static final String METHOD_NAME_UNPACKBYTE = "unpackByte"; - - static final String METHOD_NAME_UNPACKDOUBLE = "unpackDouble"; - - static final String METHOD_NAME_UNPACKFLOAT = "unpackFloat"; - - static final String METHOD_NAME_UNPACKINT = "unpackInt"; - - static final String METHOD_NAME_UNPACKLONG = "unpackLong"; - - static final String METHOD_NAME_UNPACKSHORT = "unpackShort"; - - static final String METHOD_NAME_UNPACKSTRING = "unpackString"; - - static final String METHOD_NAME_UNPACKBIGINTEGER = "unpackBigInteger"; - - static final String METHOD_NAME_UNPACKOBJECT = "unpackObject"; - - static final String METHOD_NAME_UNPACKBYTEARRAY = "unpackByteArray"; - - static final String METHOD_NAME_UNPACKARRAY = "unpackArray"; - - static final String METHOD_NAME_UNPACKMAP = "unpackMap"; - - static final String METHOD_NAME_ASARRAY = "asArray"; - - static final String METHOD_NAME_ASBOOLEAN = "asBoolean"; - - static final String METHOD_NAME_ASBYTE = "asByte"; - - static final String METHOD_NAME_ASSHORT = "asShort"; - - static final String METHOD_NAME_ASINT = "asInt"; - - static final String METHOD_NAME_ASFLOAT = "asFloat"; - - static final String METHOD_NAME_ASLONG = "asLong"; - - static final String METHOD_NAME_ASDOUBLE = "asDouble"; - - static final String METHOD_NAME_ASSTRING = "asString"; - - static final String METHOD_NAME_ASBYTEARRAY = "asByteArray"; - - static final String METHOD_NAME_ASBIGINTEGER = "asBigInteger"; - } - - public static class Enhancer { - - private ConcurrentHashMap> classCache; - - private ClassPool pool; - - protected Enhancer() { - classCache = new ConcurrentHashMap>(); - pool = ClassPool.getDefault(); - } - - protected Class getCache(String origName) { - return classCache.get(origName); - } - - protected void setCache(String origName, Class enhClass) { - classCache.putIfAbsent(origName, enhClass); - } - - protected Class generate(Class origClass, boolean packUnpackable) - throws NotFoundException, CannotCompileException { - String origName = origClass.getName(); - String enhName = origName + Constants.POSTFIX_TYPE_NAME_ENHANCER; - CtClass origCtClass = pool.get(origName); - checkClassValidation(origClass, packUnpackable); - checkDefaultConstructorValidation(origClass); - CtClass enhCtClass = pool.makeClass(enhName); - setSuperclass(enhCtClass, origCtClass); - setInterfaces(enhCtClass); - addConstructor(enhCtClass); - Field[] fields = getDeclaredFields(origClass); - addMessagePackMethod(enhCtClass, fields); - addMessageUnpackMethod(enhCtClass, fields); - addMessageConvertMethod(enhCtClass, fields); - return createClass(enhCtClass); - } - - private void checkClassValidation(Class origClass, - boolean packUnpackable) { - // not public, abstract, final - int mod = origClass.getModifiers(); - if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) - || Modifier.isAbstract(mod) || Modifier.isFinal(mod)) { - throwClassValidationException(origClass); - } - // interface, enum - if (origClass.isInterface() || origClass.isEnum()) { - throwClassValidationException(origClass); - } - // annotation - if (!packUnpackable) { - checkPackUnpackAnnotation(origClass); - } - } - - private static void throwClassValidationException(Class origClass) { - throw new DynamicCodeGenException( - "it must be a public class and have @" - + MessagePackUnpackable.class.getName() + ": " - + origClass.getName()); - } - - private void checkPackUnpackAnnotation(Class origClass) { - Annotation anno = origClass - .getAnnotation(MessagePackUnpackable.class); - if (anno == null) { - throwClassValidationException(origClass); - } - } - - private void checkDefaultConstructorValidation(Class origClass) { - Constructor cons = null; - try { - cons = origClass.getDeclaredConstructor(new Class[0]); - } catch (Exception e1) { - throwConstructoValidationException(origClass); - } - - int mod = cons.getModifiers(); - if (!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) { - throwConstructoValidationException(origClass); - } - } - - private static void throwConstructoValidationException( - Class origClass) { - throw new DynamicCodeGenException( - "it must have a public zero-argument constructor: " - + origClass.getName()); - } - - private void setSuperclass(CtClass enhCtClass, CtClass origCtClass) - throws CannotCompileException { - enhCtClass.setSuperclass(origCtClass); - } - - private void setInterfaces(CtClass enhCtClass) throws NotFoundException { - CtClass pacCtClass = pool.get(MessagePackable.class.getName()); - enhCtClass.addInterface(pacCtClass); - CtClass unpacCtClass = pool.get(MessageUnpackable.class.getName()); - enhCtClass.addInterface(unpacCtClass); - CtClass convCtClass = pool.get(MessageConvertable.class.getName()); - enhCtClass.addInterface(convCtClass); - } - - private void addConstructor(CtClass enhCtClass) - throws CannotCompileException { - CtConstructor newCtCons = CtNewConstructor - .defaultConstructor(enhCtClass); - enhCtClass.addConstructor(newCtCons); - } - - private Field[] getDeclaredFields(Class origClass) { - ArrayList allFields = new ArrayList(); - Class nextClass = origClass; - while (nextClass != Object.class) { - Field[] fields = nextClass.getDeclaredFields(); - for (Field field : fields) { - try { - checkFieldValidation(field, allFields); - allFields.add(field); - } catch (DynamicCodeGenException e) { // ignore - } - } - nextClass = nextClass.getSuperclass(); - } - return allFields.toArray(new Field[0]); - } - - private void checkFieldValidation(Field field, List fields) { - // check modifiers (public or protected) - int mod = field.getModifiers(); - if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) - || Modifier.isStatic(mod) || Modifier.isFinal(mod) - || Modifier.isTransient(mod) || field.isSynthetic()) { - throwFieldValidationException(field); - } - // check same name - for (Field f : fields) { - if (f.getName().equals(field.getName())) { - throwFieldValidationException(field); - } - } - } - - private static void throwFieldValidationException(Field field) { - throw new DynamicCodeGenException("it must be a public field: " - + field.getName()); - } - - private void addMessagePackMethod(CtClass enhCtClass, Field[] fields) - throws CannotCompileException, NotFoundException { - StringBuilder sb = new StringBuilder(); - sb.append(Constants.KEYWORD_MODIFIER_PUBLIC); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(void.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.METHOD_NAME_MSGPACK); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Packer.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_THROWS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(IOException.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_PACKARRAY); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(fields.length); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - for (Field field : fields) { - insertCodeOfMessagePackCall(sb, field); - } - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - // System.out.println("messagePack method: " + sb.toString()); - CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); - enhCtClass.addMethod(newCtMethod); - } - - private void insertCodeOfMessagePackCall(StringBuilder sb, Field field) { - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_PACK); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private void addMessageUnpackMethod(CtClass enhCtClass, Field[] fields) - throws CannotCompileException, NotFoundException { - StringBuilder sb = new StringBuilder(); - sb.append(Constants.KEYWORD_MODIFIER_PUBLIC); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(void.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.METHOD_NAME_MSGUNPACK); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Unpacker.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_THROWS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(MessageTypeException.class.getName()); - sb.append(Constants.CHAR_NAME_COMMA); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(IOException.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_UNPACKARRAY); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - insertCodeOfMessageUnpackCalls(sb, fields); - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - // System.out.println("messageUnpack method: " + sb.toString()); - CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); - enhCtClass.addMethod(newCtMethod); - } - - private void insertCodeOfMessageUnpackCalls(StringBuilder sb, - Field[] fields) throws NotFoundException { - for (Field field : fields) { - insertCodeOfMessageUnpackCall(sb, field, field.getType()); - } - } - - private void insertCodeOfMessageUnpackCall(StringBuilder sb, Field f, - Class c) throws NotFoundException { - if (c.isPrimitive()) { - // primitive type - insertCodeOfMessageUnpackCallForPrimTypes(sb, f, c); - } else if (c.equals(Boolean.class) || // Boolean - c.equals(Byte.class) || // Byte - c.equals(Double.class) || // Double - c.equals(Float.class) || // Float - c.equals(Integer.class) || // Integer - c.equals(Long.class) || // Long - c.equals(Short.class)) { // Short - // reference type (wrapper type) - insertCodeOfMessageUnpackCallForWrapTypes(sb, f, c); - } else if (c.equals(BigInteger.class) || // BigInteger - c.equals(String.class) || // String - c.equals(byte[].class)) { // byte[] - // reference type (other type) - insertCodeOfMessageUnpackCallForPrimTypes(sb, f, c); - } else if (List.class.isAssignableFrom(c)) { - // List - insertCodeOfMessageUnpackCallForListType(sb, f, c); - } else if (Map.class.isAssignableFrom(c)) { - // Map - insertCodeOfMessageUnpackCallForMapType(sb, f, c); - } else if (getCache(c.getName()) != null) { - // cached - insertCodeOfMessageUnpackCallForEnhancedType(sb, f, c); - } else if (MessageUnpackable.class.isAssignableFrom(c)) { - // MessageUnpackable - insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, f, c); - } else { - throw new NotFoundException("unknown type: " + c.getName()); - } - } - - private void insertCodeOfMessageUnpackCallForPrimTypes( - StringBuilder sb, Field field, Class type) - throws NotFoundException { - // insert a right variable - if (field != null) { - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - // insert unpack method - if (type.equals(boolean.class)) { // boolean - sb.append(Constants.METHOD_NAME_UNPACKBOOLEAN); - } else if (type.equals(byte.class)) { // byte - sb.append(Constants.METHOD_NAME_UNPACKBYTE); - } else if (type.equals(double.class)) { // double - sb.append(Constants.METHOD_NAME_UNPACKDOUBLE); - } else if (type.equals(float.class)) { // float - sb.append(Constants.METHOD_NAME_UNPACKFLOAT); - } else if (type.equals(int.class)) { // int - sb.append(Constants.METHOD_NAME_UNPACKINT); - } else if (type.equals(long.class)) { // long - sb.append(Constants.METHOD_NAME_UNPACKLONG); - } else if (type.equals(short.class)) { // short - sb.append(Constants.METHOD_NAME_UNPACKSHORT); - } else { // reference type - if (type.equals(BigInteger.class)) { // BigInteger - sb.append(Constants.METHOD_NAME_UNPACKBIGINTEGER); - } else if (type.equals(String.class)) { // String - sb.append(Constants.METHOD_NAME_UNPACKSTRING); - } else if (type.equals(byte[].class)) { // byte[] - sb.append(Constants.METHOD_NAME_UNPACKBYTEARRAY); - } else { - throw new NotFoundException("unknown type: " - + type.getName()); - } - } - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (field != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } - - private void insertCodeOfMessageUnpackCallForWrapTypes( - StringBuilder sb, Field field, Class type) - throws NotFoundException { - // insert a right variable - if (field != null) { - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(type.getName()); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_VALUEOF); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - // insert the name of a unpack method - if (type.equals(Boolean.class)) { // Boolean - sb.append(Constants.METHOD_NAME_UNPACKBOOLEAN); - } else if (type.equals(Byte.class)) { // Byte - sb.append(Constants.METHOD_NAME_UNPACKBYTE); - } else if (type.equals(Double.class)) { // Double - sb.append(Constants.METHOD_NAME_UNPACKDOUBLE); - } else if (type.equals(Float.class)) { // Float - sb.append(Constants.METHOD_NAME_UNPACKFLOAT); - } else if (type.equals(Integer.class)) { // Integer - sb.append(Constants.METHOD_NAME_UNPACKINT); - } else if (type.equals(Long.class)) { // Long - sb.append(Constants.METHOD_NAME_UNPACKLONG); - } else if (type.equals(Short.class)) { // Short - sb.append(Constants.METHOD_NAME_UNPACKSHORT); - } else { - throw new NotFoundException("unknown type: " + type.getName()); - } - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (field != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } - - private void insertCodeOfMessageUnpackCallForListType(StringBuilder sb, - Field field, Class type) throws NotFoundException { - ParameterizedType generic = (ParameterizedType) field - .getGenericType(); - Class genericType = (Class) generic.getActualTypeArguments()[0]; - - // len - sb.append(int.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_SIZE); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_UNPACKARRAY); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // field initializer - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(ArrayList.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // for loop - sb.append(Constants.KEYWORD_FOR); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(int.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(0); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LESSTHAN); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_SIZE); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_PLUS); - sb.append(Constants.CHAR_NAME_PLUS); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - - // block - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_ADD); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - insertCodeOfMessageUnpackCall(sb, null, genericType); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private void insertCodeOfMessageUnpackCallForMapType(StringBuilder sb, - Field field, Class type) throws NotFoundException { - ParameterizedType generic = (ParameterizedType) field - .getGenericType(); - Class genericType0 = (Class) generic.getActualTypeArguments()[0]; - Class genericType1 = (Class) generic.getActualTypeArguments()[1]; - - // len - sb.append(int.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_SIZE); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_UNPACKMAP); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // field initializer - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(HashMap.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // for loop - sb.append(Constants.KEYWORD_FOR); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(int.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(0); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LESSTHAN); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_SIZE); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_PLUS); - sb.append(Constants.CHAR_NAME_PLUS); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - - // block map. - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_PUT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - insertCodeOfMessageUnpackCall(sb, null, genericType0); - sb.append(Constants.CHAR_NAME_COMMA); - sb.append(Constants.CHAR_NAME_SPACE); - insertCodeOfMessageUnpackCall(sb, null, genericType1); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private void insertCodeOfMessageUnpackCallForEnhancedType( - StringBuilder sb, Field f, Class c) { - c = this.getCache(c.getName()); - insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, f, c); - } - - private void insertCodeOfMessageUnpackCallForMsgUnpackableType( - StringBuilder sb, Field f, Class c) { - // if (fi == null) { fi = new Foo_$$_Enhanced(); } - sb.append(Constants.KEYWORD_IF); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NULL); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(c.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - - // insert a right variable // ignore - sb.append(Constants.VARIABLE_NAME_PK); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_UNPACK); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessageUnpackable.class.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private void addMessageConvertMethod(CtClass enhCtClass, Field[] fields) - throws CannotCompileException { - // messageConvert(MessagePackObject obj) throws MessageTypeException - StringBuilder sb = new StringBuilder(); - sb.append(Constants.KEYWORD_MODIFIER_PUBLIC); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(void.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.METHOD_NAME_MSGCONVERT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_MPO); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_THROWS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(MessageTypeException.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - insertCodeOfMessagePackObjectArrayGet(sb); - insertCodeOfMesageConvertCalls(sb, fields); - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - // System.out.println("messageConvert method: " + sb.toString()); - CtMethod newCtMethod = CtNewMethod.make(sb.toString(), enhCtClass); - enhCtClass.addMethod(newCtMethod); - } - - private void insertCodeOfMessagePackObjectArrayGet(StringBuilder sb) { - // MessagePackObject[] ary = obj.asArray(); - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_MPO); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_ASARRAY); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private void insertCodeOfMesageConvertCalls(StringBuilder sb, - Field[] fields) { - for (int i = 0; i < fields.length; ++i) { - insertCodeOfMessageConvertCall(sb, fields[i], fields[i] - .getType(), i, null); - } - } - - private void insertCodeOfMessageConvertCall(StringBuilder sb, Field f, - Class c, int i, String v) { - if (c.isPrimitive()) { // primitive type - insertCodeOfMessageConvertCallForPrimTypes(sb, f, c, i, v); - } else { // reference type - if (c.equals(Boolean.class) || c.equals(Byte.class) - || c.equals(Short.class) || c.equals(Integer.class) - || c.equals(Float.class) || c.equals(Long.class) - || c.equals(Double.class)) { - // wrapper type - insertCodeOfMessageConvertCallForWrapTypes(sb, f, c, i, v); - } else if (c.equals(String.class) || c.equals(byte[].class) - || c.equals(BigInteger.class)) { - insertCodeOfMessageConvertCallForPrimTypes(sb, f, c, i, v); - } else if (List.class.isAssignableFrom(c)) { - insertCodeOfMessageConvertCallForList(sb, f, c, i); - } else if (Map.class.isAssignableFrom(c)) { - insertCodeOfMessageConvertCallForMap(sb, f, c, i); - } else if ((getCache(c.getName()) != null)) { - insertCodeOfMessageConvertCallForEnhancedType(sb, f, c, i); - } else if (MessageConvertable.class.isAssignableFrom(c)) { - insertCodeOfMessageConvertCallForMsgConvtblType(sb, f, c, i); - } else { - throw new MessageTypeException("Type error: " + c.getName()); - } - } - } - - private void insertCodeOfMessageConvertCallForEnhancedType( - StringBuilder sb, Field f, Class c, int i) { - c = getCache(c.getName()); - insertCodeOfMessageConvertCallForMsgConvtblType(sb, f, c, i); - } - - private void insertCodeOfMessageConvertCallForMsgConvtblType( - StringBuilder sb, Field f, Class c, int i) { - // if (fi == null) { fi = new Foo_$$_Enhanced(); } - sb.append(Constants.KEYWORD_IF); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NULL); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(c.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - - // ((MessageConvertable)f_i).messageConvert(ary[i]); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessageConvertable.class.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_MSGCONVERT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private void insertCodeOfMessageConvertCallForPrimTypes( - StringBuilder sb, Field f, Class c, int i, String name) { - // f0 = objs[0].intValue(); - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(name); - } - sb.append(Constants.CHAR_NAME_DOT); - if (c.equals(boolean.class)) { - sb.append(Constants.METHOD_NAME_ASBOOLEAN); - } else if (c.equals(byte.class)) { - sb.append(Constants.METHOD_NAME_ASBYTE); - } else if (c.equals(short.class)) { - sb.append(Constants.METHOD_NAME_ASSHORT); - } else if (c.equals(int.class)) { - sb.append(Constants.METHOD_NAME_ASINT); - } else if (c.equals(float.class)) { - sb.append(Constants.METHOD_NAME_ASFLOAT); - } else if (c.equals(long.class)) { - sb.append(Constants.METHOD_NAME_ASLONG); - } else if (c.equals(double.class)) { - sb.append(Constants.METHOD_NAME_ASDOUBLE); - } else if (c.equals(String.class)) { - sb.append(Constants.METHOD_NAME_ASSTRING); - } else if (c.equals(byte[].class)) { - sb.append(Constants.METHOD_NAME_ASBYTEARRAY); - } else if (c.equals(BigInteger.class)) { - sb.append(Constants.METHOD_NAME_ASBIGINTEGER); - } else { - throw new MessageTypeException("Type error: " + c.getName()); - } - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } - - private void insertCodeOfMessageConvertCallForWrapTypes( - StringBuilder sb, Field f, Class c, int i, String v) { - if (f != null) { - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - } - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - if (c.equals(Boolean.class)) { - sb.append(Boolean.class.getName()); - } else if (c.equals(Byte.class)) { - sb.append(Byte.class.getName()); - } else if (c.equals(Short.class)) { - sb.append(Short.class.getName()); - } else if (c.equals(Integer.class)) { - sb.append(Integer.class.getName()); - } else if (c.equals(Float.class)) { - sb.append(Float.class.getName()); - } else if (c.equals(Long.class)) { - sb.append(Long.class.getName()); - } else if (c.equals(Double.class)) { - sb.append(Double.class.getName()); - } else { - throw new MessageTypeException("Type error: " + c.getName()); - } - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - if (f != null) { - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - } else { - sb.append(v); - } - sb.append(Constants.CHAR_NAME_DOT); - if (c.equals(Boolean.class)) { - sb.append(Constants.METHOD_NAME_ASBOOLEAN); - } else if (c.equals(Byte.class)) { - sb.append(Constants.METHOD_NAME_ASBYTE); - } else if (c.equals(Short.class)) { - sb.append(Constants.METHOD_NAME_ASSHORT); - } else if (c.equals(Integer.class)) { - sb.append(Constants.METHOD_NAME_ASINT); - } else if (c.equals(Float.class)) { - sb.append(Constants.METHOD_NAME_ASFLOAT); - } else if (c.equals(Long.class)) { - sb.append(Constants.METHOD_NAME_ASLONG); - } else if (c.equals(Double.class)) { - sb.append(Constants.METHOD_NAME_ASDOUBLE); - } else { - throw new MessageTypeException("Type error: " + c.getName()); - } - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - if (f != null) { - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - } - } - - private void insertCodeOfMessageConvertCallForList(StringBuilder sb, - Field field, Class type, int i) { - ParameterizedType generic = (ParameterizedType) field - .getGenericType(); - Class genericType = (Class) generic.getActualTypeArguments()[0]; - - // List list = ary[i].asList(); - sb.append(List.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_LIST); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asList"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // int size = list.size(); - sb.append(int.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_SIZE); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_LIST); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_SIZE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // field initializer - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(ArrayList.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // for loop - sb.append(Constants.KEYWORD_FOR); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(int.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(0); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LESSTHAN); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_SIZE); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_PLUS); - sb.append(Constants.CHAR_NAME_PLUS); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - - // block begin - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_VAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_LIST); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_GET); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_I); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - sb.append(field.getName()); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_ADD); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - insertCodeOfMessageConvertCall(sb, null, genericType, -1, - Constants.VARIABLE_NAME_VAL); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - // block end - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private void insertCodeOfMessageConvertCallForMap(StringBuilder sb, - Field f, Class c, int i) { - ParameterizedType generic = (ParameterizedType) f.getGenericType(); - Class genericType0 = (Class) generic.getActualTypeArguments()[0]; - Class genericType1 = (Class) generic.getActualTypeArguments()[1]; - - // Map map = ary[i].asMap(); - sb.append(Map.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_MAP); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ARRAY); - sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); - sb.append(i); - sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); - sb.append(Constants.CHAR_NAME_DOT); - sb.append("asMap"); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // int size = list.size(); - sb.append(int.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_SIZE); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_MAP); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_SIZE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // field initializer - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.KEYWORD_NEW); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(HashMap.class.getName()); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - // for loop - sb.append(Constants.KEYWORD_FOR); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Iterator.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ITER); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_MAP); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_KEYSET); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_ITERATOR); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_ITER); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_HASNEXT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - - // block map. - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_KEY); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_ITER); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_NEXT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.VARIABLE_NAME_VAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_EQUAL); - sb.append(Constants.CHAR_NAME_SPACE); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(MessagePackObject.class.getName()); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_MAP); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_GET); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - sb.append(Constants.VARIABLE_NAME_KEY); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - sb.append(f.getName()); - sb.append(Constants.CHAR_NAME_DOT); - sb.append(Constants.METHOD_NAME_PUT); - sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); - insertCodeOfMessageConvertCall(sb, null, genericType0, -1, - Constants.VARIABLE_NAME_KEY); - sb.append(Constants.CHAR_NAME_COMMA); - sb.append(Constants.CHAR_NAME_SPACE); - insertCodeOfMessageConvertCall(sb, null, genericType1, -1, - Constants.VARIABLE_NAME_VAL); - sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); - sb.append(Constants.CHAR_NAME_SEMICOLON); - sb.append(Constants.CHAR_NAME_SPACE); - - sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACHET); - sb.append(Constants.CHAR_NAME_SPACE); - } - - private Class createClass(CtClass enhCtClass) - throws CannotCompileException { - return enhCtClass.toClass(null, null); - } - } - - private static Enhancer enhancer; - - public static void registerEnhancedClass(Class origClass, - boolean packUnpackable) { - if (enhancer == null) { - enhancer = new Enhancer(); - } - String origName = origClass.getName(); - Class enhClass = enhancer.getCache(origName); - if (enhClass == null) { - // generate a class object related to the original class - try { - enhClass = enhancer.generate(origClass, packUnpackable); - } catch (NotFoundException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (CannotCompileException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } - // set the generated class to the cache - enhancer.setCache(origName, enhClass); - } - } - - public static void registerEnhancedClass(Class origClass) { - registerEnhancedClass(origClass, false); - } - - public static boolean isRegistered(Class origClass) { - if (enhancer == null) { - enhancer = new Enhancer(); - } - return enhancer.getCache(origClass.getName()) != null; - } - - public static Class getEnhancedClass(Class origClass, - boolean packUnpackable) { - if (!isRegistered(origClass)) { - registerEnhancedClass(origClass, packUnpackable); - } - return enhancer.getCache(origClass.getName()); - } - - public static Class getEnhancedClass(Class origClass) { - return getEnhancedClass(origClass, false); - } - - public static Object newEnhancedInstance(Class origClass, - boolean packUnpackable) { - try { - Class enhClass = getEnhancedClass(origClass, packUnpackable); - // create a new object of the generated class - return enhClass.newInstance(); - } catch (InstantiationException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } - } - - public static Object newEnhancedInstance(Class origClass) { - return newEnhancedInstance(origClass, false); - } - - public static Object initEnhancedInstance(MessagePackObject obj, - Class origClass, boolean packUnpackable) { - Object ret = newEnhancedInstance(origClass, packUnpackable); - ((MessageConvertable) ret).messageConvert(obj); - return ret; - } - - public static Object initEnhancedInstance(MessagePackObject obj, - Class origClass) { - return initEnhancedInstance(obj, origClass, false); - } - - @MessagePackUnpackable - public static class Image { - public String uri = ""; - - public String title = ""; - - public int width = 0; - - public int height = 0; - - public int size = 0; - - public boolean equals(Image obj) { - return uri.equals(obj.uri) && title.equals(obj.title) - && width == obj.width && height == obj.height - && size == obj.size; - } - - public boolean equals(Object obj) { - if (obj.getClass() != Image.class) { - return false; - } - return equals((Image) obj); - } - } - - public static void main(final String[] args) throws Exception { - Image src = (Image) PackUnpackUtil.newEnhancedInstance(Image.class); - src.title = "msgpack"; - src.uri = "http://msgpack.org/"; - src.width = 2560; - src.height = 1600; - src.size = 4096000; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - Image dst = (Image) PackUnpackUtil.newEnhancedInstance(Image.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - // System.out.println(src.equals(dst)); - } -} From 923580d2cd2356e40b1d542df3625381b139f8cc Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Tue, 28 Sep 2010 15:31:55 +0900 Subject: [PATCH 9/9] write a simple test program for a DynamicCodeGenPacker class --- .../main/java/org/msgpack/MessagePacker.java | 2 +- .../annotation/MessagePackOptional.java | 12 + .../annotation/MessagePackRequired.java | 12 + .../msgpack/util/codegen/BasicConstants.java | 6 +- .../msgpack/util/codegen/DynamicCodeGen.java | 515 ++++++++++++- .../util/codegen/DynamicCodeGenBase.java | 13 +- .../TestDynamicCodeGenPackerTemplate.java | 77 ++ .../codegen/TestDynamicCodeGenPacker.java | 61 -- .../codegen/TestMessagePackUnpackable.java | 703 ------------------ 9 files changed, 619 insertions(+), 782 deletions(-) create mode 100644 java/src/main/java/org/msgpack/annotation/MessagePackOptional.java create mode 100644 java/src/main/java/org/msgpack/annotation/MessagePackRequired.java create mode 100644 java/src/test/java/org/msgpack/util/TestDynamicCodeGenPackerTemplate.java delete mode 100644 java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java delete mode 100644 java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java diff --git a/java/src/main/java/org/msgpack/MessagePacker.java b/java/src/main/java/org/msgpack/MessagePacker.java index 05d4de5d..e5d387ee 100644 --- a/java/src/main/java/org/msgpack/MessagePacker.java +++ b/java/src/main/java/org/msgpack/MessagePacker.java @@ -20,6 +20,6 @@ package org.msgpack; import java.io.IOException; public interface MessagePacker { - public void pack(Packer pk, Object target) throws IOException; + void pack(Packer pk, Object target) throws IOException; } diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackOptional.java b/java/src/main/java/org/msgpack/annotation/MessagePackOptional.java new file mode 100644 index 00000000..081b28c0 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/MessagePackOptional.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.FIELD) +@Retention(RetentionPolicy.CLASS) +public @interface MessagePackOptional { + int value() default -1; +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackRequired.java b/java/src/main/java/org/msgpack/annotation/MessagePackRequired.java new file mode 100644 index 00000000..e268c4f5 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/MessagePackRequired.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.FIELD) +@Retention(RetentionPolicy.CLASS) +public @interface MessagePackRequired { + int value() default -1; +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java index f675f815..e568a762 100644 --- a/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java +++ b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java @@ -98,10 +98,8 @@ public interface BasicConstants { String METHOD_NAME_NEXT = "next"; - String METHOD_NAME_MSGPACK = "messagePack"; - - String METHOD_NAME_MSGUNPACK = "messageUnpack"; - + String METHOD_NAME_CONVERT = "convert"; + String METHOD_NAME_MSGCONVERT = "messageConvert"; String METHOD_NAME_PACK = "pack"; diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java index bd010eac..9193b98f 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java @@ -8,6 +8,7 @@ import java.lang.reflect.ParameterizedType; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -21,6 +22,7 @@ import javassist.CtNewConstructor; import javassist.CtNewMethod; import javassist.NotFoundException; +import org.msgpack.MessageConvertable; import org.msgpack.MessagePackObject; import org.msgpack.MessagePacker; import org.msgpack.MessageTypeException; @@ -204,6 +206,7 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { private void addPackMethod(CtClass packerCtClass, Class c, Field[] fs) throws CannotCompileException, NotFoundException { + // void pack(Packer pk, Object target) throws IOException; StringBuilder sb = new StringBuilder(); StringBuilder bsb = new StringBuilder(); insertPackMethodBody(bsb, c, fs); @@ -211,7 +214,7 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { Packer.class, Object.class }, new String[] { VARIABLE_NAME_PK, VARIABLE_NAME_OBJECT }, new Class[] { IOException.class }, bsb .toString()); - System.out.println("pack method: " + sb.toString()); + // System.out.println("pack method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), packerCtClass); packerCtClass.addMethod(newCtMethod); } @@ -226,17 +229,15 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { new String[] { new Integer(fs.length).toString() }); insertSemicolon(sb); for (Field f : fs) { - insertCodeOfPackCall(sb, f); + insertCodeOfPackMethodCall(sb, f); } } - private void insertCodeOfPackCall(StringBuilder sb, Field field) { - StringBuilder aname = new StringBuilder(); - aname.append(VARIABLE_NAME_TARGET); - aname.append(CHAR_NAME_DOT); - aname.append(field.getName()); + private void insertCodeOfPackMethodCall(StringBuilder sb, Field field) { + StringBuilder fa = new StringBuilder(); + insertFieldAccess(fa, VARIABLE_NAME_TARGET, field.getName()); insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACK, - new String[] { aname.toString() }); + new String[] { fa.toString() }); insertSemicolon(sb); } @@ -251,7 +252,7 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { new String[] { VARIABLE_NAME_PK }, new Class[] { MessageTypeException.class, IOException.class }, bsb .toString()); - System.out.println("unpack method: " + sb.toString()); + // System.out.println("unpack method: " + sb.toString()); CtMethod newCtMethod = CtNewMethod.make(sb.toString(), unpackerCtClass); unpackerCtClass.addMethod(newCtMethod); } @@ -326,6 +327,7 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { Field f, Class c) { if (f != null) { sb.append(VARIABLE_NAME_TARGET); + sb.append(CHAR_NAME_DOT); sb.append(f.getName()); sb.append(CHAR_NAME_SPACE); sb.append(CHAR_NAME_EQUAL); @@ -547,10 +549,501 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants { sb.append(CHAR_NAME_SPACE); } - private void addConvertMethod(CtClass tmplCtClass, Class c, Field[] fs) + public void addConvertMethod(CtClass tmplCtClass, Class c, Field[] fs) throws CannotCompileException, NotFoundException { // Object convert(MessagePackObject from) throws MessageTypeException; - // FIXME + StringBuilder sb = new StringBuilder(); + StringBuilder bsb = new StringBuilder(); + insertConvertMethodBody(bsb, c, fs); + addPublicMethodDecl(sb, METHOD_NAME_CONVERT, Object.class, + new Class[] { MessagePackObject.class }, + new String[] { VARIABLE_NAME_MPO }, + new Class[] { MessageTypeException.class }, bsb.toString()); + // System.out.println("convert method: " + sb.toString()); + CtMethod newCtMethod = CtNewMethod.make(sb.toString(), tmplCtClass); + tmplCtClass.addMethod(newCtMethod); + } + + private void insertConvertMethodBody(StringBuilder sb, Class c, + Field[] fields) throws CannotCompileException { + insertLocalVariableDecl(sb, c, VARIABLE_NAME_TARGET); + StringBuilder mc = new StringBuilder(); + insertDefaultConsCall(mc, c); + insertValueInsertion(sb, mc.toString()); + insertSemicolon(sb); + insertCodeOfMessagePackObjectArrayGet(sb); + insertCodeOfConvertMethodCalls(sb, fields); + insertReturnStat(sb, VARIABLE_NAME_TARGET); + insertSemicolon(sb); + } + + private void insertCodeOfMessagePackObjectArrayGet(StringBuilder sb) { + // MessagePackObject[] ary = obj.asArray(); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MPO); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_ASARRAY); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + + private void insertCodeOfConvertMethodCalls(StringBuilder sb, Field[] fields) { + for (int i = 0; i < fields.length; ++i) { + insertCodeOfMessageConvertCall(sb, fields[i], fields[i].getType(), + i, null); + } + } + + private void insertCodeOfMessageConvertCall(StringBuilder sb, Field f, + Class c, int i, String v) { + if (c.isPrimitive()) { // primitive type + insertCodeOfConvertMethodCallForPrimTypes(sb, f, c, i, v); + } else { // reference type + if (c.equals(Boolean.class) || c.equals(Byte.class) + || c.equals(Short.class) || c.equals(Integer.class) + || c.equals(Float.class) || c.equals(Long.class) + || c.equals(Double.class)) { + // wrapper type + insertCodeOfMessageConvertCallForWrapTypes(sb, f, c, i, v); + } else if (c.equals(String.class) || c.equals(byte[].class) + || c.equals(BigInteger.class)) { + insertCodeOfConvertMethodCallForPrimTypes(sb, f, c, i, v); + } else if (List.class.isAssignableFrom(c)) { + insertCodeOfMessageConvertCallForList(sb, f, c, i); + } else if (Map.class.isAssignableFrom(c)) { + insertCodeOfMessageConvertCallForMap(sb, f, c, i); + } else if (MessageConvertable.class.isAssignableFrom(c)) { + insertCodeOfMessageConvertCallForMsgConvtblType(sb, f, c, i); + } else { + throw new MessageTypeException("Type error: " + c.getName()); + } + } + } + + // + // private void insertCodeOfMessageConvertCallForEnhancedType( + // StringBuilder sb, Field f, Class c, int i) { + // c = getCache(c.getName()); + // insertCodeOfMessageConvertCallForMsgConvtblType(sb, f, c, i); + // } + + private void insertCodeOfMessageConvertCallForMsgConvtblType( + StringBuilder sb, Field f, Class c, int i) { + // if (fi == null) { fi = new Foo_$$_Enhanced(); } + sb.append(Constants.KEYWORD_IF); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NULL); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(c.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); + + // ((MessageConvertable)f_i).messageConvert(ary[i]); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessageConvertable.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_MSGCONVERT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + + private void insertCodeOfConvertMethodCallForPrimTypes(StringBuilder sb, + Field f, Class c, int i, String name) { + // target.f0 = objs[0].intValue(); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_TARGET); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(name); + } + sb.append(Constants.CHAR_NAME_DOT); + if (c.equals(boolean.class)) { + sb.append(Constants.METHOD_NAME_ASBOOLEAN); + } else if (c.equals(byte.class)) { + sb.append(Constants.METHOD_NAME_ASBYTE); + } else if (c.equals(short.class)) { + sb.append(Constants.METHOD_NAME_ASSHORT); + } else if (c.equals(int.class)) { + sb.append(Constants.METHOD_NAME_ASINT); + } else if (c.equals(float.class)) { + sb.append(Constants.METHOD_NAME_ASFLOAT); + } else if (c.equals(long.class)) { + sb.append(Constants.METHOD_NAME_ASLONG); + } else if (c.equals(double.class)) { + sb.append(Constants.METHOD_NAME_ASDOUBLE); + } else if (c.equals(String.class)) { + sb.append(Constants.METHOD_NAME_ASSTRING); + } else if (c.equals(byte[].class)) { + sb.append(Constants.METHOD_NAME_ASBYTEARRAY); + } else if (c.equals(BigInteger.class)) { + sb.append(Constants.METHOD_NAME_ASBIGINTEGER); + } else { + throw new MessageTypeException("Type error: " + c.getName()); + } + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } + + private void insertCodeOfMessageConvertCallForWrapTypes(StringBuilder sb, + Field f, Class c, int i, String v) { + if (f != null) { + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + } + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + if (c.equals(Boolean.class)) { + sb.append(Boolean.class.getName()); + } else if (c.equals(Byte.class)) { + sb.append(Byte.class.getName()); + } else if (c.equals(Short.class)) { + sb.append(Short.class.getName()); + } else if (c.equals(Integer.class)) { + sb.append(Integer.class.getName()); + } else if (c.equals(Float.class)) { + sb.append(Float.class.getName()); + } else if (c.equals(Long.class)) { + sb.append(Long.class.getName()); + } else if (c.equals(Double.class)) { + sb.append(Double.class.getName()); + } else { + throw new MessageTypeException("Type error: " + c.getName()); + } + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + if (f != null) { + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + } else { + sb.append(v); + } + sb.append(Constants.CHAR_NAME_DOT); + if (c.equals(Boolean.class)) { + sb.append(Constants.METHOD_NAME_ASBOOLEAN); + } else if (c.equals(Byte.class)) { + sb.append(Constants.METHOD_NAME_ASBYTE); + } else if (c.equals(Short.class)) { + sb.append(Constants.METHOD_NAME_ASSHORT); + } else if (c.equals(Integer.class)) { + sb.append(Constants.METHOD_NAME_ASINT); + } else if (c.equals(Float.class)) { + sb.append(Constants.METHOD_NAME_ASFLOAT); + } else if (c.equals(Long.class)) { + sb.append(Constants.METHOD_NAME_ASLONG); + } else if (c.equals(Double.class)) { + sb.append(Constants.METHOD_NAME_ASDOUBLE); + } else { + throw new MessageTypeException("Type error: " + c.getName()); + } + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + if (f != null) { + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + } + } + + private void insertCodeOfMessageConvertCallForList(StringBuilder sb, + Field field, Class type, int i) { + ParameterizedType generic = (ParameterizedType) field.getGenericType(); + Class genericType = (Class) generic.getActualTypeArguments()[0]; + + // List list = ary[i].asList(); + sb.append(List.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_LIST); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asList"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // int size = list.size(); + sb.append(int.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_SIZE); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_LIST); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_SIZE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // field initializer + sb.append(field.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(ArrayList.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // for loop + sb.append(Constants.KEYWORD_FOR); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(int.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(0); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LESSTHAN); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_SIZE); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_PLUS); + sb.append(Constants.CHAR_NAME_PLUS); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + + // block begin + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_VAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_LIST); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_GET); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_I); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + sb.append(field.getName()); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_ADD); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + insertCodeOfMessageConvertCall(sb, null, genericType, -1, + Constants.VARIABLE_NAME_VAL); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + // block end + sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); + } + + private void insertCodeOfMessageConvertCallForMap(StringBuilder sb, + Field f, Class c, int i) { + ParameterizedType generic = (ParameterizedType) f.getGenericType(); + Class genericType0 = (Class) generic.getActualTypeArguments()[0]; + Class genericType1 = (Class) generic.getActualTypeArguments()[1]; + + // Map map = ary[i].asMap(); + sb.append(Map.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ARRAY); + sb.append(Constants.CHAR_NAME_LEFT_SQUARE_BRACKET); + sb.append(i); + sb.append(Constants.CHAR_NAME_RIGHT_SQUARE_BRACKET); + sb.append(Constants.CHAR_NAME_DOT); + sb.append("asMap"); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // int size = list.size(); + sb.append(int.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_SIZE); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_SIZE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // field initializer + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.KEYWORD_NEW); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(HashMap.class.getName()); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + // for loop + sb.append(Constants.KEYWORD_FOR); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Iterator.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ITER); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_KEYSET); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_ITERATOR); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_ITER); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_HASNEXT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_CURLY_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); + + // block map. + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_KEY); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_ITER); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_NEXT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.VARIABLE_NAME_VAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_EQUAL); + sb.append(Constants.CHAR_NAME_SPACE); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(MessagePackObject.class.getName()); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_MAP); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_GET); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + sb.append(Constants.VARIABLE_NAME_KEY); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + sb.append(f.getName()); + sb.append(Constants.CHAR_NAME_DOT); + sb.append(Constants.METHOD_NAME_PUT); + sb.append(Constants.CHAR_NAME_LEFT_PARENTHESIS); + insertCodeOfMessageConvertCall(sb, null, genericType0, -1, + Constants.VARIABLE_NAME_KEY); + sb.append(Constants.CHAR_NAME_COMMA); + sb.append(Constants.CHAR_NAME_SPACE); + insertCodeOfMessageConvertCall(sb, null, genericType1, -1, + Constants.VARIABLE_NAME_VAL); + sb.append(Constants.CHAR_NAME_RIGHT_PARENTHESIS); + sb.append(Constants.CHAR_NAME_SEMICOLON); + sb.append(Constants.CHAR_NAME_SPACE); + + sb.append(Constants.CHAR_NAME_RIGHT_CURLY_BRACKET); + sb.append(Constants.CHAR_NAME_SPACE); } private Class createClass(CtClass packerCtClass) diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java index 1c907a23..9e10cf7c 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java +++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java @@ -15,8 +15,8 @@ public class DynamicCodeGenBase implements BasicConstants { sb.append(CHAR_NAME_SPACE); sb.append(name); } - - public void addPublicMethodDecl(StringBuilder sb, String mname, + + public void addPublicMethodDecl(StringBuilder sb, String mname, Class returnType, Class[] paramTypes, String[] anames, Class[] exceptTypes, String methodBody) { sb.append(KEYWORD_MODIFIER_PUBLIC); @@ -54,12 +54,14 @@ public class DynamicCodeGenBase implements BasicConstants { } public void insertSemicolon(StringBuilder sb) { + // ; sb.append(CHAR_NAME_SEMICOLON); sb.append(CHAR_NAME_SPACE); } public void insertLocalVariableDecl(StringBuilder sb, Class type, String name) { + // int lv sb.append(type.getName()); sb.append(CHAR_NAME_SPACE); sb.append(name); @@ -73,6 +75,13 @@ public class DynamicCodeGenBase implements BasicConstants { sb.append(expr); } + public void insertFieldAccess(StringBuilder sb, String target, String field) { + // target.field + sb.append(target); + sb.append(CHAR_NAME_DOT); + sb.append(field); + } + public void insertDefaultConsCall(StringBuilder sb, Class type) { // new tname() insertConsCall(sb, type, null); diff --git a/java/src/test/java/org/msgpack/util/TestDynamicCodeGenPackerTemplate.java b/java/src/test/java/org/msgpack/util/TestDynamicCodeGenPackerTemplate.java new file mode 100644 index 00000000..5b52c8ac --- /dev/null +++ b/java/src/test/java/org/msgpack/util/TestDynamicCodeGenPackerTemplate.java @@ -0,0 +1,77 @@ +package org.msgpack.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +import org.junit.Test; +import org.msgpack.CustomPacker; +import org.msgpack.MessagePacker; +import org.msgpack.Packer; +import org.msgpack.ReflectionTemplate; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.util.codegen.DynamicCodeGenPacker; +import org.msgpack.util.codegen.DynamicCodeGenTemplate; + +import static org.junit.Assert.*; + +public class TestDynamicCodeGenPackerTemplate { + + public static class StringFieldClass { + public String s1; + public String s2; + public StringFieldClass() { } + } + + @Test + public void testPackConvert() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + MessagePacker packer = DynamicCodeGenPacker.create(StringFieldClass.class); + + StringFieldClass src = new StringFieldClass(); + + src.s1 = "kumofs"; + src.s2 = "frsyuki"; + + packer.pack(new Packer(out), src); + + Template tmpl = DynamicCodeGenTemplate.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); + } + + @Test + public void testPackConvert02() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + CustomPacker.register(StringFieldClass.class, DynamicCodeGenPacker.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); + } +} + diff --git a/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java b/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java deleted file mode 100644 index 88515378..00000000 --- a/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.msgpack.util.codegen; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import org.junit.Test; -import org.msgpack.MessagePacker; -import org.msgpack.MessageUnpacker; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Unpacker; - -import junit.framework.TestCase; - -public class TestDynamicCodeGenPacker extends TestCase { - public static class StringFieldClass { - public String s1; - public String s2; - - public StringFieldClass() { - } - } - - @Test - public void testPackConvert01() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicCodeGenPacker - .create(StringFieldClass.class); - MessageUnpacker unpacker = DynamicCodeGenUnpacker - .create(StringFieldClass.class); - - StringFieldClass src = new StringFieldClass(); - src.s1 = "muga"; - src.s2 = "nishizawa"; - packer.pack(new Packer(out), src); - - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - StringFieldClass dst = (StringFieldClass) new Unpacker(in) - .unpack(unpacker); - assertEquals(src.s1, dst.s1); - assertEquals(src.s2, dst.s2); - } - - @Test - public void testPackConvert02() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicCodeGenPacker - .create(StringFieldClass.class); - Template tmpl = DynamicCodeGenTemplate.create(StringFieldClass.class); - - StringFieldClass src = new StringFieldClass(); - src.s1 = "muga"; - src.s2 = "nishizawa"; - packer.pack(new Packer(out), src); - - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - StringFieldClass dst = (StringFieldClass) tmpl.unpack(new Unpacker(in)); - assertEquals(src.s1, dst.s1); - assertEquals(src.s2, dst.s2); - } -} diff --git a/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java b/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java deleted file mode 100644 index 7e0baccd..00000000 --- a/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java +++ /dev/null @@ -1,703 +0,0 @@ -package org.msgpack.util.codegen; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import junit.framework.TestCase; - -import org.junit.Test; -import org.msgpack.MessagePackObject; -import org.msgpack.MessageUnpackable; -import org.msgpack.Packer; -import org.msgpack.Unpacker; -import org.msgpack.util.codegen.MessagePackUnpackable; -import org.msgpack.util.codegen.PackUnpackUtil; -import org.msgpack.util.codegen.DynamicCodeGenException; - -public class TestMessagePackUnpackable extends TestCase { - - @Test - public void testPrimitiveTypeFields01() throws Exception { - PrimitiveTypeFieldsClass src = (PrimitiveTypeFieldsClass) PackUnpackUtil - .newEnhancedInstance(PrimitiveTypeFieldsClass.class); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) PackUnpackUtil - .newEnhancedInstance(PrimitiveTypeFieldsClass.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - } - - @Test - public void testPrimitiveTypeFields02() throws Exception { - PrimitiveTypeFieldsClass src = (PrimitiveTypeFieldsClass) PackUnpackUtil - .newEnhancedInstance(PrimitiveTypeFieldsClass.class); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) PackUnpackUtil - .initEnhancedInstance(mpo, PrimitiveTypeFieldsClass.class); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertFalse(it.hasNext()); - } - - @MessagePackUnpackable - public static class PrimitiveTypeFieldsClass { - public byte f0; - public short f1; - public int f2; - public long f3; - public float f4; - public double f5; - public boolean f6; - - public PrimitiveTypeFieldsClass() { - } - } - - @Test - public void testGeneralReferenceTypeFieldsClass01() throws Exception { - GeneralReferenceTypeFieldsClass src = (GeneralReferenceTypeFieldsClass) PackUnpackUtil - .newEnhancedInstance(GeneralReferenceTypeFieldsClass.class); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) PackUnpackUtil - .newEnhancedInstance(GeneralReferenceTypeFieldsClass.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - } - - @Test - public void testGeneralReferenceTypeFieldsClass02() throws Exception { - GeneralReferenceTypeFieldsClass src = (GeneralReferenceTypeFieldsClass) PackUnpackUtil - .newEnhancedInstance(GeneralReferenceTypeFieldsClass.class); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) PackUnpackUtil - .initEnhancedInstance(mpo, - GeneralReferenceTypeFieldsClass.class); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - assertFalse(it.hasNext()); - } - - @MessagePackUnpackable - public static class GeneralReferenceTypeFieldsClass { - public Byte f0; - public Short f1; - public Integer f2; - public Long f3; - public Float f4; - public Double f5; - public Boolean f6; - public BigInteger f7; - public String f8; - public byte[] f9; - - public GeneralReferenceTypeFieldsClass() { - } - } - - public void testListTypes01() throws Exception { - SampleListTypes src = (SampleListTypes) PackUnpackUtil - .newEnhancedInstance(SampleListTypes.class); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - SampleListTypes dst = (SampleListTypes) PackUnpackUtil - .newEnhancedInstance(SampleListTypes.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - } - - public void testListTypes02() throws Exception { - SampleListTypes src = (SampleListTypes) PackUnpackUtil - .newEnhancedInstance(SampleListTypes.class); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleListTypes dst = (SampleListTypes) PackUnpackUtil - .initEnhancedInstance(mpo, SampleListTypes.class); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - assertFalse(it.hasNext()); - } - - @MessagePackUnpackable - public static class SampleListTypes { - public List f0; - public List f1; - public List f2; - - public SampleListTypes() { - } - } - - public void testMapTypes01() throws Exception { - SampleMapTypes src = (SampleMapTypes) PackUnpackUtil - .newEnhancedInstance(SampleMapTypes.class); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - SampleMapTypes dst = (SampleMapTypes) PackUnpackUtil - .newEnhancedInstance(SampleMapTypes.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - } - - public void testMapTypes02() throws Exception { - SampleMapTypes src = (SampleMapTypes) PackUnpackUtil - .newEnhancedInstance(SampleMapTypes.class); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleMapTypes dst = (SampleMapTypes) PackUnpackUtil - .initEnhancedInstance(mpo, SampleMapTypes.class); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - assertFalse(it.hasNext()); - } - - @MessagePackUnpackable - public static class SampleMapTypes { - public Map f0; - public Map f1; - public Map f2; - - public SampleMapTypes() { - } - } - - @Test - public void testDefaultConstructorModifiers() throws Exception { - try { - PackUnpackUtil.newEnhancedInstance(NoDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil - .newEnhancedInstance(PrivateDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil - .newEnhancedInstance(ProtectedDefaultConstructorClass.class); - assertTrue(true); - } catch (DynamicCodeGenException e) { - fail(); - } - assertTrue(true); - try { - PackUnpackUtil - .newEnhancedInstance(PackageDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @MessagePackUnpackable - public static class NoDefaultConstructorClass { - public NoDefaultConstructorClass(int i) { - } - } - - @MessagePackUnpackable - public static class PrivateDefaultConstructorClass { - private PrivateDefaultConstructorClass() { - } - } - - @MessagePackUnpackable - public static class ProtectedDefaultConstructorClass { - protected ProtectedDefaultConstructorClass() { - } - } - - @MessagePackUnpackable - public static class PackageDefaultConstructorClass { - PackageDefaultConstructorClass() { - } - } - - @Test - public void testClassModifiers() throws Exception { - try { - PackUnpackUtil.newEnhancedInstance(PrivateModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(ProtectedModifierClass.class); - assertTrue(true); - } catch (DynamicCodeGenException e) { - fail(); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(PackageModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @MessagePackUnpackable - private static class PrivateModifierClass { - } - - @MessagePackUnpackable - protected static class ProtectedModifierClass { - protected ProtectedModifierClass() { - } - } - - @MessagePackUnpackable - static class PackageModifierClass { - } - - @Test - public void testFinalClassAndAbstractClass() throws Exception { - try { - PackUnpackUtil.newEnhancedInstance(FinalModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(AbstractModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @MessagePackUnpackable - public final static class FinalModifierClass { - } - - @MessagePackUnpackable - public abstract static class AbstractModifierClass { - } - - @Test - public void testInterfaceAndEnumType() throws Exception { - try { - PackUnpackUtil.newEnhancedInstance(SampleInterface.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(SampleEnum.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @MessagePackUnpackable - public interface SampleInterface { - } - - @MessagePackUnpackable - public enum SampleEnum { - } - - @Test - public void testFieldModifiers01() throws Exception { - FieldModifiersClass src = (FieldModifiersClass) PackUnpackUtil - .newEnhancedInstance(FieldModifiersClass.class); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - FieldModifiersClass dst = (FieldModifiersClass) PackUnpackUtil - .newEnhancedInstance(FieldModifiersClass.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 == dst.f3); - assertTrue(src.f4 != dst.f4); - } - - @Test - public void testFieldModifiers02() throws Exception { - FieldModifiersClass src = (FieldModifiersClass) PackUnpackUtil - .newEnhancedInstance(FieldModifiersClass.class); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - FieldModifiersClass dst = (FieldModifiersClass) PackUnpackUtil - .initEnhancedInstance(mpo, FieldModifiersClass.class); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 == dst.f3); - assertTrue(src.f4 != dst.f4); - assertFalse(it.hasNext()); - } - - @MessagePackUnpackable - public static class FieldModifiersClass { - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public FieldModifiersClass() { - } - } - - @Test - public void testNestedAnnotatedFieldClass01() throws Exception { - NestedClass src2 = (NestedClass) PackUnpackUtil - .newEnhancedInstance(NestedClass.class); - BaseClass src = (BaseClass) PackUnpackUtil - .newEnhancedInstance(BaseClass.class); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - BaseClass dst = (BaseClass) PackUnpackUtil - .newEnhancedInstance(BaseClass.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - assertTrue(src.f0 == dst.f0); - assertTrue(src2.f2 == dst.f1.f2); - } - - @Test - public void testNestedAnnotatedFieldClass02() throws Exception { - NestedClass src2 = (NestedClass) PackUnpackUtil - .newEnhancedInstance(NestedClass.class); - BaseClass src = (BaseClass) PackUnpackUtil - .newEnhancedInstance(BaseClass.class); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - BaseClass dst = (BaseClass) PackUnpackUtil.initEnhancedInstance(mpo, - BaseClass.class); - assertTrue(src.f0 == dst.f0); - assertTrue(src2.f2 == dst.f1.f2); - assertFalse(it.hasNext()); - } - - @MessagePackUnpackable - public static class BaseClass { - public int f0; - public NestedClass f1; - - public BaseClass() { - } - } - - @MessagePackUnpackable - public static class NestedClass { - public int f2; - - public NestedClass() { - } - } - - @Test - public void testExtendedClass01() throws Exception { - SampleSubClass src = (SampleSubClass) PackUnpackUtil - .newEnhancedInstance(SampleSubClass.class); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f8 = 8; - src.f9 = 9; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - SampleSubClass dst = (SampleSubClass) PackUnpackUtil - .newEnhancedInstance(SampleSubClass.class); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - pac.unpack((MessageUnpackable) dst); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 == dst.f3); - assertTrue(src.f4 != dst.f4); - assertTrue(src.f5 == dst.f5); - assertTrue(src.f6 == dst.f6); - assertTrue(src.f8 == dst.f8); - assertTrue(src.f9 != dst.f9); - } - - @Test - public void testExtendedClass02() throws Exception { - SampleSubClass src = (SampleSubClass) PackUnpackUtil - .newEnhancedInstance(SampleSubClass.class); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f8 = 8; - src.f9 = 9; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleSubClass dst = (SampleSubClass) PackUnpackUtil - .initEnhancedInstance(mpo, SampleSubClass.class); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 == dst.f3); - assertTrue(src.f4 != dst.f4); - assertTrue(src.f5 == dst.f5); - assertTrue(src.f6 == dst.f6); - assertTrue(src.f8 == dst.f8); - assertTrue(src.f9 != dst.f9); - assertFalse(it.hasNext()); - } - - @MessagePackUnpackable - public static class SampleSubClass extends SampleSuperClass { - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public SampleSubClass() { - } - } - - public static class SampleSuperClass { - public int f5; - public final int f6 = 2; - private int f7; - protected int f8; - int f9; - - public SampleSuperClass() { - } - } -}