java: Template extends MessagePacker

This commit is contained in:
frsyuki 2010-10-24 18:46:48 +09:00
parent 19fd4e755c
commit dbb28d9a8f
21 changed files with 379 additions and 160 deletions

View File

@ -29,7 +29,7 @@ import java.math.BigInteger;
import org.msgpack.annotation.MessagePackDelegate;
import org.msgpack.annotation.MessagePackMessage;
import org.msgpack.annotation.MessagePackOrdinalEnum;
import org.msgpack.packer.*;
import org.msgpack.util.codegen.DynamicTemplate;
/**
* Packer enables you to serialize objects into OutputStream.
@ -49,17 +49,7 @@ import org.msgpack.packer.*;
*/
public class Packer {
static {
// final classes
BooleanPacker.getInstance();
ByteArrayPacker.getInstance();
BytePacker.getInstance();
DoublePacker.getInstance();
FloatPacker.getInstance();
IntegerPacker.getInstance();
LongPacker.getInstance();
ShortPacker.getInstance();
StringPacker.getInstance();
//BigIntegerPacker.getInstance(); // BigInteger is not final
Templates.load();
}
public static void load() { }
@ -429,12 +419,6 @@ public class Packer {
return packString(o);
}
public Packer pack(MessagePackable o) throws IOException {
if(o == null) { return packNil(); }
o.messagePack(this);
return this;
}
public Packer pack(byte[] o) throws IOException {
if(o == null) { return packNil(); }
packRaw(o.length);
@ -458,86 +442,20 @@ public class Packer {
return this;
}
public Packer pack(MessagePackable o) throws IOException {
if(o == null) { return packNil(); }
o.messagePack(this);
return this;
}
public Packer pack(Object o) throws IOException {
if(o == null) {
return packNil();
//} else if(o instanceof String) {
// byte[] b = ((String)o).getBytes("UTF-8");
// packRaw(b.length);
// return packRawBody(b);
} else if(o instanceof MessagePackable) {
((MessagePackable)o).messagePack(this);
return this;
//} else if(o instanceof byte[]) {
// byte[] b = (byte[])o;
// packRaw(b.length);
// return packRawBody(b);
} else if(o instanceof List) {
List<Object> l = (List<Object>)o;
packArray(l.size());
for(Object i : l) { pack(i); }
return this;
} else if(o instanceof Set) {
Set<Object> l = (Set<Object>)o;
packArray(l.size());
for(Object i : l) { pack(i); }
return this;
} else if(o instanceof Map) {
Map<Object,Object> m = (Map<Object,Object>)o;
packMap(m.size());
for(Map.Entry<Object,Object> e : m.entrySet()) {
pack(e.getKey());
pack(e.getValue());
}
return this;
} else if(o instanceof Collection) {
Collection<Object> l = (Collection<Object>)o;
packArray(l.size());
for(Object i : l) { pack(i); }
return this;
//} else if(o instanceof Boolean) {
// if((Boolean)o) {
// return packTrue();
// } else {
// return packFalse();
// }
//} else if(o instanceof Integer) {
// return packInt((Integer)o);
//} else if(o instanceof Long) {
// return packLong((Long)o);
//} else if(o instanceof Short) {
// return packShort((Short)o);
//} else if(o instanceof Byte) {
// return packByte((Byte)o);
//} else if(o instanceof Float) {
// return packFloat((Float)o);
//} else if(o instanceof Double) {
// return packDouble((Double)o);
} else if(o instanceof BigInteger) {
return packBigInteger((BigInteger)o);
}
Templates.TAny.pack(this, o);
return this;
}
Class<?> klass = o.getClass();
MessagePacker packer = CustomPacker.get(klass);
if(packer != null) {
packer.pack(this, o);
return this;
} else if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
packer = ReflectionPacker.create(klass);
packer.pack(this, o);
return this;
} else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
// FIXME DelegatePacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
} else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
// FIXME OrdinalEnumPacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
}
if (packer != null) {
CustomMessage.registerPacker(klass, packer);
}
throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")");
public Packer pack(Object o, Template tmpl) throws IOException {
tmpl.pack(this, o);
return this;
}
}

View File

@ -17,6 +17,6 @@
//
package org.msgpack;
public interface Template extends MessageUnpacker, MessageConverter {
public interface Template extends MessagePacker, MessageUnpacker, MessageConverter {
}

View File

@ -22,6 +22,21 @@ import org.msgpack.template.*;
public class Templates {
public static void load() { }
public static final Template TAny = AnyTemplate.getInstance();
public static Template tAny() {
return TAny;
}
public static Template tOptional(Template elementTemplate) {
return new OptionalTemplate(elementTemplate);
}
public static Template tOptional(Template elementTemplate, Object defaultObject) {
return new OptionalTemplate(elementTemplate, defaultObject);
}
public static Template tList(Template elementTemplate) {
return new ListTemplate(elementTemplate);
}

View File

@ -24,10 +24,6 @@ import java.util.Iterator;
import java.nio.ByteBuffer;
import java.math.BigInteger;
import org.msgpack.annotation.MessagePackDelegate;
import org.msgpack.annotation.MessagePackMessage;
import org.msgpack.annotation.MessagePackOrdinalEnum;
/**
* Unpacker enables you to deserialize objects from stream.
*
@ -572,46 +568,20 @@ public class Unpacker implements Iterable<MessagePackObject> {
return impl.tryUnpackNull();
}
final public Object unpack(MessageUnpacker unpacker) throws IOException, MessageTypeException {
return unpacker.unpack(this);
}
final public void unpack(MessageUnpackable obj) throws IOException, MessageTypeException {
obj.messageUnpack(this);
}
//final public MessagePackObject unpack() throws IOException {
// return unpackObject();
//}
final public Object unpack(Template tmpl) throws IOException, MessageTypeException {
return tmpl.unpack(this);
}
final public Object unpack(Class<?> klass) throws IOException, MessageTypeException, InstantiationException, IllegalAccessException {
if(MessageUnpackable.class.isAssignableFrom(klass)) {
Object obj = klass.newInstance();
((MessageUnpackable)obj).messageUnpack(this);
return obj;
}
MessageUnpacker unpacker = CustomUnpacker.get(klass);
if(unpacker != null) {
return unpacker.unpack(this);
}
Template tmpl = null;
if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
tmpl = ReflectionTemplate.create(klass);
return tmpl.unpack(this);
} else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
// FIXME DelegateTemplate
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
} else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
// FIXME OrdinalEnumTemplate
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
}
if (tmpl != null) {
CustomMessage.registerTemplate(klass, tmpl);
}
MessageConverter converter = CustomConverter.get(klass);
if(converter != null) {
return converter.convert(unpackObject());
}
throw new MessageTypeException();
return unpack(Templates.tClass(klass));
}
}

View File

@ -0,0 +1,52 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 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 org.msgpack.*;
public class AnyTemplate implements Template {
private AnyTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
if(target == null) {
pk.packNil();
} else {
new ClassTemplate(target.getClass()).pack(pk, target);
}
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackObject();
}
public Object convert(MessagePackObject from) throws MessageTypeException {
return from;
}
static public AnyTemplate getInstance() {
return instance;
}
static final AnyTemplate instance = new AnyTemplate();
static {
CustomMessage.registerTemplate(MessagePackObject.class, instance);
}
}

View File

@ -24,6 +24,10 @@ import org.msgpack.*;
public class BigIntegerTemplate implements Template {
private BigIntegerTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packBigInteger((BigInteger)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackBigInteger();
}

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class BooleanTemplate implements Template {
private BooleanTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packBoolean((Boolean)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackBoolean();
}

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class ByteArrayTemplate implements Template {
private ByteArrayTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packByteArray((byte[])target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackByteArray();
}

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class ByteTemplate implements Template {
private ByteTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packByte((Byte)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackByte();
}

View File

@ -19,21 +19,186 @@ package org.msgpack.template;
import java.io.IOException;
import org.msgpack.*;
import org.msgpack.annotation.MessagePackDelegate;
import org.msgpack.annotation.MessagePackMessage;
import org.msgpack.annotation.MessagePackOrdinalEnum;
import org.msgpack.util.codegen.DynamicPacker;
import org.msgpack.util.codegen.DynamicConverter;
import org.msgpack.util.codegen.DynamicUnpacker;
import java.util.*;
import java.math.BigInteger;
public class ClassTemplate implements Template {
static {
Templates.load();
}
private Class klass;
private Class<?> klass;
public ClassTemplate(Class klass) {
public ClassTemplate(Class<?> klass) {
this.klass = klass;
}
public void pack(Packer pk, Object o) throws IOException {
// FIXME
if(o == null) {
pk.packNil();
return;
}
//if(o instanceof String) {
// pk.packString((String)o);
// return;
//}
if(o instanceof MessagePackable) {
((MessagePackable)o).messagePack(pk);
return;
}
//if(o instanceof byte[]) {
// pk.packByteArray((byte[])o);
// return;
//}
if(o instanceof List) {
List<Object> l = (List<Object>)o;
pk.packArray(l.size());
for(Object i : l) {
pk.pack(i);
}
return;
}
if(o instanceof Set) {
Set<Object> l = (Set<Object>)o;
pk.packArray(l.size());
for(Object i : l) {
pk.pack(i);
}
return;
}
if(o instanceof Map) {
Map<Object,Object> m = (Map<Object,Object>)o;
pk.packMap(m.size());
for(Map.Entry<Object,Object> e : m.entrySet()) {
pk.pack(e.getKey());
pk.pack(e.getValue());
}
return;
}
if(o instanceof Collection) {
Collection<Object> l = (Collection<Object>)o;
pk.packArray(l.size());
for(Object i : l) {
pk.pack(i);
}
return;
}
//if(o instanceof Boolean) {
// pk.packBoolean((Boolean)o);
// return;
//}
//if(o instanceof Integer) {
// pk.packInt((Integer)o);
// return;
//}
//if(o instanceof Long) {
// pk.packLong((Long)o);
// return;
//}
//if(o instanceof Short) {
// pk.packShort((Short)o);
// return;
//}
//if(o instanceof Byte) {
// pk.packByte((Byte)o);
// return;
//}
//if(o instanceof Float) {
// pk.packFloat((Float)o);
// return;
//}
//if(o instanceof Double) {
// pk.packDouble((Double)o);
// return;
//}
if(o instanceof BigInteger) {
pk.packBigInteger((BigInteger)o);
return;
}
MessagePacker packer = CustomPacker.get(klass);
if(packer != null) {
packer.pack(pk, o);
return;
}
if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
packer = DynamicPacker.create(klass);
} else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
// FIXME DelegatePacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
} else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
// FIXME OrdinalEnumPacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
}
if (packer != null) {
CustomPacker.register(klass, packer);
packer.pack(pk, o);
return;
}
throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")");
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
try {
return pac.unpack(klass);
MessageUnpacker unpacker = CustomUnpacker.get(klass);
if(unpacker != null) {
return unpacker.unpack(pac);
}
if(MessageUnpackable.class.isAssignableFrom(klass)) {
Object obj = klass.newInstance();
((MessageUnpackable)obj).messageUnpack(pac);
return obj;
}
if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
unpacker = DynamicUnpacker.create(klass);
} else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
// TODO DelegateUnpacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
} else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
// TODO OrdinalEnumUnpacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
}
if (unpacker != null) {
CustomUnpacker.register(klass, unpacker);
return unpacker.unpack(pac);
}
// fallback
{
MessageConverter converter = null;
if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
converter = DynamicConverter.create(klass);
} else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
// TODO DelegateConverter
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
} else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
// TODO OrdinalEnumConverter
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
}
if (converter != null) {
CustomConverter.register(klass, converter);
return converter.convert(pac.unpackObject());
}
}
throw new MessageTypeException();
} catch (IllegalAccessException e) {
throw new MessageTypeException(e.getMessage()); // FIXME
} catch (InstantiationException e) {
@ -42,27 +207,40 @@ public class ClassTemplate implements Template {
}
public Object convert(MessagePackObject from) throws MessageTypeException {
if(MessageConvertable.class.isAssignableFrom(klass)) {
Object obj;
try {
obj = klass.newInstance();
} catch (IllegalAccessException e) {
throw new MessageTypeException(e.getMessage()); // FIXME
} catch (InstantiationException e) {
throw new MessageTypeException(e.getMessage()); // FIXME
try {
MessageConverter converter = CustomConverter.get(klass);
if(converter != null) {
return converter.convert(from);
}
((MessageConvertable)obj).messageConvert(from);
return obj;
if(MessageConvertable.class.isAssignableFrom(klass)) {
Object obj = klass.newInstance();
((MessageConvertable)obj).messageConvert(from);
return obj;
}
if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
converter = DynamicConverter.create(klass);
} else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
// TODO DelegateConverter
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
} else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
// TODO OrdinalEnumConverter
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
}
if (converter != null) {
CustomConverter.register(klass, converter);
return converter.convert(from);
}
throw new MessageTypeException();
} catch (IllegalAccessException e) {
throw new MessageTypeException(e.getMessage()); // FIXME
} catch (InstantiationException e) {
throw new MessageTypeException(e.getMessage()); // FIXME
}
MessageConverter converter = CustomConverter.get(klass);
if(converter != null) {
return converter.convert(from);
}
// FIXME check annotations -> code generation -> CustomMessage.registerTemplate
throw new MessageTypeException();
}
}

View File

@ -17,6 +17,7 @@
//
package org.msgpack.template;
import java.util.Collection;
import java.util.List;
import java.util.LinkedList;
import java.io.IOException;
@ -29,6 +30,16 @@ public class CollectionTemplate implements Template {
this.elementTemplate = elementTemplate;
}
public void pack(Packer pk, Object target) throws IOException {
if(target instanceof Collection) {
throw new MessageTypeException();
}
Collection<Object> collection = (Collection<Object>)target;
for(Object element : collection) {
elementTemplate.pack(pk, element);
}
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
int length = pac.unpackArray();
List<Object> list = new LinkedList<Object>();

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class DoubleTemplate implements Template {
private DoubleTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packDouble(((Double)target));
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackDouble();
}

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class FloatTemplate implements Template {
private FloatTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packFloat((Float)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackFloat();
}

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class IntegerTemplate implements Template {
private IntegerTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packInt((Integer)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackInt();
}

View File

@ -33,6 +33,16 @@ public class ListTemplate implements Template {
return elementTemplate;
}
public void pack(Packer pk, Object target) throws IOException {
if(target instanceof List) {
throw new MessageTypeException();
}
List<Object> list = (List<Object>)target;
for(Object element : list) {
elementTemplate.pack(pk, element);
}
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
int length = pac.unpackArray();
List<Object> list = new ArrayList<Object>(length);

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class LongTemplate implements Template {
private LongTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packLong((Long)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackLong();
}

View File

@ -39,6 +39,17 @@ public class MapTemplate implements Template {
return valueTemplate;
}
public void pack(Packer pk, Object target) throws IOException {
if(target instanceof Map) {
throw new MessageTypeException();
}
Map<Object,Object> map = (Map<Object,Object>)target;
for(Map.Entry<Object,Object> pair : map.entrySet()) {
keyTemplate.pack(pk, pair.getKey());
valueTemplate.pack(pk, pair.getValue());
}
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
int length = pac.unpackMap();
Map<Object,Object> map = new HashMap<Object,Object>(length);

View File

@ -28,13 +28,21 @@ public class OptionalTemplate implements Template {
this(elementTemplate, null);
}
public OptionalTemplate(Template elementTemplate, Object defaultObject) {
this.elementTemplate = elementTemplate;
this.defaultObject = defaultObject;
}
public Template getElementTemplate() {
return elementTemplate;
}
public OptionalTemplate(Template elementTemplate, Object defaultObject) {
this.elementTemplate = elementTemplate;
this.defaultObject = defaultObject;
public void pack(Packer pk, Object target) throws IOException {
if(target == null) {
pk.pack(defaultObject);
} else {
elementTemplate.pack(pk, target);
}
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class ShortTemplate implements Template {
private ShortTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packShort((Short)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackShort();
}

View File

@ -23,6 +23,10 @@ import org.msgpack.*;
public class StringTemplate implements Template {
private StringTemplate() { }
public void pack(Packer pk, Object target) throws IOException {
pk.packString((String)target);
}
public Object unpack(Unpacker pac) throws IOException, MessageTypeException {
return pac.unpackString();
}

View File

@ -152,6 +152,12 @@ public class DynamicCodeGenBase implements Constants {
this.type = type;
}
@Override
public void pack(Packer pk, Object target) throws IOException {
// FIXME
pk.pack(target);
}
@Override
public Object unpack(Unpacker unpacker) throws IOException,
MessageTypeException {