package org.jooq.impl;
import static org.jooq.tools.reflect.Reflect.wrapper;
import java.io.File;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.sql.Struct;
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
import org.jooq.Converter;
import org.jooq.ConverterProvider;
import org.jooq.EnumType;
import org.jooq.JSON;
import org.jooq.JSONB;
import org.jooq.Record;
import org.jooq.UDTRecord;
import org.jooq.XML;
import org.jooq.tools.Convert;
import org.jetbrains.annotations.Nullable;
public final class DefaultConverterProvider implements ConverterProvider, Serializable {
private static final long serialVersionUID = 2937225066265868374L;
@Nullable
@Override
public final <T, U> Converter<T, U> provide(final Class<T> tType, final Class<U> uType) {
Class<?> tWrapper = wrapper(tType);
Class<?> uWrapper = wrapper(uType);
if (tWrapper == uWrapper
|| uWrapper.isAssignableFrom(tWrapper)
|| isCollection(tWrapper) && isCollection(uWrapper)
|| tWrapper == Optional.class
|| uWrapper == Optional.class
|| uWrapper == String.class
|| uWrapper == byte[].class
|| Number.class.isAssignableFrom(uWrapper)
|| Boolean.class.isAssignableFrom(uWrapper)
|| Character.class.isAssignableFrom(uWrapper)
|| uWrapper == URI.class && tWrapper == String.class
|| uWrapper == URL.class && tWrapper == String.class
|| uWrapper == File.class && tWrapper == String.class
|| isDate(tWrapper) && isDate(uWrapper)
|| isEnum(tWrapper) && isEnum(uWrapper)
|| isUUID(tWrapper) && isUUID(uWrapper)
|| isJSON(tWrapper)
|| isXML(tWrapper)
|| Record.class.isAssignableFrom(tWrapper)
|| Struct.class.isAssignableFrom(tWrapper) && UDTRecord.class.isAssignableFrom(uWrapper)
) {
return new AbstractConverter<T, U>(tType, uType) {
private static final long serialVersionUID = 8011099590775678430L;
@Override
public U from(T t) {
return Convert.convert(t, uType);
}
@Override
public T to(U u) {
return Convert.convert(u, tType);
}
};
}
else
return null;
}
private final boolean isJSON(Class<?> type) {
return type == JSON.class
|| type == JSONB.class;
}
private final boolean isXML(Class<?> type) {
return type == XML.class;
}
private final boolean isUUID(Class<?> type) {
return type == String.class
|| type == byte[].class
|| type == UUID.class;
}
private final boolean isEnum(Class<?> type) {
return Enum.class.isAssignableFrom(type)
|| type == String.class
|| EnumType.class.isAssignableFrom(type);
}
private final boolean isDate(Class<?> type) {
return java.util.Date.class.isAssignableFrom(type)
|| Calendar.class.isAssignableFrom(type)
|| Temporal.class.isAssignableFrom(type)
|| type == Long.class
|| type == String.class;
}
private final boolean isCollection(Class<?> type) {
return type.isArray()
|| Collection.class.isAssignableFrom(type)
|| type == java.sql.Array.class;
}
}