Skip to content

Commit 21dbd43

Browse files
committed
POJOCodec Ensure properties can be overridden by explicit types
JAVA-3040
1 parent 777faa1 commit 21dbd43

File tree

5 files changed

+60
-2
lines changed

5 files changed

+60
-2
lines changed

bson/src/main/org/bson/codecs/pojo/PojoBuilderHelper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ private static <T, S> PropertyMetadata<T> getOrCreateMethodPropertyMetadata(fina
157157
final List<String> genericTypeNames,
158158
final Type genericType) {
159159
PropertyMetadata<T> propertyMetadata = getOrCreatePropertyMetadata(propertyName, declaringClassName, propertyNameMap, typeData);
160-
if (!propertyMetadata.getTypeData().getType().isAssignableFrom(typeData.getType())) {
160+
if (!isAssignableClass(propertyMetadata.getTypeData().getType(), typeData.getType())) {
161161
throw new CodecConfigurationException(format("Property '%s' in %s, has differing data types: %s and %s", propertyName,
162162
declaringClassName, propertyMetadata.getTypeData(), typeData));
163163
}
@@ -166,6 +166,10 @@ private static <T, S> PropertyMetadata<T> getOrCreateMethodPropertyMetadata(fina
166166
return propertyMetadata;
167167
}
168168

169+
private static boolean isAssignableClass(final Class<?> propertyTypeClass, final Class<?> typeDataClass) {
170+
return propertyTypeClass.isAssignableFrom(typeDataClass) || typeDataClass.isAssignableFrom(propertyTypeClass);
171+
}
172+
169173
private static <T, S> PropertyMetadata<T> getOrCreateFieldPropertyMetadata(final String propertyName,
170174
final String declaringClassName,
171175
final Map<String, PropertyMetadata<?>> propertyNameMap,

bson/src/test/unit/org/bson/codecs/pojo/ClassModelTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
import org.bson.codecs.pojo.entities.GenericHolderModel;
2121
import org.bson.codecs.pojo.entities.NestedGenericHolderMapModel;
2222
import org.bson.codecs.pojo.entities.PropertySelectionModel;
23+
import org.bson.codecs.pojo.entities.ShapeHolderCircleModel;
24+
import org.bson.codecs.pojo.entities.ShapeHolderModel;
25+
import org.bson.codecs.pojo.entities.ShapeModelAbstract;
26+
import org.bson.codecs.pojo.entities.ShapeModelCircle;
2327
import org.bson.codecs.pojo.entities.SimpleGenericsModel;
2428
import org.bson.codecs.pojo.entities.SimpleModel;
2529
import org.bson.codecs.pojo.entities.conventions.AnnotationInheritedModel;
@@ -159,4 +163,15 @@ public void testInheritedClassAnnotations() {
159163
assertTrue(propertyModel.useDiscriminator());
160164
}
161165

166+
@Test
167+
public void testOverridePropertyWithSubclass() {
168+
ClassModel<?> classModel = ClassModel.builder(ShapeHolderModel.class).build();
169+
assertEquals(1, classModel.getPropertyModels().size());
170+
assertEquals(ShapeModelAbstract.class, classModel.getPropertyModels().get(0).getTypeData().getType());
171+
172+
ClassModel<?> overriddenImplementationClassModel = ClassModel.builder(ShapeHolderCircleModel.class).build();
173+
assertEquals(1, classModel.getPropertyModels().size());
174+
assertEquals(ShapeModelCircle.class, overriddenImplementationClassModel.getPropertyModels().get(0).getTypeData().getType());
175+
}
176+
162177
}

bson/src/test/unit/org/bson/codecs/pojo/PojoRoundTripTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.bson.codecs.pojo.entities.PropertyWithMultipleTypeParamsModel;
5252
import org.bson.codecs.pojo.entities.ReusedGenericsModel;
5353
import org.bson.codecs.pojo.entities.SelfReferentialGenericModel;
54+
import org.bson.codecs.pojo.entities.ShapeHolderCircleModel;
5455
import org.bson.codecs.pojo.entities.ShapeHolderModel;
5556
import org.bson.codecs.pojo.entities.ShapeModelAbstract;
5657
import org.bson.codecs.pojo.entities.ShapeModelCircle;
@@ -379,6 +380,11 @@ private static List<TestData> testCases() {
379380
data.add(new TestData("AnnotationBsonPropertyIdModel", new AnnotationBsonPropertyIdModel(99L),
380381
getPojoCodecProviderBuilder(AnnotationBsonPropertyIdModel.class),
381382
"{'id': {'$numberLong': '99' }}"));
383+
384+
data.add(new TestData("Shape model - circle",
385+
new ShapeHolderCircleModel(getShapeModelCircle()),
386+
getPojoCodecProviderBuilder(ShapeModelCircle.class, ShapeHolderCircleModel.class),
387+
"{'shape': {'_t': 'org.bson.codecs.pojo.entities.ShapeModelCircle', 'color': 'orange', 'radius': 4.2}}"));
382388
return data;
383389
}
384390

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.bson.codecs.pojo.entities;
18+
19+
public class ShapeHolderCircleModel extends ShapeHolderModel {
20+
21+
public ShapeHolderCircleModel() {
22+
}
23+
24+
public ShapeHolderCircleModel(final ShapeModelCircle shape) {
25+
super(shape);
26+
}
27+
28+
@Override
29+
public ShapeModelCircle getShape() {
30+
return (ShapeModelCircle) super.getShape();
31+
}
32+
}
33+

bson/src/test/unit/org/bson/codecs/pojo/entities/ShapeHolderModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package org.bson.codecs.pojo.entities;
1818

19-
public final class ShapeHolderModel {
19+
public class ShapeHolderModel {
2020

2121
private ShapeModelAbstract shape;
2222

0 commit comments

Comments
 (0)