Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fixed bug for polymorphic classes with primitives inside
- Loading branch information
1 parent
e22caaf
commit 96ab151
Showing
7 changed files
with
220 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
mongo/test/org/immutables/mongo/fixture/holder/Holder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.immutables.mongo.fixture.holder; | ||
|
||
import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | ||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
import org.immutables.gson.Gson; | ||
import org.immutables.mongo.Mongo; | ||
import org.immutables.value.Value; | ||
|
||
/** | ||
* Data object which can store heterogeneous types | ||
*/ | ||
@Gson.TypeAdapters | ||
@Mongo.Repository("holder") | ||
@Value.Immutable | ||
@JsonSerialize(as = ImmutableHolder.class) | ||
@JsonDeserialize(as = ImmutableHolder.class) | ||
public interface Holder { | ||
|
||
String TYPE_PROPERTY = "@class"; | ||
|
||
|
||
@Mongo.Id | ||
String id(); | ||
|
||
/** | ||
* Class name is encoded as JSON attribute ({@code @class} | ||
*/ | ||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = TYPE_PROPERTY) | ||
Object value(); | ||
} |
69 changes: 69 additions & 0 deletions
69
mongo/test/org/immutables/mongo/fixture/holder/HolderJsonSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package org.immutables.mongo.fixture.holder; | ||
|
||
import com.google.gson.*; | ||
|
||
import java.lang.reflect.Type; | ||
|
||
/** | ||
* Custom serializer which allows to (JSON) store different types of objects inside same class : {@link Holder} | ||
*/ | ||
public class HolderJsonSerializer implements JsonSerializer<Holder>, JsonDeserializer<Holder> { | ||
|
||
private static final String VALUE_PROPERTY = "value"; | ||
|
||
@Override | ||
public Holder deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { | ||
JsonObject root = (JsonObject) json; | ||
|
||
ImmutableHolder.Builder builder = ImmutableHolder.builder(); | ||
|
||
if (root.has("id")) { | ||
builder.id(root.get("id").getAsString()); | ||
} | ||
|
||
JsonElement value = root.get(VALUE_PROPERTY); | ||
if (value == null) { | ||
throw new JsonParseException(String.format("%s not found for %s in JSON", VALUE_PROPERTY, type)); | ||
} | ||
|
||
if (value.isJsonObject()) { | ||
final String valueTypeName = value.getAsJsonObject().get(Holder.TYPE_PROPERTY).getAsString(); | ||
try { | ||
Class<?> valueType = Class.forName(valueTypeName); | ||
builder.value(context.deserialize(value, valueType)); | ||
} catch (ClassNotFoundException e) { | ||
throw new JsonParseException(String.format("Couldn't construct value class %s for %s", valueTypeName, type) ,e); | ||
} | ||
} else if (value.isJsonPrimitive()) { | ||
final JsonPrimitive primitive = value.getAsJsonPrimitive(); | ||
if (primitive.isString()) { | ||
builder.value(primitive.getAsString()); | ||
} else if (primitive.isNumber()) { | ||
builder.value(primitive.getAsInt()); | ||
} else if (primitive.isBoolean()) { | ||
builder.value(primitive.getAsBoolean()); | ||
} | ||
} else { | ||
throw new JsonParseException(String.format("Couldn't deserialize %s : %s. Not a primitive or object", VALUE_PROPERTY, value)); | ||
} | ||
|
||
return builder.build(); | ||
|
||
} | ||
|
||
@Override | ||
public JsonElement serialize(Holder src, Type type, JsonSerializationContext context) { | ||
JsonObject root = new JsonObject(); | ||
JsonElement value = context.serialize(src.value()); | ||
|
||
root.addProperty("id", src.id()); | ||
|
||
if (value.isJsonObject()) { | ||
value.getAsJsonObject().addProperty(Holder.TYPE_PROPERTY, src.value().getClass().getName()); | ||
} | ||
|
||
root.add(VALUE_PROPERTY, value); | ||
return root; | ||
} | ||
|
||
} |
65 changes: 65 additions & 0 deletions
65
mongo/test/org/immutables/mongo/fixture/holder/HolderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package org.immutables.mongo.fixture.holder; | ||
|
||
import org.immutables.mongo.fixture.MongoContext; | ||
import org.junit.Before; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.immutables.check.Checkers.check; | ||
|
||
public class HolderTest { | ||
|
||
@Rule | ||
public final MongoContext context = new MongoContext(); | ||
|
||
private HolderRepository repository; | ||
|
||
@Before | ||
public void setUp() throws Exception { | ||
repository = new HolderRepository(context.setup()); | ||
} | ||
|
||
/** | ||
* Tests GSON parsing error when using primitives in polymorphic repository class {@link Holder} | ||
* {@code Expected VALUE_STRING but was VALUE_NUMBER_FLOAT}. GSON lazily loads numbers (without parsing the string | ||
* right away) so nextString() token might be number or float instead of string. | ||
*/ | ||
@Test | ||
public void primitives() throws Exception { | ||
Primitives prim = ImmutablePrimitives.builder() | ||
.booleanValue(true) | ||
.byteValue((byte) 4) | ||
.shortValue((short) 16) | ||
.intValue(1024) | ||
.longValue(8096) | ||
.floatValue(1.1f) | ||
.doubleValue(3.3d) | ||
.build(); | ||
|
||
Holder holder = ImmutableHolder.builder().id("h1").value(prim).build(); | ||
|
||
check(repository.upsert(holder).getUnchecked()).is(1); | ||
|
||
final List<Holder> holders = repository.findAll().fetchAll().getUnchecked(); | ||
|
||
check(holders).hasSize(1); | ||
check(holders.get(0).id()).is("h1"); | ||
check(holders.get(0)).is(holder); | ||
} | ||
|
||
@Test | ||
public void string() throws Exception { | ||
Holder holder = ImmutableHolder.builder().id("h1").value("foo").build(); | ||
check(repository.upsert(holder).getUnchecked()).is(1); | ||
check(repository.findAll().fetchAll().getUnchecked()).has(holder); | ||
} | ||
|
||
@Test | ||
public void justInt() throws Exception { | ||
Holder holder = ImmutableHolder.builder().id("h1").value(123).build(); | ||
check(repository.upsert(holder).getUnchecked()).is(1); | ||
check(repository.findAll().fetchAll().getUnchecked()).has(holder); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
mongo/test/org/immutables/mongo/fixture/holder/Primitives.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.immutables.mongo.fixture.holder; | ||
|
||
|
||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | ||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
import org.immutables.gson.Gson; | ||
import org.immutables.value.Value; | ||
|
||
/** | ||
* To test the bug with embedded primitives | ||
*/ | ||
@Value.Immutable | ||
@JsonSerialize(as = ImmutablePrimitives.class) | ||
@JsonDeserialize(as = ImmutablePrimitives.class) | ||
@Gson.TypeAdapters | ||
public interface Primitives { | ||
|
||
boolean booleanValue(); | ||
|
||
byte byteValue(); | ||
|
||
short shortValue(); | ||
|
||
int intValue(); | ||
|
||
long longValue(); | ||
|
||
float floatValue(); | ||
|
||
double doubleValue(); | ||
} |