Java tutorial
/* * Copyright 2014 Parisian Ninjas * * Licensed under the MIT License; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://opensource.org/licenses/MIT * * 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.ninjas.movietime.conf.vendor.jackson; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.Deserializers; import com.fasterxml.jackson.databind.deser.std.EnumDeserializer; import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer; import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.google.common.base.CharMatcher; import com.google.common.collect.Lists; import java.io.IOException; import java.util.Collection; import java.util.List; /** * A module for deserializing enums that is more permissive than the default. * <p/> * This deserializer is more permissive in the following ways: * <ul> * <li>Whitespace is permitted but stripped from the input.</li> * <li>Dashes and periods in the value are converted to underscores.</li> * <li>Matching against the enum values is case insensitive.</li> * </ul> */ public class FuzzyEnumModule extends Module { private static class PermissiveEnumDeserializer extends StdScalarDeserializer<Enum<?>> { private final Enum<?>[] constants; private final List<String> acceptedValues; @SuppressWarnings("unchecked") protected PermissiveEnumDeserializer(Class<Enum<?>> clazz) { super(clazz); this.constants = ((Class<Enum<?>>) handledType()).getEnumConstants(); this.acceptedValues = Lists.newArrayList(); for (Enum<?> constant : constants) { acceptedValues.add(constant.name()); } } @Override public Enum<?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { final String text = CharMatcher.WHITESPACE.removeFrom(jp.getText()).replace('-', '_').replace('.', '_'); for (Enum<?> constant : constants) { if (constant.name().equalsIgnoreCase(text)) { return constant; } } throw ctxt.mappingException(text + " was not one of " + acceptedValues); } } private static class PermissiveEnumDeserializers extends Deserializers.Base { @Override @SuppressWarnings("unchecked") public JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription desc) throws JsonMappingException { // If there is a JsonCreator annotation we should use that instead of the PermissiveEnumDeserializer final Collection<AnnotatedMethod> factoryMethods = desc.getFactoryMethods(); if (factoryMethods != null) { for (AnnotatedMethod am : factoryMethods) { final JsonCreator creator = am.getAnnotation(JsonCreator.class); if (creator != null) { return EnumDeserializer.deserializerForCreator(config, type, am); } } } return new PermissiveEnumDeserializer((Class<Enum<?>>) type); } } @Override public String getModuleName() { return "permissive-enums"; } @Override public Version version() { return Version.unknownVersion(); } @Override public void setupModule(final SetupContext context) { context.addDeserializers(new PermissiveEnumDeserializers()); } }