diff --git a/java/msgpack.iml b/java/msgpack.iml new file mode 100644 index 00000000..3a6d962d --- /dev/null +++ b/java/msgpack.iml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/java/pom.xml b/java/pom.xml index c8a19b3a..39149d20 100755 --- a/java/pom.xml +++ b/java/pom.xml @@ -81,6 +81,20 @@ scm:git://github.com/msgpack/msgpack.git + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + @@ -132,12 +146,14 @@ msgpack.org Repository at msgpack.org file://${project.build.directory}/website/maven2/ + true msgpack.org Repository at msgpack.org file://${project.build.directory}/website/maven2/ + diff --git a/java/src/main/java/org/msgpack/MessagePack.java b/java/src/main/java/org/msgpack/MessagePack.java index 4bb5d2ca..a650b797 100644 --- a/java/src/main/java/org/msgpack/MessagePack.java +++ b/java/src/main/java/org/msgpack/MessagePack.java @@ -22,7 +22,6 @@ import java.io.InputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.msgpack.template.TemplateRegistry; -import org.msgpack.template.TemplateBuilder; import org.msgpack.template.TemplateClassWriter; import org.msgpack.template.FieldList; diff --git a/java/src/main/java/org/msgpack/annotation/Ignore.java b/java/src/main/java/org/msgpack/annotation/Ignore.java index 96a37bb6..e052e58a 100644 --- a/java/src/main/java/org/msgpack/annotation/Ignore.java +++ b/java/src/main/java/org/msgpack/annotation/Ignore.java @@ -22,7 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Ignore { } diff --git a/java/src/main/java/org/msgpack/annotation/Index.java b/java/src/main/java/org/msgpack/annotation/Index.java index 7c1b6598..d3b2181f 100644 --- a/java/src/main/java/org/msgpack/annotation/Index.java +++ b/java/src/main/java/org/msgpack/annotation/Index.java @@ -22,7 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Index { int value(); diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackBeans.java b/java/src/main/java/org/msgpack/annotation/MessagePackBeans.java new file mode 100644 index 00000000..bff1b0d2 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/MessagePackBeans.java @@ -0,0 +1,35 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.msgpack.template.FieldOption; + +/** + * Annotation for java beans class + * @author takeshita + * + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MessagePackBeans { + FieldOption value() default FieldOption.DEFAULT; +} diff --git a/java/src/main/java/org/msgpack/annotation/Nullable.java b/java/src/main/java/org/msgpack/annotation/Nullable.java index e6893e72..56aea89e 100644 --- a/java/src/main/java/org/msgpack/annotation/Nullable.java +++ b/java/src/main/java/org/msgpack/annotation/Nullable.java @@ -22,7 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Nullable { } diff --git a/java/src/main/java/org/msgpack/annotation/Optional.java b/java/src/main/java/org/msgpack/annotation/Optional.java index 7894f881..a137ec86 100644 --- a/java/src/main/java/org/msgpack/annotation/Optional.java +++ b/java/src/main/java/org/msgpack/annotation/Optional.java @@ -22,7 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Optional { } diff --git a/java/src/main/java/org/msgpack/annotation/Required.java b/java/src/main/java/org/msgpack/annotation/Required.java index 16311085..de1d816b 100644 --- a/java/src/main/java/org/msgpack/annotation/Required.java +++ b/java/src/main/java/org/msgpack/annotation/Required.java @@ -22,7 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Required { } diff --git a/java/src/main/java/org/msgpack/template/BeansFieldEntry.java b/java/src/main/java/org/msgpack/template/BeansFieldEntry.java new file mode 100644 index 00000000..5d5ff816 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/BeansFieldEntry.java @@ -0,0 +1,143 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.*; +import org.msgpack.*; + +/** + * Field entry for Java beans property. + * @author takeshita + * + */ +public class BeansFieldEntry implements IFieldEntry { + + PropertyDescriptor desc; + FieldOption option = FieldOption.DEFAULT; + + public BeansFieldEntry(PropertyDescriptor desc) { + this.desc = desc; + } + + @Override + public String getName() { + return desc.getDisplayName(); + } + public String getGetterName(){ + return desc.getReadMethod().getName(); + } + public String getSetterName(){ + return desc.getWriteMethod().getName(); + } + + @Override + public Class getType() { + return desc.getPropertyType(); + } + + @Override + public String getJavaTypeName() { + Class type = getType(); + if(type.isArray()) { + return arrayTypeToString(type); + } else { + return type.getName(); + } + } + static String arrayTypeToString(Class type) { + int dim = 1; + Class baseType = type.getComponentType(); + while(baseType.isArray()) { + baseType = baseType.getComponentType(); + dim += 1; + } + StringBuilder sb = new StringBuilder(); + sb.append(baseType.getName()); + for (int i = 0; i < dim; ++i) { + sb.append("[]"); + } + return sb.toString(); + } + + @Override + public Type getGenericType() { + return desc.getReadMethod().getGenericReturnType(); + } + + @Override + public FieldOption getOption() { + return option; + } + public void setOption(FieldOption option){ + this.option = option; + } + + @Override + public boolean isAvailable() { + return option != FieldOption.IGNORE; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#isRequired() + */ + @Override + public boolean isRequired() { + return option == FieldOption.REQUIRED; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#isOptional() + */ + @Override + public boolean isOptional() { + return option == FieldOption.OPTIONAL; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#isNullable() + */ + @Override + public boolean isNullable() { + return option == FieldOption.NULLABLE; + } + + public Object get(Object target){ + try { + return desc.getReadMethod().invoke(target); + } catch (IllegalArgumentException e) { + throw new MessageTypeException(e); + } catch (IllegalAccessException e) { + throw new MessageTypeException(e); + } catch (InvocationTargetException e) { + throw new MessageTypeException(e); + } + } + public void set(Object target , Object value){ + try { + desc.getWriteMethod().invoke(target, value); + } catch (IllegalArgumentException e) { + throw new MessageTypeException(e); + } catch (IllegalAccessException e) { + throw new MessageTypeException(e); + } catch (InvocationTargetException e) { + throw new MessageTypeException(e); + } + } + +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/template/BeansFieldEntryReader.java b/java/src/main/java/org/msgpack/template/BeansFieldEntryReader.java new file mode 100644 index 00000000..9d3039b2 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/BeansFieldEntryReader.java @@ -0,0 +1,188 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.annotation.Annotation; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +import org.msgpack.annotation.Ignore; +import org.msgpack.annotation.Index; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.Nullable; +import org.msgpack.annotation.Optional; +import org.msgpack.annotation.Required; + +/** + * List up Java beans property methods. + * @author takeshita + * + */ +public class BeansFieldEntryReader implements IFieldEntryReader{ + + + public IFieldEntry[] convertFieldEntries(Class targetClass, FieldList flist) throws NoSuchFieldException { + List src = flist.getList(); + FieldEntry[] result = new FieldEntry[src.size()]; + for(int i=0; i < src.size(); i++) { + FieldList.Entry s = src.get(i); + if(s.isAvailable()) { + result[i] = new FieldEntry(targetClass.getDeclaredField(s.getName()), s.getOption()); + } else { + result[i] = new FieldEntry(); + } + } + return result; + } + + @Override + public IFieldEntry[] readFieldEntries(Class targetClass, + FieldOption implicitOption) { + BeanInfo desc; + try { + desc = Introspector.getBeanInfo(targetClass); + } catch (IntrospectionException e1) { + throw new TemplateBuildException("Class must be java beans class:" + targetClass.getName()); + } + + PropertyDescriptor[] props = desc.getPropertyDescriptors(); + ArrayList list = new ArrayList(); + for(int i = 0;i < props.length;i++){ + PropertyDescriptor pd = props[i]; + if(!isIgnoreProp(pd)){ + list.add(pd); + } + } + props = new PropertyDescriptor[list.size()]; + list.toArray(props); + + BeansFieldEntry[] entries = new BeansFieldEntry[props.length]; + for(int i = 0;i < props.length;i++){ + PropertyDescriptor p = props[i]; + int index = readPropIndex(p); + if(index >= 0){ + if(entries[index] != null){ + throw new TemplateBuildException("duplicated index: "+index); + } + if(index >= entries.length){ + throw new TemplateBuildException("invalid index: "+index); + } + entries[index] = new BeansFieldEntry(p); + props[index] = null; + } + } + int insertIndex = 0; + for(int i = 0;i < props.length;i++){ + PropertyDescriptor p = props[i]; + if(p != null){ + while(entries[insertIndex] != null){ + insertIndex++; + } + entries[insertIndex] = new BeansFieldEntry(p); + } + + } + for(int i = 0;i < entries.length;i++){ + BeansFieldEntry e = entries[i]; + FieldOption op = readPropOption(e.desc, implicitOption); + e.setOption(op); + } + return entries; + } + + public FieldOption readImplicitFieldOption(Class targetClass) { + MessagePackMessage a = targetClass.getAnnotation(MessagePackMessage.class); + if(a == null) { + return FieldOption.DEFAULT; + } + return a.value(); + } + + + private FieldOption readPropOption(PropertyDescriptor desc, FieldOption implicitOption) { + + FieldOption forGetter = readMethodOption(desc.getReadMethod()); + if(forGetter != FieldOption.DEFAULT){ + return forGetter; + } + FieldOption forSetter = readMethodOption(desc.getWriteMethod()); + if(forSetter != FieldOption.DEFAULT){ + return forSetter; + }else{ + return implicitOption; + } + + } + private FieldOption readMethodOption(Method method){ + + if(isAnnotated(method, Ignore.class)) { + return FieldOption.IGNORE; + } else if(isAnnotated(method, Required.class)) { + return FieldOption.REQUIRED; + } else if(isAnnotated(method, Optional.class)) { + return FieldOption.OPTIONAL; + } else if(isAnnotated(method, Nullable.class)) { + if(method.getDeclaringClass().isPrimitive()) { + return FieldOption.REQUIRED; + } else { + return FieldOption.NULLABLE; + } + } + return FieldOption.DEFAULT; + } + + private int readPropIndex(PropertyDescriptor desc) { + + int forGetter = readMethodIndex(desc.getReadMethod()); + if(forGetter >= 0){ + return forGetter; + } + int forSetter = readMethodIndex(desc.getWriteMethod()); + return forSetter; + } + private int readMethodIndex(Method method){ + Index a = method.getAnnotation(Index.class); + if(a == null) { + return -1; + } else { + return a.value(); + } + } + + private boolean isAnnotated(AccessibleObject ao, Class with) { + return ao.getAnnotation(with) != null; + } + boolean isIgnoreProp(PropertyDescriptor desc){ + if(desc == null)return true; + Method getter = desc.getReadMethod(); + Method setter = desc.getWriteMethod(); + return getter == null || + setter == null || + !Modifier.isPublic(getter.getModifiers()) || + !Modifier.isPublic(setter.getModifiers()) || + isAnnotated(getter,Ignore.class) || + isAnnotated(setter, Ignore.class); + } +} diff --git a/java/src/main/java/org/msgpack/template/BeansReflectionTemplateBuilder.java b/java/src/main/java/org/msgpack/template/BeansReflectionTemplateBuilder.java new file mode 100644 index 00000000..e97531f7 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/BeansReflectionTemplateBuilder.java @@ -0,0 +1,338 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.msgpack.AbstractTemplate; +import org.msgpack.MessagePackObject; +import org.msgpack.MessageTypeException; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.template.ReflectionTemplateBuilder.BooleanFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.ByteFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.DoubleFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.FloatFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.IntFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.LongFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.NullFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.ObjectFieldEntry; +import org.msgpack.template.ReflectionTemplateBuilder.ShortFieldEntry; +import org.msgpack.template.builder.CustomTemplateBuilder; + +/** + * Class for building java reflection template builder for java beans class. + * @author takeshita + * + */ +public class BeansReflectionTemplateBuilder extends CustomTemplateBuilder{ + + IFieldEntryReader reader = new BeansFieldEntryReader(); + + public BeansReflectionTemplateBuilder(){} + + @Override + public IFieldEntryReader getFieldEntryReader(){ + return reader; + } + + static class ReflectionEntry{ + BeansFieldEntry entry; + public ReflectionEntry(BeansFieldEntry entry){ + this.entry = entry; + } + + public void pack(Object value , Packer packer) throws IOException{ + packer.pack(value); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + entry.set(target, obj.convert(entry.getType())); + } + + public void unpack(Object target, Unpacker unpacker) throws IOException, MessageTypeException, IllegalAccessException { + entry.set(target, unpacker.unpack(entry.getType())); + } + + public void setNull(Object target){ + entry.set(target, null); + } + + public boolean isRequired(){ + return entry.isRequired(); + } + public boolean isNullable(){ + return entry.isNullable(); + } + public boolean isAvailable(){ + return entry.isAvailable(); + } + public boolean isOptional(){ + return entry.isOptional(); + } + public Object get(Object target){ + return entry.get(target); + } + + } + + static class ObjectFieldEntry extends ReflectionEntry{ + Template template; + public ObjectFieldEntry(BeansFieldEntry entry,Template template){ + super(entry); + this.template = template; + } + public void pack(Object value , Packer packer) throws IOException{ + template.pack(packer,value); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + Class type = (Class)entry.getType(); + Object fieldReference = entry.get(target); + Object valueReference = template.convert(obj, fieldReference); + if(valueReference != fieldReference) { + entry.set(target, valueReference); + } + } + + public void unpack(Object target, Unpacker unpacker) throws IOException, MessageTypeException, IllegalAccessException { + + Class type = (Class)entry.getType(); + Object fieldReference = entry.get(target); + Object valueReference = template.unpack(unpacker, fieldReference); + if(valueReference != fieldReference) { + entry.set(target, valueReference); + } + } + } + + static class BeansReflectionTemplate extends AbstractTemplate{ + + Class targetClass; + ReflectionEntry[] entries = null; + protected int minimumArrayLength; + + public BeansReflectionTemplate( + Class targetClass, + ReflectionEntry[] entries){ + this.targetClass = targetClass; + this.entries = entries; + this.minimumArrayLength = 0; + for(int i=0; i < entries.length; i++) { + ReflectionEntry e = entries[i]; + if(e.isRequired() || e.isNullable()) { + this.minimumArrayLength = i+1; + } + } + } + + + @Override + public void pack(Packer pk, Object target) throws IOException { + + pk.packArray(entries.length); + for(ReflectionEntry e : entries){ + if(!e.isAvailable()){ + pk.packNil(); + continue; + } + Object obj = e.get(target); + if(obj == null) { + if(!e.isNullable() && !e.isOptional()) { + throw new MessageTypeException(); + } + pk.packNil(); + } else { + pk.pack(obj); + } + } + + } + @Override + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + try { + if(to == null) { + to = targetClass.newInstance(); + } + + int length = pac.unpackArray(); + if(length < minimumArrayLength) { + throw new MessageTypeException(); + } + + int i; + for(i=0; i < minimumArrayLength; i++) { + ReflectionEntry e = entries[i]; + if(!e.isAvailable()) { + pac.unpackObject(); + continue; + } + + if(pac.tryUnpackNull()) { + if(e.isRequired()) { + // Required + nil => exception + throw new MessageTypeException(); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + e.setNull(to); + } + } else { + e.unpack(to,pac); + //e.set(to, pac.unpack(e.getType())); + } + } + + int max = length < entries.length ? length : entries.length; + for(; i < max; i++) { + ReflectionEntry e = entries[i]; + if(!e.isAvailable()) { + pac.unpackObject(); + continue; + } + + if(pac.tryUnpackNull()) { + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + } else { + e.unpack(to, pac); + //e.set(to, pac.unpack(e.getType())); + } + } + + // latter entries are all Optional + nil => keep default value + + for(; i < length; i++) { + pac.unpackObject(); + } + + return to; + + } catch (MessageTypeException e) { + throw e; + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new MessageTypeException(e); + } + } + + @Override + public Object convert(MessagePackObject from, Object to) + throws MessageTypeException { + try { + if(to == null) { + to = targetClass.newInstance(); + } + + MessagePackObject[] array = from.asArray(); + int length = array.length; + if(length < minimumArrayLength) { + throw new MessageTypeException(); + } + + int i; + for(i=0; i < minimumArrayLength; i++) { + ReflectionEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + MessagePackObject obj = array[i]; + if(obj.isNil()) { + if(e.isRequired()) { + // Required + nil => exception + throw new MessageTypeException(); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + e.setNull(to); + //e.set(to,null); + } + } else { + e.convert(to, obj); + //e.set(to, from.convert(e.getType())); + } + } + + int max = length < entries.length ? length : entries.length; + for(; i < max; i++) { + ReflectionEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + MessagePackObject obj = array[i]; + if(obj.isNil()) { + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + } else { + e.convert(to, obj); + //e.set(to, obj.convert(e.getType())); + } + } + + // latter entries are all Optional + nil => keep default value + + return to; + + } catch (MessageTypeException e) { + throw e; + } catch (Exception e) { + throw new MessageTypeException(e); + } + } + + } + + + @Override + public Template buildTemplate(Class targetClass, IFieldEntry[] entries) { + + ReflectionEntry[] refEntries = new ReflectionEntry[entries.length]; + for(int i = 0;i < entries.length;i++){ + BeansFieldEntry e = (BeansFieldEntry)entries[i]; + Class type = e.getType(); + if(type.equals(boolean.class)) { + refEntries[i] = new ReflectionEntry(e); + } else if(type.equals(byte.class)) { + refEntries[i] = new ReflectionEntry(e); + } else if(type.equals(short.class)) { + refEntries[i] = new ReflectionEntry(e); + } else if(type.equals(int.class)) { + refEntries[i] = new ReflectionEntry(e); + } else if(type.equals(long.class)) { + refEntries[i] = new ReflectionEntry(e); + } else if(type.equals(float.class)) { + refEntries[i] = new ReflectionEntry(e); + } else if(type.equals(double.class)) { + refEntries[i] = new ReflectionEntry(e); + } else { + Template tmpl = TemplateRegistry.lookup(e.getGenericType(), true); + refEntries[i] = new ObjectFieldEntry(e, tmpl); + } + } + + + return new BeansReflectionTemplate(targetClass,refEntries); + } + + +} diff --git a/java/src/main/java/org/msgpack/template/FieldEntry.java b/java/src/main/java/org/msgpack/template/FieldEntry.java new file mode 100644 index 00000000..a8437403 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/FieldEntry.java @@ -0,0 +1,143 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.io.IOException; +import java.lang.reflect.*; +import java.lang.annotation.*; +import java.util.List; +import java.util.ArrayList; +import java.util.EnumSet; +import org.msgpack.*; +import org.msgpack.annotation.*; + +public class FieldEntry implements IFieldEntry { + private Field field; + private FieldOption option; + + public FieldEntry() { + this.field = null; + this.option = FieldOption.IGNORE; + } + + public FieldEntry(FieldEntry e) { + this.field = e.field; + this.option = e.option; + } + + public FieldEntry(Field field, FieldOption option) { + this.field = field; + this.option = option; + } + + public Field getField() { + return field; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#getName() + */ + @Override + public String getName() { + return field.getName(); + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#getType() + */ + @Override + public Class getType() { + return field.getType(); + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#getJavaTypeName() + */ + @Override + public String getJavaTypeName() { + Class type = field.getType(); + if(type.isArray()) { + return arrayTypeToString(type); + } else { + return type.getName(); + } + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#getGenericType() + */ + @Override + public Type getGenericType() { + return field.getGenericType(); + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#getOption() + */ + @Override + public FieldOption getOption() { + return option; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#isAvailable() + */ + @Override + public boolean isAvailable() { + return option != FieldOption.IGNORE; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#isRequired() + */ + @Override + public boolean isRequired() { + return option == FieldOption.REQUIRED; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#isOptional() + */ + @Override + public boolean isOptional() { + return option == FieldOption.OPTIONAL; + } + + /* (non-Javadoc) + * @see org.msgpack.template.IFieldEntry#isNullable() + */ + @Override + public boolean isNullable() { + return option == FieldOption.NULLABLE; + } + + static String arrayTypeToString(Class type) { + int dim = 1; + Class baseType = type.getComponentType(); + while(baseType.isArray()) { + baseType = baseType.getComponentType(); + dim += 1; + } + StringBuilder sb = new StringBuilder(); + sb.append(baseType.getName()); + for (int i = 0; i < dim; ++i) { + sb.append("[]"); + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/template/FieldEntryReader.java b/java/src/main/java/org/msgpack/template/FieldEntryReader.java new file mode 100644 index 00000000..81114a51 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/FieldEntryReader.java @@ -0,0 +1,182 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +import org.msgpack.annotation.Ignore; +import org.msgpack.annotation.Index; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.Nullable; +import org.msgpack.annotation.Optional; +import org.msgpack.annotation.Required; + +public class FieldEntryReader implements IFieldEntryReader{ + + + public IFieldEntry[] convertFieldEntries(Class targetClass, FieldList flist) throws NoSuchFieldException { + List src = flist.getList(); + FieldEntry[] result = new FieldEntry[src.size()]; + for(int i=0; i < src.size(); i++) { + FieldList.Entry s = src.get(i); + if(s.isAvailable()) { + result[i] = new FieldEntry(targetClass.getDeclaredField(s.getName()), s.getOption()); + } else { + result[i] = new FieldEntry(); + } + } + return result; + } + + @Override + public IFieldEntry[] readFieldEntries(Class targetClass, + FieldOption implicitOption) { + Field[] allFields = readAllFields(targetClass); + + /* index: + * @Index(0) int field_a; // 0 + * int field_b; // 1 + * @Index(3) int field_c; // 3 + * int field_d; // 4 + * @Index(2) int field_e; // 2 + * int field_f; // 5 + */ + List indexed = new ArrayList(); + int maxIndex = -1; + for(Field f : allFields) { + FieldOption opt = readFieldOption(f, implicitOption); + if(opt == FieldOption.IGNORE) { + // skip + continue; + } + + int index = readFieldIndex(f, maxIndex); + + if(indexed.size() > index && indexed.get(index) != null) { + throw new TemplateBuildException("duplicated index: "+index); + } + if(index < 0) { + throw new TemplateBuildException("invalid index: "+index); + } + + while(indexed.size() <= index) { + indexed.add(null); + } + indexed.set(index, new FieldEntry(f, opt)); + + if(maxIndex < index) { + maxIndex = index; + } + } + + FieldEntry[] result = new FieldEntry[maxIndex+1]; + for(int i=0; i < indexed.size(); i++) { + FieldEntry e = indexed.get(i); + if(e == null) { + result[i] = new FieldEntry(); + } else { + result[i] = e; + } + } + + return result; + } + + public FieldOption readImplicitFieldOption(Class targetClass) { + MessagePackMessage a = targetClass.getAnnotation(MessagePackMessage.class); + if(a == null) { + return FieldOption.DEFAULT; + } + return a.value(); + } + + private Field[] readAllFields(Class targetClass) { + // order: [fields of super class, ..., fields of this class] + List succ = new ArrayList(); + int total = 0; + for(Class c = targetClass; c != Object.class; c = c.getSuperclass()) { + Field[] fields = c.getDeclaredFields(); + total += fields.length; + succ.add(fields); + } + Field[] result = new Field[total]; + int off = 0; + for(int i=succ.size()-1; i >= 0; i--) { + Field[] fields = succ.get(i); + System.arraycopy(fields, 0, result, off, fields.length); + off += fields.length; + } + return result; + } + + private static FieldOption readFieldOption(Field field, FieldOption implicitOption) { + int mod = field.getModifiers(); + if(Modifier.isStatic(mod) || Modifier.isFinal(mod)) { + return FieldOption.IGNORE; + } + + if(isAnnotated(field, Ignore.class)) { + return FieldOption.IGNORE; + } else if(isAnnotated(field, Required.class)) { + return FieldOption.REQUIRED; + } else if(isAnnotated(field, Optional.class)) { + return FieldOption.OPTIONAL; + } else if(isAnnotated(field, Nullable.class)) { + if(field.getDeclaringClass().isPrimitive()) { + return FieldOption.REQUIRED; + } else { + return FieldOption.NULLABLE; + } + } + + if(implicitOption != FieldOption.DEFAULT) { + return implicitOption; + } + + // default mode: + // transient : Ignore + // public : Required + // others : Ignore + if(Modifier.isTransient(mod)) { + return FieldOption.IGNORE; + } else if(Modifier.isPublic(mod)) { + return FieldOption.REQUIRED; + } else { + return FieldOption.IGNORE; + } + } + + private static int readFieldIndex(Field field, int maxIndex) { + Index a = field.getAnnotation(Index.class); + if(a == null) { + return maxIndex + 1; + } else { + return a.value(); + } + } + + private static boolean isAnnotated(AccessibleObject ao, Class with) { + return ao.getAnnotation(with) != null; + } + +} diff --git a/java/src/main/java/org/msgpack/template/FieldList.java b/java/src/main/java/org/msgpack/template/FieldList.java index daf59f5b..a5b141d9 100644 --- a/java/src/main/java/org/msgpack/template/FieldList.java +++ b/java/src/main/java/org/msgpack/template/FieldList.java @@ -43,19 +43,19 @@ public class FieldList { return option; } - boolean isAvailable() { + public boolean isAvailable() { return this.option != FieldOption.IGNORE; } - boolean isRequired() { + public boolean isRequired() { return this.option == FieldOption.REQUIRED; } - boolean isOptional() { + public boolean isOptional() { return this.option == FieldOption.OPTIONAL; } - boolean isNullable() { + public boolean isNullable() { return this.option == FieldOption.NULLABLE; } } @@ -89,7 +89,7 @@ public class FieldList { } } - List getList() { + public List getList() { return list; } } diff --git a/java/src/main/java/org/msgpack/template/IFieldEntry.java b/java/src/main/java/org/msgpack/template/IFieldEntry.java new file mode 100644 index 00000000..23700c67 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/IFieldEntry.java @@ -0,0 +1,42 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +import java.lang.reflect.Type; + +public interface IFieldEntry { + + public abstract String getName(); + + public abstract Class getType(); + + public abstract String getJavaTypeName(); + + public abstract Type getGenericType(); + + public abstract FieldOption getOption(); + + public abstract boolean isAvailable(); + + public abstract boolean isRequired(); + + public abstract boolean isOptional(); + + public abstract boolean isNullable(); + +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/template/IFieldEntryReader.java b/java/src/main/java/org/msgpack/template/IFieldEntryReader.java new file mode 100644 index 00000000..fe3024a7 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/IFieldEntryReader.java @@ -0,0 +1,25 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template; + +public interface IFieldEntryReader { + + public IFieldEntry[] convertFieldEntries(Class targetClass, FieldList flist) throws NoSuchFieldException; + public IFieldEntry[] readFieldEntries(Class targetClass, FieldOption implicitOption); + public FieldOption readImplicitFieldOption(Class targetClass) ; +} diff --git a/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java b/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java index a4ef98ff..7366c653 100644 --- a/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java +++ b/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java @@ -17,28 +17,21 @@ // package org.msgpack.template; -import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Type; +import java.lang.Thread; import org.msgpack.*; -import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; -import javassist.CtConstructor; -import javassist.CtMethod; -import javassist.CtNewConstructor; -import javassist.CtNewMethod; import javassist.LoaderClassPath; import javassist.NotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.msgpack.template.builder.CustomTemplateBuilder; +import org.msgpack.template.javassist.*; -public class JavassistTemplateBuilder extends TemplateBuilder { +public class JavassistTemplateBuilder extends CustomTemplateBuilder { private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class); private static JavassistTemplateBuilder instance; @@ -54,12 +47,33 @@ public class JavassistTemplateBuilder extends TemplateBuilder { getInstance().pool.appendClassPath(new LoaderClassPath(cl)); } - private JavassistTemplateBuilder() { + + IFieldEntryReader reader = new FieldEntryReader(); + + public void setFieldEntryReader(IFieldEntryReader reader){ + this.reader = reader; + } + + BuildContextFactory buildContextFactory = new BuildContextFactory() { + + @Override + public BuildContextBase createBuildContext(JavassistTemplateBuilder builder) { + + return new BuildContext(builder); + } + }; + public void setBuildContextFactory(BuildContextFactory factory){ + this.buildContextFactory = factory; + } + + + + public JavassistTemplateBuilder() { pool = new ClassPool(); boolean appended = false; ClassLoader cl = null; try { - Thread.currentThread().getContextClassLoader(); + cl = Thread.currentThread().getContextClassLoader(); if (cl != null) { pool.appendClassPath(new LoaderClassPath(cl)); appended = true; @@ -80,556 +94,38 @@ public class JavassistTemplateBuilder extends TemplateBuilder { pool.appendSystemPath(); } } + /** + * Replace FieldEntryReader and BuilderContextFactory. + * you can replace field entry rules and generated codes easily. + * @param reader + * @param buildContextFactory + */ + public JavassistTemplateBuilder(IFieldEntryReader reader,BuildContextFactory buildContextFactory ){ + this(); + this.reader = reader; + this.buildContextFactory = buildContextFactory; + } + protected ClassPool pool; private int seqId = 0; - CtClass makeCtClass(String className) { + public CtClass makeCtClass(String className) { return pool.makeClass(className); } - CtClass getCtClass(String className) throws NotFoundException { + public CtClass getCtClass(String className) throws NotFoundException { return pool.get(className); } - int nextSeqId() { + public int nextSeqId() { return seqId++; } - private static abstract class BuildContextBase { - protected JavassistTemplateBuilder director; - - protected String tmplName; - - protected CtClass tmplCtClass; - - protected abstract void setSuperClass() throws CannotCompileException, NotFoundException; - - protected abstract void buildConstructor() throws CannotCompileException, NotFoundException; - - protected void buildMethodInit() { } - - protected abstract String buildPackMethodBody(); - - protected abstract String buildUnpackMethodBody(); - - protected abstract String buildConvertMethodBody(); - - protected abstract Template buildInstance(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException; - - public BuildContextBase(JavassistTemplateBuilder director) { - this.director = director; - } - - protected void write(final String className, final String directoryName) { - try { - reset(className, false); - buildClass(); - buildConstructor(); - buildMethodInit(); - buildPackMethod(); - buildUnpackMethod(); - buildConvertMethod(); - writeClassFile(directoryName); - } catch (Exception e) { - String code = getBuiltString(); - if(code != null) { - LOG.error("builder: " + code, e); - throw new TemplateBuildException("cannot compile: " + code, e); - } else { - throw new TemplateBuildException(e); - } - } - } - protected void writeClassFile(final String directoryName) throws CannotCompileException, IOException { - tmplCtClass.writeFile(directoryName); - } - - protected Template build(final String className) { - try { - reset(className, true); - buildClass(); - buildConstructor(); - buildMethodInit(); - buildPackMethod(); - buildUnpackMethod(); - buildConvertMethod(); - return buildInstance(createClass()); - } catch (Exception e) { - String code = getBuiltString(); - if(code != null) { - LOG.error("builder: " + code, e); - throw new TemplateBuildException("cannot compile: " + code, e); - } else { - throw new TemplateBuildException(e); - } - } - } - - protected void reset(String className, boolean isBuilt) { - if (isBuilt) { - tmplName = className + "_$$_Template" + director.nextSeqId(); - } else { - tmplName = className + "_$$_Template"; - } - tmplCtClass = director.makeCtClass(tmplName); - } - - protected void buildClass() throws CannotCompileException, NotFoundException { - setSuperClass(); - tmplCtClass.addInterface(director.getCtClass(Template.class.getName())); - } - - protected void buildPackMethod() throws CannotCompileException, NotFoundException { - String mbody = buildPackMethodBody(); - int mod = javassist.Modifier.PUBLIC; - CtClass returnType = CtClass.voidType; - String mname = "pack"; - CtClass[] paramTypes = new CtClass[] { - director.getCtClass(Packer.class.getName()), - director.getCtClass(Object.class.getName()) - }; - CtClass[] exceptTypes = new CtClass[] { - director.getCtClass(IOException.class.getName()) - }; - CtMethod newCtMethod = CtNewMethod.make( - mod, returnType, mname, - paramTypes, exceptTypes, mbody, tmplCtClass); - tmplCtClass.addMethod(newCtMethod); - } - - protected void buildUnpackMethod() throws CannotCompileException, NotFoundException { - String mbody = buildUnpackMethodBody(); - int mod = javassist.Modifier.PUBLIC; - CtClass returnType = director.getCtClass(Object.class.getName()); - String mname = "unpack"; - CtClass[] paramTypes = new CtClass[] { - director.getCtClass(Unpacker.class.getName()), - director.getCtClass(Object.class.getName()) - }; - CtClass[] exceptTypes = new CtClass[] { - director.getCtClass(MessageTypeException.class.getName()) - }; - CtMethod newCtMethod = CtNewMethod.make( - mod, returnType, mname, - paramTypes, exceptTypes, mbody, tmplCtClass); - tmplCtClass.addMethod(newCtMethod); - } - - protected void buildConvertMethod() throws CannotCompileException, NotFoundException { - String mbody = buildConvertMethodBody(); - int mod = javassist.Modifier.PUBLIC; - CtClass returnType = director.getCtClass(Object.class.getName()); - String mname = "convert"; - CtClass[] paramTypes = new CtClass[] { - director.getCtClass(MessagePackObject.class.getName()), - director.getCtClass(Object.class.getName()) - }; - CtClass[] exceptTypes = new CtClass[] { - director.getCtClass(MessageTypeException.class.getName()) - }; - CtMethod newCtMethod = CtNewMethod.make( - mod, returnType, mname, - paramTypes, exceptTypes, mbody, tmplCtClass); - tmplCtClass.addMethod(newCtMethod); - } - - protected Class createClass() throws CannotCompileException { - return (Class) tmplCtClass.toClass(null, null); - } - - protected StringBuilder stringBuilder = null; - - protected void resetStringBuilder() { - stringBuilder = new StringBuilder(); - } - - protected void buildString(String str) { - stringBuilder.append(str); - } - - protected void buildString(String format, Object... args) { - stringBuilder.append(String.format(format, args)); - } - - protected String getBuiltString() { - if(stringBuilder == null) { - return null; - } - return stringBuilder.toString(); - } - } - - public static abstract class JavassistTemplate extends AbstractTemplate { - public Class targetClass; - public Template[] templates; - - public JavassistTemplate(Class targetClass, Template[] templates) { - this.targetClass = targetClass; - this.templates = templates; - } - } - - private static class BuildContext extends BuildContextBase { - protected FieldEntry[] entries; - protected Class origClass; - protected String origName; - protected Template[] templates; - protected int minimumArrayLength; - - public BuildContext(JavassistTemplateBuilder director) { - super(director); - } - - public void writeTemplateClass(Class targetClass, FieldEntry[] entries, - Template[] templates, final String directoryName) { - this.entries = entries; - this.templates = templates; - this.origClass = targetClass; - this.origName = this.origClass.getName(); - write(this.origName, directoryName); - } - - public Template buildTemplate(Class targetClass, FieldEntry[] entries, Template[] templates) { - this.entries = entries; - this.templates = templates; - this.origClass = targetClass; - this.origName = this.origClass.getName(); - return build(this.origName); - } - - protected void setSuperClass() throws CannotCompileException, NotFoundException { - this.tmplCtClass.setSuperclass( - director.getCtClass(JavassistTemplate.class.getName())); - } - - protected void buildConstructor() throws CannotCompileException, NotFoundException { - // Constructor(Class targetClass, Template[] templates) - CtConstructor newCtCons = CtNewConstructor.make( - new CtClass[] { - director.getCtClass(Class.class.getName()), - director.getCtClass(Template.class.getName()+"[]") - }, - new CtClass[0], - this.tmplCtClass); - this.tmplCtClass.addConstructor(newCtCons); - } - - protected Template buildInstance(Class targetClass, Class tmplClass, Template[] tmpls) { - try { - Constructor cons = tmplClass.getConstructor(new Class[] { - Class.class, - Template[].class - }); - Object tmpl = cons.newInstance(new Object[] { - targetClass, - tmpls - }); - return (Template)tmpl; - } catch (Exception e) { - throw new TemplateBuildException(e); - } - } - - protected Template buildInstance(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - Constructor cons = c.getConstructor(new Class[] { - Class.class, - Template[].class - }); - Object tmpl = cons.newInstance(new Object[] { - this.origClass, - this.templates - }); - return (Template)tmpl; - } - - protected void buildMethodInit() { - this.minimumArrayLength = 0; - for(int i=0; i < entries.length; i++) { - FieldEntry e = entries[i]; - if(e.isRequired() || e.isNullable()) { - this.minimumArrayLength = i+1; - } - } - } - - protected String buildPackMethodBody() { - resetStringBuilder(); - buildString("{"); - buildString("%s _$$_t = (%s)$2;", this.origName, this.origName); - buildString("$1.packArray(%d);", entries.length); - for(int i=0; i < entries.length; i++) { - FieldEntry e = entries[i]; - if(!e.isAvailable()) { - buildString("$1.packNil();"); - continue; - } - Class type = e.getType(); - if(type.isPrimitive()) { - buildString("$1.%s(_$$_t.%s);", primitivePackName(type), e.getName()); - } else { - buildString("if(_$$_t.%s == null) {", e.getName()); - if(!e.isNullable() && !e.isOptional()) { - buildString("throw new %s();", MessageTypeException.class.getName()); - } else { - buildString("$1.packNil();"); - } - buildString("} else {"); - buildString(" this.templates[%d].pack($1, _$$_t.%s);", i, e.getName()); - buildString("}"); - } - } - buildString("}"); - return getBuiltString(); - } - - protected String buildUnpackMethodBody() { - resetStringBuilder(); - buildString("{ "); - - buildString("%s _$$_t;", this.origName); - buildString("if($2 == null) {"); - buildString(" _$$_t = new %s();", this.origName); - buildString("} else {"); - buildString(" _$$_t = (%s)$2;", this.origName); - buildString("}"); - - buildString("int length = $1.unpackArray();"); - buildString("if(length < %d) {", this.minimumArrayLength); - buildString(" throw new %s();", MessageTypeException.class.getName()); - buildString("}"); - - int i; - for(i=0; i < this.minimumArrayLength; i++) { - FieldEntry e = entries[i]; - if(!e.isAvailable()) { - buildString("$1.unpackObject();"); - continue; - } - - buildString("if($1.tryUnpackNull()) {"); - if(e.isRequired()) { - // Required + nil => exception - buildString("throw new %s();", MessageTypeException.class.getName()); - } else if(e.isOptional()) { - // Optional + nil => keep default value - } else { // Nullable - // Nullable + nil => set null - buildString("_$$_t.%s = null;", e.getName()); - } - buildString("} else {"); - Class type = e.getType(); - if(type.isPrimitive()) { - buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type)); - } else { - buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); - } - buildString("}"); - } - - for(; i < entries.length; i++) { - buildString("if(length <= %d) { return _$$_t; }", i); - - FieldEntry e = entries[i]; - if(!e.isAvailable()) { - buildString("$1.unpackObject();"); - continue; - } - - buildString("if($1.tryUnpackNull()) {"); - // this is Optional field becaue i >= minimumArrayLength - // Optional + nil => keep default value - buildString("} else {"); - Class type = e.getType(); - if(type.isPrimitive()) { - buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type)); - } else { - buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); - } - buildString("}"); - } - - // latter entries are all Optional + nil => keep default value - - buildString("for(int i=%d; i < length; i++) {", i); - buildString(" $1.unpackObject();"); - buildString("}"); - - buildString("return _$$_t;"); - - buildString("}"); - return getBuiltString(); - } - - protected String buildConvertMethodBody() { - resetStringBuilder(); - buildString("{ "); - - buildString("%s _$$_t;", this.origName); - buildString("if($2 == null) {"); - buildString(" _$$_t = new %s();", this.origName); - buildString("} else {"); - buildString(" _$$_t = (%s)$2;", this.origName); - buildString("}"); - - buildString("%s[] array = $1.asArray();", MessagePackObject.class.getName()); - buildString("int length = array.length;"); - buildString("if(length < %d) {", this.minimumArrayLength); - buildString(" throw new %s();", MessageTypeException.class.getName()); - buildString("}"); - - buildString("%s obj;", MessagePackObject.class.getName()); - - int i; - for(i=0; i < this.minimumArrayLength; i++) { - FieldEntry e = entries[i]; - if(!e.isAvailable()) { - continue; - } - - buildString("obj = array[%d];", i); - buildString("if(obj.isNil()) {"); - if(e.isRequired()) { - // Required + nil => exception - buildString("throw new %s();", MessageTypeException.class.getName()); - } else if(e.isOptional()) { - // Optional + nil => keep default value - } else { // Nullable - // Nullable + nil => set null - buildString("_$$_t.%s = null;", e.getName()); - } - buildString("} else {"); - Class type = e.getType(); - if(type.isPrimitive()) { - buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type)); - } else { - buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); - } - buildString("}"); - } - - for(; i < entries.length; i++) { - buildString("if(length <= %d) { return _$$_t; }", i); - - FieldEntry e = entries[i]; - if(!e.isAvailable()) { - continue; - } - - buildString("obj = array[%d];", i); - buildString("if(obj.isNil()) {"); - // this is Optional field becaue i >= minimumArrayLength - // Optional + nil => keep default value - buildString("} else {"); - Class type = e.getType(); - if(type.isPrimitive()) { - buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type)); - } else { - buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); - } - buildString("}"); - } - - // latter entries are all Optional + nil => keep default value - - buildString("return _$$_t;"); - - buildString("}"); - return getBuiltString(); - } - - protected String primitivePackName(Class type) { - if(type == boolean.class) { - return "packBoolean"; - } else if(type == byte.class) { - return "packByte"; - } else if(type == short.class) { - return "packShort"; - } else if(type == int.class) { - return "packInt"; - } else if(type == long.class) { - return "packLong"; - } else if(type == float.class) { - return "packFloat"; - } else if(type == double.class) { - return "packDouble"; - } - return null; - } - - protected String primitiveUnpackName(Class type) { - if(type == boolean.class) { - return "unpackBoolean"; - } else if(type == byte.class) { - return "unpackByte"; - } else if(type == short.class) { - return "unpackShort"; - } else if(type == int.class) { - return "unpackInt"; - } else if(type == long.class) { - return "unpackLong"; - } else if(type == float.class) { - return "unpackFloat"; - } else if(type == double.class) { - return "unpackDouble"; - } - return null; - } - - protected String primitiveConvertName(Class type) { - if(type == boolean.class) { - return "asBoolean"; - } else if(type == byte.class) { - return "asByte"; - } else if(type == short.class) { - return "asShort"; - } else if(type == int.class) { - return "asInt"; - } else if(type == long.class) { - return "asLong"; - } else if(type == float.class) { - return "asFloat"; - } else if(type == double.class) { - return "asDouble"; - } - return null; - } - } @Override - public Class loadTemplateClass(Class targetClass) { - String tmplClassName = targetClass.getName() + "_$$_Template"; - ClassLoader cl = this.getClass().getClassLoader();// TODO - try { - return cl.loadClass(tmplClassName); - } catch (ClassNotFoundException e) { - LOG.debug("Tmplate class not found: " + tmplClassName); - return null; - } - } - - @Override - public Template initializeTemplate(Class targetClass, Class tmplClass, FieldEntry[] entries) { - Template[] tmpls = toTemplates(entries); - BuildContext bc = new BuildContext(this); - return bc.buildInstance(targetClass, tmplClass, tmpls); - } - - @Override - public void writeTemplateClass(Class targetClass, FieldEntry[] entries, String directoryName) { - Template[] tmpls = toTemplates(entries); - BuildContext bc = new BuildContext(this); - bc.writeTemplateClass(targetClass, entries, tmpls, directoryName); - } - - public Template buildTemplate(Class targetClass, FieldEntry[] entries) { - Template[] tmpls = toTemplates(entries); - BuildContext bc = new BuildContext(this); - return bc.buildTemplate(targetClass, entries, tmpls); - } - - private static Template[] toTemplates(FieldEntry[] from) { + public Template buildTemplate(Class targetClass, IFieldEntry[] entries) { // FIXME private / packagefields //for(FieldEntry e : entries) { // Field f = e.getField(); @@ -639,9 +135,9 @@ public class JavassistTemplateBuilder extends TemplateBuilder { // } //} - Template[] tmpls = new Template[from.length]; - for(int i=0; i < from.length; i++) { - FieldEntry e = from[i]; + Template[] tmpls = new Template[entries.length]; + for(int i=0; i < entries.length; i++) { + IFieldEntry e = entries[i]; if(!e.isAvailable()) { tmpls[i] = null; } else { @@ -649,9 +145,22 @@ public class JavassistTemplateBuilder extends TemplateBuilder { tmpls[i] = tmpl; } } - return tmpls; + + BuildContextBase bc = getBuildContextFacotry().createBuildContext(this); + return bc.buildTemplate(targetClass, entries, tmpls); } + @Override + public IFieldEntryReader getFieldEntryReader() { + return reader; + } + + public BuildContextFactory getBuildContextFacotry() { + return buildContextFactory; + } + + + /* static class JavassistOrdinalEnumTemplate extends ReflectionTemplateBuilder.ReflectionOrdinalEnumTemplate { JavassistOrdinalEnumTemplate(Enum[] entries) { super(entries); @@ -704,6 +213,6 @@ public class JavassistTemplateBuilder extends TemplateBuilder { Class componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass(); return new ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); } - } + }*/ } diff --git a/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java b/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java index e48bceac..057d500c 100644 --- a/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java +++ b/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java @@ -18,21 +18,21 @@ package org.msgpack.template; import java.io.IOException; -import java.lang.reflect.*; -import java.util.Map; -import java.util.HashMap; -import org.msgpack.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; -public class ReflectionTemplateBuilder extends TemplateBuilder { - private static ReflectionTemplateBuilder instance; - public synchronized static ReflectionTemplateBuilder getInstance() { - if(instance == null) { - instance = new ReflectionTemplateBuilder(); - } - return instance; +import org.msgpack.*; +import org.msgpack.template.builder.CustomTemplateBuilder; + +public class ReflectionTemplateBuilder extends CustomTemplateBuilder { + IFieldEntryReader reader = new FieldEntryReader(); + + @Override + public IFieldEntryReader getFieldEntryReader(){ + return reader; } - private ReflectionTemplateBuilder() { + public ReflectionTemplateBuilder() { } static abstract class ReflectionFieldEntry extends FieldEntry { @@ -373,25 +373,10 @@ public class ReflectionTemplateBuilder extends TemplateBuilder { } } - @Override - public Class loadTemplateClass(Class targetClass) { - throw new UnsupportedOperationException("Not supported by reflection-based template builder"); - } - - @Override - public Template initializeTemplate(Class targetClass, Class tmplClass, FieldEntry[] entries) { - throw new UnsupportedOperationException("Not supported by reflection-based template builder"); - } - - @Override - public void writeTemplateClass(Class targetClass, FieldEntry[] entries, - String directoryName) { - throw new UnsupportedOperationException("Not supported by reflection-based template builder"); - } - - public Template buildTemplate(Class targetClass, FieldEntry[] entries) { - for(FieldEntry e : entries) { - Field f = e.getField(); + public Template buildTemplate(Class targetClass, IFieldEntry[] entries) { + // TODO Now it is simply cast. + for(IFieldEntry e : entries) { + Field f = ((FieldEntry)e).getField(); int mod = f.getModifiers(); if(!Modifier.isPublic(mod)) { f.setAccessible(true); @@ -400,7 +385,7 @@ public class ReflectionTemplateBuilder extends TemplateBuilder { ReflectionFieldEntry[] res = new ReflectionFieldEntry[entries.length]; for(int i=0; i < entries.length; i++) { - FieldEntry e = entries[i]; + FieldEntry e = (FieldEntry)entries[i]; Class type = e.getType(); if(!e.isAvailable()) { res[i] = new NullFieldEntry(e); @@ -426,171 +411,5 @@ public class ReflectionTemplateBuilder extends TemplateBuilder { return new ReflectionTemplate(targetClass, res); } - - static class ReflectionOrdinalEnumTemplate extends AbstractTemplate { - protected Enum[] entries; - protected Map, Integer> reverse; - - ReflectionOrdinalEnumTemplate(Enum[] entries) { - this.entries = entries; - this.reverse = new HashMap, Integer>(); - for(int i=0; i < entries.length; i++) { - this.reverse.put(entries[i], i); - } - } - - public void pack(Packer pk, Object target) throws IOException { - Integer ord = reverse.get(target); - if(ord == null) { - throw new MessageTypeException(); - } - pk.pack((int)ord); - } - - public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { - int ord = pac.unpackInt(); - if(entries.length <= ord) { - throw new MessageTypeException(); - } - return entries[ord]; - } - - public Object convert(MessagePackObject from, Object to) throws MessageTypeException { - int ord = from.asInt(); - if(entries.length <= ord) { - throw new MessageTypeException(); - } - return entries[ord]; - } - } - - @Override - public void writeOrdinalEnumTemplateClass(Class targetClass, - Enum[] entires, String directoryName) { - throw new UnsupportedOperationException("Not supported by reflection-based template builder"); - } - - public Template buildOrdinalEnumTemplate(Class targetClass, Enum[] entries) { - return new ReflectionOrdinalEnumTemplate(entries); - } - - static class ReflectionObjectArrayTemplate extends AbstractTemplate { - private Class componentClass; - private Template elementTemplate; - - public ReflectionObjectArrayTemplate(Class componentClass, Template elementTemplate) { - this.componentClass = componentClass; - this.elementTemplate = elementTemplate; - } - - public void pack(Packer pk, Object target) throws IOException { - if(!(target instanceof Object[]) || !componentClass.isAssignableFrom(target.getClass().getComponentType())) { - throw new MessageTypeException(); - } - Object[] array = (Object[])target; - int length = array.length; - pk.packArray(length); - for(int i=0; i < length; i++) { - elementTemplate.pack(pk, array[i]); - } - } - - public Object unpack(Unpacker pac, Object to) throws IOException { - int length = pac.unpackArray(); - Object[] array = (Object[])Array.newInstance(componentClass, length); - for(int i=0; i < length; i++) { - array[i] = elementTemplate.unpack(pac, null); - } - return array; - } - - public Object convert(MessagePackObject from, Object to) throws MessageTypeException { - MessagePackObject[] src = from.asArray(); - int length = src.length; - Object[] array = (Object[])Array.newInstance(componentClass, length); - for(int i=0; i < length; i++) { - array[i] = elementTemplate.convert(src[i], null); - } - return array; - } - } - - static class ReflectionMultidimentionalArrayTemplate extends AbstractTemplate { - private Class componentClass; - private Template componentTemplate; - - public ReflectionMultidimentionalArrayTemplate(Class componentClass, Template componentTemplate) { - this.componentClass = componentClass; - this.componentTemplate = componentTemplate; - } - - Class getComponentClass() { - return componentClass; - } - - public void pack(Packer pk, Object target) throws IOException { - Object[] array = (Object[])target; - int length = array.length; - pk.packArray(length); - for(int i=0; i < length; i++) { - componentTemplate.pack(pk, array[i]); - } - } - - public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { - int length = pac.unpackArray(); - Object[] array = (Object[])Array.newInstance(componentClass, length); - for(int i=0; i < length; i++) { - array[i] = componentTemplate.unpack(pac, null); - } - return array; - } - - public Object convert(MessagePackObject from, Object to) throws MessageTypeException { - MessagePackObject[] src = from.asArray(); - int length = src.length; - Object[] array = (Object[])Array.newInstance(componentClass, length); - for(int i=0; i < length; i++) { - array[i] = componentTemplate.convert(src[i], null); - } - return array; - } - } - - @Override - public void writeArrayTemplateClass(Type arrayType, Type genericBaseType, - Class baseClass, int dim, String directoryName) { - throw new UnsupportedOperationException("Not supported by reflection-based template builder"); - } - - public Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class baseClass, int dim) { - if(dim == 1) { - if(baseClass == boolean.class) { - return BooleanArrayTemplate.getInstance(); - } else if(baseClass == short.class) { - return ShortArrayTemplate.getInstance(); - } else if(baseClass == int.class) { - return IntArrayTemplate.getInstance(); - } else if(baseClass == long.class) { - return LongArrayTemplate.getInstance(); - } else if(baseClass == float.class) { - return FloatArrayTemplate.getInstance(); - } else if(baseClass == double.class) { - return DoubleArrayTemplate.getInstance(); - } else { - Template baseTemplate = TemplateRegistry.lookup(genericBaseType); - return new ReflectionObjectArrayTemplate(baseClass, baseTemplate); - } - } else if(dim == 2) { - Class componentClass = Array.newInstance(baseClass, 0).getClass(); - Template componentTemplate = buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1); - return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); - } else { - ReflectionMultidimentionalArrayTemplate componentTemplate = (ReflectionMultidimentionalArrayTemplate) - buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1); - Class componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass(); - return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); - } - } } diff --git a/java/src/main/java/org/msgpack/template/TemplateRegistry.java b/java/src/main/java/org/msgpack/template/TemplateRegistry.java index a3fe1dff..ef4d51f2 100644 --- a/java/src/main/java/org/msgpack/template/TemplateRegistry.java +++ b/java/src/main/java/org/msgpack/template/TemplateRegistry.java @@ -26,32 +26,54 @@ import java.lang.annotation.Annotation; import org.msgpack.annotation.MessagePackMessage; import org.msgpack.annotation.MessagePackDelegate; import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.CustomTemplateBuilder; +import org.msgpack.template.builder.TemplateBuilder; import org.msgpack.Template; public class TemplateRegistry { private static Map map; private static Map genericMap; + + private static BuilderSelectorRegistry builderSelectorRegistry; static { map = new HashMap(); genericMap = new HashMap(); BuiltInTemplateLoader.load(); + builderSelectorRegistry = BuilderSelectorRegistry.getInstance(); } public static void register(Class target) { // auto-detect - if(target.isEnum()) { + TemplateBuilder builder = builderSelectorRegistry.select(target); + if(builder != null){ + register(target,builder.buildTemplate(target)); + }else{ + register(target,builderSelectorRegistry.getForceBuilder().buildTemplate(target)); + } + /*if(target.isEnum()) { register(target, TemplateBuilder.buildOrdinalEnum(target)); } else { register(target, TemplateBuilder.build(target)); - } + }*/ } public static void register(Class target, FieldOption implicitOption) { - register(target, TemplateBuilder.build(target, implicitOption)); + TemplateBuilder builder = builderSelectorRegistry.select(target); + if(builder != null && builder instanceof CustomTemplateBuilder){ + register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, implicitOption)); + }else{ + throw new TemplateBuildException("cannot build template with filed option"); + } } public static void register(Class target, FieldList flist) throws NoSuchFieldException { - register(target, TemplateBuilder.build(target, flist)); + TemplateBuilder builder = builderSelectorRegistry.select(target); + if(builder != null && builder instanceof CustomTemplateBuilder){ + register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, flist)); + }else{ + throw new TemplateBuildException("cannot build template with filed list"); + } } public static synchronized void register(Type rawType, Template tmpl) { @@ -101,7 +123,7 @@ public class TemplateRegistry { return tmpl; } - if(targetType instanceof GenericArrayType) { + /*if(targetType instanceof GenericArrayType) { // GenericArrayType is not a Class tmpl = TemplateBuilder.buildArray(targetType); register(targetType, tmpl); @@ -135,7 +157,17 @@ public class TemplateRegistry { tmpl = TemplateBuilder.buildOrdinalEnum(target); register(target, tmpl); return tmpl; + }*/ + // find match TemplateBuilder + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(targetType); + if(builder != null){ + tmpl = builder.buildTemplate(targetType); + register(targetType,tmpl); + return tmpl; } + + + Class target = (Class)targetType; for(Class i : target.getInterfaces()) { tmpl = map.get(i); @@ -156,7 +188,7 @@ public class TemplateRegistry { } if(forceBuild) { - tmpl = TemplateBuilder.build(target); + tmpl = builderSelectorRegistry.getForceBuilder().buildTemplate(target); register(target, tmpl); return tmpl; } @@ -204,8 +236,5 @@ public class TemplateRegistry { return ao.getAnnotation(with) != null; } - public static void setTemplateBuilder(TemplateBuilder builder) { - TemplateBuilder.setInstance(builder); - } } diff --git a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java new file mode 100644 index 00000000..07e49dee --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java @@ -0,0 +1,190 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +import org.msgpack.AbstractTemplate; +import org.msgpack.MessagePackObject; +import org.msgpack.MessageTypeException; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.template.BooleanArrayTemplate; +import org.msgpack.template.DoubleArrayTemplate; +import org.msgpack.template.FloatArrayTemplate; +import org.msgpack.template.IFieldEntry; +import org.msgpack.template.IFieldEntryReader; +import org.msgpack.template.IntArrayTemplate; +import org.msgpack.template.LongArrayTemplate; +import org.msgpack.template.ShortArrayTemplate; +import org.msgpack.template.TemplateRegistry; + +public class ArrayTemplateBuilder extends TemplateBuilder { + + + + + static class ReflectionObjectArrayTemplate extends AbstractTemplate { + private Class componentClass; + private Template elementTemplate; + + public ReflectionObjectArrayTemplate(Class componentClass, Template elementTemplate) { + this.componentClass = componentClass; + this.elementTemplate = elementTemplate; + } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof Object[]) || !componentClass.isAssignableFrom(target.getClass().getComponentType())) { + throw new MessageTypeException(); + } + Object[] array = (Object[])target; + int length = array.length; + pk.packArray(length); + for(int i=0; i < length; i++) { + elementTemplate.pack(pk, array[i]); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException { + int length = pac.unpackArray(); + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = elementTemplate.unpack(pac, null); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + int length = src.length; + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = elementTemplate.convert(src[i], null); + } + return array; + } + } + + static class ReflectionMultidimentionalArrayTemplate extends AbstractTemplate { + private Class componentClass; + private Template componentTemplate; + + public ReflectionMultidimentionalArrayTemplate(Class componentClass, Template componentTemplate) { + this.componentClass = componentClass; + this.componentTemplate = componentTemplate; + } + + Class getComponentClass() { + return componentClass; + } + + public void pack(Packer pk, Object target) throws IOException { + Object[] array = (Object[])target; + int length = array.length; + pk.packArray(length); + for(int i=0; i < length; i++) { + componentTemplate.pack(pk, array[i]); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = componentTemplate.unpack(pac, null); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + int length = src.length; + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = componentTemplate.convert(src[i], null); + } + return array; + } + } + @Override + public Template buildTemplate(Type arrayType) { + Type baseType; + Class baseClass; + int dim = 1; + if(arrayType instanceof GenericArrayType) { + GenericArrayType type = (GenericArrayType)arrayType; + baseType = type.getGenericComponentType(); + while(baseType instanceof GenericArrayType) { + baseType = ((GenericArrayType)baseType).getGenericComponentType(); + dim += 1; + } + if(baseType instanceof ParameterizedType) { + baseClass = (Class)((ParameterizedType)baseType).getRawType(); + } else { + baseClass = (Class)baseType; + } + } else { + Class type = (Class)arrayType; + baseClass = type.getComponentType(); + while(baseClass.isArray()) { + baseClass = baseClass.getComponentType(); + dim += 1; + } + baseType = baseClass; + } + return toTemplate(arrayType, baseType, baseClass, dim); + + } + private Template toTemplate(Type arrayType, Type genericBaseType, Class baseClass, int dim) { + if(dim == 1) { + if(baseClass == boolean.class) { + return BooleanArrayTemplate.getInstance(); + } else if(baseClass == short.class) { + return ShortArrayTemplate.getInstance(); + } else if(baseClass == int.class) { + return IntArrayTemplate.getInstance(); + } else if(baseClass == long.class) { + return LongArrayTemplate.getInstance(); + } else if(baseClass == float.class) { + return FloatArrayTemplate.getInstance(); + } else if(baseClass == double.class) { + return DoubleArrayTemplate.getInstance(); + } else { + Template baseTemplate = TemplateRegistry.lookup(genericBaseType); + return new ReflectionObjectArrayTemplate(baseClass, baseTemplate); + } + } else if(dim == 2) { + Class componentClass = Array.newInstance(baseClass, 0).getClass(); + Template componentTemplate = toTemplate(arrayType, genericBaseType, baseClass, dim-1); + return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); + } else { + ReflectionMultidimentionalArrayTemplate componentTemplate = (ReflectionMultidimentionalArrayTemplate) + toTemplate(arrayType, genericBaseType, baseClass, dim-1); + Class componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass(); + return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); + } + } + +} diff --git a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilderSelector.java new file mode 100644 index 00000000..66428bef --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilderSelector.java @@ -0,0 +1,52 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Type; + +import org.msgpack.Template; + +public class ArrayTemplateBuilderSelector implements BuilderSelector { + + public static final String NAME = "ArrayTemplateBuilder"; + + @Override + public String getName(){ + return NAME; + } + + + @Override + public boolean matchType(Type targetType) { + if(targetType instanceof GenericArrayType){ + return true; + } + Class targetClass = (Class)targetType; + return targetClass.isArray(); + } + + ArrayTemplateBuilder templateBuilder = new ArrayTemplateBuilder(); + + @Override + public TemplateBuilder getTemplateBuilder(Type target) { + return templateBuilder; + } + + +} diff --git a/java/src/main/java/org/msgpack/template/builder/BuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/BuilderSelector.java new file mode 100644 index 00000000..0691612e --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/BuilderSelector.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.reflect.Type; + +/** + * Match condition for TemplateBuilder. + * @author takeshita + * + */ +public interface BuilderSelector { + + + /** + * Name of this. + * @return + */ + public String getName(); + + + public abstract boolean matchType(Type targetType); + + + public abstract TemplateBuilder getTemplateBuilder(Type targetType); + + + +} diff --git a/java/src/main/java/org/msgpack/template/builder/BuilderSelectorRegistry.java b/java/src/main/java/org/msgpack/template/builder/BuilderSelectorRegistry.java new file mode 100644 index 00000000..02d365b8 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/BuilderSelectorRegistry.java @@ -0,0 +1,230 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.reflect.Type; +import java.util.LinkedList; +import java.util.List; + +import org.msgpack.template.BeansFieldEntryReader; +import org.msgpack.template.BeansReflectionTemplateBuilder; +import org.msgpack.template.JavassistTemplateBuilder; +import org.msgpack.template.ReflectionTemplateBuilder; +import org.msgpack.template.javassist.BeansBuildContext; +import org.msgpack.template.javassist.BuildContext; +import org.msgpack.template.javassist.BuildContextBase; +import org.msgpack.template.javassist.BuildContextFactory; + +/** + * Registry for BuilderSelectors. + * You can modify BuilderSelector chain throw this class. + * + * @author takeshita + * + */ +public class BuilderSelectorRegistry { + + private static BuilderSelectorRegistry instance = new BuilderSelectorRegistry(); + static{ + initForJava(); + } + + public static BuilderSelectorRegistry getInstance(){ + return instance; + } + + TemplateBuilder forceBuilder; + + + List builderSelectors = new LinkedList(); + + private BuilderSelectorRegistry(){ + } + /** + * initialize BuilderSelectors for basic java enviroment. + */ + private static void initForJava(){ + + instance.append(new ArrayTemplateBuilderSelector()); + + if(isSupportJavassist()){ + instance.append( + new MessagePackMessageBuilderSelector( + new JavassistTemplateBuilder())); + instance.forceBuilder = new JavassistTemplateBuilder(); + + //Java beans + instance.append(new MessagePackBeansBuilderSelector( + new JavassistTemplateBuilder( + new BeansFieldEntryReader(), + new BuildContextFactory() { + @Override + public BuildContextBase createBuildContext(JavassistTemplateBuilder builder) { + return new BeansBuildContext(builder); + } + } + ))); + }else{ + instance.append( + new MessagePackMessageBuilderSelector( + new ReflectionTemplateBuilder())); + instance.forceBuilder = new ReflectionTemplateBuilder(); + + //Java beans + instance.append(new MessagePackBeansBuilderSelector( + new BeansReflectionTemplateBuilder())); + } + + instance.append(new MessagePackOrdinalEnumBuilderSelector()); + instance.append(new EnumBuilderSelector()); + } + public static boolean isSupportJavassist(){ + try { + return System.getProperty("java.vm.name").equals("Dalvik"); + } catch (Exception e) { + return true; + } + } + + /** + * Check whether same name BuilderSelector is registered. + * @param builderSelectorName + * @return + */ + public boolean contains(String builderSelectorName){ + for(BuilderSelector bs : builderSelectors){ + if(bs.getName().equals(builderSelectorName)){ + return true; + } + } + return false; + } + /** + * Append BuilderSelector to tail + * @param builderSelector + */ + public void append(BuilderSelector builderSelector){ + + if(contains(builderSelector.getName())){ + throw new RuntimeException("Duplicate BuilderSelector name:" + builderSelector.getName()); + } + this.builderSelectors.add(builderSelector); + } + /** + * Insert BuiderSelector to head + * @param builderSelector + */ + public void prepend(BuilderSelector builderSelector){ + if(contains(builderSelector.getName())){ + throw new RuntimeException("Duplicate BuilderSelector name:" + builderSelector.getName()); + } + if(builderSelectors.size() > 0){ + this.builderSelectors.add(0, builderSelector); + }else{ + this.builderSelectors.add(builderSelector); + } + } + + /** + * Insert BuilderSelector + * @param index + * @param builderSelector + */ + public void insert(int index,BuilderSelector builderSelector){ + if(contains(builderSelector.getName())){ + throw new RuntimeException("Duplicate BuilderSelector name:" + builderSelector.getName()); + } + if(builderSelectors.size() > 0){ + this.builderSelectors.add(index, builderSelector); + + }else{ + this.builderSelectors.add(builderSelector); + } + } + /** + * Replace same name BuilderSelector + * @param builderSelector + */ + public void replace(BuilderSelector builderSelector){ + String name = builderSelector.getName(); + int index = getIndex(name); + builderSelectors.add(index, builderSelector); + builderSelectors.remove(index + 1); + } + + /** + * Insert the BuilderSelector before BuilderSelector named "builderSelectorName". + * @param builderSelectorName + * @param builderSelector + */ + public void insertBefore(String builderSelectorName,BuilderSelector builderSelector){ + int index = getIndex(builderSelectorName); + + builderSelectors.add(index,builderSelector); + } + /** + * Insert the BuilderSelector after BuilderSelector named "builderSelectorName". + * @param builderSelectorName + * @param builderSelector + */ + public void insertAfter(String builderSelectorName,BuilderSelector builderSelector){ + int index = getIndex(builderSelectorName); + if(index + 1 == builderSelectors.size()){ + builderSelectors.add(builderSelector); + }else{ + builderSelectors.add(index + 1 , builderSelector); + } + } + private int getIndex(String builderSelectorName){ + int index = 0; + for(BuilderSelector bs : builderSelectors){ + if(bs.getName().equals(builderSelectorName)){ + break; + } + index++; + } + if(index >= builderSelectors.size()){ + throw new RuntimeException( + String.format("BuilderSelector named %s does not exist",builderSelectorName)); + } + return index; + } + + + public TemplateBuilder select(Type target){ + for(BuilderSelector selector : builderSelectors){ + if(selector.matchType(target)){ + return selector.getTemplateBuilder(target); + } + } + return null; + } + + public TemplateBuilder getForceBuilder() { + return forceBuilder; + } + + + public void setForceBuilder(TemplateBuilder forceBuilder) { + this.forceBuilder = forceBuilder; + } + + + + +} diff --git a/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java new file mode 100644 index 00000000..a3875388 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java @@ -0,0 +1,70 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.reflect.Type; + +import org.msgpack.Template; +import org.msgpack.template.FieldList; +import org.msgpack.template.FieldOption; +import org.msgpack.template.IFieldEntry; +import org.msgpack.template.IFieldEntryReader; +import org.msgpack.template.TemplateBuildException; +import org.msgpack.template.javassist.BuildContextFactory; + +public abstract class CustomTemplateBuilder extends TemplateBuilder { + + + public abstract IFieldEntryReader getFieldEntryReader(); + + + public abstract Template buildTemplate(Class targetClass , IFieldEntry[] entries); + + public Template buildTemplate(Class targetClass ,FieldOption implicitOption ){ + checkValidation(targetClass); + return buildTemplate(targetClass, + getFieldEntryReader().readFieldEntries(targetClass, implicitOption)); + } + public Template buildTemplate(Class targetClass, FieldList flist) throws NoSuchFieldException { + checkValidation(targetClass); + return buildTemplate(targetClass, getFieldEntryReader().convertFieldEntries(targetClass, flist)); + } + + @Override + public Template buildTemplate(Type targetType) { + Class targetClass = (Class)targetType; + IFieldEntryReader reader = getFieldEntryReader(); + FieldOption implicitOption = reader.readImplicitFieldOption(targetClass); + checkValidation(targetClass); + + IFieldEntry[] entries = reader.readFieldEntries(targetClass, implicitOption); + + return buildTemplate(targetClass,entries); + } + private void checkValidation(Class targetClass) { + if(targetClass.isInterface()) { + throw new TemplateBuildException("cannot build template of interface"); + } + if(targetClass.isArray()) { + throw new TemplateBuildException("cannot build template of array class"); + } + if(targetClass.isPrimitive()) { + throw new TemplateBuildException("cannot build template of primitive type"); + } + } +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/template/builder/EnumBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/EnumBuilderSelector.java new file mode 100644 index 00000000..959aa9ec --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/EnumBuilderSelector.java @@ -0,0 +1,43 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.reflect.Type; + +public class EnumBuilderSelector implements BuilderSelector { + + public static final String NAME = "EnumTemplateBuilder"; + + public String getName(){ + return NAME; + } + + @Override + public boolean matchType(Type targetType) { + return ((Class)targetType).isEnum(); + } + + + OrdinalEnumTemplateBuilder builder = new OrdinalEnumTemplateBuilder(); + + @Override + public TemplateBuilder getTemplateBuilder(Type targetType) { + return builder; + } + +} diff --git a/java/src/main/java/org/msgpack/template/builder/MessagePackBeansBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/MessagePackBeansBuilderSelector.java new file mode 100644 index 00000000..bec4a4f5 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/MessagePackBeansBuilderSelector.java @@ -0,0 +1,57 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import org.msgpack.annotation.MessagePackBeans; +import org.msgpack.annotation.MessagePackMessage; + +public class MessagePackBeansBuilderSelector implements BuilderSelector{ + + public static final String NAME = "MessagePackBeansTemplateBuilder"; + + + TemplateBuilder builder; + public MessagePackBeansBuilderSelector(TemplateBuilder builder){ + this.builder = builder; + } + + + public String getName(){ + return NAME; + } + + @Override + public boolean matchType(Type targetType) { + Class target = (Class)targetType; + return isAnnotated(target, MessagePackBeans.class); + } + + @Override + public TemplateBuilder getTemplateBuilder(Type targetType) { + return builder; + } + + + private boolean isAnnotated(Class ao, Class with) { + return ao.getAnnotation(with) != null; + } + +} diff --git a/java/src/main/java/org/msgpack/template/builder/MessagePackMessageBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/MessagePackMessageBuilderSelector.java new file mode 100644 index 00000000..a4b3fe0c --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/MessagePackMessageBuilderSelector.java @@ -0,0 +1,55 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import org.msgpack.annotation.MessagePackMessage; + +public class MessagePackMessageBuilderSelector implements BuilderSelector{ + + public static final String NAME = "MessagePackMessageTemplateBuilder"; + + + TemplateBuilder builder; + public MessagePackMessageBuilderSelector(TemplateBuilder builder){ + this.builder = builder; + } + + public String getName(){ + return NAME; + } + + @Override + public boolean matchType(Type targetType) { + Class target = (Class)targetType; + return isAnnotated(target, MessagePackMessage.class); + } + + @Override + public TemplateBuilder getTemplateBuilder(Type targetType) { + return builder; + } + + + private boolean isAnnotated(Class ao, Class with) { + return ao.getAnnotation(with) != null; + } + +} diff --git a/java/src/main/java/org/msgpack/template/builder/MessagePackOrdinalEnumBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/MessagePackOrdinalEnumBuilderSelector.java new file mode 100644 index 00000000..93f0f71d --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/MessagePackOrdinalEnumBuilderSelector.java @@ -0,0 +1,51 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import org.msgpack.annotation.MessagePackOrdinalEnum; + +public class MessagePackOrdinalEnumBuilderSelector implements BuilderSelector { + + public static final String NAME = "MessagePackOrdinalEnumBuilderTemplate"; + + public String getName(){ + return NAME; + } + + @Override + public boolean matchType(Type targetType) { + Class target = (Class)targetType; + return isAnnotated(target, MessagePackOrdinalEnum.class); + } + + OrdinalEnumTemplateBuilder builder = new OrdinalEnumTemplateBuilder(); + + @Override + public TemplateBuilder getTemplateBuilder(Type targetType) { + return builder; + } + + + private boolean isAnnotated(Class ao, Class with) { + return ao.getAnnotation(with) != null; + } + +} diff --git a/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java new file mode 100644 index 00000000..d368984e --- /dev/null +++ b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java @@ -0,0 +1,85 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.builder; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +import org.msgpack.AbstractTemplate; +import org.msgpack.MessagePackObject; +import org.msgpack.MessageTypeException; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.template.TemplateBuildException; + +public class OrdinalEnumTemplateBuilder extends TemplateBuilder{ + + static class ReflectionOrdinalEnumTemplate extends AbstractTemplate { + protected Enum[] entries; + protected Map, Integer> reverse; + + ReflectionOrdinalEnumTemplate(Enum[] entries) { + this.entries = entries; + this.reverse = new HashMap, Integer>(); + for(int i=0; i < entries.length; i++) { + this.reverse.put(entries[i], i); + } + } + + public void pack(Packer pk, Object target) throws IOException { + Integer ord = reverse.get(target); + if(ord == null) { + throw new MessageTypeException(); + } + pk.pack((int)ord); + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int ord = pac.unpackInt(); + if(entries.length <= ord) { + throw new MessageTypeException(); + } + return entries[ord]; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + int ord = from.asInt(); + if(entries.length <= ord) { + throw new MessageTypeException(); + } + return entries[ord]; + } + } + @Override + public Template buildTemplate(Type targetType) { + Class targetClass = (Class)targetType; + checkOrdinalEnumValidation(targetClass); + Enum[] entries = (Enum[])targetClass.getEnumConstants(); + + return new ReflectionOrdinalEnumTemplate(entries); + } + private void checkOrdinalEnumValidation(Class targetClass) { + if(!targetClass.isEnum()) { + throw new TemplateBuildException("tried to build ordinal enum template of non-enum class"); + } + } + +} diff --git a/java/src/main/java/org/msgpack/template/TemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java similarity index 84% rename from java/src/main/java/org/msgpack/template/TemplateBuilder.java rename to java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java index f0a32089..3e04a1fa 100644 --- a/java/src/main/java/org/msgpack/template/TemplateBuilder.java +++ b/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.template; +package org.msgpack.template.builder; import java.io.IOException; import java.lang.reflect.*; @@ -25,89 +25,19 @@ import java.util.ArrayList; import java.util.EnumSet; import org.msgpack.*; import org.msgpack.annotation.*; +import org.msgpack.template.FieldList; +import org.msgpack.template.FieldOption; +import org.msgpack.template.IFieldEntry; +import org.msgpack.template.IFieldEntryReader; +import org.msgpack.template.JavassistTemplateBuilder; +import org.msgpack.template.ReflectionTemplateBuilder; public abstract class TemplateBuilder { - public static class FieldEntry { - private Field field; - private FieldOption option; - - public FieldEntry() { - this.field = null; - this.option = FieldOption.IGNORE; - } - - public FieldEntry(FieldEntry e) { - this.field = e.field; - this.option = e.option; - } - - public FieldEntry(Field field, FieldOption option) { - this.field = field; - this.option = option; - } - - public Field getField() { - return field; - } - - public String getName() { - return field.getName(); - } - - public Class getType() { - return field.getType(); - } - - public String getJavaTypeName() { - Class type = field.getType(); - if(type.isArray()) { - return arrayTypeToString(type); - } else { - return type.getName(); - } - } - - public Type getGenericType() { - return field.getGenericType(); - } - - public FieldOption getOption() { - return option; - } - - public boolean isAvailable() { - return option != FieldOption.IGNORE; - } - - public boolean isRequired() { - return option == FieldOption.REQUIRED; - } - - public boolean isOptional() { - return option == FieldOption.OPTIONAL; - } - - public boolean isNullable() { - return option == FieldOption.NULLABLE; - } - - static String arrayTypeToString(Class type) { - int dim = 1; - Class baseType = type.getComponentType(); - while(baseType.isArray()) { - baseType = baseType.getComponentType(); - dim += 1; - } - StringBuilder sb = new StringBuilder(); - sb.append(baseType.getName()); - for (int i = 0; i < dim; ++i) { - sb.append("[]"); - } - return sb.toString(); - } - } + public abstract Template buildTemplate(Type targetType); + /* // Override this method +<<<<<<< HEAD:java/src/main/java/org/msgpack/template/TemplateBuilder.java public abstract Class loadTemplateClass(Class targetClass); // Override this method @@ -118,6 +48,9 @@ public abstract class TemplateBuilder { // Override this method public abstract Template buildTemplate(Class targetClass, FieldEntry[] entries); +======= + public abstract Template buildTemplate(Class targetClass, IFieldEntry[] entries); +>>>>>>> 21f0d0bfc47ddc6d9092621705047f3bef385ba5:java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java // Override this method public abstract void writeOrdinalEnumTemplateClass(Class targetClass, Enum[] entires, String directoryName); @@ -131,6 +64,7 @@ public abstract class TemplateBuilder { // Override this method public abstract Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class baseClass, int dim); +<<<<<<< HEAD:java/src/main/java/org/msgpack/template/TemplateBuilder.java public Template initializeTemplate(Class targetClass, Class tmplClass) { return initializeTemplate(targetClass, tmplClass, readFieldEntries(targetClass, readImplicitFieldOption(targetClass))); @@ -140,10 +74,14 @@ public abstract class TemplateBuilder { checkValidation(targetClass); writeTemplateClass(targetClass, convertFieldEntries(targetClass, fList), directoryName); } +======= + + public abstract IFieldEntryReader getFieldEntryReader(); +>>>>>>> 21f0d0bfc47ddc6d9092621705047f3bef385ba5:java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java public Template buildTemplate(Class targetClass, FieldList flist) throws NoSuchFieldException { checkValidation(targetClass); - return buildTemplate(targetClass, convertFieldEntries(targetClass, flist)); + return buildTemplate(targetClass, getFieldEntryReader().convertFieldEntries(targetClass, flist)); } public void writeTemplateClass(Class targetClass, FieldOption implicitOption, String directoryName) { @@ -153,7 +91,7 @@ public abstract class TemplateBuilder { public Template buildTemplate(Class targetClass, FieldOption implicitOption) { checkValidation(targetClass); - return buildTemplate(targetClass, readFieldEntries(targetClass, implicitOption)); + return buildTemplate(targetClass, getFieldEntryReader().readFieldEntries(targetClass, implicitOption)); } public void writeTemplateClass(Class targetClass, final String directoryName) { @@ -162,7 +100,7 @@ public abstract class TemplateBuilder { } public Template buildTemplate(Class targetClass) { - FieldOption implicitOption = readImplicitFieldOption(targetClass); + FieldOption implicitOption = getFieldEntryReader().readImplicitFieldOption(targetClass); return buildTemplate(targetClass, implicitOption); } @@ -217,8 +155,24 @@ public abstract class TemplateBuilder { return ((Class)arrayType).getComponentType(); } } + private void checkValidation(Class targetClass) { + if(targetClass.isInterface()) { + throw new TemplateBuildException("cannot build template of interface"); + } + if(targetClass.isArray()) { + throw new TemplateBuildException("cannot build template of array class"); + } + if(targetClass.isPrimitive()) { + throw new TemplateBuildException("cannot build template of primitive type"); + } + } + private void checkOrdinalEnumValidation(Class targetClass) { + if(!targetClass.isEnum()) { + throw new TemplateBuildException("tried to build ordinal enum template of non-enum class"); + } + } - + private static TemplateBuilder instance; static { instance = selectDefaultTemplateBuilder(); @@ -235,7 +189,7 @@ public abstract class TemplateBuilder { return JavassistTemplateBuilder.getInstance(); } - synchronized static void setInstance(TemplateBuilder builder) { + public synchronized static void setInstance(TemplateBuilder builder) { instance = builder; } @@ -286,9 +240,9 @@ public abstract class TemplateBuilder { public static Template buildArray(Type arrayType) { return instance.buildArrayTemplate(arrayType); - } - + }*/ + /* private static void checkValidation(Class targetClass) { if(targetClass.isInterface()) { throw new TemplateBuildException("cannot build template of interface"); @@ -305,10 +259,10 @@ public abstract class TemplateBuilder { if(!targetClass.isEnum()) { throw new TemplateBuildException("tried to build ordinal enum template of non-enum class"); } - } + }*/ - - static FieldEntry[] convertFieldEntries(Class targetClass, FieldList flist) throws NoSuchFieldException { + /* + static IFieldEntry[] convertFieldEntries(Class targetClass, FieldList flist) throws NoSuchFieldException { List src = flist.getList(); FieldEntry[] result = new FieldEntry[src.size()]; for(int i=0; i < src.size(); i++) { @@ -320,9 +274,9 @@ public abstract class TemplateBuilder { } } return result; - } - - static FieldEntry[] readFieldEntries(Class targetClass, FieldOption implicitOption) { + }*/ + + /*static IFieldEntry[] readFieldEntries(Class targetClass, FieldOption implicitOption) { Field[] allFields = readAllFields(targetClass); /* index: @@ -332,7 +286,7 @@ public abstract class TemplateBuilder { * int field_d; // 4 * @Index(2) int field_e; // 2 * int field_f; // 5 - */ + *//* List indexed = new ArrayList(); int maxIndex = -1; for(Field f : allFields) { @@ -372,8 +326,8 @@ public abstract class TemplateBuilder { } return result; - } - + }*/ + /* private static Field[] readAllFields(Class targetClass) { // order: [fields of super class, ..., fields of this class] List succ = new ArrayList(); @@ -449,6 +403,6 @@ public abstract class TemplateBuilder { private static boolean isAnnotated(AccessibleObject ao, Class with) { return ao.getAnnotation(with) != null; - } + }*/ } diff --git a/java/src/main/java/org/msgpack/template/javassist/BeansBuildContext.java b/java/src/main/java/org/msgpack/template/javassist/BeansBuildContext.java new file mode 100644 index 00000000..6b4fa265 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/javassist/BeansBuildContext.java @@ -0,0 +1,289 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.javassist; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; +import java.lang.Thread; + +import org.msgpack.*; +import org.msgpack.template.*; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtMethod; +import javassist.CtNewConstructor; +import javassist.CtNewMethod; +import javassist.LoaderClassPath; +import javassist.NotFoundException; +import javassist.ClassClassPath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + + +public class BeansBuildContext extends BuildContextBase { + protected BeansFieldEntry[] entries; + protected Class origClass; + protected String origName; + protected Template[] templates; + protected int minimumArrayLength; + + public BeansBuildContext(JavassistTemplateBuilder director) { + super(director); + } + + public Template buildTemplate(Class targetClass, BeansFieldEntry[] entries, Template[] templates) { + this.entries = entries; + this.templates = templates; + this.origClass = targetClass; + this.origName = this.origClass.getName(); + return build(this.origName); + } + + protected void setSuperClass() throws CannotCompileException, NotFoundException { + this.tmplCtClass.setSuperclass( + director.getCtClass(JavassistTemplate.class.getName())); + } + + protected void buildConstructor() throws CannotCompileException, NotFoundException { + // Constructor(Class targetClass, Template[] templates) + CtConstructor newCtCons = CtNewConstructor.make( + new CtClass[] { + director.getCtClass(Class.class.getName()), + director.getCtClass(Template.class.getName()+"[]") + }, + new CtClass[0], + this.tmplCtClass); + this.tmplCtClass.addConstructor(newCtCons); + } + + protected Template buildInstance(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor cons = c.getConstructor(new Class[] { + Class.class, + Template[].class + }); + Object tmpl = cons.newInstance(new Object[] { + this.origClass, + this.templates + }); + return (Template)tmpl; + } + + protected void buildMethodInit() { + this.minimumArrayLength = 0; + for(int i=0; i < entries.length; i++) { + IFieldEntry e = entries[i]; + if(e.isRequired() || e.isNullable()) { + this.minimumArrayLength = i+1; + } + } + } + + protected String buildPackMethodBody() { + resetStringBuilder(); + buildString("{"); + buildString("%s _$$_t = (%s)$2;", this.origName, this.origName); + buildString("$1.packArray(%d);", entries.length); + for(int i=0; i < entries.length; i++) { + BeansFieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.packNil();"); + continue; + } + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("$1.%s(_$$_t.%s());", primitivePackName(type), e.getGetterName()); + } else { + buildString("if(_$$_t.%s() == null) {", e.getGetterName()); + if(!e.isNullable() && !e.isOptional()) { + buildString("throw new %s();", MessageTypeException.class.getName()); + } else { + buildString("$1.packNil();"); + } + buildString("} else {"); + buildString(" this.templates[%d].pack($1, _$$_t.%s());", i, e.getGetterName()); + buildString("}"); + } + } + buildString("}"); + return getBuiltString(); + } + + protected String buildUnpackMethodBody() { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("int length = $1.unpackArray();"); + buildString("if(length < %d) {", this.minimumArrayLength); + buildString(" throw new %s();", MessageTypeException.class.getName()); + buildString("}"); + + int i; + for(i=0; i < this.minimumArrayLength; i++) { + BeansFieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + continue; + } + + buildString("if($1.tryUnpackNull()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", MessageTypeException.class.getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s(null);", e.getSetterName()); + } + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.set%s( $1.%s() );", e.getName(), primitiveUnpackName(type)); + } else { + buildString("_$$_t.set%s( (%s)this.templates[%d].unpack($1, _$$_t.get%s()) );", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + for(; i < entries.length; i++) { + buildString("if(length <= %d) { return _$$_t; }", i); + + BeansFieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + continue; + } + + buildString("if($1.tryUnpackNull()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s( $1.%s() );", e.getSetterName(), primitiveUnpackName(type)); + } else { + buildString("_$$_t.%s( (%s)this.templates[%d].unpack($1, _$$_t.%s()) );", e.getSetterName(), e.getJavaTypeName(), i, e.getGetterName()); + } + buildString("}"); + } + + // latter entries are all Optional + nil => keep default value + + buildString("for(int i=%d; i < length; i++) {", i); + buildString(" $1.unpackObject();"); + buildString("}"); + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + + protected String buildConvertMethodBody() { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("%s[] array = $1.asArray();", MessagePackObject.class.getName()); + buildString("int length = array.length;"); + buildString("if(length < %d) {", this.minimumArrayLength); + buildString(" throw new %s();", MessageTypeException.class.getName()); + buildString("}"); + + buildString("%s obj;", MessagePackObject.class.getName()); + + int i; + for(i=0; i < this.minimumArrayLength; i++) { + BeansFieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + buildString("obj = array[%d];", i); + buildString("if(obj.isNil()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", MessageTypeException.class.getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s( null );", e.getSetterName()); + } + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s( obj.%s() );", e.getSetterName(), primitiveConvertName(type)); + } else { + buildString("_$$_t.%s( (%s)this.templates[%d].convert(obj, _$$_t.%s()) );", e.getSetterName(), e.getJavaTypeName(), i, e.getGetterName()); + } + buildString("}"); + } + + for(; i < entries.length; i++) { + buildString("if(length <= %d) { return _$$_t; }", i); + + BeansFieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + buildString("obj = array[%d];", i); + buildString("if(obj.isNil()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s( obj.%s() );", e.getSetterName(), primitiveConvertName(type)); + } else { + buildString("_$$_t.%s( (%s)this.templates[%d].convert(obj, _$$_t.%s()) );", e.getSetterName(), e.getJavaTypeName(), i, e.getGetterName()); + } + buildString("}"); + } + + // latter entries are all Optional + nil => keep default value + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/template/javassist/BuildContext.java b/java/src/main/java/org/msgpack/template/javassist/BuildContext.java new file mode 100644 index 00000000..a3ab97d9 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/javassist/BuildContext.java @@ -0,0 +1,289 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.javassist; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; +import java.lang.Thread; + +import org.msgpack.*; +import org.msgpack.template.*; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtMethod; +import javassist.CtNewConstructor; +import javassist.CtNewMethod; +import javassist.LoaderClassPath; +import javassist.NotFoundException; +import javassist.ClassClassPath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + + +public class BuildContext extends BuildContextBase { + protected IFieldEntry[] entries; + protected Class origClass; + protected String origName; + protected Template[] templates; + protected int minimumArrayLength; + + public BuildContext(JavassistTemplateBuilder director) { + super(director); + } + + public Template buildTemplate(Class targetClass, FieldEntry[] entries, Template[] templates) { + this.entries = entries; + this.templates = templates; + this.origClass = targetClass; + this.origName = this.origClass.getName(); + return build(this.origName); + } + + protected void setSuperClass() throws CannotCompileException, NotFoundException { + this.tmplCtClass.setSuperclass( + director.getCtClass(JavassistTemplate.class.getName())); + } + + protected void buildConstructor() throws CannotCompileException, NotFoundException { + // Constructor(Class targetClass, Template[] templates) + CtConstructor newCtCons = CtNewConstructor.make( + new CtClass[] { + director.getCtClass(Class.class.getName()), + director.getCtClass(Template.class.getName()+"[]") + }, + new CtClass[0], + this.tmplCtClass); + this.tmplCtClass.addConstructor(newCtCons); + } + + protected Template buildInstance(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor cons = c.getConstructor(new Class[] { + Class.class, + Template[].class + }); + Object tmpl = cons.newInstance(new Object[] { + this.origClass, + this.templates + }); + return (Template)tmpl; + } + + protected void buildMethodInit() { + this.minimumArrayLength = 0; + for(int i=0; i < entries.length; i++) { + IFieldEntry e = entries[i]; + if(e.isRequired() || e.isNullable()) { + this.minimumArrayLength = i+1; + } + } + } + + protected String buildPackMethodBody() { + resetStringBuilder(); + buildString("{"); + buildString("%s _$$_t = (%s)$2;", this.origName, this.origName); + buildString("$1.packArray(%d);", entries.length); + for(int i=0; i < entries.length; i++) { + IFieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.packNil();"); + continue; + } + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("$1.%s(_$$_t.%s);", primitivePackName(type), e.getName()); + } else { + buildString("if(_$$_t.%s == null) {", e.getName()); + if(!e.isNullable() && !e.isOptional()) { + buildString("throw new %s();", MessageTypeException.class.getName()); + } else { + buildString("$1.packNil();"); + } + buildString("} else {"); + buildString(" this.templates[%d].pack($1, _$$_t.%s);", i, e.getName()); + buildString("}"); + } + } + buildString("}"); + return getBuiltString(); + } + + protected String buildUnpackMethodBody() { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("int length = $1.unpackArray();"); + buildString("if(length < %d) {", this.minimumArrayLength); + buildString(" throw new %s();", MessageTypeException.class.getName()); + buildString("}"); + + int i; + for(i=0; i < this.minimumArrayLength; i++) { + IFieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + continue; + } + + buildString("if($1.tryUnpackNull()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", MessageTypeException.class.getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s = null;", e.getName()); + } + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + for(; i < entries.length; i++) { + buildString("if(length <= %d) { return _$$_t; }", i); + + IFieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + continue; + } + + buildString("if($1.tryUnpackNull()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + // latter entries are all Optional + nil => keep default value + + buildString("for(int i=%d; i < length; i++) {", i); + buildString(" $1.unpackObject();"); + buildString("}"); + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + + protected String buildConvertMethodBody() { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("%s[] array = $1.asArray();", MessagePackObject.class.getName()); + buildString("int length = array.length;"); + buildString("if(length < %d) {", this.minimumArrayLength); + buildString(" throw new %s();", MessageTypeException.class.getName()); + buildString("}"); + + buildString("%s obj;", MessagePackObject.class.getName()); + + int i; + for(i=0; i < this.minimumArrayLength; i++) { + IFieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + buildString("obj = array[%d];", i); + buildString("if(obj.isNil()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", MessageTypeException.class.getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s = null;", e.getName()); + } + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + for(; i < entries.length; i++) { + buildString("if(length <= %d) { return _$$_t; }", i); + + IFieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + buildString("obj = array[%d];", i); + buildString("if(obj.isNil()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + // latter entries are all Optional + nil => keep default value + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/template/javassist/BuildContextBase.java b/java/src/main/java/org/msgpack/template/javassist/BuildContextBase.java new file mode 100644 index 00000000..1b2db02b --- /dev/null +++ b/java/src/main/java/org/msgpack/template/javassist/BuildContextBase.java @@ -0,0 +1,244 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.javassist; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; +import java.lang.Thread; + +import org.msgpack.*; +import org.msgpack.template.*; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtMethod; +import javassist.CtNewConstructor; +import javassist.CtNewMethod; +import javassist.LoaderClassPath; +import javassist.NotFoundException; +import javassist.ClassClassPath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public abstract class BuildContextBase { + + private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class); + + + protected JavassistTemplateBuilder director; + + protected String tmplName; + + protected CtClass tmplCtClass; + + protected abstract void setSuperClass() throws CannotCompileException, NotFoundException; + + protected abstract void buildConstructor() throws CannotCompileException, NotFoundException; + + protected void buildMethodInit() { } + + protected abstract String buildPackMethodBody(); + + protected abstract String buildUnpackMethodBody(); + + protected abstract String buildConvertMethodBody(); + + protected abstract Template buildInstance(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException; + + public BuildContextBase(JavassistTemplateBuilder director) { + this.director = director; + } + + + public abstract Template buildTemplate(Class targetClass, T[] entries, Template[] templates); + + + protected Template build(final String className) { + try { + reset(className); + buildClass(); + buildConstructor(); + buildMethodInit(); + buildPackMethod(); + buildUnpackMethod(); + buildConvertMethod(); + return buildInstance(createClass()); + } catch (Exception e) { + String code = getBuiltString(); + if(code != null) { + LOG.error("builder: " + code, e); + throw new TemplateBuildException("cannot compile: " + code, e); + } else { + throw new TemplateBuildException(e); + } + } + } + + protected void reset(String className) { + tmplName = className + "_$$_Template" + director.nextSeqId(); + tmplCtClass = director.makeCtClass(tmplName); + } + + protected void buildClass() throws CannotCompileException, NotFoundException { + setSuperClass(); + tmplCtClass.addInterface(director.getCtClass(Template.class.getName())); + } + + protected void buildPackMethod() throws CannotCompileException, NotFoundException { + String mbody = buildPackMethodBody(); + int mod = javassist.Modifier.PUBLIC; + CtClass returnType = CtClass.voidType; + String mname = "pack"; + CtClass[] paramTypes = new CtClass[] { + director.getCtClass(Packer.class.getName()), + director.getCtClass(Object.class.getName()) + }; + CtClass[] exceptTypes = new CtClass[] { + director.getCtClass(IOException.class.getName()) + }; + CtMethod newCtMethod = CtNewMethod.make( + mod, returnType, mname, + paramTypes, exceptTypes, mbody, tmplCtClass); + tmplCtClass.addMethod(newCtMethod); + } + + protected void buildUnpackMethod() throws CannotCompileException, NotFoundException { + String mbody = buildUnpackMethodBody(); + int mod = javassist.Modifier.PUBLIC; + CtClass returnType = director.getCtClass(Object.class.getName()); + String mname = "unpack"; + CtClass[] paramTypes = new CtClass[] { + director.getCtClass(Unpacker.class.getName()), + director.getCtClass(Object.class.getName()) + }; + CtClass[] exceptTypes = new CtClass[] { + director.getCtClass(MessageTypeException.class.getName()) + }; + CtMethod newCtMethod = CtNewMethod.make( + mod, returnType, mname, + paramTypes, exceptTypes, mbody, tmplCtClass); + tmplCtClass.addMethod(newCtMethod); + } + + protected void buildConvertMethod() throws CannotCompileException, NotFoundException { + String mbody = buildConvertMethodBody(); + int mod = javassist.Modifier.PUBLIC; + CtClass returnType = director.getCtClass(Object.class.getName()); + String mname = "convert"; + CtClass[] paramTypes = new CtClass[] { + director.getCtClass(MessagePackObject.class.getName()), + director.getCtClass(Object.class.getName()) + }; + CtClass[] exceptTypes = new CtClass[] { + director.getCtClass(MessageTypeException.class.getName()) + }; + CtMethod newCtMethod = CtNewMethod.make( + mod, returnType, mname, + paramTypes, exceptTypes, mbody, tmplCtClass); + tmplCtClass.addMethod(newCtMethod); + } + + protected Class createClass() throws CannotCompileException { + return (Class) tmplCtClass.toClass(null, null); + } + + protected StringBuilder stringBuilder = null; + + protected void resetStringBuilder() { + stringBuilder = new StringBuilder(); + } + + protected void buildString(String str) { + stringBuilder.append(str); + } + + protected void buildString(String format, Object... args) { + stringBuilder.append(String.format(format, args)); + } + + protected String getBuiltString() { + if(stringBuilder == null) { + return null; + } + return stringBuilder.toString(); + } + + protected String primitivePackName(Class type) { + if(type == boolean.class) { + return "packBoolean"; + } else if(type == byte.class) { + return "packByte"; + } else if(type == short.class) { + return "packShort"; + } else if(type == int.class) { + return "packInt"; + } else if(type == long.class) { + return "packLong"; + } else if(type == float.class) { + return "packFloat"; + } else if(type == double.class) { + return "packDouble"; + } + return null; + } + + protected String primitiveUnpackName(Class type) { + if(type == boolean.class) { + return "unpackBoolean"; + } else if(type == byte.class) { + return "unpackByte"; + } else if(type == short.class) { + return "unpackShort"; + } else if(type == int.class) { + return "unpackInt"; + } else if(type == long.class) { + return "unpackLong"; + } else if(type == float.class) { + return "unpackFloat"; + } else if(type == double.class) { + return "unpackDouble"; + } + return null; + } + + protected String primitiveConvertName(Class type) { + if(type == boolean.class) { + return "asBoolean"; + } else if(type == byte.class) { + return "asByte"; + } else if(type == short.class) { + return "asShort"; + } else if(type == int.class) { + return "asInt"; + } else if(type == long.class) { + return "asLong"; + } else if(type == float.class) { + return "asFloat"; + } else if(type == double.class) { + return "asDouble"; + } + return null; + } +} \ No newline at end of file diff --git a/java/src/main/java/org/msgpack/template/javassist/BuildContextFactory.java b/java/src/main/java/org/msgpack/template/javassist/BuildContextFactory.java new file mode 100644 index 00000000..1099482b --- /dev/null +++ b/java/src/main/java/org/msgpack/template/javassist/BuildContextFactory.java @@ -0,0 +1,26 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.javassist; + +import org.msgpack.template.JavassistTemplateBuilder; + +public interface BuildContextFactory { + + public BuildContextBase createBuildContext(JavassistTemplateBuilder builder); + +} diff --git a/java/src/main/java/org/msgpack/template/javassist/JavassistTemplate.java b/java/src/main/java/org/msgpack/template/javassist/JavassistTemplate.java new file mode 100644 index 00000000..c3feabe2 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/javassist/JavassistTemplate.java @@ -0,0 +1,52 @@ +// +// MessagePack for Java +// +// Copyright (C) 2009-2011 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.template.javassist; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; +import java.lang.Thread; + +import org.msgpack.*; +import org.msgpack.template.*; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtMethod; +import javassist.CtNewConstructor; +import javassist.CtNewMethod; +import javassist.LoaderClassPath; +import javassist.NotFoundException; +import javassist.ClassClassPath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class JavassistTemplate extends AbstractTemplate { + public Class targetClass; + public Template[] templates; + + public JavassistTemplate(Class targetClass, Template[] templates) { + this.targetClass = targetClass; + this.templates = templates; + } +} \ No newline at end of file diff --git a/java/src/test/java/org/msgpack/TestArrays.java b/java/src/test/java/org/msgpack/TestArrays.java index 92bb44c2..40fa5d69 100644 --- a/java/src/test/java/org/msgpack/TestArrays.java +++ b/java/src/test/java/org/msgpack/TestArrays.java @@ -13,6 +13,10 @@ import org.junit.Test; import junit.framework.TestCase; public class TestArrays extends TestCase { + + + + @MessagePackMessage public static class PrimitiveTest { public PrimitiveTest() { } diff --git a/java/src/test/java/org/msgpack/template/BeansEntryReaderTest.java b/java/src/test/java/org/msgpack/template/BeansEntryReaderTest.java new file mode 100644 index 00000000..78880582 --- /dev/null +++ b/java/src/test/java/org/msgpack/template/BeansEntryReaderTest.java @@ -0,0 +1,133 @@ +package org.msgpack.template; + +import java.beans.BeanDescriptor; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.msgpack.template.BeansFieldEntryReader; + +import static org.junit.Assert.assertThat; +import static org.hamcrest.CoreMatchers.*; + +/** + * + * @author takeshita + * + */ +public class BeansEntryReaderTest { + + public static class VariableProps{ + + public int getCollect(){ + return 0; + } + public void setCollect(int v){} + + public int getOnlyGetter(){ + return 0; + } + + public void setOnlySetter(int v){} + + public boolean isBoolean(){ + return true; + } + public void setBoolean(boolean b){} + + + private int getPrivateBoth(){return 1;} + private void setPrivateBoth(int v){} + + private int getPrivateGetter(){return 1;} + public void setPrivateGetter(int v){} + + public int getPrivateSetter(){return 1;} + private void setPrivateSetter(int v){} + + protected int getProtected(){return 1;} + protected void setProtected(int v){} + + int getInternal(){return 1;} + void setInternal(int v){} + + public int getWrongGetter(int v){return 1;} + public void setWrongGetter(int v){} + + public void getWrongGetter2(){} + public void setWrongGetter2(int v){} + + public int isWrongGetter3(){return 1;} + public void setWrongGetter3(int v){} + + public int getWrongSetter(){return 1;} + public int setWrongSetter(int v){return 1;} + + public int getWrongSetter2(){return 1;} + public void setWrongSetter2(){} + } + + @Before + public void before(){ + reader = new BeansFieldEntryReader(); + + try { + info = Introspector.getBeanInfo(VariableProps.class); + } catch (IntrospectionException e) { + e.printStackTrace(); + Assert.fail(); + } + } + BeansFieldEntryReader reader; + BeanInfo info; + @Test + public void testIgnorePropertyDesc(){ + BeanDescriptor desc = info.getBeanDescriptor(); + + assertThat(reader.isIgnoreProp(getProp(info,"collect")),is(false)); + assertThat(reader.isIgnoreProp(getProp(info,"boolean")),is(false)); + + + assertThat(reader.isIgnoreProp(getProp(info,"onlyGetter")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"onlySetter")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"privateBoth")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"privateGetter")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"privateSetter")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"protected")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"internal")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"wrongGetter")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"wrongGetter2")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"wrongGetter3")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"wrongSetter")),is(true)); + assertThat(reader.isIgnoreProp(getProp(info,"wrongSetter2")),is(true)); + + } + @Test + public void testReadEntries(){ + + IFieldEntry[] entries = reader.readFieldEntries(VariableProps.class, FieldOption.DEFAULT); + + assertThat(entries.length, is(2)); + + + } + + + public PropertyDescriptor getProp(BeanInfo info , String name){ + PropertyDescriptor[] props = info.getPropertyDescriptors(); + for(int i = 0;i < props.length;i++){ + PropertyDescriptor d = props[i]; + if(d.getDisplayName().equalsIgnoreCase(name)){ + return d; + } + } + return null; + } + + + +} diff --git a/java/src/test/java/org/msgpack/template/BeansEquals.java b/java/src/test/java/org/msgpack/template/BeansEquals.java new file mode 100644 index 00000000..e07a224d --- /dev/null +++ b/java/src/test/java/org/msgpack/template/BeansEquals.java @@ -0,0 +1,83 @@ +package org.msgpack.template; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashSet; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.CoreMatchers; +import org.hamcrest.Description; +import org.junit.Assert; + +/** + * This matcher compares all get***() methods(except getClass) + * @author takeshita + * + */ +public class BeansEquals extends BaseMatcher{ + + Object expected; + + HashSet ignoreNames = new HashSet(); + + public BeansEquals(Object expected){ + this.expected = expected; + } + public BeansEquals(Object expected,String[] ignoreNames){ + this.expected = expected; + for(int i = 0;i < ignoreNames.length;i++){ + this.ignoreNames.add(ignoreNames[i]); + } + } + + static String errorMessage = "hoge"; + + @Override + public boolean matches(Object actual) { + if(expected == actual){ + return true; + } + if(!actual.getClass().equals(expected.getClass())){ + errorMessage = String.format("Expected class is %s but actual %s", + expected.getClass().getName(), + actual.getClass().getName()); + return false; + } + + for(Method m : expected.getClass().getMethods()){ + String n = m.getName(); + if(n.startsWith("get") && + !n.equals("getClass") && + !ignoreNames.contains(n)){ + + if(m.getParameterTypes().length == 0 && + !m.getReturnType().equals(void.class)){ + try { + Object exp = m.invoke(expected); + Object act = m.invoke(actual); + + Assert.assertThat("@" + n,act, CoreMatchers.is(exp)); + + } catch (Exception e) { + throw new RuntimeException(String.format( + "Exception occured while comparing %s",n), e); + } + + } + + } + + } + + return true; + } + + + @Override + public void describeTo(Description desc) { + + desc.appendText(errorMessage); + } + + +} diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java new file mode 100644 index 00000000..951b401c --- /dev/null +++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java @@ -0,0 +1,2207 @@ +package org.msgpack.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.hamcrest.CoreMatchers; +import org.hamcrest.Matcher; +import org.junit.Ignore; +import org.junit.Test; + +import org.msgpack.MessagePack; +import org.msgpack.MessagePackable; +import org.msgpack.MessagePacker; +import org.msgpack.MessageTypeException; +import org.msgpack.MessageUnpackable; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.annotation.MessagePackBeans; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.annotation.Optional; +import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface; +import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.MessagePackBeansBuilderSelector; +import org.msgpack.template.builder.MessagePackMessageBuilderSelector; +import org.msgpack.template.builder.TemplateBuilder; + +import org.junit.Assert; +import junit.framework.TestCase; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +public class TestReflectionTemplateBuilderJavaBeansPackUnpack extends TestCase { + static { + //Replace template selectors from javassist to reflection. + BuilderSelectorRegistry instance = BuilderSelectorRegistry.getInstance(); + + instance.replace( + new MessagePackMessageBuilderSelector( + new ReflectionTemplateBuilder())); + instance.setForceBuilder( new ReflectionTemplateBuilder()); + instance.replace(new MessagePackBeansBuilderSelector( + new BeansReflectionTemplateBuilder())); + + MessagePack.register(PrimitiveTypeFieldsClass.class); + MessagePack.register(OptionalPrimitiveTypeFieldsClass.class); + MessagePack.register(GeneralReferenceTypeFieldsClass.class); + MessagePack.register(GeneralOptionalReferenceTypeFieldsClass.class); + MessagePack.register(SampleListTypes.class); + MessagePack.register(SampleOptionalListTypes.class); + MessagePack.register(SampleMapTypes.class); + MessagePack.register(SampleOptionalMapTypes.class); + MessagePack.register(SampleEnumFieldClass.class); + MessagePack.register(SampleOptionalEnumFieldClass.class); + MessagePack.register(FieldModifiersClass.class); + MessagePack.register(OptionalFieldModifiersClass.class); + MessagePack.register(BaseClass.class); + MessagePack.register(NestedClass.class); + MessagePack.register(BaseClass2.class); + MessagePack.register(OptionalBaseClass.class); + MessagePack.register(OptionalNestedClass.class); + MessagePack.register(OptionalBaseClass2.class); + MessagePack.register(SampleSubClass.class); + MessagePack.register(SampleSuperClass.class); + MessagePack.register(SampleOptionalSubClass.class); + MessagePack.register(SampleOptionalSuperClass.class); + MessagePack.register(BaseMessagePackableUnpackableClass.class); + MessagePack.register(MessagePackableUnpackableClass.class); + MessagePack.register(OptionalBaseMessagePackableUnpackableClass.class); + MessagePack.register(OptionalMessagePackableUnpackableClass.class); + } + + Matcher beansEquals(Object actual){ + return new BeansEquals(actual); + } + Matcher beansEquals(Object actual,String[] ignoreNames){ + return new BeansEquals(actual,ignoreNames); + } + String[] ignoring(String ... strings){ + return strings; + } + + @Test + public void testPrimitiveTypeFields00() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + + + assertThat(dst,beansEquals(src)); + } + + @Test + public void testPrimitiveTypeFields01() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + + assertThat(dst,beansEquals(src)); + } + + @Test + public void testPrimitiveTypeFields02() throws Exception { + PrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + + assertThat(dst,beansEquals(src)); + } + + @MessagePackBeans + public static class PrimitiveTypeFieldsClass { + byte f0; + short f1; + int f2; + long f3; + float f4; + double f5; + boolean f6; + + public byte getF0() { + return f0; + } + + public void setF0(byte f0) { + this.f0 = f0; + } + + public short getF1() { + return f1; + } + + public void setF1(short f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public long getF3() { + return f3; + } + + public void setF3(long f3) { + this.f3 = f3; + } + + public float getF4() { + return f4; + } + + public void setF4(float f4) { + this.f4 = f4; + } + + public double getF5() { + return f5; + } + + public void setF5(double f5) { + this.f5 = f5; + } + + public boolean isF6() { + return f6; + } + + public void setF6(boolean f6) { + this.f6 = f6; + } + + public PrimitiveTypeFieldsClass() { + } + } + + @Test + public void testOptionalPrimitiveTypeFields00() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testOptionalPrimitiveTypeFields01() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.class); + + + assertThat(dst,beansEquals(src)); + } + + @Test + public void testOptionalPrimitiveTypeFields02() throws Exception { + OptionalPrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalPrimitiveTypeFieldsClass { + @Optional + public byte f0; + @Optional + public short f1; + @Optional + public int f2; + @Optional + public long f3; + @Optional + public float f4; + @Optional + public double f5; + @Optional + public boolean f6; + + @Optional + public byte getF0() { + return f0; + } + + @Optional + public void setF0(byte f0) { + this.f0 = f0; + } + + @Optional + public short getF1() { + return f1; + } + + public void setF1(short f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + @Optional + public void setF2(int f2) { + this.f2 = f2; + } + + @Optional + public long getF3() { + return f3; + } + + public void setF3(long f3) { + this.f3 = f3; + } + + @Optional + public float getF4() { + return f4; + } + + public void setF4(float f4) { + this.f4 = f4; + } + + @Optional + public double getF5() { + return f5; + } + + public void setF5(double f5) { + this.f5 = f5; + } + + @Optional + public boolean isF6() { + return f6; + } + + public void setF6(boolean f6) { + this.f6 = f6; + } + + public OptionalPrimitiveTypeFieldsClass() { + } + } + + @Test + public void testGeneralReferenceTypeFieldsClass00() throws Exception { + GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralReferenceTypeFieldsClass.class); + + + assertThat(dst,beansEquals(src)); + + } + + @Test + public void testGeneralReferenceTypeFieldsClass01() throws Exception { + GeneralReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + 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 ByteBuffer f10; + + public Byte getF0() { + return f0; + } + + public void setF0(Byte f0) { + this.f0 = f0; + } + + public Short getF1() { + return f1; + } + + public void setF1(Short f1) { + this.f1 = f1; + } + + public Integer getF2() { + return f2; + } + + public void setF2(Integer f2) { + this.f2 = f2; + } + + public Long getF3() { + return f3; + } + + public void setF3(Long f3) { + this.f3 = f3; + } + + public Float getF4() { + return f4; + } + + public void setF4(Float f4) { + this.f4 = f4; + } + + public Double getF5() { + return f5; + } + + public void setF5(Double f5) { + this.f5 = f5; + } + + public Boolean getF6() { + return f6; + } + + public void setF6(Boolean f6) { + this.f6 = f6; + } + + public BigInteger getF7() { + return f7; + } + + public void setF7(BigInteger f7) { + this.f7 = f7; + } + + public String getF8() { + return f8; + } + + public void setF8(String f8) { + this.f8 = f8; + } + + public byte[] getF9() { + return f9; + } + + public void setF9(byte[] f9) { + this.f9 = f9; + } + + public ByteBuffer getF10() { + return f10; + } + + public void setF10(ByteBuffer f10) { + this.f10 = f10; + } + + public GeneralReferenceTypeFieldsClass() { + } + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass00() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + + + assertThat(dst,beansEquals(src)); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass01() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = null; + src.f1 = null; + src.f2 = null; + src.f3 = null; + src.f4 = null; + src.f5 = null; + src.f6 = null; + src.f7 = null; + src.f8 = null; + src.f9 = null; + src.f10 = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + + + assertThat(dst,beansEquals(src)); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass02() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class GeneralOptionalReferenceTypeFieldsClass { + @Optional + public Byte f0; + @Optional + public Short f1; + @Optional + public Integer f2; + @Optional + public Long f3; + @Optional + public Float f4; + @Optional + public Double f5; + @Optional + public Boolean f6; + @Optional + public BigInteger f7; + @Optional + public String f8; + @Optional + public byte[] f9; + @Optional + public ByteBuffer f10; + + @Optional + public Byte getF0() { + return f0; + } + + @Optional + public void setF0(Byte f0) { + this.f0 = f0; + } + + @Optional + public Short getF1() { + return f1; + } + + public void setF1(Short f1) { + this.f1 = f1; + } + + public Integer getF2() { + return f2; + } + + @Optional + public void setF2(Integer f2) { + this.f2 = f2; + } + + @Optional + public Long getF3() { + return f3; + } + + public void setF3(Long f3) { + this.f3 = f3; + } + + @Optional + public Float getF4() { + return f4; + } + + public void setF4(Float f4) { + this.f4 = f4; + } + + @Optional + public Double getF5() { + return f5; + } + + public void setF5(Double f5) { + this.f5 = f5; + } + + @Optional + public Boolean getF6() { + return f6; + } + + public void setF6(Boolean f6) { + this.f6 = f6; + } + + @Optional + public BigInteger getF7() { + return f7; + } + + public void setF7(BigInteger f7) { + this.f7 = f7; + } + + @Optional + public String getF8() { + return f8; + } + + public void setF8(String f8) { + this.f8 = f8; + } + + @Optional + public byte[] getF9() { + return f9; + } + + public void setF9(byte[] f9) { + this.f9 = f9; + } + + @Optional + public ByteBuffer getF10() { + return f10; + } + + public void setF10(ByteBuffer f10) { + this.f10 = f10; + } + + public GeneralOptionalReferenceTypeFieldsClass() { + } + } + + @Test + public void testListTypes00() throws Exception { + SampleListTypes src = new SampleListTypes(); + src.integerListSize0 = new ArrayList(); + src.integerList = new ArrayList(); + src.integerList.add(1); + src.integerList.add(2); + src.integerList.add(3); + src.stringList = new ArrayList(); + src.stringList.add("e1"); + src.stringList.add("e2"); + src.stringList.add("e3"); + src.stringListList = new ArrayList>(); + src.stringListList.add(src.stringList); + src.sampleListNestedTypeList = new ArrayList(); + SampleListNestedType slnt = new SampleListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.sampleListNestedTypeList.add(slnt); + src.byteBufferList = new ArrayList(); + src.byteBufferList.add(ByteBuffer.wrap("e1".getBytes())); + src.byteBufferList.add(ByteBuffer.wrap("e2".getBytes())); + src.byteBufferList.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + + //ignore sampleListNestedTypeList, + //because SampleListNestedType is not implemented equals() correctly. + assertThat(dst,beansEquals(src, ignoring("getF4"))); + + assertEquals(src.sampleListNestedTypeList.size(), dst.sampleListNestedTypeList.size()); + for (int i = 0; i < src.sampleListNestedTypeList.size(); ++i) { + SampleListNestedType s = src.sampleListNestedTypeList.get(i); + SampleListNestedType d = dst.sampleListNestedTypeList.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + } + + @Test + public void testListTypes01() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleListTypes { + public List integerListSize0; + public List integerList; + public List stringList; + public List> stringListList; + public List sampleListNestedTypeList; + public List byteBufferList; + + public List getF0() { + return integerListSize0; + } + + public void setF0(List f0) { + this.integerListSize0 = f0; + } + + public List getF1() { + return integerList; + } + + public void setF1(List f1) { + this.integerList = f1; + } + + public List getF2() { + return stringList; + } + + public void setF2(List f2) { + this.stringList = f2; + } + + public List> getF3() { + return stringListList; + } + + public void setF3(List> f3) { + this.stringListList = f3; + } + + public List getF4() { + return sampleListNestedTypeList; + } + + public void setF4(List f4) { + this.sampleListNestedTypeList = f4; + } + + public List getF5() { + return byteBufferList; + } + + public void setF5(List f5) { + this.byteBufferList = f5; + } + + public SampleListTypes() { + } + } + + @MessagePackMessage + public static class SampleListNestedType { + public byte[] f0; + public String f1; + + public SampleListNestedType() { + } + } + + @Test + public void testOptionalListTypes00() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + 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"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.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)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleOptionalListNestedType s = src.f4.get(i); + SampleOptionalListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testOptionalListTypes01() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = null; + src.f2 = new ArrayList(); + src.f3 = new ArrayList>(); + src.f4 = null; + src.f5 = new ArrayList(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f3.size(), dst.f3.size()); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5.size(), dst.f5.size()); + } + + @Test + public void testOptionalListTypes02() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalListTypes { + @Optional + public List f0; + @Optional + public List f1; + @Optional + public List f2; + @Optional + public List> f3; + @Optional + public List f4; + @Optional + public List f5; + + @Optional + public List getF0() { + return f0; + } + + @Optional + public void setF0(List f0) { + this.f0 = f0; + } + + @Optional + public List getF1() { + return f1; + } + + public void setF1(List f1) { + this.f1 = f1; + } + + public List getF2() { + return f2; + } + + @Optional + public void setF2(List f2) { + this.f2 = f2; + } + + @Optional + public List> getF3() { + return f3; + } + + public void setF3(List> f3) { + this.f3 = f3; + } + + @Optional + public List getF4() { + return f4; + } + + public void setF4(List f4) { + this.f4 = f4; + } + + @Optional + public List getF5() { + return f5; + } + + public void setF5(List f5) { + this.f5 = f5; + } + + public SampleOptionalListTypes() { + } + } + + @MessagePackBeans + public static class SampleOptionalListNestedType { + @Optional + public byte[] f0; + @Optional + public String f1; + + @Optional + public byte[] getF0() { + return f0; + } + + public void setF0(byte[] f0) { + this.f0 = f0; + } + + @Optional + public String getF1() { + return f1; + } + + public void setF1(String f1) { + this.f1 = f1; + } + + public SampleOptionalListNestedType() { + } + } + + @Test + public void testMapTypes00() throws Exception { + SampleMapTypes src = new SampleMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + 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)); + } + } + + @Test + public void testMapTypes01() throws Exception { + SampleMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleMapTypes { + public Map f0; + public Map f1; + public Map f2; + + public Map getF0() { + return f0; + } + + public void setF0(Map f0) { + this.f0 = f0; + } + + public Map getF1() { + return f1; + } + + public void setF1(Map f1) { + this.f1 = f1; + } + + public Map getF2() { + return f2; + } + + public void setF2(Map f2) { + this.f2 = f2; + } + + public SampleMapTypes() { + } + } + + @Test + public void testOptionalMapTypes00() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.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)); + } + } + + @Test + public void testOptionalMapTypes01() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = null; + src.f2 = new HashMap(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + } + + @Test + public void testOptionalMapTypes02() throws Exception { + SampleOptionalMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalMapTypes { + @Optional + public Map f0; + @Optional + public Map f1; + @Optional + public Map f2; + + @Optional + public Map getF0() { + return f0; + } + + public void setF0(Map f0) { + this.f0 = f0; + } + + @Optional + public Map getF1() { + return f1; + } + + public void setF1(Map f1) { + this.f1 = f1; + } + + @Optional + public Map getF2() { + return f2; + } + + public void setF2(Map f2) { + this.f2 = f2; + } + + public SampleOptionalMapTypes() { + } + } + + + @MessagePackBeans + public abstract static class AbstractModifierClass { + } + + @Test + public void testInterfaceType00() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + @Test + public void testInterfaceType01() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + public interface SampleInterface { + } + + @Test + public void testEnumTypeForOrdinal00() throws Exception { + SampleEnumFieldClass src = new SampleEnumFieldClass(); + src.f0 = 23; + src.f1 = SampleEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + Assert.assertThat(dst.f0, is(src.f0)); + Assert.assertThat(dst.f1, is(src.f1)); + } + + @Test + public void testEnumTypeForOrdinal01() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + Assert.assertThat(dst,is(src)); + } + + @MessagePackBeans + public static class SampleEnumFieldClass { + public int f0; + + public SampleEnum f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public SampleEnum getF1() { + return f1; + } + + public void setF1(SampleEnum f1) { + this.f1 = f1; + } + + public SampleEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleEnum { + ONE, TWO, THREE; + } + + @Test + public void testOptionalEnumTypeForOrdinal00() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleOptionalEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal01() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal02() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalEnumFieldClass { + @Optional + public int f0; + + @Optional + public SampleOptionalEnum f1; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public SampleOptionalEnum getF1() { + return f1; + } + + public void setF1(SampleOptionalEnum f1) { + this.f1 = f1; + } + + public SampleOptionalEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleOptionalEnum { + ONE, TWO, THREE; + } + + @Test + public void testFieldModifiers() throws Exception { + FieldModifiersClass src = new FieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + FieldModifiersClass dst = + MessagePack.unpack(raw, FieldModifiersClass.class); + Assert.assertEquals(src.f1,dst.f1); + Assert.assertThat(dst.f2, is( not(src.f2))); + Assert.assertThat(dst.f3, is( not(src.f3))); + Assert.assertThat(dst.f4, is( not(src.f4))); + } + + @MessagePackBeans + public static class FieldModifiersClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + private int getF2() { + return f2; + } + + private void setF2(int f2) { + this.f2 = f2; + } + + public int getF3() { + return f3; + } + + protected void setF3(int f3) { + this.f3 = f3; + } + + public int getF4() { + return f4; + } + + void setF4(int f4) { + this.f4 = f4; + } + + public int getF1() { + return f1; + } + + public FieldModifiersClass() { + } + } + + @Test + public void testOptionalFieldModifiers() throws Exception { + OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + OptionalFieldModifiersClass dst = + MessagePack.unpack(raw, OptionalFieldModifiersClass.class); + Assert.assertThat(dst.f0, is(src.f0)); + Assert.assertThat(dst.f1, is(src.f1)); + Assert.assertThat(dst.f2, is(not(src.f2))); + Assert.assertThat(dst.f3, is(not(src.f3))); + Assert.assertThat(dst.f4, is(not(src.f4))); + } + + @MessagePackBeans + public static class OptionalFieldModifiersClass { + @Optional + public int f0; + @Optional + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + private int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + protected int getF3() { + return f3; + } + + protected void setF3(int f3) { + this.f3 = f3; + } + + public int getF4() { + return f4; + } + + void setF4(int f4) { + this.f4 = f4; + } + + public int getF1() { + return f1; + } + + public OptionalFieldModifiersClass() { + } + } + + @Test + public void testNestedFieldClass00() throws Exception { + BaseClass src = new BaseClass(); + NestedClass src2 = new NestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testNestedFieldClass01() throws Exception { + BaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class BaseClass { + public int f0; + public NestedClass f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public NestedClass getF1() { + return f1; + } + + public void setF1(NestedClass f1) { + this.f1 = f1; + } + + public BaseClass() { + } + } + + @MessagePackBeans + public static class NestedClass { + public int f2; + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public NestedClass() { + } + } + + @Test + public void testOptionalNestedFieldClass00() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + OptionalNestedClass src2 = new OptionalNestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalNestedFieldClass01() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalNestedFieldClass02() throws Exception { + OptionalBaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalBaseClass { + @Optional + public int f0; + @Optional + public OptionalNestedClass f1; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public OptionalNestedClass getF1() { + return f1; + } + + public void setF1(OptionalNestedClass f1) { + this.f1 = f1; + } + + public OptionalBaseClass() { + } + } + + @MessagePackBeans + public static class OptionalNestedClass { + @Optional + public int f2; + + @Optional + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public OptionalNestedClass() { + } + } + + @Test + public void testMessagePackMessageFieldClass00() throws Exception { + BaseClass2 src = new BaseClass2(); + MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testMessagePackMessageFieldClass01() throws Exception { + BaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class BaseClass2 { + public int f0; + public MessagePackMessageClass2 f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public MessagePackMessageClass2 getF1() { + return f1; + } + + public void setF1(MessagePackMessageClass2 f1) { + this.f1 = f1; + } + + public BaseClass2() { + } + } + + @MessagePackBeans + public static class MessagePackMessageClass2 { + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public int f2; + + public MessagePackMessageClass2() { + } + } + + @Test + public void testOptionalMessagePackMessageFieldClass00() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalMessagePackMessageFieldClass01() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalMessagePackMessageFieldClass02() throws Exception { + OptionalBaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalBaseClass2 { + @Optional + public int f0; + @Optional + public OptionalMessagePackMessageClass2 f1; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public OptionalMessagePackMessageClass2 getF1() { + return f1; + } + + public void setF1(OptionalMessagePackMessageClass2 f1) { + this.f1 = f1; + } + + public OptionalBaseClass2() { + } + } + + @MessagePackBeans + public static class OptionalMessagePackMessageClass2 { + @Optional + public int f2; + + @Optional + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public OptionalMessagePackMessageClass2() { + } + } + + @Test + public void testExtendedClass00() throws Exception { + SampleSubClass src = new SampleSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testExtendedClass01() throws Exception { + SampleSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, SampleSubClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleSubClass extends SampleSuperClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public SampleSubClass() { + } + } + + @MessagePackBeans + public static class SampleSuperClass { + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public int getF5() { + return f5; + } + + public void setF5(int f5) { + this.f5 = f5; + } + + public SampleSuperClass() { + } + } + + @Test + public void testOptionalExtendedClass00() throws Exception { + SampleOptionalSubClass src = new SampleOptionalSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.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); + } + + @Test + public void testOptionalExtendedClass01() throws Exception { + SampleOptionalSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalSubClass extends SampleOptionalSuperClass { + @Optional + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public SampleOptionalSubClass() { + } + } + + @MessagePackBeans + public static class SampleOptionalSuperClass { + @Optional + public int getF5() { + return f5; + } + + public void setF5(int f5) { + this.f5 = f5; + } + + @Optional + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleOptionalSuperClass() { + } + } + + @Test + public void testMessagePackableUnpackableClass00() throws Exception { + BaseMessagePackableUnpackableClass src = new BaseMessagePackableUnpackableClass(); + MessagePackableUnpackableClass src1 = new MessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testMessagePackableUnpackableClass01() throws Exception { + BaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class BaseMessagePackableUnpackableClass { + public MessagePackableUnpackableClass f0; + public int f1; + public List f2; + + public MessagePackableUnpackableClass getF0() { + return f0; + } + + public void setF0(MessagePackableUnpackableClass f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public List getF2() { + return f2; + } + + public void setF2(List f2) { + this.f2 = f2; + } + + public BaseMessagePackableUnpackableClass() { + } + } + + @MessagePackBeans + public static class MessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int f0; + public int f1; + + public MessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } + + @Test + public void testOptionalMessagePackableUnpackableClass00() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + OptionalMessagePackableUnpackableClass src1 = new OptionalMessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testOptionalMessagePackableUnpackableClass01() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + src.f0 = null; + src.f1 = 1; + src.f2 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + } + + @Test + public void testOptionalMessagePackableUnpackableClass02() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalBaseMessagePackableUnpackableClass { + @Optional + public OptionalMessagePackableUnpackableClass f0; + @Optional + public int f1; + @Optional + public List f2; + + @Optional + public OptionalMessagePackableUnpackableClass getF0() { + return f0; + } + + public void setF0(OptionalMessagePackableUnpackableClass f0) { + this.f0 = f0; + } + + @Optional + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + @Optional + public List getF2() { + return f2; + } + + public void setF2(List f2) { + this.f2 = f2; + } + + public OptionalBaseMessagePackableUnpackableClass() { + } + } + + @MessagePackBeans + public static class OptionalMessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + @Optional + public int f0; + @Optional + public int f1; + + public OptionalMessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } +} + diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java new file mode 100644 index 00000000..dcb039f7 --- /dev/null +++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java @@ -0,0 +1,1417 @@ +package org.msgpack.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import org.msgpack.MessagePack; +import org.msgpack.MessagePackable; +import org.msgpack.MessagePacker; +import org.msgpack.MessageTypeException; +import org.msgpack.MessageUnpackable; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.annotation.Optional; +import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.MessagePackBeansBuilderSelector; +import org.msgpack.template.builder.MessagePackMessageBuilderSelector; +import org.msgpack.template.builder.TemplateBuilder; + +import junit.framework.Assert; +import junit.framework.TestCase; + +public class TestReflectionTemplateBuilderPackConvert extends TestCase { + static { + //Replace template selectors from javassist to reflection. + BuilderSelectorRegistry instance = BuilderSelectorRegistry.getInstance(); + + instance.replace( + new MessagePackMessageBuilderSelector( + new ReflectionTemplateBuilder())); + instance.setForceBuilder( new ReflectionTemplateBuilder()); + instance.replace(new MessagePackBeansBuilderSelector( + new BeansReflectionTemplateBuilder())); + + MessagePack.register(PrimitiveTypeFieldsClass.class); + MessagePack.register(OptionalPrimitiveTypeFieldsClass.class); + MessagePack.register(GeneralReferenceTypeFieldsClass.class); + MessagePack.register(GeneralOptionalReferenceTypeFieldsClass.class); + MessagePack.register(SampleListTypes.class); + MessagePack.register(SampleOptionalListTypes.class); + MessagePack.register(SampleMapTypes.class); + MessagePack.register(SampleOptionalMapTypes.class); + MessagePack.register(SampleEnumFieldClass.class); + MessagePack.register(SampleOptionalEnumFieldClass.class); + MessagePack.register(FieldModifiersClass.class); + MessagePack.register(OptionalFieldModifiersClass.class); + MessagePack.register(BaseClass.class); + MessagePack.register(NestedClass.class); + MessagePack.register(BaseClass2.class); + MessagePack.register(OptionalBaseClass.class); + MessagePack.register(OptionalNestedClass.class); + MessagePack.register(OptionalBaseClass2.class); + MessagePack.register(SampleSubClass.class); + MessagePack.register(SampleSuperClass.class); + MessagePack.register(SampleOptionalSubClass.class); + MessagePack.register(SampleOptionalSuperClass.class); + MessagePack.register(BaseMessagePackableUnpackableClass.class); + MessagePack.register(MessagePackableUnpackableClass.class); + MessagePack.register(OptionalBaseMessagePackableUnpackableClass.class); + MessagePack.register(OptionalMessagePackableUnpackableClass.class); + } + + @Test + public void testPrimitiveTypeFields00() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(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); + } + + @Test + public void testPrimitiveTypeFields01() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(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); + } + + @Test + public void testPrimitiveTypeFields02() throws Exception { + PrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(PrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + 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 testOptionalPrimitiveTypeFields00() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(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); + } + + @Test + public void testOptionalPrimitiveTypeFields01() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(OptionalPrimitiveTypeFieldsClass.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); + } + + @Test + public void testOptionalPrimitiveTypeFields02() throws Exception { + OptionalPrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class OptionalPrimitiveTypeFieldsClass { + @Optional + public byte f0; + @Optional + public short f1; + @Optional + public int f2; + @Optional + public long f3; + @Optional + public float f4; + @Optional + public double f5; + @Optional + public boolean f6; + + public OptionalPrimitiveTypeFieldsClass() { + } + } + + @Test + public void testGeneralReferenceTypeFieldsClass00() throws Exception { + GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(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]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralReferenceTypeFieldsClass01() throws Exception { + GeneralReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + 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 ByteBuffer f10; + + public GeneralReferenceTypeFieldsClass() { + } + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass00() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralOptionalReferenceTypeFieldsClass.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]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass01() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = null; + src.f1 = null; + src.f2 = null; + src.f3 = null; + src.f4 = null; + src.f5 = null; + src.f6 = null; + src.f7 = null; + src.f8 = null; + src.f9 = null; + src.f10 = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralOptionalReferenceTypeFieldsClass.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, dst.f9); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass02() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class GeneralOptionalReferenceTypeFieldsClass { + @Optional + public Byte f0; + @Optional + public Short f1; + @Optional + public Integer f2; + @Optional + public Long f3; + @Optional + public Float f4; + @Optional + public Double f5; + @Optional + public Boolean f6; + @Optional + public BigInteger f7; + @Optional + public String f8; + @Optional + public byte[] f9; + @Optional + public ByteBuffer f10; + + public GeneralOptionalReferenceTypeFieldsClass() { + } + } + + @Test + public void testListTypes00() throws Exception { + SampleListTypes src = new SampleListTypes(); + 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"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleListNestedType slnt = new SampleListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw).convert(SampleListTypes.class); + 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)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleListNestedType s = src.f4.get(i); + SampleListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testListTypes01() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw).convert(SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleListTypes { + public List f0; + public List f1; + public List f2; + public List> f3; + public List f4; + public List f5; + + public SampleListTypes() { + } + } + + @MessagePackMessage + public static class SampleListNestedType { + public byte[] f0; + public String f1; + + public SampleListNestedType() { + } + } + + @Test + public void testOptionalListTypes00() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + 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"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalListTypes.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)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleOptionalListNestedType s = src.f4.get(i); + SampleOptionalListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testOptionalListTypes01() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = null; + src.f2 = new ArrayList(); + src.f3 = new ArrayList>(); + src.f4 = null; + src.f5 = new ArrayList(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f3.size(), dst.f3.size()); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5.size(), dst.f5.size()); + } + + @Test + public void testOptionalListTypes02() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw).convert(SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalListTypes { + @Optional + public List f0; + @Optional + public List f1; + @Optional + public List f2; + @Optional + public List> f3; + @Optional + public List f4; + @Optional + public List f5; + + public SampleOptionalListTypes() { + } + } + + @MessagePackMessage + public static class SampleOptionalListNestedType { + @Optional + public byte[] f0; + @Optional + public String f1; + + public SampleOptionalListNestedType() { + } + } + + @Test + public void testMapTypes00() throws Exception { + SampleMapTypes src = new SampleMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw).convert(SampleMapTypes.class); + 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)); + } + } + + @Test + public void testMapTypes01() throws Exception { + SampleMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw).convert(SampleMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleMapTypes { + public Map f0; + public Map f1; + public Map f2; + + public SampleMapTypes() { + } + } + + @Test + public void testOptionalMapTypes00() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalMapTypes.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)); + } + } + + @Test + public void testOptionalMapTypes01() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = null; + src.f2 = new HashMap(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + } + + @Test + public void testOptionalMapTypes02() throws Exception { + SampleOptionalMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalMapTypes { + @Optional + public Map f0; + @Optional + public Map f1; + @Optional + public Map f2; + + public SampleOptionalMapTypes() { + } + } + + @Test + public void testFinalClass() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(FinalModifierClass.class); + Assert.assertNull(builder);// no available builder + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(FinalModifierClass.class); + assertTrue(true); + } catch (TemplateBuildException e) { + fail(); + } + assertTrue(true); + } + + public final static class FinalModifierClass { + } + + public abstract static class AbstractModifierClass { + } + + @Test + public void testInterfaceType00() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder);// no available builder + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + @Test + public void testInterfaceType01() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder);// no available builder + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + public interface SampleInterface { + } + + @Test + public void testEnumTypeForOrdinal00() throws Exception { + SampleEnumFieldClass src = new SampleEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleEnumFieldClass.class); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testEnumTypeForOrdinal01() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleEnumFieldClass { + public int f0; + + public SampleEnum f1; + + public SampleEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleEnum { + ONE, TWO, THREE; + } + + @Test + public void testOptionalEnumTypeForOrdinal00() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleOptionalEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal01() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal02() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalEnumFieldClass { + @Optional + public int f0; + + @Optional + public SampleOptionalEnum f1; + + public SampleOptionalEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleOptionalEnum { + ONE, TWO, THREE; + } + + @Test + public void testFieldModifiers() throws Exception { + FieldModifiersClass src = new FieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + FieldModifiersClass dst = + MessagePack.unpack(raw).convert(FieldModifiersClass.class); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + } + + 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 testOptionalFieldModifiers() throws Exception { + OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + OptionalFieldModifiersClass dst = + MessagePack.unpack(raw).convert(OptionalFieldModifiersClass.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); + } + + public static class OptionalFieldModifiersClass { + @Optional + public int f0; + @Optional + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public OptionalFieldModifiersClass() { + } + } + + @Test + public void testNestedFieldClass00() throws Exception { + BaseClass src = new BaseClass(); + NestedClass src2 = new NestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw).convert(BaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testNestedFieldClass01() throws Exception { + BaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw).convert(BaseClass.class); + assertEquals(src, dst); + } + + public static class BaseClass { + public int f0; + public NestedClass f1; + + public BaseClass() { + } + } + + public static class NestedClass { + public int f2; + + public NestedClass() { + } + } + + @Test + public void testOptionalNestedFieldClass00() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + OptionalNestedClass src2 = new OptionalNestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw).convert(OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalNestedFieldClass01() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw).convert(OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalNestedFieldClass02() throws Exception { + OptionalBaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw).convert(OptionalBaseClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass { + @Optional + public int f0; + @Optional + public OptionalNestedClass f1; + + public OptionalBaseClass() { + } + } + + public static class OptionalNestedClass { + @Optional + public int f2; + + public OptionalNestedClass() { + } + } + + @Test + public void testMessagePackMessageFieldClass00() throws Exception { + BaseClass2 src = new BaseClass2(); + MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw).convert(BaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testMessagePackMessageFieldClass01() throws Exception { + BaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw).convert(BaseClass2.class); + assertEquals(src, dst); + } + + public static class BaseClass2 { + public int f0; + public MessagePackMessageClass2 f1; + + public BaseClass2() { + } + } + + @MessagePackMessage + public static class MessagePackMessageClass2 { + public int f2; + + public MessagePackMessageClass2() { + } + } + + @Test + public void testOptionalMessagePackMessageFieldClass00() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw).convert(OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalMessagePackMessageFieldClass01() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw).convert(OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalMessagePackMessageFieldClass02() throws Exception { + OptionalBaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw).convert(OptionalBaseClass2.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass2 { + @Optional + public int f0; + @Optional + public OptionalMessagePackMessageClass2 f1; + + public OptionalBaseClass2() { + } + } + + @MessagePackMessage + public static class OptionalMessagePackMessageClass2 { + @Optional + public int f2; + + public OptionalMessagePackMessageClass2() { + } + } + + @Test + public void testExtendedClass00() throws Exception { + SampleSubClass src = new SampleSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw).convert(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); + } + + @Test + public void testExtendedClass01() throws Exception { + SampleSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw).convert(SampleSubClass.class); + assertEquals(src, dst); + } + + 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; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleSuperClass() { + } + } + + @Test + public void testOptionalExtendedClass00() throws Exception { + SampleOptionalSubClass src = new SampleOptionalSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw).convert(SampleOptionalSubClass.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); + } + + @Test + public void testOptionalExtendedClass01() throws Exception { + SampleOptionalSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw).convert(SampleOptionalSubClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalSubClass extends SampleOptionalSuperClass { + @Optional + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public SampleOptionalSubClass() { + } + } + + public static class SampleOptionalSuperClass { + @Optional + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleOptionalSuperClass() { + } + } + + @Test + public void testMessagePackableUnpackableClass00() throws Exception { + BaseMessagePackableUnpackableClass src = new BaseMessagePackableUnpackableClass(); + MessagePackableUnpackableClass src1 = new MessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(BaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testMessagePackableUnpackableClass01() throws Exception { + BaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(BaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class BaseMessagePackableUnpackableClass { + public MessagePackableUnpackableClass f0; + public int f1; + public List f2; + + public BaseMessagePackableUnpackableClass() { + } + } + + public static class MessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + public int f0; + public int f1; + + public MessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } + + @Test + public void testOptionalMessagePackableUnpackableClass00() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + OptionalMessagePackableUnpackableClass src1 = new OptionalMessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testOptionalMessagePackableUnpackableClass01() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + src.f0 = null; + src.f1 = 1; + src.f2 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + } + + @Test + public void testOptionalMessagePackableUnpackableClass02() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseMessagePackableUnpackableClass { + @Optional + public OptionalMessagePackableUnpackableClass f0; + @Optional + public int f1; + @Optional + public List f2; + + public OptionalBaseMessagePackableUnpackableClass() { + } + } + + public static class OptionalMessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + @Optional + public int f0; + @Optional + public int f1; + + public OptionalMessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } +} + diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java new file mode 100644 index 00000000..6080df6e --- /dev/null +++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java @@ -0,0 +1,1422 @@ +package org.msgpack.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import org.msgpack.MessagePack; +import org.msgpack.MessagePackable; +import org.msgpack.MessagePacker; +import org.msgpack.MessageTypeException; +import org.msgpack.MessageUnpackable; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.annotation.Optional; +import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface; +import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.MessagePackBeansBuilderSelector; +import org.msgpack.template.builder.MessagePackMessageBuilderSelector; +import org.msgpack.template.builder.TemplateBuilder; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import static org.junit.Assert.assertThat; + +public class TestReflectionTemplateBuilderPackUnpack extends TestCase { + static { + //Replace template selectors from javassist to reflection. + BuilderSelectorRegistry instance = BuilderSelectorRegistry.getInstance(); + + instance.replace( + new MessagePackMessageBuilderSelector( + new ReflectionTemplateBuilder())); + instance.setForceBuilder( new ReflectionTemplateBuilder()); + instance.replace(new MessagePackBeansBuilderSelector( + new BeansReflectionTemplateBuilder())); + + + MessagePack.register(PrimitiveTypeFieldsClass.class); + MessagePack.register(OptionalPrimitiveTypeFieldsClass.class); + MessagePack.register(GeneralReferenceTypeFieldsClass.class); + MessagePack.register(GeneralOptionalReferenceTypeFieldsClass.class); + MessagePack.register(SampleListTypes.class); + MessagePack.register(SampleOptionalListTypes.class); + MessagePack.register(SampleMapTypes.class); + MessagePack.register(SampleOptionalMapTypes.class); + MessagePack.register(SampleEnumFieldClass.class); + MessagePack.register(SampleOptionalEnumFieldClass.class); + MessagePack.register(FieldModifiersClass.class); + MessagePack.register(OptionalFieldModifiersClass.class); + MessagePack.register(BaseClass.class); + MessagePack.register(NestedClass.class); + MessagePack.register(BaseClass2.class); + MessagePack.register(OptionalBaseClass.class); + MessagePack.register(OptionalNestedClass.class); + MessagePack.register(OptionalBaseClass2.class); + MessagePack.register(SampleSubClass.class); + MessagePack.register(SampleSuperClass.class); + MessagePack.register(SampleOptionalSubClass.class); + MessagePack.register(SampleOptionalSuperClass.class); + MessagePack.register(BaseMessagePackableUnpackableClass.class); + MessagePack.register(MessagePackableUnpackableClass.class); + MessagePack.register(OptionalBaseMessagePackableUnpackableClass.class); + MessagePack.register(OptionalMessagePackableUnpackableClass.class); + } + + @Test + public void testPrimitiveTypeFields00() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testPrimitiveTypeFields01() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testPrimitiveTypeFields02() throws Exception { + PrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + 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 testOptionalPrimitiveTypeFields00() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testOptionalPrimitiveTypeFields01() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.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); + } + + @Test + public void testOptionalPrimitiveTypeFields02() throws Exception { + OptionalPrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class OptionalPrimitiveTypeFieldsClass { + @Optional + public byte f0; + @Optional + public short f1; + @Optional + public int f2; + @Optional + public long f3; + @Optional + public float f4; + @Optional + public double f5; + @Optional + public boolean f6; + + public OptionalPrimitiveTypeFieldsClass() { + } + } + + @Test + public void testGeneralReferenceTypeFieldsClass00() throws Exception { + GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, 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]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralReferenceTypeFieldsClass01() throws Exception { + GeneralReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + 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 ByteBuffer f10; + + public GeneralReferenceTypeFieldsClass() { + } + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass00() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.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]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass01() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = null; + src.f1 = null; + src.f2 = null; + src.f3 = null; + src.f4 = null; + src.f5 = null; + src.f6 = null; + src.f7 = null; + src.f8 = null; + src.f9 = null; + src.f10 = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.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, dst.f9); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass02() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class GeneralOptionalReferenceTypeFieldsClass { + @Optional + public Byte f0; + @Optional + public Short f1; + @Optional + public Integer f2; + @Optional + public Long f3; + @Optional + public Float f4; + @Optional + public Double f5; + @Optional + public Boolean f6; + @Optional + public BigInteger f7; + @Optional + public String f8; + @Optional + public byte[] f9; + @Optional + public ByteBuffer f10; + + public GeneralOptionalReferenceTypeFieldsClass() { + } + } + + @Test + public void testListTypes00() throws Exception { + SampleListTypes src = new SampleListTypes(); + 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"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleListNestedType slnt = new SampleListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + 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)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleListNestedType s = src.f4.get(i); + SampleListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testListTypes01() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleListTypes { + public List f0; + public List f1; + public List f2; + public List> f3; + public List f4; + public List f5; + + public SampleListTypes() { + } + } + + @MessagePackMessage + public static class SampleListNestedType { + public byte[] f0; + public String f1; + + public SampleListNestedType() { + } + } + + @Test + public void testOptionalListTypes00() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + 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"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.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)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleOptionalListNestedType s = src.f4.get(i); + SampleOptionalListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testOptionalListTypes01() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = null; + src.f2 = new ArrayList(); + src.f3 = new ArrayList>(); + src.f4 = null; + src.f5 = new ArrayList(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f3.size(), dst.f3.size()); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5.size(), dst.f5.size()); + } + + @Test + public void testOptionalListTypes02() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalListTypes { + @Optional + public List f0; + @Optional + public List f1; + @Optional + public List f2; + @Optional + public List> f3; + @Optional + public List f4; + @Optional + public List f5; + + public SampleOptionalListTypes() { + } + } + + @MessagePackMessage + public static class SampleOptionalListNestedType { + @Optional + public byte[] f0; + @Optional + public String f1; + + public SampleOptionalListNestedType() { + } + } + + @Test + public void testMapTypes00() throws Exception { + SampleMapTypes src = new SampleMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + 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)); + } + } + + @Test + public void testMapTypes01() throws Exception { + SampleMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleMapTypes { + public Map f0; + public Map f1; + public Map f2; + + public SampleMapTypes() { + } + } + + @Test + public void testOptionalMapTypes00() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.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)); + } + } + + @Test + public void testOptionalMapTypes01() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = null; + src.f2 = new HashMap(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + } + + @Test + public void testOptionalMapTypes02() throws Exception { + SampleOptionalMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalMapTypes { + @Optional + public Map f0; + @Optional + public Map f1; + @Optional + public Map f2; + + public SampleOptionalMapTypes() { + } + } + + @Test + public void testFinalClass() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(FinalModifierClass.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(FinalModifierClass.class); + assertTrue(true); + } catch (TemplateBuildException e) { + fail(); + } + assertTrue(true); + } + + public final static class FinalModifierClass { + } + + public abstract static class AbstractModifierClass { + } + + @Test + public void testInterfaceType00() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + @Test + public void testInterfaceType01() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + public interface SampleInterface { + } + + @Test + public void testEnumTypeForOrdinal00() throws Exception { + SampleEnumFieldClass src = new SampleEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testEnumTypeForOrdinal01() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleEnumFieldClass { + public int f0; + + public SampleEnum f1; + + public SampleEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleEnum { + ONE, TWO, THREE; + } + + @Test + public void testOptionalEnumTypeForOrdinal00() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleOptionalEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal01() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal02() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalEnumFieldClass { + @Optional + public int f0; + + @Optional + public SampleOptionalEnum f1; + + public SampleOptionalEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleOptionalEnum { + ONE, TWO, THREE; + } + + @Test + public void testFieldModifiers() throws Exception { + FieldModifiersClass src = new FieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + FieldModifiersClass dst = + MessagePack.unpack(raw, FieldModifiersClass.class); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + } + + 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 testOptionalFieldModifiers() throws Exception { + OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + OptionalFieldModifiersClass dst = + MessagePack.unpack(raw, OptionalFieldModifiersClass.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); + } + + public static class OptionalFieldModifiersClass { + @Optional + public int f0; + @Optional + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public OptionalFieldModifiersClass() { + } + } + + @Test + public void testNestedFieldClass00() throws Exception { + BaseClass src = new BaseClass(); + NestedClass src2 = new NestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testNestedFieldClass01() throws Exception { + BaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertEquals(src, dst); + } + + public static class BaseClass { + public int f0; + public NestedClass f1; + + public BaseClass() { + } + } + + public static class NestedClass { + public int f2; + + public NestedClass() { + } + } + + @Test + public void testOptionalNestedFieldClass00() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + OptionalNestedClass src2 = new OptionalNestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalNestedFieldClass01() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalNestedFieldClass02() throws Exception { + OptionalBaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass { + @Optional + public int f0; + @Optional + public OptionalNestedClass f1; + + public OptionalBaseClass() { + } + } + + public static class OptionalNestedClass { + @Optional + public int f2; + + public OptionalNestedClass() { + } + } + + @Test + public void testMessagePackMessageFieldClass00() throws Exception { + BaseClass2 src = new BaseClass2(); + MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testMessagePackMessageFieldClass01() throws Exception { + BaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertEquals(src, dst); + } + + public static class BaseClass2 { + public int f0; + public MessagePackMessageClass2 f1; + + public BaseClass2() { + } + } + + @MessagePackMessage + public static class MessagePackMessageClass2 { + public int f2; + + public MessagePackMessageClass2() { + } + } + + @Test + public void testOptionalMessagePackMessageFieldClass00() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalMessagePackMessageFieldClass01() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalMessagePackMessageFieldClass02() throws Exception { + OptionalBaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass2 { + @Optional + public int f0; + @Optional + public OptionalMessagePackMessageClass2 f1; + + public OptionalBaseClass2() { + } + } + + @MessagePackMessage + public static class OptionalMessagePackMessageClass2 { + @Optional + public int f2; + + public OptionalMessagePackMessageClass2() { + } + } + + @Test + public void testExtendedClass00() throws Exception { + SampleSubClass src = new SampleSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testExtendedClass01() throws Exception { + SampleSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, SampleSubClass.class); + assertEquals(src, dst); + } + + 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; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleSuperClass() { + } + } + + @Test + public void testOptionalExtendedClass00() throws Exception { + SampleOptionalSubClass src = new SampleOptionalSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.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); + } + + @Test + public void testOptionalExtendedClass01() throws Exception { + SampleOptionalSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalSubClass extends SampleOptionalSuperClass { + @Optional + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public SampleOptionalSubClass() { + } + } + + public static class SampleOptionalSuperClass { + @Optional + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleOptionalSuperClass() { + } + } + + @Test + public void testMessagePackableUnpackableClass00() throws Exception { + BaseMessagePackableUnpackableClass src = new BaseMessagePackableUnpackableClass(); + MessagePackableUnpackableClass src1 = new MessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testMessagePackableUnpackableClass01() throws Exception { + BaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class BaseMessagePackableUnpackableClass { + public MessagePackableUnpackableClass f0; + public int f1; + public List f2; + + public BaseMessagePackableUnpackableClass() { + } + } + + public static class MessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + public int f0; + public int f1; + + public MessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } + + @Test + public void testOptionalMessagePackableUnpackableClass00() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + OptionalMessagePackableUnpackableClass src1 = new OptionalMessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testOptionalMessagePackableUnpackableClass01() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + src.f0 = null; + src.f1 = 1; + src.f2 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + } + + @Test + public void testOptionalMessagePackableUnpackableClass02() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseMessagePackableUnpackableClass { + @Optional + public OptionalMessagePackableUnpackableClass f0; + @Optional + public int f1; + @Optional + public List f2; + + public OptionalBaseMessagePackableUnpackableClass() { + } + } + + public static class OptionalMessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + @Optional + public int f0; + @Optional + public int f1; + + public OptionalMessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } +} + diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderJavaBeansPackUnpack.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderJavaBeansPackUnpack.java new file mode 100644 index 00000000..1310cddb --- /dev/null +++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderJavaBeansPackUnpack.java @@ -0,0 +1,2234 @@ +package org.msgpack.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.hamcrest.CoreMatchers; +import org.junit.Ignore; +import org.junit.Test; + +import org.msgpack.MessagePack; +import org.msgpack.MessagePackable; +import org.msgpack.MessagePacker; +import org.msgpack.MessageTypeException; +import org.msgpack.MessageUnpackable; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.annotation.MessagePackBeans; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.annotation.Optional; +import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface; +import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.TemplateBuilder; + +import org.junit.Assert; +import junit.framework.TestCase; +import static org.hamcrest.CoreMatchers.*; + +public class TestTemplateBuilderJavaBeansPackUnpack extends TestCase { + static { + MessagePack.register(PrimitiveTypeFieldsClass.class); + MessagePack.register(OptionalPrimitiveTypeFieldsClass.class); + MessagePack.register(GeneralReferenceTypeFieldsClass.class); + MessagePack.register(GeneralOptionalReferenceTypeFieldsClass.class); + MessagePack.register(SampleListTypes.class); + MessagePack.register(SampleOptionalListTypes.class); + MessagePack.register(SampleMapTypes.class); + MessagePack.register(SampleOptionalMapTypes.class); + MessagePack.register(SampleEnumFieldClass.class); + MessagePack.register(SampleOptionalEnumFieldClass.class); + MessagePack.register(FieldModifiersClass.class); + MessagePack.register(OptionalFieldModifiersClass.class); + MessagePack.register(BaseClass.class); + MessagePack.register(NestedClass.class); + MessagePack.register(BaseClass2.class); + MessagePack.register(OptionalBaseClass.class); + MessagePack.register(OptionalNestedClass.class); + MessagePack.register(OptionalBaseClass2.class); + MessagePack.register(SampleSubClass.class); + MessagePack.register(SampleSuperClass.class); + MessagePack.register(SampleOptionalSubClass.class); + MessagePack.register(SampleOptionalSuperClass.class); + MessagePack.register(BaseMessagePackableUnpackableClass.class); + MessagePack.register(MessagePackableUnpackableClass.class); + MessagePack.register(OptionalBaseMessagePackableUnpackableClass.class); + MessagePack.register(OptionalMessagePackableUnpackableClass.class); + } + + @Test + public void testPrimitiveTypeFields00() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testPrimitiveTypeFields01() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testPrimitiveTypeFields02() throws Exception { + PrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class PrimitiveTypeFieldsClass { + byte f0; + short f1; + int f2; + long f3; + float f4; + double f5; + boolean f6; + + public byte getF0() { + return f0; + } + + public void setF0(byte f0) { + this.f0 = f0; + } + + public short getF1() { + return f1; + } + + public void setF1(short f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public long getF3() { + return f3; + } + + public void setF3(long f3) { + this.f3 = f3; + } + + public float getF4() { + return f4; + } + + public void setF4(float f4) { + this.f4 = f4; + } + + public double getF5() { + return f5; + } + + public void setF5(double f5) { + this.f5 = f5; + } + + public boolean isF6() { + return f6; + } + + public void setF6(boolean f6) { + this.f6 = f6; + } + + public PrimitiveTypeFieldsClass() { + } + } + + @Test + public void testOptionalPrimitiveTypeFields00() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testOptionalPrimitiveTypeFields01() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.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); + } + + @Test + public void testOptionalPrimitiveTypeFields02() throws Exception { + OptionalPrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalPrimitiveTypeFieldsClass { + @Optional + public byte f0; + @Optional + public short f1; + @Optional + public int f2; + @Optional + public long f3; + @Optional + public float f4; + @Optional + public double f5; + @Optional + public boolean f6; + + @Optional + public byte getF0() { + return f0; + } + + @Optional + public void setF0(byte f0) { + this.f0 = f0; + } + + @Optional + public short getF1() { + return f1; + } + + public void setF1(short f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + @Optional + public void setF2(int f2) { + this.f2 = f2; + } + + @Optional + public long getF3() { + return f3; + } + + public void setF3(long f3) { + this.f3 = f3; + } + + @Optional + public float getF4() { + return f4; + } + + public void setF4(float f4) { + this.f4 = f4; + } + + @Optional + public double getF5() { + return f5; + } + + public void setF5(double f5) { + this.f5 = f5; + } + + @Optional + public boolean isF6() { + return f6; + } + + public void setF6(boolean f6) { + this.f6 = f6; + } + + public OptionalPrimitiveTypeFieldsClass() { + } + } + + @Test + public void testGeneralReferenceTypeFieldsClass00() throws Exception { + GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, 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]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralReferenceTypeFieldsClass01() throws Exception { + GeneralReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + 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 ByteBuffer f10; + + public Byte getF0() { + return f0; + } + + public void setF0(Byte f0) { + this.f0 = f0; + } + + public Short getF1() { + return f1; + } + + public void setF1(Short f1) { + this.f1 = f1; + } + + public Integer getF2() { + return f2; + } + + public void setF2(Integer f2) { + this.f2 = f2; + } + + public Long getF3() { + return f3; + } + + public void setF3(Long f3) { + this.f3 = f3; + } + + public Float getF4() { + return f4; + } + + public void setF4(Float f4) { + this.f4 = f4; + } + + public Double getF5() { + return f5; + } + + public void setF5(Double f5) { + this.f5 = f5; + } + + public Boolean getF6() { + return f6; + } + + public void setF6(Boolean f6) { + this.f6 = f6; + } + + public BigInteger getF7() { + return f7; + } + + public void setF7(BigInteger f7) { + this.f7 = f7; + } + + public String getF8() { + return f8; + } + + public void setF8(String f8) { + this.f8 = f8; + } + + public byte[] getF9() { + return f9; + } + + public void setF9(byte[] f9) { + this.f9 = f9; + } + + public ByteBuffer getF10() { + return f10; + } + + public void setF10(ByteBuffer f10) { + this.f10 = f10; + } + + public GeneralReferenceTypeFieldsClass() { + } + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass00() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + 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 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.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]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass01() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = null; + src.f1 = null; + src.f2 = null; + src.f3 = null; + src.f4 = null; + src.f5 = null; + src.f6 = null; + src.f7 = null; + src.f8 = null; + src.f9 = null; + src.f10 = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.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, dst.f9); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass02() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class GeneralOptionalReferenceTypeFieldsClass { + @Optional + public Byte f0; + @Optional + public Short f1; + @Optional + public Integer f2; + @Optional + public Long f3; + @Optional + public Float f4; + @Optional + public Double f5; + @Optional + public Boolean f6; + @Optional + public BigInteger f7; + @Optional + public String f8; + @Optional + public byte[] f9; + @Optional + public ByteBuffer f10; + + @Optional + public Byte getF0() { + return f0; + } + + @Optional + public void setF0(Byte f0) { + this.f0 = f0; + } + + @Optional + public Short getF1() { + return f1; + } + + public void setF1(Short f1) { + this.f1 = f1; + } + + public Integer getF2() { + return f2; + } + + @Optional + public void setF2(Integer f2) { + this.f2 = f2; + } + + @Optional + public Long getF3() { + return f3; + } + + public void setF3(Long f3) { + this.f3 = f3; + } + + @Optional + public Float getF4() { + return f4; + } + + public void setF4(Float f4) { + this.f4 = f4; + } + + @Optional + public Double getF5() { + return f5; + } + + public void setF5(Double f5) { + this.f5 = f5; + } + + @Optional + public Boolean getF6() { + return f6; + } + + public void setF6(Boolean f6) { + this.f6 = f6; + } + + @Optional + public BigInteger getF7() { + return f7; + } + + public void setF7(BigInteger f7) { + this.f7 = f7; + } + + @Optional + public String getF8() { + return f8; + } + + public void setF8(String f8) { + this.f8 = f8; + } + + @Optional + public byte[] getF9() { + return f9; + } + + public void setF9(byte[] f9) { + this.f9 = f9; + } + + @Optional + public ByteBuffer getF10() { + return f10; + } + + public void setF10(ByteBuffer f10) { + this.f10 = f10; + } + + public GeneralOptionalReferenceTypeFieldsClass() { + } + } + + @Test + public void testListTypes00() throws Exception { + SampleListTypes src = new SampleListTypes(); + 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"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleListNestedType slnt = new SampleListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + 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)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleListNestedType s = src.f4.get(i); + SampleListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testListTypes01() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleListTypes { + public List f0; + public List f1; + public List f2; + public List> f3; + public List f4; + public List f5; + + public List getF0() { + return f0; + } + + public void setF0(List f0) { + this.f0 = f0; + } + + public List getF1() { + return f1; + } + + public void setF1(List f1) { + this.f1 = f1; + } + + public List getF2() { + return f2; + } + + public void setF2(List f2) { + this.f2 = f2; + } + + public List> getF3() { + return f3; + } + + public void setF3(List> f3) { + this.f3 = f3; + } + + public List getF4() { + return f4; + } + + public void setF4(List f4) { + this.f4 = f4; + } + + public List getF5() { + return f5; + } + + public void setF5(List f5) { + this.f5 = f5; + } + + public SampleListTypes() { + } + } + + @MessagePackMessage + public static class SampleListNestedType { + public byte[] f0; + public String f1; + + public SampleListNestedType() { + } + } + + @Test + public void testOptionalListTypes00() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + 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"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.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)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleOptionalListNestedType s = src.f4.get(i); + SampleOptionalListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testOptionalListTypes01() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = null; + src.f2 = new ArrayList(); + src.f3 = new ArrayList>(); + src.f4 = null; + src.f5 = new ArrayList(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f3.size(), dst.f3.size()); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5.size(), dst.f5.size()); + } + + @Test + public void testOptionalListTypes02() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalListTypes { + @Optional + public List f0; + @Optional + public List f1; + @Optional + public List f2; + @Optional + public List> f3; + @Optional + public List f4; + @Optional + public List f5; + + @Optional + public List getF0() { + return f0; + } + + @Optional + public void setF0(List f0) { + this.f0 = f0; + } + + @Optional + public List getF1() { + return f1; + } + + public void setF1(List f1) { + this.f1 = f1; + } + + public List getF2() { + return f2; + } + + @Optional + public void setF2(List f2) { + this.f2 = f2; + } + + @Optional + public List> getF3() { + return f3; + } + + public void setF3(List> f3) { + this.f3 = f3; + } + + @Optional + public List getF4() { + return f4; + } + + public void setF4(List f4) { + this.f4 = f4; + } + + @Optional + public List getF5() { + return f5; + } + + public void setF5(List f5) { + this.f5 = f5; + } + + public SampleOptionalListTypes() { + } + } + + @MessagePackBeans + public static class SampleOptionalListNestedType { + @Optional + public byte[] f0; + @Optional + public String f1; + + @Optional + public byte[] getF0() { + return f0; + } + + public void setF0(byte[] f0) { + this.f0 = f0; + } + + @Optional + public String getF1() { + return f1; + } + + public void setF1(String f1) { + this.f1 = f1; + } + + public SampleOptionalListNestedType() { + } + } + + @Test + public void testMapTypes00() throws Exception { + SampleMapTypes src = new SampleMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + 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)); + } + } + + @Test + public void testMapTypes01() throws Exception { + SampleMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleMapTypes { + public Map f0; + public Map f1; + public Map f2; + + public Map getF0() { + return f0; + } + + public void setF0(Map f0) { + this.f0 = f0; + } + + public Map getF1() { + return f1; + } + + public void setF1(Map f1) { + this.f1 = f1; + } + + public Map getF2() { + return f2; + } + + public void setF2(Map f2) { + this.f2 = f2; + } + + public SampleMapTypes() { + } + } + + @Test + public void testOptionalMapTypes00() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + 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); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.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)); + } + } + + @Test + public void testOptionalMapTypes01() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = null; + src.f2 = new HashMap(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + } + + @Test + public void testOptionalMapTypes02() throws Exception { + SampleOptionalMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalMapTypes { + @Optional + public Map f0; + @Optional + public Map f1; + @Optional + public Map f2; + + @Optional + public Map getF0() { + return f0; + } + + public void setF0(Map f0) { + this.f0 = f0; + } + + @Optional + public Map getF1() { + return f1; + } + + public void setF1(Map f1) { + this.f1 = f1; + } + + @Optional + public Map getF2() { + return f2; + } + + public void setF2(Map f2) { + this.f2 = f2; + } + + public SampleOptionalMapTypes() { + } + } + + + @MessagePackBeans + public abstract static class AbstractModifierClass { + } + + @Test + public void testInterfaceType00() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + @Test + public void testInterfaceType01() throws Exception { + try { + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + public interface SampleInterface { + } + + @Test + public void testEnumTypeForOrdinal00() throws Exception { + SampleEnumFieldClass src = new SampleEnumFieldClass(); + src.f0 = 23; + src.f1 = SampleEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + Assert.assertThat(dst.f0, is(src.f0)); + Assert.assertThat(dst.f1, is(src.f1)); + } + + @Test + public void testEnumTypeForOrdinal01() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + Assert.assertThat(dst,is(src)); + } + + @MessagePackBeans + public static class SampleEnumFieldClass { + public int f0; + + public SampleEnum f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public SampleEnum getF1() { + return f1; + } + + public void setF1(SampleEnum f1) { + this.f1 = f1; + } + + public SampleEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleEnum { + ONE, TWO, THREE; + } + + @Test + public void testOptionalEnumTypeForOrdinal00() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleOptionalEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal01() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal02() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalEnumFieldClass { + @Optional + public int f0; + + @Optional + public SampleOptionalEnum f1; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public SampleOptionalEnum getF1() { + return f1; + } + + public void setF1(SampleOptionalEnum f1) { + this.f1 = f1; + } + + public SampleOptionalEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleOptionalEnum { + ONE, TWO, THREE; + } + + @Test + public void testFieldModifiers() throws Exception { + FieldModifiersClass src = new FieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + FieldModifiersClass dst = + MessagePack.unpack(raw, FieldModifiersClass.class); + Assert.assertEquals(src.f1,dst.f1); + Assert.assertThat(dst.f2, is( not(src.f2))); + Assert.assertThat(dst.f3, is( not(src.f3))); + Assert.assertThat(dst.f4, is( not(src.f4))); + } + + @MessagePackBeans + public static class FieldModifiersClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + private int getF2() { + return f2; + } + + private void setF2(int f2) { + this.f2 = f2; + } + + public int getF3() { + return f3; + } + + protected void setF3(int f3) { + this.f3 = f3; + } + + public int getF4() { + return f4; + } + + void setF4(int f4) { + this.f4 = f4; + } + + public int getF1() { + return f1; + } + + public FieldModifiersClass() { + } + } + + @Test + public void testOptionalFieldModifiers() throws Exception { + OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + OptionalFieldModifiersClass dst = + MessagePack.unpack(raw, OptionalFieldModifiersClass.class); + Assert.assertThat(dst.f0, is(src.f0)); + Assert.assertThat(dst.f1, is(src.f1)); + Assert.assertThat(dst.f2, is(not(src.f2))); + Assert.assertThat(dst.f3, is(not(src.f3))); + Assert.assertThat(dst.f4, is(not(src.f4))); + } + + @MessagePackBeans + public static class OptionalFieldModifiersClass { + @Optional + public int f0; + @Optional + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + private int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + protected int getF3() { + return f3; + } + + protected void setF3(int f3) { + this.f3 = f3; + } + + public int getF4() { + return f4; + } + + void setF4(int f4) { + this.f4 = f4; + } + + public int getF1() { + return f1; + } + + public OptionalFieldModifiersClass() { + } + } + + @Test + public void testNestedFieldClass00() throws Exception { + BaseClass src = new BaseClass(); + NestedClass src2 = new NestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testNestedFieldClass01() throws Exception { + BaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class BaseClass { + public int f0; + public NestedClass f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public NestedClass getF1() { + return f1; + } + + public void setF1(NestedClass f1) { + this.f1 = f1; + } + + public BaseClass() { + } + } + + @MessagePackBeans + public static class NestedClass { + public int f2; + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public NestedClass() { + } + } + + @Test + public void testOptionalNestedFieldClass00() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + OptionalNestedClass src2 = new OptionalNestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalNestedFieldClass01() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalNestedFieldClass02() throws Exception { + OptionalBaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalBaseClass { + @Optional + public int f0; + @Optional + public OptionalNestedClass f1; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public OptionalNestedClass getF1() { + return f1; + } + + public void setF1(OptionalNestedClass f1) { + this.f1 = f1; + } + + public OptionalBaseClass() { + } + } + + @MessagePackBeans + public static class OptionalNestedClass { + @Optional + public int f2; + + @Optional + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public OptionalNestedClass() { + } + } + + @Test + public void testMessagePackMessageFieldClass00() throws Exception { + BaseClass2 src = new BaseClass2(); + MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testMessagePackMessageFieldClass01() throws Exception { + BaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class BaseClass2 { + public int f0; + public MessagePackMessageClass2 f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public MessagePackMessageClass2 getF1() { + return f1; + } + + public void setF1(MessagePackMessageClass2 f1) { + this.f1 = f1; + } + + public BaseClass2() { + } + } + + @MessagePackBeans + public static class MessagePackMessageClass2 { + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public int f2; + + public MessagePackMessageClass2() { + } + } + + @Test + public void testOptionalMessagePackMessageFieldClass00() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalMessagePackMessageFieldClass01() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalMessagePackMessageFieldClass02() throws Exception { + OptionalBaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalBaseClass2 { + @Optional + public int f0; + @Optional + public OptionalMessagePackMessageClass2 f1; + + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public OptionalMessagePackMessageClass2 getF1() { + return f1; + } + + public void setF1(OptionalMessagePackMessageClass2 f1) { + this.f1 = f1; + } + + public OptionalBaseClass2() { + } + } + + @MessagePackBeans + public static class OptionalMessagePackMessageClass2 { + @Optional + public int f2; + + @Optional + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public OptionalMessagePackMessageClass2() { + } + } + + @Test + public void testExtendedClass00() throws Exception { + SampleSubClass src = new SampleSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, 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); + } + + @Test + public void testExtendedClass01() throws Exception { + SampleSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, SampleSubClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleSubClass extends SampleSuperClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public SampleSubClass() { + } + } + + @MessagePackBeans + public static class SampleSuperClass { + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public int getF5() { + return f5; + } + + public void setF5(int f5) { + this.f5 = f5; + } + + public SampleSuperClass() { + } + } + + @Test + public void testOptionalExtendedClass00() throws Exception { + SampleOptionalSubClass src = new SampleOptionalSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.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); + } + + @Test + public void testOptionalExtendedClass01() throws Exception { + SampleOptionalSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class SampleOptionalSubClass extends SampleOptionalSuperClass { + @Optional + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public SampleOptionalSubClass() { + } + } + + @MessagePackBeans + public static class SampleOptionalSuperClass { + @Optional + public int getF5() { + return f5; + } + + public void setF5(int f5) { + this.f5 = f5; + } + + @Optional + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleOptionalSuperClass() { + } + } + + @Test + public void testMessagePackableUnpackableClass00() throws Exception { + BaseMessagePackableUnpackableClass src = new BaseMessagePackableUnpackableClass(); + MessagePackableUnpackableClass src1 = new MessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testMessagePackableUnpackableClass01() throws Exception { + BaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class BaseMessagePackableUnpackableClass { + public MessagePackableUnpackableClass f0; + public int f1; + public List f2; + + public MessagePackableUnpackableClass getF0() { + return f0; + } + + public void setF0(MessagePackableUnpackableClass f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public List getF2() { + return f2; + } + + public void setF2(List f2) { + this.f2 = f2; + } + + public BaseMessagePackableUnpackableClass() { + } + } + + @MessagePackBeans + public static class MessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int f0; + public int f1; + + public MessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } + + @Test + public void testOptionalMessagePackableUnpackableClass00() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + OptionalMessagePackableUnpackableClass src1 = new OptionalMessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testOptionalMessagePackableUnpackableClass01() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + src.f0 = null; + src.f1 = 1; + src.f2 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + } + + @Test + public void testOptionalMessagePackableUnpackableClass02() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + @MessagePackBeans + public static class OptionalBaseMessagePackableUnpackableClass { + @Optional + public OptionalMessagePackableUnpackableClass f0; + @Optional + public int f1; + @Optional + public List f2; + + @Optional + public OptionalMessagePackableUnpackableClass getF0() { + return f0; + } + + public void setF0(OptionalMessagePackableUnpackableClass f0) { + this.f0 = f0; + } + + @Optional + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + @Optional + public List getF2() { + return f2; + } + + public void setF2(List f2) { + this.f2 = f2; + } + + public OptionalBaseMessagePackableUnpackableClass() { + } + } + + @MessagePackBeans + public static class OptionalMessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + @Optional + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + @Optional + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + @Optional + public int f0; + @Optional + public int f1; + + public OptionalMessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } +} + diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java index a99fa260..f316e64a 100644 --- a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java +++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java @@ -24,7 +24,10 @@ import org.msgpack.Unpacker; import org.msgpack.annotation.MessagePackMessage; import org.msgpack.annotation.MessagePackOrdinalEnum; import org.msgpack.annotation.Optional; +import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.TemplateBuilder; +import junit.framework.Assert; import junit.framework.TestCase; public class TestTemplateBuilderPackConvert extends TestCase { @@ -714,7 +717,9 @@ public class TestTemplateBuilderPackConvert extends TestCase { @Test public void testFinalClass() throws Exception { try { - TemplateBuilder.build(FinalModifierClass.class); + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(FinalModifierClass.class); + Assert.assertNull(builder);// no available builder + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(FinalModifierClass.class); assertTrue(true); } catch (TemplateBuildException e) { fail(); @@ -731,7 +736,9 @@ public class TestTemplateBuilderPackConvert extends TestCase { @Test public void testInterfaceType00() throws Exception { try { - TemplateBuilder.build(SampleInterface.class); + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder);// no available builder + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); fail(); } catch (TemplateBuildException e) { assertTrue(true); @@ -742,7 +749,9 @@ public class TestTemplateBuilderPackConvert extends TestCase { @Test public void testInterfaceType01() throws Exception { try { - TemplateBuilder.build(SampleInterface.class); + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder);// no available builder + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); fail(); } catch (TemplateBuildException e) { assertTrue(true); diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java index a2430a43..9ac94ef7 100644 --- a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java +++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java @@ -24,7 +24,11 @@ import org.msgpack.Unpacker; import org.msgpack.annotation.MessagePackMessage; import org.msgpack.annotation.MessagePackOrdinalEnum; import org.msgpack.annotation.Optional; +import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface; +import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.TemplateBuilder; +import junit.framework.Assert; import junit.framework.TestCase; public class TestTemplateBuilderPackUnpack extends TestCase { @@ -714,7 +718,9 @@ public class TestTemplateBuilderPackUnpack extends TestCase { @Test public void testFinalClass() throws Exception { try { - TemplateBuilder.build(FinalModifierClass.class); + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(FinalModifierClass.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(FinalModifierClass.class); assertTrue(true); } catch (TemplateBuildException e) { fail(); @@ -731,7 +737,9 @@ public class TestTemplateBuilderPackUnpack extends TestCase { @Test public void testInterfaceType00() throws Exception { try { - TemplateBuilder.build(SampleInterface.class); + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); fail(); } catch (TemplateBuildException e) { assertTrue(true); @@ -742,7 +750,9 @@ public class TestTemplateBuilderPackUnpack extends TestCase { @Test public void testInterfaceType01() throws Exception { try { - TemplateBuilder.build(SampleInterface.class); + TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(SampleInterface.class); + Assert.assertNull(builder); + BuilderSelectorRegistry.getInstance().getForceBuilder().buildTemplate(SampleInterface.class); fail(); } catch (TemplateBuildException e) { assertTrue(true); diff --git a/scala/.gitignore b/scala/.gitignore new file mode 100644 index 00000000..97250138 --- /dev/null +++ b/scala/.gitignore @@ -0,0 +1,40 @@ +# use glob syntax. +syntax: glob +*.ser +*.class +*~ +*.bak +#*.off +*.old + +# eclipse conf file +.settings +.classpath +.project +.manager +.scala_dependencies + +# idea +.idea +*.iml + +# building +target +build +null +tmp* +dist +test-output +build.log + +# other scm +.svn +.CVS +.hg* + +# switch to regexp syntax. +# syntax: regexp +# ^\.pc/ + +#SHITTY output not in target directory +build.log diff --git a/scala/pom.xml b/scala/pom.xml new file mode 100644 index 00000000..b6a14f2c --- /dev/null +++ b/scala/pom.xml @@ -0,0 +1,158 @@ + + 4.0.0 + org.msgpack + scala-msgpack + 0.0.1-SNAPSHOT + ${project.artifactId} + My wonderfull scala app + 2010 + + + My License + http://.... + repo + + + + + 1.5 + 1.5 + UTF-8 + 2.8.1 + + + + msgpack.org + MessagePack Repository for Maven + http://msgpack.org/maven2/ + + + + + + + org.scala-lang + scala-library + ${scala.version} + + + + + junit + junit + 4.8.1 + test + + + org.scala-tools.testing + specs_${scala.version} + 1.6.6 + test + + + org.msgpack + msgpack + 0.5.2-SNAPSHOT + + + + + + false + msgpack.org + Repository at msgpack.org + + ${deploy-release-url} + + + true + msgpack.org + Repository at msgpack.org + + ${deploy-snapshot-url} + + + + + src/main/scala + src/test/scala + + + org.scala-tools + maven-scala-plugin + 2.15.0 + + + + compile + testCompile + + + + -make:transitive + -dependencyfile + ${project.build.directory}/.scala_dependencies + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.6 + + false + true + + + + **/*Test.* + **/*Suite.* + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + maven-assembly-plugin + + + + jar-with-dependencies + + + + + + + make-assembly + package + + single + + + + + + + + diff --git a/scala/src/main/scala/org/msgpack/App.scala b/scala/src/main/scala/org/msgpack/App.scala new file mode 100644 index 00000000..f80d7a0d --- /dev/null +++ b/scala/src/main/scala/org/msgpack/App.scala @@ -0,0 +1,15 @@ +package org.msgpack + +/** + * @author ${user.name} + */ +object App { + + def foo(x : Array[String]) = x.foldLeft("")((a,b) => a + b) + + def main(args : Array[String]) { + println( "Hello World!" ) + println("concat arguments = " + foo(args)) + } + +} diff --git a/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala b/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala new file mode 100644 index 00000000..879bddea --- /dev/null +++ b/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala @@ -0,0 +1,521 @@ +package org.msgpack + +import _root_.javassist.{CtClass, CtNewConstructor} +import annotation._ +import template._ +import java.lang.Class +import collection.immutable.{ListMap, TreeMap} +import java.lang.reflect.{Type, Modifier, Method, Field} +import java.lang.annotation.{Annotation => JavaAnnotation} +import javassist.{JavassistTemplate, BuildContextBase, BuildContext} +import scala.collection.JavaConverters._ +; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/10 + * Time: 12:29 + */ + + + class BuildContextForScala(builder : JavassistTemplateBuilder) extends BuildContextBase[IFieldEntry](builder){ + + var entries : Array[IFieldEntry] = null + var origClass : Class[_] = null + var origName : String = null + var templates : Array[Template] = null + var minimumArrayLength : Int = 0 + + def buildTemplate(targetClass : Class[_] , entries : Array[IFieldEntry], templates : Array[Template]) = { + this.entries = entries; + this.templates = templates; + this.origClass = targetClass; + this.origName = this.origClass.getName(); + build(this.origName); + } + + def setSuperClass() = { + tmplCtClass.setSuperclass(director.getCtClass(classOf[JavassistTemplate].getName)) + } + + def buildConstructor() = { + val newCtCons = CtNewConstructor.make( + Array[CtClass]( + director.getCtClass(classOf[Class[_]].getName), + director.getCtClass(classOf[Template].getName + "[]") + ), + new Array[CtClass](0), + tmplCtClass + ) + this.tmplCtClass.addConstructor(newCtCons) + } + def buildInstance(c : Class[_]) = { + val cons = c.getConstructor(classOf[Class[_]], classOf[Array[Template]]) + val tmpl = cons.newInstance(origClass,templates) + tmpl.asInstanceOf[Template] + } + override def buildMethodInit() = { + this.minimumArrayLength = 0; + var i : Int = 0 + for(e <- entries) { + if(e.isRequired() || e.isNullable()) { + this.minimumArrayLength = i+1; + } + i += 1 + } + } + + lazy val newInstanceDeclaration : String = { + + def defCon = "new " + origClass.getName + "();" + try{ + val c = origClass.getClassLoader.loadClass(origClass.getName + "$") + if(Modifier.isPublic(c.getModifiers)){ + val method = c.getMethod("apply") + + if(Modifier.isPublic(method.getModifiers) && + origClass.isAssignableFrom(method.getReturnType)){ + val staticField = c.getDeclaredField("MODULE$") + "%s.%s.apply();".format(c.getName,staticField.getName) + }else{ + defCon + } + }else{ + defCon + } + }catch{ + case e : ClassNotFoundException => { + defCon + } + } + } + + protected def buildPackMethodBody() : String = { + resetStringBuilder(); + buildString("{"); + buildString("%s _$$_t = (%s)$2;", this.origName, this.origName); + buildString("$1.packArray(%d);", entries.length.asInstanceOf[AnyRef]); + for(i <- 0 until entries.length) { + val e = entries(i) + + if(!e.isAvailable) { + buildString("$1.packNil();"); + }else{ + val t = e.getType; + if(t.isPrimitive()) { + buildString("$1.%s(_$$_t.%s());", primitivePackName(t), e.getName()); + } else { + buildString("if(_$$_t.%s() == null) {", e.getName()); + if(!e.isNullable() && !e.isOptional()) { + buildString("throw new %s();", classOf[MessageTypeException].getName()); + } else { + buildString("$1.packNil();"); + } + buildString("} else {"); + buildString(" this.templates[%d].pack($1, _$$_t.%s());", i.asInstanceOf[AnyRef], e.getName()); + buildString("}"); + } + } + + } + buildString("}"); + return getBuiltString(); + } + + + def buildUnpackMethodBody() : String = { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = " + newInstanceDeclaration) //new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("int length = $1.unpackArray();"); + buildString("if(length < %d) {", this.minimumArrayLength.asInstanceOf[AnyRef]); + buildString(" throw new %s();", classOf[MessageTypeException].getName()); + buildString("}"); + + for(i <- 0 until this.minimumArrayLength) { + val e = entries(i); + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + }else{ + + buildString("if($1.tryUnpackNull()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", classOf[MessageTypeException].getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s_$eq(null);", e.getName()); + } + buildString("} else {"); + val t = e.getType(); + if(t.isPrimitive()) { + buildString("_$$_t.%s_$eq( $1.%s() );", e.getName(), primitiveUnpackName(t)); + } else { + buildString("_$$_t.%s_$eq( (%s)this.templates[%d].unpack($1, _$$_t.%s()));", e.getName(), e.getJavaTypeName(), i.asInstanceOf[AnyRef], e.getName()); + } + buildString("}"); + } + } + + for(i <- this.minimumArrayLength until entries.length) { + buildString("if(length <= %d) { return _$$_t; }", i.asInstanceOf[AnyRef]); + + val e = entries(i); + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + }else{ + + buildString("if($1.tryUnpackNull()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + val t = e.getType(); + if(t.isPrimitive()) { + buildString("_$$_t.%s_$eq( $1.%s());", e.getName(), primitiveUnpackName(t)); + } else { + buildString("_$$_t.%s_$eq( (%s)this.templates[%d].unpack($1, _$$_t.%s) );", e.getName(), e.getJavaTypeName(), i.asInstanceOf[AnyRef], e.getName()); + } + buildString("}"); + } + } + + // latter entries are all Optional + nil => keep default value + + buildString("for(int i=%d; i < length; i++) {", entries.length.asInstanceOf[AnyRef]); + buildString(" $1.unpackObject();"); + buildString("}"); + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + + protected override def buildConvertMethodBody() : String = { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = " + newInstanceDeclaration) //new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("%s[] array = $1.asArray();", classOf[MessagePackObject].getName()); + buildString("int length = array.length;"); + buildString("if(length < %d) {", this.minimumArrayLength.asInstanceOf[AnyRef]); + buildString(" throw new %s();", classOf[MessageTypeException].getName()); + buildString("}"); + + buildString("%s obj;", classOf[MessagePackObject].getName()); + + for(i <- 0 until this.minimumArrayLength) { + val e = entries(i); + if(e.isAvailable()) { + buildString("obj = array[%d];", i.asInstanceOf[AnyRef]); + buildString("if(obj.isNil()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", classOf[MessageTypeException].getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s_$eq( null );", e.getName()); + } + buildString("} else {"); + val t = e.getType(); + if(t.isPrimitive()) { + buildString("_$$_t.%s_$eq( obj.%s());", e.getName(), primitiveConvertName(t)); + } else { + buildString("_$$_t.%s_$eq( (%s)this.templates[%d].convert(obj, _$$_t.%s()) );", e.getName(), e.getJavaTypeName(), i.asInstanceOf[AnyRef], e.getName()); + } + buildString("}"); + } + } + + for(i <- this.minimumArrayLength until entries.length) { + buildString("if(length <= %d) { return _$$_t; }", i.asInstanceOf[AnyRef]); + + val e = entries(i); + if(e.isAvailable()) { + + + buildString("obj = array[%d];", i.asInstanceOf[AnyRef]); + buildString("if(obj.isNil()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + val t = e.getType(); + if(t.isPrimitive()) { + buildString("_$$_t.%s_$eq( obj.%s());", e.getName(), primitiveConvertName(t)); + } else { + buildString("_$$_t.%s_$eq( (%s)this.templates[%d].convert(obj, _$$_t.%s) );", e.getName(), e.getJavaTypeName(), i.asInstanceOf[AnyRef], e.getName()); + } + buildString("}"); + } + } + + // latter entries are all Optional + nil => keep default value + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + } + +class ScalaFieldEntryReader extends IFieldEntryReader{ + + type Property = (Method,Method,Field) + type PropertySet = (String,Property) + + def readImplicitFieldOption(targetClass: Class[_]) = { + FieldOption.NULLABLE + } + + def convertFieldEntries(targetClass: Class[_], flist: FieldList) = { + + val list : List[FieldList.Entry] = flist.getList.asScala.toList + + list.map( s => { + if(s.isAvailable){ + val getter = targetClass.getMethod(s.getName) + if(getter.getReturnType.getName != "void"){ + val setter = targetClass.getMethod(s.getName + "_$eq",getter.getReturnType) + if(setter.getReturnType.getName == "void"){ + val f = try{targetClass.getDeclaredField(s.getName)} + catch{ + case e : NoSuchFieldException => null + } + val prop = (s.getName,(getter,setter,f)) + convertToScalaFieldEntry(prop) + }else{ + new ScalaFieldEntry("") + } + }else new ScalaFieldEntry("") + }else{ + new ScalaFieldEntry("") + } + }).toArray + } + + def readFieldEntries(targetClass: Class[_], implicitOption: FieldOption) = { + val props = findPropertyMethods(targetClass) filter( !hasAnnotation(_,classOf[Ignore])) + + val indexed = indexing(props) + indexed.map(convertToScalaFieldEntry(_)) + } + + + def setter_?(method : Method) : Boolean = { + Modifier.isPublic(method.getModifiers) && + method.getReturnType.getName == "void" && + method.getName.endsWith("_$eq") && + method.getParameterTypes.length == 1 + } + + def getter_?(method : Method) : Boolean = { + Modifier.isPublic(method.getModifiers) && + method.getReturnType.getName != "void" && + method.getParameterTypes.length == 0 + + } + + + + + def findPropertyMethods(targetClass: Class[_]) : Map[String,Property] = { + var getters : Map[String,Method] = ListMap.empty + var setters : Map[String,Method] = ListMap.empty + + def extractName( n : String) = { + n.substring(0,n.length - 4) + } + + //Find getters and setters + for( m <- targetClass.getMethods){ + if(setter_?(m)){ + setters +=(extractName(m.getName) -> m) + }else if(getter_?(m)){ + getters +=(m.getName -> m) + } + } + + var props : Map[String,Property] = ListMap.empty + + def sameType_?( getter : Method,setter : Method) = { + getter.getReturnType == setter.getParameterTypes()(0) + } + + for(g <- getters){ + setters.get(g._1).map( s => { + if(sameType_?(g._2,s)){ + + val name = g._1 + val f = try{targetClass.getDeclaredField(name)} + catch{ + case e : NoSuchFieldException => null + } + + //TODO add validation for field + props +=( name -> (g._2,s,f)) + } + }) + } + props + } + + def indexing( props : Map[String , Property]) : Array[PropertySet] = { + val indexed = new Array[PropertySet](props.size) + + var notIndexed : List[PropertySet] = Nil + + for(s <- props){ + val i = getAnnotation(s,classOf[Index]) + if(i == null){ + notIndexed = notIndexed :+ s + }else{ + val index = i.value + if(indexed(index) != null){ + throw new TemplateBuildException("duplicated index: "+index); + }else{ + try{ + indexed(index) = s + }catch{ + case e : Exception => { + throw new TemplateBuildException("invalid index: %s index must be 0 <= x < %s".format(index,indexed.length)); + } + } + } + } + } + + for( i <- 0 until indexed.length ){ + if(indexed(i) == null){ + indexed(i) = notIndexed.head + notIndexed = notIndexed.drop(1) + } + } + + + indexed + } + + def convertToScalaFieldEntry( propInfo : PropertySet) = { + val entry = new ScalaFieldEntry(propInfo._1) + entry.option = readFieldOption(propInfo,FieldOption.NULLABLE) + entry.normalType = readValueType(propInfo) + entry.genericType = readGenericType(propInfo) + + entry + } + + + def hasAnnotation[T <: JavaAnnotation](prop : PropertySet , classOfAnno : Class[T]) : Boolean = { + val getter = prop._2._1 + val setter = prop._2._2 + val field = prop._2._3 + getter.getAnnotation(classOfAnno) != null || + setter.getAnnotation(classOfAnno) != null || + {if(field != null) field.getAnnotation(classOfAnno) != null + else false} + } + def getAnnotation[T <: JavaAnnotation](prop : PropertySet , classOfAnno : Class[T]) : T = { + val getter = prop._2._1 + val setter = prop._2._2 + val field = prop._2._3 + + + + val a = getter.getAnnotation(classOfAnno) + if(a != null){ + a + }else{ + val b = setter.getAnnotation(classOfAnno) + if(b != null){ + b + }else if(field != null){ + field.getAnnotation(classOfAnno) + }else{ + null.asInstanceOf[T] + } + } + } + + def readFieldOption(prop : PropertySet , implicitOption : FieldOption) = { + if(hasAnnotation(prop,classOf[Required])){ + FieldOption.REQUIRED + } else if(hasAnnotation(prop,classOf[Optional])){ + FieldOption.OPTIONAL + } else if(hasAnnotation(prop,classOf[Nullable])){ + if(readValueType(prop).isPrimitive){ + FieldOption.REQUIRED + }else{ + FieldOption.NULLABLE + } + } else{ + if(implicitOption == FieldOption.NULLABLE){ + if(readValueType(prop).isPrimitive){ + FieldOption.REQUIRED + }else{ + FieldOption.NULLABLE + } + }else{ + implicitOption + } + } + + } + + def readValueType(prop : PropertySet) = { + prop._2._1.getReturnType + } + def readGenericType(prop : PropertySet) = { + prop._2._1.getGenericReturnType + } +} + +class ScalaFieldEntry(name : String) extends IFieldEntry{ + + def getName() = name + + def isNullable() = {getOption == FieldOption.NULLABLE} + + def isOptional = {getOption == FieldOption.OPTIONAL} + + def isRequired = {getOption == FieldOption.REQUIRED} + + def isAvailable = {getOption != FieldOption.IGNORE} + + var option : FieldOption = null + + var genericType : Type = null + + def getJavaTypeName = { + if(getType.isArray){ + //TODO implement here + getType.getName() + }else{ + getType.getName() + } + + } + + var normalType : Class[_] = null + + def getOption() = option + def getType() = normalType + def getGenericType() = genericType + +} \ No newline at end of file diff --git a/scala/src/main/scala/org/msgpack/ScalaMessagePack.scala b/scala/src/main/scala/org/msgpack/ScalaMessagePack.scala new file mode 100644 index 00000000..45b6f5fc --- /dev/null +++ b/scala/src/main/scala/org/msgpack/ScalaMessagePack.scala @@ -0,0 +1,76 @@ +package org.msgpack + +import template._ +import builder.{MessagePackMessageBuilderSelector, BuilderSelectorRegistry} +import template.javassist.BuildContextFactory +import collection.mutable.{MutableList, LinkedList} +import collection.mutable.{Map => MMap,HashMap => MHashMap} +; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/10 + * Time: 1:34 + */ + +object ScalaMessagePack { + + { + // for scala object + BuilderSelectorRegistry.getInstance.insertBefore( + MessagePackMessageBuilderSelector.NAME, + new ScalaTemplateBuilderSelector) + + // register scala's list classes + TemplateRegistry.register(classOf[List[_]],new ImmutableListTemplate(AnyTemplate.getInstance)) + TemplateRegistry.registerGeneric(classOf[List[_]],new GenericTemplate1(classOf[ImmutableListTemplate])) + TemplateRegistry.register(classOf[Seq[_]],new ImmutableListTemplate(AnyTemplate.getInstance)) + TemplateRegistry.registerGeneric(classOf[Seq[_]],new GenericTemplate1(classOf[ImmutableListTemplate])) + TemplateRegistry.register(classOf[LinkedList[_]],new LinkedListTemplate(AnyTemplate.getInstance)) + TemplateRegistry.registerGeneric(classOf[LinkedList[_]],new GenericTemplate1(classOf[LinkedListTemplate])) + TemplateRegistry.register(classOf[MutableList[_]],new MutableListCTemplate(AnyTemplate.getInstance)) + TemplateRegistry.registerGeneric(classOf[MutableList[_]],new GenericTemplate1(classOf[MutableListCTemplate])) + + // register scala's map classes + TemplateRegistry.register(classOf[Map[_,_]],new ImmutableMapTemplate( + AnyTemplate.getInstance,AnyTemplate.getInstance)) + TemplateRegistry.registerGeneric(classOf[Map[_,_]],new GenericTemplate2( + classOf[ImmutableMapTemplate])) + TemplateRegistry.register(classOf[MMap[_,_]],new MutableHashMapTemplate( + AnyTemplate.getInstance,AnyTemplate.getInstance)) + TemplateRegistry.registerGeneric(classOf[MMap[_,_]],new GenericTemplate2( + classOf[MutableHashMapTemplate])) + TemplateRegistry.register(classOf[MHashMap[_,_]],new MutableHashMapTemplate( + AnyTemplate.getInstance,AnyTemplate.getInstance)) + TemplateRegistry.registerGeneric(classOf[MHashMap[_,_]],new GenericTemplate2( + classOf[MutableHashMapTemplate])) + + + + + } + + /** + * dammy method for initialize + */ + def init() = {} + + + def pack( obj : Any) = { + MessagePack.pack(obj.asInstanceOf[AnyRef]) + } + + def unpack[T]( buffer : Array[Byte])(implicit manifest : ClassManifest[T]) : T = { + MessagePack.unpack[T]( buffer, manifest.erasure.asInstanceOf[Class[T]]) + } + + def unpackD(buffer : Array[Byte]) = { + MessagePack.unpack(buffer) + } + + + + + + +} \ No newline at end of file diff --git a/scala/src/main/scala/org/msgpack/ScalaTemplateBuilder.scala b/scala/src/main/scala/org/msgpack/ScalaTemplateBuilder.scala new file mode 100644 index 00000000..f8cc2a7a --- /dev/null +++ b/scala/src/main/scala/org/msgpack/ScalaTemplateBuilder.scala @@ -0,0 +1,16 @@ +package org.msgpack; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/10 + * Time: 1:52 + */ + +class ScalaTemplateBuilder { + + + def pack(v : Int) = { + + } + +} \ No newline at end of file diff --git a/scala/src/main/scala/org/msgpack/ScalaTemplateBuilderSelector.scala b/scala/src/main/scala/org/msgpack/ScalaTemplateBuilderSelector.scala new file mode 100644 index 00000000..b8b7c122 --- /dev/null +++ b/scala/src/main/scala/org/msgpack/ScalaTemplateBuilderSelector.scala @@ -0,0 +1,48 @@ +package org.msgpack + +import annotation.MessagePackMessage +import template.builder.BuilderSelector +import java.lang.reflect.Type +import template.javassist.BuildContextFactory +import template.JavassistTemplateBuilder +import java.lang.annotation.{Annotation => JAnnotation} +; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/14 + * Time: 17:59 + */ + +class ScalaTemplateBuilderSelector extends BuilderSelector +{ + val b = new JavassistTemplateBuilder() + + { + b.setFieldEntryReader(new ScalaFieldEntryReader) + b.setBuildContextFactory(new BuildContextFactory{ + def createBuildContext(builder: JavassistTemplateBuilder) = { + new BuildContextForScala(builder) + } + }) + } + + def getName = "ScalaMessagePackMessageTemplateBuilderSelector"; + + def getTemplateBuilder(targetType: Type) = { + b + } + + def matchType(targetType: Type) = { + val c : Class[_] = targetType.asInstanceOf[Class[Object]] + isAnnotated(c, classOf[MessagePackMessage]) && + classOf[ScalaObject].isAssignableFrom(c)//c.isAssignableFrom(classOf[ScalaObject]) + + } + + private def isAnnotated(targetType : Class[_], annotation : Class[_ <: JAnnotation]) = { + targetType.getAnnotation(annotation) != null + + } + +} \ No newline at end of file diff --git a/scala/src/main/scala/org/msgpack/template/ImmutableListTemplate.scala b/scala/src/main/scala/org/msgpack/template/ImmutableListTemplate.scala new file mode 100644 index 00000000..5fab23ba --- /dev/null +++ b/scala/src/main/scala/org/msgpack/template/ImmutableListTemplate.scala @@ -0,0 +1,49 @@ +package org.msgpack.template + +import org.msgpack._ + +; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/11 + * Time: 2:25 + */ + +class ImmutableListTemplate(elementTemplate : Template) extends Template{ + def unpack(pac: Unpacker, to: AnyRef) = { + + val length = pac.unpackArray(); + val array : Array[Object] = new Array(length) + + for(i <- 0 until length){ + array(i) = elementTemplate.unpack(pac,null) + } + + array.toList + + } + + def pack(pk: Packer, target: AnyRef) = { + + val list = try{target.asInstanceOf[List[_]]} + catch{ + case e : ClassCastException => { + throw new MessageTypeException("target is not List type: " + target.getClass()); + } + case e : NullPointerException => { + throw new MessageTypeException(new NullPointerException("target is null.")); + } + } + + pk.packArray(list.size) + for( e <- list){ + elementTemplate.pack(pk,e) + } + + } + + def convert(from: MessagePackObject, to: AnyRef) = { + from.asArray.map(elementTemplate.convert(_,null)).toList + } +} diff --git a/scala/src/main/scala/org/msgpack/template/ImmutableMapTemplate.scala b/scala/src/main/scala/org/msgpack/template/ImmutableMapTemplate.scala new file mode 100644 index 00000000..d4dd01f4 --- /dev/null +++ b/scala/src/main/scala/org/msgpack/template/ImmutableMapTemplate.scala @@ -0,0 +1,54 @@ +package org.msgpack.template + +import org.msgpack._ + +import scala.collection.JavaConverters._ + +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/11 + * Time: 11:11 + */ + +class ImmutableMapTemplate(keyTemplate : Template , valueTemplate : Template) extends Template { + + def unpack(pac: Unpacker, to: AnyRef) = { + + val length = pac.unpackMap() + val array : Array[(Object,Object)] = new Array(length) + + for(i <- 0 until length){ + array(i) = (keyTemplate.unpack(pac,null),valueTemplate.unpack(pac,null)) + } + + array.toMap + + } + + def pack(pk: Packer, target: AnyRef) = { + + val map = try{target.asInstanceOf[Map[_,_]]} + catch{ + case e : ClassCastException => { + throw new MessageTypeException("target is not List type: " + target.getClass()); + } + case e : NullPointerException => { + throw new MessageTypeException(new NullPointerException("target is null.")); + } + } + pk.packMap(map.size) + for( e <- map){ + keyTemplate.pack(pk,e._1) + valueTemplate.pack(pk,e._2) + } + + } + + def convert(from: MessagePackObject, to: AnyRef) = { + from.asMap.asScala.map(p => (keyTemplate.convert(p._1,null),valueTemplate.convert(p._2,null))).toMap + } + + + +} \ No newline at end of file diff --git a/scala/src/main/scala/org/msgpack/template/MutableListTemplate.scala b/scala/src/main/scala/org/msgpack/template/MutableListTemplate.scala new file mode 100644 index 00000000..c1973ae6 --- /dev/null +++ b/scala/src/main/scala/org/msgpack/template/MutableListTemplate.scala @@ -0,0 +1,56 @@ +package org.msgpack.template + +import org.msgpack.{MessagePackObject, Packer, Unpacker, Template} +import collection.mutable.{MutableList, LinearSeq, LinkedList} +; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/11 + * Time: 2:37 + */ + +abstract class MutableListTemplate[T <: LinearSeq[_]](elementTemplate : Template) extends Template{ + def unpack(pac: Unpacker, to: AnyRef) = { + + val length = pac.unpackArray(); + + var list : LinearSeq[_] = if(to == null){ + toList(new Array[Object](0)) + }else{ + to.asInstanceOf[T] + } + for(i <- 0 until length){ + list = list :+ elementTemplate.unpack(pac,null) + } + + list + + } + def toList(array : Array[Object]) : T + + def pack(pk: Packer, target: AnyRef) = { + + val list = target.asInstanceOf[LinearSeq[_]] + pk.packArray(list.size) + for( e <- list){ + elementTemplate.pack(pk,e) + } + + } + + def convert(from: MessagePackObject, to: AnyRef) = { + toList(from.asArray.map(elementTemplate.convert(_,null))) + } +} + +class LinkedListTemplate(elementTemplate : Template) extends MutableListTemplate[LinkedList[_]](elementTemplate){ + def toList(array : Array[Object]) = LinkedList(array :_*) +} +class MutableListCTemplate(elementTemplate : Template) extends MutableListTemplate[MutableList[_]](elementTemplate){ + def toList(array : Array[Object]) = { + val list : MutableList[Object] = new MutableList + list ++= array + list + } +} \ No newline at end of file diff --git a/scala/src/main/scala/org/msgpack/template/MutableMapTemplate.scala b/scala/src/main/scala/org/msgpack/template/MutableMapTemplate.scala new file mode 100644 index 00000000..0503f069 --- /dev/null +++ b/scala/src/main/scala/org/msgpack/template/MutableMapTemplate.scala @@ -0,0 +1,70 @@ +package org.msgpack.template; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/11 + * Time: 12:06 + */ + +import org.msgpack._ +import collection.mutable.{HashMap,Map => MMap} +import scala.collection.JavaConverters._ + +abstract class MutableMapTemplate[T <: MMap[_,_]](keyTemplate : Template , valueTemplate : Template) extends Template { + + def unpack(pac: Unpacker, to: AnyRef) = { + + val length = pac.unpackMap() + val array : Array[(Object,Object)] = new Array(length) + + for(i <- 0 until length){ + array(i) = (keyTemplate.unpack(pac,null),valueTemplate.unpack(pac,null)) + } + + toMap(array) + + } + + def toMap(array : Array[(Object,Object)]) : T + + + def pack(pk: Packer, target: AnyRef) = { + + val map = try{target.asInstanceOf[MMap[_,_]]} + catch{ + case e : ClassCastException => { + throw new MessageTypeException("target is not List type: " + target.getClass()); + } + case e : NullPointerException => { + throw new MessageTypeException(new NullPointerException("target is null.")); + } + } + pk.packMap(map.size) + for( e <- map){ + keyTemplate.pack(pk,e._1) + valueTemplate.pack(pk,e._2) + } + + + } + + def convert(from: MessagePackObject, to: AnyRef) = { + toMap(from.asMap.asScala.map(p => (keyTemplate.convert(p._1,null),valueTemplate.convert(p._2,null))).toArray) + + } + + + +} + + +class MutableHashMapTemplate(keyTemplate : Template , valueTemplate : Template) + extends MutableMapTemplate[HashMap[_,_]](keyTemplate,valueTemplate ) { + + def toMap(array : Array[(Object,Object)]) = { + HashMap(array :_*) + } + + + +} diff --git a/scala/src/test/scala/org/msgpack/ClassWithList.scala b/scala/src/test/scala/org/msgpack/ClassWithList.scala new file mode 100644 index 00000000..4fc5b4ff --- /dev/null +++ b/scala/src/test/scala/org/msgpack/ClassWithList.scala @@ -0,0 +1,21 @@ +package org.msgpack; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/11 + * Time: 2:13 + */ + +import annotation.MessagePackMessage +import collection.mutable.{MutableList, LinkedList} + +@MessagePackMessage +class ClassWithList { + var immutable : List[String] = Nil + + var mutable : LinkedList[String] = LinkedList.empty + + var mutable2 : MutableList[String] = new MutableList + + //var tuple2 : (String,String) = (null,null) +} \ No newline at end of file diff --git a/scala/src/test/scala/org/msgpack/ClassWithMap.scala b/scala/src/test/scala/org/msgpack/ClassWithMap.scala new file mode 100644 index 00000000..6256dd76 --- /dev/null +++ b/scala/src/test/scala/org/msgpack/ClassWithMap.scala @@ -0,0 +1,19 @@ +package org.msgpack; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/11 + * Time: 2:22 + */ + +import annotation.MessagePackMessage +import scala.collection.mutable.{Map => MMap} + +@MessagePackMessage +class ClassWithMap { + + var immutable : Map[String,String] = Map.empty + + var mutable : MMap[String,String] = MMap.empty + +} \ No newline at end of file diff --git a/scala/src/test/scala/org/msgpack/CollectionPackSpec.scala b/scala/src/test/scala/org/msgpack/CollectionPackSpec.scala new file mode 100644 index 00000000..ec305507 --- /dev/null +++ b/scala/src/test/scala/org/msgpack/CollectionPackSpec.scala @@ -0,0 +1,71 @@ +package org.msgpack + +import org.junit.runner.RunWith +import org.specs._ +import org.specs.matcher._ +import org.specs.runner.{ JUnitSuiteRunner, JUnit } +import scala.collection.mutable.LinkedList + +//import org.scalacheck.Gen + +/** + * Sample specification. + * + * This specification can be executed with: scala -cp ${package}.SpecsTest + * Or using maven: mvn test + * + * For more information on how to write or run specifications, please visit: http://code.google.com/p/specs. + * + */ +@RunWith(classOf[JUnitSuiteRunner]) +class CollectionPackSpec extends Specification with JUnit { + + "ScalaMessagePack" should { + "pack scala-list" in { + val c = new ClassWithList + + c.immutable = List("a","b","c") + c.mutable = LinkedList("a","b","d") + c.mutable2 ++= List("gh","fjei") + //c.tuple2 = ("hoge","wahoo") + + val b = ScalaMessagePack.pack(c) + val des = ScalaMessagePack.unpack[ClassWithList](b) + + des.immutable must be_==(c.immutable) + des.mutable must be_==(c.mutable) + //des.tuple2 must be_==(c.tuple2) + + val mpo = ScalaMessagePack.unpackD(b) + val des2 = mpo.convert(classOf[ClassWithList]) + + des2.immutable must be_==(c.immutable) + des2.mutable must be_==(c.mutable) + + } + "pack scala-map" in { + val c = new ClassWithMap + c.immutable = Map("a" -> "hoge","b" -> "fuga","c" -> "hehe") + c.mutable = scala.collection.mutable.Map("d" -> "oo" , "e" -> "aa") + + val b = ScalaMessagePack.pack(c) + val des = ScalaMessagePack.unpack[ClassWithMap](b) + + des.immutable must be_==(c.immutable) + des.mutable must be_==(c.mutable) + + val mpo = ScalaMessagePack.unpackD(b) + val des2 = mpo.convert(classOf[ClassWithMap]) + + des2.immutable must be_==(c.immutable) + des2.mutable must be_==(c.mutable) + + } + + } + + + + +} + diff --git a/scala/src/test/scala/org/msgpack/SampleClass.scala b/scala/src/test/scala/org/msgpack/SampleClass.scala new file mode 100644 index 00000000..4979ec61 --- /dev/null +++ b/scala/src/test/scala/org/msgpack/SampleClass.scala @@ -0,0 +1,77 @@ +package org.msgpack + +import annotation.MessagePackMessage +import annotation.{Optional, Index} +import java.util.Date +; +/* + * Created by IntelliJ IDEA. + * User: takeshita + * Date: 11/03/10 + * Time: 1:35 + */ + +@MessagePackMessage +class SampleClass { + var name : String = "hoge" + var number : Int = 2 + +} + +trait SampleTrait { + + var traitName : String = "" + + var traitNum : Int = 12 + +} + +class SampleClass2 extends SampleClass with SampleTrait { + + + @Index(3) + var sampleClass2Name : String = "sampleclass2" + + @Index(0) + def sampleClass2Num : Int = 22 + def sampleClass2Num_=(v : Int) = {} + + val notProperty : String ="This is not prop.Only getter" + + // wrong property + def wrongValue : Int = 53 + def wrongValue_=(v : String) = {} + +} + +object NotDefaultCons{ + + def apply() : NotDefaultCons2 = { + new NotDefaultCons2() + } +} +@MessagePackMessage +class NotDefaultCons(var name : String){ +} + +class NotDefaultCons2 extends NotDefaultCons("hoge") + +@MessagePackMessage +class BasicalTypes{ + + var intVar : Int = 0 + var longVar : Long = 0 + var shortVar : Short = 0 + var byteVar : Byte = 0 + var boolVar : Boolean = false + + var floatVar : Float = 0 + var doubleVar : Double = 0 + + var strVar : String = "" + + var dateVar : Date = null + + + +} \ No newline at end of file diff --git a/scala/src/test/scala/org/msgpack/ScalaFieldEntryReaderSpec.scala b/scala/src/test/scala/org/msgpack/ScalaFieldEntryReaderSpec.scala new file mode 100644 index 00000000..3eeffaad --- /dev/null +++ b/scala/src/test/scala/org/msgpack/ScalaFieldEntryReaderSpec.scala @@ -0,0 +1,120 @@ +package org.msgpack + +import org.junit.runner.RunWith +import org.specs._ +import org.specs.matcher._ +import org.specs.runner.{ JUnitSuiteRunner, JUnit } +//import org.scalacheck.Gen + +/** + * Sample specification. + * + * This specification can be executed with: scala -cp ${package}.SpecsTest + * Or using maven: mvn test + * + * For more information on how to write or run specifications, please visit: http://code.google.com/p/specs. + * + */ +@RunWith(classOf[JUnitSuiteRunner]) +class ScalaFieldEntryReaderSpec extends Specification with JUnit { + + "ScalaFieldEntryReader" should { + "check setter " in { + val reader = new ScalaFieldEntryReader() + + val c = classOf[SampleClass] + + reader.setter_?(c.getMethod("name")) must be_==(false) + reader.setter_?(c.getMethod("name_$eq",classOf[String])) must be_==(true) + } + "check getter " in { + val reader = new ScalaFieldEntryReader() + + val c = classOf[SampleClass] + + reader.getter_?(c.getMethod("name")) must be_==(true) + reader.getter_?(c.getMethod("name_$eq",classOf[String])) must be_==(false) + } + + "find props " in { + val reader = new ScalaFieldEntryReader() + + { + val c = classOf[SampleClass] + + val props = reader.findPropertyMethods(c) + + props.size must be_==(2) + props must haveKey("name") + props must haveKey("number") + } + + { + val c = classOf[SampleClass2] + + val props = reader.findPropertyMethods(c) + + println(props.keys) + + props.size must be_==(6) + props must haveKey("name") + props must haveKey("number") + props must haveKey("traitName") + props must haveKey("traitNum") + props must haveKey("sampleClass2Name") + props must haveKey("sampleClass2Num") + } + + } + + "indexing " in { + val reader = new ScalaFieldEntryReader() + + val c = classOf[SampleClass2] + + def printDecs(c : Class[_]) : Unit = { + println(c.getName + "---") + val ds = c.getDeclaredMethods + ds.foreach(m => {println(m) + println(m.getAnnotations.toList) + }) + if(c.getSuperclass != classOf[Object]){ + printDecs(c.getSuperclass) + } + } + printDecs(c) + + + + val props = reader.findPropertyMethods(c) + + val indexed = reader.indexing(props) + + println(indexed.map(_._1).toList) + + indexed.size must be_==(6) + indexed(0)._1 must be_==("sampleClass2Num") + indexed(3)._1 must be_==("sampleClass2Name") + indexed must notContain(null) + + } + + "read entries" in { + val reader = new ScalaFieldEntryReader() + + val c = classOf[SampleClass2] + import org.msgpack.template.FieldOption + + val e = reader.readFieldEntries(c, FieldOption.NULLABLE) + + e.size must be_==(6) + + } + + } + + + + +} + diff --git a/scala/src/test/scala/org/msgpack/ScalaMessagePackSpec.scala b/scala/src/test/scala/org/msgpack/ScalaMessagePackSpec.scala new file mode 100644 index 00000000..8f464000 --- /dev/null +++ b/scala/src/test/scala/org/msgpack/ScalaMessagePackSpec.scala @@ -0,0 +1,90 @@ +package org.msgpack + +import org.junit.runner.RunWith +import org.specs._ +import org.specs.matcher._ +import org.specs.runner.{ JUnitSuiteRunner, JUnit } +import java.util.Date + +//import org.scalacheck.Gen + +/** + * Sample specification. + * + * This specification can be executed with: scala -cp ${package}.SpecsTest + * Or using maven: mvn test + * + * For more information on how to write or run specifications, please visit: http://code.google.com/p/specs. + * + */ +@RunWith(classOf[JUnitSuiteRunner]) +class ScalaMessagePackTest extends Specification with JUnit /*with ScalaCheck*/ { + + "ScalaMessagePackTest" should { + "pack and unpack" in { + + val sc = new SampleClass() + sc.name = "Test object" + sc.number = 123456 + + println("Sampleclass is inherit ScalaObject " + classOf[ScalaObject].isAssignableFrom(classOf[SampleClass])) + new ScalaTemplateBuilderSelector().matchType(classOf[SampleClass]) must be_==(true) + val b = ScalaMessagePack.pack(sc) + + val deser = ScalaMessagePack.unpack[SampleClass](b) + + deser.name must be_==(sc.name) + deser.number must be_==(sc.number) + + val mso = ScalaMessagePack.unpackD(b) + val conv = mso.convert(classOf[SampleClass]) + conv.name must be_==(sc.name) + conv.number must be_==(sc.number) + } + "check basical types" in { + val v = new BasicalTypes + v.intVar = 20 + v.longVar = 11 + v.shortVar = 7 + v.byteVar = 1 + v.floatVar = 1.5f + v.doubleVar = 2.5 + v.strVar = "fugafuga" + v.dateVar = new Date(1233333) + + val b = ScalaMessagePack.pack(v) + val des : BasicalTypes = ScalaMessagePack.unpack[BasicalTypes](b) + + des.intVar must be_==(v.intVar) + des.longVar must be_==(v.longVar) + des.shortVar must be_==(v.shortVar) + des.byteVar must be_==(v.byteVar) + des.floatVar must be_==(v.floatVar) + des.doubleVar must be_==(v.doubleVar) + des.strVar must be_==(v.strVar) + des.dateVar must be_==(v.dateVar) + + + } + + "pack and unpack none-default constructor class" in { + + val sc = new NotDefaultCons("hehehehe") + + val b = ScalaMessagePack.pack(sc) + + val deser = ScalaMessagePack.unpack[NotDefaultCons](b) + + deser.name must be_==(sc.name) + + val mso = ScalaMessagePack.unpackD(b) + val conv = mso.convert(classOf[NotDefaultCons]) + conv.name must be_==(sc.name) + } + + + } + + +} +