diff --git a/SpringBootProject/pom.xml b/SpringBootProject/pom.xml index 42c773a..9a56cb5 100644 --- a/SpringBootProject/pom.xml +++ b/SpringBootProject/pom.xml @@ -15,6 +15,7 @@ API SAE ScienceQuest 21 + UTF-8 diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/ApplicationFilter.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/ApplicationFilter.java index b5836c7..df7c8a3 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/ApplicationFilter.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/ApplicationFilter.java @@ -16,9 +16,11 @@ import org.springframework.core.annotation.Order; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.ContentCachingResponseWrapper; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; @Component @Order(1) @@ -30,83 +32,41 @@ public class ApplicationFilter extends OncePerRequestFilter { } @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // Intercept and modify the JSON response - JsonInterceptingResponseWrapper responseWrapper = new JsonInterceptingResponseWrapper(response); + ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response); filterChain.doFilter(request, responseWrapper); - // Check if the response content type is JSON if (responseWrapper.getContentType() != null && responseWrapper.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)) { try { - // Parse the JSON response - JsonNode root = objectMapper.readTree(responseWrapper.getContent()); + // Récupération du contenu en byteArray + byte[] responseArray = responseWrapper.getContentAsByteArray(); - // Check if the _embedded node exists and if it contains the tupleBackedMapList node + // Parse JSON + JsonNode root = objectMapper.readTree(new String(responseArray, StandardCharsets.UTF_8)); + + // Vérification de l'existance du node _embedded && s'il contient un node enfant JsonNode embeddedNode = root.get("_embedded"); - if (embeddedNode != null && embeddedNode.isObject()) { - JsonNode tupleBackedMapListNode = embeddedNode.get("tupleBackedMapList"); - if (tupleBackedMapListNode != null && tupleBackedMapListNode.isArray()) { - ArrayNode tupleBackedMapList = (ArrayNode) tupleBackedMapListNode; + if (embeddedNode != null && embeddedNode.isObject() && embeddedNode.size() == 1) { + JsonNode subNode = embeddedNode.elements().next(); // Récupération node enfant + if (subNode != null && subNode.isArray()) { + ArrayNode subNodeArr = (ArrayNode) subNode; - // Remove the _embedded node + // Correction de la profondeur ((ObjectNode) root).remove("_embedded"); - - // Set the tupleBackedMapList directly to the root - ((ObjectNode) root).set("_embedded", tupleBackedMapList); + ((ObjectNode) root).set("_embedded", subNodeArr); } } - // Convert the modified JSON back to string + // Retour du JSON dans l'objectMapper en String String modifiedResponseBody = objectMapper.writeValueAsString(root); - // Write the modified JSON back to the response - response.getOutputStream().write(modifiedResponseBody.getBytes()); - } catch (IOException e) { - // Handle exception - e.printStackTrace(); - } - } - } - - private static class JsonInterceptingResponseWrapper extends HttpServletResponseWrapper { - private ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - public JsonInterceptingResponseWrapper(HttpServletResponse response) { - super(response); - } - - @Override - public ServletOutputStream getOutputStream() throws IOException { - return new ServletOutputStreamWrapper(baos); - } - - public String getContent() { - return baos.toString(); - } - } - - private static class ServletOutputStreamWrapper extends ServletOutputStream { - private ByteArrayOutputStream baos; - - public ServletOutputStreamWrapper(ByteArrayOutputStream baos) { - this.baos = baos; - } - - @Override - public void write(int b) throws IOException { - baos.write(b); - } - - @Override - public boolean isReady() { - return true; - } - - @Override - public void setWriteListener(WriteListener writeListener) { - throw new UnsupportedOperationException("Not implemented"); + // Ecriture du JSON dans la réponse + response.setCharacterEncoding("UTF-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.getOutputStream().write(modifiedResponseBody.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { System.err.println(e.getMessage()); } } } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/Controller.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/Controller.java new file mode 100644 index 0000000..43e5454 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/Controller.java @@ -0,0 +1,83 @@ +package fr.iut.sciencequest.sae.controllers; + +import org.springframework.data.domain.Page; +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; + +public class Controller { + protected final int PAGE_SIZE = 1; + + protected EntityModel getSelfLinkEntityModel(T entity, String method, Object... args) { + Class[] argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = args[i].getClass(); + } + + try { + Link selfLink = linkTo(this.getClass(), this.getClass().getMethod(method, argTypes), args).withSelfRel(); + return EntityModel.of(entity, selfLink); + } catch (NoSuchMethodException e) { + System.err.println("Method doesn't exist"); + return null; + } + } + + protected CollectionModel getSelfLinkCollectionModel(Iterable entities, String method, Object... args) { + Class[] argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = args[i].getClass(); + } + + try { + Link selfLink = linkTo(this.getClass(), this.getClass().getMethod(method, argTypes), args).withSelfRel(); + return CollectionModel.of(entities, selfLink); + } catch (NoSuchMethodException e) { + System.err.println("Method doesn't exist"); + return null; + } + } + + + protected CollectionModel> getPageableCollectionModel(Page pagedResult, Integer page, String method, Object... args) { + try { + List> entities = pagedResult.map(EntityModel::of).toList(); + + Class[] argTypes = new Class[args.length+1]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = args[i].getClass(); + } + argTypes[args.length] = Optional.class; + + Method finalMethod = this.getClass().getMethod(method, argTypes); + + List selfObj = new ArrayList<>(List.of(args)); selfObj.add(page); + Link selfLink = linkTo(this.getClass(), finalMethod, selfObj.toArray()).withSelfRel().expand(page); + + CollectionModel> result = CollectionModel.of(entities, selfLink); + + if (pagedResult.hasPrevious()) { + List previousObj = new ArrayList<>(List.of(args)); previousObj.add(pagedResult.previousPageable().getPageNumber()); + result.add(linkTo(this.getClass(), finalMethod, previousObj.toArray()).withRel("previous")); + } + + if (pagedResult.hasNext()) { + List nextObj = new ArrayList<>(List.of(args)); nextObj.add(pagedResult.nextPageable().getPageNumber()); + result.add(linkTo(this.getClass(), finalMethod, nextObj.toArray()).withRel("next")); + } + + return result; + } catch(NoSuchMethodException e) { + System.err.println(e.getMessage()); + return null; + } + } +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/DifficulteController.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/DifficulteController.java index 33dab40..3ce193b 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/DifficulteController.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/DifficulteController.java @@ -3,6 +3,7 @@ package fr.iut.sciencequest.sae.controllers; import fr.iut.sciencequest.sae.entities.Difficulte; import fr.iut.sciencequest.sae.services.DifficulteService; +import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; import org.springframework.http.HttpStatus; @@ -18,8 +19,7 @@ import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; @RestController @RequestMapping("/api/v1/difficultes") -public class DifficulteController { - +public class DifficulteController extends Controller { public final DifficulteService difficulteService; public DifficulteController(DifficulteService difficulteService){ @@ -28,8 +28,7 @@ public class DifficulteController { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.OK) - public EntityModel> getAllDifficultes(){ - Link selfLink = linkTo(methodOn(DifficulteController.class).getAllDifficultes()).withSelfRel(); - return EntityModel.of(this.difficulteService.findAll(), selfLink); + public CollectionModel getAllDifficultes() { + return getSelfLinkCollectionModel(this.difficulteService.findAll(), "getAllDifficultes"); } } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/IndiceController.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/IndiceController.java index 5b66be6..f618b4b 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/IndiceController.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/IndiceController.java @@ -8,8 +8,7 @@ import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/v1/indices") -public class IndiceController { - +public class IndiceController extends Controller { private final IndiceService indiceService; public IndiceController(IndiceService indiceService) { diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/PartieController.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/PartieController.java index cb2a734..e89f0ed 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/PartieController.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/PartieController.java @@ -17,9 +17,7 @@ import java.util.Optional; @RestController @RequestMapping("/api/v1/partie") -public class PartieController { - - private static final int PAGE_SIZE = 5; +public class PartieController extends Controller { private final PartieRepository partieRepository; public PartieController(PartieRepository partieRepository) { @@ -30,7 +28,7 @@ public class PartieController { public EntityModel> getPartie(@PathVariable int id, HttpServletRequest request) { Optional partieOptional = this.partieRepository.findById(id); Partie partie = partieOptional.orElseThrow(() -> - new PartieNotFoundException("Partie introuvable avec l'ID : " + id) + new PartieNotFoundException("Partie", id) ); Link selfLink = linkTo(methodOn(PartieController.class).getPartie(id,request)).withSelfRel(); diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/QuestionController.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/QuestionController.java index 1050120..f27af1d 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/QuestionController.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/QuestionController.java @@ -2,58 +2,29 @@ package fr.iut.sciencequest.sae.controllers; import fr.iut.sciencequest.sae.entities.Question; import fr.iut.sciencequest.sae.exceptions.IncorrectPageException; -import fr.iut.sciencequest.sae.repositories.QuestionRepository; +import fr.iut.sciencequest.sae.services.QuestionService; import jakarta.servlet.http.HttpServletRequest; -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.MediaType; import org.springframework.web.bind.annotation.*; -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/questions") -public class QuestionController { - - private static final int PAGE_SIZE = 10; - private final QuestionRepository questionRepository; +public class QuestionController extends Controller { + private final QuestionService questionService; - public QuestionController(QuestionRepository questionRepository) { - this.questionRepository = questionRepository; + public QuestionController(QuestionService questionService) { + this.questionService = questionService; } @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public CollectionModel> getAllQuestions(@RequestParam(name = "page") Optional page, HttpServletRequest request) { + public CollectionModel> getAllQuestions(@RequestParam(name = "page") Optional page) { try { - Pageable paging = PageRequest.of(page.orElse(0), PAGE_SIZE); - Page pagedResult = questionRepository.findAll(paging); - - List> questions = pagedResult.map(EntityModel::of).toList(); - - Link selfLink = linkTo(methodOn(QuestionController.class).getAllQuestions(page, request)).withSelfRel().expand(page.map(Object::toString).orElse("0")); - - CollectionModel> result = CollectionModel.of(questions, selfLink); - - if (pagedResult.hasPrevious()) { - Link prevLink = linkTo(methodOn(QuestionController.class).getAllQuestions(Optional.of(pagedResult.previousPageable().getPageNumber()), request)).withRel("previous"); - result.add(prevLink.expand(pagedResult.previousPageable().getPageNumber())); - } - - if (pagedResult.hasNext()) { - Link nextLink = linkTo(methodOn(QuestionController.class).getAllQuestions(Optional.of(pagedResult.nextPageable().getPageNumber()), request)).withRel("next"); - result.add(nextLink.expand(pagedResult.nextPageable().getPageNumber())); - } - - return result; + return getPageableCollectionModel(questionService.findAll(page.orElse(0)), page.orElse(0), "getAllQuestions"); } catch (IllegalArgumentException e) { throw new IncorrectPageException("numéro de page incorrect"); } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ScientifiqueController.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ScientifiqueController.java index a0a56e2..b93a496 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ScientifiqueController.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ScientifiqueController.java @@ -1,97 +1,61 @@ package fr.iut.sciencequest.sae.controllers; -import fr.iut.sciencequest.sae.entities.Scientifique; -import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection; +import fr.iut.sciencequest.sae.entities.scientifique.Scientifique; +import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleAndScientifiqueIdOnlyProjection; 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.services.IndiceService; import fr.iut.sciencequest.sae.services.interfaces.IScientifiqueService; -import org.springframework.data.domain.Page; +import org.springframework.data.projection.ProjectionFactory; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; 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; -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; @RestController @RequestMapping("/api/v1/scientifiques") -public class ScientifiqueController { +public class ScientifiqueController extends Controller { private final IScientifiqueService scientifiqueService; private final IndiceService indiceService; - private final int PAGE_SIZE = 1; - - public ScientifiqueController(IScientifiqueService scientifiqueService, IndiceService indiceService) { this.scientifiqueService = scientifiqueService; this.indiceService = indiceService; } - private CollectionModel> getPageableCollectionModel(Page pagedResult, Integer page, Method method, Object... args) { - List> entities = pagedResult.map(EntityModel::of).toList(); - - List selfObj = new ArrayList<>(List.of(args)); selfObj.add(page); - Link selfLink = linkTo(ScientifiqueController.class, method, selfObj.toArray()).withSelfRel().expand(page); - - CollectionModel> result = CollectionModel.of(entities, selfLink); - - if (pagedResult.hasPrevious()) { - List 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 nextObj = new ArrayList<>(List.of(args)); nextObj.add(pagedResult.nextPageable().getPageNumber()); - result.add(linkTo(ScientifiqueController.class, method, nextObj.toArray()).withRel("next")); - } - - return result; - } - @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody public CollectionModel> getAllScientists(@RequestParam(name = "page") Optional page) { try { - Page pagedResult = this.scientifiqueService.findAll(page.orElse(0)); - return getPageableCollectionModel(pagedResult, page.orElse(0), ScientifiqueController.class.getMethod("getAllScientists", Optional.class)); + return getPageableCollectionModel(this.scientifiqueService.findAll(page.orElse(0)), page.orElse(0),"getAllScientists"); } 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 getScientistById(@PathVariable int id) { - Link selfLink = linkTo(methodOn(ScientifiqueController.class).getScientistById(id)).withSelfRel(); - return EntityModel.of(this.scientifiqueService.findById(id), selfLink); + public EntityModel getScientistById(@PathVariable Integer id) { + return getSelfLinkEntityModel(this.scientifiqueService.findById(id), "getScientistById", id); } @GetMapping(value="/{id}/indices", produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody - public CollectionModel getScientistHints(@PathVariable int id) { - Link selfLink = linkTo(methodOn(ScientifiqueController.class).getScientistHints(id)).withSelfRel(); - return CollectionModel.of(this.scientifiqueService.getLinkedIndicesByScientifiqueId(id), selfLink); + public CollectionModel getScientistHints(@PathVariable Integer id) { + return getSelfLinkCollectionModel(this.scientifiqueService.getLinkedIndicesByScientifiqueId(id), "getScientistHints", id); } @PostMapping(value="/{id}/indices", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.CREATED) - public Indice postIndice(@PathVariable int id, @Validated(IValidateOnlyLibelle.class) @RequestBody Indice indice){ + public IIndiceidAndLibelleAndScientifiqueIdOnlyProjection postIndice(@PathVariable Integer id, @Validated(IValidateOnlyLibelle.class) @RequestBody Indice indice){ indice.setScientifique(this.scientifiqueService.findById(id)); - return this.indiceService.create(indice); + indice = this.indiceService.create(indice); + return indice.toProjection(IIndiceidAndLibelleAndScientifiqueIdOnlyProjection.class); } - } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ThematiqueController.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ThematiqueController.java index 82211c7..2df1eb6 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ThematiqueController.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ThematiqueController.java @@ -3,13 +3,15 @@ package fr.iut.sciencequest.sae.controllers; import fr.iut.sciencequest.sae.entities.Thematique; import fr.iut.sciencequest.sae.services.interfaces.IThematiqueService; import jakarta.validation.Valid; +import org.springframework.hateoas.CollectionModel; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; + @RestController @RequestMapping("/api/v1/thematiques") -public class ThematiqueController { +public class ThematiqueController extends Controller { private final IThematiqueService thematiqueService; public ThematiqueController(IThematiqueService thematiqueService) { @@ -18,8 +20,8 @@ public class ThematiqueController { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.OK) - public Iterable getAllThematiques() { - return this.thematiqueService.findAll(); + public CollectionModel getAllThematiques() { + return getSelfLinkCollectionModel(this.thematiqueService.findAll(), "getAllThematiques"); } //TODO : gestion des erreurs remontées par @Valid diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Admin.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Admin.java index f53d4ca..85d3e4f 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Admin.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Admin.java @@ -13,7 +13,7 @@ import lombok.NoArgsConstructor; @Data @Entity @Table(name="admin") -public class Admin { +public class Admin extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/BaseEntity.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/BaseEntity.java new file mode 100644 index 0000000..c5def33 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/BaseEntity.java @@ -0,0 +1,12 @@ +package fr.iut.sciencequest.sae.entities; + +import org.springframework.data.projection.ProjectionFactory; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; + +public abstract class BaseEntity implements IToProjection { + public T toProjection(Class projectionType){ + ProjectionFactory pf = new SpelAwareProxyProjectionFactory(); + return pf.createProjection(projectionType, this); + } + +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Difficulte.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Difficulte.java index dcfcfef..fd8423b 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Difficulte.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Difficulte.java @@ -13,7 +13,7 @@ import lombok.NoArgsConstructor; @Data @Entity @Table(name="difficulte") -public class Difficulte { +public class Difficulte extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/IToProjection.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/IToProjection.java new file mode 100644 index 0000000..7e7f453 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/IToProjection.java @@ -0,0 +1,5 @@ +package fr.iut.sciencequest.sae.entities; + +public interface IToProjection { + public T toProjection(Class projectionType); +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Invite.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Invite.java index 8c316a7..cea5436 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Invite.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Invite.java @@ -5,11 +5,11 @@ import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; + @EqualsAndHashCode(callSuper = true) @AllArgsConstructor @Data @Entity @Table(name = "invite") -public class Invite extends Joueur{ +public class Invite extends Joueur { } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Jeu.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Jeu.java index 4c740a4..feb6515 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Jeu.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Jeu.java @@ -7,14 +7,13 @@ import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.boot.context.properties.bind.DefaultValue; @NoArgsConstructor @AllArgsConstructor @Data @Entity @Table(name="jeu") -public class Jeu { +public class Jeu extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Joueur.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Joueur.java index d3005b7..7d9c767 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Joueur.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Joueur.java @@ -13,7 +13,7 @@ import lombok.NoArgsConstructor; @Inheritance ( strategy = InheritanceType.JOINED) @Entity @Table(name="joueur") -public abstract class Joueur { +public abstract class Joueur extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Partie.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Partie.java index 455dfef..dcfd678 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Partie.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Partie.java @@ -4,17 +4,14 @@ import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.Set; - @AllArgsConstructor @NoArgsConstructor @Data @Entity @Table(name="partie") -public class Partie { +public class Partie extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Question.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Question.java index 4290c17..b39fd0c 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Question.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Question.java @@ -5,6 +5,8 @@ import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; import java.util.List; @@ -14,7 +16,7 @@ import java.util.List; @Data @Entity @Table(name="question") -public class Question { +public class Question extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -23,6 +25,7 @@ public class Question { @NotEmpty @OneToMany(mappedBy = "id") + @Fetch(FetchMode.JOIN) // Sinon crash (Could not write JSON: failed to lazily initialize a collection of role) private List reponses; } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Reponse.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Reponse.java index c3924e1..3b9dff9 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Reponse.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Reponse.java @@ -11,7 +11,7 @@ import lombok.NoArgsConstructor; @Data @Entity @Table(name="reponse") -public class Reponse { +public class Reponse extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Thematique.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Thematique.java index d9e9f0c..ab29139 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Thematique.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Thematique.java @@ -3,7 +3,6 @@ package fr.iut.sciencequest.sae.entities; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -14,7 +13,7 @@ import lombok.NoArgsConstructor; @Data @Entity @Table(name="thematique") -public class Thematique { +public class Thematique extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/IIndiceidAndLibelleAndScientifiqueIdOnlyProjection.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/IIndiceidAndLibelleAndScientifiqueIdOnlyProjection.java new file mode 100644 index 0000000..8a334af --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/IIndiceidAndLibelleAndScientifiqueIdOnlyProjection.java @@ -0,0 +1,10 @@ +package fr.iut.sciencequest.sae.entities.indice; + +import fr.iut.sciencequest.sae.entities.scientifique.IScientifiqueIdOnlyProjection; + +public interface IIndiceidAndLibelleAndScientifiqueIdOnlyProjection { + int getId(); + String getLibelle(); + + IScientifiqueIdOnlyProjection getScientifique(); +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/IIndiceidAndLibelleOnlyProjection.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/IIndiceidAndLibelleOnlyProjection.java deleted file mode 100644 index 11d0050..0000000 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/IIndiceidAndLibelleOnlyProjection.java +++ /dev/null @@ -1,6 +0,0 @@ -package fr.iut.sciencequest.sae.entities.indice; - -public interface IIndiceidAndLibelleOnlyProjection { - int getId(); - String getLibelle(); -} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/Indice.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/Indice.java index 933a09c..4e81cbf 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/Indice.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/indice/Indice.java @@ -1,6 +1,7 @@ package fr.iut.sciencequest.sae.entities.indice; -import fr.iut.sciencequest.sae.entities.Scientifique; +import fr.iut.sciencequest.sae.entities.BaseEntity; +import fr.iut.sciencequest.sae.entities.scientifique.Scientifique; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -13,7 +14,7 @@ import lombok.NoArgsConstructor; @Data @Entity @Table(name="indice") -public class Indice { +public class Indice extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @@ -21,7 +22,6 @@ public class Indice { @NotBlank(groups = {IValidateOnlyLibelle.class}) private String libelle; - @ManyToOne @NotNull @JoinColumn(name="idscientifique", nullable = false) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/scientifique/IScientifiqueIdOnlyProjection.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/scientifique/IScientifiqueIdOnlyProjection.java new file mode 100644 index 0000000..892b5a9 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/scientifique/IScientifiqueIdOnlyProjection.java @@ -0,0 +1,5 @@ +package fr.iut.sciencequest.sae.entities.scientifique; + +public interface IScientifiqueIdOnlyProjection { + int getId(); +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Scientifique.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/scientifique/Scientifique.java similarity index 81% rename from SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Scientifique.java rename to SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/scientifique/Scientifique.java index d2edf66..1e130af 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Scientifique.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/scientifique/Scientifique.java @@ -1,5 +1,9 @@ -package fr.iut.sciencequest.sae.entities; +package fr.iut.sciencequest.sae.entities.scientifique; +import fr.iut.sciencequest.sae.entities.BaseEntity; +import fr.iut.sciencequest.sae.entities.Difficulte; +import fr.iut.sciencequest.sae.entities.Sexe; +import fr.iut.sciencequest.sae.entities.Thematique; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -19,7 +23,7 @@ import java.util.Date; @Data @Entity @Table(name = "scientifique") -public class Scientifique { +public class Scientifique extends BaseEntity { @Id @NotNull @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/notFound/PartieNotFoundException.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/notFound/PartieNotFoundException.java index a47f72a..27b8dd1 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/notFound/PartieNotFoundException.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/notFound/PartieNotFoundException.java @@ -5,8 +5,8 @@ import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(HttpStatus.NOT_FOUND) -public class PartieNotFoundException extends RuntimeException{ - public PartieNotFoundException(String message) { - super(message); +public class PartieNotFoundException extends EntityNotFoundException{ + public PartieNotFoundException(String message, int id) { + super(message, id); } } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ScientifiqueRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ScientifiqueRepository.java index f68fe74..34bc028 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ScientifiqueRepository.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ScientifiqueRepository.java @@ -1,6 +1,6 @@ package fr.iut.sciencequest.sae.repositories; -import fr.iut.sciencequest.sae.entities.Scientifique; +import fr.iut.sciencequest.sae.entities.scientifique.Scientifique; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/IndiceService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/IndiceService.java index c8483e2..978f6f0 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/IndiceService.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/IndiceService.java @@ -1,6 +1,6 @@ package fr.iut.sciencequest.sae.services; -import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection; +import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleAndScientifiqueIdOnlyProjection; import fr.iut.sciencequest.sae.entities.indice.Indice; import fr.iut.sciencequest.sae.exceptions.DuplicatedIdException; import fr.iut.sciencequest.sae.exceptions.notFound.IndiceNotFoundException; @@ -18,8 +18,8 @@ public class IndiceService implements IIndiceService { } @Override - public Iterable findByScientifiqueId(int id) { - return this.indiceRepository.findByScientifiqueId(id, IIndiceidAndLibelleOnlyProjection.class); + public Iterable findByScientifiqueId(int id) { + return this.indiceRepository.findByScientifiqueId(id, IIndiceidAndLibelleAndScientifiqueIdOnlyProjection.class); } @Override diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/PartieService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/PartieService.java new file mode 100644 index 0000000..e81e762 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/PartieService.java @@ -0,0 +1,4 @@ +package fr.iut.sciencequest.sae.services; + +public class PartieService { +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/QuestionService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/QuestionService.java new file mode 100644 index 0000000..06c72ac --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/QuestionService.java @@ -0,0 +1,25 @@ +package fr.iut.sciencequest.sae.services; + +import fr.iut.sciencequest.sae.entities.Question; +import fr.iut.sciencequest.sae.repositories.QuestionRepository; +import fr.iut.sciencequest.sae.services.interfaces.IQuestionService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +@Service +public class QuestionService implements IQuestionService { + private static final int PAGE_SIZE = 1; + private final QuestionRepository questionRepository; + + public QuestionService(QuestionRepository questionRepository) { + this.questionRepository = questionRepository; + } + + @Override + public Page findAll(Integer page) { + Pageable paging = PageRequest.of(page, PAGE_SIZE); + return questionRepository.findAll(paging); + } +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/ScientifiqueService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/ScientifiqueService.java index f5ee452..d2e15f0 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/ScientifiqueService.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/ScientifiqueService.java @@ -1,7 +1,7 @@ package fr.iut.sciencequest.sae.services; -import fr.iut.sciencequest.sae.entities.Scientifique; -import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection; +import fr.iut.sciencequest.sae.entities.scientifique.Scientifique; +import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleAndScientifiqueIdOnlyProjection; import fr.iut.sciencequest.sae.exceptions.notFound.ScientifiqueNotFoundException; import fr.iut.sciencequest.sae.repositories.ScientifiqueRepository; import fr.iut.sciencequest.sae.services.interfaces.IScientifiqueService; @@ -47,7 +47,7 @@ public class ScientifiqueService implements IScientifiqueService { } @Override - public Iterable getLinkedIndicesByScientifiqueId(int id){ + public Iterable getLinkedIndicesByScientifiqueId(int id){ if(!this.scientifiqueRepository.existsById(id)){ throw new ScientifiqueNotFoundException(id); } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IIndiceService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IIndiceService.java index 6fa3ea3..8a6e3ca 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IIndiceService.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IIndiceService.java @@ -1,10 +1,10 @@ package fr.iut.sciencequest.sae.services.interfaces; -import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection; +import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleAndScientifiqueIdOnlyProjection; import fr.iut.sciencequest.sae.entities.indice.Indice; public interface IIndiceService { - Iterable findByScientifiqueId(int id); + Iterable findByScientifiqueId(int id); Indice update(Indice indice); Indice create(Indice indice); } diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IPartieService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IPartieService.java new file mode 100644 index 0000000..3655490 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IPartieService.java @@ -0,0 +1,5 @@ +package fr.iut.sciencequest.sae.services.interfaces; + +public class IPartieService { + +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IQuestionService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IQuestionService.java new file mode 100644 index 0000000..9a6f46f --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IQuestionService.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.services.interfaces; + +import fr.iut.sciencequest.sae.entities.Question; +import org.springframework.data.domain.Page; + +public interface IQuestionService { + Page findAll(Integer page); +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IScientifiqueService.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IScientifiqueService.java index 25d0fd4..7cdc0f9 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IScientifiqueService.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/services/interfaces/IScientifiqueService.java @@ -1,7 +1,7 @@ package fr.iut.sciencequest.sae.services.interfaces; -import fr.iut.sciencequest.sae.entities.Scientifique; -import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleOnlyProjection; +import fr.iut.sciencequest.sae.entities.scientifique.Scientifique; +import fr.iut.sciencequest.sae.entities.indice.IIndiceidAndLibelleAndScientifiqueIdOnlyProjection; import org.springframework.data.domain.Page; public interface IScientifiqueService { @@ -13,5 +13,5 @@ public interface IScientifiqueService { Scientifique findById(int id); - Iterable getLinkedIndicesByScientifiqueId(int id); + Iterable getLinkedIndicesByScientifiqueId(int id); } diff --git a/SpringBootProject/src/main/resources/META-INF/MANIFEST.MF b/SpringBootProject/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..1d13267 --- /dev/null +++ b/SpringBootProject/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: fr.iut.sciencequest.sae.SaeApplication + diff --git a/SpringBootProject/src/main/resources/schema.sql b/SpringBootProject/src/main/resources/schema.sql index fc035a7..02345c8 100644 --- a/SpringBootProject/src/main/resources/schema.sql +++ b/SpringBootProject/src/main/resources/schema.sql @@ -154,9 +154,9 @@ VALUES ('Quel mathématicienne utilisa comme nom d"emprunt « Antoine Auguste Le Blanc » ?'); -- Indices -INSERT INTO Indice (id, libelle, idscientifique) VALUES - (1, 'Indice pour aider', 1), - (2, 'S''appelle Marie', 1); +INSERT INTO Indice (libelle, idscientifique) VALUES + ('Indice pour aider', 1), + ('S''appelle Marie', 1); -- Réponses INSERT INTO Reponse(reponse, idQuestion, idScientifique)