From 2736b88dd569cc0e11c9ea18a917ba4dfc1a095e Mon Sep 17 00:00:00 2001 From: Muga Nishizawa Date: Mon, 27 Sep 2010 17:55:48 +0900 Subject: edit Packer and Unpacker classes, and move org.msgpack.util.annotation.*.java to org.msgpack.util.codegen.*.java --- .../src/main/java/org/msgpack/CustomConverter.java | 15 +- java/src/main/java/org/msgpack/CustomMessage.java | 11 +- java/src/main/java/org/msgpack/CustomUnpacker.java | 16 +- .../main/java/org/msgpack/MessageConverter.java | 4 +- java/src/main/java/org/msgpack/Packer.java | 19 +- java/src/main/java/org/msgpack/Unpacker.java | 26 +- .../util/annotation/MessagePackOptional.java | 12 - .../util/annotation/MessagePackRequired.java | 12 - .../util/annotation/MessagePackUnpackable.java | 11 - .../msgpack/util/annotation/PackUnpackUtil.java | 1372 -------------------- .../util/annotation/PackUnpackUtilException.java | 12 - .../org/msgpack/util/codegen/BasicConstants.java | 160 +++ .../java/org/msgpack/util/codegen/Constants.java | 7 + .../org/msgpack/util/codegen/DynamicCodeGen.java | 232 ++++ .../msgpack/util/codegen/DynamicCodeGenBase.java | 189 +++ .../util/codegen/DynamicCodeGenException.java | 12 + .../msgpack/util/codegen/DynamicCodeGenPacker.java | 18 + .../util/codegen/DynamicCodeGenTemplate.java | 17 + .../msgpack/util/codegen/MessagePackOptional.java | 12 + .../msgpack/util/codegen/MessagePackRequired.java | 12 + .../util/codegen/MessagePackUnpackable.java | 11 + .../org/msgpack/util/codegen/PackUnpackUtil.java | 1372 ++++++++++++++++++++ .../util/annotation/TestMessagePackUnpackable.java | 700 ---------- .../util/codegen/TestDynamicCodeGenPacker.java | 51 + .../util/codegen/TestMessagePackUnpackable.java | 703 ++++++++++ 25 files changed, 2849 insertions(+), 2157 deletions(-) delete mode 100644 java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java delete mode 100644 java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java delete mode 100644 java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java delete mode 100644 java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java 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 create mode 100644 java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java create mode 100644 java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java delete mode 100644 java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java create mode 100644 java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java create mode 100644 java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java (limited to 'java/src') diff --git a/java/src/main/java/org/msgpack/CustomConverter.java b/java/src/main/java/org/msgpack/CustomConverter.java index 4351464..abbc88a 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 f87898c..53f8323 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 b6047b8..b45292b 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 8ad60ae..5e5f437 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 b4526cd..9ea4ea2 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 4e39748..add3312 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/MessagePackOptional.java b/java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java deleted file mode 100644 index a565292..0000000 --- a/java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.msgpack.util.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/util/annotation/MessagePackRequired.java b/java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java deleted file mode 100644 index 03e50cf..0000000 --- a/java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.msgpack.util.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/annotation/MessagePackUnpackable.java b/java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java deleted file mode 100644 index 77f6e6d..0000000 --- a/java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.msgpack.util.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 MessagePackUnpackable { -} diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java deleted file mode 100644 index 0aeb6d8..0000000 --- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java +++ /dev/null @@ -1,1372 +0,0 @@ -package org.msgpack.util.annotation; - -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 PackUnpackUtilException( - "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 PackUnpackUtilException( - "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 (PackUnpackUtilException 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 PackUnpackUtilException("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 PackUnpackUtilException(e.getMessage(), e); - } catch (CannotCompileException e) { - throw new PackUnpackUtilException(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 PackUnpackUtilException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new PackUnpackUtilException(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)); - } -} 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 df3af05..0000000 --- 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 0000000..53a8a4c --- /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 0000000..ddeef31 --- /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 0000000..9f63242 --- /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 0000000..24ae579 --- /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 0000000..1877ed5 --- /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 0000000..2a014b8 --- /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 0000000..1e12f2e --- /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/codegen/MessagePackOptional.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java new file mode 100644 index 0000000..736c2ed --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..a0c956f --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..e5aff40 --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java @@ -0,0 +1,11 @@ +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 new file mode 100644 index 0000000..2062ee4 --- /dev/null +++ b/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java @@ -0,0 +1,1372 @@ +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)); + } +} diff --git a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java b/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java deleted file mode 100644 index 08c4fa8..0000000 --- a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java +++ /dev/null @@ -1,700 +0,0 @@ -package org.msgpack.util.annotation; - -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; - -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 (PackUnpackUtilException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil - .newEnhancedInstance(PrivateDefaultConstructorClass.class); - fail(); - } catch (PackUnpackUtilException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil - .newEnhancedInstance(ProtectedDefaultConstructorClass.class); - assertTrue(true); - } catch (PackUnpackUtilException e) { - fail(); - } - assertTrue(true); - try { - PackUnpackUtil - .newEnhancedInstance(PackageDefaultConstructorClass.class); - fail(); - } catch (PackUnpackUtilException 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 (PackUnpackUtilException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(ProtectedModifierClass.class); - assertTrue(true); - } catch (PackUnpackUtilException e) { - fail(); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(PackageModifierClass.class); - fail(); - } catch (PackUnpackUtilException 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 (PackUnpackUtilException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(AbstractModifierClass.class); - fail(); - } catch (PackUnpackUtilException 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 (PackUnpackUtilException e) { - assertTrue(true); - } - assertTrue(true); - try { - PackUnpackUtil.newEnhancedInstance(SampleEnum.class); - fail(); - } catch (PackUnpackUtilException 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() { - } - } -} 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 0000000..d4e9c16 --- /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/codegen/TestMessagePackUnpackable.java b/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java new file mode 100644 index 0000000..7e0bacc --- /dev/null +++ b/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java @@ -0,0 +1,703 @@ +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() { + } + } +} -- cgit v1.2.1