Remove deprecations in PersistentPropertyAccessor.
Related issue: #2813.
This commit is contained in:
@@ -17,7 +17,6 @@ package org.springframework.data.mapping;
|
||||
|
||||
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Domain service to allow accessing and setting {@link PersistentProperty}s of an entity. Usually obtained through
|
||||
@@ -46,63 +45,6 @@ public interface PersistentPropertyAccessor<T> {
|
||||
*/
|
||||
void setProperty(PersistentProperty<?> property, @Nullable Object value);
|
||||
|
||||
/**
|
||||
* Sets the given value for the {@link PersistentProperty} pointed to by the given {@link PersistentPropertyPath}. The
|
||||
* lookup of intermediate values must not yield {@literal null}.
|
||||
*
|
||||
* @param path must not be {@literal null} or empty.
|
||||
* @param value can be {@literal null}.
|
||||
* @since 2.1
|
||||
* @deprecated since 2.3, use {@link PersistentPropertyPathAccessor#setProperty(PersistentPropertyPath, Object)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default void setProperty(PersistentPropertyPath<? extends PersistentProperty<?>> path, @Nullable Object value) {
|
||||
|
||||
Assert.notNull(path, "PersistentPropertyPath must not be null");
|
||||
Assert.isTrue(!path.isEmpty(), "PersistentPropertyPath must not be empty");
|
||||
|
||||
PersistentProperty<? extends PersistentProperty<?>> leafProperty = path.getLeafProperty();
|
||||
PersistentPropertyPath<? extends PersistentProperty<?>> parentPath = path.getParentPath();
|
||||
|
||||
if (parentPath != null) {
|
||||
|
||||
PersistentProperty<? extends PersistentProperty<?>> parentProperty = parentPath.getLeafProperty();
|
||||
|
||||
if (parentProperty.isCollectionLike() || parentProperty.isMap()) {
|
||||
throw new MappingException(
|
||||
"Cannot traverse collection or map intermediate %s".formatted(parentPath.toDotPath()));
|
||||
}
|
||||
}
|
||||
|
||||
Object parent = parentPath == null ? getBean() : getProperty(parentPath);
|
||||
|
||||
if (parent == null) {
|
||||
|
||||
String nullIntermediateMessage = "Cannot lookup property %s on null intermediate; Original path was: %s on %s";
|
||||
|
||||
throw new MappingException(
|
||||
String.format(nullIntermediateMessage, path.getParentPath(), path.toDotPath(),
|
||||
getBean().getClass().getName()));
|
||||
}
|
||||
|
||||
PersistentPropertyAccessor<?> accessor = parent == getBean() //
|
||||
? this //
|
||||
: leafProperty.getOwner().getPropertyAccessor(parent);
|
||||
|
||||
accessor.setProperty(leafProperty, value);
|
||||
|
||||
if (parentPath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object bean = accessor.getBean();
|
||||
|
||||
if (bean != parent) {
|
||||
setProperty(parentPath, bean);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the given {@link PersistentProperty} of the underlying bean instance.
|
||||
*
|
||||
@@ -112,65 +54,6 @@ public interface PersistentPropertyAccessor<T> {
|
||||
@Nullable
|
||||
Object getProperty(PersistentProperty<?> property);
|
||||
|
||||
/**
|
||||
* Return the value pointed to by the given {@link PersistentPropertyPath}. If the given path is empty, the wrapped
|
||||
* bean is returned.
|
||||
*
|
||||
* @param path must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.1
|
||||
* @deprecated since 2.3, use {@link PersistentPropertyPathAccessor#getProperty(PersistentPropertyPath)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
default Object getProperty(PersistentPropertyPath<? extends PersistentProperty<?>> path) {
|
||||
return getProperty(path, new TraversalContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value pointed to by the given {@link PersistentPropertyPath}. If the given path is empty, the wrapped
|
||||
* bean is returned. On each path segment value lookup, the resulting value is post-processed by handlers registered
|
||||
* on the given {@link TraversalContext} context. This can be used to unwrap container types that are encountered
|
||||
* during the traversal.
|
||||
*
|
||||
* @param path must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.2
|
||||
* @deprecated since 2.3, use
|
||||
* {@link PersistentPropertyPathAccessor#getProperty(PersistentPropertyPath, org.springframework.data.mapping.AccessOptions.GetOptions)}
|
||||
* instead.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
default Object getProperty(PersistentPropertyPath<? extends PersistentProperty<?>> path, TraversalContext context) {
|
||||
|
||||
Object bean = getBean();
|
||||
Object current = bean;
|
||||
|
||||
if (path.isEmpty()) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
for (PersistentProperty<?> property : path) {
|
||||
|
||||
if (current == null) {
|
||||
|
||||
String nullIntermediateMessage = "Cannot lookup property %s on null intermediate; Original path was: %s on %s";
|
||||
|
||||
throw new MappingException(
|
||||
String.format(nullIntermediateMessage, property, path.toDotPath(), bean.getClass().getName()));
|
||||
}
|
||||
|
||||
PersistentEntity<?, ? extends PersistentProperty<?>> entity = property.getOwner();
|
||||
PersistentPropertyAccessor<Object> accessor = entity.getPropertyAccessor(current);
|
||||
|
||||
current = context.postProcess(property, accessor.getProperty(property));
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying bean. The actual instance may change between
|
||||
* {@link #setProperty(PersistentProperty, Object)} calls.
|
||||
|
||||
@@ -37,10 +37,7 @@ public interface PersistentPropertyPathAccessor<T> extends PersistentPropertyAcc
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("deprecation")
|
||||
default Object getProperty(PersistentPropertyPath<? extends PersistentProperty<?>> path) {
|
||||
return PersistentPropertyAccessor.super.getProperty(path);
|
||||
}
|
||||
Object getProperty(PersistentPropertyPath<? extends PersistentProperty<?>> path);
|
||||
|
||||
/**
|
||||
* Return the value pointed to by the given {@link PersistentPropertyPath}. If the given path is empty, the wrapped
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A context object for lookups of values for {@link PersistentPropertyPaths} via a {@link PersistentPropertyAccessor}.
|
||||
* It allows to register functions to post-process the objects returned for a particular property, so that the
|
||||
* subsequent traversal would rather use the processed object. This is especially helpful if you need to traverse paths
|
||||
* that contain {@link Collection}s and {@link Map} that usually need indices and keys to reasonably traverse nested
|
||||
* properties.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @since 2.2
|
||||
* @soundtrack 8-Bit Misfits - Crash Into Me (Dave Matthews Band cover)
|
||||
*/
|
||||
public class TraversalContext {
|
||||
|
||||
private Map<PersistentProperty<?>, Function<Object, Object>> handlers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Registers a {@link Function} to post-process values for the given property.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @param handler must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public TraversalContext registerHandler(PersistentProperty<?> property, Function<Object, Object> handler) {
|
||||
|
||||
Assert.notNull(property, "Property must not be null");
|
||||
Assert.notNull(handler, "Handler must not be null");
|
||||
|
||||
handlers.put(property, handler);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link Function} to handle {@link Collection} values for the given property.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @param handler must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public TraversalContext registerCollectionHandler(PersistentProperty<?> property,
|
||||
Function<? super Collection<?>, Object> handler) {
|
||||
return registerHandler(property, Collection.class, (Function<Object, Object>) handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link Function} to handle {@link List} values for the given property.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @param handler must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public TraversalContext registerListHandler(PersistentProperty<?> property,
|
||||
Function<? super List<?>, Object> handler) {
|
||||
return registerHandler(property, List.class, (Function<Object, Object>) handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link Function} to handle {@link Set} values for the given property.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @param handler must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public TraversalContext registerSetHandler(PersistentProperty<?> property, Function<? super Set<?>, Object> handler) {
|
||||
return registerHandler(property, Set.class, (Function<Object, Object>) handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link Function} to handle {@link Map} values for the given property.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @param handler must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public TraversalContext registerMapHandler(PersistentProperty<?> property,
|
||||
Function<? super Map<?, ?>, Object> handler) {
|
||||
return registerHandler(property, Map.class, (Function<Object, Object>) handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given {@link Function} to post-process values obtained for the given {@link PersistentProperty} for
|
||||
* the given type.
|
||||
*
|
||||
* @param <T> the type of the value to handle.
|
||||
* @param property must not be {@literal null}.
|
||||
* @param type must not be {@literal null}.
|
||||
* @param handler must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public <T> TraversalContext registerHandler(PersistentProperty<?> property, Class<T> type,
|
||||
Function<? super T, Object> handler) {
|
||||
|
||||
Assert.isTrue(type.isAssignableFrom(property.getType()), () -> String
|
||||
.format("Cannot register a property handler for %s on a property of type %s", type, property.getType()));
|
||||
|
||||
Function<Object, T> caster = (Function<Object, T>) it -> type.cast(it);
|
||||
|
||||
return registerHandler(property, caster.andThen(handler));
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-processes the value obtained for the given {@link PersistentProperty} using the registered handler.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @param value can be {@literal null}.
|
||||
* @return the post-processed value or the value itself if no handlers registered.
|
||||
*/
|
||||
@Nullable
|
||||
Object postProcess(PersistentProperty<?> property, @Nullable Object value) {
|
||||
|
||||
Function<Object, Object> handler = handlers.get(property);
|
||||
|
||||
return handler == null ? value : handler.apply(value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user