Refine search
@Override public Object populateId(MongoPersistentProperty property, @Nullable DBRef source, Object proxy) { if (source == null) { return proxy; } MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(property); MongoPersistentProperty idProperty = entity.getRequiredIdProperty(); if (idProperty.usePropertyAccess()) { return proxy; } SpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(proxy, spELContext); PersistentPropertyAccessor accessor = entity.getPropertyAccessor(proxy); Document object = new Document(idProperty.getFieldName(), source.getId()); ObjectPath objectPath = ObjectPath.ROOT.push(proxy, entity, null); accessor.setProperty(idProperty, resolver.getValueInternal(idProperty, object, evaluator, objectPath)); return proxy; } }
private String getMappedPropertyPath(String path, Class<?> probeType) { MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(probeType); Iterator<String> parts = Arrays.asList(path.split("\\.")).iterator(); final Stack<MongoPersistentProperty> stack = new Stack<>(); List<String> resultParts = new ArrayList<>(); while (parts.hasNext()) { String part = parts.next(); MongoPersistentProperty prop = entity.getPersistentProperty(part); if (prop == null) { entity.doWithProperties((PropertyHandler<MongoPersistentProperty>) property -> { if (property.getFieldName().equals(part)) { stack.push(property); } }); if (stack.isEmpty()) { return ""; } prop = stack.pop(); } resultParts.add(prop.getName()); if (prop.isEntity() && mappingContext.hasPersistentEntityFor(prop.getActualType())) { entity = mappingContext.getRequiredPersistentEntity(prop.getActualType()); } else { break; } } return StringUtils.collectionToDelimitedString(resultParts, "."); }
/** * Writes the given {@link Map} using the given {@link MongoPersistentProperty} information. * * @param map must not {@literal null}. * @param property must not be {@literal null}. * @return */ protected Bson createMap(Map<Object, Object> map, MongoPersistentProperty property) { Assert.notNull(map, "Given map must not be null!"); Assert.notNull(property, "PersistentProperty must not be null!"); if (!property.isDbReference()) { return writeMapInternal(map, new Document(), property.getTypeInformation()); } Document document = new Document(); for (Map.Entry<Object, Object> entry : map.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); if (conversions.isSimpleType(key.getClass())) { String simpleKey = prepareMapKey(key.toString()); document.put(simpleKey, value != null ? createDBRef(value, property) : null); } else { throw new MappingException("Cannot use a complex object as a key value."); } } return document; }
@Override public boolean isIdField() { MongoPersistentProperty idProperty = (property != null && property.isIdProperty()) ? property : entity.getIdProperty(); if (idProperty != null) { return name.equals(idProperty.getName()) || name.equals(idProperty.getFieldName()) || name.endsWith("." + idProperty.getName()) || name.endsWith("." + idProperty.getFieldName()); } return DEFAULT_ID_NAMES.contains(name); }
private static void potentiallyAssertDBRefTargetType(MongoPersistentProperty persistentProperty) { if (persistentProperty.isDbReference() && persistentProperty.getDBRef().lazy()) { if (persistentProperty.isArray() || Modifier.isFinal(persistentProperty.getActualType().getModifiers())) { throw new MappingException(String.format( "Invalid lazy DBRef property for %s. Found %s which must not be an array nor a final class.", persistentProperty.getField(), persistentProperty.getActualType())); } } }
private static void assertPropertyType(MongoPersistentProperty persistentProperty, Class<?>... validMatches) { for (Class<?> potentialMatch : validMatches) { if (ClassUtils.isAssignable(potentialMatch, persistentProperty.getActualType())) { return; } } throw new MappingException( String.format("Missmatching types for %s. Found %s expected one of %s.", persistentProperty.getField(), persistentProperty.getActualType(), StringUtils.arrayToCommaDelimitedString(validMatches))); } }
private Document mapProperty(@Nullable PersistentEntity<?, MongoPersistentProperty> entity, String sourceFieldName, Document source) { Document sink = new Document(source); if (entity != null && sink.containsKey(Type.objectType().representation())) { MongoPersistentProperty property = entity.getPersistentProperty(sourceFieldName); if (property != null && property.isEntity()) { sink = mapSchemaObject(mappingContext.getPersistentEntity(property.getActualType()), source); } } return mapEnumValuesIfNecessary(sink); }
@SuppressWarnings({ "unchecked" }) protected void writePropertyInternal(@Nullable Object obj, DocumentAccessor accessor, MongoPersistentProperty prop) { TypeInformation<?> type = prop.getTypeInformation(); if (prop.isDbReference()) { MongoPersistentEntity<?> entity = valueType.isSubTypeOf(prop.getType()) ? mappingContext.getRequiredPersistentEntity(obj.getClass()) : mappingContext.getRequiredPersistentEntity(type); Document document = existingValue instanceof Document ? (Document) existingValue : new Document(); addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, document); accessor.put(prop, document);
private String pathAwareIndexName(String indexName, String dotPath, @Nullable MongoPersistentProperty property) { String nameToUse = StringUtils.hasText(indexName) ? indexName : ""; if (!StringUtils.hasText(dotPath) || (property != null && dotPath.equals(property.getFieldName()))) { return StringUtils.hasText(nameToUse) ? nameToUse : dotPath; } if (StringUtils.hasText(dotPath)) { nameToUse = StringUtils.hasText(nameToUse) ? (property != null ? dotPath.replace("." + property.getFieldName(), "") : dotPath) + "." + nameToUse : dotPath; } return nameToUse; }
private void increaseVersionForUpdateIfNecessary(@Nullable MongoPersistentEntity<?> persistentEntity, UpdateDefinition update) { if (persistentEntity != null && persistentEntity.hasVersionProperty()) { String versionFieldName = persistentEntity.getRequiredVersionProperty().getFieldName(); if (!update.modifies(versionFieldName)) { update.inc(versionFieldName); } } }
/** * Creates {@link IndexDefinition} wrapped in {@link IndexDefinitionHolder} out of {@link GeoSpatialIndexed} for * {@link MongoPersistentProperty}. * * @param dotPath The properties {@literal "dot"} path representation from its document root. * @param collection * @param persistentProperty * @return */ @Nullable protected IndexDefinitionHolder createGeoSpatialIndexDefinition(String dotPath, String collection, MongoPersistentProperty persistentProperty) { GeoSpatialIndexed index = persistentProperty.findAnnotation(GeoSpatialIndexed.class); if (index == null) { return null; } GeospatialIndex indexDefinition = new GeospatialIndex(dotPath); indexDefinition.withBits(index.bits()); indexDefinition.withMin(index.min()).withMax(index.max()); if (!index.useGeneratedName()) { indexDefinition.named(pathAwareIndexName(index.name(), dotPath, persistentProperty)); } indexDefinition.typed(index.type()).withBucketSize(index.bucketSize()).withAdditionalField(index.additionalField()); return new IndexDefinitionHolder(dotPath, indexDefinition, collection); }
private void mapMetaAttributes(Document source, @Nullable MongoPersistentEntity<?> entity, MetaMapping metaMapping) { if (entity == null) { return; } if (entity.hasTextScoreProperty() && !MetaMapping.IGNORE.equals(metaMapping)) { MongoPersistentProperty textScoreProperty = entity.getTextScoreProperty(); if (MetaMapping.FORCE.equals(metaMapping) || (MetaMapping.WHEN_PRESENT.equals(metaMapping) && source.containsKey(textScoreProperty.getFieldName()))) { source.putAll(getMappedTextScoreField(textScoreProperty)); } } }
private boolean containsVersionProperty(Document document, @Nullable MongoPersistentEntity<?> persistentEntity) { if (persistentEntity == null || !persistentEntity.hasVersionProperty()) { return false; } return document.containsKey(persistentEntity.getRequiredIdProperty().getFieldName()); }
/** * Returns the given {@link Example} as {@link Document} holding matching values extracted from * {@link Example#getProbe()}. * * @param example must not be {@literal null}. * @param entity must not be {@literal null}. * @return */ public Document getMappedExample(Example<?> example, MongoPersistentEntity<?> entity) { Assert.notNull(example, "Example must not be null!"); Assert.notNull(entity, "MongoPersistentEntity must not be null!"); Document reference = (Document) converter.convertToMongoType(example.getProbe()); if (entity.getIdProperty() != null && ClassUtils.isAssignable(entity.getType(), example.getProbeType())) { Object identifier = entity.getIdentifierAccessor(example.getProbe()).getIdentifier(); if (identifier == null) { reference.remove(entity.getIdProperty().getFieldName()); } } ExampleMatcherAccessor matcherAccessor = new ExampleMatcherAccessor(example.getMatcher()); applyPropertySpecs("", reference, example.getProbeType(), matcherAccessor); Document flattened = ObjectUtils.nullSafeEquals(NullHandler.INCLUDE, matcherAccessor.getNullHandler()) ? reference : new Document(SerializationUtils.flattenMap(reference)); Document result = example.getMatcher().isAllMatching() ? flattened : orConcatenate(flattened); return updateTypeRestrictions(result, example); }
@Nullable public <T> T getPropertyValue(MongoPersistentProperty property) { String expression = property.getSpelExpression(); Object value = expression != null ? evaluator.evaluate(expression) : accessor.get(property); if (value == null) { return null; } return readValue(value, property.getTypeInformation(), path); } }
/** * Returns whether the given {@link Field} represents an association reference that together with the given value * requires conversion to a {@link org.springframework.data.mongodb.core.mapping.DBRef} object. We check whether the * type of the given value is compatible with the type of the given document field in order to deal with potential * query field exclusions, since MongoDB uses the {@code int} {@literal 0} as an indicator for an excluded field. * * @param documentField must not be {@literal null}. * @param value * @return */ protected boolean isAssociationConversionNecessary(Field documentField, @Nullable Object value) { Assert.notNull(documentField, "Document field must not be null!"); if (value == null) { return false; } if (!documentField.isAssociation()) { return false; } Class<? extends Object> type = value.getClass(); MongoPersistentProperty property = documentField.getProperty(); if (property.getActualType().isAssignableFrom(type)) { return true; } MongoPersistentEntity<?> entity = documentField.getPropertyEntity(); return entity.hasIdProperty() && (type.equals(DBRef.class) || entity.getRequiredIdProperty().getActualType().isAssignableFrom(type)); }
@Nullable @SuppressWarnings("unchecked") public <T> T getPropertyValue(MongoPersistentProperty property) { if (property.isDbReference() && property.getDBRef().lazy()) { Object rawRefValue = accessor.get(property); if (rawRefValue == null) { return null; } DbRefResolverCallback callback = new DefaultDbRefResolverCallback(accessor.getDocument(), path, evaluator, MappingMongoConverter.this); DBRef dbref = rawRefValue instanceof DBRef ? (DBRef) rawRefValue : null; return (T) dbRefResolver.resolveDbRef(property, dbref, callback, dbRefProxyHandler); } return super.getPropertyValue(property); } }
public DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referringProperty) { org.springframework.data.mongodb.core.mapping.DBRef annotation; if (referringProperty != null) { annotation = referringProperty.getDBRef(); Assert.isTrue(annotation != null, "The referenced property has to be mapped with @DBRef!"); } // DATAMONGO-913 if (object instanceof LazyLoadingProxy) { return ((LazyLoadingProxy) object).toDBRef(); } return createDBRef(object, referringProperty); }
/** * Creates a proxy for the given {@link MongoPersistentProperty} using the given {@link DbRefResolverCallback} to * eventually resolve the value of the property. * * @param property must not be {@literal null}. * @param dbref can be {@literal null}. * @param callback must not be {@literal null}. * @return */ private Object createLazyLoadingProxy(MongoPersistentProperty property, @Nullable DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler handler) { Class<?> propertyType = property.getType(); LazyLoadingInterceptor interceptor = new LazyLoadingInterceptor(property, dbref, exceptionTranslator, callback); if (!propertyType.isInterface()) { Factory factory = (Factory) objenesis.newInstance(getEnhancedTypeFor(propertyType)); factory.setCallbacks(new Callback[] { interceptor }); return handler.populateId(property, dbref, factory); } ProxyFactory proxyFactory = new ProxyFactory(); for (Class<?> type : propertyType.getInterfaces()) { proxyFactory.addInterface(type); } proxyFactory.addInterface(LazyLoadingProxy.class); proxyFactory.addInterface(propertyType); proxyFactory.addAdvice(interceptor); return handler.populateId(property, dbref, proxyFactory.getProxy()); }
private Document getMappedTextScoreField(MongoPersistentProperty property) { return new Document(property.getFieldName(), META_TEXT_SCORE); }