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

io.lettuce.core.dynamic.ConversionService Maven / Gradle / Ivy

Go to download

Advanced and thread-safe Java Redis client for synchronous, asynchronous, and reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs and much more.

The newest version!
package io.lettuce.core.dynamic;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

import io.lettuce.core.dynamic.support.ClassTypeInformation;
import io.lettuce.core.dynamic.support.TypeInformation;
import io.lettuce.core.internal.LettuceAssert;

/**
 * @author Mark Paluch
 */
class ConversionService {

    private Map> converterMap = new HashMap<>(10);

    /**
     * Register a converter {@link Function}.
     *
     * @param converter the converter.
     */
    @SuppressWarnings("rawtypes")
    public void addConverter(Function converter) {

        LettuceAssert.notNull(converter, "Converter must not be null");

        ClassTypeInformation classTypeInformation = ClassTypeInformation.from(converter.getClass());
        TypeInformation typeInformation = classTypeInformation.getSuperTypeInformation(Function.class);
        List> typeArguments = typeInformation.getTypeArguments();

        ConvertiblePair pair = new ConvertiblePair(typeArguments.get(0).getType(), typeArguments.get(1).getType());
        converterMap.put(pair, converter);
    }

    @SuppressWarnings("unchecked")
    public  T convert(S source, Class targetType) {

        LettuceAssert.notNull(source, "Source must not be null");

        return (T) getConverter(source.getClass(), targetType).apply(source);
    }

    public  boolean canConvert(Class sourceType, Class targetType) {
        return findConverter(sourceType, targetType).isPresent();
    }

    @SuppressWarnings("unchecked")
    Function getConverter(Class source, Class target) {
        return findConverter(source, target).orElseThrow(() -> new IllegalArgumentException(
                String.format("No converter found for %s to %s conversion", source.getName(), target.getName())));
    }

    private Optional> findConverter(Class source, Class target) {
        LettuceAssert.notNull(source, "Source type must not be null");
        LettuceAssert.notNull(target, "Target type must not be null");

        for (ConvertiblePair pair : converterMap.keySet()) {

            if (pair.getSourceType().isAssignableFrom(source) && target.isAssignableFrom(pair.getTargetType())) {
                return Optional.of((Function) converterMap.get(pair));
            }
        }
        return Optional.empty();
    }

    /**
     * Holder for a source-to-target class pair.
     */
    final class ConvertiblePair {

        private final Class sourceType;

        private final Class targetType;

        /**
         * Create a new source-to-target pair.
         *
         * @param sourceType the source type
         * @param targetType the target type
         */
        public ConvertiblePair(Class sourceType, Class targetType) {

            LettuceAssert.notNull(sourceType, "Source type must not be null");
            LettuceAssert.notNull(targetType, "Target type must not be null");
            this.sourceType = sourceType;
            this.targetType = targetType;
        }

        public Class getSourceType() {
            return this.sourceType;
        }

        public Class getTargetType() {
            return this.targetType;
        }

        @Override
        public boolean equals(Object other) {
            if (this == other) {
                return true;
            }
            if (other == null || other.getClass() != ConvertiblePair.class) {
                return false;
            }
            ConvertiblePair otherPair = (ConvertiblePair) other;
            return (this.sourceType == otherPair.sourceType && this.targetType == otherPair.targetType);
        }

        @Override
        public int hashCode() {
            return (this.sourceType.hashCode() * 31 + this.targetType.hashCode());
        }

        @Override
        public String toString() {
            return (this.sourceType.getName() + " -> " + this.targetType.getName());
        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy