
fi.evolver.basics.spring.http.crud.ReadOnlyCrudController Maven / Gradle / Ivy
package fi.evolver.basics.spring.http.crud;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.springdoc.core.converters.models.PageableAsQueryParam;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import fi.evolver.basics.spring.http.HttpInterceptor;
import fi.evolver.basics.spring.http.exception.HttpNotFoundException;
import fi.evolver.basics.spring.log.LogPolicy;
import fi.evolver.basics.spring.log.LogPolicy.Policy;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
/**
*
* An abstract REST like controller for JPA entity classes.
* The entity class must have a Long type ID.
*
*
*
* Any concrete descendants of this class require the @RestController class
* annotation to work correctly. Also, the entity class should have any unwanted methods
* marked with the @JsonIgnore annotation.
*
*
* @param The entity class type.
*/
public abstract class ReadOnlyCrudController {
protected final JpaRepository jpaRepository;
protected final String entityName;
/**
* @param jpaRepository Repository for the entity class.
*/
protected ReadOnlyCrudController(JpaRepository jpaRepository) {
this.jpaRepository = jpaRepository;
this.entityName = inferEntityTypeName(jpaRepository.getClass());
}
@LogPolicy(Policy.NONE)
@Operation(summary = "Fetch a page of entities")
@PageableAsQueryParam
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "A page of entities"),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content)
})
@GetMapping
public Page list(@PageableDefault(size = 100, direction = Direction.DESC, sort = "id") Pageable page) {
HttpInterceptor.setMessageType(String.format("%s/list", entityName));
return jpaRepository.findAll(page);
}
@LogPolicy(Policy.NONE)
@Operation(summary = "Fetch a single entity by id")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "The requested entity"),
@ApiResponse(responseCode = "404", description = "The requested entity was not found", content = @Content),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content)
})
@GetMapping("/{id}")
public T show(@PathVariable long id) {
HttpInterceptor.setMessageType(String.format("%s/show", entityName));
return jpaRepository.findById(id).orElseThrow(HttpNotFoundException::new);
}
@Operation(summary = "Fetch a text representation of a single entity by id")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "The requested entity"),
@ApiResponse(responseCode = "404", description = "The requested entity was not found", content = @Content),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content)
})
@GetMapping("/{id}/text")
public String showText(@PathVariable long id) {
HttpInterceptor.setMessageType(String.format("%s/text", entityName));
return jpaRepository.findById(id).orElseThrow(HttpNotFoundException::new).toString();
}
private static String inferEntityTypeName(Class> clazz) {
Type type = clazz;
do {
type = ((Class>)type).getGenericInterfaces()[0];
} while (!(type instanceof ParameterizedType) && type instanceof Class>);
if (!(type instanceof ParameterizedType))
return "?";
String typeName = ((ParameterizedType)type).getActualTypeArguments()[0].getTypeName();
return typeName.substring(typeName.lastIndexOf('.') + 1);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy