SGF-759 - Add support for Include Filters to MappingPdxSerializer.

This commit is contained in:
John Blum
2018-06-10 22:56:59 -07:00
parent e1c167a0d5
commit 1d2f5af14b
3 changed files with 75 additions and 30 deletions

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.gemfire.mapping;
import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeAllTypesFilter.EXCLUDE_ALL_TYPES;
import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeComGemstoneGemFireTypesFilter.EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES;
import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeJavaTypesFilter.EXCLUDE_JAVA_TYPES;
import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeNullTypesFilter.EXCLUDE_NULL_TYPES;
@@ -186,17 +187,19 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
private EntityInstantiators entityInstantiators;
private Filter<Class<?>> excludeTypeFilters = EXCLUDE_NULL_TYPES
.and(EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES)
.and(EXCLUDE_JAVA_TYPES)
.and(EXCLUDE_ORG_SPRING_FRAMEWORK_TYPES);
private Filter<Class<?>> includeTypeFilters = EXCLUDE_ALL_TYPES;
private final GemfireMappingContext mappingContext;
private final Logger logger = LoggerFactory.getLogger(getClass());
private Map<?, PdxSerializer> customPdxSerializers;
private Filter typeFilters = EXCLUDE_NULL_TYPES
.and(EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES)
.and(EXCLUDE_JAVA_TYPES)
.and(EXCLUDE_ORG_SPRING_FRAMEWORK_TYPES);
// TODO: remove? SpELContext is not used
private SpELContext spelContext;
@@ -440,19 +443,40 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
}
/**
* Sets the {@link Filter type filters} used to filter {@link Class types} serializable
* Sets the {@link Filter type filters} used to exclude or filter {@link Class types} serializable
* by this {@link MappingPdxSerializer PDX serializer}.
*
* This operation is null-safe and rather than overriding the existing {@link Filter type filters},
* this set operation combines the given {@link Filter type filters} with
* the exiting {@link Filter type filters} joined by {@literal and}.
*
* @param typeFilters {@link Filter type filters} used to to filter {@link Class type} serializable
* @param typeFilters {@link Filter type filters} used to to exclude {@link Class types} serializable
* by this {@link MappingPdxSerializer PDX serializer}.
* @see org.springframework.data.gemfire.util.Filter
*/
public void setTypeFilters(Filter<Class<?>> typeFilters) {
this.typeFilters = typeFilters != null ? this.typeFilters.and(typeFilters) : this.typeFilters;
public void setExcludeTypeFilters(Filter<Class<?>> typeFilters) {
this.excludeTypeFilters = typeFilters != null
? this.excludeTypeFilters.and(typeFilters)
: this.excludeTypeFilters;
}
/**
* Sets the {@link Filter type filters} used to include or filter {@link Class types} serializable
* by this {@link MappingPdxSerializer PDX serializer}.
*
* This operation is null-safe and rather than overriding the existing {@link Filter type filters},
* this set operation combines the given {@link Filter type filters} with
* the exiting {@link Filter type filters} joined by {@literal or}.
*
* @param typeFilters {@link Filter type filters} used to to include {@link Class types} serializable
* by this {@link MappingPdxSerializer PDX serializer}.
* @see org.springframework.data.gemfire.util.Filter
*/
public void setIncludeTypeFilters(Filter<Class<?>> typeFilters) {
this.includeTypeFilters = typeFilters != null
? this.includeTypeFilters.or(typeFilters)
: this.includeTypeFilters;
}
/**
@@ -463,7 +487,7 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
* @see org.springframework.data.gemfire.util.Filter
*/
protected Filter<Class<?>> getTypeFilters() {
return this.typeFilters;
return this.excludeTypeFilters.or(EXCLUDE_NULL_TYPES.and(this.includeTypeFilters));
}
@Override
@@ -657,6 +681,16 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
return obj != null ? obj.getClass() : null;
}
public static class ExcludeAllTypesFilter extends org.springframework.data.gemfire.util.AbstractFilter<Class<?>> {
public static final Filter<Class<?>> EXCLUDE_ALL_TYPES = new ExcludeAllTypesFilter();
@Override
public boolean accept(Class<?> obj) {
return false;
}
}
public static class ExcludeComGemstoneGemFireTypesFilter extends org.springframework.data.gemfire.util.AbstractFilter<Class<?>> {
public static final Filter<Class<?>> EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES =

View File

@@ -51,6 +51,7 @@ import org.springframework.data.annotation.ReadOnlyProperty;
import org.springframework.data.annotation.Transient;
import org.springframework.data.gemfire.repository.sample.Address;
import org.springframework.data.gemfire.repository.sample.Person;
import org.springframework.data.gemfire.util.AbstractFilter;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -78,6 +79,14 @@ public class MappingPdxSerializerIntegrationTests {
MappingPdxSerializer serializer = MappingPdxSerializer.newMappingPdxSerializer();
serializer.setIncludeTypeFilters(new AbstractFilter<Class<?>>() {
@Override
public boolean accept(Class<?> type) {
return type.getPackage().getName().startsWith("org.springframework.data.gemfire");
}
});
cache = new CacheFactory()
.set("name", MappingPdxSerializerIntegrationTests.class.getSimpleName())
.set("log-level", "error")

View File

@@ -112,6 +112,19 @@ public class MappingPdxSerializerUnitTests {
this.pdxSerializer = spy(new MappingPdxSerializer(this.mappingContext, this.conversionService));
}
private Filter<Class<?>> includePackageTypesFilter(Class<?> type) {
final Package includeTypesInPackage = type.getPackage();
return new AbstractFilter<Class<?>>() {
@Override
public boolean accept(Class<?> type) {
return includeTypesInPackage.equals(type.getPackage());
}
};
}
private String toFullyQualifiedPropertyName(PersistentProperty<?> persistentProperty) {
return this.pdxSerializer.toFullyQualifiedPropertyName(persistentProperty);
}
@@ -557,6 +570,7 @@ public class MappingPdxSerializerUnitTests {
this.pdxSerializer.setCustomPdxSerializers(Collections.singletonMap(Address.class, mockAddressSerializer));
this.pdxSerializer.setGemfireInstantiators(
Collections.<Class<?>, EntityInstantiator>singletonMap(Person.class, this.mockInstantiator));
this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class));
Object obj = this.pdxSerializer.fromData(Person.class, this.mockReader);
@@ -590,6 +604,7 @@ public class MappingPdxSerializerUnitTests {
try {
this.pdxSerializer.setGemfireInstantiators(
Collections.<Class<?>, EntityInstantiator>singletonMap(Person.class, this.mockInstantiator));
this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class));
this.pdxSerializer.fromData(Person.class, this.mockReader);
}
catch (MappingException expected) {
@@ -631,6 +646,7 @@ public class MappingPdxSerializerUnitTests {
this.pdxSerializer.setCustomPdxSerializers(Collections.singletonMap(Address.class, mockAddressSerializer));
this.pdxSerializer.setGemfireInstantiators(
Collections.<Class<?>, EntityInstantiator>singletonMap(Person.class, this.mockInstantiator));
this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class));
this.pdxSerializer.fromData(Person.class, this.mockReader);
GemfirePersistentEntity<?> persistentEntity = this.mappingContext.getPersistentEntity(Person.class);
@@ -645,15 +661,7 @@ public class MappingPdxSerializerUnitTests {
@Test
public void fromDataWithTypeFilterAcceptsApplicationDomainTypes() {
Filter<Class<?>> packageBasedTypeFilter = new AbstractFilter<Class<?>>() {
@Override
public boolean accept(Class<?> type) {
return type != null && User.class.getPackage().equals(type.getPackage());
}
};
this.pdxSerializer.setTypeFilters(packageBasedTypeFilter);
this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(User.class));
doReturn("test").when(this.pdxSerializer).doFromData(any(Class.class), any(PdxReader.class));
@@ -684,7 +692,7 @@ public class MappingPdxSerializerUnitTests {
}
};
this.pdxSerializer.setTypeFilters(applicationDomainTypeFilter);
this.pdxSerializer.setExcludeTypeFilters(applicationDomainTypeFilter);
assertThat(this.pdxSerializer.fromData(ApplicationDomainType.class, this.mockReader)).isNull();
}
@@ -715,6 +723,7 @@ public class MappingPdxSerializerUnitTests {
jonDoe.address = address;
this.pdxSerializer.setCustomPdxSerializers(Collections.singletonMap(Address.class, mockAddressSerializer));
this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class));
assertThat(this.pdxSerializer.toData(jonDoe, this.mockWriter)).isTrue();
@@ -750,6 +759,7 @@ public class MappingPdxSerializerUnitTests {
try {
this.pdxSerializer.setCustomPdxSerializers(Collections.<Object, PdxSerializer>emptyMap());
this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class));
this.pdxSerializer.toData(jonDoe, this.mockWriter);
}
catch (MappingException expected) {
@@ -803,7 +813,7 @@ public class MappingPdxSerializerUnitTests {
}
};
this.pdxSerializer.setTypeFilters(applicationDomainTypeFilter);
this.pdxSerializer.setExcludeTypeFilters(applicationDomainTypeFilter);
assertThat(this.pdxSerializer.toData(new ApplicationDomainType(), this.mockWriter)).isFalse();
}
@@ -815,15 +825,7 @@ public class MappingPdxSerializerUnitTests {
new org.springframework.data.gemfire.test.model.Person("Jon", "Doe",
null, Gender.MALE);
Filter<Class<?>> packageBasedTypeFilter = new AbstractFilter<Class<?>>() {
@Override
public boolean accept(Class<?> type) {
return type != null && User.class.getPackage().equals(type.getPackage());
}
};
this.pdxSerializer.setTypeFilters(packageBasedTypeFilter);
this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(User.class));
doReturn(true).when(this.pdxSerializer).doToData(any(), any(PdxWriter.class));