From d299d6ecb966971fa0226d4da7415bb1de62fe8c Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Wed, 13 Feb 2019 10:42:19 -0500 Subject: Refactor common class from gson code The TypeAdapters in the gson-jackson code were nearly identical, so a common class was factored out. This also enabled junit tests to attain 100% coverage on that code, whereas there were a couple of branches that could not be tested previously. Addressed new sonar issues. Removed unused import. Change-Id: Id8e6460c881c6ce0239768f182e4e652cd10645f Issue-ID: POLICY-1428 Signed-off-by: Jim Hahn --- .../gson/internal/JacksonTypeAdapterTest.java | 206 +++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 gson/src/test/java/org/onap/policy/common/gson/internal/JacksonTypeAdapterTest.java (limited to 'gson/src/test') diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/JacksonTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/JacksonTypeAdapterTest.java new file mode 100644 index 00000000..a75fe17e --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/JacksonTypeAdapterTest.java @@ -0,0 +1,206 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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 + * + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.gson.internal; + +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.TypeAdapter; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; +import org.junit.Before; +import org.junit.Test; + +public class JacksonTypeAdapterTest { + private static final String HELLO = "hello"; + private static final String WORLD = "world"; + + /** + * Gson object that excludes fields, as we're going to process the fields ourselves. + */ + private static Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); + + private JacksonTypeAdapter adapter; + private List sers; + private List desers; + + /** + * Initializes the previously defined fields. + */ + @Before + public void setUp() { + // create list of serializers, one for "id" and one for "value" + sers = new ArrayList<>(2); + sers.add(new NamedSer(HELLO) { + @Override + protected String getValue(Data data) { + return data.id; + } + }); + sers.add(new NamedSer(WORLD) { + @Override + protected String getValue(Data data) { + return data.value; + } + }); + + // create list of deserializers, one for "id" and one for "value" + desers = new ArrayList<>(2); + desers.add(new NamedDeser(HELLO) { + @Override + protected void setValue(Data data, String value) { + data.id = value; + } + }); + desers.add(new NamedDeser(WORLD) { + @Override + protected void setValue(Data data, String value) { + data.value = value; + } + }); + + TypeAdapter delegate = gson.getDelegateAdapter(null, TypeToken.get(Data.class)); + + adapter = new JacksonTypeAdapter<>(gson, delegate, sers, desers); + } + + @Test + public void testWriteJsonWriterT() throws Exception { + Data data = new Data("abc", "def"); + + StringWriter wtr = new StringWriter(); + adapter.write(new JsonWriter(wtr), data); + + assertEquals("{'hello':'abc','world':'def'}".replace('\'', '"'), wtr.toString()); + } + + /** + * Tests the case where the delegate does not return a JsonObject. + * + * @throws Exception if an error occurs + */ + @Test + public void testWriteJsonWriterT_NotAnObject() throws Exception { + TypeAdapter delegate = gson.getAdapter(String.class); + JacksonTypeAdapter stringAdapter = new JacksonTypeAdapter<>(gson, delegate, sers, desers); + + StringWriter wtr = new StringWriter(); + stringAdapter.write(new JsonWriter(wtr), "write text"); + + assertEquals("'write text'".replace('\'', '"'), wtr.toString()); + } + + @Test + public void testReadJsonReader() throws Exception { + Data data = adapter + .read(new JsonReader(new StringReader("{'hello':'four','world':'score'}".replace('\'', '"')))); + + assertEquals(new Data("four", "score").toString(), data.toString()); + } + + /** + * Tests the case where the delegate does not use a JsonObject. + * + * @throws Exception if an error occurs + */ + @Test + public void testReadJsonReader_NotAnObject() throws Exception { + TypeAdapter delegate = gson.getAdapter(String.class); + JacksonTypeAdapter stringAdapter = new JacksonTypeAdapter<>(gson, delegate, sers, desers); + + String data = stringAdapter.read(new JsonReader(new StringReader("'read text'".replace('\'', '"')))); + + assertEquals("read text", data.toString()); + } + + private static class Data { + private String id; + private String value; + + /* + * This is invoked by gson via reflection, thus no direct invocation. Hence it has + * to be labeled "unused". + */ + @SuppressWarnings("unused") + public Data() { + super(); + } + + public Data(String id, String value) { + this.id = id; + this.value = value; + } + + @Override + public String toString() { + return "Data [id=" + id + ", value=" + value + "]"; + } + } + + private abstract static class NamedSer implements Serializer { + private final String name; + + /** + * Constructs the object. + * + * @param name the name of the field, when stored in a JsonObject + */ + public NamedSer(String name) { + this.name = name; + } + + @Override + public void addToTree(Object source, JsonObject target) { + Data data = (Data) source; + target.addProperty(name, getValue(data)); + } + + protected abstract String getValue(Data data); + } + + private abstract static class NamedDeser implements Deserializer { + private final String name; + + /** + * Constructs the object. + * + * @param name the name of the field, when stored in a JsonObject + */ + public NamedDeser(String name) { + this.name = name; + } + + @Override + public void getFromTree(JsonObject source, Object target) { + Data data = (Data) target; + setValue(data, source.get(name).getAsString()); + } + + protected abstract void setValue(Data data, String value); + } +} -- cgit 1.2.3-korg