ServiceResourcesManager.java
/*
* Copyright (C) 2000 - 2025 Silverpeas
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* As a special exception to the terms and conditions of version 3.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* Open Source Software ("FLOSS") applications as described in Silverpeas's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* "https://www.silverpeas.org/legal/floss_exception.html"
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.silverpeas.mobile.server.services;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import org.silverpeas.components.resourcesmanager.ResourcesManagerProvider;
import org.silverpeas.components.resourcesmanager.model.Reservation;
import org.silverpeas.components.resourcesmanager.model.Resource;
import org.silverpeas.components.resourcesmanager.model.ResourceStatus;
import org.silverpeas.components.resourcesmanager.model.ResourceValidator;
import org.silverpeas.components.resourcesmanager.service.ReservationService;
import org.silverpeas.core.annotation.WebService;
import org.silverpeas.core.notification.NotificationException;
import org.silverpeas.core.notification.user.client.NotificationMetaData;
import org.silverpeas.core.notification.user.client.NotificationParameters;
import org.silverpeas.core.notification.user.client.NotificationSender;
import org.silverpeas.core.notification.user.client.UserRecipient;
import org.silverpeas.core.ui.DisplayI18NHelper;
import org.silverpeas.core.util.DateUtil;
import org.silverpeas.core.util.Link;
import org.silverpeas.core.util.ServiceProvider;
import org.silverpeas.core.util.URLUtil;
import org.silverpeas.core.web.rs.annotation.Authorized;
import org.silverpeas.kernel.bundle.LocalizationBundle;
import org.silverpeas.kernel.bundle.ResourceLocator;
import org.silverpeas.kernel.logging.SilverLogger;
import org.silverpeas.mobile.shared.dto.reservations.Errors;
import org.silverpeas.mobile.shared.dto.reservations.ReservationDTO;
import org.silverpeas.mobile.shared.dto.reservations.ResourceDTO;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@WebService
@Authorized
@Path(ServiceResourcesManager.PATH + "/{appId}")
public class ServiceResourcesManager extends AbstractRestWebService {
@Context
HttpServletRequest request;
@PathParam("appId")
private String componentId;
private NotificationSender notifSender;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");
static final String PATH = "mobile/resourcesManager";
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("resources/checkdates/{startDate}/{endDate}")
public String checkDates(@PathParam("startDate") String startDate,
@PathParam("endDate") String endDate) {
try {
Date start = sdf.parse(startDate.replace("T", " "));
Date end = sdf.parse(endDate.replace("T", " "));
Date now = Calendar.getInstance().getTime();
if (end.before(start)) {
return Errors.dateOrder.toString();
} else if (start.before(now)) {
return Errors.earlierDate.toString();
}
} catch (Exception e) {
SilverLogger.getLogger(this).error(e);
}
return "";
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("resources/available/{startDate}/{endDate}")
public List<ResourceDTO> getAvailableResources(@PathParam("startDate") String startDate,
@PathParam("endDate") String endDate) {
List<ResourceDTO> resources = new ArrayList<>();
try {
Date start = sdf.parse(startDate.replace("T", " "));
Date end = sdf.parse(endDate.replace("T", " "));
List<Resource> availablesResources = ResourcesManagerProvider.getResourcesManager()
.getResourcesReservable(componentId, start, end);
for (Resource res : availablesResources) {
ResourceDTO dto = new ResourceDTO();
dto.setId(res.getId());
dto.setName(res.getName());
dto.setCategoryId(res.getCategory().getId());
dto.setCategoryName(res.getCategory().getName());
dto.setDescription(res.getDescription());
resources.add(dto);
}
} catch (Exception e) {
SilverLogger.getLogger(this).error(e);
}
return resources;
}
@DELETE
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/reservation")
public void deleteReservation(ReservationDTO reservation) {
ResourcesManagerProvider.getResourcesManager().deleteReservation(Long.parseLong(reservation.getId()), componentId);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/reservations/my")
public List<ReservationDTO> getMyReservations() {
List<ReservationDTO> reservations = new ArrayList<>();
try {
ReservationService service = ServiceProvider.getService(ReservationService.class);
String startPeriod = String.valueOf(Calendar.getInstance().getTime().getTime());
String endPeriod = String.valueOf(DateUtil.MAXIMUM_DATE.getTime());
List<Reservation> reservationList =
service.findAllReservationsInRange(componentId, Integer.parseInt(getUser().getId()),
startPeriod, endPeriod);
for (Reservation reserv : reservationList) {
ReservationDTO dto = populate(reserv);
dto = populateResourcesOfReservation(reserv, dto);
reservations.add(dto);
}
} catch (Exception e) {
SilverLogger.getLogger(this).error(e);
}
return reservations;
}
private ReservationDTO populateResourcesOfReservation(final Reservation reserv, final ReservationDTO dto) {
List<Resource> resources = ResourcesManagerProvider.getResourcesManager().getResourcesOfReservation(componentId, reserv.getIdAsLong());
List<ResourceDTO> resourcesBooked = new ArrayList();
for (Resource res : resources) {
ResourceDTO resourceDTO = new ResourceDTO();
String status = ResourcesManagerProvider.getResourcesManager().getResourceOfReservationStatus(res.getIdAsLong(), reserv.getIdAsLong());
resourceDTO.setReservationStatus(status);
resourceDTO.setName(res.getName());
resourceDTO.setId(res.getId());
resourceDTO.setDescription(res.getDescription());
resourceDTO.setCategoryId(String.valueOf(res.getCategoryId()));
resourcesBooked.add(resourceDTO);
}
dto.setResources(resourcesBooked);
return dto;
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("saveReservation")
public ReservationDTO saveReservation(ReservationDTO dto) {
try {
Reservation reservation = new Reservation();
reservation.setEvent(dto.getEvenement());
Date start = sdf.parse(dto.getStartDate().replace("T", " "));
Date end = sdf.parse(dto.getEndDate().replace("T", " "));
reservation.setBeginDate(start);
reservation.setEndDate(end);
reservation.setReason(dto.getReason());
List<Long> resources = new ArrayList<>();
for (ResourceDTO res : dto.getResources()) {
resources.add(Long.parseLong(res.getId()));
}
reservation.setInstanceId(componentId);
reservation.setUserId(getUser().getId());
reservation.setPlace("");
ResourcesManagerProvider.getResourcesManager().saveReservation(reservation, resources);
dto = populate(reservation);
dto = populateResourcesOfReservation(reservation, dto);
// envoi d'une notification pour validation aux responsables des ressources selectionnées.
for (Long resourceId : resources) {
sendNotificationForValidation(resourceId, reservation.getIdAsLong());
}
} catch (Exception e) {
SilverLogger.getLogger(this).error(e);
}
return dto;
}
private ReservationDTO populate(final Reservation reservation) {
ReservationDTO dto = new ReservationDTO();
dto.setId(reservation.getId());
dto.setEvenement(reservation.getEvent());
dto.setStartDate(sdf.format(reservation.getBeginDate()));
dto.setEndDate(sdf.format(reservation.getEndDate()));
dto.setReason(reservation.getReason());
dto.setStatus(reservation.getStatus());
return dto;
}
private void sendNotificationForValidation(Long resourceId, Long reservationId)
throws NotificationException {
Resource resource = getResource(resourceId);
String status = ResourcesManagerProvider.getResourcesManager()
.getResourceOfReservationStatus(resourceId, reservationId);
if (ResourceStatus.STATUS_FOR_VALIDATION.equals(status)) {
// envoyer une notification aux responsables de la ressource
String user = getUser().getDisplayedName();
LocalizationBundle message = ResourceLocator.getLocalizationBundle(
"org.silverpeas.resourcesmanager.multilang.resourcesManagerBundle",
DisplayI18NHelper.getDefaultLanguage());
StringBuilder messageBody = new StringBuilder();
// liste des responsables (de la ressource) à notifier
List<ResourceValidator> validators =
ResourcesManagerProvider.getResourcesManager().getManagers(resource.getIdAsLong());
List<UserRecipient> managers = new ArrayList<UserRecipient>(validators.size());
if (!ResourcesManagerProvider.getResourcesManager()
.isManager(Long.parseLong(getUser().getId()), resourceId)) {
// envoie de la notification seulement si le user courant n'est pas aussi responsable
for (ResourceValidator validator : validators) {
managers.add(new UserRecipient(String.valueOf(validator.getManagerId())));
}
String url = URLUtil.getURL(null, getComponentId()) + "ViewReservation?reservationId=" +
reservationId;
String subject = message.getString("resourcesManager.notifSubject");
messageBody = messageBody.append(user).append(" ")
.append(message.getString("resourcesManager.notifBody")).append(" '")
.append(resource.getName()).append("'");
NotificationMetaData notifMetaData =
new NotificationMetaData(NotificationParameters.PRIORITY_NORMAL, subject,
messageBody.toString());
for (String language : DisplayI18NHelper.getLanguages()) {
message = ResourceLocator.getLocalizationBundle(
"org.silverpeas.resourcesmanager.multilang.resourcesManagerBundle", language);
subject = message.getString("resourcesManager.notifSubject");
messageBody = new StringBuilder();
messageBody = messageBody.append(user).append(" ")
.append(message.getString("resourcesManager.notifBody")).append(" '")
.append(resource.getName()).append("'.");
notifMetaData.addLanguage(language, subject, messageBody.toString());
Link link =
new Link(url, message.getString("resourcesManager.notifReservationLinkLabel"));
notifMetaData.setLink(link, language);
}
notifMetaData.addUserRecipients(managers);
setMetaData(notifMetaData);
// 2. envoie de la notification aux responsables
getNotificationSender().notifyUser(notifMetaData);
}
}
}
public Resource getResource(Long id) {
return ResourcesManagerProvider.getResourcesManager().getResource(id);
}
public NotificationSender getNotificationSender() {
if (notifSender == null) {
notifSender = new NotificationSender(getComponentId());
}
return notifSender;
}
private void setMetaData(NotificationMetaData notifMetaData) {
notifMetaData.setComponentId(getComponentId());
notifMetaData.setSender(getUser().getId());
}
@Override
protected String getResourceBasePath() {
return PATH;
}
@Override
public String getComponentId() {
return this.componentId;
}
}