All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.yasson.internal.serializer.DefaultSerializers Maven / Gradle / Ivy

/*
 * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

package org.eclipse.yasson.internal.serializer;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Period;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.TimeZone;
import java.util.UUID;

import jakarta.json.JsonArray;
import jakarta.json.JsonNumber;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;

import javax.xml.datatype.XMLGregorianCalendar;

/**
 * Cache of default serializers.
 */
public class DefaultSerializers {

    private static final Map, SerializerProviderWrapper> SERIALIZERS = initSerializers();

    private static final SerializerProviderWrapper ENUM_PROVIDER = new SerializerProviderWrapper(EnumTypeSerializer::new, EnumTypeDeserializer::new);

    private DefaultSerializers() {
    }

    private static Map, SerializerProviderWrapper> initSerializers() {
        final Map, SerializerProviderWrapper> serializers = new HashMap<>();

        serializers.put(Boolean.class, new SerializerProviderWrapper(BooleanTypeSerializer::new, BooleanTypeDeserializer::new));
        serializers.put(Boolean.TYPE, new SerializerProviderWrapper(BooleanTypeSerializer::new, BooleanTypeDeserializer::new));
        serializers.put(Byte.class, new SerializerProviderWrapper(ByteTypeSerializer::new, ByteTypeDeserializer::new));
        serializers.put(Byte.TYPE, new SerializerProviderWrapper(ByteTypeSerializer::new, ByteTypeDeserializer::new));
        serializers
                .put(Calendar.class, new SerializerProviderWrapper(CalendarTypeSerializer::new, CalendarTypeDeserializer::new));
        serializers.put(GregorianCalendar.class,
                        new SerializerProviderWrapper(CalendarTypeSerializer::new, CalendarTypeDeserializer::new));
        serializers.put(Character.class,
                        new SerializerProviderWrapper(CharacterTypeSerializer::new, CharacterTypeDeserializer::new));
        serializers
                .put(Character.TYPE, new SerializerProviderWrapper(CharacterTypeSerializer::new, CharacterTypeDeserializer::new));
        
        if (isClassAvailable("java.sql.Date")) {
            serializers.put(Date.class, new SerializerProviderWrapper(SqlDateTypeSerializer::new, DateTypeDeserializer::new));
            serializers.put(java.sql.Date.class,
                    new SerializerProviderWrapper(SqlDateTypeSerializer::new, SqlDateTypeDeserializer::new));
            serializers.put(java.sql.Timestamp.class,
                    new SerializerProviderWrapper(SqlTimestampTypeSerializer::new, SqlTimestampTypeDeserializer::new));
        } else {
            serializers.put(Date.class, new SerializerProviderWrapper(DateTypeSerializer::new, DateTypeDeserializer::new));
        }
        
        serializers.put(Double.class, new SerializerProviderWrapper(DoubleTypeSerializer::new, DoubleTypeDeserializer::new));
        serializers.put(Double.TYPE, new SerializerProviderWrapper(DoubleTypeSerializer::new, DoubleTypeDeserializer::new));
        serializers.put(Float.class, new SerializerProviderWrapper(FloatTypeSerializer::new, FloatTypeDeserializer::new));
        serializers.put(Float.TYPE, new SerializerProviderWrapper(FloatTypeSerializer::new, FloatTypeDeserializer::new));
        serializers.put(Instant.class, new SerializerProviderWrapper(InstantTypeSerializer::new, InstantTypeDeserializer::new));
        serializers.put(Integer.class, new SerializerProviderWrapper(IntegerTypeSerializer::new, IntegerTypeDeserializer::new));
        serializers.put(Integer.TYPE, new SerializerProviderWrapper(IntegerTypeSerializer::new, IntegerTypeDeserializer::new));
        serializers
                .put(JsonNumber.class, new SerializerProviderWrapper(JsonValueSerializer::new, JsonNumberTypeDeserializer::new));
        serializers
                .put(JsonString.class, new SerializerProviderWrapper(JsonValueSerializer::new, JsonStringTypeDeserializer::new));
        serializers.put(JsonValue.class, new SerializerProviderWrapper(JsonValueSerializer::new, JsonValueDeserializer::new));
        serializers.put(LocalDateTime.class,
                        new SerializerProviderWrapper(LocalDateTimeTypeSerializer::new, LocalDateTimeTypeDeserializer::new));
        serializers.put(LocalDate.class,
                        new SerializerProviderWrapper(LocalDateTypeSerializer::new, LocalDateTypeDeserializer::new));
        serializers.put(LocalTime.class,
                        new SerializerProviderWrapper(LocalTimeTypeSerializer::new, LocalTimeTypeDeserializer::new));
        serializers.put(Long.class, new SerializerProviderWrapper(LongTypeSerializer::new, LongTypeDeserializer::new));
        serializers.put(Long.TYPE, new SerializerProviderWrapper(LongTypeSerializer::new, LongTypeDeserializer::new));
        serializers.put(Number.class, new SerializerProviderWrapper(NumberTypeSerializer::new, NumberTypeDeserializer::new));
        serializers.put(OffsetDateTime.class,
                        new SerializerProviderWrapper(OffsetDateTimeTypeSerializer::new, OffsetDateTimeTypeDeserializer::new));
        serializers.put(OffsetTime.class,
                        new SerializerProviderWrapper(OffsetTimeTypeSerializer::new, OffsetTimeTypeDeserializer::new));
        serializers.put(OptionalDouble.class,
                        new SerializerProviderWrapper(OptionalDoubleTypeSerializer::new, OptionalDoubleTypeDeserializer::new));
        serializers.put(OptionalInt.class,
                        new SerializerProviderWrapper(OptionalIntTypeSerializer::new, OptionalIntTypeDeserializer::new));
        serializers.put(OptionalLong.class,
                        new SerializerProviderWrapper(OptionalLongTypeSerializer::new, OptionalLongTypeDeserializer::new));
        serializers.put(Path.class,
                        new SerializerProviderWrapper(PathTypeSerializer::new, PathTypeDeserializer::new));
        serializers.put(Short.class, new SerializerProviderWrapper(ShortTypeSerializer::new, ShortTypeDeserializer::new));
        serializers.put(Short.TYPE, new SerializerProviderWrapper(ShortTypeSerializer::new, ShortTypeDeserializer::new));
        serializers.put(String.class, new SerializerProviderWrapper(StringTypeSerializer::new, StringTypeDeserializer::new));
        serializers
                .put(TimeZone.class, new SerializerProviderWrapper(TimeZoneTypeSerializer::new, TimeZoneTypeDeserializer::new));
        serializers.put(URI.class, new SerializerProviderWrapper(URITypeSerializer::new, URITypeDeserializer::new));
        serializers.put(URL.class, new SerializerProviderWrapper(URLTypeSerializer::new, URLTypeDeserializer::new));
        serializers.put(UUID.class, new SerializerProviderWrapper(UUIDTypeSerializer::new, UUIDTypeDeserializer::new));
        serializers.put(ZonedDateTime.class,
                        new SerializerProviderWrapper(ZonedDateTimeTypeSerializer::new, ZonedDateTimeTypeDeserializer::new));
        serializers
                .put(Duration.class, new SerializerProviderWrapper(DurationTypeSerializer::new, DurationTypeDeserializer::new));
        serializers.put(Period.class, new SerializerProviderWrapper(PeriodTypeSerializer::new, PeriodTypeDeserializer::new));
        serializers.put(ZoneId.class, new SerializerProviderWrapper(ZoneIdTypeSerializer::new, ZoneIdTypeDeserializer::new));
        serializers.put(BigInteger.class,
                        new SerializerProviderWrapper(BigIntegerTypeSerializer::new, BigIntegerTypeDeserializer::new));
        serializers.put(BigDecimal.class,
                        new SerializerProviderWrapper(BigDecimalTypeSerializer::new, BigDecimalTypeDeserializer::new));
        serializers.put(ZoneOffset.class,
                        new SerializerProviderWrapper(ZoneOffsetTypeSerializer::new, ZoneOffsetTypeDeserializer::new));
        
        if (isClassAvailable("javax.xml.datatype.XMLGregorianCalendar")) {
            serializers.put(XMLGregorianCalendar.class,
                    new SerializerProviderWrapper(XMLGregorianCalendarTypeSerializer::new,
                                                  XMLGregorianCalendarTypeDeserializer::new));
        }
        
        serializers.put(YearMonth.class,
                        new SerializerProviderWrapper(YearMonthTypeSerializer::new, YearMonthTypeDeserializer::new));
        serializers.put(MonthDay.class,
                        new SerializerProviderWrapper(MonthDayTypeSerializer::new, MonthDayTypeDeserializer::new));

        return serializers;
    }

    /**
     * Look for a provider for a supported value type. These serializers are basically singleton stateless shared instances.
     *
     * @param clazz supported type class
     * @param    Type of serializer
     * @return serializer if found
     */
    public static  Optional findValueSerializerProvider(Class clazz) {
        Class candidate = clazz;
        do {
            final SerializerProviderWrapper provider = SERIALIZERS.get(candidate);
            if (provider != null) {
                return Optional.of(provider);
            }
            candidate = candidate.getSuperclass();
        } while (candidate != null);

        return findByCondition(clazz);
    }

    private static  Optional findByCondition(Class clazz) {
        if (Enum.class.isAssignableFrom(clazz)) {
            return Optional.of(ENUM_PROVIDER);
        } else if (JsonString.class.isAssignableFrom(clazz)) {
            return Optional.of(SERIALIZERS.get(JsonString.class));
        } else if (JsonNumber.class.isAssignableFrom(clazz)) {
            return Optional.of(SERIALIZERS.get(JsonNumber.class));
        } else if (JsonValue.class.isAssignableFrom(clazz) && !(
                JsonObject.class.isAssignableFrom(clazz) || JsonArray.class.isAssignableFrom(clazz))) {
            return Optional.of(SERIALIZERS.get(JsonValue.class));
        }
        return Optional.empty();
    }

    /**
     * Checks a class if it is supported by Yasson builtin serializers/deserializers in order to decide if it
     * should be introspected with reflection.
     *
     * @param clazz class to check
     * @return true if supported
     */
    public static boolean isKnownType(Class clazz) {
        boolean knownContainerValueType = Collection.class.isAssignableFrom(clazz)
                || Map.class.isAssignableFrom(clazz)
                || JsonValue.class.isAssignableFrom(clazz)
                || Optional.class.isAssignableFrom(clazz)
                || clazz.isArray();

        return knownContainerValueType || findValueSerializerProvider(clazz).isPresent();
    }
    
    private static boolean isClassAvailable(String className) {
        try {
            Class.forName(className);
            return true;
        } catch (ClassNotFoundException | LinkageError e) {
            return false;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy