QuickInfoRequestRouter.java
/*
* Copyright (C) 2000 - 2026 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:
* "http://www.silverpeas.org/docs/core/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 <https://www.gnu.org/licenses/>.
*/
package org.silverpeas.components.quickinfo.servlets;
import org.silverpeas.components.quickinfo.NewsByStatus;
import org.silverpeas.components.quickinfo.control.QuickInfoSessionController;
import org.silverpeas.components.quickinfo.model.News;
import org.silverpeas.core.ResourceReference;
import org.silverpeas.core.admin.user.model.SilverpeasRole;
import org.silverpeas.core.date.Period;
import org.silverpeas.core.io.media.image.thumbnail.control.ThumbnailController;
import org.silverpeas.core.io.upload.UploadedFile;
import org.silverpeas.core.security.authorization.ForbiddenRuntimeException;
import org.silverpeas.core.util.DateUtil;
import org.silverpeas.core.util.file.FileItem;
import org.silverpeas.kernel.util.StringUtil;
import org.silverpeas.core.util.URLUtil;
import org.silverpeas.core.util.file.FileUploadUtil;
import org.silverpeas.core.web.http.HttpRequest;
import org.silverpeas.core.web.mvc.controller.ComponentContext;
import org.silverpeas.core.web.mvc.controller.MainSessionController;
import org.silverpeas.core.web.mvc.route.ComponentRequestRouter;
import org.silverpeas.core.web.util.viewgenerator.html.list.ListPaneTag;
import java.io.IOException;
import java.text.ParseException;
import java.time.ZoneId;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import static java.time.OffsetDateTime.ofInstant;
public class QuickInfoRequestRouter extends ComponentRequestRouter<QuickInfoSessionController> {
private static final long serialVersionUID = 2256481728385587395L;
@Override
public String getSessionControlBeanName() {
return "quickinfo";
}
@Override
public QuickInfoSessionController createComponentSessionController(
MainSessionController mainSessionCtrl, ComponentContext componentContext) {
return new QuickInfoSessionController(mainSessionCtrl, componentContext);
}
/**
* This method has to be implemented by the component request rooter it has to compute a
* destination page
* @param function The entering request function (ex : "Main.jsp")
* @param quickInfo The component Session Control, build and initialized.
* @param request The entering request. The request rooter need it to get parameters
* @return The complete destination URL for a forward (ex :
* "/almanach/jsp/almanach.jsp?flag=user")
*/
@Override
public String getDestination(String function, QuickInfoSessionController quickInfo,
HttpRequest request) {
String destination;
SilverpeasRole flag = quickInfo.getHighestSilverpeasUserRole();
if (flag == null) {
return null;
}
request.setAttribute("Role", flag.toString());
request.setAttribute("AppSettings", quickInfo.getInstanceSettings());
try {
if ("Main".equals(function)) {
Collection<News> infos;
if (isContributor(flag)) {
NewsByStatus allNews = quickInfo.getQuickInfos();
request.setAttribute("NotVisibleNews", allNews);
request.setAttribute("isNewsToPaste", quickInfo.isNewsToPaste());
infos = allNews.getVisibles();
} else {
infos = quickInfo.getVisibleQuickInfos();
}
request.setAttribute("ListOfNews", infos);
request.setAttribute("IsSubscriberUser", quickInfo.isSubscriberUser());
destination = "/quickinfo/jsp/home.jsp";
} else if (function.startsWith("portlet")) {
List<News> infos = quickInfo.getVisibleQuickInfos();
request.setAttribute("infos", infos);
if (!"portletPagination".equals(function)) {
final String listName = ListPaneTag.class.getSimpleName() + "listOfNewsFromPortlet";
request.getSession(false).setAttribute(listName, null);
}
destination = "/portlets/jsp/quickInfos/portlet.jsp";
} else if ("Save".equals(function)) {
String id = saveQuickInfo(quickInfo, request, false);
request.setAttribute("Id", id);
destination = getDestination("View", quickInfo, request);
} else if ("Publish".equals(function)) {
String id = request.getParameter("Id");
quickInfo.publish(id);
request.setAttribute("Id", id);
destination = getDestination("View", quickInfo, request);
} else if ("SaveAndPublish".equals(function)) {
String id = saveQuickInfo(quickInfo, request, true);
request.setAttribute("Id", id);
destination = getDestination("View", quickInfo, request);
} else if ("View".equals(function)) {
News news = (News) request.getAttribute("News");
if (news == null) {
String id = (String) request.getAttribute("Id");
if (!StringUtil.isDefined(id)) {
id = request.getParameter("Id");
}
news = quickInfo.getNews(id, true);
request.setAttribute("News", news);
}
if (!isContributor(flag) && (news.isDraft() || !news.isVisible())) {
if (news.isDraft() || news.isNotYetVisible()) {
request.setAttribute("ErrorMessage", "quickinfo.news.error.notyetvisible");
} else {
request.setAttribute("ErrorMessage", "quickinfo.news.error.nomorevisible");
}
destination = getDestination("Main", quickInfo, request);
} else {
request.setAttribute("Index", quickInfo.getIndex());
String anchor = request.getParameter("Anchor");
destination = "/quickinfo/jsp/news.jsp";
if (StringUtil.isDefined(anchor)) {
destination += "#" + anchor;
}
}
} else if ("ViewOnly".equals(function)) {
String id = request.getParameter("Id");
News news = quickInfo.getNewsByForeignId(id);
request.setAttribute("News", news);
request.setAttribute("ViewOnly", true);
destination = getDestination("View", quickInfo, request);
} else if ("ReadingControl".equals(function)) {
String id = request.getParameter("Id");
News news = quickInfo.getNews(id, false);
request.setAttribute("News", news);
SilverpeasRole role = quickInfo.getHighestSilverpeasUserRole();
if (!role.isGreaterThanOrEquals(SilverpeasRole.MANAGER)) {
throwHttpForbiddenError();
}
destination = "/quickinfo/jsp/readingTracking.jsp";
} else if ("Previous".equals(function)) {
request.setAttribute("News", quickInfo.getPrevious());
destination = getDestination("View", quickInfo, request);
} else if ("Next".equals(function)) {
request.setAttribute("News", quickInfo.getNext());
destination = getDestination("View", quickInfo, request);
} else if ("copy".equals(function)) {
if (!isContributor(flag)) {
throwHttpForbiddenError();
}
final String newsId = request.getParameter("Id");
quickInfo.addNewsToBeCopied(newsId);
destination =
URLUtil.getURL(URLUtil.CMP_CLIPBOARD, null, null) + "Idle.jsp?message=REFRESHCLIPBOARD";
} else if (function.startsWith("paste")) {
if (!isContributor(flag)) {
throwHttpForbiddenError();
}
quickInfo.paste();
destination = getDestination("Main", quickInfo, request);
} else if ("Add".equals(function)) {
if (!isContributor(flag)) {
throwHttpForbiddenError();
}
News news = quickInfo.prepareEmptyNews();
request.setAttribute("NewOneInProgress", true);
setCommonAttributesToAddOrUpdate(quickInfo, news, request);
destination = "/quickinfo/jsp/quickInfoEdit.jsp";
} else if ("Edit".equals(function)) {
if (!isContributor(flag)) {
throwHttpForbiddenError();
}
String id = request.getParameter("Id");
News news = quickInfo.getNews(id, false);
setCommonAttributesToAddOrUpdate(quickInfo, news, request);
destination = "/quickinfo/jsp/quickInfoEdit.jsp";
} else if (function.startsWith("searchResult")) {
String id = request.getParameter("Id");
News news;
if (StringUtil.isInteger(id)) {
// from a search result
news = quickInfo.getNewsByForeignId(id);
} else {
// from a comment
news = quickInfo.getNews(id, true);
}
request.setAttribute("News", news);
destination = getDestination("View", quickInfo, request);
} else if ("SubmitOnHomepage".equals(function)) {
if (!isContributor(flag)) {
throwHttpForbiddenError();
}
String id = request.getParameter("Id");
quickInfo.submitNewsOnHomepage(id);
destination = getDestination("View", quickInfo, request);
} else if ("ManageSubscriptions".equals(function)) {
destination = quickInfo.manageSubscriptions();
} else {
destination = "/quickinfo/jsp/" + function;
}
} catch (Exception e) {
request.setAttribute("jakarta.servlet.jsp.jspException", e);
destination = "/admin/jsp/errorpage.jsp";
}
return destination;
}
private boolean isContributor(SilverpeasRole role) {
return role.isGreaterThanOrEquals(SilverpeasRole.PUBLISHER);
}
private void setCommonAttributesToAddOrUpdate(QuickInfoSessionController quickInfo, News news,
HttpRequest request) {
request.setAttribute("info", news);
request.setAttribute("ThumbnailSettings", quickInfo.getThumbnailSettings());
}
/**
* This method retrieve all the request parameters before creating or updating a quick info
* @param quickInfo the QuickInfoSessionController
* @param request the HttpServletRequest
* @param publish true if publish action, false otherwise.
* @throws ParseException if the file items cannot be parsed
* @throws IOException if the file saving fails.
*/
private String saveQuickInfo(QuickInfoSessionController quickInfo, HttpRequest request,
boolean publish) throws ParseException, IOException {
List<FileItem> items = request.getFileItems();
News news = requestToNews(items, quickInfo.getLanguage());
String positions = request.getParameter("Positions");
if (quickInfo.isNewsIdentifierFromMemory(news.getId())) {
quickInfo.create(news);
}
String id = news.getId();
// process thumbnail first to be stored in index when publication is updated
ThumbnailController
.processThumbnail(new ResourceReference(news.getPublicationId(),
quickInfo.getComponentId()), items);
// process files
Collection<UploadedFile> uploadedFiles = request.getUploadedFiles();
quickInfo.update(id, news, positions, uploadedFiles, publish);
return id;
}
private News requestToNews(List<FileItem> items, String language) throws ParseException {
String id = FileUploadUtil.getParameter(items, "Id");
String name = FileUploadUtil.getParameter(items, "Name");
String description = FileUploadUtil.getParameter(items, "Description");
String keywords = FileUploadUtil.getParameter(items, "Keywords");
String content = FileUploadUtil.getParameter(items, "editorContent");
String pubId = FileUploadUtil.getParameter(items, "PubId");
boolean important =
StringUtil.getBooleanValue(FileUploadUtil.getParameter(items, "BroadcastImportant"));
boolean ticker =
StringUtil.getBooleanValue(FileUploadUtil.getParameter(items, "BroadcastTicker"));
boolean mandatory =
StringUtil.getBooleanValue(FileUploadUtil.getParameter(items, "BroadcastMandatory"));
Date beginDate = null;
String beginString = FileUploadUtil.getParameter(items, "BeginDate");
if (StringUtil.isDefined(beginString)) {
String hour = FileUploadUtil.getParameter(items, "BeginHour");
beginDate = DateUtil.stringToDate(beginString, hour, language);
}
Date endDate = null;
String endString = FileUploadUtil.getParameter(items, "EndDate");
if (StringUtil.isDefined(endString)) {
String hour = FileUploadUtil.getParameter(items, "EndHour");
endDate = DateUtil.stringToDate(endString, hour, language);
}
News news = News.builder()
.setTitleAndDescription(name, description)
.setKeywords(keywords)
.setVisibilityPeriod(getPeriod(beginDate, endDate))
.setImportant(important)
.setTicker(ticker)
.setMandatory(mandatory)
.build();
news.setId(id);
news.setContentToStore(content);
if (StringUtil.isDefined(pubId)) {
news.setPublicationId(pubId);
}
return news;
}
private Period getPeriod(Date begin, Date end) {
return Period.betweenNullable(
begin != null ? ofInstant(begin.toInstant(), ZoneId.systemDefault()) : null,
end != null ? ofInstant(end.toInstant(), ZoneId.systemDefault()) : null
);
}
}