From d66be27cfe101ae460a17023156a844c56a64a76 Mon Sep 17 00:00:00 2001 From: MAIZY Amaury Date: Wed, 30 Apr 2025 09:01:07 +0200 Subject: [PATCH] Modif --- .../java/fr/clelia/avis/business/Editeur.java | 2 +- .../java/fr/clelia/avis/business/Jeu.java | 6 ++- .../java/fr/clelia/avis/business/Joueur.java | 4 +- .../fr/clelia/avis/business/Moderateur.java | 6 +-- .../fr/clelia/avis/business/Plateforme.java | 6 +-- .../fr/clelia/avis/business/Utilisateur.java | 6 +++ .../avis/controller/EditeurController.java | 10 ++-- .../controller/EditeurRestController.java | 24 --------- .../rest/EditeurRestController.java | 49 +++++++++++++++++++ .../exception/EditeurInexistantException.java | 8 +++ .../initialisation/AjoutDonneesInitiales.java | 32 +++++------- .../avis/repository/EditeurRepository.java | 15 ++---- .../clelia/avis/repository/JeuRepository.java | 26 +++++++--- .../avis/repository/JoueurRepository.java | 20 +++++++- .../avis/repository/PlateformeRepository.java | 17 +------ .../clelia/avis/service/EditeurService.java | 4 ++ .../avis/service/impl/EditeurServiceImpl.java | 16 +++++- .../java/fr/clelia/avis/util/ReponseApi.java | 20 ++++++++ 18 files changed, 173 insertions(+), 98 deletions(-) delete mode 100644 src/main/java/fr/clelia/avis/controller/EditeurRestController.java create mode 100644 src/main/java/fr/clelia/avis/controller/rest/EditeurRestController.java create mode 100644 src/main/java/fr/clelia/avis/exception/EditeurInexistantException.java create mode 100644 src/main/java/fr/clelia/avis/util/ReponseApi.java diff --git a/src/main/java/fr/clelia/avis/business/Editeur.java b/src/main/java/fr/clelia/avis/business/Editeur.java index 7be2843..fb702d8 100644 --- a/src/main/java/fr/clelia/avis/business/Editeur.java +++ b/src/main/java/fr/clelia/avis/business/Editeur.java @@ -33,7 +33,7 @@ public class Editeur { @JsonManagedReference @ToString.Exclude - @OneToMany(mappedBy = "editeur", cascade = CascadeType.REMOVE) // OneEditeurToManyJeux + @OneToMany(mappedBy = "editeur", cascade = {CascadeType.REMOVE, CascadeType.PERSIST}) // OneEditeurToManyJeux private List jeux; public Editeur(String nom, String logo) { diff --git a/src/main/java/fr/clelia/avis/business/Jeu.java b/src/main/java/fr/clelia/avis/business/Jeu.java index 2543b81..e37ed72 100644 --- a/src/main/java/fr/clelia/avis/business/Jeu.java +++ b/src/main/java/fr/clelia/avis/business/Jeu.java @@ -1,8 +1,10 @@ package fr.clelia.avis.business; import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; +import lombok.Builder; import lombok.Data; import lombok.NonNull; @@ -11,6 +13,7 @@ import java.util.List; @Entity @Data +@Builder public class Jeu { @Id @@ -25,9 +28,8 @@ public class Jeu { @JsonBackReference private Editeur editeur; - @ManyToMany + @ManyToMany(fetch = FetchType.EAGER) @NonNull - @JsonManagedReference // On souhaite voir en Json les plateformes du jeu private List plateformes; private LocalDate dateDeSortie; diff --git a/src/main/java/fr/clelia/avis/business/Joueur.java b/src/main/java/fr/clelia/avis/business/Joueur.java index 9033dc3..af8fa43 100644 --- a/src/main/java/fr/clelia/avis/business/Joueur.java +++ b/src/main/java/fr/clelia/avis/business/Joueur.java @@ -16,9 +16,7 @@ public class Joueur extends Utilisateur { private LocalDate dateDeNaissance; public Joueur(String pseudo, String email, String motDePasse, LocalDate dateDeNaissance) { - this.setPseudo(pseudo); - this.setEmail(email); - this.setMotDePasse(motDePasse); + super(pseudo, email, motDePasse); this.dateDeNaissance = dateDeNaissance; } } diff --git a/src/main/java/fr/clelia/avis/business/Moderateur.java b/src/main/java/fr/clelia/avis/business/Moderateur.java index cb3dfb2..c9381e4 100644 --- a/src/main/java/fr/clelia/avis/business/Moderateur.java +++ b/src/main/java/fr/clelia/avis/business/Moderateur.java @@ -6,6 +6,8 @@ import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.springframework.boot.convert.DataSizeUnit; +import java.time.LocalDate; + @Entity @Data @SuperBuilder @@ -15,9 +17,7 @@ public class Moderateur extends Utilisateur { private String numeroDeTelephone; public Moderateur(String pseudo, String email, String motDePasse, String numeroDeTelephone) { - this.setPseudo(pseudo); - this.setEmail(email); - this.setMotDePasse(motDePasse); + super(pseudo, email, motDePasse); this.setNumeroDeTelephone(numeroDeTelephone); } } diff --git a/src/main/java/fr/clelia/avis/business/Plateforme.java b/src/main/java/fr/clelia/avis/business/Plateforme.java index 12a0040..5694531 100644 --- a/src/main/java/fr/clelia/avis/business/Plateforme.java +++ b/src/main/java/fr/clelia/avis/business/Plateforme.java @@ -25,9 +25,5 @@ public class Plateforme { @NonNull private String nom; - - @ManyToMany(mappedBy="plateformes") - @JsonIgnore - @ToString.Exclude - private List jeux; + } \ No newline at end of file diff --git a/src/main/java/fr/clelia/avis/business/Utilisateur.java b/src/main/java/fr/clelia/avis/business/Utilisateur.java index fd54e32..3e96f3e 100644 --- a/src/main/java/fr/clelia/avis/business/Utilisateur.java +++ b/src/main/java/fr/clelia/avis/business/Utilisateur.java @@ -25,4 +25,10 @@ public abstract class Utilisateur { @OneToOne protected Avatar avatar; + + protected Utilisateur(String pseudo, String email, String motDePasse) { + this.pseudo = pseudo; + this.email = email; + this.motDePasse = motDePasse; + } } \ No newline at end of file diff --git a/src/main/java/fr/clelia/avis/controller/EditeurController.java b/src/main/java/fr/clelia/avis/controller/EditeurController.java index 6916a39..330a629 100644 --- a/src/main/java/fr/clelia/avis/controller/EditeurController.java +++ b/src/main/java/fr/clelia/avis/controller/EditeurController.java @@ -1,17 +1,18 @@ package fr.clelia.avis.controller; +import fr.clelia.avis.exception.EditeurInexistantException; import fr.clelia.avis.service.EditeurService; +import fr.clelia.avis.util.ReponseApi; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; @Controller public class EditeurController { // Dépendance - private final EditeurService editeurService; + private EditeurService editeurService; public EditeurController(EditeurService editeurService) { this.editeurService = editeurService; @@ -31,4 +32,5 @@ public class EditeurController { modelAndView.addObject("nom", nomRecherche); return modelAndView; } + } diff --git a/src/main/java/fr/clelia/avis/controller/EditeurRestController.java b/src/main/java/fr/clelia/avis/controller/EditeurRestController.java deleted file mode 100644 index 80b0722..0000000 --- a/src/main/java/fr/clelia/avis/controller/EditeurRestController.java +++ /dev/null @@ -1,24 +0,0 @@ -package fr.clelia.avis.controller; - -import fr.clelia.avis.business.Editeur; -import fr.clelia.avis.repository.EditeurRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/editeur") -public class EditeurRestController { - - - @Autowired - private EditeurRepository editeurRepository; - - @GetMapping("/{id}") - public Editeur getEntityById(@PathVariable int id) { - return editeurRepository.findById(id); - } - -} diff --git a/src/main/java/fr/clelia/avis/controller/rest/EditeurRestController.java b/src/main/java/fr/clelia/avis/controller/rest/EditeurRestController.java new file mode 100644 index 0000000..ab47b85 --- /dev/null +++ b/src/main/java/fr/clelia/avis/controller/rest/EditeurRestController.java @@ -0,0 +1,49 @@ +package fr.clelia.avis.controller.rest; + +import fr.clelia.avis.business.Editeur; +import fr.clelia.avis.exception.EditeurInexistantException; +import fr.clelia.avis.service.EditeurService; +import fr.clelia.avis.util.ReponseApi; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import lombok.AllArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@AllArgsConstructor +@RestController +@RequestMapping("api/editeurs") +public class EditeurRestController { + + private final EditeurService editeurService; + + @GetMapping("") + @Operation(summary="Récupère tous les éditeurs") + public List getEditeurs() { + return editeurService.recupererEditeurs(); + } + + @GetMapping("/{id}") + @Operation(summary="Récupère un éditeur par son id") + public Editeur getEditeur(@PathVariable Long id) { + return editeurService.recupererEditeur(id); + } + + @PostMapping("") + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "Ajoute un nouvel éditeur") + public Editeur postEditeur(@RequestBody Editeur editeur) { + return editeurService.ajouterEditeur(editeur); + } + + // TODO comprendre comment les plateformes sur le findAll + + @ExceptionHandler(EditeurInexistantException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ReponseApi traiterEditeurInexistantException(EditeurInexistantException e){ + //return e.getMessage(); + return new ReponseApi<>(String.valueOf(HttpStatus.NOT_FOUND.value()), e.getMessage(), null); + } +} diff --git a/src/main/java/fr/clelia/avis/exception/EditeurInexistantException.java b/src/main/java/fr/clelia/avis/exception/EditeurInexistantException.java new file mode 100644 index 0000000..3a45c66 --- /dev/null +++ b/src/main/java/fr/clelia/avis/exception/EditeurInexistantException.java @@ -0,0 +1,8 @@ +package fr.clelia.avis.exception; + +public class EditeurInexistantException extends RuntimeException { + + public EditeurInexistantException(String message) { + super(message); + } +} diff --git a/src/main/java/fr/clelia/avis/initialisation/AjoutDonneesInitiales.java b/src/main/java/fr/clelia/avis/initialisation/AjoutDonneesInitiales.java index cf05932..79fedb6 100644 --- a/src/main/java/fr/clelia/avis/initialisation/AjoutDonneesInitiales.java +++ b/src/main/java/fr/clelia/avis/initialisation/AjoutDonneesInitiales.java @@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.util.List; @@ -14,21 +15,20 @@ import java.util.Random; @Component // Spring va instancier cette classe // et placer cette instance dans son conteneur IoC -//@AllArgsConstructor +@AllArgsConstructor public class AjoutDonneesInitiales { // Dépendances - @Autowired + //@Autowired private EditeurRepository editeurRepository; - @Autowired + //@Autowired private PlateformeRepository plateformeRepository; - @Autowired private JeuRepository jeuRepository; - @Autowired private JoueurRepository joueurRepository; - @Autowired private ModerateurRepository moderateurRepository; + private UtilisateurRepository utilisateurRepository; + @Transactional @EventListener(ApplicationReadyEvent.class) public void init() { System.out.println("Ajout des données initiales"); @@ -36,17 +36,16 @@ public class AjoutDonneesInitiales { ajouterPlateformes(); ajouterJeux(); ajouterJoueurs(); - ajouteurModerateur(); + ajouterModerateur(); afficherStatistiques(); - // afficherJeuxSurPlateforme("Steam"); + //utilisateurRepository.deleteByMotDePasse("12345"); } private void afficherStatistiques() { editeurRepository.findByLogoStartsWith("micro") .forEach(System.out::println); - plateformeRepository.findByNomStartsWith("Nintendo") - .forEach(System.out::println); - // editeurRepository.findEditeurWithoutJeux(); + joueurRepository.findJoueursTrentenaires().forEach(System.out::println); + jeuRepository.findJeuxByPlateforme(plateformeRepository.findAll().get(0)).forEach(System.out::println); } private void ajouterEditeurs() { @@ -140,6 +139,7 @@ public class AjoutDonneesInitiales { .editeur(editeur) .plateformes(List.of(plateformes.get(0))) .build(); + jeuRepository.save(jeuAvecBuilder); jeuRepository.save(new Jeu("Rocket League", editeurRepository.findByNom("Psyonix"), List.of(plateformeRepository.findByNom("Windows")))); @@ -208,15 +208,7 @@ public class AjoutDonneesInitiales { } - private void ajouteurModerateur() { + private void ajouterModerateur() { moderateurRepository.save(new Moderateur("Fx", "Fx@soprasteria.com", "12345", "+33777777777")); } - - private void afficherJeuxSurPlateforme(String nomPlateforme) { - List jeux = jeuRepository.findJeuxByPlateforme(nomPlateforme); - - System.out.println("Jeux disponibles sur " + nomPlateforme + " :"); - jeux.forEach(System.out::println); - } - } diff --git a/src/main/java/fr/clelia/avis/repository/EditeurRepository.java b/src/main/java/fr/clelia/avis/repository/EditeurRepository.java index 0f6393a..759fd76 100644 --- a/src/main/java/fr/clelia/avis/repository/EditeurRepository.java +++ b/src/main/java/fr/clelia/avis/repository/EditeurRepository.java @@ -1,6 +1,7 @@ package fr.clelia.avis.repository; import fr.clelia.avis.business.Editeur; +import lombok.NonNull; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -8,9 +9,11 @@ import org.springframework.data.repository.query.Param; import java.util.List; public interface EditeurRepository extends JpaRepository { - // Méthode dérivée + // Méthode dérivée (Spring Data nous permet de faire ces méthodes) List findByNomContainingIgnoreCase(String nomRecherche); + // Hibernate va traduire cette requête dans le SQL + // correspondant à notre couche de persistence (H2 ds ce projet) @Query(""" SELECT e FROM Editeur e @@ -19,14 +22,4 @@ public interface EditeurRepository extends JpaRepository { List findByLogoStartsWith(@Param("logo") String logo); Editeur findByNom(String nom); - - @Query(""" - SELECT e - FROM Editeur e - LEFT JOIN e.jeux j - WHERE j IS NULL - """) - List findEditeurWithoutJeux(); - - Editeur findById(int id); } \ No newline at end of file diff --git a/src/main/java/fr/clelia/avis/repository/JeuRepository.java b/src/main/java/fr/clelia/avis/repository/JeuRepository.java index e8b5315..863be67 100644 --- a/src/main/java/fr/clelia/avis/repository/JeuRepository.java +++ b/src/main/java/fr/clelia/avis/repository/JeuRepository.java @@ -1,18 +1,32 @@ package fr.clelia.avis.repository; import fr.clelia.avis.business.Jeu; +import fr.clelia.avis.business.Plateforme; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; import java.util.List; public interface JeuRepository extends JpaRepository { + @Query( - """ - SELECT j - FROM Jeu j - WHERE :plateforme member Of j.plateformes - """ + """ + SELECT j + FROM Jeu j + WHERE :plateforme member Of j.plateformes + """ ) - List findJeuxByPlateforme(String plateforme); + List findJeuxByPlateforme(Plateforme plateforme); + + @Query(""" + SELECT j + FROM Jeu j + JOIN j.plateformes p + WHERE p.nom = :nomPlateforme + """) + List findJeuxByNomPlateforme(@Param("nomPlateforme") String nomPlateforme); + + List findByPlateformesNom(String nom); } \ No newline at end of file diff --git a/src/main/java/fr/clelia/avis/repository/JoueurRepository.java b/src/main/java/fr/clelia/avis/repository/JoueurRepository.java index 6f9fba2..c50f390 100644 --- a/src/main/java/fr/clelia/avis/repository/JoueurRepository.java +++ b/src/main/java/fr/clelia/avis/repository/JoueurRepository.java @@ -3,9 +3,25 @@ package fr.clelia.avis.repository; import fr.clelia.avis.business.Joueur; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import java.util.List; public interface JoueurRepository extends JpaRepository { -} + + @Query(""" + FROM Joueur + WHERE + month(dateDeNaissance) = month(current_date()) + AND day(dateDeNaissance) = day(current_date()) + """) + List findJoueursAnniversaire(); + + @Query(""" + SELECT j + FROM Joueur j + WHERE + j.dateDeNaissance <= current_date() - 30 year + AND j.dateDeNaissance > current_date() - 40 year + """) + List findJoueursTrentenaires(); +} \ No newline at end of file diff --git a/src/main/java/fr/clelia/avis/repository/PlateformeRepository.java b/src/main/java/fr/clelia/avis/repository/PlateformeRepository.java index dcbb35c..ee643c3 100644 --- a/src/main/java/fr/clelia/avis/repository/PlateformeRepository.java +++ b/src/main/java/fr/clelia/avis/repository/PlateformeRepository.java @@ -1,23 +1,8 @@ package fr.clelia.avis.repository; -import fr.clelia.avis.business.Editeur; import fr.clelia.avis.business.Plateforme; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; public interface PlateformeRepository extends JpaRepository { - // Méthode dérivée - List findByNomContainingIgnoreCase(String nomRecherche); - - @Query(""" - SELECT p - FROM Plateforme p - WHERE p.nom LIKE concat(:nom, '%') - """) - List findByNomStartsWith(@Param("nom") String nom); - - Plateforme findByNom(String nom); + Plateforme findByNom(String nintendoSwitch); } \ No newline at end of file diff --git a/src/main/java/fr/clelia/avis/service/EditeurService.java b/src/main/java/fr/clelia/avis/service/EditeurService.java index 54ceeeb..ce820cc 100644 --- a/src/main/java/fr/clelia/avis/service/EditeurService.java +++ b/src/main/java/fr/clelia/avis/service/EditeurService.java @@ -9,4 +9,8 @@ public interface EditeurService { List recupererEditeurs(); List recupererEditeursAyantUnNomContenant(String nomRecherche); + + Editeur recupererEditeur(Long id); + + Editeur ajouterEditeur(Editeur editeur); } diff --git a/src/main/java/fr/clelia/avis/service/impl/EditeurServiceImpl.java b/src/main/java/fr/clelia/avis/service/impl/EditeurServiceImpl.java index 9919c89..02a9c59 100644 --- a/src/main/java/fr/clelia/avis/service/impl/EditeurServiceImpl.java +++ b/src/main/java/fr/clelia/avis/service/impl/EditeurServiceImpl.java @@ -1,17 +1,20 @@ package fr.clelia.avis.service.impl; import fr.clelia.avis.business.Editeur; +import fr.clelia.avis.exception.EditeurInexistantException; import fr.clelia.avis.repository.EditeurRepository; import fr.clelia.avis.service.EditeurService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; //@Component @Service +@Transactional public class EditeurServiceImpl implements EditeurService { - private final EditeurRepository editeurRepository; + private EditeurRepository editeurRepository; // Ce constructeur va faire déduire à Spring // qu'il doit d'abord instancier la repo @@ -29,4 +32,15 @@ public class EditeurServiceImpl implements EditeurService { public List recupererEditeursAyantUnNomContenant(String nomRecherche) { return editeurRepository.findByNomContainingIgnoreCase(nomRecherche); } + + @Override + public Editeur recupererEditeur(Long id) { + // C'est un des rôles du service de lever des exceptions maison + return editeurRepository.findById(id).orElseThrow(() -> new EditeurInexistantException("L'éditeur ayant l'id " + id + " n'existe pas")); + } + + @Override + public Editeur ajouterEditeur(Editeur editeur) { + return editeurRepository.save(editeur); + } } diff --git a/src/main/java/fr/clelia/avis/util/ReponseApi.java b/src/main/java/fr/clelia/avis/util/ReponseApi.java new file mode 100644 index 0000000..85c079f --- /dev/null +++ b/src/main/java/fr/clelia/avis/util/ReponseApi.java @@ -0,0 +1,20 @@ +package fr.clelia.avis.util; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import lombok.AllArgsConstructor; +import lombok.Data; + +@AllArgsConstructor +@Data +public class ReponseApi { + + private String statut; + + @JsonInclude(Include.NON_NULL) + private String message; + + @JsonInclude(Include.NON_NULL) + private T t; + +}