Skip to content

Commit b155ec6

Browse files
hacking
any better
1 parent ce80187 commit b155ec6

File tree

6 files changed

+406
-215
lines changed

6 files changed

+406
-215
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,14 @@
5757
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
5858
import org.springframework.data.mongodb.core.convert.MappingMongoConverter.NestedDocument;
5959
import org.springframework.data.mongodb.core.mapping.FieldName;
60+
import org.springframework.data.mongodb.core.mapping.MongoPath.MappedMongoPath;
61+
import org.springframework.data.mongodb.core.mapping.MongoPath.MappedMongoPath.MappedSegment;
6062
import org.springframework.data.mongodb.core.mapping.MongoPath;
63+
import org.springframework.data.mongodb.core.mapping.MongoPath.PathSegment;
64+
import org.springframework.data.mongodb.core.mapping.MongoPaths;
65+
import org.springframework.data.mongodb.core.mapping.MongoPath.RawMongoPath;
66+
import org.springframework.data.mongodb.core.mapping.MongoPath.RawMongoPath.Segment;
67+
import org.springframework.data.mongodb.core.mapping.MongoPath.RawMongoPath.TargetType;
6168
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
6269
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
6370
import org.springframework.data.mongodb.core.query.Query;
@@ -104,6 +111,7 @@ private enum MetaMapping {
104111
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
105112
private final MongoExampleMapper exampleMapper;
106113
private final MongoJsonSchemaMapper schemaMapper;
114+
protected final MongoPaths paths;
107115

108116
/**
109117
* Creates a new {@link QueryMapper} with the given {@link MongoConverter}.
@@ -119,6 +127,7 @@ public QueryMapper(MongoConverter converter) {
119127
this.mappingContext = converter.getMappingContext();
120128
this.exampleMapper = new MongoExampleMapper(converter);
121129
this.schemaMapper = new MongoJsonSchemaMapper(converter);
130+
this.paths = new MongoPaths(mappingContext);
122131
}
123132

124133
public Document getMappedObject(Bson query, Optional<? extends MongoPersistentEntity<?>> entity) {
@@ -381,10 +390,10 @@ protected Field createPropertyField(@Nullable MongoPersistentEntity<?> entity, S
381390
}
382391

383392
if (FieldName.ID.name().equals(key)) {
384-
return new MetadataBackedField(key, entity, mappingContext, entity.getIdProperty());
393+
return new MetadataBackedField(paths.create(key), entity, mappingContext, entity.getIdProperty());
385394
}
386395

387-
return new MetadataBackedField(key, entity, mappingContext);
396+
return new MetadataBackedField(paths.create(key), entity, mappingContext);
388397
}
389398

390399
/**
@@ -1123,67 +1132,120 @@ public Class<?> getFieldType() {
11231132
}
11241133
}
11251134

1135+
/**
1136+
* Create a {@link PropertyPath} starting at {@link MongoPersistentEntity}.
1137+
* <p>
1138+
* Can return {@code null} if the property path contains named segments that are not mapped to the entity.
1139+
*
1140+
* @param persistentEntity
1141+
* @return
1142+
*/
1143+
@Nullable
1144+
public PropertyPath toPropertyPath(
1145+
MongoPath mongoPath, MongoPersistentEntity<?> persistentEntity) {
1146+
1147+
StringBuilder path = new StringBuilder();
1148+
MongoPersistentEntity<?> entity = persistentEntity;
1149+
1150+
for (PathSegment segment : mongoPath.segments()) {
1151+
1152+
if (segment.isKeyword()) {
1153+
continue;
1154+
}
1155+
1156+
if (entity == null) {
1157+
return null;
1158+
}
1159+
1160+
MongoPersistentProperty persistentProperty = entity.getPersistentProperty(segment.segment());
1161+
1162+
if (persistentProperty == null) {
1163+
1164+
if (segment.isNumeric()) {
1165+
continue;
1166+
1167+
}
1168+
1169+
return null;
1170+
}
1171+
1172+
entity = mappingContext.getPersistentEntity(persistentProperty);
1173+
1174+
String name = segment.segment();
1175+
1176+
if (!path.isEmpty()) {
1177+
path.append(".");
1178+
}
1179+
path.append(Pattern.quote(name));
1180+
}
1181+
1182+
if (path.isEmpty()) {
1183+
return null;
1184+
}
1185+
1186+
return PropertyPath.from(path.toString(), persistentEntity.getType());
1187+
}
1188+
1189+
11261190
/**
11271191
* Extension of {@link Field} to be backed with mapping metadata.
11281192
*
11291193
* @author Oliver Gierke
11301194
* @author Thomas Darimont
11311195
*/
1132-
protected static class MetadataBackedField extends Field {
1196+
protected class MetadataBackedField extends Field {
11331197

1134-
private static final Pattern POSITIONAL_PARAMETER_PATTERN = Pattern.compile("\\.\\$(\\[.*?\\])?");
1135-
private static final Pattern NUMERIC_SEGMENT = Pattern.compile("\\d+");
11361198
private static final String INVALID_ASSOCIATION_REFERENCE = "Invalid path reference %s; Associations can only be pointed to directly or via their id property";
11371199

11381200
private final MongoPersistentEntity<?> entity;
11391201
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
11401202
private final MongoPersistentProperty property;
1141-
private final @Nullable PersistentPropertyPath<MongoPersistentProperty> path;
1203+
private final @Nullable PersistentPropertyPath<MongoPersistentProperty> propertyPath;
11421204
private final @Nullable Association<MongoPersistentProperty> association;
11431205
private final MongoPath mongoPath;
11441206

11451207
/**
11461208
* Creates a new {@link MetadataBackedField} with the given name, {@link MongoPersistentEntity} and
11471209
* {@link MappingContext}.
11481210
*
1149-
* @param name must not be {@literal null} or empty.
1211+
* @param path must not be {@literal null} or empty.
11501212
* @param entity must not be {@literal null}.
11511213
* @param context must not be {@literal null}.
11521214
*/
1153-
public MetadataBackedField(String name, MongoPersistentEntity<?> entity,
1215+
public MetadataBackedField(MongoPath path, MongoPersistentEntity<?> entity,
11541216
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
1155-
this(name, entity, context, null);
1217+
this(path, entity, context, null);
11561218
}
11571219

11581220
/**
11591221
* Creates a new {@link MetadataBackedField} with the given name, {@link MongoPersistentEntity} and
11601222
* {@link MappingContext} with the given {@link MongoPersistentProperty}.
11611223
*
1162-
* @param name must not be {@literal null} or empty.
1224+
* @param path must not be {@literal null} or empty.
11631225
* @param entity must not be {@literal null}.
11641226
* @param context must not be {@literal null}.
11651227
* @param property may be {@literal null}.
11661228
*/
1167-
public MetadataBackedField(String name, MongoPersistentEntity<?> entity,
1229+
public MetadataBackedField(MongoPath path, MongoPersistentEntity<?> entity,
11681230
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context,
11691231
@Nullable MongoPersistentProperty property) {
11701232

1171-
super(name);
1233+
super(path.path());
11721234

11731235
Assert.notNull(entity, "MongoPersistentEntity must not be null");
11741236

11751237
this.entity = entity;
11761238
this.mappingContext = context;
11771239

1178-
this.mongoPath = MongoPath.parse(name);
1179-
this.path = getPath(mongoPath, property);
1180-
this.property = path == null ? property : path.getLeafProperty();
1240+
this.mongoPath = path;
1241+
this.propertyPath = getPath(mongoPath, property);
1242+
this.property = this.propertyPath == null ? property : this.propertyPath.getLeafProperty();
11811243
this.association = findAssociation();
11821244
}
11831245

11841246
@Override
11851247
public MetadataBackedField with(String name) {
1186-
return new MetadataBackedField(name, entity, mappingContext, property);
1248+
return new MetadataBackedField(mongoPath, entity, mappingContext, property);
11871249
}
11881250

11891251
@Override
@@ -1237,8 +1299,8 @@ public Association<MongoPersistentProperty> getAssociation() {
12371299
@Nullable
12381300
private Association<MongoPersistentProperty> findAssociation() {
12391301

1240-
if (this.path != null) {
1241-
for (MongoPersistentProperty p : this.path) {
1302+
if (this.propertyPath != null) {
1303+
for (MongoPersistentProperty p : this.propertyPath) {
12421304

12431305
Association<MongoPersistentProperty> association = p.getAssociation();
12441306

@@ -1261,19 +1323,20 @@ public String getMappedKey() {
12611323

12621324
// TODO: Switch to MongoPath?!
12631325
if (isAssociation()) {
1264-
return path == null ? name : path.toDotPath(getAssociationConverter());
1326+
return propertyPath == null ? name : propertyPath.toDotPath(getAssociationConverter());
12651327
}
12661328

12671329
if (entity != null) {
1268-
return mongoPath.applyFieldNames(mappingContext, entity).toString();
1330+
return paths.mappedPath(mongoPath, entity.getTypeInformation()).toString();
12691331
}
12701332

12711333
return name;
12721334
}
12731335

1336+
12741337
@Nullable
12751338
protected PersistentPropertyPath<MongoPersistentProperty> getPath() {
1276-
return path;
1339+
return propertyPath;
12771340
}
12781341

12791342
/**
@@ -1290,7 +1353,7 @@ private PersistentPropertyPath<MongoPersistentProperty> getPath(MongoPath mongoP
12901353
PropertyPath.from(Pattern.quote(sourceProperty.getName()), entity.getTypeInformation()));
12911354
}
12921355

1293-
PropertyPath path = mongoPath.toPropertyPath(mappingContext, entity);
1356+
PropertyPath path = toPropertyPath(mongoPath, entity);
12941357

12951358
if (path == null || isPathToJavaLangClassProperty(path)) {
12961359
return null;

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.data.domain.Sort;
2828
import org.springframework.data.domain.Sort.Order;
2929
import org.springframework.data.mapping.context.MappingContext;
30+
import org.springframework.data.mongodb.core.mapping.MongoPath;
3031
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
3132
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
3233
import org.springframework.data.mongodb.core.query.Query;
@@ -250,7 +251,7 @@ protected Field createPropertyField(MongoPersistentEntity<?> entity, String key,
250251
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
251252

252253
return entity == null ? super.createPropertyField(entity, key, mappingContext)
253-
: new MetadataBackedUpdateField(entity, key, mappingContext);
254+
: new MetadataBackedUpdateField(entity, paths.create(key), mappingContext);
254255
}
255256

256257
private static Document getSortObject(Sort sort) {
@@ -274,7 +275,7 @@ private static Document getSortObject(Sort sort) {
274275
* @author Oliver Gierke
275276
* @author Christoph Strobl
276277
*/
277-
private static class MetadataBackedUpdateField extends MetadataBackedField {
278+
private class MetadataBackedUpdateField extends MetadataBackedField {
278279

279280
private final String key;
280281

@@ -287,11 +288,11 @@ private static class MetadataBackedUpdateField extends MetadataBackedField {
287288
* @param key must not be {@literal null} or empty.
288289
* @param mappingContext must not be {@literal null}.
289290
*/
290-
public MetadataBackedUpdateField(MongoPersistentEntity<?> entity, String key,
291+
public MetadataBackedUpdateField(MongoPersistentEntity<?> entity, MongoPath key,
291292
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
292293

293294
super(key, entity, mappingContext);
294-
this.key = key;
295+
this.key = key.path();
295296
}
296297

297298
@Override

0 commit comments

Comments
 (0)