Skip to content

Commit

Permalink
Add @JsonValue support
Browse files Browse the repository at this point in the history
  • Loading branch information
nmorel committed Dec 6, 2014
1 parent 613da8e commit e831d56
Show file tree
Hide file tree
Showing 17 changed files with 408 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.github.nmorel.gwtjackson.client.JsonSerializationContext;
import com.github.nmorel.gwtjackson.client.JsonSerializer;
import com.github.nmorel.gwtjackson.client.JsonSerializerParameters;
Expand All @@ -36,7 +37,7 @@
*/
public abstract class AbstractBeanJsonSerializer<T> extends JsonSerializer<T> implements InternalSerializer<T> {

private final Map<String, BeanPropertySerializer<T, ?>> serializers;
protected final Map<String, BeanPropertySerializer<T, ?>> serializers;

private final Map<Class, SubtypeSerializer> subtypeClassToSerializer;

Expand Down Expand Up @@ -143,29 +144,16 @@ public void serializeInternally( JsonWriter writer, T value, JsonSerializationCo
switch ( typeInfo.getInclude() ) {
case PROPERTY:
// type info is included as a property of the object
writer.beginObject();
writer.name( typeInfo.getPropertyName() );
writer.value( typeInformation );
if ( null != idWriter ) {
writer.name( identityInfo.getPropertyName() );
idWriter.serializeId( writer, ctx );
}
serializeObject( writer, value, ctx, identityInfo, ignoredProperties );
writer.endObject();
serializeObject( writer, value, ctx, ignoredProperties, identityInfo, idWriter, typeInfo
.getPropertyName(), typeInformation );
return;

case WRAPPER_OBJECT:
// type info is included in a wrapper object that contains only one property. The name of this property is the type
// info and the value the object
writer.beginObject();
writer.name( typeInformation );
writer.beginObject();
if ( null != idWriter ) {
writer.name( identityInfo.getPropertyName() );
idWriter.serializeId( writer, ctx );
}
serializeObject( writer, value, ctx, identityInfo, ignoredProperties );
writer.endObject();
serializeObject( writer, value, ctx, ignoredProperties, identityInfo, idWriter );
writer.endObject();
return;

Expand All @@ -174,13 +162,7 @@ public void serializeInternally( JsonWriter writer, T value, JsonSerializationCo
// info and the second one the object
writer.beginArray();
writer.value( typeInformation );
writer.beginObject();
if ( null != idWriter ) {
writer.name( identityInfo.getPropertyName() );
idWriter.serializeId( writer, ctx );
}
serializeObject( writer, value, ctx, identityInfo, ignoredProperties );
writer.endObject();
serializeObject( writer, value, ctx, ignoredProperties, identityInfo, idWriter );
writer.endArray();
return;

Expand All @@ -190,30 +172,59 @@ public void serializeInternally( JsonWriter writer, T value, JsonSerializationCo
}
}

writer.beginObject();
if ( null != idWriter ) {
writer.name( identityInfo.getPropertyName() );
idWriter.serializeId( writer, ctx );
}
serializeObject( writer, value, ctx, identityInfo, ignoredProperties );
writer.endObject();
serializeObject( writer, value, ctx, ignoredProperties, identityInfo, idWriter );
}

/**
* Serializes all the properties of the bean in a json object.
*
* @param writer writer
* @param value bean to serialize
* @param ctx context of the serialization process
* @param ignoredProperties ignored properties
* @param identityInfo identity info
* @param idWriter identifier writer
*/
private void serializeObject( JsonWriter writer, T value, JsonSerializationContext ctx, Set<String> ignoredProperties,
IdentitySerializationInfo identityInfo, ObjectIdSerializer<?> idWriter ) {
serializeObject( writer, value, ctx, ignoredProperties, identityInfo, idWriter, null, null );
}

/**
* Serializes all the properties of the bean. The {@link JsonWriter} must be in a json object.
* Serializes all the properties of the bean in a json object.
*
* @param writer writer
* @param value bean to serialize
* @param ctx context of the serialization process
* @param ignoredProperties ignored properties
* @param identityInfo identity info
* @param idWriter identifier writer
* @param typeName in case of type info as property, the name of the property
* @param typeInformation in case of type info as property, the type information
*/
private void serializeObject( JsonWriter writer, T value, JsonSerializationContext ctx, IdentitySerializationInfo identityInfo,
Set<String> ignoredProperties ) {
protected void serializeObject( JsonWriter writer, T value, JsonSerializationContext ctx, Set<String> ignoredProperties,
IdentitySerializationInfo identityInfo, ObjectIdSerializer<?> idWriter, String typeName, String
typeInformation ) {
writer.beginObject();

if ( null != typeName && null != typeInformation ) {
writer.name( typeName );
writer.value( typeInformation );
}

if ( null != idWriter ) {
writer.name( identityInfo.getPropertyName() );
idWriter.serializeId( writer, ctx );
}

for ( Map.Entry<String, BeanPropertySerializer<T, ?>> entry : serializers.entrySet() ) {
if ( (null == identityInfo || !identityInfo.isProperty() || !identityInfo.getPropertyName().equals( entry
.getKey() )) && !ignoredProperties.contains( entry.getKey() ) ) {
writer.name( entry.getKey() );
entry.getValue().serialize( writer, value, ctx );
}
}

writer.endObject();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2014 Nicolas Morel
*
* 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.github.nmorel.gwtjackson.client.ser.bean;

import java.util.Set;

import com.github.nmorel.gwtjackson.client.JsonSerializationContext;
import com.github.nmorel.gwtjackson.client.stream.JsonWriter;

/**
* @author Nicolas Morel
*/
public abstract class AbstractValueBeanJsonSerializer<T> extends AbstractBeanJsonSerializer<T> {

private final BeanPropertySerializer<T, ?> serializer;

protected AbstractValueBeanJsonSerializer() {
super();
this.serializer = initValueSerializer();
}

protected abstract BeanPropertySerializer<T, ?> initValueSerializer();

@Override
protected void serializeObject( JsonWriter writer, T value, JsonSerializationContext ctx, Set<String> ignoredProperties,
IdentitySerializationInfo identityInfo, ObjectIdSerializer<?> idWriter, String typeName, String
typeInformation ) {
serializer.serialize( writer, value, ctx );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.github.nmorel.gwtjackson.client.deser.bean.PropertyIdentityDeserializationInfo;
import com.github.nmorel.gwtjackson.client.ser.bean.AbstractBeanJsonSerializer;
import com.github.nmorel.gwtjackson.client.ser.bean.AbstractIdentitySerializationInfo;
import com.github.nmorel.gwtjackson.client.ser.bean.AbstractValueBeanJsonSerializer;
import com.github.nmorel.gwtjackson.client.ser.bean.ObjectIdSerializer;
import com.github.nmorel.gwtjackson.client.ser.bean.PropertyIdentitySerializationInfo;
import com.github.nmorel.gwtjackson.rebind.bean.BeanIdentityInfo;
Expand Down Expand Up @@ -102,8 +103,8 @@ public String getJoinedTypeParameterMappersWithType() {

protected BeanJsonMapperInfo mapperInfo;

public AbstractBeanJsonCreator( TreeLogger logger, GeneratorContext context, RebindConfiguration configuration,
JacksonTypeOracle typeOracle ) {
public AbstractBeanJsonCreator( TreeLogger logger, GeneratorContext context, RebindConfiguration configuration, JacksonTypeOracle
typeOracle ) {
super( logger, context, configuration, typeOracle );
}

Expand Down Expand Up @@ -167,6 +168,8 @@ public String create( JClassType beanType ) throws UnableToCompleteException, Un
ImmutableMap<String, PropertyInfo> properties = PropertyProcessor
.findAllProperties( configuration, logger, typeOracle, beanInfo, samePackage );

beanInfo = BeanProcessor.processProperties( configuration, logger, typeOracle, beanInfo, properties );

mapperInfo = new BeanJsonMapperInfo( beanType, qualifiedSerializerClassName, simpleSerializerClassName,
qualifiedDeserializerClassName, simpleDeserializerClassName, beanInfo, properties );

Expand All @@ -175,15 +178,23 @@ public String create( JClassType beanType ) throws UnableToCompleteException, Un

String superclass;
if ( isSerializer() ) {
superclass = ABSTRACT_BEAN_JSON_SERIALIZER_CLASS + "<" + beanType.getParameterizedQualifiedSourceName() + ">";
} else if ( isObject( beanType ) ) {
superclass = AbstractObjectBeanJsonDeserializer.class.getCanonicalName();
} else if ( isSerializable( beanType ) ) {
superclass = AbstractSerializableBeanJsonDeserializer.class.getCanonicalName();
} else if ( mapperInfo.getBeanInfo().isCreatorDelegation() ) {
superclass = AbstractDelegationBeanJsonDeserializer.class.getCanonicalName() + "<" + beanType.getParameterizedQualifiedSourceName() + ">";
if ( mapperInfo.getBeanInfo().getValuePropertyInfo().isPresent() ) {
superclass = AbstractValueBeanJsonSerializer.class.getCanonicalName();
} else {
superclass = ABSTRACT_BEAN_JSON_SERIALIZER_CLASS;
}
superclass = superclass + "<" + beanType.getParameterizedQualifiedSourceName() + ">";
} else {
superclass = ABSTRACT_BEAN_JSON_DESERIALIZER_CLASS + "<" + beanType.getParameterizedQualifiedSourceName() + ">";
if ( isObject( beanType ) ) {
superclass = AbstractObjectBeanJsonDeserializer.class.getCanonicalName();
} else if ( isSerializable( beanType ) ) {
superclass = AbstractSerializableBeanJsonDeserializer.class.getCanonicalName();
} else if ( mapperInfo.getBeanInfo().isCreatorDelegation() ) {
superclass = AbstractDelegationBeanJsonDeserializer.class.getCanonicalName() + "<" + beanType
.getParameterizedQualifiedSourceName() + ">";
} else {
superclass = ABSTRACT_BEAN_JSON_DESERIALIZER_CLASS + "<" + beanType.getParameterizedQualifiedSourceName() + ">";
}
}

SourceWriter source = getSourceWriter( printWriter, packageName, getSimpleClassName() + getGenericClassBoundedParameters(),
Expand Down Expand Up @@ -214,11 +225,11 @@ protected String getGenericClassBoundedParameters() {
return mapperInfo.getGenericClassBoundedParameters();
}

protected abstract void writeClassBody( SourceWriter source, BeanInfo info, ImmutableMap<String,
PropertyInfo> properties ) throws UnableToCompleteException, UnsupportedTypeException;
protected abstract void writeClassBody( SourceWriter source, BeanInfo info, ImmutableMap<String, PropertyInfo> properties ) throws
UnableToCompleteException, UnsupportedTypeException;

protected TypeParameters generateTypeParameterMapperFields( SourceWriter source, BeanInfo beanInfo, String mapperClass,
String mapperNameFormat ) throws UnableToCompleteException {
protected TypeParameters generateTypeParameterMapperFields( SourceWriter source, BeanInfo beanInfo, String mapperClass, String
mapperNameFormat ) throws UnableToCompleteException {
if ( beanInfo.getParameterizedTypes().isEmpty() ) {
return null;
}
Expand Down Expand Up @@ -252,14 +263,6 @@ protected String getParameterizedQualifiedClassName( JType type ) {
}
}

protected String getQualifiedClassName( JType type ) {
if ( null == type.isPrimitive() ) {
return type.getQualifiedSourceName();
} else {
return type.isPrimitive().getQualifiedBoxedSourceName();
}
}

protected Optional<JSerializerType> getIdentitySerializerType( BeanIdentityInfo identityInfo ) throws UnableToCompleteException,
UnsupportedTypeException {
if ( identityInfo.isIdABeanProperty() ) {
Expand Down Expand Up @@ -401,8 +404,8 @@ private JClassType findFirstTypeToApplyPropertyAnnotation( List<JMapperType> map
return findFirstTypeToApplyPropertyAnnotation( subLevel );
}

protected void generateCommonPropertyParameters( SourceWriter source, PropertyInfo property,
JMapperType mapperType ) throws UnableToCompleteException {
protected void generateCommonPropertyParameters( SourceWriter source, PropertyInfo property, JMapperType mapperType ) throws
UnableToCompleteException {
if ( property.getFormat().isPresent() ) {
JsonFormat format = property.getFormat().get();
if ( !Strings.isNullOrEmpty( format.pattern() ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public class BeanJsonMapperInfo {
private final ImmutableMap<String, PropertyInfo> properties;

public BeanJsonMapperInfo( JClassType type, String qualifiedSerializerClassName, String simpleSerializerClassName, String
qualifiedDeserializerClassName, String simpleDeserializerClassName, BeanInfo beanInfo, ImmutableMap<String,
PropertyInfo> properties ) {
qualifiedDeserializerClassName, String simpleDeserializerClassName, BeanInfo beanInfo, ImmutableMap<String, PropertyInfo>
properties ) {
this.type = type;
this.qualifiedSerializerClassName = qualifiedSerializerClassName;
this.simpleSerializerClassName = simpleSerializerClassName;
Expand Down
Loading

0 comments on commit e831d56

Please sign in to comment.