package core.framework.impl.mongo; import core.framework.api.util.Exceptions; import core.framework.api.util.Maps; import core.framework.api.util.Sets; import org.bson.codecs.Codec; import org.bson.codecs.configuration.CodecRegistries; import org.bson.codecs.configuration.CodecRegistry; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; /** * @author neo */ public final class EntityCodecs { private final Map<Class<?>, EntityCodec<?>> codecs = Maps.newHashMap(); private final Set<Class<? extends Enum<?>>> enumClasses = Sets.newHashSet(); public <T> void registerEntity(Class<T> entityClass) { EntityIdHandler<T> entityIdHandler = new EntityIdHandlerBuilder<>(entityClass).build(); register(entityClass, entityIdHandler); } public <T> void registerView(Class<T> viewClass) { register(viewClass, null); } public <T> Object id(T entity) { @SuppressWarnings("unchecked") EntityCodec<T> codec = (EntityCodec<T>) codecs.get(entity.getClass()); EntityIdHandler<T> idHandler = codec.idHandler; return idHandler.get(entity); } private <T> void register(Class<T> entityClass, EntityIdHandler<T> idHandler) { EntityEncoderBuilder<T> builder = new EntityEncoderBuilder<>(entityClass); EntityEncoder<T> entityEncoder = builder.build(); enumClasses.addAll(builder.enumClasses); EntityDecoder<T> entityDecoder = new EntityDecoderBuilder<>(entityClass).build(); EntityCodec<T> codec = new EntityCodec<>(entityClass, idHandler, entityEncoder, entityDecoder); Codec<?> previous = codecs.putIfAbsent(entityClass, codec); if (previous != null) throw Exceptions.error("entity or view class is registered, entityClass={}", entityClass.getCanonicalName()); } <T extends Enum<T>> CodecRegistry codecRegistry() { List<Codec<?>> codecs = new ArrayList<>(this.codecs.values()); codecs.add(new LocalDateTimeCodec()); codecs.add(new ZonedDateTimeCodec()); for (Class<? extends Enum<?>> enumClass : enumClasses) { @SuppressWarnings("unchecked") Class<T> codecClass = (Class<T>) enumClass; codecs.add(new EnumCodec<>(codecClass)); } return CodecRegistries.fromCodecs(codecs); } }