diff --git a/spring-geode/src/main/java/org/springframework/geode/data/json/converter/support/JSONFormatterPdxToJsonConverter.java b/spring-geode/src/main/java/org/springframework/geode/data/json/converter/support/JSONFormatterPdxToJsonConverter.java new file mode 100644 index 00000000..6bd12de0 --- /dev/null +++ b/spring-geode/src/main/java/org/springframework/geode/data/json/converter/support/JSONFormatterPdxToJsonConverter.java @@ -0,0 +1,75 @@ +/* + * Copyright 2020 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.geode.data.json.converter.support; + +import java.util.Optional; + +import org.apache.geode.pdx.JSONFormatter; +import org.apache.geode.pdx.PdxInstance; + +import org.springframework.geode.data.json.converter.ObjectToJsonConverter; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; + +/** + * An {@link ObjectToJsonConverter} implementation using the Apache Geode {@link JSONFormatter} to convert + * from a {@link PdxInstance} to a {@literal JSON} {@link String}. + * + * @author John Blum + * @see org.apache.geode.pdx.JSONFormatter + * @see org.apache.geode.pdx.PdxInstance + * @see org.springframework.geode.data.json.converter.ObjectToJsonConverter + * @see org.springframework.geode.data.json.converter.support.JacksonObjectToJsonConverter + * @since 1.3.0 + */ +public class JSONFormatterPdxToJsonConverter extends JacksonObjectToJsonConverter { + + /** + * @inheritDoc + */ + @Nullable @Override + public final String convert(@Nullable Object source) { + + return Optional.ofNullable(source) + .filter(PdxInstance.class::isInstance) + .map(PdxInstance.class::cast) + .map(this::convertPdxToJson) + .orElseGet(() -> convertObjectToJson(source)); + } + + /** + * Converts the given {@link Object} to JSON. + * + * @param source {@link Object} to convert to JSON. + * @return the JSON generated from the given {@link Object}. + * @see JacksonObjectToJsonConverter#convert(Object) + */ + protected @Nullable String convertObjectToJson(Object source) { + return super.convert(source); + } + + /** + * Converts the given {@link PdxInstance PDX} to JSON. + * + * @param pdxInstance {@link PdxInstance} to convert to JSON; must not be {@literal null}. + * @return JSON generated from the given {@link PdxInstance}. + * @see org.apache.geode.pdx.JSONFormatter#toJSON(PdxInstance) + * @see org.apache.geode.pdx.PdxInstance + */ + protected @NonNull String convertPdxToJson(@NonNull PdxInstance pdxInstance) { + return JSONFormatter.toJSON(pdxInstance); + } +} diff --git a/spring-geode/src/test/java/org/springframework/geode/data/json/converter/support/JSONFormatterPdxToJsonConverterUnitTests.java b/spring-geode/src/test/java/org/springframework/geode/data/json/converter/support/JSONFormatterPdxToJsonConverterUnitTests.java new file mode 100644 index 00000000..da284ee8 --- /dev/null +++ b/spring-geode/src/test/java/org/springframework/geode/data/json/converter/support/JSONFormatterPdxToJsonConverterUnitTests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2020 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.geode.data.json.converter.support; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; + +import org.junit.Test; + +import org.apache.geode.pdx.PdxInstance; + +/** + * Unit Tests for {@link JSONFormatterPdxToJsonConverter}. + * + * @author John Blum + * @see org.junit.Test + * @see org.mockito.Mockito + * @see org.apache.geode.pdx.PdxInstance + * @see org.springframework.geode.data.json.converter.support.JSONFormatterPdxToJsonConverter + * @since 1.3.0 + */ +public class JSONFormatterPdxToJsonConverterUnitTests { + + @Test + public void convertsObjectToJson() { + + String json = "{ \"name\": \"Jason Doe\" }"; + + Object object = new Object(); + + JSONFormatterPdxToJsonConverter converter = spy(new JSONFormatterPdxToJsonConverter()); + + doReturn(json).when(converter).convertObjectToJson(eq(object)); + + assertThat(converter.convert(object)).isEqualTo(json); + + verify(converter, times(1)).convertObjectToJson(eq(object)); + verify(converter, never()).convertPdxToJson(any()); + } + + @Test + public void convertsPdxInstanceToJson() { + + String json = "{ \"name\": \"Jon Doe\" }"; + + PdxInstance mockPdxInstance = mock(PdxInstance.class); + + JSONFormatterPdxToJsonConverter converter = spy(new JSONFormatterPdxToJsonConverter()); + + doReturn(json).when(converter).convertPdxToJson(eq(mockPdxInstance)); + + assertThat(converter.convertPdxToJson(mockPdxInstance)).isEqualTo(json); + + verify(converter, times(1)).convertPdxToJson(eq(mockPdxInstance)); + verify(converter, never()).convertObjectToJson(any()); + verifyNoInteractions(mockPdxInstance); + } +}