/* ==================================================================
* ObjectMapperFactoryBean.java - Mar 20, 2013 5:28:37 PM
*
* Copyright 2007-2013 SolarNetwork.net Dev Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ==================================================================
*/
package net.solarnetwork.util;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.FactoryBean;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
/**
* Factory for {@link ObjectMapper} that allows configuring an application-wide
* ObjectMapper.
*
* <p>
* This factory will generate a {@link Module} and register that with the
* returned {@link ObjectMapper}.
* </p>
*
* <p>
* The configurable properties of this class are:
* </p>
*
* <dl class="class-properties">
* <dt>moduleName</dt>
* <dd>A {@link Module} name to use.</dd>
*
* <dt>moduleVersion</dt>
* <dd>A {@link Version} to use for the module.</dd>
*
* <dt>serializers</dt>
* <dd>A list of serializers to register with the module.</dd>
*
* <dt>deserializers</dt>
* <dd>A list of deserializers to register with the module. Note that these must
* be subclasses of {@link StdDeserializer}.</dd>
*
* <dt>mapper</dt>
* <dd>The {@link ObjectMapper} to configure.</dd>
*
* <dt>serializationInclusion</dt>
* <dd>A serialization inclusion setting to configure.</dd>
*
* <dt>featuresToEnable</dt>
* <dd>A list of {@link SerializationFeature} or {@link DeserializationFeature}
* flags to enable.</dd>
*
* <dt>featuresToDisable</dt>
* <dd>A list of {@link SerializationFeature} or {@link DeserializationFeature}
* flags to disable.</dd>
* </dl>
*
* @author matt
* @version 1.3
*/
public class ObjectMapperFactoryBean extends ObjectMapperModuleSupport
implements FactoryBean<ObjectMapper> {
private JsonInclude.Include serializationInclusion = JsonInclude.Include.NON_NULL;
private List<Object> featuresToEnable = null;
private List<Object> featuresToDisable = null;
@Override
public ObjectMapper getObject() throws Exception {
ObjectMapper mapper = getObjectMapper();
if ( mapper == null ) {
mapper = new ObjectMapper();
setObjectMapper(mapper);
}
SimpleModule module = new SimpleModule(getModuleName(), getModuleVersion());
if ( getSerializers() != null ) {
for ( JsonSerializer<?> serializer : getSerializers() ) {
module.addSerializer(serializer);
}
}
if ( getDeserializers() != null ) {
for ( JsonDeserializer<?> deserializer : getDeserializers() ) {
registerDeserializer(module, deserializer);
}
}
if ( getKeyDeserializers() != null ) {
for ( TypedKeyDeserializer deserializer : getKeyDeserializers() ) {
module.addKeyDeserializer(deserializer.getClass(), deserializer.getKeyDeserializer());
}
}
if ( getKeySerializers() != null ) {
for ( JsonSerializer<?> serializer : getKeySerializers() ) {
registerKeySerializer(module, serializer);
}
}
if ( serializationInclusion != null ) {
mapper.setSerializationInclusion(serializationInclusion);
}
setupFeatures(mapper, featuresToEnable, true);
setupFeatures(mapper, featuresToDisable, false);
mapper.registerModule(module);
return mapper;
}
private void setupFeatures(final ObjectMapper m, final Collection<?> features, final boolean state) {
if ( features == null ) {
return;
}
for ( Object o : features ) {
if ( o instanceof SerializationFeature ) {
m.configure((SerializationFeature) o, state);
} else if ( o instanceof DeserializationFeature ) {
m.configure((DeserializationFeature) o, state);
}
}
}
@Override
public Class<?> getObjectType() {
return ObjectMapper.class;
}
@Override
public boolean isSingleton() {
return true;
}
/**
* Get the {@code ObjectMapper} to use.
*
* @return the mapper
* @deprecated see {@link #getObjectMapper()}
*/
@Deprecated
public ObjectMapper getMapper() {
return getObjectMapper();
}
/**
* Set the {@code ObjectMapper} to use.
*
* @param obj
* the mapper to use
* @deprecated see @link {@link #setObjectMapper(ObjectMapper)}
*/
@Deprecated
public void setMapper(ObjectMapper obj) {
setObjectMapper(obj);
}
/**
* Get the serialization inclusion setting.
*
* @return the serialization inclusion
* @since 1.2
*/
public JsonInclude.Include getSerializationInclusion() {
return serializationInclusion;
}
/**
* Set the serialization inclusion to use.
*
* @param serializationInclusion
* the inclusion setting
* @since 1.2
*/
public void setSerializationInclusion(JsonInclude.Include serializationInclusion) {
this.serializationInclusion = serializationInclusion;
}
public List<Object> getFeaturesToEnable() {
return featuresToEnable;
}
/**
* Set a list of {@link SerializationFeature} or
* {@link DeserializationFeature} flags to enable.
*
* @param featuresToEnable
* @since 1.2
*/
public void setFeaturesToEnable(List<Object> featuresToEnable) {
this.featuresToEnable = featuresToEnable;
}
public List<Object> getFeaturesToDisable() {
return featuresToDisable;
}
/**
* Set a list of {@link SerializationFeature} or
* {@link DeserializationFeature} flags to disable.
*
* @param featuresToDisable
* @since 1.2
*/
public void setFeaturesToDisable(List<Object> featuresToDisable) {
this.featuresToDisable = featuresToDisable;
}
}