io.vertx.ext.mongo.impl.codec.json.AbstractJsonCodec Maven / Gradle / Ivy
package io.vertx.ext.mongo.impl.codec.json;
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.HashSet;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* @author Nick Scavelli
*/
@SuppressWarnings("unused")
public abstract class AbstractJsonCodec implements Codec {
@Override
public O decode(BsonReader reader, DecoderContext decoderContext) {
return readDocument(reader, decoderContext);
}
@Override
public void encode(BsonWriter writer, O value, EncoderContext encoderContext) {
writeDocument(writer, null, value, encoderContext);
}
protected Object readValue(BsonReader reader, DecoderContext ctx) {
BsonType type = reader.getCurrentBsonType();
switch (type) {
case NULL:
return readNull(reader, ctx);
case ARRAY:
return readArray(reader, ctx);
case BINARY:
return readBinary(reader, ctx);
case BOOLEAN:
return readBoolean(reader, ctx);
case DATE_TIME:
return readDateTime(reader, ctx);
case DB_POINTER:
return readDbPointer(reader, ctx);
case DOCUMENT:
return readDocument(reader, ctx);
case DOUBLE:
return readDouble(reader, ctx);
case INT32:
return readInt32(reader, ctx);
case INT64:
return readInt64(reader, ctx);
case MAX_KEY:
return readMaxKey(reader, ctx);
case MIN_KEY:
return readMinKey(reader, ctx);
case JAVASCRIPT:
return readJavaScript(reader, ctx);
case JAVASCRIPT_WITH_SCOPE:
return readJavaScriptWithScope(reader, ctx);
case OBJECT_ID:
return readObjectId(reader, ctx);
case REGULAR_EXPRESSION:
return readRegularExpression(reader, ctx);
case STRING:
return readString(reader, ctx);
case SYMBOL:
return readSymbol(reader, ctx);
case TIMESTAMP:
return readTimeStamp(reader, ctx);
case UNDEFINED:
return readUndefined(reader, ctx);
default:
throw new IllegalStateException("Unknown bson type " + type);
}
}
@SuppressWarnings("unchecked")
protected void writeValue(BsonWriter writer, String name, Object value, EncoderContext ctx) {
BsonType type = getBsonType(value);
if (type == null) {
throw new IllegalStateException("Unknown BsonType for '" + value + "'");
}
switch (type) {
case NULL:
writeNull(writer, name, value, ctx);
break;
case ARRAY:
writeArray(writer, name, value, ctx);
break;
case BINARY:
writeBinary(writer, name, value, ctx);
break;
case BOOLEAN:
writeBoolean(writer, name, value, ctx);
break;
case DATE_TIME:
writeDateTime(writer, name, value, ctx);
break;
case DB_POINTER:
writeDbPointer(writer, name, value, ctx);
break;
case DOCUMENT:
writeDocument(writer, name, value, ctx);
break;
case DOUBLE:
writeDouble(writer, name, value, ctx);
break;
case INT32:
writeInt32(writer, name, value, ctx);
break;
case INT64:
writeInt64(writer, name, value, ctx);
break;
case MAX_KEY:
writeMaxKey(writer, name, value, ctx);
break;
case MIN_KEY:
writeMinKey(writer, name, value, ctx);
break;
case JAVASCRIPT:
writeJavaScript(writer, name, value, ctx);
break;
case JAVASCRIPT_WITH_SCOPE:
writeJavaScriptWithScope(writer, name, value, ctx);
break;
case OBJECT_ID:
writeObjectId(writer, name, value, ctx);
break;
case REGULAR_EXPRESSION:
writeRegularExpression(writer, name, value, ctx);
break;
case STRING:
writeString(writer, name, value, ctx);
break;
case SYMBOL:
writeSymbol(writer, name, value, ctx);
break;
case TIMESTAMP:
writeTimeStamp(writer, name, value, ctx);
break;
case UNDEFINED:
writeUndefined(writer, name, value, ctx);
break;
default:
throw new IllegalStateException("Unknown bson type " + type);
}
}
protected BsonType getBsonType(Object value) {
if (value == null) {
return BsonType.NULL;
} else if (value instanceof Boolean) {
return BsonType.BOOLEAN;
} else if (value instanceof Double) {
return BsonType.DOUBLE;
} else if (value instanceof Integer) {
return BsonType.INT32;
} else if (value instanceof Long) {
return BsonType.INT64;
} else if (value instanceof String) {
return BsonType.STRING;
} else if (isObjectIdInstance(value)) {
return BsonType.OBJECT_ID;
} else if (isObjectInstance(value)) {
return BsonType.DOCUMENT;
} else if (isArrayInstance(value)) {
return BsonType.ARRAY;
} else {
return null;
}
}
//------------------- Basic types
protected Object readNull(BsonReader reader, DecoderContext ctx) {
reader.readNull();
return null;
}
protected void writeNull(BsonWriter writer, String name, Object value, EncoderContext ctx) {
writer.writeNull();
}
protected Object readBoolean(BsonReader reader, DecoderContext ctx) {
return reader.readBoolean();
}
protected void writeBoolean(BsonWriter writer, String name, Object value, EncoderContext ctx) {
writer.writeBoolean((Boolean) value);
}
protected Object readDouble(BsonReader reader, DecoderContext ctx) {
return reader.readDouble();
}
protected void writeDouble(BsonWriter writer, String name, Object value, EncoderContext ctx) {
writer.writeDouble((double) value);
}
protected Object readInt32(BsonReader reader, DecoderContext ctx) {
return reader.readInt32();
}
protected void writeInt32(BsonWriter writer, String name, Object value, EncoderContext ctx) {
writer.writeInt32((int) value);
}
protected Object readInt64(BsonReader reader, DecoderContext ctx) {
return reader.readInt64();
}
protected void writeInt64(BsonWriter writer, String name, Object value, EncoderContext ctx) {
writer.writeInt64((long) value);
}
protected Object readString(BsonReader reader, DecoderContext ctx) {
return reader.readString();
}
protected void writeString(BsonWriter writer, String name, Object value, EncoderContext ctx) {
writer.writeString((String) value);
}
protected abstract boolean isObjectIdInstance(Object instance);
//-------------- JSON Object
protected O readDocument(BsonReader reader, DecoderContext ctx) {
O object = newObject();
reader.readStartDocument();
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
String name = reader.readName();
add(object, name, readValue(reader, ctx));
}
reader.readEndDocument();
return object;
}
protected void writeDocument(BsonWriter writer, String name, Object value, EncoderContext ctx) {
@SuppressWarnings("unchecked")
O object = (O) value;
writer.writeStartDocument();
Set skip = new HashSet<>();
if (ctx.isEncodingCollectibleDocument()) {
beforeFields(object, (k, v) -> {
skip.add(k);
writer.writeName(k);
writeValue(writer, k, v, ctx);
});
}
forEach(object, (k, v) -> {
if (!skip.contains(k)) {
writer.writeName(k);
writeValue(writer, k, v, ctx);
}
});
writer.writeEndDocument();
}
protected abstract O newObject();
protected abstract void add(O object, String name, Object value);
protected abstract boolean isObjectInstance(Object instance);
protected void beforeFields(O object, BiConsumer objectConsumer) {
}
protected abstract void forEach(O object, BiConsumer objectConsumer);
//-------------- JSON Array
protected A readArray(BsonReader reader, DecoderContext ctx) {
A array = newArray();
reader.readStartArray();
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
add(array, readValue(reader, ctx));
}
reader.readEndArray();
return array;
}
protected void writeArray(BsonWriter writer, String name, Object value, EncoderContext ctx) {
@SuppressWarnings("unchecked")
A array = (A) value;
writer.writeStartArray();
forEach(array, o -> writeValue(writer, null, o, ctx));
writer.writeEndArray();
}
protected abstract A newArray();
protected abstract void add(A array, Object value);
protected abstract boolean isArrayInstance(Object instance);
protected abstract void forEach(A array, Consumer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy