Files
mic-after-work-server-impl-…/src/main/java/com/lions/dev/resource/EventsResource.java
2024-09-24 00:31:52 +00:00

589 lines
24 KiB
Java

package com.lions.dev.resource;
import com.lions.dev.service.EventService;
import com.lions.dev.repository.EventsRepository;
import com.lions.dev.dto.request.events.EventCreateRequestDTO;
import com.lions.dev.dto.request.events.EventUpdateRequestDTO;
import com.lions.dev.dto.response.events.EventCreateResponseDTO;
import com.lions.dev.dto.response.events.EventUpdateResponseDTO;
import com.lions.dev.entity.events.Events;
import com.lions.dev.entity.users.Users;
import com.lions.dev.repository.UsersRepository; // Ajout du UsersRepository pour gérer les
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Response;
import java.io.File; // participants
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import com.lions.dev.core.errors.exceptions.EventNotFoundException;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.jboss.logging.Logger;
/**
* Ressource REST pour la gestion des événements dans le système AfterWork. Cette classe expose des
* endpoints pour créer, récupérer, et supprimer des événements.
*
* <p>Tous les logs nécessaires pour la traçabilité sont intégrés.
*/
@Path("/events")
@Produces("application/json")
@Consumes("application/json")
@Tag(name = "Events", description = "Opérations liées à la gestion des événements")
public class EventsResource {
@Inject
EventsRepository eventsRepository;
@Inject
UsersRepository usersRepository; // Ajout pour la gestion des participants
@Inject
EventService eventService;
private static final Logger LOG = Logger.getLogger(EventsResource.class);
/**
* Endpoint pour créer un nouvel événement.
*
* @param eventCreateRequestDTO Le DTO contenant les informations de l'événement à créer.
* @return Une réponse HTTP contenant l'événement créé ou un message d'erreur.
*/
@POST
@Transactional
@Operation(
summary = "Créer un nouvel événement",
description = "Crée un nouvel événement et retourne ses détails")
public Response createEvent(EventCreateRequestDTO eventCreateRequestDTO) {
LOG.info(
"[LOG] Tentative de création d'un nouvel événement : " + eventCreateRequestDTO.getTitle());
// Récupérer l'utilisateur créateur à partir de l'identifiant
Users creator = usersRepository.findById(eventCreateRequestDTO.getCreatorId());
if (creator == null) {
LOG.error("[ERROR] Créateur non trouvé avec l'ID : " + eventCreateRequestDTO.getCreatorId());
return Response.status(Response.Status.BAD_REQUEST).entity("Créateur non trouvé").build();
}
// Appel au service pour créer l'événement
Events event = eventService.createEvent(eventCreateRequestDTO, creator);
LOG.info("[LOG] Événement créé avec succès : " + event.getTitle());
EventCreateResponseDTO responseDTO = new EventCreateResponseDTO(event);
return Response.status(Response.Status.CREATED).entity(responseDTO).build();
}
/**
* Endpoint pour récupérer les détails d'un événement par ID.
*
* @param id L'ID de l'événement.
* @return Une réponse HTTP contenant les informations de l'événement.
*/
@GET
@Path("/{id}")
@Operation(
summary = "Récupérer un événement par ID",
description = "Retourne les détails de l'événement demandé")
public Response getEventById(@PathParam("id") UUID id) {
LOG.info("[LOG] Récupération de l'événement avec l'ID : " + id);
Events event = eventsRepository.findById(id);
if (event == null) {
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
EventCreateResponseDTO responseDTO = new EventCreateResponseDTO(event);
LOG.info("[LOG] Événement trouvé : " + event.getTitle());
return Response.ok(responseDTO).build();
}
/**
* Endpoint pour récupérer une liste de tous les événements après une date donnée.
*
* @param startDate La date de début à partir de laquelle filtrer les événements.
* @return Une réponse HTTP contenant la liste des événements après cette date.
*/
@GET
@Path("/after-date")
@Operation(
summary = "Récupérer les événements après une date",
description = "Retourne les événements après une date donnée")
public Response getEventsAfterDate(@QueryParam("startDate") LocalDateTime startDate) {
LOG.info("[LOG] Récupération des événements après la date : " + startDate);
// Appel au service pour récupérer les événements après une date donnée
List<Events> events = eventService.getEventsAfterDate(startDate);
if (events.isEmpty()) {
LOG.warn("[LOG] Aucun événement trouvé après la date : " + startDate);
return Response.status(Response.Status.NOT_FOUND)
.entity("Aucun événement trouvé après cette date.")
.build();
}
// Transformer la liste des événements en DTO pour la réponse
List<EventCreateResponseDTO> responseDTOs = events.stream()
.map(EventCreateResponseDTO::new)
.toList();
LOG.info("[LOG] Nombre d'événements trouvés après la date : " + events.size());
return Response.ok(responseDTOs).build();
}
/**
* Endpoint pour supprimer un événement par ID.
*
* @param id L'ID de l'événement à supprimer.
* @return Une réponse HTTP indiquant le succès ou l'échec de la suppression.
*/
@DELETE
@Path("/{id}")
@Transactional
@Operation(
summary = "Supprimer un événement",
description = "Supprime un événement de la base de données")
public Response deleteEvent(@PathParam("id") UUID id) {
LOG.info("Tentative de suppression de l'événement avec l'ID : " + id);
// Appel du service pour la suppression de l'événement
try {
boolean deleted = eventService.deleteEvent(id);
if (deleted) {
LOG.info("Événement supprimé avec succès.");
return Response.noContent().build();
} else {
LOG.warn("Échec de la suppression : événement introuvable avec l'ID : " + id);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
} catch (EventNotFoundException e) {
LOG.error("[ERROR] Échec de la suppression : " + e.getMessage());
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
}
/**
* Endpoint pour ajouter un participant à un événement.
*
* @param eventId L'ID de l'événement.
* @param user L'utilisateur à ajouter comme participant.
* @return Une réponse HTTP indiquant le succès de l'ajout.
*/
@POST
@Path("/{id}/participants")
@Transactional
@Operation(
summary = "Ajouter un participant à un événement",
description = "Ajoute un utilisateur à un événement")
public Response addParticipant(@PathParam("id") UUID eventId, Users user) {
LOG.info("Ajout d'un participant à l'événement : " + eventId);
Events event = eventsRepository.findById(eventId);
if (event == null) {
LOG.warn("Événement non trouvé avec l'ID : " + eventId);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
event.addParticipant(user);
eventsRepository.persist(event);
LOG.info("Participant ajouté avec succès à l'événement : " + event.getTitle());
return Response.ok(new EventCreateResponseDTO(event)).build();
}
/**
* Endpoint pour retirer un participant d'un événement.
*
* @param eventId L'ID de l'événement.
* @param userId L'ID de l'utilisateur à retirer.
* @return Une réponse HTTP indiquant le succès du retrait.
*/
@DELETE
@Path("/{id}/participants/{userId}")
@Transactional
@Operation(
summary = "Retirer un participant d'un événement",
description = "Supprime un utilisateur de la liste des participants d'un événement")
public Response removeParticipant(
@PathParam("id") UUID eventId, @PathParam("userId") UUID userId) {
LOG.info("Retrait d'un participant de l'événement : " + eventId);
Events event = eventsRepository.findById(eventId);
if (event == null) {
LOG.warn("Événement non trouvé avec l'ID : " + eventId);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
Users user = usersRepository.findById(userId);
if (user == null) {
LOG.warn("Utilisateur non trouvé avec l'ID : " + userId);
return Response.status(Response.Status.NOT_FOUND).entity("Utilisateur non trouvé.").build();
}
event.removeParticipant(user);
eventsRepository.persist(event);
LOG.info("Participant retiré avec succès de l'événement : " + event.getTitle());
return Response.noContent().build();
}
/**
* Endpoint pour obtenir le nombre de participants à un événement.
*
* @param eventId L'ID de l'événement.
* @return Le nombre de participants.
*/
@GET
@Path("/{id}/participants/count")
@Operation(
summary = "Obtenir le nombre de participants à un événement",
description = "Retourne le nombre total de participants à un événement")
public Response getNumberOfParticipants(@PathParam("id") UUID eventId) {
LOG.info("Récupération du nombre de participants pour l'événement : " + eventId);
Events event = eventsRepository.findById(eventId);
if (event == null) {
LOG.warn("Événement non trouvé avec l'ID : " + eventId);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
int participantCount = event.getNumberOfParticipants();
LOG.info("Nombre de participants pour l'événement : " + participantCount);
return Response.ok(participantCount).build();
}
/**
* Endpoint pour fermer un événement.
*
* @param eventId L'ID de l'événement.
* @return Une réponse HTTP indiquant le succès de la fermeture.
*/
@POST
@Path("/{id}/close")
@Transactional
@Operation(
summary = "Fermer un événement",
description = "Ferme un événement et empêche les nouvelles participations")
public Response closeEvent(@PathParam("id") UUID eventId) {
LOG.info("Tentative de fermeture de l'événement avec l'ID : " + eventId);
Events event = eventsRepository.findById(eventId);
if (event == null) {
LOG.warn("Événement non trouvé avec l'ID : " + eventId);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
event.setClosed(true); // Marquer l'événement comme fermé
eventsRepository.persist(event);
LOG.info("Événement fermé avec succès : " + event.getTitle());
return Response.ok(new EventCreateResponseDTO(event)).build();
}
/**
* Endpoint pour mettre à jour un événement.
*
* @param id L'ID de l'événement.
* @param eventUpdateRequestDTO Le DTO de la requête de mise à jour.
* @return Une réponse HTTP indiquant la mise à jour.
*/
@PUT
@Path("/{id}")
@Transactional
@Operation(summary = "Mettre à jour un événement", description = "Modifie un événement existant")
public Response updateEvent(
@PathParam("id") UUID id, EventUpdateRequestDTO eventUpdateRequestDTO) {
LOG.info("[LOG] Tentative de mise à jour de l'événement avec l'ID : " + id);
Events event = eventsRepository.findById(id);
if (event == null) {
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
// Mise à jour des attributs de l'événement
event.setTitle(eventUpdateRequestDTO.getTitle());
event.setStartDate(eventUpdateRequestDTO.getStartDate());
event.setEndDate(eventUpdateRequestDTO.getEndDate());
event.setDescription(eventUpdateRequestDTO.getDescription());
event.setLocation(eventUpdateRequestDTO.getLocation());
event.setCategory(eventUpdateRequestDTO.getCategory());
event.setLink(eventUpdateRequestDTO.getLink());
event.setImageUrl(eventUpdateRequestDTO.getImageUrl());
eventsRepository.persist(event);
LOG.info("[LOG] Événement mis à jour avec succès : " + event.getTitle());
EventUpdateResponseDTO responseDTO = new EventUpdateResponseDTO(event);
return Response.ok(responseDTO).build();
}
/**
* Endpoint pour mettre à jour l'image d'un événement.
*
* @param id L'identifiant de l'événement.
* @param imageFilePath Le chemin vers l'image de l'événement.
* @return Un message indiquant si la mise à jour a réussi ou non.
*/
@PUT
@jakarta.ws.rs.Path("/{id}/image")
public String updateEventImage(@PathParam("id") UUID id, String imageFilePath) {
try {
// Vérification si le chemin d'image est vide ou null
if (imageFilePath == null || imageFilePath.isEmpty()) {
System.out.println("[ERROR] Le chemin de l'image est vide ou null.");
return "Le chemin de l'image est vide ou null.";
}
// Utiliser File pour vérifier si le fichier existe
File file = new File(imageFilePath);
if (!file.exists()) {
System.out.println("[ERROR] Le fichier spécifié n'existe pas : " + imageFilePath);
return "Le fichier spécifié n'existe pas.";
}
// Récupérer l'événement par son ID
Events event = eventService.getEventById(id);
if (event == null) {
System.out.println("[ERROR] Événement non trouvé avec l'ID : " + id);
return "Événement non trouvé.";
}
// Mettre à jour l'URL de l'image de l'événement
String imageUrl = file.getAbsolutePath(); // Obtenir le chemin complet du fichier
event.setImageUrl(imageUrl);
// Mise à jour de l'événement
eventService.updateEvent(event);
System.out.println(
"[LOG] Image de l'événement mise à jour avec succès pour : " + event.getTitle());
return "Image de l'événement mise à jour avec succès.";
} catch (Exception e) {
System.out.println(
"[ERROR] Erreur lors de la mise à jour de l'image de l'événement : " + e.getMessage());
return "Erreur lors de la mise à jour de l'image de l'événement.";
}
}
/**
* Endpoint pour récupérer la liste de tous les événements.
*
* @return Une réponse HTTP contenant la liste des événements.
*/
@GET
@Operation(
summary = "Récupérer tous les événements",
description = "Retourne la liste de tous les événements disponibles")
public Response getAllEvents() {
LOG.info("[LOG] Récupération de tous les événements disponibles");
List<Events> events = eventsRepository.findAll().list();
if (events.isEmpty()) {
LOG.warn("[LOG] Aucun événement trouvé.");
return Response.status(Response.Status.NOT_FOUND)
.entity("Aucun événement trouvé.")
.build();
}
List<EventCreateResponseDTO> responseDTOs = events.stream()
.map(EventCreateResponseDTO::new)
.toList();
LOG.info("[LOG] Nombre total d'événements trouvés : " + events.size());
return Response.ok(responseDTOs).build();
}
/**
* Endpoint pour récupérer les événements par catégorie.
*
* @param category La catégorie d'événement à filtrer.
* @return Une réponse HTTP contenant la liste des événements dans cette catégorie.
*/
@GET
@Path("/category/{category}")
@Operation(
summary = "Récupérer les événements par catégorie",
description = "Retourne la liste des événements correspondant à une catégorie donnée")
public Response getEventsByCategory(@PathParam("category") String category) {
LOG.info("[LOG] Récupération des événements dans la catégorie : " + category);
List<Events> events = eventService.findEventsByCategory(category);
if (events.isEmpty()) {
LOG.warn("[LOG] Aucun événement trouvé pour la catégorie : " + category);
return Response.status(Response.Status.NOT_FOUND)
.entity("Aucun événement trouvé pour cette catégorie.")
.build();
}
List<EventCreateResponseDTO> responseDTOs = events.stream()
.map(EventCreateResponseDTO::new)
.toList();
LOG.info("[LOG] Nombre d'événements trouvés dans la catégorie '" + category + "' : " + events.size());
return Response.ok(responseDTOs).build();
}
/**
* Endpoint pour mettre à jour le statut d'un événement.
*
* @param id L'ID de l'événement.
* @param status Le nouveau statut de l'événement.
* @return Une réponse HTTP indiquant la mise à jour du statut.
*/
@PUT
@Path("/{id}/status")
@Transactional
@Operation(
summary = "Mettre à jour le statut d'un événement",
description = "Modifie le statut d'un événement (ouvert, fermé, annulé, etc.)")
public Response updateEventStatus(@PathParam("id") UUID id, @QueryParam("status") String status) {
LOG.info("[LOG] Mise à jour du statut de l'événement avec l'ID : " + id);
Events event = eventsRepository.findById(id);
if (event == null) {
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
event.setStatus(status);
eventsRepository.persist(event);
LOG.info("[LOG] Statut de l'événement mis à jour avec succès : " + status);
EventUpdateResponseDTO responseDTO = new EventUpdateResponseDTO(event);
return Response.ok(responseDTO).build();
}
/**
* Endpoint pour rechercher des événements par mots-clés.
*
* @param keyword Le mot-clé à rechercher.
* @return Une réponse HTTP contenant la liste des événements correspondant au mot-clé.
*/
@GET
@Path("/search")
@Operation(
summary = "Rechercher des événements par mots-clés",
description = "Retourne la liste des événements dont le titre ou la description contient les mots-clés spécifiés")
public Response searchEvents(@QueryParam("keyword") String keyword) {
LOG.info("[LOG] Recherche d'événements avec le mot-clé : " + keyword);
List<Events> events = eventService.searchEvents(keyword);
if (events.isEmpty()) {
LOG.warn("[LOG] Aucun événement trouvé avec le mot-clé : " + keyword);
return Response.status(Response.Status.NOT_FOUND)
.entity("Aucun événement trouvé pour ce mot-clé.")
.build();
}
List<EventCreateResponseDTO> responseDTOs = events.stream()
.map(EventCreateResponseDTO::new)
.toList();
LOG.info("[LOG] Nombre d'événements trouvés avec le mot-clé '" + keyword + "' : " + events.size());
return Response.ok(responseDTOs).build();
}
/**
* Endpoint pour récupérer les événements auxquels un utilisateur est inscrit.
*
* @param userId L'ID de l'utilisateur.
* @return Une réponse HTTP contenant la liste des événements.
*/
@GET
@Path("/user/{userId}")
@Operation(
summary = "Récupérer les événements auxquels un utilisateur est inscrit",
description = "Retourne la liste des événements auxquels un utilisateur spécifique est inscrit")
public Response getEventsByUser(@PathParam("userId") UUID userId) {
LOG.info("[LOG] Récupération des événements pour l'utilisateur avec l'ID : " + userId);
Users user = usersRepository.findById(userId);
if (user == null) {
LOG.warn("[LOG] Utilisateur non trouvé avec l'ID : " + userId);
return Response.status(Response.Status.NOT_FOUND).entity("Utilisateur non trouvé.").build();
}
List<Events> events = eventService.findEventsByUser(user);
if (events.isEmpty()) {
LOG.warn("[LOG] Aucun événement trouvé pour l'utilisateur avec l'ID : " + userId);
return Response.status(Response.Status.NOT_FOUND).entity("Aucun événement trouvé.").build();
}
List<EventCreateResponseDTO> responseDTOs = events.stream()
.map(EventCreateResponseDTO::new)
.toList();
LOG.info("[LOG] Nombre d'événements trouvés pour l'utilisateur : " + events.size());
return Response.ok(responseDTOs).build();
}
/**
* Endpoint pour récupérer les événements par statut.
*
* @param status Le statut des événements à filtrer (en cours, terminé, etc.).
* @return Une réponse HTTP contenant la liste des événements avec ce statut.
*/
@GET
@Path("/status/{status}")
@Operation(
summary = "Récupérer les événements par statut",
description = "Retourne la liste des événements correspondant à un statut spécifique")
public Response getEventsByStatus(@PathParam("status") String status) {
LOG.info("[LOG] Récupération des événements avec le statut : " + status);
List<Events> events = eventService.findEventsByStatus(status);
if (events.isEmpty()) {
LOG.warn("[LOG] Aucun événement trouvé avec le statut : " + status);
return Response.status(Response.Status.NOT_FOUND)
.entity("Aucun événement trouvé pour ce statut.")
.build();
}
List<EventCreateResponseDTO> responseDTOs = events.stream()
.map(EventCreateResponseDTO::new)
.toList();
LOG.info("[LOG] Nombre d'événements trouvés avec le statut '" + status + "' : " + events.size());
return Response.ok(responseDTOs).build();
}
/**
* Endpoint pour récupérer les événements entre deux dates spécifiques.
*
* @param startDate La date de début pour filtrer les événements.
* @param endDate La date de fin pour filtrer les événements.
* @return Une réponse HTTP contenant la liste des événements entre les deux dates.
*/
@GET
@Path("/between-dates")
@Operation(
summary = "Récupérer les événements entre deux dates",
description = "Retourne la liste des événements qui se déroulent entre deux dates spécifiques")
public Response findEventsBetweenDates(
@QueryParam("startDate") LocalDateTime startDate,
@QueryParam("endDate") LocalDateTime endDate) {
LOG.info("[LOG] Récupération des événements entre les dates : " + startDate + " et " + endDate);
// Vérification de la validité des dates
if (startDate == null || endDate == null || endDate.isBefore(startDate)) {
LOG.error("[ERROR] Les dates fournies sont invalides.");
return Response.status(Response.Status.BAD_REQUEST)
.entity("Les dates sont invalides ou mal formatées.")
.build();
}
// Appel au service pour récupérer les événements entre les dates données
List<Events> events = eventService.findEventsBetweenDates(startDate, endDate);
if (events.isEmpty()) {
LOG.warn("[LOG] Aucun événement trouvé entre les dates : " + startDate + " et " + endDate);
return Response.status(Response.Status.NOT_FOUND)
.entity("Aucun événement trouvé entre ces dates.")
.build();
}
// Transformation des événements en DTO pour la réponse
List<EventCreateResponseDTO> responseDTOs = events.stream()
.map(EventCreateResponseDTO::new)
.toList();
LOG.info("[LOG] Nombre d'événements trouvés entre les dates : " + events.size());
return Response.ok(responseDTOs).build();
}
}