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

com.alon.spring.crud.service.CrudService Maven / Gradle / Ivy

Go to download

Projeto base para criação de serviços e recusos de CRUD com Spring Data JPA.

There is a newer version: 3.0.0
Show newest version
package com.alon.spring.crud.service;

import com.alon.querydecoder.Expression;
import com.alon.querydecoder.SingleExpression;
import com.alon.spring.crud.model.BaseEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

public interface CrudService {
    
    public R getRepository();
    
    default  Page list() {
        return this.list(0, Integer.MAX_VALUE);
    }
    
    default  Page list(SingleExpression order) {
        return this.list(0, Integer.MAX_VALUE, order);
    }
    
    default  Page list(int page, int size) {
        return this.getRepository().findAll(PageRequest.of(page, size));
    }

    default  Page list(int page, int size, SingleExpression order) {
        return this.getRepository().findAll(Hidden.buildPageable(page, size, order));
    }
    
    default  Page list(Specification specification, int page, int size) {
        return this.getRepository().findAll(specification, PageRequest.of(page, size));
    }

    default  Page list(Specification specification, int page, int size, SingleExpression order) {
        return this.getRepository().findAll(specification, Hidden.buildPageable(page, size, order));
    }

    default  E create(@Valid E entity) throws CreateException {
        try {
            entity = Hidden.executeHook(this, entity, LifeCycleHook.BEFORE_CREATE);
            entity = (E) this.getRepository().save(entity);
            return Hidden.executeHook(this, entity, LifeCycleHook.AFTER_CREATE);
        } catch (Throwable ex) {
            throw new CreateException(ex.getMessage(), ex);
        }
    }

    default > E read(ID id) {
        return (E) this.getRepository().findById(id).get();
    }

    default  E update(@Valid E entity) throws UpdateException {
        if (entity.id() == null)
            throw new UpdateException("Unmanaged entity. Use the create method.");
            
        try {
            entity = Hidden.executeHook(this, entity, LifeCycleHook.BEFORE_UPDATE);
            entity = this.create(entity);
            return Hidden.executeHook(this, entity, LifeCycleHook.AFTER_UPDATE);
        } catch (Throwable ex) {
            throw new UpdateException(ex.getMessage(), ex);
        }
    }

    default  void delete(ID id) throws DeleteException {
        try {
            Hidden.executeHook(this, id, LifeCycleHook.BEFORE_DELETE);
            this.getRepository().deleteById(id);
            Hidden.executeHook(this, id, LifeCycleHook.AFTER_DELETE);
        } catch (Throwable ex) {
            throw new DeleteException(ex.getMessage(), ex);
        }
    }
    
    default  CrudService addBeforeCreateHook(Function function) {
    	Hidden.getServiceHooks(this).get(LifeCycleHook.BEFORE_CREATE).add(function);
    	return this;
    }
    
    default  CrudService addAfterCreateHook(Function function) {
    	Hidden.getServiceHooks(this).get(LifeCycleHook.AFTER_CREATE).add(function);    	
    	return this;
    }
    
    default  CrudService addBeforeUpdateHook(Function function) {
    	Hidden.getServiceHooks(this).get(LifeCycleHook.BEFORE_UPDATE).add(function);    	
    	return this;
    }
    
    default  CrudService addAfterUpdateHook(Function function) {
    	Hidden.getServiceHooks(this).get(LifeCycleHook.AFTER_UPDATE).add(function);    	
    	return this;
    }
    
    default  CrudService addBeforeDeleteHook(Function function) {
    	Hidden.getServiceHooks(this).get(LifeCycleHook.BEFORE_DELETE).add(function);    	
    	return this;
    }
    
    default  CrudService addAfterDeleteHook(Function function) {
    	Hidden.getServiceHooks(this).get(LifeCycleHook.AFTER_DELETE).add(function);    	
    	return this;
    }
        
    enum LifeCycleHook {
    	BEFORE_CREATE,
    	AFTER_CREATE,
    	BEFORE_UPDATE,
    	AFTER_UPDATE,
    	BEFORE_DELETE,
    	AFTER_DELETE
    }
    
    /**
     * This class has the function of restricting methods, 
     * because private methods are not allowed in interfaces.
     */
    class Hidden {
        
        private static Map>> GLOBAL_HOOKS = new HashMap<>();
        
        private static Pageable buildPageable(int page, int size, SingleExpression orders) {
            return PageRequest.of(page, size, buildSort(orders));
        }

        private static Sort buildSort(SingleExpression order) {
            
            List orders = new ArrayList<>();

            do {
                boolean desc = order.getValue().equalsIgnoreCase("DESC");

                if (desc)
                    orders.add(Order.desc(order.getField()));
                else
                    orders.add(Order.asc(order.getField()));

                order = (SingleExpression) order.getNext();
            } while (order != null);

            return Sort.by(orders);
            
        }
    
        private static  P executeHook(S service, P param, LifeCycleHook hookType) throws Throwable {
            
            List hooks = getHook(service, hookType);

            for (Function hook : hooks)
                param = (P) hook.apply(param);

            return param;
            
        }

        private static  List getHook(T service, LifeCycleHook hookType) {
            return getServiceHooks(service).get(hookType);
        }
        
        private static  Map> getServiceHooks(T service) {
            
            Map> hooks = GLOBAL_HOOKS.get(service);

            if (hooks == null)
                hooks = initHooks(service);

            return hooks;
            
        }
        
        private static  Map> initHooks(T service) {
            
            Map> hooks = new HashMap<>();

            for (LifeCycleHook hook : LifeCycleHook.values())
                hooks.put(hook, new ArrayList<>());

            GLOBAL_HOOKS.put(service, hooks);

            return hooks;
            
        }
        
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy