package restx.jackson; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.jsontype.TypeIdResolver; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.datatype.guava.GuavaModule; import com.fasterxml.jackson.datatype.joda.JodaModule; import restx.AppSettings; import restx.RestxContext; import restx.factory.Factory; import restx.factory.Module; import restx.factory.Name; import restx.factory.Provides; import javax.inject.Named; import java.util.Set; /** * User: xavierhanin * Date: 1/19/13 * Time: 12:12 AM */ @Module public class FrontObjectMapperFactory { public static final String MAPPER_NAME = "FrontObjectMapper"; public static final Name<ObjectMapper> NAME = Name.of(ObjectMapper.class, MAPPER_NAME); public static final String WRITER_NAME = "FrontObjectWriter"; public static final String READER_NAME = "FrontObjectReader"; @Provides @Named(MAPPER_NAME) public ObjectMapper mapper(final Factory factory) { ObjectMapper mapper = new ObjectMapper() .registerModule(new JodaModule()) .registerModule(new GuavaModule()) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) .disable(DeserializationFeature.EAGER_DESERIALIZER_FETCH) .disable(SerializationFeature.EAGER_SERIALIZER_FETCH); Set<com.fasterxml.jackson.databind.Module> modules = factory.getComponents(com.fasterxml.jackson.databind.Module.class); mapper.registerModules(modules); mapper.setHandlerInstantiator(new HandlerInstantiator() { @Override public JsonDeserializer<?> deserializerInstance(DeserializationConfig config, Annotated annotated, Class<?> deserClass) { return (JsonDeserializer<?>) factory.queryByClass(deserClass).optional().findOneAsComponent().orNull(); } @Override public KeyDeserializer keyDeserializerInstance(DeserializationConfig config, Annotated annotated, Class<?> keyDeserClass) { return (KeyDeserializer) factory.queryByClass(keyDeserClass).optional().findOneAsComponent().orNull(); } @Override public JsonSerializer<?> serializerInstance(SerializationConfig config, Annotated annotated, Class<?> serClass) { return (JsonSerializer<?>) factory.queryByClass(serClass).optional().findOneAsComponent().orNull(); } @Override public TypeResolverBuilder<?> typeResolverBuilderInstance(MapperConfig<?> config, Annotated annotated, Class<?> builderClass) { return (TypeResolverBuilder<?>) factory.queryByClass(builderClass).optional().findOneAsComponent().orNull(); } @Override public TypeIdResolver typeIdResolverInstance(MapperConfig<?> config, Annotated annotated, Class<?> resolverClass) { return (TypeIdResolver) factory.queryByClass(resolverClass).optional().findOneAsComponent().orNull(); } }); return mapper; } @Provides @Named(WRITER_NAME) public ObjectWriter objectWriter(@Named(FrontObjectMapperFactory.MAPPER_NAME) final ObjectMapper mapper, AppSettings appSettings) { ObjectWriter objectWriter = RestxContext.Modes.PROD.equals(appSettings.mode()) ? mapper.writer() : mapper.writerWithDefaultPrettyPrinter(); return objectWriter.withView(Views.Transient.class); } @Provides @Named(READER_NAME) public ObjectReader objectReader(@Named(FrontObjectMapperFactory.MAPPER_NAME) final ObjectMapper mapper) { return mapper.readerWithView(Views.Transient.class); } }