// Path: stardao-core/src/main/java/io/stardog/stardao/core/field/Field.java
// @AutoValue
// public abstract class Field {
//     public abstract String getName();
//     public abstract String getStorageName();
//     public abstract boolean isOptional();
//     public abstract boolean isCreatable();
//     public abstract boolean isUpdatable();
// 
//     public abstract Field.Builder toBuilder();
//     public static Field.Builder builder() { return new AutoValue_Field.Builder(); }
// 
//     @AutoValue.Builder
//     public abstract static class Builder {
//         public abstract Builder name(String name);
//         public abstract Builder storageName(String storageName);
//         public abstract Builder optional(boolean optional);
//         public abstract Builder creatable(boolean creatable);
//         public abstract Builder updatable(boolean updatable);
//         public abstract Field build();
//     }
// }
// 
// Path: stardao-core/src/main/java/io/stardog/stardao/core/field/FieldData.java
// @AutoValue
// public abstract class FieldData {
//     @Nullable
//     public abstract Field getId();
//     @Nullable
//     public abstract Field getCreatedAt();
//     @Nullable
//     public abstract Field getCreatedBy();
//     @Nullable
//     public abstract Field getUpdatedAt();
//     @Nullable
//     public abstract Field getUpdatedBy();
//     public abstract Map<String,Field> getMap();
// 
//     public abstract Builder toBuilder();
//     public static FieldData.Builder builder() {
//         return new AutoValue_FieldData.Builder();
//     }
// 
//     @AutoValue.Builder
//     public abstract static class Builder {
//         public abstract Builder id(Field id);
//         public abstract Builder createdAt(Field field);
//         public abstract Builder createdBy(Field field);
//         public abstract Builder updatedAt(Field field);
//         public abstract Builder updatedBy(Field field);
//         public abstract Builder map(Map<String,Field> fields);
//         public abstract FieldData build();
//     }
// }
// 
// Path: stardao-mongodb/src/main/java/io/stardog/stardao/mongodb/mapper/DocumentMapper.java
// public interface DocumentMapper<M> {
//     public M toObject(Document document);
//     public Document toDocument(M object);
// }
// 
// Path: stardao-mongodb/src/main/java/io/stardog/stardao/mongodb/mapper/jackson/modules/ExtendedJsonModule.java
// public class ExtendedJsonModule extends SimpleModule {
//     public ExtendedJsonModule() {
//         super();
//         addSerializer(ObjectId.class, new ObjectIdExtJsonSerializer());
//         addSerializer(Instant.class, new InstantExtJsonSerializer());
//         addSerializer(BigDecimal.class, new BigDecimalExtJsonSerializer());
//         addSerializer(UUID.class, new UUIDExtJsonSerializer());
// 
//         // local dates should be stored as strings, not arrays
//         addSerializer(LocalDate.class, new ToStringSerializer());
//     }
// }
// 
// Path: stardao-mongodb/src/main/java/io/stardog/stardao/mongodb/mapper/jackson/modules/MongoModule.java
// public class MongoModule extends SimpleModule {
//     public MongoModule() {
//         super();
//         addSerializer(Decimal128.class, new ToStringSerializer());
//         addSerializer(ObjectId.class, new ToStringSerializer());
//         addDeserializer(ObjectId.class, new ObjectIdDeserializer());
//     }
// }


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.collect.ImmutableMap;
import com.mongodb.MongoException;
import io.stardog.stardao.core.field.Field;
import io.stardog.stardao.core.field.FieldData;
import io.stardog.stardao.mongodb.mapper.DocumentMapper;
import io.stardog.stardao.mongodb.mapper.jackson.modules.ExtendedJsonModule;
import io.stardog.stardao.mongodb.mapper.jackson.modules.MongoModule;
import org.bson.Document;
import java.util.HashMap;
import java.util.Map;
package io.stardog.stardao.mongodb.mapper.jackson;



public class JacksonDocumentMapper<M> implements DocumentMapper<M> {
    private final Class<M> modelClass;
    private final ObjectMapper objectMapper;
    private final ObjectMapper extendedJsonMapper;
    private final Map<String,String> objectToDocumentFieldRenames;
    private final Map<String,String> documentToObjectFieldRenames;

    public final static ObjectMapper DEFAULT_EXTENDED_JSON_MAPPER = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .registerModule(new Jdk8Module())
            .registerModule(new ExtendedJsonModule());

    public final static ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            .registerModule(new JavaTimeModule())
            .registerModule(new Jdk8Module())
            .registerModule(new MongoModule());

    public JacksonDocumentMapper(Class<M> modelClass) {
        this.modelClass = modelClass;
        this.objectMapper = DEFAULT_OBJECT_MAPPER;
        this.extendedJsonMapper = DEFAULT_EXTENDED_JSON_MAPPER;
        this.objectToDocumentFieldRenames = ImmutableMap.of();
        this.documentToObjectFieldRenames = ImmutableMap.of();
    }

// Path: stardao-core/src/main/java/io/stardog/stardao/core/field/Field.java
// @AutoValue
// public abstract class Field {
//     public abstract String getName();
//     public abstract String getStorageName();
//     public abstract boolean isOptional();
//     public abstract boolean isCreatable();
//     public abstract boolean isUpdatable();
// 
//     public abstract Field.Builder toBuilder();
//     public static Field.Builder builder() { return new AutoValue_Field.Builder(); }
// 
//     @AutoValue.Builder
//     public abstract static class Builder {
//         public abstract Builder name(String name);
//         public abstract Builder storageName(String storageName);
//         public abstract Builder optional(boolean optional);
//         public abstract Builder creatable(boolean creatable);
//         public abstract Builder updatable(boolean updatable);
//         public abstract Field build();
//     }
// }
// 
// Path: stardao-core/src/main/java/io/stardog/stardao/core/field/FieldData.java
// @AutoValue
// public abstract class FieldData {
//     @Nullable
//     public abstract Field getId();
//     @Nullable
//     public abstract Field getCreatedAt();
//     @Nullable
//     public abstract Field getCreatedBy();
//     @Nullable
//     public abstract Field getUpdatedAt();
//     @Nullable
//     public abstract Field getUpdatedBy();
//     public abstract Map<String,Field> getMap();
// 
//     public abstract Builder toBuilder();
//     public static FieldData.Builder builder() {
//         return new AutoValue_FieldData.Builder();
//     }
// 
//     @AutoValue.Builder
//     public abstract static class Builder {
//         public abstract Builder id(Field id);
//         public abstract Builder createdAt(Field field);
//         public abstract Builder createdBy(Field field);
//         public abstract Builder updatedAt(Field field);
//         public abstract Builder updatedBy(Field field);
//         public abstract Builder map(Map<String,Field> fields);
//         public abstract FieldData build();
//     }
// }
// 
// Path: stardao-mongodb/src/main/java/io/stardog/stardao/mongodb/mapper/DocumentMapper.java
// public interface DocumentMapper<M> {
//     public M toObject(Document document);
//     public Document toDocument(M object);
// }
// 
// Path: stardao-mongodb/src/main/java/io/stardog/stardao/mongodb/mapper/jackson/modules/ExtendedJsonModule.java
// public class ExtendedJsonModule extends SimpleModule {
//     public ExtendedJsonModule() {
//         super();
//         addSerializer(ObjectId.class, new ObjectIdExtJsonSerializer());
//         addSerializer(Instant.class, new InstantExtJsonSerializer());
//         addSerializer(BigDecimal.class, new BigDecimalExtJsonSerializer());
//         addSerializer(UUID.class, new UUIDExtJsonSerializer());
// 
//         // local dates should be stored as strings, not arrays
//         addSerializer(LocalDate.class, new ToStringSerializer());
//     }
// }
// 
// Path: stardao-mongodb/src/main/java/io/stardog/stardao/mongodb/mapper/jackson/modules/MongoModule.java
// public class MongoModule extends SimpleModule {
//     public MongoModule() {
//         super();
//         addSerializer(Decimal128.class, new ToStringSerializer());
//         addSerializer(ObjectId.class, new ToStringSerializer());
//         addDeserializer(ObjectId.class, new ObjectIdDeserializer());
//     }
// }


// Path: stardao-mongodb/src/main/java/io/stardog/stardao/mongodb/mapper/jackson/JacksonDocumentMapper.java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.collect.ImmutableMap;
import com.mongodb.MongoException;
import io.stardog.stardao.core.field.Field;
import io.stardog.stardao.core.field.FieldData;
import io.stardog.stardao.mongodb.mapper.DocumentMapper;
import io.stardog.stardao.mongodb.mapper.jackson.modules.ExtendedJsonModule;
import io.stardog.stardao.mongodb.mapper.jackson.modules.MongoModule;
import org.bson.Document;
import java.util.HashMap;
import java.util.Map;

package io.stardog.stardao.mongodb.mapper.jackson;



public class JacksonDocumentMapper<M> implements DocumentMapper<M> {
    private final Class<M> modelClass;
    private final ObjectMapper objectMapper;
    private final ObjectMapper extendedJsonMapper;
    private final Map<String,String> objectToDocumentFieldRenames;
    private final Map<String,String> documentToObjectFieldRenames;

    public final static ObjectMapper DEFAULT_EXTENDED_JSON_MAPPER = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .registerModule(new Jdk8Module())
            .registerModule(new ExtendedJsonModule());

    public final static ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            .registerModule(new JavaTimeModule())
            .registerModule(new Jdk8Module())
            .registerModule(new MongoModule());

    public JacksonDocumentMapper(Class<M> modelClass) {
        this.modelClass = modelClass;
        this.objectMapper = DEFAULT_OBJECT_MAPPER;
        this.extendedJsonMapper = DEFAULT_EXTENDED_JSON_MAPPER;
        this.objectToDocumentFieldRenames = ImmutableMap.of();
        this.documentToObjectFieldRenames = ImmutableMap.of();
    }

    public JacksonDocumentMapper(Class<M> modelClass, FieldData fieldData) {