// Path: src/main/java/de/galan/verjson/serializer/DateDeserializer.java
// public class DateDeserializer extends JsonDeserializer<Date> {
// 
// 	@Override
// 	public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// 		return from(instantUtc(jp.getText())).toDate();
// 	}
// 
// }
// 
// Path: src/main/java/de/galan/verjson/serializer/DateSerializer.java
// public class DateSerializer extends JsonSerializer<Date> {
// 
// 	@Override
// 	public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
// 		jgen.writeString(from(value).toStringUtc());
// 	}
// 
// 
// 	@Override
// 	public Class<Date> handledType() {
// 		return Date.class;
// 	}
// 
// }
// 
// Path: src/main/java/de/galan/verjson/serializer/ZonedDateTimeDeserializer.java
// public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
// 
// 	@Override
// 	public ZonedDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// 		return ZonedDateTime.parse(jp.getText());
// 	}
// 
// }
// 
// Path: src/main/java/de/galan/verjson/serializer/ZonedDateTimeSerializer.java
// public class ZonedDateTimeSerializer extends JsonSerializer<ZonedDateTime> {
// 
// 	private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'").withZone(ZONE_UTC);
// 
// 
// 	@Override
// 	public void serialize(ZonedDateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
// 		jgen.writeString(DTF.format(value));
// 	}
// 
// 
// 	@Override
// 	public Class<ZonedDateTime> handledType() {
// 		return ZonedDateTime.class;
// 	}
// 
// }


import java.lang.reflect.Method;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.Logger;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.collect.Lists;
import de.galan.commons.logging.Logr;
import de.galan.commons.util.Pair;
import de.galan.verjson.serializer.DateDeserializer;
import de.galan.verjson.serializer.DateSerializer;
import de.galan.verjson.serializer.ZonedDateTimeDeserializer;
import de.galan.verjson.serializer.ZonedDateTimeSerializer;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.AnnotationMemberValue;
import javassist.bytecode.annotation.ArrayMemberValue;
import javassist.bytecode.annotation.ClassMemberValue;
import javassist.bytecode.annotation.EnumMemberValue;
import javassist.bytecode.annotation.MemberValue;
import javassist.bytecode.annotation.StringMemberValue;
package de.galan.verjson.core;






/**
 * Construction of the Jackson ObjectMapper. Configuring Fieldintrospection, Serializer/Deserializer, Polymorph class
 * registration.
 *
 * @author daniel
 */
public class ObjectMapperFactory {

	private static final Logger LOG = Logr.get();


	public ObjectMapper create(Versions versions) {
		ObjectMapper result = new ObjectMapper();
		result.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
		result.setSerializationInclusion(Include.NON_NULL);
		SimpleModule module = new SimpleModule("VerjsonModule");
		registerSerializer(result, module, versions);
		result.registerModule(module);

		for (Class<?> parentClass: versions.getRegisteredSubclasses().keySet()) {
			Class<?> mixin = generateMixIn(parentClass, versions.getRegisteredSubclasses().get(parentClass));
			result.addMixIn(parentClass, mixin);
		}

		return result;
	}


	@SuppressWarnings({"unchecked", "rawtypes"})
	protected void registerSerializer(ObjectMapper result, SimpleModule module, Versions versions) {
		// Default serializer
		module.addSerializer(new DateSerializer());
		module.addDeserializer(Date.class, new DateDeserializer());
// Path: src/main/java/de/galan/verjson/serializer/DateDeserializer.java
// public class DateDeserializer extends JsonDeserializer<Date> {
// 
// 	@Override
// 	public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// 		return from(instantUtc(jp.getText())).toDate();
// 	}
// 
// }
// 
// Path: src/main/java/de/galan/verjson/serializer/DateSerializer.java
// public class DateSerializer extends JsonSerializer<Date> {
// 
// 	@Override
// 	public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
// 		jgen.writeString(from(value).toStringUtc());
// 	}
// 
// 
// 	@Override
// 	public Class<Date> handledType() {
// 		return Date.class;
// 	}
// 
// }
// 
// Path: src/main/java/de/galan/verjson/serializer/ZonedDateTimeDeserializer.java
// public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
// 
// 	@Override
// 	public ZonedDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// 		return ZonedDateTime.parse(jp.getText());
// 	}
// 
// }
// 
// Path: src/main/java/de/galan/verjson/serializer/ZonedDateTimeSerializer.java
// public class ZonedDateTimeSerializer extends JsonSerializer<ZonedDateTime> {
// 
// 	private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'").withZone(ZONE_UTC);
// 
// 
// 	@Override
// 	public void serialize(ZonedDateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
// 		jgen.writeString(DTF.format(value));
// 	}
// 
// 
// 	@Override
// 	public Class<ZonedDateTime> handledType() {
// 		return ZonedDateTime.class;
// 	}
// 
// }


// Path: src/main/java/de/galan/verjson/core/ObjectMapperFactory.java
import java.lang.reflect.Method;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.Logger;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.collect.Lists;
import de.galan.commons.logging.Logr;
import de.galan.commons.util.Pair;
import de.galan.verjson.serializer.DateDeserializer;
import de.galan.verjson.serializer.DateSerializer;
import de.galan.verjson.serializer.ZonedDateTimeDeserializer;
import de.galan.verjson.serializer.ZonedDateTimeSerializer;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.AnnotationMemberValue;
import javassist.bytecode.annotation.ArrayMemberValue;
import javassist.bytecode.annotation.ClassMemberValue;
import javassist.bytecode.annotation.EnumMemberValue;
import javassist.bytecode.annotation.MemberValue;
import javassist.bytecode.annotation.StringMemberValue;

package de.galan.verjson.core;






/**
 * Construction of the Jackson ObjectMapper. Configuring Fieldintrospection, Serializer/Deserializer, Polymorph class
 * registration.
 *
 * @author daniel
 */
public class ObjectMapperFactory {

	private static final Logger LOG = Logr.get();


	public ObjectMapper create(Versions versions) {
		ObjectMapper result = new ObjectMapper();
		result.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
		result.setSerializationInclusion(Include.NON_NULL);
		SimpleModule module = new SimpleModule("VerjsonModule");
		registerSerializer(result, module, versions);
		result.registerModule(module);

		for (Class<?> parentClass: versions.getRegisteredSubclasses().keySet()) {
			Class<?> mixin = generateMixIn(parentClass, versions.getRegisteredSubclasses().get(parentClass));
			result.addMixIn(parentClass, mixin);
		}

		return result;
	}


	@SuppressWarnings({"unchecked", "rawtypes"})
	protected void registerSerializer(ObjectMapper result, SimpleModule module, Versions versions) {
		// Default serializer
		module.addSerializer(new DateSerializer());
		module.addDeserializer(Date.class, new DateDeserializer());
		module.addSerializer(new ZonedDateTimeSerializer());