mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-31 16:04:22 +02:00
java: adds a test program of the DynamicCodeGen class for packing and unpacking an object that has a field anntated by @MessagePackMessage
This commit is contained in:
parent
92ddb37ed3
commit
7f7f5253f2
@ -29,7 +29,7 @@ public class CustomMessage {
|
|||||||
CustomConverter.register(target, tmpl);
|
CustomConverter.register(target, tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isAnnotated(Class<?> target, Class<? extends Annotation> with) {
|
public static boolean isAnnotated(Class<?> target, Class<? extends Annotation> with) {
|
||||||
return target.getAnnotation(with) != null;
|
return target.getAnnotation(with) != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ import javassist.CtNewMethod;
|
|||||||
import javassist.NotFoundException;
|
import javassist.NotFoundException;
|
||||||
|
|
||||||
import org.msgpack.CustomConverter;
|
import org.msgpack.CustomConverter;
|
||||||
|
import org.msgpack.CustomMessage;
|
||||||
import org.msgpack.CustomUnpacker;
|
import org.msgpack.CustomUnpacker;
|
||||||
import org.msgpack.MessageConvertable;
|
import org.msgpack.MessageConvertable;
|
||||||
import org.msgpack.MessagePackObject;
|
import org.msgpack.MessagePackObject;
|
||||||
|
import org.msgpack.MessagePackable;
|
||||||
import org.msgpack.MessagePacker;
|
import org.msgpack.MessagePacker;
|
||||||
import org.msgpack.MessageTypeException;
|
import org.msgpack.MessageTypeException;
|
||||||
import org.msgpack.MessageUnpackable;
|
import org.msgpack.MessageUnpackable;
|
||||||
@ -33,6 +35,9 @@ import org.msgpack.MessageUnpacker;
|
|||||||
import org.msgpack.Packer;
|
import org.msgpack.Packer;
|
||||||
import org.msgpack.Template;
|
import org.msgpack.Template;
|
||||||
import org.msgpack.Unpacker;
|
import org.msgpack.Unpacker;
|
||||||
|
import org.msgpack.annotation.MessagePackDelegate;
|
||||||
|
import org.msgpack.annotation.MessagePackMessage;
|
||||||
|
import org.msgpack.annotation.MessagePackOrdinalEnum;
|
||||||
|
|
||||||
public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
||||||
|
|
||||||
@ -98,11 +103,10 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
|||||||
public Class<?> generateMessageConverterClass(Class<?> origClass) {
|
public Class<?> generateMessageConverterClass(Class<?> origClass) {
|
||||||
try {
|
try {
|
||||||
String origName = origClass.getName();
|
String origName = origClass.getName();
|
||||||
String converterName = origName + POSTFIX_TYPE_NAME_CONVERTER
|
String convName = origName + POSTFIX_TYPE_NAME_CONVERTER + inc();
|
||||||
+ inc();
|
|
||||||
checkClassValidation(origClass);
|
checkClassValidation(origClass);
|
||||||
checkDefaultConstructorValidation(origClass);
|
checkDefaultConstructorValidation(origClass);
|
||||||
CtClass converterCtClass = pool.makeClass(converterName);
|
CtClass converterCtClass = pool.makeClass(convName);
|
||||||
setInterface(converterCtClass, MessageUnpacker.class);
|
setInterface(converterCtClass, MessageUnpacker.class);
|
||||||
addDefaultConstructor(converterCtClass);
|
addDefaultConstructor(converterCtClass);
|
||||||
Field[] fields = getDeclaredFields(origClass);
|
Field[] fields = getDeclaredFields(origClass);
|
||||||
@ -162,7 +166,6 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
|||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
throwConstructoValidationException(origClass);
|
throwConstructoValidationException(origClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mod = cons.getModifiers();
|
int mod = cons.getModifiers();
|
||||||
if (!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) {
|
if (!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) {
|
||||||
throwConstructoValidationException(origClass);
|
throwConstructoValidationException(origClass);
|
||||||
@ -256,6 +259,28 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void insertCodeOfPackMethodCall(StringBuilder sb, Field field) {
|
private void insertCodeOfPackMethodCall(StringBuilder sb, Field field) {
|
||||||
|
Class<?> c = field.getType();
|
||||||
|
if (c.isPrimitive() || c.equals(Boolean.class) || c.equals(Byte.class)
|
||||||
|
|| c.equals(Double.class) || c.equals(Float.class)
|
||||||
|
|| c.equals(Integer.class) || c.equals(Long.class)
|
||||||
|
|| c.equals(Short.class) || List.class.isAssignableFrom(c)
|
||||||
|
|| Map.class.isAssignableFrom(c)
|
||||||
|
|| CustomUnpacker.isRegistered(c)
|
||||||
|
|| MessagePackable.class.isAssignableFrom(c)) {
|
||||||
|
;
|
||||||
|
} else if (CustomMessage.isAnnotated(c, MessagePackMessage.class)) {
|
||||||
|
// @MessagePackMessage
|
||||||
|
MessagePacker packer = DynamicCodeGenPacker.create(c);
|
||||||
|
CustomMessage.registerPacker(c, packer);
|
||||||
|
} else if (CustomMessage.isAnnotated(c, MessagePackDelegate.class)) {
|
||||||
|
// FIXME DelegatePacker
|
||||||
|
throw new UnsupportedOperationException("not supported yet. : "
|
||||||
|
+ c.getName());
|
||||||
|
} else if (CustomMessage.isAnnotated(c, MessagePackOrdinalEnum.class)) {
|
||||||
|
// FIXME OrdinalEnumPacker
|
||||||
|
throw new UnsupportedOperationException("not supported yet. : "
|
||||||
|
+ c.getName());
|
||||||
|
}
|
||||||
StringBuilder fa = new StringBuilder();
|
StringBuilder fa = new StringBuilder();
|
||||||
insertFieldAccess(fa, VARIABLE_NAME_TARGET, field.getName());
|
insertFieldAccess(fa, VARIABLE_NAME_TARGET, field.getName());
|
||||||
insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACK,
|
insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACK,
|
||||||
@ -265,6 +290,9 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
|||||||
|
|
||||||
private void addUnpackMethod(CtClass unpackerCtClass, Class<?> c, Field[] fs)
|
private void addUnpackMethod(CtClass unpackerCtClass, Class<?> c, Field[] fs)
|
||||||
throws CannotCompileException, NotFoundException {
|
throws CannotCompileException, NotFoundException {
|
||||||
|
if (CustomMessage.isAnnotated(c, MessagePackMessage.class)) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
// Object unpack(Unpacker pac) throws IOException, MessageTypeException;
|
// Object unpack(Unpacker pac) throws IOException, MessageTypeException;
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
StringBuilder bsb = new StringBuilder();
|
StringBuilder bsb = new StringBuilder();
|
||||||
@ -324,7 +352,12 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
|||||||
insertCodeOfUnpackMethodCallForRegisteredType(sb, f, c);
|
insertCodeOfUnpackMethodCallForRegisteredType(sb, f, c);
|
||||||
} else if (MessageUnpackable.class.isAssignableFrom(c)) {
|
} else if (MessageUnpackable.class.isAssignableFrom(c)) {
|
||||||
// MessageUnpackable
|
// MessageUnpackable
|
||||||
insertCodeOfMessageUnpackCallForMsgUnpackableType(sb, f, c);
|
insertCodeOfUnpackMethodCallForMsgUnpackableType(sb, f, c);
|
||||||
|
} else if (CustomMessage.isAnnotated(c, MessagePackMessage.class)) {
|
||||||
|
// @MessagePackMessage
|
||||||
|
Template tmpl = DynamicCodeGenTemplate.create(c);
|
||||||
|
CustomMessage.registerTemplate(c, tmpl);
|
||||||
|
insertCodeOfUnpackMethodCallForRegisteredType(sb, f, c);
|
||||||
} else {
|
} else {
|
||||||
throw new MessageTypeException("unknown type: " + c.getName());
|
throw new MessageTypeException("unknown type: " + c.getName());
|
||||||
}
|
}
|
||||||
@ -532,78 +565,26 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
|||||||
|
|
||||||
private void insertCodeOfUnpackMethodCallForRegisteredType(
|
private void insertCodeOfUnpackMethodCallForRegisteredType(
|
||||||
StringBuilder sb, Field f, Class<?> c) {
|
StringBuilder sb, Field f, Class<?> c) {
|
||||||
// if (t.fi == null) { t.fi = new Foo(); }
|
// target.field = (Cast) CustomUnpacker.get(C.class).unpack(pk);
|
||||||
// sb.append(KEYWORD_IF);
|
StringBuilder mc = new StringBuilder();
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
insertTypeCast(mc, c);
|
||||||
// sb.append(CHAR_NAME_LEFT_PARENTHESIS);
|
mc.append(CustomUnpacker.class.getName());
|
||||||
// sb.append(VARIABLE_NAME_TARGET);
|
String t = mc.toString();
|
||||||
// sb.append(CHAR_NAME_DOT);
|
mc = new StringBuilder();
|
||||||
// sb.append(f.getName());
|
insertMethodCall(mc, t, METHOD_NAME_GET, new String[] { c.getName()
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
+ ".class" });
|
||||||
// sb.append(CHAR_NAME_EQUAL);
|
t = mc.toString();
|
||||||
// sb.append(CHAR_NAME_EQUAL);
|
mc = new StringBuilder();
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
insertMethodCall(mc, t, METHOD_NAME_UNPACK,
|
||||||
// sb.append(KEYWORD_NULL);
|
new String[] { VARIABLE_NAME_PK });
|
||||||
// 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(VARIABLE_NAME_TARGET);
|
|
||||||
// sb.append(CHAR_NAME_DOT);
|
|
||||||
// sb.append(f.getName());
|
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
|
||||||
// sb.append(CHAR_NAME_EQUAL);
|
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
|
||||||
// sb.append(KEYWORD_NEW);
|
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
|
||||||
// sb.append(c.getName());
|
|
||||||
// sb.append(CHAR_NAME_LEFT_PARENTHESIS);
|
|
||||||
// sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
|
|
||||||
// sb.append(CHAR_NAME_SEMICOLON);
|
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
|
||||||
// sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET);
|
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
|
||||||
|
|
||||||
// tmpl1.unpack(new Unpacker(in));
|
|
||||||
// CustomUnpacker.get(c).pack(new Packer(out), src);
|
|
||||||
sb.append(VARIABLE_NAME_TARGET);
|
sb.append(VARIABLE_NAME_TARGET);
|
||||||
sb.append(CHAR_NAME_DOT);
|
sb.append(CHAR_NAME_DOT);
|
||||||
sb.append(f.getName());
|
sb.append(f.getName());
|
||||||
sb.append(CHAR_NAME_SPACE);
|
insertValueInsertion(sb, mc.toString());
|
||||||
sb.append(CHAR_NAME_EQUAL);
|
|
||||||
sb.append(CHAR_NAME_SPACE);
|
|
||||||
sb.append(CHAR_NAME_LEFT_PARENTHESIS);
|
|
||||||
sb.append(c.getName());
|
|
||||||
sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
|
|
||||||
sb.append(CustomUnpacker.class.getName());
|
|
||||||
sb.append(CHAR_NAME_DOT);
|
|
||||||
sb.append(METHOD_NAME_GET);
|
|
||||||
sb.append(CHAR_NAME_LEFT_PARENTHESIS);
|
|
||||||
sb.append(c.getName() + ".class");
|
|
||||||
sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
|
|
||||||
sb.append(CHAR_NAME_DOT);
|
|
||||||
sb.append(METHOD_NAME_UNPACK);
|
|
||||||
sb.append(CHAR_NAME_LEFT_PARENTHESIS);
|
|
||||||
sb.append(VARIABLE_NAME_PK);
|
|
||||||
sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
|
|
||||||
insertSemicolon(sb);
|
insertSemicolon(sb);
|
||||||
//
|
|
||||||
// sb.append(VARIABLE_NAME_PK);
|
|
||||||
// sb.append(CHAR_NAME_DOT);
|
|
||||||
// sb.append(METHOD_NAME_UNPACK);
|
|
||||||
// sb.append(CHAR_NAME_LEFT_PARENTHESIS);
|
|
||||||
// sb.append(CHAR_NAME_LEFT_PARENTHESIS);
|
|
||||||
// sb.append(MessageUnpackable.class.getName());
|
|
||||||
// sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
|
|
||||||
// sb.append(VARIABLE_NAME_TARGET);
|
|
||||||
// sb.append(CHAR_NAME_DOT);
|
|
||||||
// sb.append(f.getName());
|
|
||||||
// sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
|
|
||||||
// sb.append(CHAR_NAME_SEMICOLON);
|
|
||||||
// sb.append(CHAR_NAME_SPACE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertCodeOfMessageUnpackCallForMsgUnpackableType(
|
private void insertCodeOfUnpackMethodCallForMsgUnpackableType(
|
||||||
StringBuilder sb, Field f, Class<?> c) {
|
StringBuilder sb, Field f, Class<?> c) {
|
||||||
// if (t.fi == null) { t.fi = new Foo(); }
|
// if (t.fi == null) { t.fi = new Foo(); }
|
||||||
sb.append(KEYWORD_IF);
|
sb.append(KEYWORD_IF);
|
||||||
@ -663,7 +644,7 @@ public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
|
|||||||
new Class<?>[] { MessagePackObject.class },
|
new Class<?>[] { MessagePackObject.class },
|
||||||
new String[] { VARIABLE_NAME_MPO },
|
new String[] { VARIABLE_NAME_MPO },
|
||||||
new Class<?>[] { MessageTypeException.class }, bsb.toString());
|
new Class<?>[] { MessageTypeException.class }, bsb.toString());
|
||||||
//System.out.println("convert method: " + sb.toString());
|
// System.out.println("convert method: " + sb.toString());
|
||||||
CtMethod newCtMethod = CtNewMethod.make(sb.toString(), tmplCtClass);
|
CtMethod newCtMethod = CtNewMethod.make(sb.toString(), tmplCtClass);
|
||||||
tmplCtClass.addMethod(newCtMethod);
|
tmplCtClass.addMethod(newCtMethod);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import org.msgpack.MessagePacker;
|
|||||||
import org.msgpack.Packer;
|
import org.msgpack.Packer;
|
||||||
import org.msgpack.Template;
|
import org.msgpack.Template;
|
||||||
import org.msgpack.Unpacker;
|
import org.msgpack.Unpacker;
|
||||||
|
import org.msgpack.annotation.MessagePackMessage;
|
||||||
|
|
||||||
public class TestDynamicCodeGenPackerConverter extends TestCase {
|
public class TestDynamicCodeGenPackerConverter extends TestCase {
|
||||||
|
|
||||||
@ -534,6 +535,44 @@ public class TestDynamicCodeGenPackerConverter extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMessagePackMessageFieldClass() throws Exception {
|
||||||
|
BaseClass2 src = new BaseClass2();
|
||||||
|
MessagePackMessageClass2 src2 = new MessagePackMessageClass2();
|
||||||
|
src.f0 = 0;
|
||||||
|
src2.f2 = 2;
|
||||||
|
src.f1 = src2;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
MessagePacker packer = DynamicCodeGenPacker.create(BaseClass2.class);
|
||||||
|
packer.pack(new Packer(out), src);
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
Unpacker pac = new Unpacker(in);
|
||||||
|
Iterator<MessagePackObject> it = pac.iterator();
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
MessagePackObject mpo = it.next();
|
||||||
|
Template tmpl = DynamicCodeGenTemplate.create(BaseClass2.class);
|
||||||
|
BaseClass2 dst = (BaseClass2) tmpl.convert(mpo);
|
||||||
|
assertTrue(src.f0 == dst.f0);
|
||||||
|
assertTrue(src.f1.f2 == dst.f1.f2);
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BaseClass2 {
|
||||||
|
public int f0;
|
||||||
|
public MessagePackMessageClass2 f1;
|
||||||
|
|
||||||
|
public BaseClass2() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MessagePackMessage
|
||||||
|
public static class MessagePackMessageClass2 {
|
||||||
|
public int f2;
|
||||||
|
|
||||||
|
public MessagePackMessageClass2() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExtendedClass() throws Exception {
|
public void testExtendedClass() throws Exception {
|
||||||
SampleSubClass src = new SampleSubClass();
|
SampleSubClass src = new SampleSubClass();
|
||||||
@ -581,6 +620,7 @@ public class TestDynamicCodeGenPackerConverter extends TestCase {
|
|||||||
public static class SampleSuperClass {
|
public static class SampleSuperClass {
|
||||||
public int f5;
|
public int f5;
|
||||||
public final int f6 = 2;
|
public final int f6 = 2;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private int f7;
|
private int f7;
|
||||||
protected int f8;
|
protected int f8;
|
||||||
int f9;
|
int f9;
|
||||||
|
@ -17,6 +17,7 @@ import org.msgpack.MessagePacker;
|
|||||||
import org.msgpack.Packer;
|
import org.msgpack.Packer;
|
||||||
import org.msgpack.Template;
|
import org.msgpack.Template;
|
||||||
import org.msgpack.Unpacker;
|
import org.msgpack.Unpacker;
|
||||||
|
import org.msgpack.annotation.MessagePackMessage;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -504,6 +505,39 @@ public class TestDynamicCodeGenPackerUnpacker extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMessagePackMessageFieldClass() throws Exception {
|
||||||
|
BaseClass2 src = new BaseClass2();
|
||||||
|
MessagePackMessageClass2 src2 = new MessagePackMessageClass2();
|
||||||
|
src.f0 = 0;
|
||||||
|
src2.f2 = 2;
|
||||||
|
src.f1 = src2;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
MessagePacker packer = DynamicCodeGenPacker.create(BaseClass2.class);
|
||||||
|
packer.pack(new Packer(out), src);
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
Template tmpl = DynamicCodeGenTemplate.create(BaseClass2.class);
|
||||||
|
BaseClass2 dst = (BaseClass2) tmpl.unpack(new Unpacker(in));
|
||||||
|
assertTrue(src.f0 == dst.f0);
|
||||||
|
assertTrue(src.f1.f2 == dst.f1.f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BaseClass2 {
|
||||||
|
public int f0;
|
||||||
|
public MessagePackMessageClass2 f1;
|
||||||
|
|
||||||
|
public BaseClass2() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MessagePackMessage
|
||||||
|
public static class MessagePackMessageClass2 {
|
||||||
|
public int f2;
|
||||||
|
|
||||||
|
public MessagePackMessageClass2() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExtendedClass() throws Exception {
|
public void testExtendedClass() throws Exception {
|
||||||
SampleSubClass src = new SampleSubClass();
|
SampleSubClass src = new SampleSubClass();
|
||||||
@ -546,6 +580,7 @@ public class TestDynamicCodeGenPackerUnpacker extends TestCase {
|
|||||||
public static class SampleSuperClass {
|
public static class SampleSuperClass {
|
||||||
public int f5;
|
public int f5;
|
||||||
public final int f6 = 2;
|
public final int f6 = 2;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private int f7;
|
private int f7;
|
||||||
protected int f8;
|
protected int f8;
|
||||||
int f9;
|
int f9;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user