package de.agilecoders.wicket.jquery.settings;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.RawSerializer;
import de.agilecoders.wicket.jquery.Config;
import de.agilecoders.wicket.jquery.ConfigModel;
import de.agilecoders.wicket.jquery.util.Json;

import java.io.IOException;

/**
 * {@link com.fasterxml.jackson.databind.ObjectMapper} factory
 *
 * @author Michael Haitz <michael.haitz@agilecoders.de>
 */
public class DefaultObjectMapperFactory implements ObjectMapperFactory {

    /**
     * lazy holder pattern to prevent instantiation of serializers if not used.
     */
    protected static final class Holder {
        private static final RawSerializer<Json.RawValue> rawSerializer = new RawSerializer<Json.RawValue>(Json.RawValue.class) {
            @Override
            public void serialize(Json.RawValue value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
                jsonGenerator.writeObject(value.value());
            }
        };
        public static JsonSerializer<Config> configSerializer = new JsonSerializer<Config>() {
            @Override
            public void serialize(Config value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
                jsonGenerator.writeObject(value.toJsonString());
            }
        };
        public static JsonSerializer<ConfigModel> configModelSerializer = new JsonSerializer<ConfigModel>() {
            @Override
            public void serialize(ConfigModel value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
                jsonGenerator.writeString(value.getObject());
            }
        };
    }

    /**
     * Construct.
     */
    public DefaultObjectMapperFactory() {
        super();
    }

    /**
     * @return new object mapper instance
     */
    @Override
    public ObjectMapper newObjectMapper() {
        return configure(new ObjectMapper()).registerModule(newModule());
    }

    /**
     * @return new mapper module
     */
    protected Module newModule() {
        return addSerializer(new SimpleModule("wicket-jquery-selectors", new Version(1, 0, 0, null, "de.agilecoders.wicket", "wicket-jquery-selectors")));
    }

    /**
     * adds custom serializers to given module
     *
     * @param module the module to extend
     * @return module instance for chaining
     */
    protected Module addSerializer(SimpleModule module) {
        module.addSerializer(ConfigModel.class, Holder.configModelSerializer);
        module.addSerializer(Config.class, Holder.configSerializer);
        module.addSerializer(Json.RawValue.class, Holder.rawSerializer);

        return module;
    }

    /**
     * configures given object mapper instance.
     *
     * @param mapper the object to configure
     * @return mapper instance for chaining
     */
    protected ObjectMapper configure(ObjectMapper mapper) {
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

        return mapper;
    }
}

@@ -83,160 +83,57 @@
 Json
-Generator;%0Aimport com.fasterxml.jackson.core.JsonParser;%0Aimport com.fasterxml.jackson.core.Version;%0Aimport com.fasterxml.jackson.databind.JsonSerializer
+Parser;%0Aimport com.fasterxml.jackson.core.Version
 ;%0Aim
@@ -232,66 +232,8 @@
 er;%0A
-import com.fasterxml.jackson.databind.SerializerProvider;%0A
 impo
@@ -291,68 +291,8 @@
 le;%0A
-import com.fasterxml.jackson.databind.ser.std.RawSerializer;
 %0Aimp
@@ -432,35 +432,218 @@
 on;%0A
-%0A
 import 
-java.io.IOException
+de.agilecoders.wicket.jquery.util.serializer.ConfigModelSerializer;%0Aimport de.agilecoders.wicket.jquery.util.serializer.ConfigSerializer;%0Aimport de.agilecoders.wicket.jquery.util.serializer.RawSerializer
 ;%0A%0A/
@@ -995,15 +995,26 @@
     
-private
+%0A        protected
  sta
@@ -1040,1018 +1040,253 @@
 izer
-%3CJson.RawValue%3E rawSerializer = new RawSerializer%3CJson.RawValue%3E(Json.RawValue.class) %7B%0A            @Override%0A            public void serialize(Json.RawValue value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException %7B%0A                jsonGenerator.writeObject(value.value());%0A            %7D%0A        %7D;%0A        public static JsonSerializer%3CConfig%3E configSerializer = new JsonSerializer%3CConfig%3E() %7B%0A            @Override%0A            public void serialize(Config value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException %7B%0A                jsonGenerator.writeObject(value.toJsonString());%0A            %7D%0A        %7D;%0A        public static JsonSerializer%3CConfigModel%3E configModelSerializer = new JsonSerializer%3CConfigModel%3E() %7B%0A            @Override%0A            public void serialize(ConfigModel value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException %7B%0A                jsonGenerator.writeString(value.getObject());%0A            %7D%0A        %7D
+ RAW_VALUE_SERIALIZER = new RawSerializer();%0A%0A        protected static final ConfigSerializer CONFIG_SERIALIZER = new ConfigSerializer();%0A%0A        protected static final ConfigModelSerializer CONFIG_MODEL_SERIALIZER = new ConfigModelSerializer()
 ;%0A  
@@ -2106,29 +2106,31 @@
 der.
-configModelSerializer
+CONFIG_MODEL_SERIALIZER
 );%0A 
@@ -2182,24 +2182,25 @@
 der.
-configSerializer
+CONFIG_SERIALIZER
 );%0A 
@@ -2259,21 +2259,28 @@
 der.
-rawSerializer
+RAW_VALUE_SERIALIZER
 );%0A%0A

Use the newly introduced serializer classes.