From fadc870078822013a06eaf8e530e6bb899477f3c Mon Sep 17 00:00:00 2001 From: godotg Date: Mon, 17 Jun 2024 10:53:07 +0800 Subject: [PATCH] chore[orm]: support map of basic types --- .../java/com/zfoo/orm/codec/BaseTypeEnum.java | 53 ++++++++++++++ ...MapCodec.java => BaseTypeKeyMapCodec.java} | 33 +++++---- .../java/com/zfoo/orm/codec/LongMapCodec.java | 70 ------------------- .../com/zfoo/orm/codec/MapCodecProvider.java | 8 +-- .../java/com/zfoo/orm/codec/MapKeyCodec.java | 22 ++++++ .../orm/codec/basetype/BooleanMapCodec.java | 37 ++++++++++ .../zfoo/orm/codec/basetype/ByteMapCodec.java | 22 ++++++ .../orm/codec/basetype/CharacterMapCodec.java | 27 +++++++ .../orm/codec/basetype/DoubleMapCodec.java | 22 ++++++ .../orm/codec/basetype/FloatMapCodec.java | 22 ++++++ .../zfoo/orm/codec/basetype/IntMapCodec.java | 25 +++++++ .../zfoo/orm/codec/basetype/LongMapCodec.java | 25 +++++++ .../orm/codec/basetype/ShortMapCodec.java | 21 ++++++ 13 files changed, 298 insertions(+), 89 deletions(-) create mode 100644 orm/src/main/java/com/zfoo/orm/codec/BaseTypeEnum.java rename orm/src/main/java/com/zfoo/orm/codec/{IntMapCodec.java => BaseTypeKeyMapCodec.java} (54%) delete mode 100644 orm/src/main/java/com/zfoo/orm/codec/LongMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/MapKeyCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/BooleanMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/ByteMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/CharacterMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/DoubleMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/FloatMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/IntMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/LongMapCodec.java create mode 100644 orm/src/main/java/com/zfoo/orm/codec/basetype/ShortMapCodec.java diff --git a/orm/src/main/java/com/zfoo/orm/codec/BaseTypeEnum.java b/orm/src/main/java/com/zfoo/orm/codec/BaseTypeEnum.java new file mode 100644 index 00000000..0f2c6d83 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/BaseTypeEnum.java @@ -0,0 +1,53 @@ +package com.zfoo.orm.codec; + +import com.zfoo.orm.codec.basetype.*; + +/** + * 基础类型枚举 + * @Author:lqh + * @Date:2024/6/17 11:41 + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public enum BaseTypeEnum { + Float(java.lang.Float.class, new FloatMapCodec()), + Integer(java.lang.Integer.class, new IntMapCodec()), + Double(java.lang.Double.class, new DoubleMapCodec()), + Character(java.lang.Character.class, new CharacterMapCodec()), + Byte(java.lang.Byte.class, new ByteMapCodec()), + Boolean(java.lang.Boolean.class, new BooleanMapCodec()), + Long(java.lang.Long.class, new LongMapCodec()), + Short(java.lang.Short.class, new ShortMapCodec()), + ; + private final MapKeyCodec mapKeyCodec; + + private final Class clazz; + + BaseTypeEnum(Class clazz, MapKeyCodec mapKeyCodec) { + this.clazz = clazz; + this.mapKeyCodec = mapKeyCodec; + } + + public MapKeyCodec getMapKeyCodec() { + return mapKeyCodec; + } + + public Class getClazz() { + return clazz; + } + public static boolean containsKeyType(Class keyClass){ + for (BaseTypeEnum typeEnum : values()) { + if (typeEnum.getClazz() == keyClass) { + return true; + } + } + return false; + } + public static MapKeyCodec getCodec(Class clazz) { + for (BaseTypeEnum typeEnum : values()) { + if (typeEnum.getClazz() == clazz) { + return typeEnum.getMapKeyCodec(); + } + } + return null; + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/IntMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/BaseTypeKeyMapCodec.java similarity index 54% rename from orm/src/main/java/com/zfoo/orm/codec/IntMapCodec.java rename to orm/src/main/java/com/zfoo/orm/codec/BaseTypeKeyMapCodec.java index acb30378..39dd579b 100644 --- a/orm/src/main/java/com/zfoo/orm/codec/IntMapCodec.java +++ b/orm/src/main/java/com/zfoo/orm/codec/BaseTypeKeyMapCodec.java @@ -11,45 +11,49 @@ import java.util.HashMap; import java.util.Map; /** - * map解析器 - * + * 基础类型作为key的map解析器 * @Author:lqh - * @Date:2024/6/14 10:32 + * @Date:2024/6/17 13:55 */ -public class IntMapCodec implements Codec> { +public class BaseTypeKeyMapCodec implements Codec> { - private final Class> encoderClass; - private final Codec keyCodec; + private final Class> encoderClass; + private final Codec keyCodec; private final Codec valueCodec; - IntMapCodec(final Class> encoderClass, final Codec keyCodec, final Codec valueCodec) { + BaseTypeKeyMapCodec(final Class> encoderClass, final Codec keyCodec, final Codec valueCodec) { this.encoderClass = encoderClass; this.keyCodec = keyCodec; this.valueCodec = valueCodec; } @Override - public void encode(final BsonWriter writer, final Map map, final EncoderContext encoderContext) { + @SuppressWarnings({"unchecked"}) + public void encode(final BsonWriter writer, final Map map, final EncoderContext encoderContext) { writer.writeStartDocument(); for (var entry : map.entrySet()) { var key = entry.getKey(); var value = entry.getValue(); - writer.writeName(key.toString()); + MapKeyCodec codec = BaseTypeEnum.getCodec(keyCodec.getEncoderClass()); + String keyValue = codec.encode(key); + writer.writeName(keyValue); if (value == null) { writer.writeNull(); } else { - valueCodec.encode(writer, entry.getValue(), encoderContext); + valueCodec.encode(writer, value, encoderContext); } } writer.writeEndDocument(); } @Override - public Map decode(final BsonReader reader, final DecoderContext context) { + @SuppressWarnings({"unchecked"}) + public Map decode(final BsonReader reader, final DecoderContext context) { reader.readStartDocument(); - var map = new HashMap(); + var map = new HashMap(); while (!BsonType.END_OF_DOCUMENT.equals(reader.readBsonType())) { - int key = Integer.parseInt(reader.readName()); + MapKeyCodec codec = BaseTypeEnum.getCodec(keyCodec.getEncoderClass()); + K key = codec.decode(reader.readName()); V value = null; if (BsonType.NULL.equals(reader.getCurrentBsonType())) { reader.readNull(); @@ -63,8 +67,9 @@ public class IntMapCodec implements Codec> { } @Override - public Class> getEncoderClass() { + public Class> getEncoderClass() { return encoderClass; } } + diff --git a/orm/src/main/java/com/zfoo/orm/codec/LongMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/LongMapCodec.java deleted file mode 100644 index 4fb3b5da..00000000 --- a/orm/src/main/java/com/zfoo/orm/codec/LongMapCodec.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.zfoo.orm.codec; - -import org.bson.BsonReader; -import org.bson.BsonType; -import org.bson.BsonWriter; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; - -import java.util.HashMap; -import java.util.Map; - -/** - * map解析器 - * - * @Author:lqh - * @Date:2024/6/14 10:32 - */ -public class LongMapCodec implements Codec> { - - private final Class> encoderClass; - private final Codec keyCodec; - private final Codec valueCodec; - - LongMapCodec(final Class> encoderClass, final Codec keyCodec, final Codec valueCodec) { - this.encoderClass = encoderClass; - this.keyCodec = keyCodec; - this.valueCodec = valueCodec; - } - - @Override - public void encode(final BsonWriter writer, final Map map, final EncoderContext encoderContext) { - writer.writeStartDocument(); - for (var entry : map.entrySet()) { - var key = entry.getKey(); - var value = entry.getValue(); - writer.writeName(key.toString()); - if (value == null) { - writer.writeNull(); - } else { - valueCodec.encode(writer, entry.getValue(), encoderContext); - } - } - writer.writeEndDocument(); - } - - @Override - public Map decode(final BsonReader reader, final DecoderContext context) { - reader.readStartDocument(); - var map = new HashMap(); - while (!BsonType.END_OF_DOCUMENT.equals(reader.readBsonType())) { - long key = Long.parseLong(reader.readName()); - V value = null; - if (BsonType.NULL.equals(reader.getCurrentBsonType())) { - reader.readNull(); - } else { - value = valueCodec.decode(reader, context); - } - map.put(key, value); - } - reader.readEndDocument(); - return map; - } - - @Override - public Class> getEncoderClass() { - return encoderClass; - } - -} diff --git a/orm/src/main/java/com/zfoo/orm/codec/MapCodecProvider.java b/orm/src/main/java/com/zfoo/orm/codec/MapCodecProvider.java index 41005420..63d8475e 100644 --- a/orm/src/main/java/com/zfoo/orm/codec/MapCodecProvider.java +++ b/orm/src/main/java/com/zfoo/orm/codec/MapCodecProvider.java @@ -1,5 +1,6 @@ package com.zfoo.orm.codec; + import org.bson.codecs.Codec; import org.bson.codecs.pojo.PropertyCodecProvider; import org.bson.codecs.pojo.PropertyCodecRegistry; @@ -24,11 +25,8 @@ public class MapCodecProvider implements PropertyCodecProvider { } var keyType = typeParameters.get(0); var valueType = typeParameters.get(1); - if (keyType.getType() == Integer.class) { - return new IntMapCodec(type.getType(), registry.get(keyType), registry.get(valueType)); - } - if (keyType.getType() == Long.class) { - return new LongMapCodec(type.getType(), registry.get(keyType), registry.get(valueType)); + if (BaseTypeEnum.containsKeyType(keyType.getType())){ + return new BaseTypeKeyMapCodec(type.getType(), registry.get(keyType), registry.get(valueType)); } return null; } diff --git a/orm/src/main/java/com/zfoo/orm/codec/MapKeyCodec.java b/orm/src/main/java/com/zfoo/orm/codec/MapKeyCodec.java new file mode 100644 index 00000000..5d7523c8 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/MapKeyCodec.java @@ -0,0 +1,22 @@ +package com.zfoo.orm.codec; + +/** + * map key编码接口 + * @Author:lqh + * @Date:2024/6/17 13:51 + */ +public interface MapKeyCodec { + /** + * 编码 + * @param value + * @return + */ + String encode(K value); + + /** + * 解析 + * @param text + * @return + */ + K decode(String text); +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/BooleanMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/BooleanMapCodec.java new file mode 100644 index 00000000..63197040 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/BooleanMapCodec.java @@ -0,0 +1,37 @@ +package com.zfoo.orm.codec.basetype; + +import com.zfoo.orm.codec.MapKeyCodec; + +/** + * @Author:lqh + * @Date:2024/6/17 11:32 + */ +public class BooleanMapCodec implements MapKeyCodec { + + + @Override + public String encode(Boolean value) { + return value ? "True" : "False"; + } + + @Override + public Boolean decode(String text) { + if (text == null) { + return null; + } else if (isValidName(true, text)) { + return true; + } else if (isValidName(false, text)) { + return false; + } else { + throw new java.lang.IllegalArgumentException(text); + } + } + + private String getValidName(boolean value) { + return value ? "True" : "False"; + } + + private boolean isValidName(boolean value, String name) { + return getValidName(value).equalsIgnoreCase(name); + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/ByteMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/ByteMapCodec.java new file mode 100644 index 00000000..b0554bd9 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/ByteMapCodec.java @@ -0,0 +1,22 @@ +package com.zfoo.orm.codec.basetype; + + +import com.zfoo.orm.codec.MapKeyCodec; + +/** + * @Author:lqh + * @Date:2024/6/17 11:39 + */ +public class ByteMapCodec implements MapKeyCodec { + @Override + public String encode(Byte value) { + return (value != null) + ? value.toString() + : null; + } + + @Override + public Byte decode(String text) { + return (text == null) ? null : Byte.decode(text); + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/CharacterMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/CharacterMapCodec.java new file mode 100644 index 00000000..fe6f197a --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/CharacterMapCodec.java @@ -0,0 +1,27 @@ +package com.zfoo.orm.codec.basetype; + +import com.zfoo.orm.codec.MapKeyCodec; +import org.springframework.util.StringUtils; + + +/** + * @Author:lqh + * @Date:2024/6/17 11:34 + */ +public class CharacterMapCodec implements MapKeyCodec { + @Override + public String encode(Character value) { + return (value != null) + ? value.toString() + : ""; + } + + @Override + public Character decode(String text) { + if (!StringUtils.hasLength(text)) { + return null; + } else { + return text.charAt(0); + } + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/DoubleMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/DoubleMapCodec.java new file mode 100644 index 00000000..e1a69e56 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/DoubleMapCodec.java @@ -0,0 +1,22 @@ +package com.zfoo.orm.codec.basetype; + +import com.zfoo.orm.codec.MapKeyCodec; + +/** + * @Author:lqh + * @Date:2024/6/17 11:35 + */ +public class DoubleMapCodec implements MapKeyCodec { + + @Override + public String encode(Double value) { + return (value != null) + ? value.toString() + : null; + } + + @Override + public Double decode(String text) { + return (text == null) ? null : Double.valueOf(text); + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/FloatMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/FloatMapCodec.java new file mode 100644 index 00000000..5996ba80 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/FloatMapCodec.java @@ -0,0 +1,22 @@ +package com.zfoo.orm.codec.basetype; + +import com.zfoo.orm.codec.MapKeyCodec; + +/** + * @Author:lqh + * @Date:2024/6/17 11:38 + */ +public class FloatMapCodec implements MapKeyCodec { + + @Override + public String encode(Float value) { + return (value != null) + ? value.toString() + : null; + } + + @Override + public Float decode(String text) { + return (text == null) ? null : Float.valueOf(text); + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/IntMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/IntMapCodec.java new file mode 100644 index 00000000..dcfab09d --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/IntMapCodec.java @@ -0,0 +1,25 @@ +package com.zfoo.orm.codec.basetype; + +import com.zfoo.orm.codec.MapKeyCodec; + +/** + * map解析器 + * + * @Author:lqh + * @Date:2024/6/14 10:32 + */ +public class IntMapCodec implements MapKeyCodec { + + + @Override + public String encode(Integer value) { + return (value != null) + ? value.toString() + : null; + } + + @Override + public Integer decode(String text) { + return (text == null) ? null : Integer.parseInt(text); + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/LongMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/LongMapCodec.java new file mode 100644 index 00000000..950995f7 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/LongMapCodec.java @@ -0,0 +1,25 @@ +package com.zfoo.orm.codec.basetype; + +import com.zfoo.orm.codec.MapKeyCodec; + +/** + * map解析器 + * + * @Author:lqh + * @Date:2024/6/14 10:32 + */ +public class LongMapCodec implements MapKeyCodec { + + + @Override + public String encode(Long value) { + return (value != null) + ? value.toString() + : null; + } + + @Override + public Long decode(String text) { + return (text == null) ? null : Long.parseLong(text); + } +} diff --git a/orm/src/main/java/com/zfoo/orm/codec/basetype/ShortMapCodec.java b/orm/src/main/java/com/zfoo/orm/codec/basetype/ShortMapCodec.java new file mode 100644 index 00000000..9400d0c6 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/codec/basetype/ShortMapCodec.java @@ -0,0 +1,21 @@ +package com.zfoo.orm.codec.basetype; + +import com.zfoo.orm.codec.MapKeyCodec; + +/** + * @Author:lqh + * @Date:2024/6/17 11:38 + */ +public class ShortMapCodec implements MapKeyCodec { + @Override + public String encode(Short value) { + return (value != null) + ? value.toString() + : null; + } + + @Override + public Short decode(String text) { + return (text == null) ? null : Short.parseShort(text); + } +}