
com.dyuproject.protostuff.json.ReflectionConvertor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of protostuff-model-json Show documentation
Show all versions of protostuff-model-json Show documentation
json serialization for objects generated by google's protoc(objects using the builder pattern).
The newest version!
//========================================================================
//Copyright 2007-2008 David Yu [email protected]
//------------------------------------------------------------------------
//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 com.dyuproject.protostuff.json;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import com.dyuproject.protostuff.model.BuilderPropertyAccessor;
import com.dyuproject.protostuff.model.DefaultProperty;
import com.dyuproject.protostuff.model.MessagePropertyAccessor;
import com.dyuproject.protostuff.model.Model;
import com.dyuproject.protostuff.model.ModelMeta;
import com.dyuproject.protostuff.model.ParamType;
import com.dyuproject.protostuff.model.Property;
import com.dyuproject.protostuff.model.PropertyMeta;
import com.google.protobuf.MessageLite;
import com.google.protobuf.MessageLite.Builder;
/**
* Converts a message to/from json via java reflections.
*
* @author David Yu
* @created Oct 1, 2009
*/
public class ReflectionConvertor implements ProtobufConvertor
{
static final Property.Factory PROPERTY_FACTORY = new Property.Factory()
{
public Field create(PropertyMeta propertyMeta)
{
if(propertyMeta.isMessage())
{
return propertyMeta.isRepeated() ? new RepeatedMessageField(propertyMeta) :
new MessageField(propertyMeta);
}
return propertyMeta.isRepeated() ? new RepeatedInlineField(propertyMeta) :
new InlineField(propertyMeta);
}
public Class getType()
{
return Field.class;
}
};
protected final Model _model;
protected final ReflectionJSON _lite;
public ReflectionConvertor(ModelMeta modelMeta, ReflectionJSON lite)
{
_model = new Model(modelMeta, PROPERTY_FACTORY);
_lite = lite;
for(Field f : _model.getProperties())
f._convertor = this;
}
public Builder parseFrom(JsonParser parser) throws IOException
{
Builder builder = _model.getModelMeta().getPrototype().newBuilderForType();
mergeFrom(parser, builder);
return builder;
}
public void mergeFrom(JsonParser parser, Builder builder) throws IOException
{
for(JsonToken t = parser.nextToken(); t!=JsonToken.END_OBJECT; t=parser.nextToken())
{
if(t!=JsonToken.FIELD_NAME)
{
throw new IOException("Expected token: $field: but was " +
parser.getCurrentToken() + " on message " +
_model.getModelMeta().getMessageClass());
}
String name = parser.getCurrentName();
Field field = _lite.getField(name, _model);
if(field==null)
{
throw new IOException("unknown field: " + name + " on message " +
_model.getModelMeta().getMessageClass());
}
field.readFrom(parser, builder);
}
}
public void generateTo(JsonGenerator generator, MessageLite message) throws IOException
{
generator.writeStartObject();
for(Field f : _model.getProperties())
f.writeTo(generator, message, _lite.getFieldName(f));
generator.writeEndObject();
}
static abstract class Field extends DefaultProperty implements ProtobufField
{
protected ReflectionConvertor _convertor;
public Field(PropertyMeta propertyMeta)
{
super(propertyMeta, new MessagePropertyAccessor(propertyMeta),
new BuilderPropertyAccessor(propertyMeta)
{
protected boolean set(Object builder, Object value, Method method)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
method.invoke(builder, value);
return true;
}
});
}
}
static class MessageField extends Field
{
public MessageField(PropertyMeta propertyMeta)
{
super(propertyMeta);
}
public void readFrom(JsonParser parser, Builder owner) throws IOException
{
if(parser.nextToken() != JsonToken.START_OBJECT)
{
throw new IOException("Expected token: { but was " +
parser.getCurrentToken() + " on message " +
_propertyMeta.getMessageClass());
}
ReflectionConvertor convertor = _convertor._lite.get(_messagePropertyAccessor.getTypeClass());
if(convertor==null)
{
throw new IOException("Message not included: " +
_messagePropertyAccessor.getTypeClass());
}
try
{
_builderPropertyAccessor.setValue(owner, convertor.parseFrom(parser).build());
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
}
public void writeTo(JsonGenerator generator, MessageLite owner, String fieldName) throws IOException
{
MessageLite message;
try
{
message = (MessageLite)_messagePropertyAccessor.getValue(owner);
if(message==null)
return;
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
ReflectionConvertor convertor = _convertor._lite.get(_messagePropertyAccessor.getTypeClass());
if(convertor==null)
throw new IOException("Message not included: " + message.getClass());
generator.writeFieldName(fieldName);
convertor.generateTo(generator, message);
}
}
static class RepeatedMessageField extends Field
{
public RepeatedMessageField(PropertyMeta propertyMeta)
{
super(propertyMeta);
}
public void readFrom(JsonParser parser, Builder owner) throws IOException
{
if(parser.nextToken()!=JsonToken.START_ARRAY)
{
throw new IOException("Expected token: [ but was " +
parser.getCurrentToken() + " on message " +
_propertyMeta.getMessageClass());
}
ReflectionConvertor convertor = _convertor._lite.get(_messagePropertyAccessor.getTypeClass());
if(convertor==null)
{
throw new IOException("Message not included: " +
_messagePropertyAccessor.getTypeClass());
}
try
{
for(JsonToken t=parser.nextToken(); t!=JsonToken.END_ARRAY; t=parser.nextToken())
{
if(t != JsonToken.START_OBJECT)
{
throw new IOException("Expected token: { but was " +
parser.getCurrentToken() + " on " + _propertyMeta.getName()+ " of message " +
_propertyMeta.getMessageClass());
}
_builderPropertyAccessor.setValue(owner, convertor.parseFrom(parser).build());
}
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
}
@SuppressWarnings("unchecked")
public void writeTo(JsonGenerator generator, MessageLite owner, String fieldName) throws IOException
{
try
{
List messages = (List)_messagePropertyAccessor.getValue(owner);
if(messages!=null)
{
ReflectionConvertor convertor = _convertor._lite.get(_messagePropertyAccessor.getTypeClass());
if(convertor==null)
{
throw new IOException("Message not included: " +
_messagePropertyAccessor.getTypeClass());
}
generator.writeFieldName(fieldName);
generator.writeStartArray();
for(MessageLite m : messages)
convertor.generateTo(generator, m);
generator.writeEndArray();
}
else
{
generator.writeArrayFieldStart(fieldName);
generator.writeEndArray();
}
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
}
}
static class InlineField extends Field
{
protected final InlineValue> _inlineValue;
public InlineField(PropertyMeta propertyMeta)
{
super(propertyMeta);
ParamType type = _messagePropertyAccessor.getParamType();
_inlineValue = type.isPrimitive() ? InlineValue.getPrimitive(type.getJavaType()) :
InlineValue.EnumValue.create(_messagePropertyAccessor.getTypeClass());
}
public void readFrom(JsonParser parser, Builder builder) throws IOException
{
try
{
parser.nextToken();
_builderPropertyAccessor.setValue(builder, _inlineValue.readFrom(parser));
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
}
public void writeTo(JsonGenerator generator, MessageLite message, String fieldName) throws IOException
{
try
{
Object value = _messagePropertyAccessor.getValue(message);
if(value!=null)
{
generator.writeFieldName(fieldName);
_inlineValue.writeObjectTo(generator, value);
}
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
}
}
static class RepeatedInlineField extends Field
{
protected final InlineValue> _inlineValue;
public RepeatedInlineField(PropertyMeta propertyMeta)
{
super(propertyMeta);
ParamType type = _messagePropertyAccessor.getParamType();
_inlineValue = type.isPrimitive() ? InlineValue.getPrimitive(type.getJavaType()) :
InlineValue.EnumValue.create(_messagePropertyAccessor.getTypeClass());
}
public void readFrom(JsonParser parser, Builder owner) throws IOException
{
if(parser.nextToken()!=JsonToken.START_ARRAY)
{
throw new IOException("Expected token: [ but was " +
parser.getCurrentToken() + " on " + _propertyMeta.getName() + " of message: " +
_propertyMeta.getMessageClass());
}
try
{
for(JsonToken t = parser.nextToken(); t!=JsonToken.END_ARRAY; t=parser.nextToken())
_builderPropertyAccessor.setValue(owner, _inlineValue.readFrom(parser));
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
}
public void writeTo(JsonGenerator generator, MessageLite owner, String fieldName) throws IOException
{
try
{
List> values = (List>)_messagePropertyAccessor.getValue(owner);
if(values!=null)
{
generator.writeFieldName(fieldName);
generator.writeStartArray();
for(Object value : values)
_inlineValue.writeObjectTo(generator, value);
generator.writeEndArray();
}
else
{
generator.writeArrayFieldStart(fieldName);
generator.writeEndArray();
}
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
if(e.getCause() instanceof IOException)
throw (IOException)e.getCause();
throw new IOException(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy