DATACMNS-867 - Further polishing in MappingContext APIs.

This commit is contained in:
Oliver Gierke
2016-11-14 08:15:49 +01:00
parent 142f8b4b4b
commit 8268373d11
4 changed files with 42 additions and 61 deletions

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.data.mapping.context;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -48,6 +51,7 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.Optionals;
import org.springframework.data.util.Pair;
import org.springframework.data.util.Streamable;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
@@ -120,13 +124,15 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
/**
* Configures the {@link SimpleTypeHolder} to be used by the {@link MappingContext}. Allows customization of what
* types will be regarded as simple types and thus not recursively analysed. Setting this to {@literal null} will
* reset the context to use the default {@link SimpleTypeHolder}.
* types will be regarded as simple types and thus not recursively analysed.
*
* @param simpleTypes
* @param simpleTypes must not be {@literal null}.
*/
public void setSimpleTypeHolder(SimpleTypeHolder simpleTypes) {
this.simpleTypeHolder = simpleTypes == null ? new SimpleTypeHolder() : simpleTypes;
Assert.notNull(simpleTypes, "SimpleTypeHolder must not be null!");
this.simpleTypeHolder = simpleTypes;
}
/*
@@ -173,7 +179,10 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
*/
@Override
public boolean hasPersistentEntityFor(Class<?> type) {
return type == null ? false : persistentEntities.containsKey(ClassTypeInformation.from(type));
Assert.notNull(type, "Type must not be null!");
return persistentEntities.containsKey(ClassTypeInformation.from(type));
}
/*
@@ -468,10 +477,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
* context.
*/
public void initialize() {
for (Class<?> initialEntity : initialEntitySet) {
addPersistentEntity(initialEntity);
}
initialEntitySet.forEach(it -> addPersistentEntity(it));
}
/**
@@ -492,28 +498,12 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
*
* @author Oliver Gierke
*/
@RequiredArgsConstructor
private final class PersistentPropertyCreator implements FieldCallback {
private final E entity;
private final Map<String, PropertyDescriptor> descriptors;
private final Map<String, PropertyDescriptor> remainingDescriptors;
/**
* Creates a new {@link PersistentPropertyCreator} for the given {@link PersistentEntity} and
* {@link PropertyDescriptor}s.
*
* @param entity must not be {@literal null}.
* @param descriptors must not be {@literal null}.
*/
private PersistentPropertyCreator(E entity, Map<String, PropertyDescriptor> descriptors) {
Assert.notNull(entity, "PersistentEntity must not be null!");
Assert.notNull(descriptors, "PropertyDescriptors must not be null!");
this.entity = entity;
this.descriptors = descriptors;
this.remainingDescriptors = new HashMap<String, PropertyDescriptor>(descriptors);
}
private final @NonNull E entity;
private final @NonNull Map<String, PropertyDescriptor> descriptors;
private final Map<String, PropertyDescriptor> remainingDescriptors = new HashMap<>();
/*
* (non-Javadoc)
@@ -537,11 +527,10 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
*/
public void addPropertiesForRemainingDescriptors() {
for (PropertyDescriptor descriptor : remainingDescriptors.values()) {
if (PersistentPropertyFilter.INSTANCE.matches(descriptor)) {
createAndRegisterProperty(Property.of(descriptor));
}
}
remainingDescriptors.values().stream()//
.map(Property::of)//
.filter(PersistentPropertyFilter.INSTANCE::matches)//
.forEach(this::createAndRegisterProperty);
}
private void createAndRegisterProperty(Property input) {
@@ -563,9 +552,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
return;
}
for (TypeInformation<?> candidate : property.getPersistentEntityType()) {
addPersistentEntity(candidate);
}
property.getPersistentEntityType().forEach(it -> addPersistentEntity(it));
}
}
@@ -579,7 +566,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
INSTANCE;
private static final Iterable<PropertyMatch> UNMAPPED_PROPERTIES;
private static final Streamable<PropertyMatch> UNMAPPED_PROPERTIES;
static {
@@ -588,7 +575,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
matches.add(new PropertyMatch("this\\$.*", null));
matches.add(new PropertyMatch("metaClass", "groovy.lang.MetaClass"));
UNMAPPED_PROPERTIES = Collections.unmodifiableCollection(matches);
UNMAPPED_PROPERTIES = Streamable.of(matches);
}
/*
@@ -601,13 +588,8 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
return false;
}
for (PropertyMatch candidate : UNMAPPED_PROPERTIES) {
if (candidate.matches(field.getName(), field.getType())) {
return false;
}
}
return true;
return !UNMAPPED_PROPERTIES.stream()//
.anyMatch(it -> it.matches(field.getName(), field.getType()));
}
/**
@@ -616,21 +598,16 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
* @param descriptor must not be {@literal null}.
* @return
*/
public boolean matches(PropertyDescriptor descriptor) {
public boolean matches(Property property) {
Assert.notNull(descriptor, "PropertyDescriptor must not be null!");
Assert.notNull(property, "Property must not be null!");
if (descriptor.getReadMethod() == null && descriptor.getWriteMethod() == null) {
if (!property.hasAccessor()) {
return false;
}
for (PropertyMatch candidate : UNMAPPED_PROPERTIES) {
if (candidate.matches(descriptor.getName(), descriptor.getPropertyType())) {
return false;
}
}
return true;
return !UNMAPPED_PROPERTIES.stream()//
.anyMatch(it -> it.matches(property.getName(), property.getType()));
}
/**

View File

@@ -56,7 +56,7 @@ public interface MappingContext<E extends PersistentEntity<?, P>, P extends Pers
/**
* Returns whether the {@link MappingContext} currently contains a {@link PersistentEntity} for the type.
*
* @param type can be {@literal null}.
* @param type must not be {@literal null}.
* @return
* @since 1.8
*/

View File

@@ -65,7 +65,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
Assert.notNull(owner, "Owner entity must not be null!");
this.name = property.getName();
this.rawType = property.getRawType();
this.rawType = property.getType();
this.information = PropertyPath.from(property.getName(), owner.getTypeInformation()).getTypeInformation();
this.property = property;

View File

@@ -71,12 +71,16 @@ public class Property {
public Optional<Method> getGetter() {
return descriptor.map(it -> it.getReadMethod())//
.filter(it -> getRawType().isAssignableFrom(it.getReturnType()));
.filter(it -> getType().isAssignableFrom(it.getReturnType()));
}
public Optional<Method> getSetter() {
return descriptor.map(it -> it.getWriteMethod())//
.filter(it -> it.getParameterTypes()[0].isAssignableFrom(getRawType()));
.filter(it -> it.getParameterTypes()[0].isAssignableFrom(getType()));
}
public boolean hasAccessor() {
return getGetter().isPresent() || getSetter().isPresent();
}
/**
@@ -87,7 +91,7 @@ public class Property {
.orElseThrow(() -> new IllegalStateException()));
}
public Class<?> getRawType() {
public Class<?> getType() {
return rawType.get();
}