Jour 3 -- Soir

Springboot
Victor SOULIER 1 year ago
parent d284ee23fa
commit 5bd5393612

@ -3,6 +3,8 @@ package fr.iut.sciencequest.sae.controllers;
import fr.iut.sciencequest.sae.entities.Difficulte;
import fr.iut.sciencequest.sae.services.DifficulteService;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
@ -10,6 +12,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@RestController
@RequestMapping("/api/v1/difficultes")
@ -23,7 +28,8 @@ public class DifficulteController {
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public Iterable<Difficulte> getAllDifficultes(){
return this.difficulteService.findAll();
public EntityModel<Iterable<Difficulte>> getAllDifficultes(){
Link selfLink = linkTo(methodOn(DifficulteController.class).getAllDifficultes()).withSelfRel();
return EntityModel.of(this.difficulteService.findAll(), selfLink);
}
}

@ -0,0 +1,25 @@
package fr.iut.sciencequest.sae.controllers;
import fr.iut.sciencequest.sae.entities.indice.Indice;
import fr.iut.sciencequest.sae.services.IndiceService;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/v1/indices")
public class IndiceController {
private final IndiceService indiceService;
public IndiceController(IndiceService indiceService) {
this.indiceService = indiceService;
}
@PatchMapping(value="/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public Indice patchIndice(@PathVariable("id") int id, @RequestBody Indice indice){
indice.setId(id);
return this.indiceService.update(indice);
}
}

@ -2,7 +2,7 @@ package fr.iut.sciencequest.sae.controllers;
import fr.iut.sciencequest.sae.entities.Partie;
import fr.iut.sciencequest.sae.exceptions.DuplicatedFieldException;
import fr.iut.sciencequest.sae.exceptions.PartieNotFoundException;
import fr.iut.sciencequest.sae.exceptions.notFound.PartieNotFoundException;
import fr.iut.sciencequest.sae.repositories.PartieRepository;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.dao.DataIntegrityViolationException;

@ -1,21 +1,19 @@
package fr.iut.sciencequest.sae.controllers;
import fr.iut.sciencequest.sae.entities.IidAndLibelleOnly;
import fr.iut.sciencequest.sae.entities.Indice;
import fr.iut.sciencequest.sae.entities.Scientifique;
import fr.iut.sciencequest.sae.exceptions.DuplicatedFieldException;
import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection;
import fr.iut.sciencequest.sae.entities.indice.Indice;
import fr.iut.sciencequest.sae.entities.indice.IValidateOnlyLibelle;
import fr.iut.sciencequest.sae.exceptions.IncorrectPageException;
import fr.iut.sciencequest.sae.repositories.IndiceRepository;
import fr.iut.sciencequest.sae.services.IndiceService;
import fr.iut.sciencequest.sae.services.interfaces.IScientifiqueService;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.lang.reflect.Method;
@ -24,19 +22,21 @@ import java.util.List;
import java.util.Optional;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@RestController
@RequestMapping("/api/v1/scientifiques")
public class ScientifiqueController {
private final IScientifiqueService scientifiqueService;
private final IndiceRepository indiceRepository;
private final IndiceService indiceService;
private final int PAGE_SIZE = 1;
public ScientifiqueController(IScientifiqueService scientifiqueService, IndiceRepository indiceRepository) {
public ScientifiqueController(IScientifiqueService scientifiqueService, IndiceService indiceService) {
this.scientifiqueService = scientifiqueService;
this.indiceRepository = indiceRepository;
this.indiceService = indiceService;
}
private <T> CollectionModel<EntityModel<T>> getPageableCollectionModel(Page<T> pagedResult, Integer page, Method method, Object... args) {
@ -63,40 +63,35 @@ public class ScientifiqueController {
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CollectionModel<EntityModel<Scientifique>> getAllScientists(@RequestParam(name = "page") Optional<Integer> page) {
return this.scientifiqueService.findAll(page.orElse(0));
try {
Page<Scientifique> pagedResult = this.scientifiqueService.findAll(page.orElse(0));
return getPageableCollectionModel(pagedResult, page.orElse(0), ScientifiqueController.class.getMethod("getAllScientists", Optional.class));
} catch (IllegalArgumentException e) {
throw new IncorrectPageException("numéro de page incorrect");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public EntityModel<Optional<Scientifique>> getScientistById(@PathVariable int id) {
return this.scientifiqueService.findById(id);
public EntityModel<Scientifique> getScientistById(@PathVariable int id) {
Link selfLink = linkTo(methodOn(ScientifiqueController.class).getScientistById(id)).withSelfRel();
return EntityModel.of(this.scientifiqueService.findById(id), selfLink);
}
@GetMapping(value="/{id}/indices", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public /*CollectionModel<EntityModel<Indice>>*/ Iterable<IidAndLibelleOnly> getScientistHints(@PathVariable int id, @RequestParam(name = "page") Optional<Integer> page) {
return this.indiceRepository.findByScientifiqueId(id);
/*try {
Pageable paging = PageRequest.of(page.orElse(0), PAGE_SIZE);
Page<Indice> pagedResult = indiceRepository.findAll(paging);
return this.getPageableCollectionModel(pagedResult, page.orElse(0), ScientifiqueController.class.getMethod("getScientistHints", int.class, Optional.class), id);
} catch (IllegalArgumentException e) {
throw new IncorrectPageException("numéro de page incorrect");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}*/
public CollectionModel<IIndiceidAndLibelleOnlyProjection> getScientistHints(@PathVariable int id) {
Link selfLink = linkTo(methodOn(ScientifiqueController.class).getScientistHints(id)).withSelfRel();
return CollectionModel.of(this.scientifiqueService.getLinkedIndicesByScientifiqueId(id), selfLink);
}
@PostMapping(value="/{id}/indices", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public Indice postIndice(@RequestBody Indice indice){
try{
return this.indiceRepository.save(indice);
} catch (DataIntegrityViolationException e){
throw new DuplicatedFieldException(e.getMessage());
}
public Indice postIndice(@PathVariable int id, @Validated(IValidateOnlyLibelle.class) @RequestBody Indice indice){
indice.setScientifique(this.scientifiqueService.findById(id));
return this.indiceService.create(indice);
}
}

@ -1,6 +0,0 @@
package fr.iut.sciencequest.sae.entities;
public interface IidAndLibelleOnly{
int getId();
String getLibelle();
}

@ -9,11 +9,13 @@ import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.hibernate.annotations.Type;
import org.hibernate.validator.constraints.URL;
import org.springframework.hateoas.server.core.Relation;
import java.util.Date;
@AllArgsConstructor
@RequiredArgsConstructor
@Relation(collectionRelation = "scientifiques", itemRelation = "scientifique")
@Data
@Entity
@Table(name = "scientifique")

@ -0,0 +1,6 @@
package fr.iut.sciencequest.sae.entities.indice;
public interface IIndiceidAndLibelleOnlyProjection {
int getId();
String getLibelle();
}

@ -0,0 +1,3 @@
package fr.iut.sciencequest.sae.entities.indice;
public interface IValidateOnlyLibelle {}

@ -1,5 +1,6 @@
package fr.iut.sciencequest.sae.entities;
package fr.iut.sciencequest.sae.entities.indice;
import fr.iut.sciencequest.sae.entities.Scientifique;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@ -14,16 +15,21 @@ import lombok.NoArgsConstructor;
@Table(name="indice")
public class Indice {
@Id
@NotNull
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotBlank
@NotBlank(groups = {IValidateOnlyLibelle.class})
private String libelle;
@NotNull
@JoinColumn(name="idscientifique")
@ManyToOne
@NotNull
@JoinColumn(name="idscientifique", nullable = false)
private Scientifique scientifique;
public Indice(int id, String libelle) { // Used for projection
this.id = id;
this.libelle = libelle;
}
}

@ -1,12 +0,0 @@
package fr.iut.sciencequest.sae.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class EntityNotFoundException extends RuntimeException {
public EntityNotFoundException(){
super("entity not found");
}
}

@ -1,12 +0,0 @@
package fr.iut.sciencequest.sae.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ScientifiqueNotFoundException extends RuntimeException {
public ScientifiqueNotFoundException(String message) {
super(message);
}
}

@ -0,0 +1,15 @@
package fr.iut.sciencequest.sae.exceptions.notFound;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public abstract class EntityNotFoundException extends RuntimeException {
public EntityNotFoundException(){
super("entity not found");
}
public EntityNotFoundException(String entityName, int id){
super(entityName + " not found with id : " + id);
}
}

@ -0,0 +1,7 @@
package fr.iut.sciencequest.sae.exceptions.notFound;
public class IndiceNotFoundException extends EntityNotFoundException{
public IndiceNotFoundException(int id){
super("indice", id);
}
}

@ -1,4 +1,4 @@
package fr.iut.sciencequest.sae.exceptions;
package fr.iut.sciencequest.sae.exceptions.notFound;
import org.springframework.http.HttpStatus;

@ -0,0 +1,8 @@
package fr.iut.sciencequest.sae.exceptions.notFound;
public class ScientifiqueNotFoundException extends EntityNotFoundException {
public ScientifiqueNotFoundException(int id) {
super("scientifique", id);
}
}

@ -0,0 +1,7 @@
package fr.iut.sciencequest.sae.exceptions.notFound;
public class ThematiqueNotFoundException extends EntityNotFoundException{
public ThematiqueNotFoundException(int id) {
super("thématique", id);
}
}

@ -1,13 +1,16 @@
package fr.iut.sciencequest.sae.repositories;
import fr.iut.sciencequest.sae.entities.IidAndLibelleOnly;
import fr.iut.sciencequest.sae.entities.Indice;
import fr.iut.sciencequest.sae.entities.indice.Indice;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface IndiceRepository extends PagingAndSortingRepository<Indice, Integer>, CrudRepository<Indice, Integer> {
Iterable<IidAndLibelleOnly> findByScientifiqueId(int id);
<T> Iterable<T> findByScientifiqueId(int id, Class<T> type);
boolean existsByScientifiqueId(int id);
Iterable<Indice> findByScientifiqueId(int id);
}

@ -0,0 +1,40 @@
package fr.iut.sciencequest.sae.services;
import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection;
import fr.iut.sciencequest.sae.entities.indice.Indice;
import fr.iut.sciencequest.sae.exceptions.DuplicatedIdException;
import fr.iut.sciencequest.sae.exceptions.notFound.IndiceNotFoundException;
import fr.iut.sciencequest.sae.repositories.IndiceRepository;
import fr.iut.sciencequest.sae.services.interfaces.IIndiceService;
import org.springframework.stereotype.Service;
@Service
public class IndiceService implements IIndiceService {
private final IndiceRepository indiceRepository;
public IndiceService(IndiceRepository indiceRepository){
this.indiceRepository = indiceRepository;
}
@Override
public Iterable<IIndiceidAndLibelleOnlyProjection> findByScientifiqueId(int id) {
return this.indiceRepository.findByScientifiqueId(id, IIndiceidAndLibelleOnlyProjection.class);
}
@Override
public Indice update(Indice indice){
if(!this.indiceRepository.existsById(indice.getId())){
throw new IndiceNotFoundException(indice.getId());
}
return this.indiceRepository.save(indice);
}
@Override
public Indice create(Indice indice){
if(this.indiceRepository.existsById(indice.getId())){
throw new DuplicatedIdException();
}
return this.indiceRepository.save(indice);
}
}

@ -1,27 +1,16 @@
package fr.iut.sciencequest.sae.services;
import fr.iut.sciencequest.sae.controllers.ScientifiqueController;
import fr.iut.sciencequest.sae.entities.Scientifique;
import fr.iut.sciencequest.sae.exceptions.IncorrectPageException;
import fr.iut.sciencequest.sae.exceptions.ScientifiqueNotFoundException;
import fr.iut.sciencequest.sae.repositories.IndiceRepository;
import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection;
import fr.iut.sciencequest.sae.exceptions.notFound.ScientifiqueNotFoundException;
import fr.iut.sciencequest.sae.repositories.ScientifiqueRepository;
import fr.iut.sciencequest.sae.services.interfaces.IScientifiqueService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.stereotype.Service;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Service
public class ScientifiqueService implements IScientifiqueService {
@ -29,30 +18,11 @@ public class ScientifiqueService implements IScientifiqueService {
private static final int PAGE_SIZE = 1;
private final ScientifiqueRepository scientifiqueRepository;
private final IndiceService indiceService;
public ScientifiqueService(ScientifiqueRepository scientifiqueRepository) {
public ScientifiqueService(ScientifiqueRepository scientifiqueRepository, IndiceService indiceService) {
this.scientifiqueRepository = scientifiqueRepository;
}
private <T> CollectionModel<EntityModel<T>> getPageableCollectionModel(Page<T> pagedResult, Integer page, Method method, Object... args) {
List<EntityModel<T>> entities = pagedResult.map(EntityModel::of).toList();
List<Object> selfObj = new ArrayList<>(List.of(args)); selfObj.add(page);
Link selfLink = linkTo(ScientifiqueController.class, method, selfObj.toArray()).withSelfRel().expand(page);
CollectionModel<EntityModel<T>> result = CollectionModel.of(entities, selfLink);
if (pagedResult.hasPrevious()) {
List<Object> previousObj = new ArrayList<>(List.of(args)); previousObj.add(pagedResult.previousPageable().getPageNumber());
result.add(linkTo(ScientifiqueController.class, method, previousObj.toArray()).withRel("previous"));
}
if (pagedResult.hasNext()) {
List<Object> nextObj = new ArrayList<>(List.of(args)); nextObj.add(pagedResult.nextPageable().getPageNumber());
result.add(linkTo(ScientifiqueController.class, method, nextObj.toArray()).withRel("next"));
}
return result;
this.indiceService = indiceService;
}
@Override
@ -66,25 +36,21 @@ public class ScientifiqueService implements IScientifiqueService {
}
@Override
public CollectionModel<EntityModel<Scientifique>> findAll(Integer page) {
try {
public Page<Scientifique> findAll(Integer page) {
Pageable paging = PageRequest.of(page, PAGE_SIZE);
Page<Scientifique> pagedResult = scientifiqueRepository.findAll(paging);
return getPageableCollectionModel(pagedResult, page, ScientifiqueController.class.getMethod("getAllScientists", Optional.class));
} catch (IllegalArgumentException e) {
throw new IncorrectPageException("numéro de page incorrect");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return scientifiqueRepository.findAll(paging);
}
@Override
public EntityModel<Optional<Scientifique>> findById(int id) {
Optional<Scientifique> scientifiqueOptional = this.scientifiqueRepository.findById(id);
Scientifique scientifique = scientifiqueOptional.orElseThrow(() -> new ScientifiqueNotFoundException("Scientifique non trouvé avec l'ID : " + id));
public Scientifique findById(int id) {
return this.scientifiqueRepository.findById(id).orElseThrow(() -> new ScientifiqueNotFoundException(id));
}
Link selfLink = linkTo(methodOn(ScientifiqueController.class).getScientistById(id)).withSelfRel();
return EntityModel.of(Optional.ofNullable(scientifique), selfLink);
@Override
public Iterable<IIndiceidAndLibelleOnlyProjection> getLinkedIndicesByScientifiqueId(int id){
if(!this.scientifiqueRepository.existsById(id)){
throw new ScientifiqueNotFoundException(id);
}
return this.indiceService.findByScientifiqueId(id);
}
}

@ -3,7 +3,7 @@ package fr.iut.sciencequest.sae.services;
import fr.iut.sciencequest.sae.entities.Thematique;
import fr.iut.sciencequest.sae.exceptions.DuplicatedFieldException;
import fr.iut.sciencequest.sae.exceptions.DuplicatedIdException;
import fr.iut.sciencequest.sae.exceptions.EntityNotFoundException;
import fr.iut.sciencequest.sae.exceptions.notFound.ThematiqueNotFoundException;
import fr.iut.sciencequest.sae.repositories.ThematiqueRepository;
import fr.iut.sciencequest.sae.services.interfaces.IThematiqueService;
import org.springframework.stereotype.Service;
@ -25,7 +25,7 @@ public class ThematiqueService implements IThematiqueService {
@Override
public Thematique update(Thematique thematique){
if(!this.thematiqueRepository.existsById(thematique.getId())){
throw new EntityNotFoundException();
throw new ThematiqueNotFoundException(thematique.getId());
}
this.checkFieldsConstraints(thematique);
return this.thematiqueRepository.save(thematique);

@ -0,0 +1,10 @@
package fr.iut.sciencequest.sae.services.interfaces;
import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection;
import fr.iut.sciencequest.sae.entities.indice.Indice;
public interface IIndiceService {
Iterable<IIndiceidAndLibelleOnlyProjection> findByScientifiqueId(int id);
Indice update(Indice indice);
Indice create(Indice indice);
}

@ -1,17 +1,17 @@
package fr.iut.sciencequest.sae.services.interfaces;
import fr.iut.sciencequest.sae.entities.Scientifique;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import java.util.Optional;
import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection;
import org.springframework.data.domain.Page;
public interface IScientifiqueService {
Scientifique update(Scientifique scientifique);
Scientifique create(Scientifique scientifique);
CollectionModel<EntityModel<Scientifique>> findAll(Integer page);
Page<Scientifique> findAll(Integer page);
Scientifique findById(int id);
EntityModel<Optional<Scientifique>> findById(int id);
Iterable<IIndiceidAndLibelleOnlyProjection> getLinkedIndicesByScientifiqueId(int id);
}

@ -51,7 +51,7 @@ CREATE TABLE Scientifique(
CREATE TABLE Indice(
id SERIAL PRIMARY KEY,
libelle varchar(512) NOT NULL UNIQUE,
libelle varchar(512) NOT NULL,
idScientifique integer REFERENCES Scientifique(id)
);

Loading…
Cancel
Save