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

win.doyto.query.core.AbstractCrudService Maven / Gradle / Ivy

package win.doyto.query.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import win.doyto.query.cache.CacheWrapper;
import win.doyto.query.entity.EntityAspect;
import win.doyto.query.entity.Persistable;
import win.doyto.query.entity.UserIdProvider;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.LinkedList;
import java.util.List;

/**
 * AbstractCrudService
 *
 * @author f0rb
 */
public abstract class AbstractCrudService, I extends Serializable, Q> implements CrudService {

    protected DataAccess dataAccess;

    protected CacheWrapper entityCacheWrapper = CacheWrapper.createInstance();

    @Autowired(required = false)
    protected UserIdProvider userIdProvider;

    @Autowired(required = false)
    protected List> entityAspects = new LinkedList<>();

    protected Class domainType;

    public AbstractCrudService() {
        this.domainType = getDomainType();
        this.dataAccess = new MemoryDataAccess<>(this.domainType);
    }

    @SuppressWarnings("unchecked")
    private Class getDomainType() {
        return (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    @Autowired(required = false)
    public void setCacheManager(CacheManager cacheManager) {
        String cacheName = getCacheName();
        if (cacheName != null) {
            entityCacheWrapper.setCache(cacheManager.getCache(cacheName));
        }
    }

    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        dataAccess = new JdbcDataAccess<>(jdbcTemplate, domainType);
    }

    protected String getCacheName() {
        return null;
    }

    @Override
    public List query(Q query) {
        return dataAccess.query(query);
    }

    @Override
    public long count(Q query) {
        return dataAccess.count(query);
    }

    @Override
    public E get(I id) {
        return entityCacheWrapper.execute(id, () -> dataAccess.get(id));
    }

    @Override
    @Transactional
    public void create(E e) {
        if (userIdProvider != null) {
            userIdProvider.setupUserId(e);
        }
        dataAccess.create(e);
        entityAspects.forEach(entityAspect -> entityAspect.afterCreate(e));
        entityCacheWrapper.evict(e.getId());
    }

    @Override
    @Transactional
    public void update(E e) {
        doUpdate(e, () -> dataAccess.update(e));
    }

    @Override
    @Transactional
    public void patch(E e) {
        doUpdate(e, () -> dataAccess.patch(e));
    }

    private void doUpdate(E e, Runnable runnable) {
        if (userIdProvider != null) {
            userIdProvider.setupUserId(e);
        }
        E origin = entityAspects.isEmpty() ? null : dataAccess.fetch(e.getId());
        runnable.run();
        entityAspects.forEach(entityAspect -> entityAspect.afterUpdate(origin, e));
        entityCacheWrapper.evict(e.getId());
    }

    @Override
    public E delete(I id) {
        E e = get(id);
        if (e != null) {
            dataAccess.delete(id);
            entityCacheWrapper.execute(id, () -> null);
            entityAspects.forEach(entityAspect -> entityAspect.afterDelete(e));
        }
        return e;
    }

    @Override
    public int delete(Q query) {
        return dataAccess.delete(query);
    }

    public boolean exists(Q query) {
        return count(query) > 0;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy