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

com.github.molcikas.photon.converters.Convert Maven / Gradle / Ivy

The newest version!
package com.github.molcikas.photon.converters;

import com.github.molcikas.photon.converters.date.*;
import com.github.molcikas.photon.converters.number.*;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Static class used to register new converters.
 * Also used internally by sql2o to lookup a converter.
 */
@SuppressWarnings("unchecked")
public class Convert {

    private static final ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();
    private static final ReentrantReadWriteLock.ReadLock rl = rrwl.readLock();
    private static final ReentrantReadWriteLock.WriteLock wl = rrwl.writeLock();
    private static volatile EnumConverterFactory registeredEnumConverterFactory = new DefaultEnumConverterFactory();
    private static Map, Converter> registeredConverters = new HashMap, Converter>();

    private static void processProvider(ConvertersProvider convertersProvider) {
        convertersProvider.fill(registeredConverters);
    }

    private static void fillDefaults(Map, Converter> mapToFill) {
        mapToFill.put(Integer.class, new IntegerConverter(false));
        mapToFill.put(int.class, new IntegerConverter(true));

        mapToFill.put(Double.class, new DoubleConverter(false));
        mapToFill.put(double.class, new DoubleConverter(true));

        mapToFill.put(Float.class, new FloatConverter(false));
        mapToFill.put(float.class, new FloatConverter(true));

        mapToFill.put(Long.class, new LongConverter(false));
        mapToFill.put(long.class, new LongConverter(true));

        mapToFill.put(Short.class, new ShortConverter(false));
        mapToFill.put(short.class, new ShortConverter(true));

        mapToFill.put(Byte.class, new ByteConverter(false));
        mapToFill.put(byte.class, new ByteConverter(true));

        mapToFill.put(BigDecimal.class, new BigDecimalConverter());

        mapToFill.put(String.class, new StringConverter());

        mapToFill.put(Timestamp.class, new TimestampConverter());
        mapToFill.put(Date.class, new DateConverter());
        mapToFill.put(Instant.class, new InstantConverter());
        mapToFill.put(LocalDate.class, new LocalDateConverter());
        mapToFill.put(LocalDateTime.class, new LocalDateTimeConverter());
        mapToFill.put(ZonedDateTime.class, new ZonedDateTimeConverter());

        BooleanConverter booleanConverter = new BooleanConverter();
        mapToFill.put(Boolean.class, booleanConverter);
        mapToFill.put(boolean.class, booleanConverter);

        ByteArrayConverter byteArrayConverter = new ByteArrayConverter();
        //it's impossible to cast Byte[].class <-> byte[].class
        // and I'm too lazy to implement converter for Byte[].class
        // since it's really doesn't wide-used
        // otherwise someone already detect this error
        //mapToFill.put(Byte[].class, byteArrayConverter);
        mapToFill.put(byte[].class, byteArrayConverter);

        InputStreamConverter inputStreamConverter = new InputStreamConverter();
        mapToFill.put(InputStream.class, inputStreamConverter);
        mapToFill.put(ByteArrayInputStream.class, inputStreamConverter);

        mapToFill.put(UUID.class, new UUIDConverter());
    }


    static {
        fillDefaults(registeredConverters);
        ServiceLoader loader = ServiceLoader.load(ConvertersProvider.class);
        for (ConvertersProvider provider : loader) {
            processProvider(provider);
        }
    }

    public static Converter getConverter(Class clazz) throws ConverterException {
        return throwIfNull(clazz, getConverterIfExists(clazz));
    }

    public static  Converter throwIfNull(Class clazz, Converter converter) throws ConverterException {
        if (converter == null) {
            throw new ConverterException("No converter registered for class: " + clazz.getName());
        }
        return converter;
    }

    public static  Converter getConverterIfExists(Class clazz) {
        Converter c;
        rl.lock();
        try {
            c = registeredConverters.get(clazz);
        } finally {
            rl.unlock();
        }
        if (c != null) return c;

        if (clazz.isEnum()) {
            return registeredEnumConverterFactory.newConverter((Class) clazz);
        }
        return null;
    }

    public static void registerConverter(Class clazz, Converter converter) {
        wl.lock();
        try {
            registerConverter0(clazz, converter);
        } finally {
            wl.unlock();
        }
    }


    private static void registerConverter0(Class clazz, Converter converter) {
        registeredConverters.put(clazz, converter);
    }

    @SuppressWarnings("UnusedDeclaration")
    public static void registerEnumConverter(EnumConverterFactory enumConverterFactory) {
        if (enumConverterFactory == null) throw new IllegalArgumentException();
        registeredEnumConverterFactory = enumConverterFactory;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy