Skip to content

Package: TypeSerializers

TypeSerializers

nameinstructionbranchcomplexitylinemethod
TypeSerializers()
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
getTypeSerializer(Class, Customization, JsonbContext)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getTypeSerializer(List, Class, Customization, JsonbContext, boolean)
M: 135 C: 0
0%
M: 26 C: 0
0%
M: 14 C: 0
0%
M: 31 C: 0
0%
M: 1 C: 0
0%
isSupportedMapKey(Class)
M: 12 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 287 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 61 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0 which is available at
6: * http://www.eclipse.org/legal/epl-2.0,
7: * or the Eclipse Distribution License v. 1.0 which is available at
8: * http://www.eclipse.org/org/documents/edl-v10.php.
9: *
10: * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11: */
12:
13: package org.eclipse.yasson.internal.serializer.types;
14:
15: import java.lang.reflect.Type;
16: import java.math.BigDecimal;
17: import java.math.BigInteger;
18: import java.net.URI;
19: import java.net.URL;
20: import java.nio.file.Path;
21: import java.time.Duration;
22: import java.time.Instant;
23: import java.time.LocalDate;
24: import java.time.LocalDateTime;
25: import java.time.LocalTime;
26: import java.time.MonthDay;
27: import java.time.OffsetDateTime;
28: import java.time.OffsetTime;
29: import java.time.Period;
30: import java.time.YearMonth;
31: import java.time.ZoneId;
32: import java.time.ZoneOffset;
33: import java.time.ZonedDateTime;
34: import java.util.Calendar;
35: import java.util.Collections;
36: import java.util.Date;
37: import java.util.HashMap;
38: import java.util.HashSet;
39: import java.util.LinkedList;
40: import java.util.List;
41: import java.util.Map;
42: import java.util.OptionalDouble;
43: import java.util.OptionalInt;
44: import java.util.OptionalLong;
45: import java.util.Set;
46: import java.util.TimeZone;
47: import java.util.UUID;
48: import java.util.function.Function;
49:
50: import javax.xml.datatype.XMLGregorianCalendar;
51:
52: import jakarta.json.JsonNumber;
53: import jakarta.json.JsonString;
54: import jakarta.json.JsonValue;
55: import jakarta.json.bind.JsonbException;
56:
57: import org.eclipse.yasson.internal.JsonbContext;
58: import org.eclipse.yasson.internal.model.customization.Customization;
59: import org.eclipse.yasson.internal.serializer.ModelSerializer;
60: import org.eclipse.yasson.internal.serializer.SerializationModelCreator;
61:
62: import static org.eclipse.yasson.internal.BuiltInTypes.isClassAvailable;
63:
64: /**
65: * Specific type serializers.
66: */
67: public class TypeSerializers {
68:
69: private static final Map<Class<?>, Function<TypeSerializerBuilder, ModelSerializer>> SERIALIZERS;
70: private static final Set<Class<?>> SUPPORTED_MAP_KEYS;
71:
72: private static final Map<Class<?>, Class<?>> OPTIONALS;
73:
74: static {
75: Map<Class<?>, Function<TypeSerializerBuilder, ModelSerializer>> cache = new HashMap<>();
76: cache.put(Byte.class, ByteSerializer::new);
77: cache.put(Byte.TYPE, ByteSerializer::new);
78: cache.put(BigDecimal.class, BigDecimalSerializer::new);
79: cache.put(BigInteger.class, BigIntegerSerializer::new);
80: cache.put(Boolean.class, BooleanSerializer::new);
81: cache.put(Boolean.TYPE, BooleanSerializer::new);
82: cache.put(Calendar.class, CalendarSerializer::new);
83: cache.put(Character.class, CharSerializer::new);
84: cache.put(Character.TYPE, CharSerializer::new);
85: cache.put(Date.class, DateSerializer::new);
86: cache.put(Double.class, DoubleSerializer::new);
87: cache.put(Double.TYPE, DoubleSerializer::new);
88: cache.put(Duration.class, DurationSerializer::new);
89: cache.put(Float.class, FloatSerializer::new);
90: cache.put(Float.TYPE, FloatSerializer::new);
91: cache.put(Integer.class, IntegerSerializer::new);
92: cache.put(Integer.TYPE, IntegerSerializer::new);
93: cache.put(Instant.class, InstantSerializer::new);
94: cache.put(LocalDateTime.class, LocalDateTimeSerializer::new);
95: cache.put(LocalDate.class, LocalDateSerializer::new);
96: cache.put(LocalTime.class, LocalTimeSerializer::new);
97: cache.put(Long.class, LongSerializer::new);
98: cache.put(Long.TYPE, LongSerializer::new);
99: cache.put(MonthDay.class, MonthDayTypeSerializer::new);
100: cache.put(Number.class, NumberSerializer::new);
101: cache.put(Object.class, ObjectTypeSerializer::new);
102: cache.put(OffsetDateTime.class, OffsetDateTimeSerializer::new);
103: cache.put(OffsetTime.class, OffsetTimeSerializer::new);
104: cache.put(Path.class, PathSerializer::new);
105: cache.put(Period.class, PeriodSerializer::new);
106: cache.put(Short.class, ShortSerializer::new);
107: cache.put(Short.TYPE, ShortSerializer::new);
108: cache.put(String.class, StringSerializer::new);
109: cache.put(TimeZone.class, TimeZoneSerializer::new);
110: cache.put(URI.class, UriSerializer::new);
111: cache.put(URL.class, UrlSerializer::new);
112: cache.put(UUID.class, UuidSerializer::new);
113:• if (isClassAvailable("javax.xml.datatype.XMLGregorianCalendar")) {
114: cache.put(XMLGregorianCalendar.class, XmlGregorianCalendarSerializer::new);
115: }
116: cache.put(YearMonth.class, YearMonthTypeSerializer::new);
117: cache.put(ZonedDateTime.class, ZonedDateTimeSerializer::new);
118: cache.put(ZoneId.class, ZoneIdSerializer::new);
119: cache.put(ZoneOffset.class, ZoneOffsetSerializer::new);
120:• if (isClassAvailable("java.sql.Date")) {
121: cache.put(Date.class, SqlDateSerializer::new);
122: cache.put(java.sql.Date.class, SqlDateSerializer::new);
123: cache.put(java.sql.Timestamp.class, SqlTimestampSerializer::new);
124: }
125: SERIALIZERS = Map.copyOf(cache);
126:
127: Map<Class<?>, Class<?>> optionals = new HashMap<>();
128: optionals.put(OptionalDouble.class, Double.class);
129: optionals.put(OptionalInt.class, Integer.class);
130: optionals.put(OptionalLong.class, Long.class);
131: OPTIONALS = Map.copyOf(optionals);
132:
133: Set<Class<?>> mapKeys = new HashSet<>(SERIALIZERS.keySet());
134: mapKeys.addAll(optionals.keySet());
135: mapKeys.add(JsonNumber.class);
136: mapKeys.add(JsonString.class);
137: mapKeys.remove(Object.class);
138: SUPPORTED_MAP_KEYS = Set.copyOf(mapKeys);
139:
140: }
141:
142: private TypeSerializers() {
143: throw new IllegalStateException("Util class cannot be instantiated");
144: }
145:
146: /**
147: * Whether type is the supported key type.
148: *
149: * @param clazz key type
150: * @return whether type is supported key type
151: */
152: public static boolean isSupportedMapKey(Class<?> clazz) {
153:• return Enum.class.isAssignableFrom(clazz) || SUPPORTED_MAP_KEYS.contains(clazz);
154: }
155:
156: /**
157: * Create new type serializer.
158: *
159: * @param clazz type of the serializer
160: * @param customization serializer customization
161: * @param jsonbContext jsonb context
162: * @return new type serializer
163: */
164: public static ModelSerializer getTypeSerializer(Class<?> clazz, Customization customization, JsonbContext jsonbContext) {
165: return getTypeSerializer(Collections.emptyList(), clazz, customization, jsonbContext, false);
166: }
167:
168: /**
169: * Create new type serializer.
170: *
171: * @param chain chain of the type predecessors
172: * @param clazz type of the serializer
173: * @param customization serializer customization
174: * @param jsonbContext jsonb context
175: * @param key whether serializer is a key
176: * @return new type serializer
177: */
178: public static ModelSerializer getTypeSerializer(List<Type> chain,
179: Class<?> clazz,
180: Customization customization,
181: JsonbContext jsonbContext,
182: boolean key) {
183: Class<?> current = clazz;
184: List<Type> chainClone = new LinkedList<>(chain);
185: TypeSerializerBuilder builder = new TypeSerializerBuilder(chainClone, clazz, customization, jsonbContext, key);
186: ModelSerializer typeSerializer = null;
187:• if (Object.class.equals(current)) {
188: return SERIALIZERS.get(current).apply(builder);
189: }
190:• if (OPTIONALS.containsKey(current)) {
191: Class<?> optionalInner = OPTIONALS.get(current);
192: ModelSerializer serializer = getTypeSerializer(chainClone, optionalInner, customization, jsonbContext, key);
193:• if (OptionalInt.class.equals(current)) {
194: return new OptionalIntSerializer(serializer);
195:• } else if (OptionalLong.class.equals(current)) {
196: return new OptionalLongSerializer(serializer);
197:• } else if (OptionalDouble.class.equals(current)) {
198: return new OptionalDoubleSerializer(serializer);
199: } else {
200: throw new JsonbException("Unsupported Optional type for serialization: " + clazz);
201: }
202: }
203:
204:• if (Enum.class.isAssignableFrom(clazz)) {
205: typeSerializer = new EnumSerializer(builder);
206:• } else if (JsonValue.class.isAssignableFrom(clazz)) {
207: typeSerializer = new JsonValueSerializer(builder);
208: }
209:• if (typeSerializer == null) {
210: do {
211:• if (SERIALIZERS.containsKey(current)) {
212: typeSerializer = SERIALIZERS.get(current).apply(builder);
213: break;
214: }
215: current = current.getSuperclass();
216:• } while (!Object.class.equals(current) && current != null);
217: }
218:
219:• if (key) {
220: //We do not want any other special serializers around our type serializer if it will be used as a key
221: return typeSerializer;
222: }
223:• return typeSerializer == null
224: ? null
225: : SerializationModelCreator.wrapInCommonSet(typeSerializer, customization, jsonbContext);
226: }
227:
228: }