Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb685ef004 | ||
|
|
fbff98f1dd | ||
|
|
1354457836 | ||
|
|
6388783cff | ||
|
|
74b13cc7f4 | ||
|
|
d55e48b7e4 | ||
|
|
50c9f5a61e | ||
|
|
4b2604fe17 | ||
|
|
0553fc13f7 | ||
|
|
9b6b8d6c80 | ||
|
|
b446b16027 | ||
|
|
16126c6364 | ||
|
|
9945ca0baa | ||
|
|
23363c5070 | ||
|
|
de18627c30 | ||
|
|
d79f4f4b8f | ||
|
|
27aff73824 | ||
|
|
b8df2eccd8 | ||
|
|
a99c7676b1 | ||
|
|
bd301f169d | ||
|
|
f4c990c0fb | ||
|
|
72ecb82a46 | ||
|
|
d18bb21b74 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/target/
|
||||||
|
/data/
|
||||||
112
README.md
112
README.md
@@ -1,15 +1,117 @@
|
|||||||
# TP TAA
|
# TP TAA
|
||||||
|
|
||||||
|
## TP2 Partie API REST
|
||||||
|
|
||||||
## TP1 - TP2
|
### Compte rendu
|
||||||
|
Dans ce TP REST, nous avons implémenté les éléments suivants:
|
||||||
|
- Mapper pour convertir les entités vers les DTO et inversement
|
||||||
|
- Lombok afin de simplifier le code et éviter le code boilerplate (getters, setters, constructeurs, etc.)
|
||||||
|
- API REST pour exposer les différentes ressources
|
||||||
|
- Swagger UI pour documenter et tester facilement toutes les méthodes de l’API.
|
||||||
|
- DTO (Data Transfer Objects) afin d’éviter les problèmes de boucle infinie liés aux relations bidirectionnelles entre entités.
|
||||||
|
|
||||||
Le compte rendu pour le TP1 et TP2 partie servlet est dans la branche tp_servlet
|
|
||||||
|
|
||||||
Le compte rendu de la partie API Rest du TP2 est dans la branche tp_rest
|
#### Execution du projet
|
||||||
|
Recharger les dépendances Maven :
|
||||||
|
`mvn clean install`
|
||||||
|
|
||||||
## TP3 - TP4
|
Lancer la base de données (Linux) : `./run-hsqldb-server.sh`
|
||||||
|
|
||||||
Le compte rendu des TP3 et TP4 est dans la branche tp_spring
|
Lancer le serveur par fichier `src/main/java/fr.istic.taa.jaxrs/RestServer.java`
|
||||||
|
|
||||||
|
Après le lancement du serveur, on a testé des appels API avec Insomnia et l'interface Swagger est accessible via: http://localhost:8080/api
|
||||||
|
Seuls Utilisateur et Question sont fonctionnels, il reste quelques problèmes sur le reste.
|
||||||
|
|
||||||
|
|
||||||
|
#### Diagramme de classe
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
Utilisateur "*" -- "*" Session
|
||||||
|
Session "*" -- "*" Quizz
|
||||||
|
Quizz "1" -- "1..*" Question
|
||||||
|
Utilisateur "1" -- "*" Quizz
|
||||||
|
Question "1" -- "1" Reponse
|
||||||
|
Reponse <|-- ReponseCourte
|
||||||
|
Reponse <|-- Choix
|
||||||
|
|
||||||
|
class Utilisateur {
|
||||||
|
-id : int
|
||||||
|
-name : String
|
||||||
|
-session : List<Session>
|
||||||
|
-email : String
|
||||||
|
-password : String
|
||||||
|
-quizzs : String
|
||||||
|
}
|
||||||
|
class Session{
|
||||||
|
-id : int
|
||||||
|
-codePIN : int
|
||||||
|
-quizzs : List<Quizz>
|
||||||
|
-utilisateurs : List<Utilisateur>
|
||||||
|
-theme : String
|
||||||
|
}
|
||||||
|
class Quizz{
|
||||||
|
-session: Session
|
||||||
|
-id : int
|
||||||
|
-createur: Utilisateur
|
||||||
|
}
|
||||||
|
class Reponse{
|
||||||
|
-id : int
|
||||||
|
-question: Question
|
||||||
|
-reponses : ArrayList<String>
|
||||||
|
}
|
||||||
|
class Choix{
|
||||||
|
-choix : ArrayList<String>
|
||||||
|
}
|
||||||
|
class ReponseCourte{
|
||||||
|
}
|
||||||
|
class Question{
|
||||||
|
-id : int
|
||||||
|
-enonce : String
|
||||||
|
-reponse: Reponse
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Utilisateur Resource
|
||||||
|
| Methode | URL | Description |
|
||||||
|
|---------|---------------------------------------------------|-------------------------------------------------------|
|
||||||
|
| GET | `/utilisateur` | Retourne toute la liste de l'utilisateur |
|
||||||
|
| POST | `/utilisateur/register` | S'incrire nouveaux utilisateur |
|
||||||
|
| GET | `/utilisateur/login` | Se connecter |
|
||||||
|
| GET | `/utilisateur/{id}` | Retourne l'utilisateur par id |
|
||||||
|
| GET | `/utilisateur/{user_id}/session` | Retoune la liste de session que l'utilisateur attends |
|
||||||
|
| PUT | `/utilisateur/{user_id}/add_session/{session_id}` | Ajoute un nouveau session à la liste de l'utilisateur |
|
||||||
|
| DELETE | `/utilisteur/{user_id}/delete` | Supprime l'utilisateur |
|
||||||
|
|
||||||
|
##### Session Resource
|
||||||
|
| Methode | URL | Description |
|
||||||
|
|---------|--------------------------------------|------------------------------------|
|
||||||
|
| GET | `/session` | Retourne toute la liste du session |
|
||||||
|
| GET | `/session/{id}` | Retourne la session par id |
|
||||||
|
| GET | `/session/{session_id}/quizzs` | Retourne la liste de quizzs |
|
||||||
|
| GET | `/session/{session_id}/utilisateurs` | Retourne la liste de l'utilisateur |
|
||||||
|
| DELETE | `/session/{session_id}/delete` | Supprime la session |
|
||||||
|
|
||||||
|
##### Quizz Resource
|
||||||
|
| Methode | URL | Description |
|
||||||
|
|---------|------------------------------------------------|-----------------------------------------|
|
||||||
|
| GET | `/quizz` | Retourne toute la liste du quizz |
|
||||||
|
| GET | `/quizz/{quizz_id}/questions` | Retourne toutes questions du quizz |
|
||||||
|
| GET | `/quizz/{quizz_id}/add_question/{question_id}` | Ajoute une nouvuelle question au quizz |
|
||||||
|
| DELETE | `/quizz/{quizz_id}/delete` | Suprrime le quizz |
|
||||||
|
| PUT | `/quizz/{quizz_id}/deleteQ` | Supprime toute les questions de quizz |
|
||||||
|
|
||||||
|
##### Question Resource
|
||||||
|
| Methode | URL | Description |
|
||||||
|
|----------|----------------------------------------------------|-----------------------------------------------------------------------|
|
||||||
|
| GET | `/question` | Retourne toute la liste du question |
|
||||||
|
| POST | `/question/addQuestion` | Créer une question |
|
||||||
|
| PUT | `/question/{question_id}/changeQuestion` | Change l'énoncé de la question |
|
||||||
|
| GET | `/question/{question_id}/getReponse` | retourne l'objet Reponse |
|
||||||
|
| DELETE | `/question/{question_id}/deletReponses` | supprime toute les réponse correct |
|
||||||
|
| PUT | `/question/{question_id}/addReponse` | Ajoute une réponse à Reponse |
|
||||||
|
| PUT | `/question/{question_id}/setReponse/choix` | créer un nouvel objet Reponse de type Choix pour la question |
|
||||||
|
| PUT | `/question/{question_id}/setReponse/reponseCourte` | créer un nouvel objet Reponse de type reponse courte pour la question |
|
||||||
|
| PUT | `/question/{question_id}/addChoix` | rajoute un choix si Reponse est de type Choix |
|
||||||
|
|
||||||
## Auteurs
|
## Auteurs
|
||||||
|
|
||||||
|
|||||||
129
pom.xml
Normal file
129
pom.xml
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>fr.istic.taa</groupId>
|
||||||
|
<artifactId>jaxrs-example</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>jaxrs-example</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
|
<org.mapstruct.version>1.6.3</org.mapstruct.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- ==== JPA / Hibernate ==== -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<version>6.2.7.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>1.7.30</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hsqldb</groupId>
|
||||||
|
<artifactId>hsqldb</artifactId>
|
||||||
|
<version>2.7.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<version>8.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
|
<version>4.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- ==== REST API ==== -->
|
||||||
|
<!--https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-undertow -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-undertow</artifactId>
|
||||||
|
<version>6.2.4.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<!--https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jackson2-provider -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-jackson2-provider</artifactId>
|
||||||
|
<version>6.2.4.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<!--https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jaxb-provider -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-jaxb-provider</artifactId>
|
||||||
|
<version>6.2.4.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- OpenAPI-->
|
||||||
|
<!--https://mvnrepository.com/artifact/io.swagger.core.v3/swagger-jaxrs2-jakarta -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger.core.v3</groupId>
|
||||||
|
<artifactId>swagger-jaxrs2-jakarta</artifactId>
|
||||||
|
<version>2.2.15</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger.core.v3</groupId>
|
||||||
|
<artifactId>swagger-jaxrs2-servlet-initializer-v2</artifactId>
|
||||||
|
<version>2.2.15</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- ==== MapStruct/ Lombok ==== -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<version>1.6.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.42</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<defaultGoal>install</defaultGoal>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>11</source>
|
||||||
|
<target>11</target>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.42</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>1.6.3</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
3
run-hsqldb-server.bat
Executable file
3
run-hsqldb-server.bat
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
mkdir data
|
||||||
|
cd data
|
||||||
|
java -cp ..\hsqldb-2.7.2.jar org.hsqldb.Server
|
||||||
4
run-hsqldb-server.sh
Executable file
4
run-hsqldb-server.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
mvn dependency:copy-dependencies
|
||||||
|
mkdir data 2> /dev/null
|
||||||
|
cd data
|
||||||
|
java -cp ../target/dependency/hsqldb-2.7.2.jar org.hsqldb.Server
|
||||||
2
show-hsqldb.bat
Normal file
2
show-hsqldb.bat
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
java -cp ./target/dependency/hsqldb-2.7.2.jar org.hsqldb.util.DatabaseManagerSwing --driver org.hsqldb.jdbcDriver --url jdbc:hsqldb:hsql://localhost/ --user SA
|
||||||
|
|
||||||
2
show-hsqldb.sh
Executable file
2
show-hsqldb.sh
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#mvn dependency:copy-dependencies
|
||||||
|
java -cp ./target/dependency/hsqldb-2.7.2.jar org.hsqldb.util.DatabaseManagerSwing --driver org.hsqldb.jdbcDriver --url jdbc:hsqldb:hsql://localhost/ --user SA
|
||||||
60
src/main/java/fr/istic/taa/jaxrs/DAO/AbstractJpaDao.java
Normal file
60
src/main/java/fr/istic/taa/jaxrs/DAO/AbstractJpaDao.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.EntityTransaction;
|
||||||
|
public abstract class AbstractJpaDao<K, T extends Serializable> implements IGenericDao<K, T> {
|
||||||
|
protected EntityManager em;
|
||||||
|
private Class<T> entityClass;
|
||||||
|
|
||||||
|
public AbstractJpaDao() {
|
||||||
|
this.em = EntityManagerHelper.getEntityManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pour connaitre qu'on travaille avec quelle classe
|
||||||
|
public void setClass(Class<T> class2){
|
||||||
|
this.entityClass= class2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T findOne(K id) {
|
||||||
|
return em.find(entityClass, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> findAll() {
|
||||||
|
return em.createQuery("select e from " + entityClass.getName() + " as e", entityClass).getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
//CRUD
|
||||||
|
public void create(T entity){
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
t.begin();
|
||||||
|
em.persist(entity);
|
||||||
|
t.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T findById(K id) {
|
||||||
|
return em.find(entityClass, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T update(T entity){
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
t.begin();
|
||||||
|
T T_sync = em.merge(entity);
|
||||||
|
t.commit();
|
||||||
|
return T_sync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(T entity){
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
t.begin();
|
||||||
|
em.remove(entity);
|
||||||
|
t.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteById(K id) {
|
||||||
|
T T_to_be_deleted = em.find(entityClass, id);
|
||||||
|
em.remove(T_to_be_deleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.EntityManagerFactory;
|
||||||
|
import jakarta.persistence.Persistence;
|
||||||
|
|
||||||
|
public class EntityManagerHelper {
|
||||||
|
|
||||||
|
private static EntityManagerFactory emf;
|
||||||
|
private static final ThreadLocal<EntityManager> threadLocal;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
emf = Persistence.createEntityManagerFactory("dev");
|
||||||
|
} catch (Exception e) {
|
||||||
|
emf = null;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
threadLocal = new ThreadLocal<EntityManager>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityManager getEntityManager() {
|
||||||
|
EntityManager em = threadLocal.get();
|
||||||
|
|
||||||
|
if (em == null) {
|
||||||
|
em = emf.createEntityManager();
|
||||||
|
threadLocal.set(em);
|
||||||
|
}
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeEntityManager() {
|
||||||
|
EntityManager em = threadLocal.get();
|
||||||
|
if (em != null) {
|
||||||
|
em.close();
|
||||||
|
threadLocal.set(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeEntityManagerFactory() {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void beginTransaction() {
|
||||||
|
getEntityManager().getTransaction().begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rollback() {
|
||||||
|
getEntityManager().getTransaction().rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void commit() {
|
||||||
|
getEntityManager().getTransaction().commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/main/java/fr/istic/taa/jaxrs/DAO/IGenericDao.java
Normal file
14
src/main/java/fr/istic/taa/jaxrs/DAO/IGenericDao.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface IGenericDao<K, T extends Serializable> {
|
||||||
|
void create(final T entity);
|
||||||
|
T findById(final K id);
|
||||||
|
T update(final T entity);
|
||||||
|
void delete(final T entity);
|
||||||
|
void deleteById(final K id);
|
||||||
|
List<T> findAll();
|
||||||
|
T findOne(final K id);
|
||||||
|
}
|
||||||
108
src/main/java/fr/istic/taa/jaxrs/DAO/QuestionDAO.java
Normal file
108
src/main/java/fr/istic/taa/jaxrs/DAO/QuestionDAO.java
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.metier.Choix;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Question;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Reponse;
|
||||||
|
import fr.istic.taa.jaxrs.metier.ReponseCourte;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Session;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Utilisateur;
|
||||||
|
import jakarta.persistence.EntityTransaction;
|
||||||
|
|
||||||
|
public class QuestionDAO extends AbstractJpaDao<Integer, Question> {
|
||||||
|
public QuestionDAO() {
|
||||||
|
super();
|
||||||
|
this.setClass(Question.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addReponse(String reponse, int questionId) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) t.begin();
|
||||||
|
Question q = em.find(Question.class, questionId);
|
||||||
|
if (q != null && q.getReponse() != null) {
|
||||||
|
q.getReponse().getReponses().add(reponse);
|
||||||
|
em.merge(q);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteReponse(int questionId) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) t.begin();
|
||||||
|
Question q = em.find(Question.class, questionId);
|
||||||
|
if (q != null && q.getReponse() != null) {
|
||||||
|
q.getReponse().setReponses(new ArrayList<>());
|
||||||
|
em.merge(q);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReponse(Reponse rep, Integer id) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) t.begin();
|
||||||
|
Question q = em.find(Question.class, id);
|
||||||
|
if (q != null) {
|
||||||
|
q.setReponse(rep);
|
||||||
|
em.merge(q);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChoix(Integer id) {
|
||||||
|
setReponse(new Choix(), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReponseCourte(Integer id) {
|
||||||
|
setReponse(new ReponseCourte(), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChoix(Integer id, String choix) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) t.begin();
|
||||||
|
Question q = em.find(Question.class, id);
|
||||||
|
if (q != null && q.getReponse() instanceof Choix) {
|
||||||
|
((Choix) q.getReponse()).getChoix().add(choix);
|
||||||
|
em.merge(q);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeEnonce(String newEnonce, Integer id) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) t.begin();
|
||||||
|
Question q = em.find(Question.class, id);
|
||||||
|
if (q != null) {
|
||||||
|
q.setEnonce(newEnonce);
|
||||||
|
em.merge(q);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
48
src/main/java/fr/istic/taa/jaxrs/DAO/QuizzDAO.java
Normal file
48
src/main/java/fr/istic/taa/jaxrs/DAO/QuizzDAO.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.metier.Question;
|
||||||
|
import jakarta.persistence.EntityTransaction;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Quizz;
|
||||||
|
|
||||||
|
public class QuizzDAO extends AbstractJpaDao<Integer, Quizz> {
|
||||||
|
public QuizzDAO(){
|
||||||
|
super();
|
||||||
|
this.setClass(Quizz.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAllQuestion(int quizzId) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) t.begin();
|
||||||
|
Quizz quizz = em.find(Quizz.class, quizzId);
|
||||||
|
if (quizz != null) {
|
||||||
|
quizz.getQuestions().clear();
|
||||||
|
em.merge(quizz);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addQuestion(int quizzId, int questionId) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) t.begin();
|
||||||
|
Quizz quizz = em.find(Quizz.class, quizzId);
|
||||||
|
Question question = em.find(Question.class, questionId);
|
||||||
|
|
||||||
|
if (quizz != null && question != null) {
|
||||||
|
quizz.getQuestions().add(question);
|
||||||
|
em.merge(quizz);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/main/java/fr/istic/taa/jaxrs/DAO/ReponseDAO.java
Normal file
11
src/main/java/fr/istic/taa/jaxrs/DAO/ReponseDAO.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.metier.Reponse;
|
||||||
|
|
||||||
|
public class ReponseDAO extends AbstractJpaDao<Integer, Reponse> {
|
||||||
|
public ReponseDAO(){
|
||||||
|
super();
|
||||||
|
this.setClass(Reponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
33
src/main/java/fr/istic/taa/jaxrs/DAO/SessionDAO.java
Normal file
33
src/main/java/fr/istic/taa/jaxrs/DAO/SessionDAO.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityTransaction;
|
||||||
|
import jakarta.persistence.Query;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Session;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SessionDAO extends AbstractJpaDao<Integer, Session> {
|
||||||
|
public SessionDAO() {
|
||||||
|
super();
|
||||||
|
this.setClass(Session.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Session> findByTheme(String theme) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) {
|
||||||
|
t.begin();
|
||||||
|
}
|
||||||
|
Query query = em.createQuery("SELECT s FROM Session s WHERE s.theme = :theme", Session.class);
|
||||||
|
query.setParameter("theme", theme);
|
||||||
|
List<Session> sessions = query.getResultList();
|
||||||
|
t.commit();
|
||||||
|
return sessions;
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/main/java/fr/istic/taa/jaxrs/DAO/UtilisateurDAO.java
Normal file
61
src/main/java/fr/istic/taa/jaxrs/DAO/UtilisateurDAO.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DAO;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityTransaction;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Session;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Utilisateur;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UtilisateurDAO extends AbstractJpaDao<Integer, Utilisateur> {
|
||||||
|
public UtilisateurDAO() {
|
||||||
|
super();
|
||||||
|
this.setClass(Utilisateur.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Utilisateur findByEmail(String email) {
|
||||||
|
List<Utilisateur> results = em.createQuery(
|
||||||
|
"SELECT u FROM Utilisateur u WHERE u.email = :email", Utilisateur.class)
|
||||||
|
.setParameter("email", email)
|
||||||
|
.getResultList();
|
||||||
|
return results.isEmpty() ? null : results.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToSession(int userId, int sessionId) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) {
|
||||||
|
t.begin();
|
||||||
|
}
|
||||||
|
Session s = em.find(Session.class, sessionId);
|
||||||
|
Utilisateur u = em.find(Utilisateur.class, userId);
|
||||||
|
if (s == null || u == null) {
|
||||||
|
throw new IllegalArgumentException("User or session not found");
|
||||||
|
}
|
||||||
|
if (!u.getSessions().contains(s)) {
|
||||||
|
u.getSessions().add(s);
|
||||||
|
em.merge(u);
|
||||||
|
}
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create(Utilisateur entity) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
try {
|
||||||
|
if (!t.isActive()) {
|
||||||
|
t.begin();
|
||||||
|
}
|
||||||
|
em.merge(entity);
|
||||||
|
t.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (t.isActive()) t.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/main/java/fr/istic/taa/jaxrs/DTO/QuestionDTO.java
Normal file
13
src/main/java/fr/istic/taa/jaxrs/DTO/QuestionDTO.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DTO;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@XmlRootElement
|
||||||
|
public class QuestionDTO {
|
||||||
|
private int id;
|
||||||
|
private String enonce;
|
||||||
|
}
|
||||||
14
src/main/java/fr/istic/taa/jaxrs/DTO/QuizzDTO.java
Normal file
14
src/main/java/fr/istic/taa/jaxrs/DTO/QuizzDTO.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DTO;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@XmlRootElement
|
||||||
|
public class QuizzDTO {
|
||||||
|
private int id;
|
||||||
|
private List<Integer> sessionsId;
|
||||||
|
private Integer utilisateurId;
|
||||||
|
private List<Integer> questionsId;
|
||||||
|
}
|
||||||
11
src/main/java/fr/istic/taa/jaxrs/DTO/ReponseDTO.java
Normal file
11
src/main/java/fr/istic/taa/jaxrs/DTO/ReponseDTO.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DTO;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@XmlRootElement
|
||||||
|
public class ReponseDTO {
|
||||||
|
public List<String> reponses;
|
||||||
|
}
|
||||||
17
src/main/java/fr/istic/taa/jaxrs/DTO/SessionDTO.java
Normal file
17
src/main/java/fr/istic/taa/jaxrs/DTO/SessionDTO.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DTO;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@XmlRootElement
|
||||||
|
public class SessionDTO {
|
||||||
|
private String theme;
|
||||||
|
private int codePIN;
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private List<Integer> quizzsId;
|
||||||
|
private List<Integer> utilisateursId;
|
||||||
|
}
|
||||||
13
src/main/java/fr/istic/taa/jaxrs/DTO/UtilisateurDTO.java
Normal file
13
src/main/java/fr/istic/taa/jaxrs/DTO/UtilisateurDTO.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package fr.istic.taa.jaxrs.DTO;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@XmlRootElement
|
||||||
|
public class UtilisateurDTO {
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
private String email;
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
26
src/main/java/fr/istic/taa/jaxrs/Mapper/QuestionMapper.java
Normal file
26
src/main/java/fr/istic/taa/jaxrs/Mapper/QuestionMapper.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package fr.istic.taa.jaxrs.Mapper;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DTO.QuestionDTO;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Question;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Reponse;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface QuestionMapper {
|
||||||
|
QuestionMapper INSTANCE = Mappers.getMapper( QuestionMapper.class );
|
||||||
|
|
||||||
|
|
||||||
|
QuestionDTO toDTO(Question question);
|
||||||
|
|
||||||
|
Question toEntity(QuestionDTO questionDTO);
|
||||||
|
|
||||||
|
List<QuestionDTO> toDTOs(List<Question> questionList);
|
||||||
|
|
||||||
|
default List<String> question_ReponseString(Reponse reponse){
|
||||||
|
return reponse.getReponses();
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/main/java/fr/istic/taa/jaxrs/Mapper/QuizzMapper.java
Normal file
43
src/main/java/fr/istic/taa/jaxrs/Mapper/QuizzMapper.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package fr.istic.taa.jaxrs.Mapper;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DTO.QuizzDTO;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Question;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Session;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Quizz;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface QuizzMapper {
|
||||||
|
QuizzMapper INSTANCE = Mappers.getMapper( QuizzMapper.class );
|
||||||
|
|
||||||
|
//https://www.baeldung.com/mapstruct-map-source-object-target-list
|
||||||
|
//https://mapstruct.org/
|
||||||
|
@Mapping(target="sessionsId", expression="java(function_mapS(quizz.getSessions()))")
|
||||||
|
@Mapping(target="utilisateurId", source = "createur.id")
|
||||||
|
@Mapping(target="questionsId",expression="java(function_mapQ(quizz.getQuestions()))")
|
||||||
|
QuizzDTO toDTO(Quizz quizz);
|
||||||
|
Quizz toEntity(QuizzDTO quizzDTO);
|
||||||
|
|
||||||
|
List<QuizzDTO> toDTOs(List<Quizz> quizzes);
|
||||||
|
|
||||||
|
default List<Integer> function_mapQ(List<Question> questionList){
|
||||||
|
List<Integer> list=new ArrayList<Integer>();
|
||||||
|
for(Question question : questionList){
|
||||||
|
list.add(question.getId());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<Integer> function_mapS(List<Session> sessionList){
|
||||||
|
List<Integer> list=new ArrayList<Integer>();
|
||||||
|
for(Session session : sessionList){
|
||||||
|
list.add(session.getId());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/main/java/fr/istic/taa/jaxrs/Mapper/SessionMapper.java
Normal file
42
src/main/java/fr/istic/taa/jaxrs/Mapper/SessionMapper.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package fr.istic.taa.jaxrs.Mapper;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DTO.SessionDTO;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Quizz;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Session;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.metier.Utilisateur;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SessionMapper {
|
||||||
|
SessionMapper INSTANCE = Mappers.getMapper( SessionMapper.class );
|
||||||
|
|
||||||
|
@Mapping(target="utilisateursId",expression="java(function_mapU(session.getUtilisateurs()))")
|
||||||
|
@Mapping(target="quizzsId",expression="java(function_mapQ(session.getQuizzs()))")
|
||||||
|
SessionDTO toDTO(Session session);
|
||||||
|
Session toEntity(SessionDTO sessionDTO);
|
||||||
|
|
||||||
|
List<SessionDTO> toDTOs(List<Session> sessions);
|
||||||
|
|
||||||
|
//https://www.baeldung.com/mapstruct-map-source-object-target-list
|
||||||
|
default List<Integer> function_mapU(List<Utilisateur> utilisateurList) {
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
for (Utilisateur utilisateur : utilisateurList) {
|
||||||
|
result.add(utilisateur.getId());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<Integer> function_mapQ(List<Quizz> quizzList) {
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
for (Quizz quizz : quizzList) {
|
||||||
|
result.add(quizz.getId());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package fr.istic.taa.jaxrs.Mapper;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DTO.UtilisateurDTO;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Utilisateur;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UtilisateurMapper {
|
||||||
|
UtilisateurMapper INSTANCE = Mappers.getMapper(UtilisateurMapper.class);
|
||||||
|
|
||||||
|
UtilisateurDTO toDTO(Utilisateur utilisateur);
|
||||||
|
Utilisateur toEntity(UtilisateurDTO dto);
|
||||||
|
|
||||||
|
List<UtilisateurDTO> toDTOs(List<Utilisateur> utilisateurList);
|
||||||
|
}
|
||||||
28
src/main/java/fr/istic/taa/jaxrs/RestServer.java
Normal file
28
src/main/java/fr/istic/taa/jaxrs/RestServer.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package fr.istic.taa.jaxrs;
|
||||||
|
|
||||||
|
import io.undertow.Undertow;
|
||||||
|
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RESTfull microservice, based on JAX-RS and JBoss Undertow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RestServer {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(RestServer.class.getName());
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
UndertowJaxrsServer ut = new UndertowJaxrsServer();
|
||||||
|
TestApplication ta = new TestApplication();
|
||||||
|
ut.deploy(ta);
|
||||||
|
ut.start(
|
||||||
|
Undertow.builder()
|
||||||
|
.addHttpListener(8080, "localhost")
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.info("JAX-RS based micro-service running!");
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/main/java/fr/istic/taa/jaxrs/TestApplication.java
Normal file
45
src/main/java/fr/istic/taa/jaxrs/TestApplication.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright Red Hat, Inc., and individual contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package fr.istic.taa.jaxrs;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.rest.*;
|
||||||
|
import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
|
||||||
|
import jakarta.ws.rs.ApplicationPath;
|
||||||
|
import jakarta.ws.rs.core.Application;
|
||||||
|
|
||||||
|
@ApplicationPath("/")
|
||||||
|
public class TestApplication extends Application {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Class<?>> getClasses() {
|
||||||
|
|
||||||
|
final Set<Class<?>> clazzes = new HashSet<Class<?>>();
|
||||||
|
|
||||||
|
clazzes.add(OpenApiResource.class);
|
||||||
|
clazzes.add(QuestionResource.class);
|
||||||
|
clazzes.add(QuizzResource.class);
|
||||||
|
clazzes.add(UtilisateurResource.class);
|
||||||
|
clazzes.add(SessionResource.class);
|
||||||
|
clazzes.add(SwaggerResource.class);
|
||||||
|
return clazzes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/main/java/fr/istic/taa/jaxrs/metier/Choix.java
Normal file
28
src/main/java/fr/istic/taa/jaxrs/metier/Choix.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package fr.istic.taa.jaxrs.metier;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.PrimaryKeyJoinColumn;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@PrimaryKeyJoinColumn(name = "Choix_Id")
|
||||||
|
public class Choix extends Reponse{
|
||||||
|
List<String> choix;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String valHTML(){
|
||||||
|
String res = "";
|
||||||
|
|
||||||
|
for (String val : this.choix) {
|
||||||
|
res+=val+"<br/>";
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/main/java/fr/istic/taa/jaxrs/metier/Question.java
Normal file
29
src/main/java/fr/istic/taa/jaxrs/metier/Question.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package fr.istic.taa.jaxrs.metier;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@XmlRootElement
|
||||||
|
public class Question implements Serializable {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private int id;
|
||||||
|
private String enonce;
|
||||||
|
|
||||||
|
@OneToOne(cascade = CascadeType.ALL)
|
||||||
|
@JoinColumn(name ="bonne_reponse", referencedColumnName = "id")
|
||||||
|
private Reponse reponse;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name="id_quizz")
|
||||||
|
private Quizz quizz;
|
||||||
|
}
|
||||||
32
src/main/java/fr/istic/taa/jaxrs/metier/Quizz.java
Normal file
32
src/main/java/fr/istic/taa/jaxrs/metier/Quizz.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package fr.istic.taa.jaxrs.metier;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@XmlRootElement
|
||||||
|
public class Quizz implements Serializable {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
private List<Session> sessions;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name="id_utilisateur")
|
||||||
|
private Utilisateur createur;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "quizz")
|
||||||
|
private List<Question> questions=new ArrayList<Question>();
|
||||||
|
}
|
||||||
31
src/main/java/fr/istic/taa/jaxrs/metier/Reponse.java
Normal file
31
src/main/java/fr/istic/taa/jaxrs/metier/Reponse.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package fr.istic.taa.jaxrs.metier;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Inheritance(strategy=InheritanceType.JOINED)
|
||||||
|
@DiscriminatorColumn(name="Type_reponse")
|
||||||
|
@DiscriminatorValue("Reponse")
|
||||||
|
public abstract class Reponse implements Serializable {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@OneToOne
|
||||||
|
private Question question;
|
||||||
|
public List<String> reponses = new ArrayList<String>();
|
||||||
|
|
||||||
|
public String valHTML(){
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/main/java/fr/istic/taa/jaxrs/metier/ReponseCourte.java
Normal file
21
src/main/java/fr/istic/taa/jaxrs/metier/ReponseCourte.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package fr.istic.taa.jaxrs.metier;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.PrimaryKeyJoinColumn;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@PrimaryKeyJoinColumn(name = "RC_Id")
|
||||||
|
public class ReponseCourte extends Reponse{
|
||||||
|
String value;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String valHTML(){
|
||||||
|
return "INPUT";
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/main/java/fr/istic/taa/jaxrs/metier/Session.java
Normal file
32
src/main/java/fr/istic/taa/jaxrs/metier/Session.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package fr.istic.taa.jaxrs.metier;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@XmlRootElement
|
||||||
|
public class Session implements Serializable {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@Column(unique=true)
|
||||||
|
private int codePIN;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy="sessions", fetch = FetchType.EAGER)
|
||||||
|
private List<Quizz> quizzs = new ArrayList<>();
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "sessions", fetch = FetchType.EAGER)
|
||||||
|
private List<Utilisateur> utilisateurs = new ArrayList<>();
|
||||||
|
private String theme;
|
||||||
|
}
|
||||||
35
src/main/java/fr/istic/taa/jaxrs/metier/Utilisateur.java
Normal file
35
src/main/java/fr/istic/taa/jaxrs/metier/Utilisateur.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package fr.istic.taa.jaxrs.metier;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
import lombok.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@XmlRootElement
|
||||||
|
public class Utilisateur implements Serializable {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(unique=true)
|
||||||
|
private String email;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(
|
||||||
|
name="utilisateur_session",
|
||||||
|
joinColumns = @JoinColumn(name="utilisateur_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "session_id")
|
||||||
|
)
|
||||||
|
private List<Session> sessions= new ArrayList<Session>();
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "createur")
|
||||||
|
private List<Quizz> quizzs = new ArrayList<Quizz>();;
|
||||||
|
}
|
||||||
222
src/main/java/fr/istic/taa/jaxrs/rest/QuestionResource.java
Normal file
222
src/main/java/fr/istic/taa/jaxrs/rest/QuestionResource.java
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
package fr.istic.taa.jaxrs.rest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DAO.QuestionDAO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.QuestionDTO;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.QuestionMapper;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Choix;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Question;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Reponse;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
|
||||||
|
@Path("question")
|
||||||
|
@Consumes({"application/json", "application/xml"})
|
||||||
|
@Produces({"application/json", "application/xml"})
|
||||||
|
public class QuestionResource {
|
||||||
|
private final QuestionDAO questionDAO = new QuestionDAO();
|
||||||
|
private final QuestionMapper mapper = QuestionMapper.INSTANCE;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Operation(summary = "List all questions",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "List all questions.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "List of all questions", content = @Content(
|
||||||
|
array = @ArraySchema(schema = @Schema(implementation = Question.class))))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public List<QuestionDTO> listQuestion() {
|
||||||
|
List<Question> questions = questionDAO.findAll();
|
||||||
|
return mapper.toDTOs(questions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/addQuestion")
|
||||||
|
@Operation(summary = "Create a new question",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Create a new question",
|
||||||
|
responses = {@ApiResponse(responseCode = "201", description = "Question added.")}
|
||||||
|
)
|
||||||
|
public Response addQuestion(
|
||||||
|
@Parameter(description = "The question details to be added", required = true) QuestionDTO dto) {
|
||||||
|
Question question = mapper.toEntity(dto);
|
||||||
|
questionDAO.create(question);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Question ajouté avec Succès : \"" + dto.getEnonce() + "\"").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{question_id}/changeQuestion/")
|
||||||
|
@Operation(summary = "Update the text of a question",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Update the text of a question.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Question answer updated."),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Question not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response changeQuestion(
|
||||||
|
@Parameter(description = "ID of the question to modify", required = true) @PathParam("question_id") Integer id,
|
||||||
|
@Parameter(description = "New answer for the question", required = true) String newQuestion) {
|
||||||
|
Question question = questionDAO.findById(id);
|
||||||
|
if (question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
questionDAO.changeEnonce(newQuestion, id);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Enonce de la question mis à jour : " + newQuestion).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{question_id}/getReponse/")
|
||||||
|
@Operation(summary = "Get the correct answer for question",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Get the correct answer for question by ID of question.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "The correct answer", content = @Content(
|
||||||
|
schema = @Schema(implementation = Reponse.class))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Question not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response getReponse(
|
||||||
|
@Parameter(description = "ID of the question", required = true)
|
||||||
|
@PathParam("question_id") Integer id) {
|
||||||
|
|
||||||
|
Question question = questionDAO.findById(id);
|
||||||
|
if (question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
Reponse result = question.getReponse();
|
||||||
|
return Response.ok(result).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{question_id}/addReponse/")
|
||||||
|
@Operation(summary = "Add/Update the correct answer for question",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Add/Update the correct answer for question",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Answer text updated."),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Question not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response addReponse(
|
||||||
|
@Parameter(description = "ID of the question", required = true) @PathParam("question_id") Integer id,
|
||||||
|
@Parameter(description = "The correct answer", required = true) String reponse) {
|
||||||
|
|
||||||
|
Question question = questionDAO.findById(id);
|
||||||
|
if (question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
questionDAO.addReponse(reponse, id);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Reponse correct \"" + reponse + "\" ajouté à la question " + id).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/{question_id}/deletReponses/")
|
||||||
|
@Operation(summary = "Removes the correct response.",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Removes the correct response.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Response deleted."),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Question not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response deleteReponses(
|
||||||
|
@Parameter(description = "ID of the question", required = true)
|
||||||
|
@PathParam("question_id") Integer id) {
|
||||||
|
Question question = questionDAO.findById(id);
|
||||||
|
if (question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
questionDAO.deleteReponse(id);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Reponses supprimé de la question " + id).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{question_id}/setReponse/choix")
|
||||||
|
@Operation(summary = "Set question type to multiple choice",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Set question type to multiple choice type. It could override old answers",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Question type set to multiple choice."),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Question not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response setChoix(
|
||||||
|
@Parameter(description = "ID of the question", required = true)
|
||||||
|
@PathParam("question_id") Integer id) {
|
||||||
|
Question question = questionDAO.findById(id);
|
||||||
|
if (question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
questionDAO.setChoix(id);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Reponses à choix multiple mise sur la question " + id).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{question_id}/setReponse/reponseCourte")
|
||||||
|
@Operation(summary = "Set question type to short answer",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Set question type to multiple short answer. It could override old answers",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Question type set to short answer."),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Question not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response setReponseCourte(
|
||||||
|
@Parameter(description = "ID of the question", required = true)
|
||||||
|
@PathParam("question_id") Integer id) {
|
||||||
|
Question question = questionDAO.findById(id);
|
||||||
|
if (question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
questionDAO.setReponseCourte(id);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Reponses courte mise sur la question " + id).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{question_id}/AddChoix")
|
||||||
|
@Operation(summary = "Add a choice option to a multiple-choice question",
|
||||||
|
tags = {"Questions"},
|
||||||
|
description = "Adds a new choice option to the question (Type Multiple Choice obligatoire)",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Choice added."),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Question not found"),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Wrong type")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response addChoix(
|
||||||
|
@Parameter(description = "ID of the question", required = true) @PathParam("question_id") Integer id,
|
||||||
|
@Parameter(description = "The choice", required = true) String choix){
|
||||||
|
Question question = questionDAO.findById(id);
|
||||||
|
if (question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
if (question.getReponse() instanceof Choix) {
|
||||||
|
return Response.status(Response.Status.EXPECTATION_FAILED).build();
|
||||||
|
}
|
||||||
|
questionDAO.addChoix(id, choix);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Reponses courte mise sur la question " + id).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
180
src/main/java/fr/istic/taa/jaxrs/rest/QuizzResource.java
Normal file
180
src/main/java/fr/istic/taa/jaxrs/rest/QuizzResource.java
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
package fr.istic.taa.jaxrs.rest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DAO.QuestionDAO;
|
||||||
|
import fr.istic.taa.jaxrs.DAO.QuizzDAO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.QuestionDTO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.QuizzDTO;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.QuestionMapper;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.QuizzMapper;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Question;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Quizz;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
@Path("quizz")
|
||||||
|
@Consumes({"application/json", "application/xml"})
|
||||||
|
@Produces({"application/json", "application/xml"})
|
||||||
|
public class QuizzResource {
|
||||||
|
public final QuizzMapper mapper = QuizzMapper.INSTANCE;
|
||||||
|
public final QuizzDAO quizzDAO = new QuizzDAO();
|
||||||
|
public final QuestionDAO questionDAO = new QuestionDAO();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/addQuizz")
|
||||||
|
@Operation(summary = "Create a new quizz",
|
||||||
|
tags = {"Quizz"},
|
||||||
|
description = "Create a new quizz",
|
||||||
|
responses = {@ApiResponse(responseCode = "201", description = "Quizz added.")}
|
||||||
|
)
|
||||||
|
public Response addQuizz(
|
||||||
|
@Parameter(description = "The quizz details to be added", required = true) QuizzDTO dto) {
|
||||||
|
Quizz quizz = mapper.toEntity(dto);
|
||||||
|
quizzDAO.create(quizz);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Quizz ajouté avec Succès : \"" + dto.getId() + "\"").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Operation(summary = "List all quizz",
|
||||||
|
tags = {"Quizz"},
|
||||||
|
description = "List all quizz.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "List of all quizz", content = @Content(
|
||||||
|
array = @ArraySchema(schema = @Schema(implementation = Question.class))))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public List<QuizzDTO> listQuizz() {
|
||||||
|
List<Quizz> quizz = quizzDAO.findAll();
|
||||||
|
return mapper.toDTOs(quizz);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{quizz_id}")
|
||||||
|
@Operation(summary = "Get a quizz by ID",
|
||||||
|
tags = {"Quizzes"},
|
||||||
|
description = "Get a quizz by ID",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "The quizz by ID", content = @Content(
|
||||||
|
schema = @Schema(implementation = QuizzDTO.class))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Quizz not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response getQuizzById(
|
||||||
|
@Parameter(description = "ID of the quizz to fetch", required = true)
|
||||||
|
@PathParam("quizz_id") Integer quizzId) {
|
||||||
|
Quizz quizz = quizzDAO.findById(quizzId);
|
||||||
|
if (quizz == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
QuizzDTO dto = mapper.toDTO(quizz);
|
||||||
|
return Response.status(Response.Status.OK).entity(dto).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{quizz_id}/questions")
|
||||||
|
@Operation(summary = "List all questions for a quizz",
|
||||||
|
tags = {"Quizzes"},
|
||||||
|
description = "List all questions by quizz ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "List of questions", content = @Content(
|
||||||
|
array = @ArraySchema(schema = @Schema(implementation = QuestionDTO.class)))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Quizz not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response getQuestions(
|
||||||
|
@Parameter(description = "ID of the quizz", required = true)
|
||||||
|
@PathParam("quizz_id") Integer quizzId) {
|
||||||
|
Quizz quizz = quizzDAO.findById(quizzId);
|
||||||
|
if (quizz == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
List<Question> questionList = quizz.getQuestions();
|
||||||
|
List<QuestionDTO> dtos = QuestionMapper.INSTANCE.toDTOs(questionList);
|
||||||
|
|
||||||
|
return Response.status(Response.Status.OK).entity(dtos).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{quizz_id}/add_question/{question_id}")
|
||||||
|
@Operation(summary = "Add a question to a quizz",
|
||||||
|
tags = {"Quizzes"},
|
||||||
|
description = "Add question to quizz by quizz ID and question ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Question added successfully",
|
||||||
|
content = @Content(schema = @Schema(implementation = QuizzDTO.class))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Quizz or Question not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response addQuestion(
|
||||||
|
@Parameter(description = "ID of the quizz to update", required = true) @PathParam("quizz_id") Integer quizzId,
|
||||||
|
@Parameter(description = "ID of the question to add", required = true) @PathParam("question_id") Integer questionId) {
|
||||||
|
Quizz quizz = quizzDAO.findById(quizzId);
|
||||||
|
Question question = questionDAO.findById(questionId);
|
||||||
|
if (quizz == null || question == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
quizzDAO.addQuestion(quizzId, questionId);
|
||||||
|
quizzDAO.update(quizz);
|
||||||
|
QuizzDTO quizzDTO = mapper.toDTO(quizz);
|
||||||
|
return Response.status(Response.Status.OK).entity(quizzDTO).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{quizz_id}/deleteQ")
|
||||||
|
@Operation(summary = "Remove all questions from a quizz",
|
||||||
|
tags = {"Quizzes"},
|
||||||
|
description = "Removes all questions by ID of quizz.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Removed all questions"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Quizz not found")}
|
||||||
|
)
|
||||||
|
public Response deleteQuestion(
|
||||||
|
@Parameter(description = "ID of the quizz", required = true)
|
||||||
|
@PathParam("quizz_id") Integer quizzId) {
|
||||||
|
Quizz quizz = quizzDAO.findById(quizzId);
|
||||||
|
if (quizz == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
quizzDAO.deleteAllQuestion(quizzId);
|
||||||
|
quizzDAO.update(quizz);
|
||||||
|
return Response.status(Response.Status.OK).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/{quizz_id}/delete")
|
||||||
|
@Operation(summary = "Delete a Quizz",
|
||||||
|
tags = {"Quizzes"},
|
||||||
|
description = "Deletes a Quizz by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Quizz deleted."),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Quizz not found.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response deleteQuizz(
|
||||||
|
@Parameter(description = "ID of the Quizz to delete", required = true)
|
||||||
|
@PathParam("quizz_id") Integer quizzId) {
|
||||||
|
Quizz quizz = quizzDAO.findById(quizzId);
|
||||||
|
if (quizz == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
quizzDAO.delete(quizz);
|
||||||
|
return Response.status(Response.Status.OK).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
158
src/main/java/fr/istic/taa/jaxrs/rest/SessionResource.java
Normal file
158
src/main/java/fr/istic/taa/jaxrs/rest/SessionResource.java
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
package fr.istic.taa.jaxrs.rest;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DAO.SessionDAO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.QuizzDTO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.SessionDTO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.UtilisateurDTO;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.QuizzMapper;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.SessionMapper;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.UtilisateurMapper;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Quizz;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Session;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Utilisateur;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
|
||||||
|
@Path("session")
|
||||||
|
@Consumes({"application/json", "application/xml"})
|
||||||
|
@Produces({"application/json", "application/xml"})
|
||||||
|
public class SessionResource {
|
||||||
|
private final SessionDAO sessionDAO = new SessionDAO();
|
||||||
|
private final SessionMapper mapper = SessionMapper.INSTANCE;
|
||||||
|
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/addSession")
|
||||||
|
@Operation(summary = "Create a new session",
|
||||||
|
tags = {"Session"},
|
||||||
|
description = "Create a new session",
|
||||||
|
responses = {@ApiResponse(responseCode = "201", description = "Session added.")}
|
||||||
|
)
|
||||||
|
public Response addQuizz(
|
||||||
|
@Parameter(description = "The session details to be added", required = true) SessionDTO dto) {
|
||||||
|
Session session = mapper.toEntity(dto);
|
||||||
|
sessionDAO.create(session);
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Session ajouté avec Succès : \"" + dto.getTheme() + "\"").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Operation(summary = "List all session", tags = {"Sessions"},
|
||||||
|
description = "Get a list of all sessions in BDD",
|
||||||
|
responses = {@ApiResponse(description = "List of sessions", content = @Content(
|
||||||
|
schema = @Schema(implementation = Session.class)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public List<SessionDTO> listSession() {
|
||||||
|
List<Session> sessions = sessionDAO.findAll();
|
||||||
|
return mapper.toDTOs(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{id}")
|
||||||
|
@Operation(summary = "Get session by ID",
|
||||||
|
tags = {"Sessions"},
|
||||||
|
description = "Get session by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "Session", content = @Content(
|
||||||
|
schema = @Schema(implementation = SessionDTO.class)
|
||||||
|
)),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Session not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response getSession(
|
||||||
|
@Parameter(description = "ID of the session to fetch", required = true)
|
||||||
|
@PathParam("id") Integer id) {
|
||||||
|
Session session = sessionDAO.findById(id);
|
||||||
|
if (session == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
SessionDTO result = mapper.toDTO(session);
|
||||||
|
return Response.status(Response.Status.OK).entity(result).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{session_id}/quizzs")
|
||||||
|
@Operation(summary = "Get all quizzes for a session",
|
||||||
|
tags = {"Sessions"},
|
||||||
|
description = "Get all quizzes for a session by ID of session.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "List of quizzes", content = @Content(
|
||||||
|
array = @ArraySchema(schema = @Schema(implementation = QuizzDTO.class))
|
||||||
|
)),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Session not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response getQuizzs(
|
||||||
|
@Parameter(description = "ID of the session to get quizzes", required = true)
|
||||||
|
@PathParam("session_id") Integer sessionId) {
|
||||||
|
Session session = sessionDAO.findById(sessionId);
|
||||||
|
if (session == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
List<QuizzDTO> results = QuizzMapper.INSTANCE.toDTOs(session.getQuizzs());
|
||||||
|
return Response.status(Response.Status.OK).entity(results).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{session_id}/utilisateurs")
|
||||||
|
@Operation(summary = "Get all users for a session",
|
||||||
|
tags = {"Sessions"},
|
||||||
|
description = "Get all users for a session by ID of session.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "List of users", content = @Content(
|
||||||
|
array = @ArraySchema(schema = @Schema(implementation = UtilisateurDTO.class))
|
||||||
|
)),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Session not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response getUtilisateurs(
|
||||||
|
@Parameter(description = "ID of the session to get users", required = true)
|
||||||
|
@PathParam("session_id") Integer sessionId) {
|
||||||
|
|
||||||
|
Session session = sessionDAO.findById(sessionId);
|
||||||
|
if (session == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
List<Utilisateur> utilisateurList = session.getUtilisateurs();
|
||||||
|
List<UtilisateurDTO> dtos = UtilisateurMapper.INSTANCE.toDTOs(utilisateurList);
|
||||||
|
return Response.status(Response.Status.OK).entity(dtos).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/{session_id}/delete")
|
||||||
|
@Operation(summary = "Delete a session",
|
||||||
|
tags = {"Sessions"},
|
||||||
|
description = "Deletes a session by ID of session.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Session deleted"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Session not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response deleteSession(
|
||||||
|
@Parameter(description = "ID of the session to delete", required = true)
|
||||||
|
@PathParam("session_id") Integer sessionId) {
|
||||||
|
Session session = sessionDAO.findById(sessionId);
|
||||||
|
if (session == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
sessionDAO.delete(session);
|
||||||
|
return Response.status(Response.Status.OK).entity("Session deleted").build();
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/main/java/fr/istic/taa/jaxrs/rest/SwaggerResource.java
Normal file
45
src/main/java/fr/istic/taa/jaxrs/rest/SwaggerResource.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package fr.istic.taa.jaxrs.rest;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
|
||||||
|
@Path("/api")
|
||||||
|
public class SwaggerResource {
|
||||||
|
private static final Logger logger = Logger.getLogger(SwaggerResource.class.getName());
|
||||||
|
|
||||||
|
private static final String SWAGGER_BASE_PATH = "swagger/";
|
||||||
|
|
||||||
|
@GET
|
||||||
|
public Response Get1() {
|
||||||
|
return getFileContent("index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{path:.*}")
|
||||||
|
public Response Get(@PathParam("path") String path) {
|
||||||
|
return getFileContent(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response getFileContent(String fileName) {
|
||||||
|
String fullPath = SWAGGER_BASE_PATH + fileName;
|
||||||
|
try (InputStream is = getClass().getClassLoader().getResourceAsStream(fullPath)) {
|
||||||
|
if (is == null) {
|
||||||
|
logger.warning("File not found: " + fullPath);
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build(); // HTTP 404
|
||||||
|
}
|
||||||
|
return Response.ok(is.readAllBytes()).build();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.severe("Error reading file " + fullPath + ": " + e.getMessage());
|
||||||
|
return Response.serverError().build(); // HTTP 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
204
src/main/java/fr/istic/taa/jaxrs/rest/UtilisateurResource.java
Normal file
204
src/main/java/fr/istic/taa/jaxrs/rest/UtilisateurResource.java
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package fr.istic.taa.jaxrs.rest;
|
||||||
|
|
||||||
|
import fr.istic.taa.jaxrs.DAO.SessionDAO;
|
||||||
|
import fr.istic.taa.jaxrs.DAO.UtilisateurDAO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.SessionDTO;
|
||||||
|
import fr.istic.taa.jaxrs.DTO.UtilisateurDTO;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.SessionMapper;
|
||||||
|
import fr.istic.taa.jaxrs.Mapper.UtilisateurMapper;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Question;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Session;
|
||||||
|
import fr.istic.taa.jaxrs.metier.Utilisateur;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Path("utilisateur")
|
||||||
|
@Consumes({"application/json", "application/xml"})
|
||||||
|
@Produces({"application/json", "application/xml"})
|
||||||
|
public class UtilisateurResource {
|
||||||
|
private final UtilisateurDAO utilisateurDAO = new UtilisateurDAO();
|
||||||
|
private final UtilisateurMapper mapper = UtilisateurMapper.INSTANCE;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Operation(summary = "List all users", tags = {"Utilisateurs"},
|
||||||
|
description = "Get a list of all users in BDD",
|
||||||
|
responses = {@ApiResponse(description = "List of users", content = @Content(
|
||||||
|
schema = @Schema(implementation = Utilisateur.class)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public List<UtilisateurDTO> listUtilisateur() {
|
||||||
|
List<Utilisateur> utilisateurs = utilisateurDAO.findAll();
|
||||||
|
return mapper.toDTOs(utilisateurs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//https://stackoverflow.com/questions/9269040/which-http-response-code-for-this-email-is-already-registered
|
||||||
|
@POST
|
||||||
|
@Path("/register")
|
||||||
|
@Operation(summary = "Register a new user",
|
||||||
|
tags = {"Utilisateurs"},
|
||||||
|
description = "Registers a new user.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Registration succès"),
|
||||||
|
@ApiResponse(responseCode = "409", description = "Email est déjà registré")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response registerUtilisateur(
|
||||||
|
@Parameter(description = "User details for registration", required = true) UtilisateurDTO dto) {
|
||||||
|
String email_verification = dto.getEmail();
|
||||||
|
Utilisateur existing = utilisateurDAO.findByEmail(email_verification);
|
||||||
|
|
||||||
|
//VERIFACTION S'IL EXISTE DANS BDD
|
||||||
|
if (existing != null) {
|
||||||
|
return Response.status(Response.Status.CONFLICT).entity("Email est déjà registré").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
Utilisateur utilisateur = mapper.toEntity(dto);
|
||||||
|
utilisateurDAO.create(utilisateur);
|
||||||
|
|
||||||
|
return Response.status(Response.Status.CREATED).entity("Registration succès").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/login")
|
||||||
|
@Operation(summary = "Log in a user",
|
||||||
|
tags = {"Utilisateurs"},
|
||||||
|
description = "Authenticates a user and returns the user's details upon success.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Successful login", content = @Content(
|
||||||
|
schema = @Schema(implementation = UtilisateurDTO.class)
|
||||||
|
)),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Email n'existe pas"),
|
||||||
|
@ApiResponse(responseCode = "401", description = "Mauvais mdp")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response loginUtilisateur(
|
||||||
|
@Parameter(description = "User credentials (email and password)", required = true) UtilisateurDTO dto) {
|
||||||
|
Utilisateur utilisateur = utilisateurDAO.findByEmail(dto.getEmail());
|
||||||
|
|
||||||
|
if (utilisateur == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).entity("Email n'existe pas").build();
|
||||||
|
} else if (!utilisateur.getPassword().equals(dto.getPassword())) {
|
||||||
|
return Response.status(Response.Status.UNAUTHORIZED).entity("Mauvais mdp").build();
|
||||||
|
}
|
||||||
|
UtilisateurDTO result = mapper.toDTO(utilisateur);
|
||||||
|
|
||||||
|
return Response.status(Response.Status.OK).entity(result).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{id}")
|
||||||
|
@Operation(summary = "Get user by ID",
|
||||||
|
tags = {"Utilisateurs"},
|
||||||
|
description = "Get User by ID",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(description = "Utilisateur", content = @Content(
|
||||||
|
schema = @Schema(implementation = Utilisateur.class)
|
||||||
|
)),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Invalid ID supplied"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
})
|
||||||
|
public Response getUtilisateur(@Parameter(
|
||||||
|
description = "ID of user that needs to be fetched",
|
||||||
|
schema = @Schema(
|
||||||
|
type = "integer",
|
||||||
|
format = "int32",
|
||||||
|
description = "param ID of user that needs to be fetched"
|
||||||
|
),
|
||||||
|
required = true)
|
||||||
|
@PathParam("id") Integer id) {
|
||||||
|
Utilisateur utilisateur = utilisateurDAO.findById(id);
|
||||||
|
if (utilisateur == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
UtilisateurDTO result = mapper.toDTO(utilisateur);
|
||||||
|
return Response.ok(result).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{user_id}/add_session/{session_id}")
|
||||||
|
@Operation(summary = "Add a session to a user",
|
||||||
|
tags = {"Utilisateurs"},
|
||||||
|
description = "Add a session to a user existed in BDD",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Session added successfully", content = @Content(
|
||||||
|
schema = @Schema(implementation = UtilisateurDTO.class) // Returns updated user DTO
|
||||||
|
)),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User or Session not found"),
|
||||||
|
@ApiResponse(responseCode = "409", description = "User is already in the session")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response addSession(
|
||||||
|
@Parameter(description = "ID of the user") @PathParam("user_id") Integer user_id,
|
||||||
|
@Parameter(description = "ID of the session to add") @PathParam("session_id") Integer session_id) {
|
||||||
|
SessionDAO sessionDAO = new SessionDAO();
|
||||||
|
|
||||||
|
Session existingSession = sessionDAO.findById(session_id);
|
||||||
|
Utilisateur utilisateur = utilisateurDAO.findById(user_id);
|
||||||
|
|
||||||
|
if (existingSession == null || utilisateur == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
//If user already joined
|
||||||
|
if (utilisateur.getSessions().contains(existingSession)) {
|
||||||
|
return Response.status(Response.Status.CONFLICT).build();
|
||||||
|
}
|
||||||
|
utilisateurDAO.addToSession(user_id, session_id);
|
||||||
|
utilisateurDAO.update(utilisateur);
|
||||||
|
|
||||||
|
// We update it so have to return new DTO
|
||||||
|
UtilisateurDTO dto = mapper.toDTO(utilisateur);
|
||||||
|
|
||||||
|
return Response.status(Response.Status.OK).entity(dto).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{user_id}/session")
|
||||||
|
@Operation(summary = "List of all sessions of a user",
|
||||||
|
tags = {"Utilisateurs"},
|
||||||
|
description = "Return a response of all sessions of a user",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "List of user's sessions", content = @Content(
|
||||||
|
schema = @Schema(implementation = SessionDTO.class)
|
||||||
|
)),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response listSession(
|
||||||
|
@Parameter(description = "ID of the user") @PathParam("user_id") Integer user_id) {
|
||||||
|
|
||||||
|
Utilisateur utilisateur = utilisateurDAO.findById(user_id);
|
||||||
|
if (utilisateur == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
List<Session> sess = utilisateur.getSessions();
|
||||||
|
List<SessionDTO> dtos = SessionMapper.INSTANCE.toDTOs(sess);
|
||||||
|
return Response.status(Response.Status.OK).entity(dtos).build();
|
||||||
|
}
|
||||||
|
@DELETE
|
||||||
|
@Path("{user_id}/delete")
|
||||||
|
@Operation(summary = "Delete a user",
|
||||||
|
tags = {"Utilisateurs"},
|
||||||
|
description = "Delete a user with ID",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "User deleted"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public Response deleteUtilisateur(
|
||||||
|
@Parameter(description = "ID of the user to delete") @PathParam("user_id") Integer user_id) {
|
||||||
|
Utilisateur existing = utilisateurDAO.findById(user_id);
|
||||||
|
if (existing == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
utilisateurDAO.delete(existing);
|
||||||
|
return Response.status(Response.Status.OK).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/main/resources/META-INF/persistence.xml
Normal file
67
src/main/resources/META-INF/persistence.xml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
|
||||||
|
version="3.0">
|
||||||
|
|
||||||
|
<persistence-unit name="dev" transaction-type="RESOURCE_LOCAL">
|
||||||
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
<properties>
|
||||||
|
<property name="jakarta.persistence.jdbc.driver"
|
||||||
|
value="org.hsqldb.jdbcDriver" />
|
||||||
|
<property name="jakarta.persistence.jdbc.url"
|
||||||
|
value="jdbc:hsqldb:hsql://localhost/" />
|
||||||
|
<property name="jakarta.persistence.jdbc.user" value="sa" />
|
||||||
|
<property name="jakarta.persistence.jdbc.password" value="" />
|
||||||
|
<property
|
||||||
|
name="jakarta.persistence.schema-generation.database.action"
|
||||||
|
value="create" />
|
||||||
|
<property name="jakarta.persistence.dialect"
|
||||||
|
value="org.hibernate.dialect.HSQLDialect" />
|
||||||
|
<property name="hibernate.show_sql" value="true" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
<persistence-unit name="prod" transaction-type="RESOURCE_LOCAL">
|
||||||
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
<properties>
|
||||||
|
<property name="jakarta.persistence.jdbc.driver"
|
||||||
|
value="org.hsqldb.jdbcDriver" />
|
||||||
|
<property name="jakarta.persistence.jdbc.url"
|
||||||
|
value="jdbc:hsqldb:hsql://localhost/" />
|
||||||
|
<property name="jakarta.persistence.jdbc.user" value="sa" />
|
||||||
|
<property name="jakarta.persistence.jdbc.password" value="" />
|
||||||
|
<property
|
||||||
|
name="jakarta.persistence.schema-generation.database.action"
|
||||||
|
value="update" />
|
||||||
|
<property name="jakarta.persistence.dialect"
|
||||||
|
value="org.hibernate.dialect.HSQLDialect" />
|
||||||
|
<property name="hibernate.show_sql" value="true" />
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="mysql">
|
||||||
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<property name="jakarta.persistence.jdbc.driver"
|
||||||
|
value="com.mysql.cj.jdbc.Driver" />
|
||||||
|
<property name="jakarta.persistence.jdbc.url"
|
||||||
|
value="jdbc:mysql://localhost/mydatabase" />
|
||||||
|
<property name="jakarta.persistence.jdbc.user" value="tlc" />
|
||||||
|
<property name="jakarta.persistence.jdbc.password" value="tlc" />
|
||||||
|
<property
|
||||||
|
name="jakarta.persistence.schema-generation.database.action"
|
||||||
|
value="update" />
|
||||||
|
<property name="jakarta.persistence.dialect"
|
||||||
|
value="org.hibernate.dialect.MySQL8Dialect" />
|
||||||
|
<property name="hibernate.show_sql" value="true" />
|
||||||
|
<property name="hibernate.c3p0.min_size" value="5" />
|
||||||
|
<property name="hibernate.c3p0.max_size" value="20" />
|
||||||
|
<property name="hibernate.c3p0.timeout" value="300" />
|
||||||
|
<property name="hibernate.c3p0.max_statements" value="50" />
|
||||||
|
<property name="hibernate.c3p0.idle_test_period" value="3000" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
|
</persistence>
|
||||||
92
src/main/resources/swagger/index.html
Normal file
92
src/main/resources/swagger/index.html
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<!-- HTML for static distribution bundle build -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Swagger UI</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="https://unpkg.com/swagger-ui-dist/swagger-ui.css">
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: -moz-scrollbars-vertical;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
style="position:absolute;width:0;height:0">
|
||||||
|
<defs>
|
||||||
|
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||||
|
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol viewBox="0 0 20 20" id="locked">
|
||||||
|
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol viewBox="0 0 20 20" id="close">
|
||||||
|
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol viewBox="0 0 20 20" id="large-arrow">
|
||||||
|
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol viewBox="0 0 20 20" id="large-arrow-down">
|
||||||
|
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
|
||||||
|
<symbol viewBox="0 0 24 24" id="jump-to">
|
||||||
|
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol viewBox="0 0 24 24" id="expand">
|
||||||
|
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
|
||||||
|
<script src="https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"></script>
|
||||||
|
<script src="https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
// Build a system
|
||||||
|
const ui = SwaggerUIBundle({
|
||||||
|
url: "http://localhost:8080/openapi.json",
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
|
],
|
||||||
|
layout: "StandaloneLayout"
|
||||||
|
})
|
||||||
|
|
||||||
|
window.ui = ui
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user