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

io.rtr.alchemy.mapping.Mappers Maven / Gradle / Ivy

The newest version!
package io.rtr.alchemy.mapping;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.util.Arrays;
import java.util.Map;
import java.util.Set;

/** The main class for registering mappers and doing mapping */
public class Mappers {
    private final Map, Map, Mapper>> mappers = Maps.newConcurrentMap();

    public void register(Class dtoType, Class boType, Mapper mapper) {
        registerMapper(dtoType, boType, mapper);
        registerMapper(boType, dtoType, mapper);
    }

    private void registerMapper(Class sourceType, Class destType, Mapper mapper) {
        Map, Mapper> bySourceType = mappers.get(sourceType);

        if (bySourceType == null) {
            bySourceType = Maps.newConcurrentMap();
            mappers.put(sourceType, bySourceType);
        }

        Class targetType = destType;
        final Set> interfaces = Sets.newHashSet();

        while (!targetType.equals(Object.class)) {
            bySourceType.put(targetType, mapper);
            interfaces.addAll(Arrays.asList(targetType.getInterfaces()));
            targetType = targetType.getSuperclass();
        }

        for (final Class ifaceType : interfaces) {
            bySourceType.put(ifaceType, mapper);
        }
    }

    private Mapper findMapper(Class sourceType, Class destType) {
        Class mappableType = sourceType;
        Map, Mapper> bySourceType = mappers.get(mappableType);

        while (bySourceType == null && !mappableType.equals(Object.class)) {
            mappableType = mappableType.getSuperclass();
            bySourceType = mappers.get(mappableType);
        }

        Preconditions.checkNotNull(
                bySourceType, "No mapper defined from type %s to type %s", sourceType, destType);

        final Mapper mapper = bySourceType.get(destType);

        Preconditions.checkArgument(
                mapper != null, "No mapper defined from type %s to type %s", sourceType, destType);

        return mapper;
    }

    public  T toDto(Object source, Class destinationType) {
        if (source == null) {
            return null;
        }

        @SuppressWarnings("unchecked")
        final Mapper mapper = findMapper(source.getClass(), destinationType);
        return mapper.toDto(source);
    }

    public  T fromDto(Object source, Class destinationType) {
        if (source == null) {
            return null;
        }

        @SuppressWarnings("unchecked")
        final Mapper mapper = findMapper(source.getClass(), destinationType);
        return mapper.fromDto(source);
    }

    public  Iterable toDto(Iterable source, Class desinationType) {
        if (source == null) {
            return null;
        }

        final ImmutableList.Builder builder = ImmutableList.builder();
        for (final Object item : source) {
            builder.add(toDto(item, desinationType));
        }

        return builder.build();
    }

    public  Iterable fromDto(Iterable source, Class desinationType) {
        if (source == null) {
            return null;
        }

        final ImmutableList.Builder builder = ImmutableList.builder();
        for (final Object item : source) {
            builder.add(fromDto(item, desinationType));
        }

        return builder.build();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy