SGF-582 - Polish.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
@@ -24,9 +25,12 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* Spring Data {@link AbstractMappingContext} implementation defining entity mapping meta-data
|
||||
* for GemFire persistent entities.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext
|
||||
*/
|
||||
public class GemfireMappingContext extends AbstractMappingContext<GemfirePersistentEntity<?>, GemfirePersistentProperty> {
|
||||
|
||||
@@ -42,23 +46,23 @@ public class GemfireMappingContext extends AbstractMappingContext<GemfirePersist
|
||||
setSimpleTypeHolder(new GemfireSimpleTypeHolder());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> GemfirePersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new GemfirePersistentEntity<T>(typeInformation);
|
||||
return new GemfirePersistentEntity<>(typeInformation);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder)
|
||||
*/
|
||||
@Override
|
||||
protected GemfirePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
protected GemfirePersistentProperty createPersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
|
||||
GemfirePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
|
||||
return new GemfirePersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
return new GemfirePersistentProperty(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,23 +19,16 @@ package org.springframework.data.gemfire.mapping;
|
||||
import static org.springframework.data.gemfire.util.SpringUtils.defaultIfEmpty;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
|
||||
import org.springframework.data.gemfire.mapping.annotation.LocalRegion;
|
||||
import org.springframework.data.gemfire.mapping.annotation.PartitionRegion;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
import org.springframework.data.gemfire.mapping.annotation.ReplicateRegion;
|
||||
import org.springframework.data.mapping.IdentifierAccessor;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.mapping.model.IdPropertyIdentifierAccessor;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link PersistentEntity} implementation adding custom GemFire persistent entity related metadata, such as the
|
||||
@@ -54,61 +47,12 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
|
||||
private final String regionName;
|
||||
|
||||
/**
|
||||
* GET_ID_METHOD_NAME = "getId" Used to support getting the region key when the @Id annotation does not exist.
|
||||
*/
|
||||
private static final String GET_ID_METHOD_NAME = "getId";
|
||||
|
||||
/**
|
||||
* Get the identifier access strategy object that determines the region key to use
|
||||
*
|
||||
* @return implementation of the Identifier access strategy with support to use the getId bean method.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public IdentifierAccessor getIdentifierAccessor(Object bean) {
|
||||
|
||||
Assert.notNull(bean, "Target bean must not be null!");
|
||||
Assert.isTrue(getType().isInstance(bean), "Target bean is not of type of the persistent entity!");
|
||||
|
||||
// Check if @Id access
|
||||
if (hasIdProperty()) {
|
||||
return new IdPropertyIdentifierAccessor(this, bean);
|
||||
}
|
||||
|
||||
// use getId() method via a lamba function implementation of IdentifierAccessor
|
||||
IdentifierAccessor getIdAccessor = () -> {
|
||||
|
||||
try {
|
||||
Method getMethod = bean.getClass().getMethod(GET_ID_METHOD_NAME);
|
||||
|
||||
if (getMethod == null)
|
||||
return null; // getId method not found
|
||||
|
||||
return getMethod.invoke(bean);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
} catch (SecurityException e) {
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
} catch (InvocationTargetException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return getIdAccessor;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static Annotation resolveRegionAnnotation(Class<?> persistentEntityType) {
|
||||
|
||||
for (Class<? extends Annotation> regionAnnotationType : Region.REGION_ANNOTATION_TYPES) {
|
||||
Annotation regionAnnotation = AnnotatedElementUtils.getMergedAnnotation(persistentEntityType,
|
||||
regionAnnotationType);
|
||||
Annotation regionAnnotation = AnnotatedElementUtils.getMergedAnnotation(
|
||||
persistentEntityType, regionAnnotationType);
|
||||
|
||||
if (regionAnnotation != null) {
|
||||
return regionAnnotation;
|
||||
@@ -122,16 +66,24 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
protected static String resolveRegionName(Class<?> persistentEntityType, Annotation regionAnnotation) {
|
||||
|
||||
String regionName = (regionAnnotation != null
|
||||
? AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(regionAnnotation)).getString("value")
|
||||
: null);
|
||||
? getAnnotationAttributeStringValue(regionAnnotation, "value") : null);
|
||||
|
||||
return defaultIfEmpty(regionName, persistentEntityType.getSimpleName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static String getAnnotationAttributeStringValue(Annotation annotation, String attributeName) {
|
||||
return AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(annotation))
|
||||
.getString(attributeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link GemfirePersistentEntity} for the given {@link TypeInformation}.
|
||||
* Constructs a new instance of {@link GemfirePersistentEntity} initialized with the given {@link TypeInformation}
|
||||
* describing the domain object (entity) {@link Class} type.
|
||||
*
|
||||
* @param information must not be {@literal null}.
|
||||
* @param information {@link TypeInformation} meta-data describing the domain object (entity) {@link Class} type.
|
||||
* @throws IllegalArgumentException if the given {@link TypeInformation} is {@literal null}.
|
||||
* @see org.springframework.data.util.TypeInformation
|
||||
*/
|
||||
public GemfirePersistentEntity(TypeInformation<T> information) {
|
||||
super(information);
|
||||
@@ -143,17 +95,17 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Region} annotation used to annotate this {@link PersistentEntity} or {@literal null} if this
|
||||
* {@link PersistentEntity} was not annotated with a {@link Region} annotation.
|
||||
* Returns the {@link Region} {@link Annotation} used to annotate this {@link PersistentEntity} or {@literal null}
|
||||
* if this {@link PersistentEntity} was not annotated with a {@link Region} {@link Annotation}.
|
||||
*
|
||||
* @param <T> concrete {@link Class} type of the Region {@link Annotation}.
|
||||
* @return the {@link Region} annotation used to annotate this {@link PersistentEntity} or {@literal null} if this
|
||||
* {@link PersistentEntity} was not annotated with a {@link Region} annotation.
|
||||
* @see ClientRegion
|
||||
* @see LocalRegion
|
||||
* @see PartitionRegion
|
||||
* @see ReplicateRegion
|
||||
* @see Region
|
||||
* @param <T> concrete {@link Class} type of the {@link Region} {@link Annotation}.
|
||||
* @return the {@link Region} {@link Annotation} used to annotate this {@link PersistentEntity} or {@literal null}
|
||||
* if this {@link PersistentEntity} was not annotated with a {@link Region} {@link Annotation}.
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.ClientRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.LocalRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.PartitionRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.ReplicateRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @see java.lang.annotation.Annotation
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -162,11 +114,11 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Class} type of the Region {@link Annotation} or {@literal null} if this {@link PersistentEntity}
|
||||
* was not annotated with a Region {@link Annotation}.
|
||||
* Returns the {@link Class} type of the {@link Region} {@link Annotation} used to annotate this entity
|
||||
* or {@literal null} if this entity was not annotated with a {@link Region} {@link Annotation}.
|
||||
*
|
||||
* @return the {@link Class} type of the Region {@link Annotation} or {@literal null} if this {@link PersistentEntity}
|
||||
* was not annotated with a Region {@link Annotation}.
|
||||
* @return the {@link Class} type of the {@link Region} {@link Annotation} used to annotate this entity
|
||||
* or {@literal null} if this entity was not annotated with a {@link Region} {@link Annotation}.
|
||||
* @see java.lang.annotation.Annotation#annotationType()
|
||||
* @see #getRegionAnnotation()
|
||||
*/
|
||||
@@ -176,12 +128,47 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the {@link Region} in which this {@link PersistentEntity} will be stored.
|
||||
* Returns the name of the {@link org.apache.geode.cache.Region} in which this {@link PersistentEntity}
|
||||
* will be stored.
|
||||
*
|
||||
* @return the name of the {@link Region} in which this {@link PersistentEntity} will be stored.
|
||||
* @return the name of the {@link org.apache.geode.cache.Region} in which this {@link PersistentEntity}
|
||||
* will be stored.
|
||||
* @see org.apache.geode.cache.Region#getName()
|
||||
*/
|
||||
public String getRegionName() {
|
||||
return this.regionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @see org.springframework.data.mapping.model.BasicPersistentEntity#returnPropertyIfBetterIdPropertyCandidateOrNull(PersistentProperty)
|
||||
*/
|
||||
@Override
|
||||
protected GemfirePersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNull(
|
||||
GemfirePersistentProperty property) {
|
||||
|
||||
if (property.isIdProperty()) {
|
||||
if (hasIdProperty()) {
|
||||
GemfirePersistentProperty currentIdProperty = getIdProperty();
|
||||
|
||||
if (currentIdProperty.isExplicitIdProperty()) {
|
||||
if (property.isExplicitIdProperty()) {
|
||||
throw new MappingException(String.format(
|
||||
"Attempt to add explicit id property [%1$s] but already have id property [%2$s] registered as explicit;"
|
||||
+ " Please check your object [%3$s] mapping configuration",
|
||||
property.getName(), currentIdProperty.getName(), getType().getName()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return (property.isExplicitIdProperty() ? property : null);
|
||||
}
|
||||
else {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,11 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.asSet;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.model.GemfireSimpleTypeHolder;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
@@ -27,11 +32,13 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
|
||||
/**
|
||||
* {@link PersistentProperty} implementation to for Gemfire related metadata.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfirePersistentProperty extends AnnotationBasedPersistentProperty<GemfirePersistentProperty> {
|
||||
|
||||
protected static final Set<String> SUPPORTED_IDENTIFIER_NAMES = asSet("id");
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private static SimpleTypeHolder resolveSimpleTypeHolder(SimpleTypeHolder source) {
|
||||
return (source instanceof GemfireSimpleTypeHolder ? source
|
||||
@@ -39,26 +46,59 @@ public class GemfirePersistentProperty extends AnnotationBasedPersistentProperty
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of the GemfirePersistentProperty with entity information.
|
||||
* Constructs an instance of the {@link GemfirePersistentProperty} initialized with entity
|
||||
* persistent property information (meta-data).
|
||||
*
|
||||
* @param field the entity field corresponding to the persistent property.
|
||||
* @param propertyDescriptor PropertyDescriptor for the entity's persistent property.
|
||||
* @param owner the entity owning the persistent property.
|
||||
* @param simpleTypeHolder type holder for primitive types.
|
||||
* @param field entity {@link Field} corresponding to the persistent property.
|
||||
* @param propertyDescriptor {@link PropertyDescriptor} for the entity's persistent property.
|
||||
* @param owner entity owning the persistent property.
|
||||
* @param simpleTypeHolder {@link SimpleTypeHolder} used to handle primitive types.
|
||||
* @see org.springframework.data.mapping.model.SimpleTypeHolder
|
||||
* @see org.springframework.data.mapping.PersistentEntity
|
||||
* @see java.beans.PropertyDescriptor
|
||||
* @see java.lang.reflect.Field
|
||||
*/
|
||||
public GemfirePersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
|
||||
PersistentEntity<?, GemfirePersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
|
||||
super(field, propertyDescriptor, owner, resolveSimpleTypeHolder(simpleTypeHolder));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.mapping.model.AbstractPersistentProperty#
|
||||
* createAssociation()
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
protected Association<GemfirePersistentProperty> createAssociation() {
|
||||
return new Association<GemfirePersistentProperty>(this, null);
|
||||
return new Association<>(this, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this {@link GemfirePersistentProperty} explicitly identifies an entity property identifier,
|
||||
* one in which the user explicitly annotated a entity class member (field or getter/setter).
|
||||
*
|
||||
* @return a boolean value indicating whether this {@link GemfirePersistentProperty} explicitly identifies
|
||||
* an entity property identifier.
|
||||
* @see org.springframework.data.annotation.Id
|
||||
* @see #isAnnotationPresent(Class)
|
||||
*/
|
||||
public boolean isExplicitIdProperty() {
|
||||
return isAnnotationPresent(Id.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @see org.springframework.data.mapping.model.AnnotationBasedPersistentProperty#isIdProperty()
|
||||
*/
|
||||
@Override
|
||||
public boolean isIdProperty() {
|
||||
return (super.isIdProperty() || SUPPORTED_IDENTIFIER_NAMES.contains(getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean usePropertyAccess() {
|
||||
return (super.usePropertyAccess() || (getField() == null && this.propertyDescriptor != null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,14 +178,14 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
*/
|
||||
@Override
|
||||
public Object fromData(final Class<?> type, final PdxReader reader) {
|
||||
|
||||
final GemfirePersistentEntity<?> entity = getPersistentEntity(type);
|
||||
|
||||
final Object instance = getInstantiatorFor(entity).createInstance(entity,
|
||||
new PersistentEntityParameterValueProvider<GemfirePersistentProperty>(entity,
|
||||
new GemfirePropertyValueProvider(reader), null));
|
||||
new PersistentEntityParameterValueProvider<>(entity, new GemfirePropertyValueProvider(reader), null));
|
||||
|
||||
final PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance),
|
||||
getConversionService());
|
||||
final PersistentPropertyAccessor propertyAccessor =
|
||||
new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance), getConversionService());
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<GemfirePersistentProperty>() {
|
||||
public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) {
|
||||
@@ -209,7 +209,7 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
log.debug(String.format("with value [%1$s]", value));
|
||||
}
|
||||
|
||||
accessor.setProperty(persistentProperty, value);
|
||||
propertyAccessor.setProperty(persistentProperty, value);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException(String.format(
|
||||
@@ -221,7 +221,7 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
}
|
||||
});
|
||||
|
||||
return accessor.getBean();
|
||||
return propertyAccessor.getBean();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,39 +229,40 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
*/
|
||||
@Override
|
||||
public boolean toData(final Object value, final PdxWriter writer) {
|
||||
GemfirePersistentEntity<?> entity = getPersistentEntity(value.getClass());
|
||||
|
||||
final PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(value),
|
||||
getConversionService());
|
||||
GemfirePersistentEntity<?> entity = getPersistentEntity(value);
|
||||
|
||||
final PersistentPropertyAccessor propertyAccessor =
|
||||
new ConvertingPropertyAccessor(entity.getPropertyAccessor(value), getConversionService());
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<GemfirePersistentProperty>() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) {
|
||||
PdxSerializer customSerializer = getCustomSerializer(persistentProperty.getType());
|
||||
|
||||
Object propertyValue = null;
|
||||
|
||||
try {
|
||||
propertyValue = accessor.getProperty(persistentProperty);
|
||||
propertyValue = propertyAccessor.getProperty(persistentProperty);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("serializing value [%1$s] of property [%2$s] for entity of type [%3$s] to PDX%4$s",
|
||||
propertyValue, persistentProperty.getName(), value.getClass(), (customSerializer != null ?
|
||||
String.format(" using custom PdxSerializer [%1$s]", customSerializer) : "")));
|
||||
log.debug(String.format("Serializing entity property [%1$s] value [%2$s] of type [%3$s] to PDX%4$s",
|
||||
persistentProperty.getName(), propertyValue, value.getClass(), (customSerializer != null ?
|
||||
String.format(" using custom PdxSerializer [%s]", customSerializer) : "")));
|
||||
}
|
||||
|
||||
if (customSerializer != null) {
|
||||
customSerializer.toData(propertyValue, writer);
|
||||
}
|
||||
else {
|
||||
writer.writeField(persistentProperty.getName(), propertyValue, (Class) persistentProperty.getType());
|
||||
writer.writeField(persistentProperty.getName(), propertyValue,
|
||||
(Class<Object>) persistentProperty.getType());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException(String.format(
|
||||
"while serializing value [%1$s] of property [%2$s] for entity of type [%3$s] to PDX%4$s",
|
||||
propertyValue, persistentProperty.getName(), value.getClass(),
|
||||
"Error while serializing entity property [%1$s] value [%2$s] of type [%3$s] to PDX%4$s",
|
||||
persistentProperty.getName(), propertyValue, value.getClass(),
|
||||
(customSerializer != null ? String.format(" using custom PdxSerializer [%1$s].",
|
||||
customSerializer.getClass().getName()) : ".")), e);
|
||||
}
|
||||
@@ -304,12 +305,24 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up and returns the PersistentEntity meta-data for the given entity class type.
|
||||
* Looks up and returns the {@link PersistentEntity} meta-data for the given entity object.
|
||||
*
|
||||
* @param entityType the Class type of the actual persistent entity, application domain object class.
|
||||
* @return the PersistentEntity meta-data for the given entity class type.
|
||||
* @see #getMappingContext()
|
||||
* @param entity actual persistent entity, application domain object.
|
||||
* @return the {@link PersistentEntity} meta-data for the given entity object.
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
* @see #getPersistentEntity(Class)
|
||||
*/
|
||||
protected GemfirePersistentEntity<?> getPersistentEntity(Object entity) {
|
||||
return getPersistentEntity(entity.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up and returns the {@link PersistentEntity} meta-data for the given entity {@link Class} type.
|
||||
*
|
||||
* @param entityType {@link Class} type of the actual persistent entity, application domain object {@link Class}.
|
||||
* @return the {@link PersistentEntity} meta-data for the given entity {@link Class} type.
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
* @see #getMappingContext()
|
||||
*/
|
||||
protected GemfirePersistentEntity<?> getPersistentEntity(Class<?> entityType) {
|
||||
return getMappingContext().getPersistentEntity(entityType);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.data.gemfire.util;
|
||||
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -82,6 +84,26 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe method to determines whether the given {@link Collection} contains any elements from the given array.
|
||||
*
|
||||
* @param collection {@link Collection} to evaluate
|
||||
* @param elements array of elements to evaluate.
|
||||
* @return a boolean value indicating whether the collection contains at least 1 element from the given array.
|
||||
* @see java.util.Collection#contains(Object)
|
||||
*/
|
||||
public static boolean containsAny(Collection<?> collection, Object... elements) {
|
||||
if (collection != null) {
|
||||
for (Object element : nullSafeArray(elements, Object.class)) {
|
||||
if (collection.contains(element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given {@link Iterable} if not {@literal null} or empty, otherwise returns the {@code defaultIterable}.
|
||||
*
|
||||
|
||||
@@ -13,129 +13,204 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
import org.springframework.data.mapping.IdentifierAccessor;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GemfirePersistentEntity}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author John Blum
|
||||
* @author Gregory Green
|
||||
* @see org.junit.Rule
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
*/
|
||||
public class GemfirePersistentEntityUnitTests {
|
||||
|
||||
protected MappingContext<GemfirePersistentEntity<?>, GemfirePersistentProperty> getMappingContext() {
|
||||
return new GemfireMappingContext();
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
private GemfireMappingContext mappingContext = new GemfireMappingContext();
|
||||
|
||||
protected IdentifierAccessor getIdentifierAccessor(Object domainObject) {
|
||||
return getMappingContextPersistentEntity(domainObject).getIdentifierAccessor(domainObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* JIRA ticket SGF-582
|
||||
*
|
||||
* Used an object's getId method if the @Id does not exists
|
||||
*/
|
||||
@Test
|
||||
public void supportsGetId() {
|
||||
|
||||
GemfirePersistentEntity<UnannotatedRegion> unnamedRegionEntity = new GemfirePersistentEntity<UnannotatedRegion>(
|
||||
ClassTypeInformation.from(UnannotatedRegion.class));
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> GemfirePersistentEntity<T> getMappingContextPersistentEntity(Object domainObject) {
|
||||
return this.<T>getMappingContextPersistentEntity((Class<T>) domainObject.getClass());
|
||||
}
|
||||
|
||||
IdentifierAccessor accessor = unnamedRegionEntity.getIdentifierAccessor(new UnannotatedRegion());
|
||||
Assert.assertNull(accessor.getIdentifier());
|
||||
|
||||
GemfirePersistentEntity<NotAnnotationIdRegion> entity = new GemfirePersistentEntity<NotAnnotationIdRegion>(
|
||||
ClassTypeInformation.from(NotAnnotationIdRegion.class));
|
||||
|
||||
NotAnnotationIdRegion region = new NotAnnotationIdRegion();
|
||||
|
||||
region.setId("id");
|
||||
region.setValue("value");
|
||||
|
||||
accessor = entity.getIdentifierAccessor(region);
|
||||
|
||||
Assert.assertNotNull(accessor.getIdentifier());
|
||||
|
||||
Assert.assertEquals("id", accessor.getIdentifier());
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> GemfirePersistentEntity<T> getMappingContextPersistentEntity(Class<T> type) {
|
||||
return (GemfirePersistentEntity<T>) this.mappingContext.getPersistentEntity(type);
|
||||
}
|
||||
|
||||
protected <T> GemfirePersistentEntity<T> newPersistentEntity(Class<T> type) {
|
||||
return new GemfirePersistentEntity<>(ClassTypeInformation.from(type));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultsRegionNameToClassName() {
|
||||
GemfirePersistentEntity<UnannotatedRegion> entity = new GemfirePersistentEntity<UnannotatedRegion>(
|
||||
ClassTypeInformation.from(UnannotatedRegion.class));
|
||||
assertThat(entity.getRegionName(), is(UnannotatedRegion.class.getSimpleName()));
|
||||
public void defaultsRegionNameForNonRegionAnnotatedEntityToClassName() {
|
||||
assertThat(newPersistentEntity(NonRegionAnnotatedEntity.class).getRegionName())
|
||||
.isEqualTo(NonRegionAnnotatedEntity.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultsAnnotatedRegionToCLassName() {
|
||||
GemfirePersistentEntity<UnnamedRegion> entity = new GemfirePersistentEntity<UnnamedRegion>(
|
||||
ClassTypeInformation.from(UnnamedRegion.class));
|
||||
assertThat(entity.getRegionName(), is(UnnamedRegion.class.getSimpleName()));
|
||||
public void defaultsRegionNameForUnnamedRegionAnnotatedEntityToClassName() {
|
||||
assertThat(newPersistentEntity(UnnamedRegionAnnotatedEntity.class).getRegionName())
|
||||
.isEqualTo(UnnamedRegionAnnotatedEntity.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readsRegionNameFromAnnotation() {
|
||||
|
||||
GemfirePersistentEntity<AnnotatedRegion> entity = new GemfirePersistentEntity<AnnotatedRegion>(
|
||||
ClassTypeInformation.from(AnnotatedRegion.class));
|
||||
assertThat(entity.getRegionName(), is("Foo"));
|
||||
public void returnsGivenNameForNamedRegionAnnotatedEntityAsRegionName() {
|
||||
assertThat(newPersistentEntity(NamedRegionAnnotatedEntity.class).getRegionName()).isEqualTo("Foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bigDecimalPersistentPropertyIsNotEntity() {
|
||||
GemfirePersistentEntity<ExampleDomainObject> entity = (GemfirePersistentEntity<ExampleDomainObject>) getMappingContext()
|
||||
.getPersistentEntity(ExampleDomainObject.class);
|
||||
public void bigDecimalPersistentPropertyIsNotAnEntity() {
|
||||
GemfirePersistentEntity<ExampleDomainObject> entity =
|
||||
getMappingContextPersistentEntity(ExampleDomainObject.class);
|
||||
|
||||
assertThat(entity.getRegionName(), is(equalTo("Example")));
|
||||
assertThat(entity).isNotNull();
|
||||
assertThat(entity.getRegionName()).isEqualTo("Example");
|
||||
|
||||
GemfirePersistentProperty currency = entity.getPersistentProperty("currency");
|
||||
|
||||
assertThat(currency, is(notNullValue()));
|
||||
assertThat(currency.isEntity(), is(false));
|
||||
assertThat(currency).isNotNull();
|
||||
assertThat(currency.isEntity()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bigIntegerPersistentPropertyIsNotEntity() {
|
||||
GemfirePersistentEntity<ExampleDomainObject> entity = (GemfirePersistentEntity<ExampleDomainObject>) getMappingContext()
|
||||
.getPersistentEntity(ExampleDomainObject.class);
|
||||
public void bigIntegerPersistentPropertyIsNotAnEntity() {
|
||||
GemfirePersistentEntity<ExampleDomainObject> entity =
|
||||
getMappingContextPersistentEntity(ExampleDomainObject.class);
|
||||
|
||||
assertThat(entity.getRegionName(), is(equalTo("Example")));
|
||||
assertThat(entity).isNotNull();
|
||||
assertThat(entity.getRegionName()).isEqualTo("Example");
|
||||
|
||||
GemfirePersistentProperty bigNumber = entity.getPersistentProperty("bigNumber");
|
||||
|
||||
assertThat(bigNumber, is(notNullValue()));
|
||||
assertThat(bigNumber.isEntity(), is(false));
|
||||
assertThat(bigNumber).isNotNull();
|
||||
assertThat(bigNumber.isEntity()).isFalse();
|
||||
}
|
||||
|
||||
static class UnannotatedRegion {}
|
||||
/**
|
||||
* <a href="https://jira.spring.io/browse/SGF-582">SGF-582</a>
|
||||
*/
|
||||
@Test
|
||||
public void identifierForNonIdAnnotatedEntityWithNoIdFieldOrPropertyIsNull() {
|
||||
IdentifierAccessor identifierAccessor = getIdentifierAccessor(new NonRegionAnnotatedEntity());
|
||||
|
||||
assertThat(identifierAccessor).isNotNull();
|
||||
assertThat(identifierAccessor.getIdentifier()).isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* <a href="https://jira.spring.io/browse/SGF-582">SGF-582</a>
|
||||
*/
|
||||
@Test
|
||||
public void identifierForNonIdAnnotatedEntityWithIdFieldIsNotNull() {
|
||||
IdentifierAccessor identifierAccessor = getIdentifierAccessor(new NonIdAnnotatedIdFieldEntity());
|
||||
|
||||
assertThat(identifierAccessor.getIdentifier()).isNotNull();
|
||||
assertThat(identifierAccessor.getIdentifier()).isEqualTo(123L);
|
||||
}
|
||||
|
||||
/**
|
||||
* <a href="https://jira.spring.io/browse/SGF-582">SGF-582</a>
|
||||
*/
|
||||
@Test
|
||||
public void identifierForNonIdAnnotatedEntityWithIdPropertyIsNotNull() {
|
||||
IdentifierAccessor identifierAccessor = getIdentifierAccessor(new NonIdAnnotatedIdGetterEntity());
|
||||
|
||||
assertThat(identifierAccessor).isNotNull();
|
||||
assertThat(identifierAccessor.getIdentifier()).isEqualTo(456L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void identifierForIdAnnotatedFieldAndPropertyEntityShouldNotConflict() {
|
||||
IdentifierAccessor identifierAccessor = getIdentifierAccessor(new IdAnnotatedFieldAndPropertyEntity());
|
||||
|
||||
assertThat(identifierAccessor).isNotNull();
|
||||
assertThat(identifierAccessor.getIdentifier()).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void identifierForAmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntityThrowsMappingException() {
|
||||
AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity entity
|
||||
= new AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity();
|
||||
|
||||
String expectedMessage = String.format("Attempt to add explicit id property [ssn] but already have id property [id] registered as explicit;"
|
||||
+ " Please check your object [%s] mapping configuration", entity.getClass().getName());
|
||||
|
||||
exception.expect(MappingException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(expectedMessage);
|
||||
|
||||
getIdentifierAccessor(new AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity());
|
||||
}
|
||||
|
||||
static class AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity {
|
||||
|
||||
@Id
|
||||
private Long id = 1L;
|
||||
|
||||
@Id
|
||||
public String getSsn() {
|
||||
return "123456789";
|
||||
}
|
||||
}
|
||||
|
||||
static class IdAnnotatedFieldAndPropertyEntity {
|
||||
|
||||
@Id
|
||||
private Long id = 1L;
|
||||
|
||||
@Id
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
||||
static class NonIdAnnotatedIdFieldEntity {
|
||||
private Long id = 123L;
|
||||
}
|
||||
|
||||
static class NonIdAnnotatedIdGetterEntity {
|
||||
public Long getId() {
|
||||
return 456L;
|
||||
}
|
||||
}
|
||||
|
||||
static class NonRegionAnnotatedEntity {
|
||||
}
|
||||
|
||||
@Region("Foo")
|
||||
static class AnnotatedRegion {}
|
||||
static class NamedRegionAnnotatedEntity {
|
||||
}
|
||||
|
||||
@Region
|
||||
static class UnnamedRegion {}
|
||||
|
||||
static @Data class NotAnnotationIdRegion {
|
||||
|
||||
private String value;
|
||||
private String id;
|
||||
static class UnnamedRegionAnnotatedEntity {
|
||||
}
|
||||
|
||||
@Region("Example")
|
||||
@@ -154,5 +229,4 @@ public class GemfirePersistentEntityUnitTests {
|
||||
return bigNumber;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -154,8 +154,7 @@ public class MappingPdxSerializerUnitTests {
|
||||
when(mockInstantiator.createInstance(any(GemfirePersistentEntity.class), any(ParameterValueProvider.class)))
|
||||
.thenReturn(person);
|
||||
|
||||
serializer.setGemfireInstantiators(Collections.<Class<?>, EntityInstantiator>singletonMap(
|
||||
Person.class, mockInstantiator));
|
||||
serializer.setGemfireInstantiators(Collections.singletonMap(Person.class, mockInstantiator));
|
||||
|
||||
serializer.fromData(Person.class, mockReader);
|
||||
|
||||
@@ -258,7 +257,7 @@ public class MappingPdxSerializerUnitTests {
|
||||
expectedException.expect(MappingException.class);
|
||||
expectedException.expectCause(isA(IllegalArgumentException.class));
|
||||
expectedException.expectMessage(String.format(
|
||||
"while serializing value [Portland, 12345] of property [address] for entity of type [%1$s] to PDX",
|
||||
"Error while serializing entity property [address] value [Portland, 12345] of type [%s] to PDX",
|
||||
Person.class));
|
||||
|
||||
new MappingPdxSerializer(context, conversionService).toData(jonDoe, mockWriter);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -107,6 +108,7 @@ public class Person implements Serializable {
|
||||
* @see #getFirstname()
|
||||
* @see #getLastname()
|
||||
*/
|
||||
@Transient
|
||||
public String getName() {
|
||||
return String.format("%1$s %2$s", getFirstname(), getLastname());
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ public class CollectionUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void addAllIterableElementsToList() {
|
||||
List<Integer> target = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
|
||||
Set<Integer> source = new HashSet<Integer>(Arrays.asList(1, 2, 3));
|
||||
List<Integer> target = new ArrayList<>(Arrays.asList(1, 2, 3));
|
||||
Set<Integer> source = new HashSet<>(Arrays.asList(1, 2, 3));
|
||||
|
||||
target = CollectionUtils.addAll(target, source);
|
||||
|
||||
@@ -75,8 +75,8 @@ public class CollectionUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void addAllIterableElementsToSet() {
|
||||
Set<Integer> target = new HashSet<Integer>(Arrays.asList(1, 2, 3));
|
||||
Set<Integer> source = new HashSet<Integer>(Arrays.asList(1, 2, 3, 4, 5));
|
||||
Set<Integer> target = new HashSet<>(Arrays.asList(1, 2, 3));
|
||||
Set<Integer> source = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
|
||||
|
||||
target = CollectionUtils.addAll(target, source);
|
||||
|
||||
@@ -96,9 +96,9 @@ public class CollectionUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void addEmptyIterableToCollection() {
|
||||
Collection<Integer> target = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
|
||||
Collection<Integer> target = new ArrayList<>(Arrays.asList(1, 2, 3));
|
||||
|
||||
target = CollectionUtils.addAll(target, Collections.<Integer>emptyList());
|
||||
target = CollectionUtils.addAll(target, Collections.emptyList());
|
||||
|
||||
assertThat(target).isNotNull();
|
||||
assertThat(target.size()).isEqualTo(3);
|
||||
@@ -107,7 +107,7 @@ public class CollectionUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void addNullIterableToCollection() {
|
||||
Collection<Integer> target = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
|
||||
Collection<Integer> target = new ArrayList<>(Arrays.asList(1, 2, 3));
|
||||
|
||||
target = CollectionUtils.addAll(target, null);
|
||||
|
||||
@@ -156,10 +156,30 @@ public class CollectionUtilsUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsAnyWithCollectionAndArrayIsTrue() {
|
||||
assertThat(CollectionUtils.containsAny(Arrays.asList(1, 2, 3), 1, 2)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsAnyWithCollectionAndArrayIsFalse() {
|
||||
assertThat(CollectionUtils.containsAny(Arrays.asList(1, 2, 3), 4)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsAnyWithCollectionAndNullArrayIsFalse() {
|
||||
assertThat(CollectionUtils.containsAny(Arrays.asList(1, 2, 3), (Object[]) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsAnyWithNullCollectionAndArrayIsFalse() {
|
||||
assertThat(CollectionUtils.containsAny(null, 1)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultIfEmptyWithNonNullNonEmptyIterableReturnsIterable() {
|
||||
Iterable<Object> iterable = Collections.<Object>singleton(1);
|
||||
Iterable<Object> defaultIterable = Collections.<Object>singleton(2);
|
||||
Iterable<Object> iterable = Collections.singleton(1);
|
||||
Iterable<Object> defaultIterable = Collections.singleton(2);
|
||||
|
||||
assertThat(CollectionUtils.defaultIfEmpty(iterable, defaultIterable)).isSameAs(iterable);
|
||||
}
|
||||
@@ -167,7 +187,7 @@ public class CollectionUtilsUnitTests {
|
||||
@Test
|
||||
public void defaultIfEmptyWithEmptyIterableReturnsDefault() {
|
||||
Iterable<Object> iterable = Collections.emptySet();
|
||||
Iterable<Object> defaultIterable = Collections.<Object>singleton(2);
|
||||
Iterable<Object> defaultIterable = Collections.singleton(2);
|
||||
|
||||
assertThat(CollectionUtils.defaultIfEmpty(iterable, defaultIterable)).isSameAs(defaultIterable);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user