diff --git a/src/main/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdvice.java b/src/main/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdvice.java index 75edd7df..1838b91a 100644 --- a/src/main/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdvice.java +++ b/src/main/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdvice.java @@ -20,19 +20,26 @@ import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeList import static org.springframework.data.gemfire.util.RegionUtils.toRegionName; import static org.springframework.data.gemfire.util.RegionUtils.toRegionPath; +import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.stream.Collectors; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.geode.cache.Region; import org.apache.geode.cache.query.SelectResults; +import org.apache.geode.cache.query.types.CollectionType; +import org.apache.geode.cache.query.types.ObjectType; import org.apache.geode.pdx.JSONFormatter; import org.apache.geode.pdx.PdxInstance; @@ -261,13 +268,13 @@ public class JSONRegionAdvice { if (returnValue instanceof SelectResults && this.convertReturnedCollections) { - Collection results = new ArrayList<>(); + List results = new ArrayList<>(); for (Object obj : (SelectResults) returnValue) { results.add(convertToJson(obj)); } - returnValue = results; + returnValue = new ImmutableSelectResults<>(results); } else { returnValue = convertToJson(returnValue); @@ -280,10 +287,10 @@ public class JSONRegionAdvice { catch (Throwable cause) { handleThrowable(cause); } + return returnValue; } - private boolean isIncludedJsonRegion(Object target) { return target instanceof Region && isIncludedJsonRegion((Region) target); } @@ -367,4 +374,53 @@ public class JSONRegionAdvice { throw new RuntimeException(cause); } } + + private static final class ImmutableSelectResults extends AbstractCollection implements SelectResults { + + private final List results; + + private ImmutableSelectResults(List results) { + this.results = new ArrayList<>(results); + } + + @Override + public List asList() { + return Collections.unmodifiableList(this.results); + } + + @Override + public Set asSet() { + return new HashSet<>(this.results); + } + + @Override + public void setElementType(ObjectType elementType) { + throw new UnsupportedOperationException("Setting element type on an immutable SelectResults object is not supported"); + } + + @Override + public CollectionType getCollectionType() { + throw new UnsupportedOperationException("Not Implemented"); + } + + @Override + public boolean isModifiable() { + return false; + } + + @Override + public Iterator iterator() { + return asList().iterator(); + } + + @Override + public int occurrences(T element) { + return Long.valueOf(asList().stream().filter(item -> item.equals(element)).count()).intValue(); + } + + @Override + public int size() { + return this.results.size(); + } + } } diff --git a/src/main/java/org/springframework/data/gemfire/support/AbstractFactoryBeanSupport.java b/src/main/java/org/springframework/data/gemfire/support/AbstractFactoryBeanSupport.java index f0545d1b..be61fb94 100644 --- a/src/main/java/org/springframework/data/gemfire/support/AbstractFactoryBeanSupport.java +++ b/src/main/java/org/springframework/data/gemfire/support/AbstractFactoryBeanSupport.java @@ -18,9 +18,6 @@ package org.springframework.data.gemfire.support; import java.util.Optional; import java.util.function.Supplier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; @@ -28,6 +25,9 @@ import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.FactoryBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * The {@link AbstractFactoryBeanSupport} class is an abstract Spring {@link FactoryBean} base class implementation * encapsulating operations common to SDG's {@link FactoryBean} implementations. diff --git a/src/test/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdviceIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdviceIntegrationTests.java index 44dab50e..acd692ff 100644 --- a/src/test/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdviceIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/serialization/json/JSONRegionAdviceIntegrationTests.java @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.serialization.json; import static org.junit.Assert.assertEquals; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; -import java.io.IOException; import java.util.Arrays; import java.util.Map; @@ -28,13 +26,13 @@ import javax.annotation.Resource; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.query.SelectResults; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.query.SelectResults; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.gemfire.GemfireOperations; import org.springframework.data.gemfire.repository.sample.Person; @@ -66,6 +64,7 @@ public class JSONRegionAdviceIntegrationTests { @Autowired private GemfireOperations template; + @SuppressWarnings("rawtypes") @Resource(name = "JsonRegion") private Region jsonRegion; @@ -116,7 +115,7 @@ public class JSONRegionAdviceIntegrationTests { } @Test - public void objectToJSon() throws IOException { + public void objectToJSon() { Person davidTuranski = new Person(1L, "David", "Turanski");