This is an automated email from the ASF dual-hosted git repository.
bschuchardt pushed a commit to branch feature/GEODE-6196
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/feature/GEODE-6196 by this
push:
new efa4757 removed TypedJson, replacing with QueryResultFormatter
efa4757 is described below
commit efa4757126a7e642fd87f4c7ab6a227fa9f81d28
Author: Bruce Schuchardt <[email protected]>
AuthorDate: Tue Mar 5 15:13:34 2019 -0800
removed TypedJson, replacing with QueryResultFormatter
most of TypedJson's internals were replaced so I just renamed it to
QueryResultFormatter to better show its intended purpose.
Object traversal depth is now limited to the element-count being passed
by the QueryDataFunction function. This will prevent the stack-overflow
problems seen in GEODE-1842.
---
.../geode/tools/pulse/PulseDataExportTest.java | 2 +-
... QueryResultFormatterQueryIntegrationTest.java} | 40 +-
.../management/DataQueryEngineIntegrationTest.java | 14 +-
...=> QueryResultFormatterPdxIntegrationTest.java} | 18 +-
.../internal/beans/QueryDataFunction.java | 4 +-
.../internal/cli/json/QueryResultFormatter.java | 447 +++++++++++++++++++++
.../management/internal/cli/json/TypedJson.java | 359 -----------------
...JsonTest.java => QueryResultFormatterTest.java} | 56 +--
8 files changed, 517 insertions(+), 423 deletions(-)
diff --git
a/geode-assembly/src/integrationTest/java/org/apache/geode/tools/pulse/PulseDataExportTest.java
b/geode-assembly/src/integrationTest/java/org/apache/geode/tools/pulse/PulseDataExportTest.java
index 5fb6cfa..9b1b81c 100644
---
a/geode-assembly/src/integrationTest/java/org/apache/geode/tools/pulse/PulseDataExportTest.java
+++
b/geode-assembly/src/integrationTest/java/org/apache/geode/tools/pulse/PulseDataExportTest.java
@@ -57,6 +57,6 @@ public class PulseDataExportTest {
.hasStatusCode(200)
.hasResponseBody()
.isEqualToIgnoringWhitespace(
-
"{\"result\":[[\"java.lang.String\",\"value1\"],[\"java.lang.String\",\"value2\"],[\"java.lang.String\",\"value3\"]]}");
+
"{\"result\":[[\"[Lorg.apache.geode.management.model.SubOrder;\",[[\"org.apache.geode.management.model.SubOrder\",{\"id\":\"null1\",\"items\":[\"java.util.ArrayList\",[]]}],null]]]}");
}
}
diff --git
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/TypedJsonQueryIntegrationTest.java
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/QueryResultFormatterQueryIntegrationTest.java
similarity index 65%
rename from
geode-core/src/integrationTest/java/org/apache/geode/cache/query/TypedJsonQueryIntegrationTest.java
rename to
geode-core/src/integrationTest/java/org/apache/geode/cache/query/QueryResultFormatterQueryIntegrationTest.java
index 82ffada..1e9373c 100644
---
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/TypedJsonQueryIntegrationTest.java
+++
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/QueryResultFormatterQueryIntegrationTest.java
@@ -24,21 +24,21 @@ import org.apache.geode.cache.query.data.Position;
import org.apache.geode.cache.util.ObjectSizer;
import org.apache.geode.management.internal.cli.json.GfJsonException;
import org.apache.geode.management.internal.cli.json.GfJsonObject;
-import org.apache.geode.management.internal.cli.json.TypedJson;
-import
org.apache.geode.management.internal.cli.json.TypedJsonPdxIntegrationTest;
+import org.apache.geode.management.internal.cli.json.QueryResultFormatter;
+import
org.apache.geode.management.internal.cli.json.QueryResultFormatterPdxIntegrationTest;
import org.apache.geode.test.junit.categories.OQLQueryTest;
/**
- * Integration tests for {@link TypedJson} querying {@link Portfolio}.
+ * Integration tests for {@link QueryResultFormatter} querying {@link
Portfolio}.
* <p>
*
- * Extracted from {@link TypedJsonPdxIntegrationTest}.
+ * Extracted from {@link QueryResultFormatterPdxIntegrationTest}.
* <p>
*
* TODO: add real assertions
*/
@Category({OQLQueryTest.class})
-public class TypedJsonQueryIntegrationTest {
+public class QueryResultFormatterQueryIntegrationTest {
private static final String RESULT = "result";
@@ -46,18 +46,19 @@ public class TypedJsonQueryIntegrationTest {
public void testUserObject() throws Exception {
Portfolio p = new Portfolio(2);
- TypedJson typedJson = new TypedJson(RESULT, p, 100);
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, p);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
public void testUserObjectArray() throws Exception {
Portfolio[] portfolios = createPortfoliosAndPositions(2);
- TypedJson typedJson = new TypedJson(RESULT, portfolios, 100);
+ QueryResultFormatter queryResultFormatter =
+ new QueryResultFormatter(100).add(RESULT, portfolios);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
@@ -65,24 +66,25 @@ public class TypedJsonQueryIntegrationTest {
Portfolio[] portfolios = createPortfoliosAndPositions(1000);
System.out.println("Size Of port " +
ObjectSizer.REFLECTION_SIZE.sizeof(portfolios));
- TypedJson typedJson = new TypedJson(RESULT, portfolios, 100);
- System.out.println("Size Of json " +
ObjectSizer.REFLECTION_SIZE.sizeof(typedJson));
+ QueryResultFormatter queryResultFormatter =
+ new QueryResultFormatter(100).add(RESULT, portfolios);
+ System.out.println("Size Of json " +
ObjectSizer.REFLECTION_SIZE.sizeof(queryResultFormatter));
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
public void testQueryLike() throws Exception {
Portfolio[] portfolios = createPortfoliosAndPositions(2);
- TypedJson typedJson = new TypedJson(RESULT, null, 100);
- typedJson.add("member", "server1");
- // checkResult(typedJson); -- fails
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, null);
+ queryResultFormatter.add("member", "server1");
+ // checkResult(queryResultFormatter); -- fails
for (int i = 0; i < 2; i++) {
- typedJson.add(RESULT, portfolios[i]);
+ queryResultFormatter.add(RESULT, portfolios[i]);
}
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
private Portfolio[] createPortfoliosAndPositions(final int count) {
@@ -94,8 +96,8 @@ public class TypedJsonQueryIntegrationTest {
return portfolios;
}
- private void checkResult(final TypedJson typedJson) throws GfJsonException {
- GfJsonObject gfJsonObject = new GfJsonObject(typedJson.toString());
+ private void checkResult(final QueryResultFormatter queryResultFormatter)
throws GfJsonException {
+ GfJsonObject gfJsonObject = new
GfJsonObject(queryResultFormatter.toString());
System.out.println(gfJsonObject);
assertThat(gfJsonObject.get(RESULT)).isNotNull();
}
diff --git
a/geode-core/src/integrationTest/java/org/apache/geode/management/DataQueryEngineIntegrationTest.java
b/geode-core/src/integrationTest/java/org/apache/geode/management/DataQueryEngineIntegrationTest.java
index daf69fa..43be476 100644
---
a/geode-core/src/integrationTest/java/org/apache/geode/management/DataQueryEngineIntegrationTest.java
+++
b/geode-core/src/integrationTest/java/org/apache/geode/management/DataQueryEngineIntegrationTest.java
@@ -98,7 +98,7 @@ public class DataQueryEngineIntegrationTest {
region.put("order1", order);
String expectedResult =
-
"{\"result\":[[\"org.apache.geode.management.model.Order\",{\"items\":[\"java.util.Collection\",{\"0\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":[\"java.lang.String\",\"Book\"],\"itemId\":[\"java.lang.String\",\"ID_1\"],\"order\":[\"org.apache.geode.management.model.Order\",\"org.apache.geode.management.model.Order\"]}],\"1\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":[\"java.lang.String\",\"Book\"],\"itemId\":[\"java.lang.String\",\"I
[...]
+
"{\"result\":[[\"org.apache.geode.management.model.Order\",{\"id\":\"test\",\"items\":[\"java.util.ArrayList\",{\"0\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":\"Book\",\"itemId\":\"ID_1\",\"order\":\"duplicate
org.apache.geode.management.model.Order\"}],\"1\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":\"Book\",\"itemId\":\"ID_2\",\"order\":\"duplicate
org.apache.geode.management.model.Order\"}],\"2\":[\"org.apache.geode.management.mod
[...]
Object result = queryEngine.queryForJsonResult(QUERY_1, 0,
queryResultSetLimit,
queryCollectionsDepth);
String queryResult = (String) result;
@@ -131,7 +131,7 @@ public class DataQueryEngineIntegrationTest {
queryCollectionsDepth);
String expectedResult =
-
"{\"result\":[[\"org.apache.geode.management.model.Order\",{\"items\":[\"java.util.Collection\",{\"0\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":[\"java.lang.String\",\"Book\"],\"itemId\":[\"java.lang.String\",\"ID_1\"],\"order\":[\"org.apache.geode.management.model.Order\",{\"items\":[\"java.util.Collection\",{}],\"id\":[\"java.lang.String\",\"ORDER_ID_1\"]}]}],\"1\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":[\"java.lang.String\",\"B
[...]
+
"{\"result\":[[\"org.apache.geode.management.model.Order\",{\"id\":\"test\",\"items\":[\"java.util.ArrayList\",{\"0\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":\"Book\",\"itemId\":\"ID_1\",\"order\":[\"org.apache.geode.management.model.Order\",{\"id\":\"ORDER_ID_1\",\"items\":[\"java.util.ArrayList\",{}]}]}],\"1\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":\"Book\",\"itemId\":\"ID_2\",\"order\":[\"org.apache.geode.management.model.Orde
[...]
assertThat(queryResult).isEqualToIgnoringWhitespace(expectedResult);
// If not correct JSON format this will throw a JSONException
@@ -161,7 +161,7 @@ public class DataQueryEngineIntegrationTest {
String queryResult = queryEngine.queryForJsonResult(QUERY_1, 0,
queryResultSetLimit,
queryCollectionsDepth);
String expectedResult =
-
"{\"result\":[[\"org.apache.geode.management.model.Order\",{\"items\":[\"java.util.Collection\",{\"0\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":[\"java.lang.String\",\"Book\"],\"itemId\":[\"java.lang.String\",\"ID_1\"],\"order\":[\"org.apache.geode.management.model.Order\",{\"items\":[\"java.util.Collection\",\"java.util.ArrayList\"],\"id\":[\"java.lang.String\",\"ORDER_ID_1\"]}]}],\"1\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":[\"j
[...]
+
"{\"result\":[[\"org.apache.geode.management.model.Order\",{\"id\":\"ORDER_TEST\",\"items\":[\"java.util.ArrayList\",{\"0\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":\"Book\",\"itemId\":\"ID_1\",\"order\":[\"org.apache.geode.management.model.Order\",{\"id\":\"ORDER_ID_1\",\"items\":[\"java.util.ArrayList\",{\"0\":\"duplicate
org.apache.geode.management.model.Item\",\"1\":[\"org.apache.geode.management.model.Item\",{\"itemDescription\":\"Book\",\"itemId\":\"
[...]
assertThat(queryResult).isEqualToIgnoringWhitespace(expectedResult);
// If not correct JSON format this will throw a JSONException
@@ -277,7 +277,7 @@ public class DataQueryEngineIntegrationTest {
String queryResult = queryEngine.queryForJsonResult(QUERY_1, 0,
queryResultSetLimit,
queryCollectionsDepth);
String expectedResult =
-
"{\"result\":[[\"org.apache.geode.management.model.SubOrder\",{\"items\":[\"java.util.Collection\",{}],\"id\":[\"java.lang.String\",\"null1\"]}]]}";
+
"{\"result\":[[\"org.apache.geode.management.model.SubOrder\",{\"id\":\"null1\",\"items\":[\"java.util.ArrayList\",{}]}]]}";
assertThat(queryResult).isEqualToIgnoringWhitespace(expectedResult);
// If not correct JSON format this will throw a JSONException
@@ -300,7 +300,7 @@ public class DataQueryEngineIntegrationTest {
String queryResult = queryEngine.queryForJsonResult(QUERY_1, 0,
queryResultSetLimit,
queryCollectionsDepth);
String expectedResult =
-
"{\"result\":[[\"org.apache.geode.pdx.PdxInstance\",{\"ID\":[\"java.lang.Integer\",111],\"status\":[\"java.lang.String\",\"active\"],\"secId\":[\"java.lang.String\",\"IBM\"]}]]}";
+
"{\"result\":[[\"org.apache.geode.pdx.internal.PdxInstanceImpl\",{\"ID\":111,\"status\":\"active\",\"secId\":\"IBM\"}]]}";
assertThat(queryResult).isEqualToIgnoringWhitespace(expectedResult);
// If not correct JSON format this will throw a JSONException
@@ -318,7 +318,7 @@ public class DataQueryEngineIntegrationTest {
String queryResult = queryEngine.queryForJsonResult(QUERY_1, 0,
queryResultSetLimit,
queryCollectionsDepth);
String expectedResult =
-
"{\"result\":[[\"org.apache.geode.management.model.SubOrder[]\",[{\"items\":[\"java.util.Collection\",{}],\"id\":[\"java.lang.String\",\"null1\"]},null]]]}";
+
"{\"result\":[[\"[Lorg.apache.geode.management.model.SubOrder;\",[[\"org.apache.geode.management.model.SubOrder\",{\"id\":\"null1\",\"items\":[\"java.util.ArrayList\",{}]}],null]]]}";
assertThat(queryResult).isEqualToIgnoringWhitespace(expectedResult);
// If not correct JSON format this will throw a JSONException
@@ -336,7 +336,7 @@ public class DataQueryEngineIntegrationTest {
String queryResult = queryEngine.queryForJsonResult(QUERY_1, 0,
queryResultSetLimit,
queryCollectionsDepth);
String expectedResult =
-
"{\"result\":[[\"org.apache.geode.management.model.SubOrder[]\",[{\"items\":[\"java.util.Collection\",{}],\"id\":[\"java.lang.String\",\"null1\"]},null]]]}";
+
"{\"result\":[[\"[Lorg.apache.geode.management.model.SubOrder;\",[[\"org.apache.geode.management.model.SubOrder\",{\"id\":\"null1\",\"items\":[\"java.util.ArrayList\",{}]}],null]]]}";
assertThat(queryResult).isEqualToIgnoringWhitespace(expectedResult);
// If not correct JSON format this will throw a JSONException
diff --git
a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/json/TypedJsonPdxIntegrationTest.java
b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/json/QueryResultFormatterPdxIntegrationTest.java
similarity index 85%
rename from
geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/json/TypedJsonPdxIntegrationTest.java
rename to
geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/json/QueryResultFormatterPdxIntegrationTest.java
index ab93adc..dfe9f8c 100644
---
a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/json/TypedJsonPdxIntegrationTest.java
+++
b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/json/QueryResultFormatterPdxIntegrationTest.java
@@ -34,12 +34,12 @@ import org.apache.geode.pdx.PdxInstanceFactory;
import org.apache.geode.pdx.internal.PdxInstanceFactoryImpl;
/**
- * Integration tests for {@link TypedJson}.
+ * Integration tests for {@link QueryResultFormatter}.
* <p>
*
* TODO: add actual assertions
*/
-public class TypedJsonPdxIntegrationTest {
+public class QueryResultFormatterPdxIntegrationTest {
private static final String RESULT = "result";
@@ -71,9 +71,10 @@ public class TypedJsonPdxIntegrationTest {
pdxInstanceFactory.writeObject("object", new SerializableObject(2));
PdxInstance pdxInstance = pdxInstanceFactory.create();
- TypedJson typedJson = new TypedJson(RESULT, pdxInstance, 100);
+ QueryResultFormatter queryResultFormatter =
+ new QueryResultFormatter(100).add(RESULT, pdxInstance);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
@@ -83,13 +84,14 @@ public class TypedJsonPdxIntegrationTest {
pdxInstanceFactory.writeString("secId", "IBM");
PdxContainer pdxContainer = new PdxContainer(pdxInstanceFactory.create(),
1);
- TypedJson typedJson = new TypedJson(RESULT, pdxContainer, 100);
+ QueryResultFormatter queryResultFormatter =
+ new QueryResultFormatter(100).add(RESULT, pdxContainer);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
- private void checkResult(TypedJson typedJson) throws GfJsonException {
- GfJsonObject gfJsonObject = new GfJsonObject(typedJson.toString());
+ private void checkResult(QueryResultFormatter queryResultFormatter) throws
GfJsonException {
+ GfJsonObject gfJsonObject = new
GfJsonObject(queryResultFormatter.toString());
System.out.println(gfJsonObject);
assertThat(gfJsonObject.get(RESULT)).isNotNull();
}
diff --git
a/geode-core/src/main/java/org/apache/geode/management/internal/beans/QueryDataFunction.java
b/geode-core/src/main/java/org/apache/geode/management/internal/beans/QueryDataFunction.java
index 809e724..9b1fb91 100644
---
a/geode-core/src/main/java/org/apache/geode/management/internal/beans/QueryDataFunction.java
+++
b/geode-core/src/main/java/org/apache/geode/management/internal/beans/QueryDataFunction.java
@@ -43,7 +43,7 @@ import
org.apache.geode.internal.cache.PartitionedRegionHelper;
import org.apache.geode.internal.cache.execute.InternalFunction;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.management.internal.ManagementConstants;
-import org.apache.geode.management.internal.cli.json.TypedJson;
+import org.apache.geode.management.internal.cli.json.QueryResultFormatter;
/**
* This function is executed on one or multiple members based on the member
input to
@@ -118,7 +118,7 @@ public class QueryDataFunction implements Function,
InternalEntity {
queryString = applyLimitClause(queryString, limit, queryResultSetLimit);
try {
- TypedJson result = new TypedJson(queryCollectionsDepth);
+ QueryResultFormatter result = new
QueryResultFormatter(queryCollectionsDepth);
Region region = cache.getRegion(regionName);
diff --git
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/QueryResultFormatter.java
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/QueryResultFormatter.java
new file mode 100644
index 0000000..935f1d7
--- /dev/null
+++
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/QueryResultFormatter.java
@@ -0,0 +1,447 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional
information regarding
+ * copyright ownership. The ASF licenses this file to You 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
+ *
+ * http://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.apache.geode.management.internal.cli.json;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonStreamContext;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.type.WritableTypeId;
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
+import com.fasterxml.jackson.databind.ser.PropertyWriter;
+import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.query.internal.StructImpl;
+import org.apache.geode.pdx.PdxInstance;
+
+/**
+ * A JSON serializer that has special handling for collections to limit the
number of elements
+ * written to the document. It also has special handling for PdxInstance and
query Structs.
+ */
+public class QueryResultFormatter {
+
+ private final ObjectMapper mapper;
+ private final SimpleModule mapperModule;
+
+ /**
+ * map contains the named objects to be serialized
+ */
+ private final Map<String, List<Object>> map;
+
+ /**
+ * serializedObjects is used to prevent recursive serialization in cases
where
+ * there are cyclical references
+ */
+ private final Map<Object, Object> serializedObjects;
+
+ /**
+ * Create a formatter that will limit collection sizes to
maxCollectionElements
+ * and will limit object traversal to being the same but in depth.
+ *
+ * @param maxCollectionElements limit on collection elements and depth-first
object traversal
+ */
+ public QueryResultFormatter(int maxCollectionElements) {
+ this(maxCollectionElements, maxCollectionElements);
+ }
+
+ /**
+ * Create a formatter that will limit collection sizes to
maxCollectionElements
+ *
+ * @param maxCollectionElements limit on collection elements
+ * @param serializationDepth when traversing objects, how deep should we go?
+ */
+ public QueryResultFormatter(int maxCollectionElements, int
serializationDepth) {
+ this.map = new LinkedHashMap<>();
+
+ this.serializedObjects = new IdentityHashMap<>();
+ this.mapper = new ObjectMapper();
+ this.mapperModule = new SimpleModule() {
+ @Override
+ public void setupModule(SetupContext context) {
+ // install a modifier that prevents recursive serialization in cases
where
+ // there are cyclical references
+ super.setupModule(context);
+ context.addBeanSerializerModifier(new BeanSerializerModifier() {
+ @Override
+ public JsonSerializer<?> modifySerializer(
+ SerializationConfig config, BeanDescription desc,
JsonSerializer<?> serializer) {
+ return new PreventReserializationSerializer(serializer,
serializedObjects,
+ serializationDepth);
+ }
+ });
+ }
+ };
+ // insert a collection serializer that limits the number of elements
generated
+ mapperModule.addSerializer(Collection.class, new
CollectionSerializer(maxCollectionElements));
+ // insert a PdxInstance serializer that knows about PDX fields/values
+ mapperModule.addSerializer(PdxInstance.class, new PdxInstanceSerializer());
+ // insert a Struct serializer that knows about its format
+ mapperModule.addSerializer(StructImpl.class, new StructSerializer());
+ // insert a RegionEntry serializer because they're too messy looking
+ mapperModule.addSerializer(Region.Entry.class, new
RegionEntrySerializer());
+
+ // mapper.setFilterProvider(new
SimpleFilterProvider().setDefaultFilter(new DepthFilter(4)));
+ mapper.registerModule(mapperModule);
+
+ // allow objects with no content
+ mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
+ // use toString on Enums
+ mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
+ // sort fields alphabetically
+ mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
+ // add type information (Jackson has no way to force it to do this for all
values)
+ mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+
+ }
+
+ /**
+ * After instantiating a formatter add the objects you want to be formatted
+ * using this method. Typically this will be add("result", queryResult)
+ */
+ public QueryResultFormatter add(String key, Object value) {
+ List<Object> list = this.map.get(key);
+ if (list != null) {
+ list.add(value);
+ } else {
+ list = new ArrayList<>();
+ if (value != null) {
+ list.add(value);
+ }
+ this.map.put(key, list);
+ }
+ return this;
+ }
+
+ /* non-javadoc use Jackson to serialize added objects into JSON format */
+ @Override
+ public String toString() {
+ StringWriter w = new StringWriter();
+ synchronized (w.getBuffer()) {
+ try {
+ return this.write(w).toString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ }
+
+
+ private Writer write(Writer writer) throws GfJsonException {
+ try {
+ boolean addComma = false;
+
+ writer.write('{');
+ for (Map.Entry<String, List<Object>> entry : this.map.entrySet()) {
+ if (addComma) {
+ writer.write(',');
+ }
+ mapper.writerFor(entry.getKey().getClass()).writeValue(writer,
entry.getKey());
+ writer.write(':');
+ writeList(writer, entry.getValue());
+ addComma = true;
+ }
+ writer.write('}');
+
+ return writer;
+ } catch (IOException exception) {
+ throw new GfJsonException(exception);
+ }
+ }
+
+ private Writer writeList(Writer writer, List<Object> values) throws
GfJsonException {
+ // for each object we clear out the serializedObjects recursion map so that
+ // we don't immediately see "duplicate" entries
+ serializedObjects.clear();
+ try {
+ boolean addComma = false;
+ int length = values.size();
+ writer.write('[');
+
+ if (length == 0) {
+ mapper.writeValue(writer, null);
+ } else {
+ for (int i = 0; i < length; i += 1) {
+ if (addComma) {
+ writer.write(',');
+ }
+ mapper.writerFor(values.get(i).getClass()).writeValue(writer,
values.get(i));
+
+ addComma = true;
+ }
+ }
+ writer.write(']');
+ } catch (IOException e) {
+ throw new GfJsonException(e);
+ }
+ return writer;
+ }
+
+
+ private static class PreventReserializationSerializer extends JsonSerializer
{
+
+ private JsonSerializer defaultSerializer;
+ Map<Object, Object> serializedObjects;
+ private final int serializationDepth;
+ int depth;
+
+ PreventReserializationSerializer(JsonSerializer serializer, Map
serializedObjects,
+ int serializationDepth) {
+ defaultSerializer = serializer;
+ this.serializedObjects = serializedObjects;
+ this.serializationDepth = serializationDepth;
+ }
+
+ boolean isPrimitiveOrWrapper(Class<?> klass) {
+ return klass.isAssignableFrom(Byte.class) ||
klass.isAssignableFrom(byte.class)
+ || klass.isAssignableFrom(Short.class) ||
klass.isAssignableFrom(short.class)
+ || klass.isAssignableFrom(Integer.class) ||
klass.isAssignableFrom(int.class)
+ || klass.isAssignableFrom(Long.class) ||
klass.isAssignableFrom(long.class)
+ || klass.isAssignableFrom(Float.class) ||
klass.isAssignableFrom(float.class)
+ || klass.isAssignableFrom(Double.class) ||
klass.isAssignableFrom(double.class)
+ || klass.isAssignableFrom(Boolean.class) ||
klass.isAssignableFrom(boolean.class)
+ || klass.isAssignableFrom(String.class) ||
klass.isAssignableFrom(char.class)
+ || klass.isAssignableFrom(Character.class) ||
klass.isAssignableFrom(java.sql.Date.class)
+ || klass.isAssignableFrom(java.util.Date.class)
+ || klass.isAssignableFrom(java.math.BigDecimal.class);
+ }
+
+ @Override
+ public void serializeWithType(Object value, JsonGenerator gen,
+ SerializerProvider serializers, TypeSerializer typeSer)
+ throws IOException {
+ if (value == null || isPrimitiveOrWrapper(value.getClass())) {
+ defaultSerializer.serializeWithType(value, gen, serializers, typeSer);
+ return;
+ }
+ depth += 1;
+ try {
+ if (depth > serializationDepth) {
+ gen.writeString("{}");
+ } else if (serializedObjects.containsKey(value)) {
+ gen.writeString("duplicate " + value.getClass().getName());
+ } else {
+ serializedObjects.put(value, value);
+ defaultSerializer.serializeWithType(value, gen, serializers,
typeSer);
+ }
+ } finally {
+ depth--;
+ }
+ }
+
+ @Override
+ public void serialize(Object value, JsonGenerator gen, SerializerProvider
serializers)
+ throws IOException {
+ if (value == null || isPrimitiveOrWrapper(value.getClass())) {
+ defaultSerializer.serialize(value, gen, serializers);
+ return;
+ }
+ if (serializedObjects.containsKey(value)) {
+ gen.writeStartObject(value);
+ gen.writeFieldName("duplicate");
+ gen.writeString("reference@" +
Integer.toHexString(System.identityHashCode(value)));
+ gen.writeEndObject();
+ } else {
+ serializedObjects.put(value, value);
+ defaultSerializer.serialize(value, gen, serializers);
+ }
+ }
+ }
+
+
+ /* found on StackOverflow */
+ static class DepthFilter extends SimpleBeanPropertyFilter {
+ private final int maxDepth;
+
+ public DepthFilter(int maxDepth) {
+ super();
+ this.maxDepth = maxDepth;
+ }
+
+ private int calcDepth(JsonGenerator jgen) {
+ JsonStreamContext streamContext = jgen.getOutputContext();
+ int depth = -1;
+ while (streamContext != null) {
+ streamContext = streamContext.getParent();
+ depth++;
+ }
+ return depth;
+ }
+
+ @Override
+ public void serializeAsField(Object pojo, JsonGenerator gen,
SerializerProvider provider,
+ PropertyWriter writer)
+ throws Exception {
+ int depth = calcDepth(gen);
+ System.out.println("depth of " + pojo.getClass().getSimpleName() + " is
" + depth);
+ if (depth <= maxDepth) {
+ writer.serializeAsField(pojo, gen, provider);
+ }
+ // comment this if you don't want {} placeholders
+ else {
+ writer.serializeAsOmittedField(pojo, gen, provider);
+ }
+ }
+
+ }
+
+ private static class CollectionSerializer extends JsonSerializer<Collection>
{
+ private final int maxCollectionElements;
+
+ public CollectionSerializer(int maxCollectionElements) {
+ this.maxCollectionElements = maxCollectionElements;
+ }
+
+ @Override
+ public void serializeWithType(Collection value, JsonGenerator gen,
+ SerializerProvider serializers, TypeSerializer typeSer)
+ throws IOException {
+ gen.setCurrentValue(value);
+ WritableTypeId typeIdDef = typeSer.writeTypePrefix(gen,
+ typeSer.typeId(value, JsonToken.START_OBJECT));
+ _serialize(value, gen);
+ typeSer.writeTypeSuffix(gen, typeIdDef);
+ }
+
+ @Override
+ public void serialize(Collection value, JsonGenerator gen,
SerializerProvider serializers)
+ throws IOException {
+ gen.writeStartObject();
+ _serialize(value, gen);
+ gen.writeEndObject();
+ }
+
+ public void _serialize(Collection value, JsonGenerator gen) throws
IOException {
+ Iterator<Object> objects = value.iterator();
+ for (int i = 0; i < maxCollectionElements && objects.hasNext(); i++) {
+ Object nextObject = objects.next();
+ gen.writeObjectField("" + i, nextObject);
+ }
+ }
+
+ @Override
+ public Class<Collection> handledType() {
+ return Collection.class;
+ }
+ }
+
+
+ private static class PdxInstanceSerializer extends
JsonSerializer<PdxInstance> {
+ @Override
+ public void serializeWithType(PdxInstance value, JsonGenerator gen,
+ SerializerProvider serializers, TypeSerializer typeSer)
+ throws IOException {
+ WritableTypeId writableTypeId = typeSer.typeId(value,
JsonToken.START_OBJECT);
+ typeSer.writeTypePrefix(gen, writableTypeId);
+ _serialize(value, gen);
+ typeSer.writeTypeSuffix(gen, writableTypeId);
+ }
+
+ @Override
+ public void serialize(PdxInstance value, JsonGenerator gen,
SerializerProvider serializers)
+ throws IOException {
+ gen.writeStartObject();
+ _serialize(value, gen);
+ gen.writeEndObject();
+ }
+
+ public void _serialize(PdxInstance value, JsonGenerator gen) throws
IOException {
+ for (String field : value.getFieldNames()) {
+ gen.writeObjectField(field, value.getField(field));
+ }
+ }
+
+ @Override
+ public Class<PdxInstance> handledType() {
+ return PdxInstance.class;
+ }
+ }
+
+ private static class StructSerializer extends JsonSerializer<StructImpl> {
+ @Override
+ public void serializeWithType(StructImpl value, JsonGenerator gen,
+ SerializerProvider serializers, TypeSerializer typeSer)
+ throws IOException {
+ typeSer.writeTypePrefix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
+ _serialize(value, gen);
+ typeSer.writeTypeSuffix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
+ }
+
+ @Override
+ public void serialize(StructImpl value, JsonGenerator gen,
SerializerProvider serializers)
+ throws IOException {
+ gen.writeStartObject();
+ _serialize(value, gen);
+ gen.writeEndObject();
+ }
+
+ public void _serialize(StructImpl value, JsonGenerator gen) throws
IOException {
+ String fields[] = value.getFieldNames();
+ Object[] values = value.getFieldValues();
+ for (int i = 0; i < fields.length; i++) {
+ gen.writeObjectField(fields[i], values[i]);
+ }
+ }
+
+ @Override
+ public Class<StructImpl> handledType() {
+ return StructImpl.class;
+ }
+ }
+
+ private static class RegionEntrySerializer extends
JsonSerializer<Region.Entry> {
+ @Override
+ public void serializeWithType(Region.Entry value, JsonGenerator gen,
+ SerializerProvider serializers, TypeSerializer typeSer)
+ throws IOException {
+ typeSer.writeTypePrefix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
+ gen.writeObjectField(value.getKey().toString(), value.getValue());
+ typeSer.writeTypeSuffix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
+ }
+
+ @Override
+ public void serialize(Region.Entry value, JsonGenerator gen,
SerializerProvider serializers)
+ throws IOException {
+ gen.writeStartObject();
+ gen.writeObjectField(value.getKey().toString(), value.getValue());
+ gen.writeEndObject();
+ }
+
+ @Override
+ public Class<Region.Entry> handledType() {
+ return Region.Entry.class;
+ }
+ }
+}
diff --git
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/TypedJson.java
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/TypedJson.java
deleted file mode 100644
index 4e22e69..0000000
---
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/TypedJson.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license
- * agreements. See the NOTICE file distributed with this work for additional
information regarding
- * copyright ownership. The ASF licenses this file to You 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
- *
- * http://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.apache.geode.management.internal.cli.json;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.core.type.WritableTypeId;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.query.internal.StructImpl;
-import org.apache.geode.pdx.PdxInstance;
-
-/**
- * A JSON serializer that has special handling for collections to limit the
number of elements
- * written to the document. It also has special handling for PdxInstance and
query Structs.
- */
-public class TypedJson {
-
- ObjectMapper mapper;
- SimpleModule mapperModule;
-
- Map<Object, List<Object>> forbidden = new java.util.IdentityHashMap<Object,
List<Object>>();
-
- boolean addCommaBeforeNextElement;
-
- private Map<String, List<Object>> map;
-
- private int maxCollectionElements;
-
-
- {
- mapper = new ObjectMapper();
- mapperModule = new SimpleModule();
- // todo: Collection.class is probably too generic. Is there another way to
- // limit the number of elements generated by Jackson w/o using a
serializer for Collection?
- mapperModule.addSerializer(Collection.class, new
TypedJsonCollectionSerializer());
- mapperModule.addSerializer(PdxInstance.class, new
TypedJsonPdxInstanceSerializer());
- mapperModule.addSerializer(StructImpl.class, new
TypedJsonStructSerializer());
- mapperModule.addSerializer(Region.Entry.class, new
TypedJsonRegionEntrySerializer());
- mapper.registerModule(mapperModule);
- mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
- // todo: we need type information for enums but Jackson doesn't seem to do
that
- // -- look at the standard EnumSerializer to see if it can be configured
- mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
- mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- }
-
-
- public TypedJson(int maxCollectionElements) {
- this.map = new LinkedHashMap<>();
- this.maxCollectionElements = maxCollectionElements;
- }
-
- /**
- * Constructor for tests. This is equivalent to
- * new TypedJson(maxCollectionElements).add(key, value)
- */
- public TypedJson(String key, Object value, int maxCollectionElements) {
- List<Object> list = new ArrayList<>(1);
- this.map = new LinkedHashMap<>();
- if (value != null) {
- list.add(value);
- }
- this.map.put(key, list);
- this.maxCollectionElements = maxCollectionElements;
- }
-
- /**
- * User can build on this object by adding Objects against a key.
- *
- * TypedJson result = new TypedJson(); result.add(KEY,object); If users add
more objects against
- * the same key the newly added object will be appended to the existing key
forming an array of
- * objects.
- *
- * If the KEY is a new one then it will be a key map value.
- *
- * @param key Key against which an object will be added
- * @param value Object to be added
- * @return TypedJson object
- */
- public TypedJson add(String key, Object value) {
- List<Object> list = this.map.get(key);
- if (list != null) {
- list.add(value);
- } else {
- list = new ArrayList<>();
- list.add(value);
- this.map.put(key, list);
- }
- return this;
- }
-
- @Override
- public String toString() {
- StringWriter w = new StringWriter();
- synchronized (w.getBuffer()) {
- try {
- return this.write(w).toString();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
- }
-
-
- private Writer write(Writer writer) throws GfJsonException {
- try {
- boolean addComma = false;
-
- writer.write('{');
- for (Map.Entry<String, List<Object>> entry : this.map.entrySet()) {
- if (addComma) {
- writer.write(',');
- }
- mapper.writerFor(entry.getKey().getClass()).writeValue(writer,
entry.getKey());
- writer.write(':');
- writeList(writer, entry.getValue());
- addCommaBeforeNextElement = false;
- addComma = true;
- }
- writer.write('}');
-
- return writer;
- } catch (IOException exception) {
- throw new GfJsonException(exception);
- }
- }
-
- private Writer writeList(Writer writer, List<Object> values) throws
GfJsonException {
- try {
- boolean addComma = false;
- int length = values.size();
- writer.write('[');
-
- if (length == 0) {
- mapper.writeValue(writer, null);
- } else {
- for (int i = 0; i < length; i += 1) {
- if (addComma) {
- writer.write(',');
- }
- // System.out.format("BRUCE: writeList is serializing %s\n",
values.get(i));
- mapper.writerFor(values.get(i).getClass()).writeValue(writer,
values.get(i));
-
- addCommaBeforeNextElement = false;
- addComma = true;
- }
- }
- writer.write(']');
- } catch (IOException e) {
- throw new GfJsonException(e);
- }
- return writer;
- }
-
-
-
- class TypedJsonCollectionSerializer extends JsonSerializer<Collection> {
- @Override
- public void serializeWithType(Collection value, JsonGenerator gen,
- SerializerProvider serializers, TypeSerializer typeSer)
- throws IOException {
- gen.setCurrentValue(value);
- boolean isArray = value.getClass().isArray();
- WritableTypeId typeIdDef = typeSer.writeTypePrefix(gen,
- typeSer.typeId(value, JsonToken.START_ARRAY));
- _serialize(value, gen);
- typeSer.writeTypeSuffix(gen, typeIdDef);
- }
-
- @Override
- public void serialize(Collection value, JsonGenerator gen,
SerializerProvider serializers)
- throws IOException {
- gen.writeStartObject();
- _serialize(value, gen);
- gen.writeEndObject();
- }
-
- public void _serialize(Collection value, JsonGenerator gen) throws
IOException {
- // System.out.println("BRUCE: collection serializer starting for
collection " + value);
- Iterator<Object> objects = value.iterator();
- for (int i = 0; i < maxCollectionElements && objects.hasNext(); i++) {
- Object nextObject = objects.next();
- // System.out.format("BRUCE: collection serializer writing #%s: %s\n",
i, nextObject);
- gen.writeObject(nextObject);
- // System.out.println("BRUCE: collection serializer done writing #" +
i);
- }
- }
-
- @Override
- public Class<Collection> handledType() {
- return Collection.class;
- }
- }
-
- class TypedJsonMapSerializer extends JsonSerializer<Map> {
-
- @Override
- public void serializeWithType(Map value, JsonGenerator gen,
- SerializerProvider serializers, TypeSerializer typeSer)
- throws IOException {
- gen.setCurrentValue(value);
- WritableTypeId typeIdDef = typeSer.writeTypePrefix(gen,
- typeSer.typeId(value, JsonToken.START_OBJECT));
- // typeSer.writeTypePrefix(gen, typeSer.typeId(value,
JsonToken.START_ARRAY));
- _serialize(value, gen);
- // typeSer.writeTypeSuffix(gen, typeSer.typeId(value,
JsonToken.START_ARRAY));
- typeSer.writeTypeSuffix(gen, typeIdDef);
- }
-
- @Override
- public void serialize(Map value, JsonGenerator gen, SerializerProvider
serializers)
- throws IOException {
- gen.writeStartObject();
- _serialize(value, gen);
- gen.writeEndObject();
- }
-
- public void _serialize(Map value, JsonGenerator gen) throws IOException {
- Iterator<Map.Entry> entries = value.entrySet().iterator();
- for (int i = 0; i < maxCollectionElements && entries.hasNext(); i++) {
- Map.Entry entry = entries.next();
- // System.out.format("BRUCE: map serializer writing key %s value %s
value class %s\n",
- // entry.getKey(), entry.getValue(),
entry.getValue().getClass().getName());
- // gen.writeObjectField(entry.getKey().toString(), entry.getValue());
- // try {
- gen.writeFieldName(entry.getKey().toString());
- gen.writeObject(entry.getValue());
- // } catch (JsonGenerationException e) {
- // System.out.println("BRUCE: exception serializing value for " +
- // entry.getKey().toString());
- // throw e;
- // }
- // System.out.println("BRUCE: map serializer done writing key " +
entry.getKey());
- }
- }
-
- @Override
- public Class<Map> handledType() {
- return Map.class;
- }
- }
-
- static class TypedJsonPdxInstanceSerializer extends
JsonSerializer<PdxInstance> {
- @Override
- public void serializeWithType(PdxInstance value, JsonGenerator gen,
- SerializerProvider serializers, TypeSerializer typeSer)
- throws IOException {
- WritableTypeId writableTypeId = typeSer.typeId(value,
JsonToken.START_OBJECT);
- typeSer.writeTypePrefix(gen, writableTypeId);
- _serialize(value, gen);
- typeSer.writeTypeSuffix(gen, writableTypeId);
- }
-
- @Override
- public void serialize(PdxInstance value, JsonGenerator gen,
SerializerProvider serializers)
- throws IOException {
- gen.writeStartObject();
- _serialize(value, gen);
- gen.writeEndObject();
- }
-
- public void _serialize(PdxInstance value, JsonGenerator gen) throws
IOException {
- for (String field : value.getFieldNames()) {
- gen.writeObjectField(field, value.getField(field));
- }
- }
-
- @Override
- public Class<PdxInstance> handledType() {
- return PdxInstance.class;
- }
- }
-
- static class TypedJsonStructSerializer extends JsonSerializer<StructImpl> {
- @Override
- public void serializeWithType(StructImpl value, JsonGenerator gen,
- SerializerProvider serializers, TypeSerializer typeSer)
- throws IOException {
- typeSer.writeTypePrefix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
- _serialize(value, gen);
- typeSer.writeTypeSuffix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
- }
-
- @Override
- public void serialize(StructImpl value, JsonGenerator gen,
SerializerProvider serializers)
- throws IOException {
- gen.writeStartObject();
- _serialize(value, gen);
- gen.writeEndObject();
- }
-
- public void _serialize(StructImpl value, JsonGenerator gen) throws
IOException {
- String fields[] = value.getFieldNames();
- Object[] values = value.getFieldValues();
- for (int i = 0; i < fields.length; i++) {
- gen.writeObjectField(fields[i], values[i]);
- }
- }
-
- @Override
- public Class<StructImpl> handledType() {
- return StructImpl.class;
- }
- }
-
- static class TypedJsonRegionEntrySerializer extends
JsonSerializer<Region.Entry> {
- @Override
- public void serializeWithType(Region.Entry value, JsonGenerator gen,
- SerializerProvider serializers, TypeSerializer typeSer)
- throws IOException {
- typeSer.writeTypePrefix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
- gen.writeObjectField(value.getKey().toString(), value.getValue());
- typeSer.writeTypeSuffix(gen, typeSer.typeId(value,
JsonToken.START_OBJECT));
- }
-
- @Override
- public void serialize(Region.Entry value, JsonGenerator gen,
SerializerProvider serializers)
- throws IOException {
- gen.writeStartObject();
- gen.writeObjectField(value.getKey().toString(), value.getValue());
- gen.writeEndObject();
- }
-
- @Override
- public Class<Region.Entry> handledType() {
- return Region.Entry.class;
- }
- }
-}
diff --git
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/json/TypedJsonTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/json/QueryResultFormatterTest.java
similarity index 64%
rename from
geode-core/src/test/java/org/apache/geode/management/internal/cli/json/TypedJsonTest.java
rename to
geode-core/src/test/java/org/apache/geode/management/internal/cli/json/QueryResultFormatterTest.java
index 9a6996d..b076d22 100644
---
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/json/TypedJsonTest.java
+++
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/json/QueryResultFormatterTest.java
@@ -34,18 +34,18 @@ import org.junit.Test;
*
* TODO: add actual assertions
*/
-public class TypedJsonTest {
+public class QueryResultFormatterTest {
private static final String RESULT = "result";
@Test
public void canBeMocked() throws Exception {
- TypedJson mockTypedJson = mock(TypedJson.class);
+ QueryResultFormatter mockQueryResultFormatter =
mock(QueryResultFormatter.class);
Object value = new Object();
- mockTypedJson.add("key", value);
+ mockQueryResultFormatter.add("key", value);
- verify(mockTypedJson, times(1)).add("key", value);
+ verify(mockQueryResultFormatter, times(1)).add("key", value);
}
@Test
@@ -55,9 +55,9 @@ public class TypedJsonTest {
list.add("TWO");
list.add("THREE");
- TypedJson typedJson = new TypedJson(RESULT, list, 100);
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, list);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
@@ -67,9 +67,9 @@ public class TypedJsonTest {
intArray[i] = i;
}
- TypedJson typedJson = new TypedJson(RESULT, intArray, 100);
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, intArray);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
@@ -79,25 +79,27 @@ public class TypedJsonTest {
list.add("BIG_COLL_" + i);
}
- TypedJson typedJson = new TypedJson(RESULT, list, 100);
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, list);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
public void testEnumContainer() throws Exception {
EnumContainer enumContainer = new EnumContainer(Currency.DIME);
- TypedJson typedJson = new TypedJson(RESULT, enumContainer, 100);
+ QueryResultFormatter queryResultFormatter =
+ new QueryResultFormatter(100).add(RESULT, enumContainer);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
public void testEnum() throws Exception {
- TypedJson typedJson = new TypedJson(RESULT, Currency.DIME, 100);
+ QueryResultFormatter queryResultFormatter =
+ new QueryResultFormatter(100).add(RESULT, Currency.DIME);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
@@ -108,9 +110,9 @@ public class TypedJsonTest {
list.add(Currency.QUARTER);
list.add(Currency.NICKLE);
- TypedJson typedJson = new TypedJson(RESULT, list, 100);
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, list);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
@@ -121,32 +123,32 @@ public class TypedJsonTest {
map.put("3", "THREE");
map.put("4", "FOUR");
- TypedJson typedJson = new TypedJson(RESULT, map, 100);
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, map);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
public void testBigDecimal() throws Exception {
BigDecimal dc = new BigDecimal(20);
- TypedJson typedJson = new TypedJson(RESULT, dc, 100);
+ QueryResultFormatter queryResultFormatter = new
QueryResultFormatter(100).add(RESULT, dc);
- checkResult(typedJson);
+ checkResult(queryResultFormatter);
}
@Test
public void testObjects() throws Exception {
Object object = new Object();
- TypedJson typedJson = new TypedJson(100);
- typedJson.add(RESULT, object);
- checkResult(typedJson);
+ QueryResultFormatter queryResultFormatter = new QueryResultFormatter(100);
+ queryResultFormatter.add(RESULT, object);
+ checkResult(queryResultFormatter);
}
- private void checkResult(final TypedJson typedJson) throws GfJsonException {
- String jsonString = typedJson.toString();
- System.out.println("typedJson.toString=" + jsonString);
+ private void checkResult(final QueryResultFormatter queryResultFormatter)
throws GfJsonException {
+ String jsonString = queryResultFormatter.toString();
+ System.out.println("queryResultFormatter.toString=" + jsonString);
GfJsonObject gfJsonObject = new GfJsonObject(jsonString);
System.out.println("gfJsonObject=" + gfJsonObject);
assertThat(gfJsonObject.get(RESULT)).isNotNull();
@@ -154,7 +156,7 @@ public class TypedJsonTest {
private enum Currency {
PENNY, NICKLE, DIME, QUARTER
- };
+ }
private static class EnumContainer {