
org.dominokit.jacksonapt.ser.bean.AbstractBeanJsonSerializer Maven / Gradle / Ivy
/*
* Copyright 2013 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 org.dominokit.jacksonapt.ser.bean;
import org.dominokit.jacksonapt.JsonSerializationContext;
import org.dominokit.jacksonapt.JsonSerializer;
import org.dominokit.jacksonapt.JsonSerializerParameters;
import org.dominokit.jacksonapt.stream.JsonWriter;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
/**
* Base implementation of {@link org.dominokit.jacksonapt.JsonSerializer} for beans.
*
* @author Nicolas Morel
* @version $Id: $
*/
public abstract class AbstractBeanJsonSerializer extends JsonSerializer implements InternalSerializer {
protected final BeanPropertySerializer[] serializers;
private final Map subtypeClassToSerializer;
private final IdentitySerializationInfo defaultIdentityInfo;
private final TypeSerializationInfo defaultTypeInfo;
private final AnyGetterPropertySerializer anyGetterPropertySerializer;
/**
* Constructor for AbstractBeanJsonSerializer.
*/
protected AbstractBeanJsonSerializer() {
this.serializers = initSerializers();
this.defaultIdentityInfo = initIdentityInfo();
this.defaultTypeInfo = initTypeInfo();
this.subtypeClassToSerializer = initMapSubtypeClassToSerializer();
this.anyGetterPropertySerializer = initAnyGetterPropertySerializer();
}
/**
* Initialize the {@link java.util.Map} containing the property serializers. Returns an empty map if there are no properties to
* serialize.
*
* @return an array of {@link org.dominokit.jacksonapt.ser.bean.BeanPropertySerializer} objects.
*/
protected BeanPropertySerializer[] initSerializers() {
return new BeanPropertySerializer[0];
}
/**
* Initialize the {@link org.dominokit.jacksonapt.ser.bean.IdentitySerializationInfo}. Returns null if there is no {@link com.fasterxml.jackson.annotation.JsonIdentityInfo} annotation on bean.
*
* @return a {@link org.dominokit.jacksonapt.ser.bean.IdentitySerializationInfo} object.
*/
protected IdentitySerializationInfo initIdentityInfo() {
return null;
}
/**
* Initialize the {@link org.dominokit.jacksonapt.ser.bean.TypeSerializationInfo}. Returns null if there is no {@link com.fasterxml.jackson.annotation.JsonTypeInfo} annotation on bean.
*
* @return a {@link org.dominokit.jacksonapt.ser.bean.TypeSerializationInfo} object.
*/
protected TypeSerializationInfo initTypeInfo() {
return null;
}
/**
* Initialize the {@link java.util.Map} containing the {@link org.dominokit.jacksonapt.ser.bean.SubtypeSerializer}. Returns an empty map if the bean has no subtypes.
*
* @return a {@link java.util.Map} object.
*/
protected Map initMapSubtypeClassToSerializer() {
return Collections.emptyMap();
}
/**
* Initialize the {@link org.dominokit.jacksonapt.ser.bean.AnyGetterPropertySerializer}. Returns null if there is no method annoted with {@link com.fasterxml.jackson.annotation.JsonAnyGetter} on bean.
*
* @return a {@link org.dominokit.jacksonapt.ser.bean.AnyGetterPropertySerializer} object.
*/
protected AnyGetterPropertySerializer initAnyGetterPropertySerializer() {
return null;
}
/**
* getSerializedType
*
* @return a {@link java.lang.Class} object.
*/
public abstract Class getSerializedType();
/** {@inheritDoc} */
@Override
public void doSerialize(JsonWriter writer, T value, JsonSerializationContext ctx, JsonSerializerParameters params) {
getSerializer(writer, value, ctx).serializeInternally(writer, value, ctx, params, defaultIdentityInfo, defaultTypeInfo);
}
private InternalSerializer getSerializer(JsonWriter writer, T value, JsonSerializationContext ctx) {
if (value.getClass() == getSerializedType()) {
return this;
}
SubtypeSerializer subtypeSerializer = subtypeClassToSerializer.get(value.getClass());
if (null == subtypeSerializer) {
if (ctx.getLogger().isLoggable(Level.FINE)) {
ctx.getLogger().fine("Cannot find serializer for class " + value
.getClass() + ". Fallback to the serializer of " + getSerializedType());
}
return this;
}
return subtypeSerializer;
}
/** {@inheritDoc} */
public void serializeInternally(JsonWriter writer, T value, JsonSerializationContext ctx, JsonSerializerParameters params,
IdentitySerializationInfo defaultIdentityInfo, TypeSerializationInfo defaultTypeInfo) {
// Processing the parameters. We fallback to default if parameter is not present.
final IdentitySerializationInfo identityInfo = null == params.getIdentityInfo() ? defaultIdentityInfo : params.getIdentityInfo();
final TypeSerializationInfo typeInfo = null == params.getTypeInfo() ? defaultTypeInfo : params.getTypeInfo();
final Set ignoredProperties = null == params.getIgnoredProperties() ? Collections.emptySet() : params
.getIgnoredProperties();
if (params.isUnwrapped()) {
// if unwrapped, we serialize the properties inside the current object
serializeProperties(writer, value, ctx, ignoredProperties, identityInfo);
return;
}
ObjectIdSerializer> idWriter = null;
if (null != identityInfo) {
idWriter = ctx.getObjectId(value);
if (null != idWriter) {
// the bean has already been serialized, we just serialize the id
idWriter.serializeId(writer, ctx);
return;
}
idWriter = identityInfo.getObjectId(value, ctx);
if (identityInfo.isAlwaysAsId()) {
idWriter.serializeId(writer, ctx);
return;
}
ctx.addObjectId(value, idWriter);
}
if (null != typeInfo) {
String typeInformation = typeInfo.getTypeInfo(value.getClass());
if (null == typeInformation) {
ctx.getLogger().log(Level.WARNING, "Cannot find type info for class " + value.getClass());
} else {
switch (typeInfo.getInclude()) {
case PROPERTY:
// type info is included as a property of the object
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);
serializeObject(writer, value, ctx, ignoredProperties, identityInfo, idWriter);
writer.endObject();
return;
case WRAPPER_ARRAY:
// type info is included in a wrapper array that contains two elements. First one is the type
// info and the second one the object
writer.beginArray();
writer.value(typeInformation);
serializeObject(writer, value, ctx, ignoredProperties, identityInfo, idWriter);
writer.endArray();
return;
default:
ctx.getLogger().log(Level.SEVERE, "JsonTypeInfo.As." + typeInfo.getInclude() + " is not supported");
}
}
}
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 ignoredProperties,
IdentitySerializationInfo identityInfo, ObjectIdSerializer> idWriter) {
serializeObject(writer, value, ctx, ignoredProperties, identityInfo, idWriter, null, null);
}
/**
* 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
*/
protected void serializeObject(JsonWriter writer, T value, JsonSerializationContext ctx, Set 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);
}
serializeProperties(writer, value, ctx, ignoredProperties, identityInfo);
writer.endObject();
}
private void serializeProperties(JsonWriter writer, T value, JsonSerializationContext ctx, Set ignoredProperties,
IdentitySerializationInfo identityInfo) {
for (BeanPropertySerializer propertySerializer : serializers) {
if ((null == identityInfo || !identityInfo.isProperty() || !identityInfo.getPropertyName().equals(propertySerializer
.getPropertyName())) && !ignoredProperties.contains(propertySerializer.getPropertyName())) {
propertySerializer.serializePropertyName(writer, value, ctx);
propertySerializer.serialize(writer, value, ctx);
}
}
if (null != anyGetterPropertySerializer) {
anyGetterPropertySerializer.serialize(writer, value, ctx);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy