diff options
Diffstat (limited to 'gson/src')
43 files changed, 1261 insertions, 210 deletions
diff --git a/gson/src/main/java/org/onap/policy/common/gson/DoubleConverter.java b/gson/src/main/java/org/onap/policy/common/gson/DoubleConverter.java index 81803ff2..4d10bd13 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/DoubleConverter.java +++ b/gson/src/main/java/org/onap/policy/common/gson/DoubleConverter.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -25,18 +25,17 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; /** * Converter for Double values. By default, GSON treats all Objects that are numbers, as * Double. This converts Doubles to Integer or Long, if possible. It converts stand-alone * Doubles, as well as those found within Arrays and Maps. */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class DoubleConverter { - private DoubleConverter() { - // do nothing - } - /** * Performs in-place conversion of all values in a list. * @@ -98,7 +97,7 @@ public class DoubleConverter { } Double num = (Double) value; - long longval = num.longValue(); + var longval = num.longValue(); if (Double.compare(num.doubleValue(), longval) != 0) { // it isn't integral - return unchanged value @@ -106,7 +105,7 @@ public class DoubleConverter { } // it's integral - determine if it's an integer or a long - int intval = (int) longval; + var intval = (int) longval; if (intval == longval) { return intval; diff --git a/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java b/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java index 75d58f2f..a693b7f4 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java +++ b/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +23,13 @@ package org.onap.policy.common.gson; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.ext.MessageBodyReader; +import jakarta.ws.rs.ext.MessageBodyWriter; +import jakarta.ws.rs.ext.Provider; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -30,13 +38,13 @@ import java.io.OutputStreamWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyReader; -import javax.ws.rs.ext.MessageBodyWriter; -import javax.ws.rs.ext.Provider; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import lombok.AccessLevel; import lombok.Getter; import org.slf4j.Logger; @@ -85,7 +93,14 @@ public class GsonMessageBodyHandler implements MessageBodyReader<Object>, Messag * @return the configured builder */ public static GsonBuilder configBuilder(GsonBuilder builder) { - return builder.disableHtmlEscaping().registerTypeAdapterFactory(new MapDoubleAdapterFactory()); + return builder.disableHtmlEscaping().registerTypeAdapterFactory(new MapDoubleAdapterFactory()) + .registerTypeAdapter(Instant.class, new InstantTypeAdapter()) + .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()) + .registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdapter()) + .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter()) + .registerTypeAdapter(OffsetTime.class, new OffsetTimeTypeAdapter()) + .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) + .registerTypeAdapter(ZoneOffset.class, new ZoneOffsetTypeAdapter()); } @Override @@ -102,7 +117,7 @@ public class GsonMessageBodyHandler implements MessageBodyReader<Object>, Messag public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException { - try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) { + try (var writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) { Type jsonType = (type.equals(genericType) ? type : genericType); gson.toJson(object, jsonType, writer); } @@ -138,7 +153,7 @@ public class GsonMessageBodyHandler implements MessageBodyReader<Object>, Messag public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException { - try (InputStreamReader streamReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) { + try (var streamReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) { Type jsonType = (type.equals(genericType) ? type : genericType); return gson.fromJson(streamReader, jsonType); } diff --git a/gson/src/main/java/org/onap/policy/common/gson/InstantAsMillisTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/InstantAsMillisTypeAdapter.java new file mode 100644 index 00000000..c38a3e9b --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/InstantAsMillisTypeAdapter.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 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; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.time.Instant; + +/** + * GSON Type Adapter for "Instant" fields, that encodes them as milliseconds. + */ +public class InstantAsMillisTypeAdapter extends TypeAdapter<Instant> { + + @Override + public void write(JsonWriter out, Instant value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + out.value(value.toEpochMilli()); + } + } + + @Override + public Instant read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } else { + var millis = in.nextLong(); + return Instant.ofEpochMilli(millis); + } + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/InstantTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/InstantTypeAdapter.java new file mode 100644 index 00000000..bad66af3 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/InstantTypeAdapter.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 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; + +import java.time.Instant; + +/** + * GSON Type Adapter for "Instant" fields, that uses the standard ISO_INSTANT formatter. + */ +public class InstantTypeAdapter extends StringTypeAdapter<Instant> { + + /** + * Constructs an adapter. + */ + public InstantTypeAdapter() { + super("date", Instant::parse, Instant::toString); + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/JacksonFieldAdapterFactory.java b/gson/src/main/java/org/onap/policy/common/gson/JacksonFieldAdapterFactory.java index 3458a590..18157b03 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/JacksonFieldAdapterFactory.java +++ b/gson/src/main/java/org/onap/policy/common/gson/JacksonFieldAdapterFactory.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -54,7 +54,7 @@ public class JacksonFieldAdapterFactory implements TypeAdapterFactory { return null; } - ClassWalker data = new ClassWalker(); + var data = new ClassWalker(); data.walkClassHierarchy(clazz); if (data.getInProps(Field.class).isEmpty() && data.getOutProps(Field.class).isEmpty()) { diff --git a/gson/src/main/java/org/onap/policy/common/gson/JacksonMethodAdapterFactory.java b/gson/src/main/java/org/onap/policy/common/gson/JacksonMethodAdapterFactory.java index de962316..b7414004 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/JacksonMethodAdapterFactory.java +++ b/gson/src/main/java/org/onap/policy/common/gson/JacksonMethodAdapterFactory.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -58,7 +58,7 @@ public class JacksonMethodAdapterFactory implements TypeAdapterFactory { return null; } - ClassWalker data = new ClassWalker(); + var data = new ClassWalker(); data.walkClassHierarchy(clazz); if (data.getInProps(Method.class).isEmpty() && data.getOutProps(Method.class).isEmpty() diff --git a/gson/src/main/java/org/onap/policy/common/gson/LocalDateTimeTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/LocalDateTimeTypeAdapter.java new file mode 100644 index 00000000..5dc597e2 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/LocalDateTimeTypeAdapter.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 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; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * GSON Type Adapter for "LocalDateTime" fields, that uses the standard + * ISO_LOCAL_DATE_TIME formatter, by default. + */ +public class LocalDateTimeTypeAdapter extends StringTypeAdapter<LocalDateTime> { + + public LocalDateTimeTypeAdapter() { + this(DateTimeFormatter.ISO_LOCAL_DATE_TIME); + } + + public LocalDateTimeTypeAdapter(DateTimeFormatter formatter) { + super("date", string -> LocalDateTime.parse(string, formatter), value -> value.format(formatter)); + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/LocalDateTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/LocalDateTypeAdapter.java new file mode 100644 index 00000000..0f666e5e --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/LocalDateTypeAdapter.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class LocalDateTypeAdapter extends StringTypeAdapter<LocalDate> { + + public LocalDateTypeAdapter() { + this(DateTimeFormatter.ISO_LOCAL_DATE); + } + + public LocalDateTypeAdapter(DateTimeFormatter formatter) { + super("date", string -> LocalDate.parse(string, formatter), value -> value.format(formatter)); + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/MapDoubleAdapterFactory.java b/gson/src/main/java/org/onap/policy/common/gson/MapDoubleAdapterFactory.java index bd031999..057e97f8 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/MapDoubleAdapterFactory.java +++ b/gson/src/main/java/org/onap/policy/common/gson/MapDoubleAdapterFactory.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -51,24 +51,36 @@ public class MapDoubleAdapterFactory implements TypeAdapterFactory { } private <T> boolean isMapType(TypeToken<T> type) { - if (type.getRawType() != Map.class) { + if (!Map.class.isAssignableFrom(type.getRawType())) { return false; } + // only supports Map<String,Object> + + if (!(type.getType() instanceof ParameterizedType)) { + // untyped - assume the parameters are the correct type + return true; + } + Type[] actualParams = ((ParameterizedType) type.getType()).getActualTypeArguments(); - // only supports Map<String,Object> return (actualParams[0] == String.class && actualParams[1] == Object.class); } private <T> boolean isListType(TypeToken<T> type) { - if (type.getRawType() != List.class) { + if (!List.class.isAssignableFrom(type.getRawType())) { return false; } + // only supports List<Object> + + if (!(type.getType() instanceof ParameterizedType)) { + // untyped - assume the parameters are the correct type + return true; + } + Type[] actualParams = ((ParameterizedType) type.getType()).getActualTypeArguments(); - // only supports List<Object> return (actualParams[0] == Object.class); } @@ -100,7 +112,7 @@ public class MapDoubleAdapterFactory implements TypeAdapterFactory { @Override public T read(JsonReader in) throws IOException { - T value = delegate.read(in); + var value = delegate.read(in); DoubleConverter.convertFromDouble(value); diff --git a/gson/src/main/java/org/onap/policy/common/gson/OffsetDateTimeTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/OffsetDateTimeTypeAdapter.java new file mode 100644 index 00000000..3f046b01 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/OffsetDateTimeTypeAdapter.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +public class OffsetDateTimeTypeAdapter extends StringTypeAdapter<OffsetDateTime> { + + public OffsetDateTimeTypeAdapter() { + this(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + + public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) { + super("date", string -> OffsetDateTime.parse(string, formatter), value -> value.format(formatter)); + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/OffsetTimeTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/OffsetTimeTypeAdapter.java new file mode 100644 index 00000000..895b9de6 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/OffsetTimeTypeAdapter.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import java.time.OffsetTime; +import java.time.format.DateTimeFormatter; + +public class OffsetTimeTypeAdapter extends StringTypeAdapter<OffsetTime> { + + public OffsetTimeTypeAdapter() { + this(DateTimeFormatter.ISO_OFFSET_TIME); + } + + public OffsetTimeTypeAdapter(DateTimeFormatter formatter) { + super("time", string -> OffsetTime.parse(string, formatter), value -> value.format(formatter)); + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/StringTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/StringTypeAdapter.java new file mode 100644 index 00000000..22481697 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/StringTypeAdapter.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.util.function.Function; + +/** + * GSON Type Adapter for fields that are encoded as Strings. + */ +public class StringTypeAdapter<T> extends TypeAdapter<T> { + private final String exMessage; + private final Function<String, T> deserializer; + private final Function<T, String> serializer; + + /** + * Constructs an adapter. + * + * @param type type of value, used in exception messages + * @param deserializer function used to deserialize a String into a value + * @param serializer function used to serialize a value into a String + */ + public StringTypeAdapter(String type, Function<String, T> deserializer, Function<T, String> serializer) { + this.exMessage = "invalid " + type; + this.deserializer = deserializer; + this.serializer = serializer; + } + + @Override + public T read(JsonReader in) throws IOException { + try { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } else { + return deserializer.apply(in.nextString()); + } + + } catch (RuntimeException e) { + throw new JsonParseException(exMessage, e); + } + } + + @Override + public void write(JsonWriter out, T value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + String text = serializer.apply(value); + out.value(text); + } + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapter.java new file mode 100644 index 00000000..60758ff3 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapter.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import java.time.ZoneOffset; + +public class ZoneOffsetTypeAdapter extends StringTypeAdapter<ZoneOffset> { + + public ZoneOffsetTypeAdapter() { + super("zone", ZoneOffset::of, ZoneOffset::toString); + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/ZonedDateTimeTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/ZonedDateTimeTypeAdapter.java new file mode 100644 index 00000000..928fae95 --- /dev/null +++ b/gson/src/main/java/org/onap/policy/common/gson/ZonedDateTimeTypeAdapter.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 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; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +/** + * GSON Type Adapter for "ZonedDateTime" fields, that uses the standard + * ISO_ZONED_DATE_TIME formatter. + */ +public class ZonedDateTimeTypeAdapter extends StringTypeAdapter<ZonedDateTime> { + + /** + * Constructs an adapter that uses the ISO_ZONED_DATE_TIME formatter. + */ + public ZonedDateTimeTypeAdapter() { + this(DateTimeFormatter.ISO_ZONED_DATE_TIME); + } + + /** + * Constructs an adapter that uses the specified formatter for reading and writing. + * + * @param formatter date-time formatter + */ + public ZonedDateTimeTypeAdapter(DateTimeFormatter formatter) { + super("date", string -> ZonedDateTime.parse(string, formatter), value -> value.format(formatter)); + } +} diff --git a/gson/src/main/java/org/onap/policy/common/gson/internal/Adapter.java b/gson/src/main/java/org/onap/policy/common/gson/internal/Adapter.java index 174b4912..af4a746c 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/internal/Adapter.java +++ b/gson/src/main/java/org/onap/policy/common/gson/internal/Adapter.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 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. @@ -24,11 +24,12 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.TypeAdapter; import com.google.gson.reflect.TypeToken; +import com.google.re2j.Pattern; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.function.Supplier; -import java.util.regex.Pattern; +import lombok.Getter; import org.onap.policy.common.gson.annotation.GsonJsonProperty; /** @@ -49,6 +50,7 @@ public class Adapter { /** * Name of the property within the json structure containing the item. */ + @Getter private final String propName; /** @@ -69,6 +71,7 @@ public class Adapter { /** * Name of the item being lifted - used when throwing exceptions. */ + @Getter private final String fullName; /** @@ -83,7 +86,10 @@ public class Adapter { this.gson = gson; this.fullName = getQualifiedName(field); - field.setAccessible(true); + /* + * Turning off sonar, as this is required for emulation of "jackson". + */ + field.setAccessible(true); // NOSONAR } /** @@ -100,7 +106,10 @@ public class Adapter { this.gson = gson; this.fullName = getQualifiedName(accessor); - accessor.setAccessible(true); + /* + * Turning off sonar, as this is required for emulation of "jackson". + */ + accessor.setAccessible(true); // NOSONAR } /** @@ -121,8 +130,8 @@ public class Adapter { ConvInfo wtr = writer; - @SuppressWarnings("rawtypes") - TypeAdapter conv = (wtr.clazz == clazz ? wtr.getConverter() : gson.getAdapter(clazz)); + TypeAdapter<Object> conv = + (wtr.clazz == clazz ? wtr.getConverter() : (TypeAdapter<Object>) gson.getAdapter(clazz)); return conv.toJsonTree(object); } @@ -137,14 +146,6 @@ public class Adapter { return reader.getConverter().fromJsonTree(tree); } - public final String getPropName() { - return propName; - } - - public final String getFullName() { - return fullName; - } - /** * Makes an error message, appending the item's full name to the message prefix. * @@ -310,36 +311,33 @@ public class Adapter { /** * Type on which the converter works. */ - @SuppressWarnings("rawtypes") - private TypeToken type; + private TypeToken<?> type; /** * Class of object on which the converter works. */ - @SuppressWarnings("rawtypes") - private Class clazz; + private Class<?> clazz; /** * Converter to use, initialized lazily. */ - @SuppressWarnings("rawtypes") - private TypeAdapter conv = null; + private TypeAdapter<Object> conv = null; /** * Constructs the object. * * @param type type of object to be converted */ - public ConvInfo(@SuppressWarnings("rawtypes") TypeToken type) { + public ConvInfo(TypeToken<?> type) { this.type = type; this.clazz = type.getRawType(); } - @SuppressWarnings({"rawtypes", "unchecked"}) - public final TypeAdapter getConverter() { + @SuppressWarnings("unchecked") + public final TypeAdapter<Object> getConverter() { if (conv == null) { // race condition here, but it's ok to overwrite a previous value - this.conv = gson.getAdapter(type); + this.conv = (TypeAdapter<Object>) gson.getAdapter(type); } return conv; diff --git a/gson/src/main/java/org/onap/policy/common/gson/internal/ClassWalker.java b/gson/src/main/java/org/onap/policy/common/gson/internal/ClassWalker.java index ef4eaae3..954d3f4c 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/internal/ClassWalker.java +++ b/gson/src/main/java/org/onap/policy/common/gson/internal/ClassWalker.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import lombok.Getter; import org.onap.policy.common.gson.annotation.GsonJsonAnyGetter; import org.onap.policy.common.gson.annotation.GsonJsonAnySetter; import org.onap.policy.common.gson.annotation.GsonJsonIgnore; @@ -79,23 +80,16 @@ public class ClassWalker { * Method having {@link GsonJsonAnyGetter} annotation. Overwritten as new "any-getters" * are identified. */ + @Getter private Method anyGetter = null; /** * Method having {@link GsonJsonAnySetter} annotation. Overwritten as new "any-setters" * are identified. */ + @Getter private Method anySetter = null; - - public Method getAnyGetter() { - return anyGetter; - } - - public Method getAnySetter() { - return anySetter; - } - /** * Gets the names of input properties that are not being ignored. * diff --git a/gson/src/main/java/org/onap/policy/common/gson/internal/FieldDeserializer.java b/gson/src/main/java/org/onap/policy/common/gson/internal/FieldDeserializer.java index 14a432d1..123b0195 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/internal/FieldDeserializer.java +++ b/gson/src/main/java/org/onap/policy/common/gson/internal/FieldDeserializer.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -49,7 +49,10 @@ public class FieldDeserializer extends Adapter implements Deserializer { this.field = field; - field.setAccessible(true); + /* + * Turning off sonar, as this is required for emulation of "jackson". + */ + field.setAccessible(true); // NOSONAR } @Override @@ -62,7 +65,10 @@ public class FieldDeserializer extends Adapter implements Deserializer { Object value = fromJsonTree(jsonEl); try { - field.set(target, value); + /* + * Turning off sonar, as this is required for emulation of "jackson". + */ + field.set(target, value); // NOSONAR } catch (IllegalArgumentException | IllegalAccessException e) { throw new JsonParseException(makeError(SET_ERR), e); diff --git a/gson/src/main/java/org/onap/policy/common/gson/internal/FieldSerializer.java b/gson/src/main/java/org/onap/policy/common/gson/internal/FieldSerializer.java index 1c9d8b37..348ef5a0 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/internal/FieldSerializer.java +++ b/gson/src/main/java/org/onap/policy/common/gson/internal/FieldSerializer.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -50,7 +50,10 @@ public class FieldSerializer extends Adapter implements Serializer { this.field = field; - field.setAccessible(true); + /* + * Turning off sonar, as this is required for emulation of "jackson". + */ + field.setAccessible(true); // NOSONAR } @Override diff --git a/gson/src/main/java/org/onap/policy/common/gson/internal/JacksonTypeAdapter.java b/gson/src/main/java/org/onap/policy/common/gson/internal/JacksonTypeAdapter.java index 1171fd4d..34d61f47 100644 --- a/gson/src/main/java/org/onap/policy/common/gson/internal/JacksonTypeAdapter.java +++ b/gson/src/main/java/org/onap/policy/common/gson/internal/JacksonTypeAdapter.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -22,7 +22,6 @@ package org.onap.policy.common.gson.internal; import com.google.gson.Gson; import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; @@ -78,7 +77,7 @@ public class JacksonTypeAdapter<T> extends TypeAdapter<T> { JsonElement tree = delegate.toJsonTree(value); if (tree.isJsonObject()) { - JsonObject jsonObj = tree.getAsJsonObject(); + var jsonObj = tree.getAsJsonObject(); // serialize each item from the value into the target tree for (Serializer serializer : serializers) { @@ -92,10 +91,10 @@ public class JacksonTypeAdapter<T> extends TypeAdapter<T> { @Override public T read(JsonReader in) throws IOException { JsonElement tree = elementAdapter.read(in); - T object = delegate.fromJsonTree(tree); + var object = delegate.fromJsonTree(tree); if (tree.isJsonObject()) { - JsonObject jsonObj = tree.getAsJsonObject(); + var jsonObj = tree.getAsJsonObject(); // deserialize each item from the tree into the target object for (Deserializer dser : deserializers) { diff --git a/gson/src/test/java/org/onap/policy/common/gson/DoubleConverterTest.java b/gson/src/test/java/org/onap/policy/common/gson/DoubleConverterTest.java index c81a5cd6..f4e3a76b 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/DoubleConverterTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/DoubleConverterTest.java @@ -59,7 +59,7 @@ public class DoubleConverterTest { assertEquals("[list, null, 21]", list.toString()); // map - Map<String,Object> map = new LinkedHashMap<>(); + Map<String, Object> map = new LinkedHashMap<>(); map.put("map-A", "map-value"); map.put("map-B", null); map.put("map-C", 22.0); @@ -88,13 +88,13 @@ public class DoubleConverterTest { @Test public void testConvertFromDoubleMap() { // null is ok - DoubleConverter.convertFromDouble((Map<String,Object>) null); + DoubleConverter.convertFromDouble((Map<String, Object>) null); - Map<String,Object> map = new LinkedHashMap<>(); + Map<String, Object> map = new LinkedHashMap<>(); map.put("keyA", "valueA"); map.put("keyB", 200.0); - Map<String,Object> nested = new LinkedHashMap<>(); + Map<String, Object> nested = new LinkedHashMap<>(); map.put("keyC", nested); nested.put("nested-key", 201.0); diff --git a/gson/src/test/java/org/onap/policy/common/gson/GsonMessageBodyHandlerTest.java b/gson/src/test/java/org/onap/policy/common/gson/GsonMessageBodyHandlerTest.java index f1740ac1..fc101430 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/GsonMessageBodyHandlerTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/GsonMessageBodyHandlerTest.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,15 +21,24 @@ package org.onap.policy.common.gson; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import jakarta.ws.rs.core.MediaType; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.HashMap; import java.util.Map; -import javax.ws.rs.core.MediaType; +import java.util.UUID; +import lombok.ToString; import org.junit.Before; import org.junit.Test; @@ -160,7 +170,34 @@ public class GsonMessageBodyHandlerTest { assertEquals(12.5, map.props.get("doubleVal")); } + @Test + public void testInterestingFields() throws IOException { + InterestingFields data = new InterestingFields(); + data.instant = Instant.ofEpochMilli(1583249713500L); + data.uuid = UUID.fromString("a850cb9f-3c5e-417c-abfd-0679cdcd1ab0"); + data.localDate = LocalDateTime.of(2020, 2, 3, 4, 5, 6, 789000000); + data.zonedDate = ZonedDateTime.of(2020, 2, 3, 4, 5, 6, 789000000, ZoneId.of("US/Eastern")); + + ByteArrayOutputStream outstr = new ByteArrayOutputStream(); + hdlr.writeTo(data, data.getClass(), data.getClass(), null, null, null, outstr); + + // ensure fields are encoded as expected + + // @formatter:off + assertThat(outstr.toString(StandardCharsets.UTF_8)) + .contains("\"2020-03-03T15:35:13.500Z\"") + .contains("\"2020-02-03T04:05:06.789\"") + .contains("\"2020-02-03T04:05:06.789-05:00[US/Eastern]\"") + .contains("a850cb9f-3c5e-417c-abfd-0679cdcd1ab0"); + // @formatter:on + + Object obj2 = hdlr.readFrom(Object.class, data.getClass(), null, null, null, + new ByteArrayInputStream(outstr.toByteArray())); + assertEquals(data.toString(), obj2.toString()); + } + + @ToString public static class MyObject { private int id; @@ -171,11 +208,6 @@ public class GsonMessageBodyHandlerTest { public MyObject(int id) { this.id = id; } - - @Override - public String toString() { - return "MyObject [id=" + id + "]"; - } } private static class MyMap { @@ -186,4 +218,12 @@ public class GsonMessageBodyHandlerTest { return props.toString(); } } + + @ToString + private static class InterestingFields { + private LocalDateTime localDate; + private Instant instant; + private UUID uuid; + private ZonedDateTime zonedDate; + } } diff --git a/gson/src/test/java/org/onap/policy/common/gson/InstantAsMillisTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/InstantAsMillisTypeAdapterTest.java new file mode 100644 index 00000000..c48919a7 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/InstantAsMillisTypeAdapterTest.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.time.Instant; +import lombok.ToString; +import org.junit.Test; + +public class InstantAsMillisTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(Instant.class, new InstantAsMillisTypeAdapter()).create(); + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.instant = Instant.ofEpochMilli(1583249713500L); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("nanos").contains("1583249713500").doesNotContain("\"1583249713500\"") + .doesNotContain("T"); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null output + data.instant = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"instant\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + + @ToString + private static class InterestingFields { + private Instant instant; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/InstantTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/InstantTypeAdapterTest.java new file mode 100644 index 00000000..68f54ed8 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/InstantTypeAdapterTest.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.Instant; +import lombok.ToString; +import org.junit.Test; + +public class InstantTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(Instant.class, new InstantTypeAdapter()).create(); + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.instant = Instant.ofEpochMilli(1583249713500L); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("nanos").contains("\"2020-03-03T15:35:13.500Z\"") + .doesNotContain("1583249713500"); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("2020", "invalid-date"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid date"); + } + + + @ToString + private static class InterestingFields { + private Instant instant; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/JacksonExclusionStrategyTest.java b/gson/src/test/java/org/onap/policy/common/gson/JacksonExclusionStrategyTest.java index 3ce16964..9d8d3495 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/JacksonExclusionStrategyTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/JacksonExclusionStrategyTest.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. + * Modificaitons Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +32,7 @@ import com.google.gson.JsonElement; import java.lang.reflect.GenericArrayType; import java.util.LinkedList; import java.util.TreeMap; +import lombok.ToString; import org.junit.BeforeClass; import org.junit.Test; @@ -80,39 +82,29 @@ public class JacksonExclusionStrategyTest { @Test public void testIsManaged() { - assertTrue(JacksonExclusionStrategy.isManaged(Data.class)); - assertTrue(JacksonExclusionStrategy.isManaged(Intfc.class)); - assertTrue(JacksonExclusionStrategy.isManaged(com.google.gson.TypeAdapter.class)); - - // generic classes - assertFalse(JacksonExclusionStrategy.isManaged(new Data[0].getClass())); - assertFalse(JacksonExclusionStrategy.isManaged(Enum.class)); - assertFalse(JacksonExclusionStrategy.isManaged(boolean.class)); - assertFalse(JacksonExclusionStrategy.isManaged(byte.class)); - assertFalse(JacksonExclusionStrategy.isManaged(short.class)); - assertFalse(JacksonExclusionStrategy.isManaged(int.class)); - assertFalse(JacksonExclusionStrategy.isManaged(long.class)); - assertFalse(JacksonExclusionStrategy.isManaged(float.class)); - assertFalse(JacksonExclusionStrategy.isManaged(double.class)); - assertFalse(JacksonExclusionStrategy.isManaged(char.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Boolean.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Byte.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Short.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Integer.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Long.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Float.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Double.class)); - assertFalse(JacksonExclusionStrategy.isManaged(Character.class)); - assertFalse(JacksonExclusionStrategy.isManaged(String.class)); - assertFalse(JacksonExclusionStrategy.isManaged(MyMap.class)); - assertFalse(JacksonExclusionStrategy.isManaged(MyList.class)); - assertFalse(JacksonExclusionStrategy.isManaged(MyJson.class)); - assertFalse(JacksonExclusionStrategy.isManaged(GenericArrayType.class)); + // these classes SHOULD be managed + Class<?>[] managed = {Data.class, Intfc.class, com.google.gson.TypeAdapter.class}; + + for (Class<?> clazz : managed) { + assertTrue(clazz.getName(), JacksonExclusionStrategy.isManaged(clazz)); + } + + // generic classes should NOT be managed + Class<?>[] unmanaged = { + new Data[0].getClass(), Enum.class, boolean.class, byte.class, short.class, int.class, + long.class, float.class, double.class, char.class, Boolean.class, Byte.class, Short.class, + Integer.class, Long.class, Float.class, Double.class, Character.class, String.class, + MyMap.class, MyList.class, MyJson.class, GenericArrayType.class}; + + for (Class<?> clazz : unmanaged) { + assertFalse(clazz.getName(), JacksonExclusionStrategy.isManaged(clazz)); + } } /** * Used to verify that no fields are exposed. */ + @ToString public static class Data { private int id; public String text; @@ -132,13 +124,9 @@ public class JacksonExclusionStrategyTest { public void setText(String text) { this.text = text; } - - @Override - public String toString() { - return "Data [id=" + id + ", text=" + text + "]"; - } } + @ToString(callSuper = true) public static class Derived extends Data { protected String value; @@ -149,11 +137,6 @@ public class JacksonExclusionStrategyTest { public void setValue(String value) { this.value = value; } - - @Override - public String toString() { - return "Derived [value=" + value + ", " + super.toString() + "]"; - } } /** @@ -193,6 +176,7 @@ public class JacksonExclusionStrategyTest { /** * Used to verify that JsonElements are not managed. */ + @SuppressWarnings("deprecation") public static class MyJson extends JsonElement { @Override public JsonElement deepCopy() { diff --git a/gson/src/test/java/org/onap/policy/common/gson/JacksonFieldAdapterFactoryTest.java b/gson/src/test/java/org/onap/policy/common/gson/JacksonFieldAdapterFactoryTest.java index bbeb1e26..dc62186b 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/JacksonFieldAdapterFactoryTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/JacksonFieldAdapterFactoryTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -31,6 +31,7 @@ import com.google.gson.JsonElement; import com.google.gson.reflect.TypeToken; import java.util.ArrayList; import java.util.List; +import lombok.ToString; import org.junit.Test; import org.onap.policy.common.gson.annotation.GsonJsonIgnore; import org.onap.policy.common.gson.annotation.GsonJsonProperty; @@ -137,6 +138,7 @@ public class JacksonFieldAdapterFactoryTest { return text.replaceFirst("@\\w+", "@"); } + @ToString private static class Data { @GsonJsonProperty("my-id") private int id; @@ -155,21 +157,12 @@ public class JacksonFieldAdapterFactoryTest { public void setId(int id) { this.id = id; } - - @Override - public String toString() { - return "Data [id=" + id + ", text=" + text + "]"; - } } + @ToString(callSuper = true) private static class Derived extends Data { // not serialized private String unserialized; - - @Override - public String toString() { - return "Derived [unserialized=" + unserialized + ", toString()=" + super.toString() + "]"; - } } private static class DataList { diff --git a/gson/src/test/java/org/onap/policy/common/gson/JacksonHandlerTest.java b/gson/src/test/java/org/onap/policy/common/gson/JacksonHandlerTest.java index 18a6fc73..7131817d 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/JacksonHandlerTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/JacksonHandlerTest.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,13 +27,14 @@ import static org.junit.Assert.assertTrue; import com.google.gson.Gson; import com.google.gson.JsonObject; +import jakarta.ws.rs.core.MediaType; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.StringReader; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; -import javax.ws.rs.core.MediaType; +import lombok.ToString; import org.junit.Test; import org.onap.policy.common.gson.annotation.GsonJsonAnyGetter; import org.onap.policy.common.gson.annotation.GsonJsonAnySetter; @@ -109,6 +111,7 @@ public class JacksonHandlerTest { /** * This class includes all policy-specific gson annotations. */ + @ToString public static class Data { protected int id; @@ -147,11 +150,6 @@ public class JacksonHandlerTest { props.put(name, value); } - - @Override - public String toString() { - return "Data [id=" + id + ", value=" + value + ", props=" + props + "]"; - } } private static class MyMap { diff --git a/gson/src/test/java/org/onap/policy/common/gson/JacksonMethodAdapterFactoryTest.java b/gson/src/test/java/org/onap/policy/common/gson/JacksonMethodAdapterFactoryTest.java index 6377420d..7afb0e5a 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/JacksonMethodAdapterFactoryTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/JacksonMethodAdapterFactoryTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -32,6 +32,7 @@ import com.google.gson.JsonElement; import com.google.gson.reflect.TypeToken; import java.util.Map; import java.util.TreeMap; +import lombok.ToString; import org.junit.Test; import org.onap.policy.common.gson.annotation.GsonJsonAnyGetter; import org.onap.policy.common.gson.annotation.GsonJsonAnySetter; @@ -117,6 +118,7 @@ public class JacksonMethodAdapterFactoryTest { assertEquals("{'id':500,'nested':{'value':'bye bye'}}".replace('\'', '"'), result); } + @ToString protected static class Data { private int id; private String text; @@ -142,13 +144,9 @@ public class JacksonMethodAdapterFactoryTest { public void unused(String text) { // do nothing } - - @Override - public String toString() { - return "Data [id=" + id + ", text=" + text + "]"; - } } + @ToString(callSuper = true) protected static class Derived extends Data { // overrides private field from Data @@ -174,11 +172,6 @@ public class JacksonMethodAdapterFactoryTest { map.put(key, value); } - - @Override - public String toString() { - return "Derived [text=" + text + ", map=" + map + ", toString()=" + super.toString() + "]"; - } } /** @@ -258,6 +251,7 @@ public class JacksonMethodAdapterFactoryTest { /** * Used to test serialization of non-static nested classes. */ + @ToString protected static class Container { private int id; private Nested nested; @@ -283,12 +277,8 @@ public class JacksonMethodAdapterFactoryTest { return nested; } - @Override - public String toString() { - return "Container [id=" + id + ", nested=" + nested + "]"; - } - + @ToString protected class Nested { private String value; @@ -299,11 +289,6 @@ public class JacksonMethodAdapterFactoryTest { public String getValue() { return value; } - - @Override - public String toString() { - return "Nested [value=" + value + "]"; - } } } } diff --git a/gson/src/test/java/org/onap/policy/common/gson/LocalDateTimeTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/LocalDateTimeTypeAdapterTest.java new file mode 100644 index 00000000..2778a4ba --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/LocalDateTimeTypeAdapterTest.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.LocalDateTime; +import lombok.ToString; +import org.junit.Test; + +public class LocalDateTimeTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create(); + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.date = LocalDateTime.of(2020, 2, 3, 4, 5, 6, 789000000); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("year").contains("\"2020-02-03T04:05:06.789\""); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("2020", "invalid-date"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid date"); + + // null output + data.date = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"date\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + + @ToString + private static class InterestingFields { + private LocalDateTime date; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/LocalDateTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/LocalDateTypeAdapterTest.java new file mode 100644 index 00000000..17acf5e6 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/LocalDateTypeAdapterTest.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.LocalDate; +import lombok.ToString; +import org.junit.Test; + +public class LocalDateTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()).create(); + private static final String TEST_DATE = "2020-01-01"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.date = LocalDate.parse(TEST_DATE); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("year").contains(TEST_DATE); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("2020", "invalid-date"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid date"); + + // null output + data.date = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"date\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private LocalDate date; + } + +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/MapDoubleAdapterFactoryTest.java b/gson/src/test/java/org/onap/policy/common/gson/MapDoubleAdapterFactoryTest.java index 79631c5c..30d99466 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/MapDoubleAdapterFactoryTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/MapDoubleAdapterFactoryTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -21,6 +21,7 @@ package org.onap.policy.common.gson; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -104,8 +105,8 @@ public class MapDoubleAdapterFactoryTest { map = gson.fromJson(json, MyDoubleMap.class); // everything should still be Double - check by simply accessing - map.data.get("plainDouble"); - map.data.get("doubleAsInt"); + assertNotNull(map.data.get("plainDouble")); + assertNotNull(map.data.get("doubleAsInt")); } @Test diff --git a/gson/src/test/java/org/onap/policy/common/gson/OffsetDateTimeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/OffsetDateTimeAdapterTest.java new file mode 100644 index 00000000..a0bcb1b2 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/OffsetDateTimeAdapterTest.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.OffsetDateTime; +import lombok.ToString; +import org.junit.Test; + +public class OffsetDateTimeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter()).create(); + private static final String TEST_DATE = "2020-01-01T12:00:00.999+05:00"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.date = OffsetDateTime.parse(TEST_DATE); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("year").contains(TEST_DATE); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("2020", "invalid-date"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid date"); + + // null output + data.date = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"date\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private OffsetDateTime date; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/OffsetTimeTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/OffsetTimeTypeAdapterTest.java new file mode 100644 index 00000000..8098af98 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/OffsetTimeTypeAdapterTest.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.OffsetTime; +import lombok.ToString; +import org.junit.Test; + +public class OffsetTimeTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(OffsetTime.class, new OffsetTimeTypeAdapter()).create(); + private static final String TEST_TIME = "12:00:00.999+05:00"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.time = OffsetTime.parse(TEST_TIME); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("foo").contains(TEST_TIME); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("12", "invalid-time"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid time"); + + // null output + data.time = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"time\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private OffsetTime time; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/StringTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/StringTypeAdapterTest.java new file mode 100644 index 00000000..f35677cd --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/StringTypeAdapterTest.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; +import org.junit.Test; + +public class StringTypeAdapterTest { + private static Gson gson = new GsonBuilder().registerTypeAdapter(MyData.class, new MyAdapter()).create(); + private static final int TEST_NUM1 = 10; + private static final int TEST_NUM3 = 30; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.data1 = new MyData(TEST_NUM1); + data.data2 = null; + data.data3 = new MyData(TEST_NUM3); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).contains("10", "30"); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the string is invalid + String json2 = json.replace("30", "invalid-value"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid data"); + + // null output + data = new InterestingFields(); + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"data1\":null, \"data1\":null, \"data1\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // empty input + data2 = gson.fromJson("{}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @Getter + @ToString + @AllArgsConstructor + private static class MyData { + private int num; + } + + @ToString + private static class InterestingFields { + private MyData data1; + private MyData data2; + private MyData data3; + } + + private static class MyAdapter extends StringTypeAdapter<MyData> { + public MyAdapter() { + super("data", string -> new MyData(Integer.parseInt(string)), data -> String.valueOf(data.num)); + } + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapterTest.java new file mode 100644 index 00000000..d9a33169 --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/ZoneOffsetTypeAdapterTest.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.ZoneOffset; +import lombok.ToString; +import org.junit.Test; + +public class ZoneOffsetTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(ZoneOffset.class, new ZoneOffsetTypeAdapter()).create(); + private static final String TEST_ZONE = "+05:00"; + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.zone = ZoneOffset.of(TEST_ZONE); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("foo").contains(TEST_ZONE); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("05", "invalid-zone"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid zone"); + + // null output + data.zone = null; + json = gson.toJson(data); + data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // null input + data2 = gson.fromJson("{\"zone\":null}", InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + } + + @ToString + private static class InterestingFields { + private ZoneOffset zone; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/ZonedDateTimeTypeAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/ZonedDateTimeTypeAdapterTest.java new file mode 100644 index 00000000..032533eb --- /dev/null +++ b/gson/src/test/java/org/onap/policy/common/gson/ZonedDateTimeTypeAdapterTest.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import lombok.ToString; +import org.junit.Test; + +public class ZonedDateTimeTypeAdapterTest { + private static Gson gson = + new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdapter()).create(); + + @Test + public void test() { + InterestingFields data = new InterestingFields(); + data.date = ZonedDateTime.of(2020, 2, 3, 4, 5, 6, 789000000, ZoneId.of("US/Eastern")); + + String json = gson.toJson(data); + + // instant should be encoded as a number, without quotes + assertThat(json).doesNotContain("year").contains("\"2020-02-03T04:05:06.789-05:00[US/Eastern]\""); + + InterestingFields data2 = gson.fromJson(json, InterestingFields.class); + assertEquals(data.toString(), data2.toString()); + + // try when the date-time string is invalid + String json2 = json.replace("2020", "invalid-date"); + assertThatThrownBy(() -> gson.fromJson(json2, InterestingFields.class)).isInstanceOf(JsonParseException.class) + .hasMessageContaining("invalid date"); + } + + + @ToString + private static class InterestingFields { + private ZonedDateTime date; + } +} diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/AdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/AdapterTest.java index 9d80c860..fd999951 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/AdapterTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/AdapterTest.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +43,7 @@ import org.onap.policy.common.gson.annotation.GsonJsonProperty; import org.onap.policy.common.gson.internal.Adapter.Factory; import org.onap.policy.common.gson.internal.DataAdapterFactory.Data; import org.onap.policy.common.gson.internal.DataAdapterFactory.DerivedData; -import org.powermock.reflect.Whitebox; +import org.springframework.test.util.ReflectionTestUtils; public class AdapterTest { private static final String GET_INVALID_NAME = "get$InvalidName"; @@ -83,12 +84,12 @@ public class AdapterTest { @BeforeClass public static void setUpBeforeClass() { - saveFactory = Whitebox.getInternalState(Adapter.class, FACTORY_FIELD); + saveFactory = (Factory) ReflectionTestUtils.getField(Adapter.class, FACTORY_FIELD); } @After public void tearDown() { - Whitebox.setInternalState(Adapter.class, FACTORY_FIELD, saveFactory); + ReflectionTestUtils.setField(Adapter.class, FACTORY_FIELD, saveFactory); } @Test @@ -98,7 +99,7 @@ public class AdapterTest { // return an invalid field name Factory factory = mock(Factory.class); when(factory.getName(any(Field.class))).thenReturn("$invalidFieldName"); - Whitebox.setInternalState(Adapter.class, FACTORY_FIELD, factory); + ReflectionTestUtils.setField(Adapter.class, FACTORY_FIELD, factory); assertFalse(Adapter.isManaged(field(VALUE_NAME))); } @@ -108,7 +109,7 @@ public class AdapterTest { // return an invalid method name Factory factory = mock(Factory.class); - Whitebox.setInternalState(Adapter.class, FACTORY_FIELD, factory); + ReflectionTestUtils.setField(Adapter.class, FACTORY_FIELD, factory); when(factory.getName(any(Method.class))).thenReturn(GET_INVALID_NAME); assertFalse(Adapter.isManaged(mget(GET_VALUE_NAME))); @@ -240,7 +241,7 @@ public class AdapterTest { // return an invalid field name Factory factory = mock(Factory.class); when(factory.getName(any(Field.class))).thenReturn("$invalidFieldName"); - Whitebox.setInternalState(Adapter.class, FACTORY_FIELD, factory); + ReflectionTestUtils.setField(Adapter.class, FACTORY_FIELD, factory); assertEquals(null, Adapter.detmPropName(field(VALUE_NAME))); } @@ -257,7 +258,7 @@ public class AdapterTest { // return an invalid method name Factory factory = mock(Factory.class); - Whitebox.setInternalState(Adapter.class, FACTORY_FIELD, factory); + ReflectionTestUtils.setField(Adapter.class, FACTORY_FIELD, factory); when(factory.getName(any(Method.class))).thenReturn(GET_INVALID_NAME); assertEquals(null, Adapter.detmGetterPropName(mget(GET_VALUE_NAME))); @@ -273,7 +274,7 @@ public class AdapterTest { // return an invalid method name Factory factory = mock(Factory.class); - Whitebox.setInternalState(Adapter.class, FACTORY_FIELD, factory); + ReflectionTestUtils.setField(Adapter.class, FACTORY_FIELD, factory); when(factory.getName(any(Method.class))).thenReturn(SET_INVALID_NAME); assertEquals(null, Adapter.detmSetterPropName(mset(SET_VALUE_NAME))); diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/DataAdapterFactory.java b/gson/src/test/java/org/onap/policy/common/gson/internal/DataAdapterFactory.java index 2799d8ba..d2cdf7f8 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/DataAdapterFactory.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/DataAdapterFactory.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -35,6 +35,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeMap; +import lombok.ToString; /** * Factory used with test Data. @@ -54,6 +55,7 @@ public class DataAdapterFactory implements TypeAdapterFactory { /** * Object handled by this factory. */ + @ToString public static class Data { private int id; @@ -72,16 +74,12 @@ public class DataAdapterFactory implements TypeAdapterFactory { public void setId(int id) { this.id = id; } - - @Override - public String toString() { - return "Data [id=" + id + "]"; - } } /** * Object derived from Data. */ + @ToString(callSuper = true) public static class DerivedData extends Data { private String text; @@ -101,11 +99,6 @@ public class DataAdapterFactory implements TypeAdapterFactory { public void setText(String text) { this.text = text; } - - @Override - public String toString() { - return "DerivedData [text=" + text + ", toString()=" + super.toString() + "]"; - } } /** diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/FieldDeserializerTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/FieldDeserializerTest.java index 509ddb79..acb241e6 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/FieldDeserializerTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/FieldDeserializerTest.java @@ -1,8 +1,8 @@ -/* +/*- * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -61,18 +61,18 @@ public class FieldDeserializerTest { // no value in tree - text remains unchanged text = INITIAL_VALUE; deser.getFromTree(json, this); - assertEquals(text, INITIAL_VALUE); + assertEquals(INITIAL_VALUE, text); // null value in tree - text remains unchanged json.add(TEXT_FIELD_NAME, JsonNull.INSTANCE); deser.getFromTree(json, this); - assertEquals(text, INITIAL_VALUE); + assertEquals(INITIAL_VALUE, text); // now assign a value - text should be changed now json.addProperty(TEXT_FIELD_NAME, NEW_VALUE); deser.getFromTree(json, this); - assertEquals(text, NEW_VALUE); + assertEquals(NEW_VALUE, text); /* * check list field diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/FieldSerializerTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/FieldSerializerTest.java index cc5ef928..156e4ef3 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/FieldSerializerTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/FieldSerializerTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -89,7 +89,9 @@ public class FieldSerializerTest { text = "world"; - assertThatThrownBy(() -> ser.addToTree(this, new JsonObject())).isInstanceOf(JsonParseException.class) + JsonObject obj = new JsonObject(); + + assertThatThrownBy(() -> ser.addToTree(this, obj)).isInstanceOf(JsonParseException.class) .hasMessage(FieldSerializer.GET_ERR + FieldSerializerTest.class.getName() + ".text"); } } 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 index 6be4e590..5e73d06e 100644 --- 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 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. @@ -33,6 +33,7 @@ import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; +import lombok.ToString; import org.junit.Before; import org.junit.Test; @@ -138,6 +139,7 @@ public class JacksonTypeAdapterTest { assertEquals("read text", data); } + @ToString private static class Data { private String id; private String value; @@ -155,11 +157,6 @@ public class JacksonTypeAdapterTest { this.id = id; this.value = value; } - - @Override - public String toString() { - return "Data [id=" + id + ", value=" + value + "]"; - } } private abstract static class NamedSer implements Serializer { diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/MethodAdapterTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/MethodAdapterTest.java index 9f39e3ce..6c13865d 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/MethodAdapterTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/MethodAdapterTest.java @@ -1,8 +1,8 @@ -/* +/*-- * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -26,7 +26,6 @@ import static org.junit.Assert.assertEquals; import com.google.gson.Gson; import com.google.gson.JsonParseException; import org.junit.Test; -import org.onap.policy.common.gson.internal.MethodAdapter; public class MethodAdapterTest { private static final Gson gson = new Gson(); @@ -36,16 +35,16 @@ public class MethodAdapterTest { @Test public void testMethodAdapter_testInvoke() throws Exception { MethodAdapter adapter = - new MethodAdapter(gson, MethodAdapterTest.class.getDeclaredMethod("getValue"), String.class); + new MethodAdapter(gson, MethodAdapterTest.class.getDeclaredMethod("getValue"), String.class); assertEquals("hello", adapter.invoke(this)); MethodAdapter adapter2 = new MethodAdapter(gson, - MethodAdapterTest.class.getDeclaredMethod("setValue", String.class), String.class); + MethodAdapterTest.class.getDeclaredMethod("setValue", String.class), String.class); adapter2.invoke(this, "world"); assertEquals("world", saved); assertThatThrownBy(() -> adapter2.invoke(this, 100)).isInstanceOf(JsonParseException.class) - .hasMessage(MethodAdapter.INVOKE_ERR + MethodAdapterTest.class.getName() + ".setValue"); + .hasMessage(MethodAdapter.INVOKE_ERR + MethodAdapterTest.class.getName() + ".setValue"); } public String getValue() { diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/MethodDeserializerTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/MethodDeserializerTest.java index 338644ae..7fcfca18 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/MethodDeserializerTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/MethodDeserializerTest.java @@ -1,8 +1,8 @@ -/* +/*-- * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -32,7 +32,6 @@ import java.util.List; import org.junit.Test; import org.onap.policy.common.gson.JacksonExclusionStrategy; import org.onap.policy.common.gson.internal.DataAdapterFactory.Data; -import org.onap.policy.common.gson.internal.MethodDeserializer; public class MethodDeserializerTest { private static final String PROP_NAME = "text"; @@ -43,7 +42,7 @@ public class MethodDeserializerTest { private static DataAdapterFactory dataAdapter = new DataAdapterFactory(); private static Gson gson = new GsonBuilder().registerTypeAdapterFactory(dataAdapter) - .setExclusionStrategies(new JacksonExclusionStrategy()).create(); + .setExclusionStrategies(new JacksonExclusionStrategy()).create(); private MethodDeserializer deser; diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/MethodSerializerTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/MethodSerializerTest.java index 586bf54d..ed240513 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/MethodSerializerTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/MethodSerializerTest.java @@ -1,8 +1,8 @@ -/* +/*-- * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -31,7 +31,6 @@ import java.util.List; import org.junit.Test; import org.onap.policy.common.gson.JacksonExclusionStrategy; import org.onap.policy.common.gson.internal.DataAdapterFactory.Data; -import org.onap.policy.common.gson.internal.MethodSerializer; public class MethodSerializerTest { private static final String PROP_NAME = "text"; @@ -40,7 +39,7 @@ public class MethodSerializerTest { private static DataAdapterFactory dataAdapter = new DataAdapterFactory(); private static Gson gson = new GsonBuilder().registerTypeAdapterFactory(dataAdapter) - .setExclusionStrategies(new JacksonExclusionStrategy()).create(); + .setExclusionStrategies(new JacksonExclusionStrategy()).create(); private MethodSerializer ser; |