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

fun.fengwk.convention4j.springboot.test.starter.repo.AbstractTestRepository Maven / Gradle / Ivy

The newest version!
package fun.fengwk.convention4j.springboot.test.starter.repo;

import fun.fengwk.convention4j.api.page.Page;
import fun.fengwk.convention4j.api.page.PageQuery;
import fun.fengwk.convention4j.common.json.JsonUtils;
import fun.fengwk.convention4j.common.page.Pages;
import org.springframework.beans.BeanUtils;
import org.springframework.core.ResolvableType;
import org.springframework.util.ReflectionUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author fengwk
 */
public abstract class AbstractTestRepository {

    protected final ConcurrentMap entityMap = new ConcurrentHashMap<>();

    protected abstract ID getId(ENTITY entity);

    protected boolean doInsert(ENTITY entity) {
        if (entity == null) {
            return false;
        }
        ENTITY copiedEntity = copy(entity);
        ID id = getId(copiedEntity);
        return entityMap.putIfAbsent(id, copiedEntity) == null;
    }

    protected int doInsertAll(Collection entities) {
        int inserted = 0;
        for (ENTITY entity : entities) {
            if (doInsert(entity)) {
                inserted++;
            }
        }
        return inserted;
    }

    protected boolean doDeleteById(ID id) {
        return entityMap.remove(id) != null;
    }

    protected boolean doUpdateById(ENTITY entity) {
        if (entity == null) {
            return false;
        }
        ENTITY copiedEntity = copy(entity);
        ID id = getId(copiedEntity);
        return entityMap.computeIfPresent(id, (k, v) -> copiedEntity) != null;
    }

    protected ENTITY doGetById(ID id) {
        return copy(entityMap.get(id));
    }

    protected int doDelete(Predicate predicate) {
        int deleted = 0;
        for (ENTITY entity : doList(predicate)) {
            ID id = getId(entity);
            if (doDeleteById(id)) {
                deleted++;
            }
        }
        return deleted;
    }

    protected int doUpdate(Predicate predicate, Function updater) {
        int updated = 0;
        for (ENTITY entity : doList(predicate)) {
            ID id = getId(entity);
            if (updater.apply(entity)) {
                entityMap.remove(id);
                entityMap.put(getId(entity), entity);
                updated++;
            }
        }
        return updated;
    }

    protected int doUpdate(Predicate predicate, Supplier newEntitySupplier) {
        return doUpdate(predicate, entity -> {
            ENTITY newEntity = newEntitySupplier.get();
            if (newEntity == null) {
                return false;
            }
            copyProperties(newEntity, entity);
            return true;
        });
    }

    protected int doUpdateSelective(Predicate predicate, Supplier newEntitySupplier) {
        return doUpdate(predicate, entity -> {
            ENTITY newEntity = newEntitySupplier.get();
            if (newEntity == null) {
                return false;
            }
            copyPropertiesSelective(newEntity, entity);
            return true;
        });
    }

    protected ENTITY doGet(Predicate predicate) {
        return entityMap.values().stream()
            .filter(predicate).findFirst()
            .map(this::copy).orElse(null);
    }

    protected List doList(Predicate predicate) {
        return entityMap.values().stream()
            .filter(predicate).map(this::copy).collect(Collectors.toList());
    }

    protected List doList(Predicate predicate, Comparator order) {
        return entityMap.values().stream()
            .sorted(order).filter(predicate).map(this::copy).collect(Collectors.toList());
    }

    protected long doCount(Predicate predicate) {
        return entityMap.values().stream()
            .filter(predicate).map(this::copy).count();
    }

    protected Page doPage(PageQuery pageQuery, Predicate predicate) {
        long offset = Pages.queryOffset(pageQuery);
        int limit = Pages.queryLimit(pageQuery);
        List result = doList(predicate).stream().skip(offset).limit(limit).toList();
        long count = doCount(predicate);
        return Pages.page(pageQuery, result, count);
    }

    protected Page doPage(PageQuery pageQuery, Predicate predicate, Comparator order) {
        long offset = Pages.queryOffset(pageQuery);
        int limit = Pages.queryLimit(pageQuery);
        List result = doList(predicate, order).stream().skip(offset).limit(limit).toList();
        long count = doCount(predicate);
        return Pages.page(pageQuery, result, count);
    }

    private ENTITY copy(ENTITY entity) {
        if (entity == null) {
            return null;
        }
        Type type = ResolvableType.forClass(getClass()).as(AbstractTestRepository.class).getGeneric(0).getType();
        return JsonUtils.fromJson(JsonUtils.toJson(entity), type);
    }

    private void copyProperties(ENTITY from, ENTITY to) {
        BeanUtils.copyProperties(from, to);
    }

    private void copyPropertiesSelective(ENTITY from, ENTITY to) {
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(from.getClass());
        for (PropertyDescriptor pd : pds) {
            Method readMethod = pd.getReadMethod();
            Method writeMethod = pd.getWriteMethod();
            if (readMethod != null && writeMethod != null) {
                Object value = ReflectionUtils.invokeMethod(readMethod, from);
                if (value != null) {
                    ReflectionUtils.invokeMethod(writeMethod, to, value);
                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy