diff --git a/SpringBootProject/pom.xml b/SpringBootProject/pom.xml index 7aa6c3f..d968683 100644 --- a/SpringBootProject/pom.xml +++ b/SpringBootProject/pom.xml @@ -37,6 +37,18 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-hateoas + diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/ApplicationConfig.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/ApplicationConfig.java new file mode 100644 index 0000000..62d7b2a --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/ApplicationConfig.java @@ -0,0 +1,18 @@ +package fr.iut.sciencequest.sae; + +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.accept.FixedContentNegotiationStrategy; +import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +public class ApplicationConfig implements WebMvcConfigurer { + // Permet de forcer l'affichage des erreurs en JSON sans prendre en compte les headers du client + @Override + public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { + configurer.strategies(List.of(new FixedContentNegotiationStrategy(MediaType.APPLICATION_JSON))); + } +} \ No newline at end of file diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/SaeApplication.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/SaeApplication.java index e4c25d6..3595451 100644 --- a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/SaeApplication.java +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/SaeApplication.java @@ -9,5 +9,4 @@ public class SaeApplication { public static void main(String[] args) { SpringApplication.run(SaeApplication.class, args); } - } 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 new file mode 100644 index 0000000..51747ea --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/PartieController.java @@ -0,0 +1,52 @@ +package fr.iut.sciencequest.sae.controllers; + +import fr.iut.sciencequest.sae.entities.Partie; +import fr.iut.sciencequest.sae.exceptions.DuplicatedEntity; +import fr.iut.sciencequest.sae.exceptions.PartieNotFoundException; +import fr.iut.sciencequest.sae.repositories.PartieRepository; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.dao.DataIntegrityViolationException; +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.*; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import javax.print.attribute.standard.Media; +import java.util.Optional; + +@RestController +@RequestMapping("/api/v1/partie") +public class PartieController { + + private static final int PAGE_SIZE = 5; + private final PartieRepository partieRepository; + + public PartieController(PartieRepository partieRepository) { + this.partieRepository = partieRepository; + } + + @RequestMapping(value = "/{id}",method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + 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) + ); + + Link selfLink = linkTo(methodOn(PartieController.class).getPartie(id,request)).withSelfRel(); + return EntityModel.of(Optional.ofNullable(partie), selfLink); + } + + @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.CREATED) + public Partie createPartie(@RequestBody Partie partie) { + try { + return this.partieRepository.save(partie); + } catch (DataIntegrityViolationException e) { + throw new DuplicatedEntity("ERREUR : il existe déjà une partie : " + partie.getId() + " en base"); + } + } + + +} 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 new file mode 100644 index 0000000..484b1c7 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/QuestionController.java @@ -0,0 +1,62 @@ +package fr.iut.sciencequest.sae.controllers; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import fr.iut.sciencequest.sae.entities.Question; +import fr.iut.sciencequest.sae.exceptions.IncorrectPageException; +import fr.iut.sciencequest.sae.repositories.QuestionRepository; +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.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; +import java.util.List; + +@Controller +@RequestMapping("/api/v1/questions") +public class QuestionController { + + private static final int PAGE_SIZE = 10; + private final QuestionRepository questionRepository; + + public QuestionController(QuestionRepository questionRepository) { + this.questionRepository = questionRepository; + } + + @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public CollectionModel> getAllQuestions(@RequestParam(name = "page") Optional page, HttpServletRequest request) { + 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; + } 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 new file mode 100644 index 0000000..5127c6a --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ScientifiqueController.java @@ -0,0 +1,118 @@ +package fr.iut.sciencequest.sae.controllers; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import fr.iut.sciencequest.sae.entities.Indice; +import fr.iut.sciencequest.sae.entities.Scientifique; +import fr.iut.sciencequest.sae.exceptions.DuplicatedEntity; +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.repositories.ScientifiqueRepository; +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.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/api/v1/scientifiques") +public class ScientifiqueController { + + private static final int PAGE_SIZE = 1; + + private final ScientifiqueRepository scientifiqueRepository; + private final IndiceRepository indiceRepository; + + public ScientifiqueController(ScientifiqueRepository scientifiqueRepository, IndiceRepository indiceRepository) { + this.scientifiqueRepository = scientifiqueRepository; + this.indiceRepository = indiceRepository; + } + + @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public CollectionModel> getAllScientists(@RequestParam(name = "page") Optional page) { + try { + Pageable paging = PageRequest.of(page.orElse(0), PAGE_SIZE); + Page pagedResult = scientifiqueRepository.findAll(paging); + + List> scientifiques = pagedResult.map(EntityModel::of).toList(); + + Link selfLink = linkTo(methodOn(ScientifiqueController.class).getAllScientists(page)).withSelfRel().expand(page.map(Object::toString).orElse("0")); + + CollectionModel> result = CollectionModel.of(scientifiques, selfLink); + + if (pagedResult.hasPrevious()) { + Link prevLink = linkTo(methodOn(ScientifiqueController.class).getAllScientists(Optional.of(pagedResult.previousPageable().getPageNumber()))).withRel("previous"); + result.add(prevLink.expand(pagedResult.previousPageable().getPageNumber())); + } + + if (pagedResult.hasNext()) { + Link nextLink = linkTo(methodOn(ScientifiqueController.class).getAllScientists(Optional.of(pagedResult.nextPageable().getPageNumber()))).withRel("next"); + result.add(nextLink.expand(pagedResult.nextPageable().getPageNumber())); + } + + return result; + } catch (IllegalArgumentException e) { + throw new IncorrectPageException("numéro de page incorrect"); + } + } + + @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public EntityModel> getScientistById(@PathVariable int id) { + Optional scientifiqueOptional = this.scientifiqueRepository.findById(id); + Scientifique scientifique = scientifiqueOptional.orElseThrow(() -> new ScientifiqueNotFoundException("Scientifique non trouvé avec l'ID : " + id)); + + Link selfLink = linkTo(methodOn(ScientifiqueController.class).getScientistById(id)).withSelfRel(); + return EntityModel.of(Optional.ofNullable(scientifique), selfLink); + } + + @GetMapping(value="/{id}/indices", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public CollectionModel> getScientistHints(@PathVariable int id, @RequestParam(name = "page") Optional page) { + try { + Pageable paging = PageRequest.of(page.orElse(0), PAGE_SIZE); + Page pagedResult = indiceRepository.findAll(paging); + + List> indices = pagedResult.map(EntityModel::of).toList(); + + Link selfLink = linkTo(methodOn(ScientifiqueController.class).getScientistHints(id, page)).withSelfRel().expand(page.map(Object::toString).orElse("0")); + + CollectionModel> result = CollectionModel.of(indices, selfLink); + + if (pagedResult.hasPrevious()) { + Link prevLink = linkTo(methodOn(ScientifiqueController.class).getScientistHints(id, Optional.of(pagedResult.previousPageable().getPageNumber()))).withRel("previous"); + result.add(prevLink.expand(pagedResult.previousPageable().getPageNumber())); + } + + if (pagedResult.hasNext()) { + Link nextLink = linkTo(methodOn(ScientifiqueController.class).getScientistHints(id, Optional.of(pagedResult.nextPageable().getPageNumber()))).withRel("next"); + result.add(nextLink.expand(pagedResult.nextPageable().getPageNumber())); + } + + return result; + } catch (IllegalArgumentException e) { + throw new IncorrectPageException("numéro de page incorrect"); + } + } + + @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 DuplicatedEntity(e.getMessage()); + } + } +} 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 new file mode 100644 index 0000000..ef6401c --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/controllers/ThematiqueController.java @@ -0,0 +1,40 @@ +package fr.iut.sciencequest.sae.controllers; + +import fr.iut.sciencequest.sae.entities.Thematique; +import fr.iut.sciencequest.sae.exceptions.DuplicatedEntity; +import fr.iut.sciencequest.sae.repositories.ThematiqueRepository; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/thematiques") +public class ThematiqueController { + + private final ThematiqueRepository thematiqueRepository; + + public ThematiqueController(ThematiqueRepository thematiqueRepository) { + this.thematiqueRepository = thematiqueRepository; + } + + @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.OK) + public Iterable getAllThematiques() { + return this.thematiqueRepository.findAll(); + } + + @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.CREATED) + public Thematique postThematique(@RequestBody Thematique thematique, HttpServletRequest request){ + if(this.thematiqueRepository.existsById(thematique.getId())) + throw new DuplicatedEntity("Une thématique avec l'ID "+thematique.getId()+" existe déjà"); + try{ + thematique = this.thematiqueRepository.save(thematique); + return thematique; + } catch (DataIntegrityViolationException e) { + throw new DuplicatedEntity("Une thématique avec le libelle : " + thematique.getLibelle() + " existe déjà"); + } + } +} 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 new file mode 100644 index 0000000..f53d4ca --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Admin.java @@ -0,0 +1,32 @@ +package fr.iut.sciencequest.sae.entities; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Entity +@Table(name="admin") +public class Admin { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Email(message="Veuillez fournir une adresse mail valide") + @NotNull + @NotBlank + @Column(unique = true) + private String email; + + @NotNull + @NotBlank + @Column() + private String password; +} 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 new file mode 100644 index 0000000..dcfcfef --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Difficulte.java @@ -0,0 +1,25 @@ +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; + + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Entity +@Table(name="difficulte") +public class Difficulte { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @NotBlank + @Column(unique = true) + private String libelle; +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Indice.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Indice.java new file mode 100644 index 0000000..1d919ed --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Indice.java @@ -0,0 +1,26 @@ +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; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Entity +@Table(name="indice") +public class Indice { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @NotBlank + private String libelle; + + @NotNull + private int idScientifique; +} 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 new file mode 100644 index 0000000..8c316a7 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Invite.java @@ -0,0 +1,15 @@ +package fr.iut.sciencequest.sae.entities; + + +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{ +} 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 new file mode 100644 index 0000000..4c740a4 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Jeu.java @@ -0,0 +1,30 @@ +package fr.iut.sciencequest.sae.entities; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +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 { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @NotBlank + @Column(unique = true) + private String nom; + + @Column(name = "nbrparties") + @Min(0) + private int nbrParties = 0; +} 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 new file mode 100644 index 0000000..d3005b7 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Joueur.java @@ -0,0 +1,26 @@ +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; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Inheritance ( strategy = InheritanceType.JOINED) +@Entity +@Table(name="joueur") +public abstract class Joueur { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @NotBlank + @Column(unique = true) + private String pseudo; + //private Partie partie; +} 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 new file mode 100644 index 0000000..455dfef --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Partie.java @@ -0,0 +1,36 @@ +package fr.iut.sciencequest.sae.entities; + +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 { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column(name = "codeinvitation", unique = true) + private String codeInvitation; + /*private Jeu jeu; + @Getter() private Set joueurs; + + public boolean add(Joueur joueur){ + return this.joueurs.add(joueur); + } + + public boolean remove(Joueur joueur){ + return this.joueurs.remove(joueur); + } + */ +} 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 new file mode 100644 index 0000000..4290c17 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Question.java @@ -0,0 +1,28 @@ +package fr.iut.sciencequest.sae.entities; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name="question") +public class Question { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + private String question; + + @NotEmpty + @OneToMany(mappedBy = "id") + 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 new file mode 100644 index 0000000..c3924e1 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Reponse.java @@ -0,0 +1,23 @@ +package fr.iut.sciencequest.sae.entities; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name="reponse") +public class Reponse { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @NotNull + private String reponse; + +} 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.java new file mode 100644 index 0000000..336cae0 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Scientifique.java @@ -0,0 +1,58 @@ +package fr.iut.sciencequest.sae.entities; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import org.hibernate.annotations.Type; + +import java.util.Date; + +@AllArgsConstructor +@RequiredArgsConstructor +@Data +@Entity +@Table(name = "scientifique") +public class Scientifique { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @NotNull + @ManyToOne + @JoinColumn(name="iddifficulte") + private Difficulte difficulte; + + @NotNull + @ManyToOne + @JoinColumn(name="idthematique") + private Thematique thematique; + + @Column(name = "photo") + private String pathToPhoto; + + @NotBlank + private String nom; + + @NotBlank + private String prenom; + + @NotBlank + private String descriptif; + + @NotBlank + @Column(name = "datenaissance") + private Date dateNaissance; + + @NotBlank + @Enumerated(EnumType.STRING) + private Sexe sexe; + + @Column(name = "ratiotrouvee") + @Size(min=0, max=1) + private double ratioTrouve = 0.0; +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Sexe.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Sexe.java new file mode 100644 index 0000000..e064ef7 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Sexe.java @@ -0,0 +1,6 @@ +package fr.iut.sciencequest.sae.entities; + +public enum Sexe { + F, + H +} 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 new file mode 100644 index 0000000..e825295 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Thematique.java @@ -0,0 +1,24 @@ +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; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Entity +@Table(name="thematique") +public class Thematique { + @Id + @NotNull + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @NotBlank + @Column(unique = true) + private String libelle; +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Utilisateur.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Utilisateur.java new file mode 100644 index 0000000..05ee7ee --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/entities/Utilisateur.java @@ -0,0 +1,29 @@ +package fr.iut.sciencequest.sae.entities; + + +import jakarta.persistence.*; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +@Data +@Entity +@Table(name="utilisateur") +public class Utilisateur extends Joueur{ + @Email(message="Veuillez fournir une adresse mail valide") + @NotNull + @Column(unique = true) + private String email; + + @NotBlank + @Column(name = "motdepasse") + private String motDePasse; +} + diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/DuplicatedEntity.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/DuplicatedEntity.java new file mode 100644 index 0000000..8bfefa0 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/DuplicatedEntity.java @@ -0,0 +1,12 @@ +package fr.iut.sciencequest.sae.exceptions; + + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.CONFLICT) +public class DuplicatedEntity extends RuntimeException { + public DuplicatedEntity(String message){ + super(message); + } +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/IncorrectPageException.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/IncorrectPageException.java new file mode 100644 index 0000000..57fbd68 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/IncorrectPageException.java @@ -0,0 +1,12 @@ +package fr.iut.sciencequest.sae.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.NOT_ACCEPTABLE) +public class IncorrectPageException extends RuntimeException { + + public IncorrectPageException(String exception) { + super(exception); + } +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/PartieNotFoundException.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/PartieNotFoundException.java new file mode 100644 index 0000000..da3d34c --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/PartieNotFoundException.java @@ -0,0 +1,12 @@ +package fr.iut.sciencequest.sae.exceptions; + + +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); + } +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/ScientifiqueNotFoundException.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/ScientifiqueNotFoundException.java new file mode 100644 index 0000000..b5fbe36 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/exceptions/ScientifiqueNotFoundException.java @@ -0,0 +1,12 @@ +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); + } +} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/AdminRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/AdminRepository.java new file mode 100644 index 0000000..f17aa0d --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/AdminRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Admin; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AdminRepository extends CrudRepository {} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/DifficulteRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/DifficulteRepository.java new file mode 100644 index 0000000..c3a49ec --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/DifficulteRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Difficulte; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DifficulteRepository extends CrudRepository {} \ No newline at end of file diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/IndiceRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/IndiceRepository.java new file mode 100644 index 0000000..62fa68b --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/IndiceRepository.java @@ -0,0 +1,11 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Indice; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface IndiceRepository extends PagingAndSortingRepository, CrudRepository { + +} \ No newline at end of file diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/InviteRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/InviteRepository.java new file mode 100644 index 0000000..cb89deb --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/InviteRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Invite; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface InviteRepository extends CrudRepository {} \ No newline at end of file diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/JeuRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/JeuRepository.java new file mode 100644 index 0000000..5d237b9 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/JeuRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Jeu; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface JeuRepository extends CrudRepository {} \ No newline at end of file diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/JoueurRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/JoueurRepository.java new file mode 100644 index 0000000..61ae108 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/JoueurRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Joueur; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface JoueurRepository extends CrudRepository {} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/PartieRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/PartieRepository.java new file mode 100644 index 0000000..0de5afa --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/PartieRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Partie; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PartieRepository extends CrudRepository {} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/QuestionRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/QuestionRepository.java new file mode 100644 index 0000000..0a5a69e --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/QuestionRepository.java @@ -0,0 +1,11 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Question; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface QuestionRepository extends PagingAndSortingRepository {} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ReponseRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ReponseRepository.java new file mode 100644 index 0000000..8eff9b1 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ReponseRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Reponse; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ReponseRepository extends CrudRepository {} 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 new file mode 100644 index 0000000..c47a28a --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ScientifiqueRepository.java @@ -0,0 +1,9 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Scientifique; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ScientifiqueRepository extends PagingAndSortingRepository, CrudRepository {} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ThematiqueRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ThematiqueRepository.java new file mode 100644 index 0000000..d57aec4 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/ThematiqueRepository.java @@ -0,0 +1,9 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Thematique; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + + +@Repository +public interface ThematiqueRepository extends CrudRepository {} diff --git a/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/UtilisateurRepository.java b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/UtilisateurRepository.java new file mode 100644 index 0000000..ec10a32 --- /dev/null +++ b/SpringBootProject/src/main/java/fr/iut/sciencequest/sae/repositories/UtilisateurRepository.java @@ -0,0 +1,8 @@ +package fr.iut.sciencequest.sae.repositories; + +import fr.iut.sciencequest.sae.entities.Utilisateur; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UtilisateurRepository extends CrudRepository {} \ No newline at end of file diff --git a/SpringBootProject/src/main/resources/application.properties b/SpringBootProject/src/main/resources/application.properties index 8b13789..2e130ca 100644 --- a/SpringBootProject/src/main/resources/application.properties +++ b/SpringBootProject/src/main/resources/application.properties @@ -1 +1,8 @@ - +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=iut +spring.datasource.password=password974519874185$976 +spring.datasource.driver-class-name=org.postgresql.Driver +spring.sql.init.mode=always +spring.sql.init.schema-locations=classpath:schema.sql +spring.jackson.serialization.indent_output = true +server.error.include-message=always \ No newline at end of file diff --git a/SpringBootProject/src/main/resources/schema.sql b/SpringBootProject/src/main/resources/schema.sql new file mode 100644 index 0000000..6f13849 --- /dev/null +++ b/SpringBootProject/src/main/resources/schema.sql @@ -0,0 +1,176 @@ +-- Testé sous pgsql 15 + +DROP TABLE IF EXISTS Reponse CASCADE; +DROP TABLE IF EXISTS Question CASCADE; +DROP TABLE IF EXISTS Admin CASCADE; +DROP TABLE IF EXISTS Partie CASCADE; +DROP TABLE IF EXISTS Jeu CASCADE; +DROP TABLE IF EXISTS Decouvrir CASCADE; +DROP TABLE IF EXISTS Utilisateur CASCADE; +DROP TABLE IF EXISTS Invite CASCADE; +DROP TABLE IF EXISTS Joueur CASCADE; +DROP TABLE IF EXISTS Indice CASCADE; +DROP TABLE IF EXISTS Scientifique CASCADE; +DROP TABLE IF EXISTS Thematique CASCADE; +DROP TABLE IF EXISTS Difficulte; + + +-- THEMATIQUE + +CREATE TABLE Thematique( + id SERIAL PRIMARY KEY, + libelle varchar(128) NOT NULL UNIQUE +); + + +-- DIFFICULTE + +CREATE TABLE Difficulte( + id SERIAL PRIMARY KEY, + libelle varchar(128) NOT NULL UNIQUE +); + + +-- SCIENTIFIQUE + +CREATE TABLE Scientifique( + id SERIAL PRIMARY KEY, + nom varchar(128) NOT NULL, + prenom varchar(128) NOT NULL, + photo varchar(512) NOT NULL, + dateNaissance date NOT NULL, + descriptif text NOT NULL, + ratioTrouvee numeric(5,4), + sexe char(1) NOT NULL CHECK(sexe IN ('F', 'H')), + idThematique integer REFERENCES Thematique(id), + idDifficulte integer REFERENCES Difficulte(id) +); + + +-- INDICE + +CREATE TABLE Indice( + id SERIAL PRIMARY KEY, + libelle varchar(512) NOT NULL UNIQUE, + idScientifique integer REFERENCES Scientifique(id) +); + +-- QUESTION + +CREATE TABLE Question( + id SERIAL PRIMARY KEY, + question varchar(256) NOT NULL UNIQUE +); + + +-- REPONSE + +CREATE TABLE Reponse( + id SERIAL PRIMARY KEY, + reponse varchar(255) NOT NULL, + idQuestion integer REFERENCES Question(id), + idScientifique integer REFERENCES Scientifique(id) +); + + +-- ADMIN + +CREATE TABLE Admin( + id SERIAL PRIMARY KEY, + email varchar(255) NOT NULL UNIQUE, + password varchar(255) NOT NULL +); + +-- Jeu + +CREATE TABLE Jeu( + id SERIAL PRIMARY KEY, + nom varchar(128) NOT NULL UNIQUE, + nbrParties integer NOT NULL DEFAULT 0 +); + + +-- Partie + +CREATE TABLE Partie( + id SERIAL PRIMARY KEY, + codeInvitation varchar(10) NOT NULL UNIQUE, + idJeu integer REFERENCES Jeu(id) +); + +-- JOUEUR + +CREATE TABLE Joueur( + id SERIAL PRIMARY KEY, + idPartie integer REFERENCES Partie(id), + pseudo varchar(255) NOT NULL UNIQUE +); + + +-- Invite + +CREATE TABLE Invite( + idJoueur integer PRIMARY KEY REFERENCES Joueur(id) +); + + +-- Utilisateur + +CREATE TABLE Utilisateur( + idJoueur integer PRIMARY KEY REFERENCES Joueur(id), + email varchar(255) NOT NULL UNIQUE, + password varchar(255) NOT NULL +); + + +-- Decouvrir + +CREATE TABLE Decouvrir( + idUtilisateur integer REFERENCES Utilisateur(idJoueur), + idScientifique integer REFERENCES Scientifique(id), + PRIMARY KEY (idUtilisateur, idScientifique) +); + + +-- INSERTS + +-- Scientifiques +INSERT INTO Difficulte(libelle) VALUES ('Facile'),('Intermédiaire'),('Difficile'); +INSERT INTO Thematique(libelle) VALUES ('Nucléaire'),('Mathématiques'); +INSERT INTO Scientifique(nom, prenom, photo, dateNaissance, descriptif, ratioTrouvee, idThematique, idDifficulte, sexe) +VALUES + ('Marie', 'Curie', '', CURRENT_DATE, 'desc', 0, 1, 1, 'F'), + ('Albert', 'Einstein', '', CURRENT_DATE, 'desc', 0, 2, 1, 'H'), + ('Sophie', 'Germain', '', CURRENT_DATE, 'desc', 0, 2, 2, 'F'); + +-- Jeu +INSERT INTO Jeu(nom) VALUES ('Qui-est-ce ?'),('Science Quizz'), ('Pendu'); + +-- Questions +INSERT INTO Question(question) +VALUES + ('Qui a reçu le prix Nobel de chimie en 1911, pour avoir réussi à isoler un gramme de radium ?'), + ('Quel mathématicien a dit : « Dieu existe, c’est les mathématiques » ?'), + ('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); + +-- Réponses +INSERT INTO Reponse(reponse, idQuestion, idScientifique) +VALUES + ('Marie Curie', 1, 1), + ('Albert Einstein', 2, 2), + ('Sophie Germain', 3, 3); + +-- Utilisateurs +INSERT INTO Joueur(id,pseudo) VALUES (1337, 'moi, le meilleur joueur du monde'); +INSERT INTO Utilisateur(idJoueur,email,password) VALUES (1337, 'joueur','$2y$10$juGnlWC9cS19popEKLZsYeir0Jl39k6hDl0dpaCix00FDcdiEbtmS'); +-- mdp = test + +INSERT INTO decouvrir(idUtilisateur,idScientifique) VALUES (1337,1); + +INSERT INTO Admin(id,email,password) VALUES (1, 'admin','$2y$10$juGnlWC9cS19popEKLZsYeir0Jl39k6hDl0dpaCix00FDcdiEbtmS'); +-- mdp = test