Skip to content

Commit

Permalink
exposing method in PolymorphicReflectionCodec
Browse files Browse the repository at this point in the history
  • Loading branch information
webermich committed Nov 7, 2017
1 parent 85cd814 commit 0f5b66c
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Note: There are plenty of code examples to be found in the tests.
Attention: In order to scan packages you need to provide either [spring-core](https://github.com/spring-projects/spring-framework) library or [org.reflections.reflections](https://github.com/ronmamo/reflections) library in the class path.
Alternatively you could register all your POJO classes one by one!

Instantiate the POJOCodecProvider and add it to the CodecRegistry.
Instantiate the [PojoCodecProvider](src/main/java/de/bild/codec/PojoCodecProvider.java) and add it to the CodecRegistry.
Example: [PolymorphicReflectionCodecTest](src/test/java/de/bild/codec/PolymorphicReflectionCodecTest.java)

One motivation to start this project was the missing feature of existing Pojo-codec solutions to easily model polymorphic structures and write/read those to/from the database (e.g.[https://github.com/mongodb/morphia/issues/22](https://github.com/mongodb/morphia/issues/22))
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>de.bild.backend</groupId>
<artifactId>polymorphia</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>

<name>${project.groupId}:${project.artifactId}</name>

Expand Down
15 changes: 10 additions & 5 deletions src/main/java/de/bild/codec/PolymorphicReflectionCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public PolymorphicReflectionCodec(Type type, Set<Type> validTypes, TypeCodecRegi
boolean isAnyCodecCollectible = false;

for (Type validType : validTypes) {
Class<?> clazz = AbstractTypeCodec.extractClass(validType);
Class<T> clazz = AbstractTypeCodec.extractClass(validType);
if (!clazz.isInterface()) {
String discriminatorKey = getDiscriminatorKeyForClass(clazz);
boolean isFallBack = clazz.getDeclaredAnnotation(DiscriminatorFallback.class) != null;
Expand Down Expand Up @@ -162,13 +162,17 @@ protected T decodeWithType(BsonReader reader, DecoderContext decoderContext, Ref

@Override
public void encode(BsonWriter writer, T value, EncoderContext encoderContext) {
writer.writeStartDocument();
encodeFields(writer, value, encoderContext);
writer.writeEndDocument();
}

public void encodeFields(BsonWriter writer, T value, EncoderContext encoderContext) {
ReflectionCodec<T> codecForValue = getCodecForClass(value.getClass());
if (codecForValue != null) {
writer.writeStartDocument();
writer.writeName(discriminatorKeys.get(codecForValue.getEncoderClass()));
writer.writeString(mainDiscriminators.get(codecForValue.getEncoderClass()));
encodeType(writer, value, encoderContext, codecForValue);
writer.writeEndDocument();
} else {
LOGGER.warn("The value to be encoded has the wrong type {}. This codec can only handle {}", value.getClass(), discriminatorToCodec);
}
Expand All @@ -185,10 +189,11 @@ private ReflectionCodec getCodecForDiscriminator(String discriminator) {

/**
* Walks up class hierarchy until a registered codec (in the context of registered model classes) is found
*
* @return a codec responsible for a valid class within the class hierarchy
*/
private ReflectionCodec<T> getCodecForClass(Class<?> clazz) {
if (Object.class.equals(clazz)) {
public ReflectionCodec<T> getCodecForClass(Class<?> clazz) {
if (clazz == null || Object.class.equals(clazz)) {
return null;
}
ReflectionCodec<T> codec = classToCodec.get(clazz);
Expand Down
23 changes: 18 additions & 5 deletions src/test/java/de/bild/codec/CodecResolverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import de.bild.codec.annotations.DiscriminatorKey;
import de.bild.codec.annotations.Id;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.bson.BsonReader;
Expand Down Expand Up @@ -54,7 +55,7 @@ public static CodecRegistry getCodecRegistry() {
.register(CodecResolverTest.class)
.registerCodecResolver((CodecResolver) (type, typeCodecRegistry) -> {
if (TypeUtils.isAssignable(type, Base.class)) {
return new DocumentCodec(type, typeCodecRegistry);
return new DocumentCodec((Class<? extends Base>) type, typeCodecRegistry);
}
return null;
})
Expand All @@ -70,7 +71,11 @@ public static CodecRegistry getCodecRegistry() {
@Autowired
private MongoClient mongoClient;

static class MetaData {
static class MetaBase {

}

static class MetaData extends MetaBase {
@Id(collectible = true)
ObjectId id;
long version;
Expand Down Expand Up @@ -148,13 +153,21 @@ public int hashCode() {


static class DocumentCodec<T extends Base> extends BasicReflectionCodec<T> {
private final ReflectionCodec<MetaData> documentMetaCodec;
final ReflectionCodec<MetaData> documentMetaCodec;

public DocumentCodec(Type type, TypeCodecRegistry typeCodecRegistry) {
public DocumentCodec(Class<T> type, TypeCodecRegistry typeCodecRegistry) {
super(type, typeCodecRegistry);
this.documentMetaCodec = (ReflectionCodec<MetaData>) getMappedField("meta").getCodec();
MappedField mappedField = getMappedField("meta");
Codec metaCodec = mappedField.getCodec();
if (metaCodec instanceof PolymorphicReflectionCodec) {
PolymorphicReflectionCodec<MetaData> polymorphicMetaCodec = (PolymorphicReflectionCodec<MetaData>) metaCodec;
this.documentMetaCodec = polymorphicMetaCodec.getCodecForClass(mappedField.getField().getType());
} else {
this.documentMetaCodec = (ReflectionCodec<MetaData>) metaCodec;
}
}


@Override
public T decodeFields(BsonReader reader, DecoderContext decoderContext, T instance) {
MetaData documentMeta = instance.getMeta();
Expand Down

0 comments on commit 0f5b66c

Please sign in to comment.