
com.alon.spring.crud.service.CrudService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-crud-base Show documentation
Show all versions of spring-crud-base Show documentation
Projeto base para criação de serviços e recusos de CRUD com Spring Data JPA.
package com.alon.spring.crud.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
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 com.alon.querydecoder.Expression;
import com.alon.spring.crud.model.BaseEntity;
public abstract class CrudService & JpaSpecificationExecutor> {
@Autowired
protected R repository;
private final Map> HOOKS = new HashMap<>();
public CrudService() {
for (LifeCycleHook hook : LifeCycleHook.values())
this.HOOKS.put(hook, new ArrayList<>());
this.addBeforeUpdateHook(this::checkEntityState);
this.addBeforeUpdateHook(this::entityExists);
}
public Page list(int page, int size) {
return this.list(page, size, null);
}
public Page list(int page, int size, Expression order) {
return this.repository.findAll(this.buildPageable(page, size, order));
}
public Page list(Specification specification, int page, int size, Expression order) {
return this.repository.findAll(specification, this.buildPageable(page, size, order));
}
private Pageable buildPageable(int page, int size, Expression orders) {
return PageRequest.of(page, size, this.getSort(orders));
}
private Sort getSort(Expression order) {
if (order == null || order.getField() == null)
return Sort.by(this.getDefaultSort());
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 = (Expression) order.getNext();
} while (order != null);
return Sort.by(orders);
}
public E create(@Valid E entity) throws CreateException {
try {
entity = this.executeHook(entity, LifeCycleHook.BEFORE_CREATE);
entity = this.repository.save(entity);
return this.executeHook(entity, LifeCycleHook.AFTER_CREATE);
} catch (Throwable ex) {
throw new CreateException(ex.getMessage(), ex);
}
}
public E read(Long id) throws NotFoundException {
Optional entity = this.repository.findById(id);
if (entity.isEmpty())
throw new NotFoundException(String.format("Entity with id %d not found.", id));
return entity.get();
}
public E update(@Valid E entity) throws UpdateException {
try {
entity = this.executeHook(entity, LifeCycleHook.BEFORE_UPDATE);
entity = this.create(entity);
return this.executeHook(entity, LifeCycleHook.AFTER_UPDATE);
} catch (Throwable ex) {
throw new UpdateException(ex.getMessage(), ex);
}
}
public void delete(Long id) throws DeleteException {
try {
this.executeHook(id, LifeCycleHook.BEFORE_DELETE);
this.repository.deleteById(id);
this.executeHook(id, LifeCycleHook.AFTER_DELETE);
} catch (Throwable ex) {
throw new DeleteException(ex.getMessage(), ex);
}
}
private E checkEntityState(E entity) throws UpdateException {
if (entity.getId() == null)
throw new UpdateException("Unmanaged entity. Use the create method.");
return entity;
}
private E entityExists(E entity) throws UpdateException {
boolean exists = this.repository.existsById(entity.getId());
if (!exists)
throw new UpdateException("Entity not exists");
return entity;
}
public abstract List getDefaultSort();
public final CrudService addBeforeCreateHook(CheckedFunction function) {
this.HOOKS.get(LifeCycleHook.BEFORE_CREATE).add(function);
return this;
}
public final CrudService addAfterCreateHook(CheckedFunction function) {
this.HOOKS.get(LifeCycleHook.AFTER_CREATE).add(function);
return this;
}
public final CrudService addBeforeUpdateHook(CheckedFunction function) {
this.HOOKS.get(LifeCycleHook.BEFORE_UPDATE).add(function);
return this;
}
public final CrudService addAfterUpdateHook(CheckedFunction function) {
this.HOOKS.get(LifeCycleHook.AFTER_UPDATE).add(function);
return this;
}
public final CrudService addBeforeDeleteHook(CheckedFunction function) {
this.HOOKS.get(LifeCycleHook.BEFORE_DELETE).add(function);
return this;
}
public final CrudService addAfterDeleteHook(CheckedFunction function) {
this.HOOKS.get(LifeCycleHook.AFTER_DELETE).add(function);
return this;
}
private O executeHook(O param, LifeCycleHook hookType) throws Throwable {
List hooks = this.getHook(hookType);
for (CheckedFunction hook : hooks)
param = (O) hook.apply(param);
return param;
}
private List getHook(LifeCycleHook hookType) {
return HOOKS.get(hookType);
}
private enum LifeCycleHook {
BEFORE_CREATE,
AFTER_CREATE,
BEFORE_UPDATE,
AFTER_UPDATE,
BEFORE_DELETE,
AFTER_DELETE
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy